From e089497ffb21fde74a3f21e8c259cceac1eb39dd Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 25 Oct 2024 12:27:11 +0200 Subject: [PATCH 01/76] refactor: rename Target to Target Config (#1292) * refactor: rename Target to Target Config BREAKING CHANGE: - target commands are now target-config commands - Target property is now TargetConfig property in all Workspace models - /target endpoint is now /target-config endpoint Signed-off-by: Toma Puljak --- docs/daytona.md | 2 +- docs/daytona_target-config.md | 18 ++ ..._list.md => daytona_target-config_list.md} | 8 +- ...ove.md => daytona_target-config_remove.md} | 8 +- docs/daytona_target-config_set-default.md | 18 ++ docs/daytona_target-config_set.md | 18 ++ docs/daytona_target.md | 18 -- docs/daytona_target_set-default.md | 18 -- docs/daytona_target_set.md | 24 -- hack/docs/daytona.yaml | 2 +- hack/docs/daytona_target-config.yaml | 12 + ...t.yaml => daytona_target-config_list.yaml} | 8 +- ...yaml => daytona_target-config_remove.yaml} | 8 +- .../daytona_target-config_set-default.yaml | 9 + hack/docs/daytona_target-config_set.yaml | 9 + hack/docs/daytona_target.yaml | 12 - hack/docs/daytona_target_set-default.yaml | 9 - hack/docs/daytona_target_set.yaml | 14 - .../testing/provider/targetconfigs/store.go | 80 ++++++ internal/testing/provider/targets/store.go | 80 ------ .../server/workspaces/mocks/provisioner.go | 28 +- internal/util/apiclient/conversion/project.go | 2 +- internal/util/apiclient/conversion/target.go | 17 -- .../apiclient/conversion/target_config.go | 17 ++ pkg/agent/agent_test.go | 10 +- .../provider/{targets.go => target_config.go} | 16 +- pkg/api/controllers/target/list.go | 70 ----- pkg/api/controllers/target/remove.go | 45 ---- pkg/api/controllers/target/set.go | 78 ------ pkg/api/controllers/targetconfig/list.go | 70 +++++ pkg/api/controllers/targetconfig/remove.go | 45 ++++ pkg/api/controllers/targetconfig/set.go | 78 ++++++ pkg/api/docs/docs.go | 252 +++++++++--------- pkg/api/docs/swagger.json | 252 +++++++++--------- pkg/api/docs/swagger.yaml | 216 +++++++-------- pkg/api/server.go | 14 +- pkg/apiclient/README.md | 18 +- pkg/apiclient/api/openapi.yaml | 252 +++++++++--------- pkg/apiclient/api_provider.go | 26 +- .../{api_target.go => api_target_config.go} | 136 +++++----- pkg/apiclient/client.go | 4 +- ...rTargetDTO.md => CreateTargetConfigDTO.md} | 32 +-- pkg/apiclient/docs/CreateWorkspaceDTO.md | 22 +- pkg/apiclient/docs/Project.md | 22 +- pkg/apiclient/docs/ProviderAPI.md | 20 +- .../ProviderProviderTargetPropertyType.md | 21 -- .../docs/ProviderTargetConfigPropertyType.md | 21 ++ .../{ProviderTarget.md => TargetConfig.md} | 38 +-- .../docs/{TargetAPI.md => TargetConfigAPI.md} | 76 +++--- ...getProperty.md => TargetConfigProperty.md} | 76 +++--- pkg/apiclient/docs/Workspace.md | 22 +- pkg/apiclient/docs/WorkspaceAPI.md | 2 +- pkg/apiclient/docs/WorkspaceDTO.md | 22 +- ...o.go => model_create_target_config_dto.go} | 72 ++--- pkg/apiclient/model_create_workspace_dto.go | 34 +-- pkg/apiclient/model_project.go | 28 +- ..._provider_provider_target_property_type.go | 118 -------- ...el_provider_target_config_property_type.go | 118 ++++++++ ...vider_target.go => model_target_config.go} | 78 +++--- ...rty.go => model_target_config_property.go} | 112 ++++---- pkg/apiclient/model_workspace.go | 34 +-- pkg/apiclient/model_workspace_dto.go | 36 +-- pkg/cmd/cmd.go | 8 +- pkg/cmd/provider/install.go | 32 +-- pkg/cmd/server/serve.go | 32 +-- pkg/cmd/target/target.go | 22 -- pkg/cmd/{target => targetconfig}/list.go | 16 +- pkg/cmd/{target => targetconfig}/remove.go | 57 ++-- pkg/cmd/{target => targetconfig}/set.go | 95 ++++--- .../{target => targetconfig}/setdefault.go | 30 +-- pkg/cmd/targetconfig/target_config.go | 23 ++ pkg/cmd/workspace/create.go | 32 +-- pkg/cmd/workspace/ssh-proxy.go | 2 +- pkg/cmd/workspace/util/get_target.go | 122 --------- pkg/cmd/workspace/util/get_target_config.go | 122 +++++++++ pkg/db/container_registry_store.go | 6 +- pkg/db/dto/project.go | 6 +- pkg/db/dto/provider_target.go | 39 --- pkg/db/dto/target_config.go | 39 +++ pkg/db/dto/workspace.go | 26 +- pkg/db/provider_target_store.go | 88 ------ pkg/db/target_config_store.go | 86 ++++++ pkg/docker/client_test.go | 16 +- pkg/docker/info_test.go | 6 +- pkg/provider/manager/manager.go | 30 +-- pkg/provider/provider.go | 4 +- pkg/provider/rpc_client.go | 12 +- pkg/provider/rpc_server.go | 12 +- pkg/provider/store.go | 18 +- pkg/provider/types.go | 38 +-- pkg/provisioner/create.go | 12 +- pkg/provisioner/destroy.go | 16 +- pkg/provisioner/info.go | 8 +- pkg/provisioner/provisioner.go | 16 +- pkg/provisioner/start.go | 12 +- pkg/provisioner/stop.go | 16 +- pkg/server/providertargets/service.go | 94 ------- pkg/server/providertargets/service_test.go | 153 ----------- pkg/server/server.go | 8 +- .../dto/target_config.go} | 4 +- pkg/server/targetconfigs/service.go | 94 +++++++ pkg/server/targetconfigs/service_test.go | 153 +++++++++++ pkg/server/workspaces/create.go | 26 +- pkg/server/workspaces/dto/workspace.go | 8 +- pkg/server/workspaces/get.go | 4 +- pkg/server/workspaces/list.go | 6 +- pkg/server/workspaces/remove.go | 16 +- pkg/server/workspaces/service.go | 10 +- pkg/server/workspaces/service_test.go | 68 ++--- pkg/server/workspaces/start.go | 20 +- pkg/server/workspaces/stop.go | 12 +- pkg/telemetry/server_events.go | 10 +- pkg/views/initial/view.go | 2 +- pkg/views/target/list/view.go | 98 ------- pkg/views/targetconfig/list.go | 92 +++++++ pkg/views/{target => targetconfig}/select.go | 38 +-- pkg/views/{target => targetconfig}/set.go | 58 ++-- pkg/views/{target => targetconfig}/view.go | 20 +- pkg/views/util/empty_list.go | 6 +- pkg/views/util/help.go | 4 +- pkg/views/util/table.go | 2 +- pkg/views/workspace/info/view.go | 4 +- pkg/views/workspace/list/view.go | 20 +- pkg/views/workspace/selection/view.go | 32 +-- pkg/views/workspace/selection/workspace.go | 2 +- pkg/workspace/project/project.go | 2 +- pkg/workspace/workspace.go | 12 +- 127 files changed, 2592 insertions(+), 2610 deletions(-) create mode 100644 docs/daytona_target-config.md rename docs/{daytona_target_list.md => daytona_target-config_list.md} (55%) rename docs/{daytona_target_remove.md => daytona_target-config_remove.md} (52%) create mode 100644 docs/daytona_target-config_set-default.md create mode 100644 docs/daytona_target-config_set.md delete mode 100644 docs/daytona_target.md delete mode 100644 docs/daytona_target_set-default.md delete mode 100644 docs/daytona_target_set.md create mode 100644 hack/docs/daytona_target-config.yaml rename hack/docs/{daytona_target_list.yaml => daytona_target-config_list.yaml} (56%) rename hack/docs/{daytona_target_remove.yaml => daytona_target-config_remove.yaml} (58%) create mode 100644 hack/docs/daytona_target-config_set-default.yaml create mode 100644 hack/docs/daytona_target-config_set.yaml delete mode 100644 hack/docs/daytona_target.yaml delete mode 100644 hack/docs/daytona_target_set-default.yaml delete mode 100644 hack/docs/daytona_target_set.yaml create mode 100644 internal/testing/provider/targetconfigs/store.go delete mode 100644 internal/testing/provider/targets/store.go delete mode 100644 internal/util/apiclient/conversion/target.go create mode 100644 internal/util/apiclient/conversion/target_config.go rename pkg/api/controllers/provider/{targets.go => target_config.go} (65%) delete mode 100644 pkg/api/controllers/target/list.go delete mode 100644 pkg/api/controllers/target/remove.go delete mode 100644 pkg/api/controllers/target/set.go create mode 100644 pkg/api/controllers/targetconfig/list.go create mode 100644 pkg/api/controllers/targetconfig/remove.go create mode 100644 pkg/api/controllers/targetconfig/set.go rename pkg/apiclient/{api_target.go => api_target_config.go} (73%) rename pkg/apiclient/docs/{CreateProviderTargetDTO.md => CreateTargetConfigDTO.md} (62%) delete mode 100644 pkg/apiclient/docs/ProviderProviderTargetPropertyType.md create mode 100644 pkg/apiclient/docs/ProviderTargetConfigPropertyType.md rename pkg/apiclient/docs/{ProviderTarget.md => TargetConfig.md} (67%) rename pkg/apiclient/docs/{TargetAPI.md => TargetConfigAPI.md} (60%) rename pkg/apiclient/docs/{ProviderProviderTargetProperty.md => TargetConfigProperty.md} (59%) rename pkg/apiclient/{model_create_provider_target_dto.go => model_create_target_config_dto.go} (57%) delete mode 100644 pkg/apiclient/model_provider_provider_target_property_type.go create mode 100644 pkg/apiclient/model_provider_target_config_property_type.go rename pkg/apiclient/{model_provider_target.go => model_target_config.go} (63%) rename pkg/apiclient/{model_provider_provider_target_property.go => model_target_config_property.go} (61%) delete mode 100644 pkg/cmd/target/target.go rename pkg/cmd/{target => targetconfig}/list.go (65%) rename pkg/cmd/{target => targetconfig}/remove.go (61%) rename pkg/cmd/{target => targetconfig}/set.go (68%) rename pkg/cmd/{target => targetconfig}/setdefault.go (58%) create mode 100644 pkg/cmd/targetconfig/target_config.go delete mode 100644 pkg/cmd/workspace/util/get_target.go create mode 100644 pkg/cmd/workspace/util/get_target_config.go delete mode 100644 pkg/db/dto/provider_target.go create mode 100644 pkg/db/dto/target_config.go delete mode 100644 pkg/db/provider_target_store.go create mode 100644 pkg/db/target_config_store.go delete mode 100644 pkg/server/providertargets/service.go delete mode 100644 pkg/server/providertargets/service_test.go rename pkg/server/{providertargets/dto/providertargets.go => targetconfigs/dto/target_config.go} (83%) create mode 100644 pkg/server/targetconfigs/service.go create mode 100644 pkg/server/targetconfigs/service_test.go delete mode 100644 pkg/views/target/list/view.go create mode 100644 pkg/views/targetconfig/list.go rename pkg/views/{target => targetconfig}/select.go (62%) rename pkg/views/{target => targetconfig}/set.go (77%) rename pkg/views/{target => targetconfig}/view.go (77%) diff --git a/docs/daytona.md b/docs/daytona.md index c1d845a9d6..11323cf20a 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -46,7 +46,7 @@ daytona [flags] * [daytona ssh](daytona_ssh.md) - SSH into a project using the terminal * [daytona start](daytona_start.md) - Start a workspace * [daytona stop](daytona_stop.md) - Stop a workspace -* [daytona target](daytona_target.md) - Manage provider targets +* [daytona target-config](daytona_target-config.md) - Manage target configs * [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection * [daytona update](daytona_update.md) - Update Daytona CLI * [daytona use](daytona_use.md) - Use profile [PROFILE_NAME] diff --git a/docs/daytona_target-config.md b/docs/daytona_target-config.md new file mode 100644 index 0000000000..3effd3ca45 --- /dev/null +++ b/docs/daytona_target-config.md @@ -0,0 +1,18 @@ +## daytona target-config + +Manage target configs + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona target-config list](daytona_target-config_list.md) - List target configs +* [daytona target-config remove](daytona_target-config_remove.md) - Remove target config +* [daytona target-config set](daytona_target-config_set.md) - Set target config +* [daytona target-config set-default](daytona_target-config_set-default.md) - Set default target config + diff --git a/docs/daytona_target_list.md b/docs/daytona_target-config_list.md similarity index 55% rename from docs/daytona_target_list.md rename to docs/daytona_target-config_list.md index 286cd46b2a..b14c9641fd 100644 --- a/docs/daytona_target_list.md +++ b/docs/daytona_target-config_list.md @@ -1,9 +1,9 @@ -## daytona target list +## daytona target-config list -List targets +List target configs ``` -daytona target list [flags] +daytona target-config list [flags] ``` ### Options @@ -20,5 +20,5 @@ daytona target list [flags] ### SEE ALSO -* [daytona target](daytona_target.md) - Manage provider targets +* [daytona target-config](daytona_target-config.md) - Manage target configs diff --git a/docs/daytona_target_remove.md b/docs/daytona_target-config_remove.md similarity index 52% rename from docs/daytona_target_remove.md rename to docs/daytona_target-config_remove.md index 2d6828fcbc..93e7c60e5b 100644 --- a/docs/daytona_target_remove.md +++ b/docs/daytona_target-config_remove.md @@ -1,9 +1,9 @@ -## daytona target remove +## daytona target-config remove -Remove target +Remove target config ``` -daytona target remove [TARGET_NAME] [flags] +daytona target-config remove [CONFIG_NAME] [flags] ``` ### Options @@ -20,5 +20,5 @@ daytona target remove [TARGET_NAME] [flags] ### SEE ALSO -* [daytona target](daytona_target.md) - Manage provider targets +* [daytona target-config](daytona_target-config.md) - Manage target configs diff --git a/docs/daytona_target-config_set-default.md b/docs/daytona_target-config_set-default.md new file mode 100644 index 0000000000..60aa9b6f7c --- /dev/null +++ b/docs/daytona_target-config_set-default.md @@ -0,0 +1,18 @@ +## daytona target-config set-default + +Set default target config + +``` +daytona target-config set-default [CONFIG_NAME] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target-config](daytona_target-config.md) - Manage target configs + diff --git a/docs/daytona_target-config_set.md b/docs/daytona_target-config_set.md new file mode 100644 index 0000000000..fb453a3699 --- /dev/null +++ b/docs/daytona_target-config_set.md @@ -0,0 +1,18 @@ +## daytona target-config set + +Set target config + +``` +daytona target-config set [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target-config](daytona_target-config.md) - Manage target configs + diff --git a/docs/daytona_target.md b/docs/daytona_target.md deleted file mode 100644 index 32b4b9f7f3..0000000000 --- a/docs/daytona_target.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona target - -Manage provider targets - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona target list](daytona_target_list.md) - List targets -* [daytona target remove](daytona_target_remove.md) - Remove target -* [daytona target set](daytona_target_set.md) - Set provider target -* [daytona target set-default](daytona_target_set-default.md) - Set target to be used by default - diff --git a/docs/daytona_target_set-default.md b/docs/daytona_target_set-default.md deleted file mode 100644 index d37fb3155c..0000000000 --- a/docs/daytona_target_set-default.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona target set-default - -Set target to be used by default - -``` -daytona target set-default [TARGET_NAME] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target](daytona_target.md) - Manage provider targets - diff --git a/docs/daytona_target_set.md b/docs/daytona_target_set.md deleted file mode 100644 index c7bf440d4d..0000000000 --- a/docs/daytona_target_set.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona target set - -Set provider target - -``` -daytona target set [flags] -``` - -### Options - -``` - -f, --file string Path to JSON file for target configuration, use '-' to read from stdin -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target](daytona_target.md) - Manage provider targets - diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 611aba624e..1ea45ce8ac 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -38,7 +38,7 @@ see_also: - daytona ssh - SSH into a project using the terminal - daytona start - Start a workspace - daytona stop - Stop a workspace - - daytona target - Manage provider targets + - daytona target-config - Manage target configs - daytona telemetry - Manage telemetry collection - daytona update - Update Daytona CLI - daytona use - Use profile [PROFILE_NAME] diff --git a/hack/docs/daytona_target-config.yaml b/hack/docs/daytona_target-config.yaml new file mode 100644 index 0000000000..60577252ee --- /dev/null +++ b/hack/docs/daytona_target-config.yaml @@ -0,0 +1,12 @@ +name: daytona target-config +synopsis: Manage target configs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona target-config list - List target configs + - daytona target-config remove - Remove target config + - daytona target-config set - Set target config + - daytona target-config set-default - Set default target config diff --git a/hack/docs/daytona_target_list.yaml b/hack/docs/daytona_target-config_list.yaml similarity index 56% rename from hack/docs/daytona_target_list.yaml rename to hack/docs/daytona_target-config_list.yaml index 80c5e8c7de..a96c7f7908 100644 --- a/hack/docs/daytona_target_list.yaml +++ b/hack/docs/daytona_target-config_list.yaml @@ -1,6 +1,6 @@ -name: daytona target list -synopsis: List targets -usage: daytona target list [flags] +name: daytona target-config list +synopsis: List target configs +usage: daytona target-config list [flags] options: - name: format shorthand: f @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona target - Manage provider targets + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target_remove.yaml b/hack/docs/daytona_target-config_remove.yaml similarity index 58% rename from hack/docs/daytona_target_remove.yaml rename to hack/docs/daytona_target-config_remove.yaml index ac8a3eebf3..e9f4a6e74e 100644 --- a/hack/docs/daytona_target_remove.yaml +++ b/hack/docs/daytona_target-config_remove.yaml @@ -1,6 +1,6 @@ -name: daytona target remove -synopsis: Remove target -usage: daytona target remove [TARGET_NAME] [flags] +name: daytona target-config remove +synopsis: Remove target config +usage: daytona target-config remove [CONFIG_NAME] [flags] options: - name: "yes" shorthand: "y" @@ -11,4 +11,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona target - Manage provider targets + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_set-default.yaml b/hack/docs/daytona_target-config_set-default.yaml new file mode 100644 index 0000000000..dc6fe9e01e --- /dev/null +++ b/hack/docs/daytona_target-config_set-default.yaml @@ -0,0 +1,9 @@ +name: daytona target-config set-default +synopsis: Set default target config +usage: daytona target-config set-default [CONFIG_NAME] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_set.yaml b/hack/docs/daytona_target-config_set.yaml new file mode 100644 index 0000000000..21c4fa5447 --- /dev/null +++ b/hack/docs/daytona_target-config_set.yaml @@ -0,0 +1,9 @@ +name: daytona target-config set +synopsis: Set target config +usage: daytona target-config set [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target.yaml b/hack/docs/daytona_target.yaml deleted file mode 100644 index 92ce570824..0000000000 --- a/hack/docs/daytona_target.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: daytona target -synopsis: Manage provider targets -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona target list - List targets - - daytona target remove - Remove target - - daytona target set - Set provider target - - daytona target set-default - Set target to be used by default diff --git a/hack/docs/daytona_target_set-default.yaml b/hack/docs/daytona_target_set-default.yaml deleted file mode 100644 index 138758fbd2..0000000000 --- a/hack/docs/daytona_target_set-default.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona target set-default -synopsis: Set target to be used by default -usage: daytona target set-default [TARGET_NAME] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target - Manage provider targets diff --git a/hack/docs/daytona_target_set.yaml b/hack/docs/daytona_target_set.yaml deleted file mode 100644 index 96d66090af..0000000000 --- a/hack/docs/daytona_target_set.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona target set -synopsis: Set provider target -usage: daytona target set [flags] -options: - - name: file - shorthand: f - usage: | - Path to JSON file for target configuration, use '-' to read from stdin -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target - Manage provider targets diff --git a/internal/testing/provider/targetconfigs/store.go b/internal/testing/provider/targetconfigs/store.go new file mode 100644 index 0000000000..9c40b2be58 --- /dev/null +++ b/internal/testing/provider/targetconfigs/store.go @@ -0,0 +1,80 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfigs + +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/provider" +) + +type InMemoryTargetConfigStore struct { + targetConfigs map[string]*provider.TargetConfig +} + +func NewInMemoryTargetConfigStore() provider.TargetConfigStore { + return &InMemoryTargetConfigStore{ + targetConfigs: make(map[string]*provider.TargetConfig), + } +} + +func (s *InMemoryTargetConfigStore) List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { + return s.processFilters(filter) +} + +func (s *InMemoryTargetConfigStore) Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) { + targetConfigs, err := s.processFilters(filter) + if err != nil { + return nil, err + } + if len(targetConfigs) == 0 { + return nil, provider.ErrTargetConfigNotFound + } + + return targetConfigs[0], nil +} + +func (s *InMemoryTargetConfigStore) Save(targetConfig *provider.TargetConfig) error { + s.targetConfigs[targetConfig.Name] = targetConfig + return nil +} + +func (s *InMemoryTargetConfigStore) Delete(targetConfig *provider.TargetConfig) error { + delete(s.targetConfigs, targetConfig.Name) + return nil +} + +func (s *InMemoryTargetConfigStore) processFilters(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { + var result []*provider.TargetConfig + targetConfigs := make(map[string]*provider.TargetConfig) + for k, v := range s.targetConfigs { + targetConfigs[k] = v + } + + if filter != nil { + if filter.Name != nil { + targetConfig, ok := s.targetConfigs[*filter.Name] + if ok { + return []*provider.TargetConfig{targetConfig}, nil + } else { + return []*provider.TargetConfig{}, fmt.Errorf("target config with name %s not found", *filter.Name) + } + } + if filter.Default != nil { + for _, targetConfig := range targetConfigs { + if targetConfig.IsDefault != *filter.Default { + delete(targetConfigs, targetConfig.Name) + } + } + } + } + + for _, targetConfig := range targetConfigs { + result = append(result, targetConfig) + } + + return result, nil +} diff --git a/internal/testing/provider/targets/store.go b/internal/testing/provider/targets/store.go deleted file mode 100644 index 160089e340..0000000000 --- a/internal/testing/provider/targets/store.go +++ /dev/null @@ -1,80 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package targets - -import ( - "fmt" - - "github.com/daytonaio/daytona/pkg/provider" -) - -type InMemoryTargetStore struct { - targets map[string]*provider.ProviderTarget -} - -func NewInMemoryTargetStore() provider.TargetStore { - return &InMemoryTargetStore{ - targets: make(map[string]*provider.ProviderTarget), - } -} - -func (s *InMemoryTargetStore) List(filter *provider.TargetFilter) ([]*provider.ProviderTarget, error) { - return s.processFilters(filter) -} - -func (s *InMemoryTargetStore) Find(filter *provider.TargetFilter) (*provider.ProviderTarget, error) { - targets, err := s.processFilters(filter) - if err != nil { - return nil, err - } - if len(targets) == 0 { - return nil, provider.ErrTargetNotFound - } - - return targets[0], nil -} - -func (s *InMemoryTargetStore) Save(target *provider.ProviderTarget) error { - s.targets[target.Name] = target - return nil -} - -func (s *InMemoryTargetStore) Delete(target *provider.ProviderTarget) error { - delete(s.targets, target.Name) - return nil -} - -func (s *InMemoryTargetStore) processFilters(filter *provider.TargetFilter) ([]*provider.ProviderTarget, error) { - var result []*provider.ProviderTarget - filteredTargets := make(map[string]*provider.ProviderTarget) - for k, v := range s.targets { - filteredTargets[k] = v - } - - if filter != nil { - if filter.Name != nil { - target, ok := s.targets[*filter.Name] - if ok { - return []*provider.ProviderTarget{target}, nil - } else { - return []*provider.ProviderTarget{}, fmt.Errorf("target with name %s not found", *filter.Name) - } - } - if filter.Default != nil { - for _, target := range filteredTargets { - if target.IsDefault != *filter.Default { - delete(filteredTargets, target.Name) - } - } - } - } - - for _, target := range filteredTargets { - result = append(result, target) - } - - return result, nil -} diff --git a/internal/testing/server/workspaces/mocks/provisioner.go b/internal/testing/server/workspaces/mocks/provisioner.go index 11e84f7640..e4567f58df 100644 --- a/internal/testing/server/workspaces/mocks/provisioner.go +++ b/internal/testing/server/workspaces/mocks/provisioner.go @@ -28,23 +28,23 @@ func (p *mockProvisioner) CreateProject(params provisioner.ProjectParams) error return args.Error(0) } -func (p *mockProvisioner) CreateWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - args := p.Called(workspace, target) +func (p *mockProvisioner) CreateWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + args := p.Called(workspace, targetConfig) return args.Error(0) } -func (p *mockProvisioner) DestroyProject(proj *project.Project, target *provider.ProviderTarget) error { - args := p.Called(proj, target) +func (p *mockProvisioner) DestroyProject(proj *project.Project, targetConfig *provider.TargetConfig) error { + args := p.Called(proj, targetConfig) return args.Error(0) } -func (p *mockProvisioner) DestroyWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - args := p.Called(workspace, target) +func (p *mockProvisioner) DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + args := p.Called(workspace, targetConfig) return args.Error(0) } -func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, target *provider.ProviderTarget) (*workspace.WorkspaceInfo, error) { - args := p.Called(ctx, w, target) +func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { + args := p.Called(ctx, w, targetConfig) return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) } @@ -53,17 +53,17 @@ func (p *mockProvisioner) StartProject(params provisioner.ProjectParams) error { return args.Error(0) } -func (p *mockProvisioner) StartWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - args := p.Called(workspace, target) +func (p *mockProvisioner) StartWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + args := p.Called(workspace, targetConfig) return args.Error(0) } -func (p *mockProvisioner) StopProject(proj *project.Project, target *provider.ProviderTarget) error { - args := p.Called(proj, target) +func (p *mockProvisioner) StopProject(proj *project.Project, targetConfig *provider.TargetConfig) error { + args := p.Called(proj, targetConfig) return args.Error(0) } -func (p *mockProvisioner) StopWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - args := p.Called(workspace, target) +func (p *mockProvisioner) StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + args := p.Called(workspace, targetConfig) return args.Error(0) } diff --git a/internal/util/apiclient/conversion/project.go b/internal/util/apiclient/conversion/project.go index db1283b6d7..d7290b1061 100644 --- a/internal/util/apiclient/conversion/project.go +++ b/internal/util/apiclient/conversion/project.go @@ -55,7 +55,7 @@ func ToProject(projectDTO *apiclient.Project) *project.Project { User: projectDTO.User, BuildConfig: projectBuild, Repository: repository, - Target: projectDTO.Target, + TargetConfig: projectDTO.TargetConfig, WorkspaceId: projectDTO.WorkspaceId, State: projectState, GitProviderConfigId: projectDTO.GitProviderConfigId, diff --git a/internal/util/apiclient/conversion/target.go b/internal/util/apiclient/conversion/target.go deleted file mode 100644 index 2ad2ba2f33..0000000000 --- a/internal/util/apiclient/conversion/target.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package conversion - -import ( - "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/server/providertargets/dto" -) - -func ToProviderTarget(createProviderTargetDto dto.CreateProviderTargetDTO) *provider.ProviderTarget { - return &provider.ProviderTarget{ - Name: createProviderTargetDto.Name, - ProviderInfo: createProviderTargetDto.ProviderInfo, - Options: createProviderTargetDto.Options, - } -} diff --git a/internal/util/apiclient/conversion/target_config.go b/internal/util/apiclient/conversion/target_config.go new file mode 100644 index 0000000000..cf7f646de0 --- /dev/null +++ b/internal/util/apiclient/conversion/target_config.go @@ -0,0 +1,17 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package conversion + +import ( + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" +) + +func ToTargetConfig(createTargetConfigDto dto.CreateTargetConfigDTO) *provider.TargetConfig { + return &provider.TargetConfig{ + Name: createTargetConfigDto.Name, + ProviderInfo: createTargetConfigDto.ProviderInfo, + Options: createTargetConfigDto.Options, + } +} diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 9b1cf49fca..472fcd94a0 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -27,8 +27,8 @@ var project1 = &project.Project{ Url: "https://github.com/daytonaio/daytona", Name: "daytona", }, - WorkspaceId: "123", - Target: "local", + WorkspaceId: "123", + TargetConfig: "local", State: &project.ProjectState{ UpdatedAt: "123", Uptime: 148, @@ -37,9 +37,9 @@ var project1 = &project.Project{ } var workspace1 = &workspace.Workspace{ - Id: "123", - Name: "test", - Target: "local", + Id: "123", + Name: "test", + TargetConfig: "local", Projects: []*project.Project{ project1, }, diff --git a/pkg/api/controllers/provider/targets.go b/pkg/api/controllers/provider/target_config.go similarity index 65% rename from pkg/api/controllers/provider/targets.go rename to pkg/api/controllers/provider/target_config.go index 173a6e7463..4b43d146c8 100644 --- a/pkg/api/controllers/provider/targets.go +++ b/pkg/api/controllers/provider/target_config.go @@ -11,18 +11,18 @@ import ( "github.com/gin-gonic/gin" ) -// GetTargetManifest godoc +// GetTargetConfigManifest godoc // // @Tags provider -// @Summary Get provider target manifest -// @Description Get provider target manifest +// @Summary Get provider target config manifest +// @Description Get provider target config manifest // @Param provider path string true "Provider name" // @Success 200 -// @Success 200 {object} ProviderTargetManifest -// @Router /provider/{provider}/target-manifest [get] +// @Success 200 {object} TargetConfigManifest +// @Router /provider/{provider}/target-config-manifest [get] // -// @id GetTargetManifest -func GetTargetManifest(ctx *gin.Context) { +// @id GetTargetConfigManifest +func GetTargetConfigManifest(ctx *gin.Context) { providerName := ctx.Param("provider") server := server.GetInstance(nil) @@ -33,7 +33,7 @@ func GetTargetManifest(ctx *gin.Context) { return } - manifest, err := (*p).GetTargetManifest() + manifest, err := (*p).GetTargetConfigManifest() if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get provider manifest: %w", err)) return diff --git a/pkg/api/controllers/target/list.go b/pkg/api/controllers/target/list.go deleted file mode 100644 index 6a8a55726d..0000000000 --- a/pkg/api/controllers/target/list.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// ListTargets godoc -// -// @Tags target -// @Summary List targets -// @Description List targets -// @Produce json -// @Success 200 {array} ProviderTarget -// @Router /target [get] -// -// @id ListTargets -func ListTargets(ctx *gin.Context) { - server := server.GetInstance(nil) - - targets, err := server.ProviderTargetService.List(nil) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list targets: %w", err)) - return - } - - for _, target := range targets { - p, err := server.ProviderManager.GetProvider(target.ProviderInfo.Name) - if err != nil { - target.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - manifest, err := (*p).GetTargetManifest() - if err != nil { - target.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - var opts map[string]interface{} - err = json.Unmarshal([]byte(target.Options), &opts) - if err != nil { - target.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - for name, property := range *manifest { - if property.InputMasked { - delete(opts, name) - } - } - - updatedOptions, err := json.MarshalIndent(opts, "", " ") - if err != nil { - target.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - target.Options = string(updatedOptions) - } - - ctx.JSON(200, targets) -} diff --git a/pkg/api/controllers/target/remove.go b/pkg/api/controllers/target/remove.go deleted file mode 100644 index dcf61ea6ce..0000000000 --- a/pkg/api/controllers/target/remove.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// RemoveTarget godoc -// -// @Tags target -// @Summary Remove a target -// @Description Remove a target -// @Param target path string true "Target name" -// @Success 204 -// @Router /target/{target} [delete] -// -// @id RemoveTarget -func RemoveTarget(ctx *gin.Context) { - targetName := ctx.Param("target") - - server := server.GetInstance(nil) - - target, err := server.ProviderTargetService.Find(&provider.TargetFilter{ - Name: &targetName, - }) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find target: %w", err)) - return - } - - err = server.ProviderTargetService.Delete(target) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target: %w", err)) - return - } - - ctx.Status(204) -} diff --git a/pkg/api/controllers/target/set.go b/pkg/api/controllers/target/set.go deleted file mode 100644 index 93b681f23e..0000000000 --- a/pkg/api/controllers/target/set.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" - "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/providertargets/dto" - "github.com/gin-gonic/gin" -) - -// SetTarget godoc -// -// @Tags target -// @Summary Set a target -// @Description Set a target -// @Param target body CreateProviderTargetDTO true "Target to set" -// @Success 201 -// @Router /target [put] -// -// @id SetTarget -func SetTarget(ctx *gin.Context) { - var req dto.CreateProviderTargetDTO - err := ctx.BindJSON(&req) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - - target := conversion.ToProviderTarget(req) - - err = server.ProviderTargetService.Save(target) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target: %w", err)) - return - } - - ctx.Status(201) -} - -// SetDefaultTarget godoc -// -// @Tags target -// @Summary Set target to default -// @Description Set target to default -// @Param target path string true "Target name" -// @Success 200 -// @Router /target/{target}/set-default [patch] -// -// @id SetDefaultTarget -func SetDefaultTarget(ctx *gin.Context) { - targetName := ctx.Param("target") - - server := server.GetInstance(nil) - - target, err := server.ProviderTargetService.Find(&provider.TargetFilter{ - Name: &targetName, - }) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find target: %w", err)) - return - } - - err = server.ProviderTargetService.SetDefault(target) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set project config to default: %s", err.Error())) - return - } - - ctx.Status(200) -} diff --git a/pkg/api/controllers/targetconfig/list.go b/pkg/api/controllers/targetconfig/list.go new file mode 100644 index 0000000000..86bbdd063e --- /dev/null +++ b/pkg/api/controllers/targetconfig/list.go @@ -0,0 +1,70 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfig + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// ListTargetConfigs godoc +// +// @Tags target-config +// @Summary List target configs +// @Description List target configs +// @Produce json +// @Success 200 {array} TargetConfig +// @Router /target-config [get] +// +// @id ListTargetConfigs +func ListTargetConfigs(ctx *gin.Context) { + server := server.GetInstance(nil) + + targetConfigs, err := server.TargetConfigService.List(nil) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list target configs: %w", err)) + return + } + + for _, targetConfig := range targetConfigs { + p, err := server.ProviderManager.GetProvider(targetConfig.ProviderInfo.Name) + if err != nil { + targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) + continue + } + + manifest, err := (*p).GetTargetConfigManifest() + if err != nil { + targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) + continue + } + + var opts map[string]interface{} + err = json.Unmarshal([]byte(targetConfig.Options), &opts) + if err != nil { + targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) + continue + } + + for name, property := range *manifest { + if property.InputMasked { + delete(opts, name) + } + } + + updatedOptions, err := json.MarshalIndent(opts, "", " ") + if err != nil { + targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) + continue + } + + targetConfig.Options = string(updatedOptions) + } + + ctx.JSON(200, targetConfigs) +} diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/remove.go new file mode 100644 index 0000000000..bd00fba0a2 --- /dev/null +++ b/pkg/api/controllers/targetconfig/remove.go @@ -0,0 +1,45 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfig + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// RemoveTargetConfig godoc +// +// @Tags target-config +// @Summary Remove a target config +// @Description Remove a target config +// @Param configName path string true "Target Config name" +// @Success 204 +// @Router /target-config/{configName} [delete] +// +// @id RemoveTargetConfig +func RemoveTargetConfig(ctx *gin.Context) { + configName := ctx.Param("configName") + + server := server.GetInstance(nil) + + targetConfig, err := server.TargetConfigService.Find(&provider.TargetConfigFilter{ + Name: &configName, + }) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find target config: %w", err)) + return + } + + err = server.TargetConfigService.Delete(targetConfig) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target config: %w", err)) + return + } + + ctx.Status(204) +} diff --git a/pkg/api/controllers/targetconfig/set.go b/pkg/api/controllers/targetconfig/set.go new file mode 100644 index 0000000000..063cdeed9f --- /dev/null +++ b/pkg/api/controllers/targetconfig/set.go @@ -0,0 +1,78 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfig + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" + "github.com/gin-gonic/gin" +) + +// SetTargetConfig godoc +// +// @Tags target-config +// @Summary Set a target config +// @Description Set a target config +// @Param targetConfig body CreateTargetConfigDTO true "Target config to set" +// @Success 201 +// @Router /target-config [put] +// +// @id SetTargetConfig +func SetTargetConfig(ctx *gin.Context) { + var req dto.CreateTargetConfigDTO + err := ctx.BindJSON(&req) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + targetConfig := conversion.ToTargetConfig(req) + + err = server.TargetConfigService.Save(targetConfig) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target config: %w", err)) + return + } + + ctx.Status(201) +} + +// SetDefaultTargetConfig godoc +// +// @Tags target-config +// @Summary Set target config to default +// @Description Set target config to default +// @Param configName path string true "Target config name" +// @Success 200 +// @Router /target-config/{configName}/set-default [patch] +// +// @id SetDefaultTargetConfig +func SetDefaultTargetConfig(ctx *gin.Context) { + configName := ctx.Param("configName") + + server := server.GetInstance(nil) + + targetConfig, err := server.TargetConfigService.Find(&provider.TargetConfigFilter{ + Name: &configName, + }) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find target config: %w", err)) + return + } + + err = server.TargetConfigService.SetDefault(targetConfig) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set target config to default: %s", err.Error())) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index fa9765d94f..e33828f245 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1332,14 +1332,14 @@ const docTemplate = `{ } } }, - "/provider/{provider}/target-manifest": { + "/provider/{provider}/target-config-manifest": { "get": { - "description": "Get provider target manifest", + "description": "Get provider target config manifest", "tags": [ "provider" ], - "summary": "Get provider target manifest", - "operationId": "GetTargetManifest", + "summary": "Get provider target config manifest", + "operationId": "GetTargetConfigManifest", "parameters": [ { "type": "string", @@ -1353,7 +1353,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProviderTargetManifest" + "$ref": "#/definitions/TargetConfigManifest" } } } @@ -1509,44 +1509,44 @@ const docTemplate = `{ } } }, - "/target": { + "/target-config": { "get": { - "description": "List targets", + "description": "List target configs", "produces": [ "application/json" ], "tags": [ - "target" + "target-config" ], - "summary": "List targets", - "operationId": "ListTargets", + "summary": "List target configs", + "operationId": "ListTargetConfigs", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/ProviderTarget" + "$ref": "#/definitions/TargetConfig" } } } } }, "put": { - "description": "Set a target", + "description": "Set a target config", "tags": [ - "target" + "target-config" ], - "summary": "Set a target", - "operationId": "SetTarget", + "summary": "Set a target config", + "operationId": "SetTargetConfig", "parameters": [ { - "description": "Target to set", - "name": "target", + "description": "Target config to set", + "name": "targetConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateProviderTargetDTO" + "$ref": "#/definitions/CreateTargetConfigDTO" } } ], @@ -1557,19 +1557,19 @@ const docTemplate = `{ } } }, - "/target/{target}": { + "/target-config/{configName}": { "delete": { - "description": "Remove a target", + "description": "Remove a target config", "tags": [ - "target" + "target-config" ], - "summary": "Remove a target", - "operationId": "RemoveTarget", + "summary": "Remove a target config", + "operationId": "RemoveTargetConfig", "parameters": [ { "type": "string", - "description": "Target name", - "name": "target", + "description": "Target Config name", + "name": "configName", "in": "path", "required": true } @@ -1581,19 +1581,19 @@ const docTemplate = `{ } } }, - "/target/{target}/set-default": { + "/target-config/{configName}/set-default": { "patch": { - "description": "Set target to default", + "description": "Set target config to default", "tags": [ - "target" + "target-config" ], - "summary": "Set target to default", - "operationId": "SetDefaultTarget", + "summary": "Set target config to default", + "operationId": "SetDefaultTargetConfig", "parameters": [ { "type": "string", - "description": "Target name", - "name": "target", + "description": "Target config name", + "name": "configName", "in": "path", "required": true } @@ -3802,7 +3802,18 @@ const docTemplate = `{ } } }, - "CreateProviderTargetDTO": { + "CreateSessionRequest": { + "type": "object", + "required": [ + "sessionId" + ], + "properties": { + "sessionId": { + "type": "string" + } + } + }, + "CreateTargetConfigDTO": { "type": "object", "required": [ "name", @@ -3821,24 +3832,13 @@ const docTemplate = `{ } } }, - "CreateSessionRequest": { - "type": "object", - "required": [ - "sessionId" - ], - "properties": { - "sessionId": { - "type": "string" - } - } - }, "CreateWorkspaceDTO": { "type": "object", "required": [ "id", "name", "projects", - "target" + "targetConfig" ], "properties": { "id": { @@ -3853,7 +3853,7 @@ const docTemplate = `{ "$ref": "#/definitions/CreateProjectDTO" } }, - "target": { + "targetConfig": { "type": "string" } } @@ -4662,7 +4662,7 @@ const docTemplate = `{ "image", "name", "repository", - "target", + "targetConfig", "user", "workspaceId" ], @@ -4691,7 +4691,7 @@ const docTemplate = `{ "state": { "$ref": "#/definitions/ProjectState" }, - "target": { + "targetConfig": { "type": "string" }, "user": { @@ -4818,36 +4818,6 @@ const docTemplate = `{ } } }, - "ProviderTarget": { - "type": "object", - "required": [ - "isDefault", - "name", - "options", - "providerInfo" - ], - "properties": { - "isDefault": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "options": { - "description": "JSON encoded map of options", - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" - } - } - }, - "ProviderTargetManifest": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/provider.ProviderTargetProperty" - } - }, "ReplaceRequest": { "type": "object", "required": [ @@ -5127,13 +5097,80 @@ const docTemplate = `{ "UpdatedButUnmerged" ] }, + "TargetConfig": { + "type": "object", + "required": [ + "isDefault", + "name", + "options", + "providerInfo" + ], + "properties": { + "isDefault": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "options": { + "description": "JSON encoded map of options", + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/provider.ProviderInfo" + } + } + }, + "TargetConfigManifest": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/TargetConfigProperty" + } + }, + "TargetConfigProperty": { + "type": "object", + "properties": { + "defaultValue": { + "description": "DefaultValue is converted into the appropriate type based on the Type\nIf the property is a FilePath, the DefaultValue is a path to a directory", + "type": "string" + }, + "description": { + "description": "Brief description of the property", + "type": "string" + }, + "disabledPredicate": { + "description": "A regex string matched with the name of the target config to determine if the property should be disabled\nIf the regex matches the target config name, the property will be disabled\nE.g. \"^local$\" will disable the property for the local target", + "type": "string" + }, + "inputMasked": { + "type": "boolean" + }, + "options": { + "description": "Options is only used if the Type is TargetConfigPropertyTypeOption", + "type": "array", + "items": { + "type": "string" + } + }, + "suggestions": { + "description": "Suggestions is an optional list of auto-complete values to assist the user while filling the field", + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "$ref": "#/definitions/provider.TargetConfigPropertyType" + } + } + }, "Workspace": { "type": "object", "required": [ "id", "name", "projects", - "target" + "targetConfig" ], "properties": { "id": { @@ -5148,7 +5185,7 @@ const docTemplate = `{ "$ref": "#/definitions/Project" } }, - "target": { + "targetConfig": { "type": "string" } } @@ -5159,7 +5196,7 @@ const docTemplate = `{ "id", "name", "projects", - "target" + "targetConfig" ], "properties": { "id": { @@ -5177,7 +5214,7 @@ const docTemplate = `{ "$ref": "#/definitions/Project" } }, - "target": { + "targetConfig": { "type": "string" } } @@ -5257,44 +5294,7 @@ const docTemplate = `{ } } }, - "provider.ProviderTargetProperty": { - "type": "object", - "properties": { - "defaultValue": { - "description": "DefaultValue is converted into the appropriate type based on the Type\nIf the property is a FilePath, the DefaultValue is a path to a directory", - "type": "string" - }, - "description": { - "description": "Brief description of the property", - "type": "string" - }, - "disabledPredicate": { - "description": "A regex string matched with the name of the target to determine if the property should be disabled\nIf the regex matches the target name, the property will be disabled\nE.g. \"^local$\" will disable the property for the local target", - "type": "string" - }, - "inputMasked": { - "type": "boolean" - }, - "options": { - "description": "Options is only used if the Type is ProviderTargetPropertyTypeOption", - "type": "array", - "items": { - "type": "string" - } - }, - "suggestions": { - "description": "Suggestions is an optional list of auto-complete values to assist the user while filling the field", - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "$ref": "#/definitions/provider.ProviderTargetPropertyType" - } - } - }, - "provider.ProviderTargetPropertyType": { + "provider.TargetConfigPropertyType": { "type": "string", "enum": [ "string", @@ -5305,12 +5305,12 @@ const docTemplate = `{ "file-path" ], "x-enum-varnames": [ - "ProviderTargetPropertyTypeString", - "ProviderTargetPropertyTypeOption", - "ProviderTargetPropertyTypeBoolean", - "ProviderTargetPropertyTypeInt", - "ProviderTargetPropertyTypeFloat", - "ProviderTargetPropertyTypeFilePath" + "TargetConfigPropertyTypeString", + "TargetConfigPropertyTypeOption", + "TargetConfigPropertyTypeBoolean", + "TargetConfigPropertyTypeInt", + "TargetConfigPropertyTypeFloat", + "TargetConfigPropertyTypeFilePath" ] } }, diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 868ccdda88..99c99ea854 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1329,14 +1329,14 @@ } } }, - "/provider/{provider}/target-manifest": { + "/provider/{provider}/target-config-manifest": { "get": { - "description": "Get provider target manifest", + "description": "Get provider target config manifest", "tags": [ "provider" ], - "summary": "Get provider target manifest", - "operationId": "GetTargetManifest", + "summary": "Get provider target config manifest", + "operationId": "GetTargetConfigManifest", "parameters": [ { "type": "string", @@ -1350,7 +1350,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProviderTargetManifest" + "$ref": "#/definitions/TargetConfigManifest" } } } @@ -1506,44 +1506,44 @@ } } }, - "/target": { + "/target-config": { "get": { - "description": "List targets", + "description": "List target configs", "produces": [ "application/json" ], "tags": [ - "target" + "target-config" ], - "summary": "List targets", - "operationId": "ListTargets", + "summary": "List target configs", + "operationId": "ListTargetConfigs", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/ProviderTarget" + "$ref": "#/definitions/TargetConfig" } } } } }, "put": { - "description": "Set a target", + "description": "Set a target config", "tags": [ - "target" + "target-config" ], - "summary": "Set a target", - "operationId": "SetTarget", + "summary": "Set a target config", + "operationId": "SetTargetConfig", "parameters": [ { - "description": "Target to set", - "name": "target", + "description": "Target config to set", + "name": "targetConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateProviderTargetDTO" + "$ref": "#/definitions/CreateTargetConfigDTO" } } ], @@ -1554,19 +1554,19 @@ } } }, - "/target/{target}": { + "/target-config/{configName}": { "delete": { - "description": "Remove a target", + "description": "Remove a target config", "tags": [ - "target" + "target-config" ], - "summary": "Remove a target", - "operationId": "RemoveTarget", + "summary": "Remove a target config", + "operationId": "RemoveTargetConfig", "parameters": [ { "type": "string", - "description": "Target name", - "name": "target", + "description": "Target Config name", + "name": "configName", "in": "path", "required": true } @@ -1578,19 +1578,19 @@ } } }, - "/target/{target}/set-default": { + "/target-config/{configName}/set-default": { "patch": { - "description": "Set target to default", + "description": "Set target config to default", "tags": [ - "target" + "target-config" ], - "summary": "Set target to default", - "operationId": "SetDefaultTarget", + "summary": "Set target config to default", + "operationId": "SetDefaultTargetConfig", "parameters": [ { "type": "string", - "description": "Target name", - "name": "target", + "description": "Target config name", + "name": "configName", "in": "path", "required": true } @@ -3799,7 +3799,18 @@ } } }, - "CreateProviderTargetDTO": { + "CreateSessionRequest": { + "type": "object", + "required": [ + "sessionId" + ], + "properties": { + "sessionId": { + "type": "string" + } + } + }, + "CreateTargetConfigDTO": { "type": "object", "required": [ "name", @@ -3818,24 +3829,13 @@ } } }, - "CreateSessionRequest": { - "type": "object", - "required": [ - "sessionId" - ], - "properties": { - "sessionId": { - "type": "string" - } - } - }, "CreateWorkspaceDTO": { "type": "object", "required": [ "id", "name", "projects", - "target" + "targetConfig" ], "properties": { "id": { @@ -3850,7 +3850,7 @@ "$ref": "#/definitions/CreateProjectDTO" } }, - "target": { + "targetConfig": { "type": "string" } } @@ -4659,7 +4659,7 @@ "image", "name", "repository", - "target", + "targetConfig", "user", "workspaceId" ], @@ -4688,7 +4688,7 @@ "state": { "$ref": "#/definitions/ProjectState" }, - "target": { + "targetConfig": { "type": "string" }, "user": { @@ -4815,36 +4815,6 @@ } } }, - "ProviderTarget": { - "type": "object", - "required": [ - "isDefault", - "name", - "options", - "providerInfo" - ], - "properties": { - "isDefault": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "options": { - "description": "JSON encoded map of options", - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" - } - } - }, - "ProviderTargetManifest": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/provider.ProviderTargetProperty" - } - }, "ReplaceRequest": { "type": "object", "required": [ @@ -5124,13 +5094,80 @@ "UpdatedButUnmerged" ] }, + "TargetConfig": { + "type": "object", + "required": [ + "isDefault", + "name", + "options", + "providerInfo" + ], + "properties": { + "isDefault": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "options": { + "description": "JSON encoded map of options", + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/provider.ProviderInfo" + } + } + }, + "TargetConfigManifest": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/TargetConfigProperty" + } + }, + "TargetConfigProperty": { + "type": "object", + "properties": { + "defaultValue": { + "description": "DefaultValue is converted into the appropriate type based on the Type\nIf the property is a FilePath, the DefaultValue is a path to a directory", + "type": "string" + }, + "description": { + "description": "Brief description of the property", + "type": "string" + }, + "disabledPredicate": { + "description": "A regex string matched with the name of the target config to determine if the property should be disabled\nIf the regex matches the target config name, the property will be disabled\nE.g. \"^local$\" will disable the property for the local target", + "type": "string" + }, + "inputMasked": { + "type": "boolean" + }, + "options": { + "description": "Options is only used if the Type is TargetConfigPropertyTypeOption", + "type": "array", + "items": { + "type": "string" + } + }, + "suggestions": { + "description": "Suggestions is an optional list of auto-complete values to assist the user while filling the field", + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "$ref": "#/definitions/provider.TargetConfigPropertyType" + } + } + }, "Workspace": { "type": "object", "required": [ "id", "name", "projects", - "target" + "targetConfig" ], "properties": { "id": { @@ -5145,7 +5182,7 @@ "$ref": "#/definitions/Project" } }, - "target": { + "targetConfig": { "type": "string" } } @@ -5156,7 +5193,7 @@ "id", "name", "projects", - "target" + "targetConfig" ], "properties": { "id": { @@ -5174,7 +5211,7 @@ "$ref": "#/definitions/Project" } }, - "target": { + "targetConfig": { "type": "string" } } @@ -5254,44 +5291,7 @@ } } }, - "provider.ProviderTargetProperty": { - "type": "object", - "properties": { - "defaultValue": { - "description": "DefaultValue is converted into the appropriate type based on the Type\nIf the property is a FilePath, the DefaultValue is a path to a directory", - "type": "string" - }, - "description": { - "description": "Brief description of the property", - "type": "string" - }, - "disabledPredicate": { - "description": "A regex string matched with the name of the target to determine if the property should be disabled\nIf the regex matches the target name, the property will be disabled\nE.g. \"^local$\" will disable the property for the local target", - "type": "string" - }, - "inputMasked": { - "type": "boolean" - }, - "options": { - "description": "Options is only used if the Type is ProviderTargetPropertyTypeOption", - "type": "array", - "items": { - "type": "string" - } - }, - "suggestions": { - "description": "Suggestions is an optional list of auto-complete values to assist the user while filling the field", - "type": "array", - "items": { - "type": "string" - } - }, - "type": { - "$ref": "#/definitions/provider.ProviderTargetPropertyType" - } - } - }, - "provider.ProviderTargetPropertyType": { + "provider.TargetConfigPropertyType": { "type": "string", "enum": [ "string", @@ -5302,12 +5302,12 @@ "file-path" ], "x-enum-varnames": [ - "ProviderTargetPropertyTypeString", - "ProviderTargetPropertyTypeOption", - "ProviderTargetPropertyTypeBoolean", - "ProviderTargetPropertyTypeInt", - "ProviderTargetPropertyTypeFloat", - "ProviderTargetPropertyTypeFilePath" + "TargetConfigPropertyTypeString", + "TargetConfigPropertyTypeOption", + "TargetConfigPropertyTypeBoolean", + "TargetConfigPropertyTypeInt", + "TargetConfigPropertyTypeFloat", + "TargetConfigPropertyTypeFilePath" ] } }, diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 61df4a4a14..17ace20c20 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -236,7 +236,14 @@ definitions: required: - repository type: object - CreateProviderTargetDTO: + CreateSessionRequest: + properties: + sessionId: + type: string + required: + - sessionId + type: object + CreateTargetConfigDTO: properties: name: type: string @@ -249,13 +256,6 @@ definitions: - options - providerInfo type: object - CreateSessionRequest: - properties: - sessionId: - type: string - required: - - sessionId - type: object CreateWorkspaceDTO: properties: id: @@ -266,13 +266,13 @@ definitions: items: $ref: '#/definitions/CreateProjectDTO' type: array - target: + targetConfig: type: string required: - id - name - projects - - target + - targetConfig type: object DevcontainerConfig: properties: @@ -835,7 +835,7 @@ definitions: $ref: '#/definitions/GitRepository' state: $ref: '#/definitions/ProjectState' - target: + targetConfig: type: string user: type: string @@ -846,7 +846,7 @@ definitions: - image - name - repository - - target + - targetConfig - user - workspaceId type: object @@ -929,27 +929,6 @@ definitions: - name - version type: object - ProviderTarget: - properties: - isDefault: - type: boolean - name: - type: string - options: - description: JSON encoded map of options - type: string - providerInfo: - $ref: '#/definitions/provider.ProviderInfo' - required: - - isDefault - - name - - options - - providerInfo - type: object - ProviderTargetManifest: - additionalProperties: - $ref: '#/definitions/provider.ProviderTargetProperty' - type: object ReplaceRequest: properties: files: @@ -1144,6 +1123,59 @@ definitions: - Renamed - Copied - UpdatedButUnmerged + TargetConfig: + properties: + isDefault: + type: boolean + name: + type: string + options: + description: JSON encoded map of options + type: string + providerInfo: + $ref: '#/definitions/provider.ProviderInfo' + required: + - isDefault + - name + - options + - providerInfo + type: object + TargetConfigManifest: + additionalProperties: + $ref: '#/definitions/TargetConfigProperty' + type: object + TargetConfigProperty: + properties: + defaultValue: + description: |- + DefaultValue is converted into the appropriate type based on the Type + If the property is a FilePath, the DefaultValue is a path to a directory + type: string + description: + description: Brief description of the property + type: string + disabledPredicate: + description: |- + A regex string matched with the name of the target config to determine if the property should be disabled + If the regex matches the target config name, the property will be disabled + E.g. "^local$" will disable the property for the local target + type: string + inputMasked: + type: boolean + options: + description: Options is only used if the Type is TargetConfigPropertyTypeOption + items: + type: string + type: array + suggestions: + description: Suggestions is an optional list of auto-complete values to assist + the user while filling the field + items: + type: string + type: array + type: + $ref: '#/definitions/provider.TargetConfigPropertyType' + type: object Workspace: properties: id: @@ -1154,13 +1186,13 @@ definitions: items: $ref: '#/definitions/Project' type: array - target: + targetConfig: type: string required: - id - name - projects - - target + - targetConfig type: object WorkspaceDTO: properties: @@ -1174,13 +1206,13 @@ definitions: items: $ref: '#/definitions/Project' type: array - target: + targetConfig: type: string required: - id - name - projects - - target + - targetConfig type: object WorkspaceInfo: properties: @@ -1238,39 +1270,7 @@ definitions: - name - version type: object - provider.ProviderTargetProperty: - properties: - defaultValue: - description: |- - DefaultValue is converted into the appropriate type based on the Type - If the property is a FilePath, the DefaultValue is a path to a directory - type: string - description: - description: Brief description of the property - type: string - disabledPredicate: - description: |- - A regex string matched with the name of the target to determine if the property should be disabled - If the regex matches the target name, the property will be disabled - E.g. "^local$" will disable the property for the local target - type: string - inputMasked: - type: boolean - options: - description: Options is only used if the Type is ProviderTargetPropertyTypeOption - items: - type: string - type: array - suggestions: - description: Suggestions is an optional list of auto-complete values to assist - the user while filling the field - items: - type: string - type: array - type: - $ref: '#/definitions/provider.ProviderTargetPropertyType' - type: object - provider.ProviderTargetPropertyType: + provider.TargetConfigPropertyType: enum: - string - option @@ -1280,12 +1280,12 @@ definitions: - file-path type: string x-enum-varnames: - - ProviderTargetPropertyTypeString - - ProviderTargetPropertyTypeOption - - ProviderTargetPropertyTypeBoolean - - ProviderTargetPropertyTypeInt - - ProviderTargetPropertyTypeFloat - - ProviderTargetPropertyTypeFilePath + - TargetConfigPropertyTypeString + - TargetConfigPropertyTypeOption + - TargetConfigPropertyTypeBoolean + - TargetConfigPropertyTypeInt + - TargetConfigPropertyTypeFloat + - TargetConfigPropertyTypeFilePath host: localhost:3986 info: contact: {} @@ -2156,10 +2156,10 @@ paths: summary: List providers tags: - provider - /provider/{provider}/target-manifest: + /provider/{provider}/target-config-manifest: get: - description: Get provider target manifest - operationId: GetTargetManifest + description: Get provider target config manifest + operationId: GetTargetConfigManifest parameters: - description: Provider name in: path @@ -2170,8 +2170,8 @@ paths: "200": description: OK schema: - $ref: '#/definitions/ProviderTargetManifest' - summary: Get provider target manifest + $ref: '#/definitions/TargetConfigManifest' + summary: Get provider target config manifest tags: - provider /provider/{provider}/uninstall: @@ -2293,10 +2293,10 @@ paths: summary: Generate a new authentication key tags: - server - /target: + /target-config: get: - description: List targets - operationId: ListTargets + description: List target configs + operationId: ListTargetConfigs produces: - application/json responses: @@ -2304,59 +2304,59 @@ paths: description: OK schema: items: - $ref: '#/definitions/ProviderTarget' + $ref: '#/definitions/TargetConfig' type: array - summary: List targets + summary: List target configs tags: - - target + - target-config put: - description: Set a target - operationId: SetTarget + description: Set a target config + operationId: SetTargetConfig parameters: - - description: Target to set + - description: Target config to set in: body - name: target + name: targetConfig required: true schema: - $ref: '#/definitions/CreateProviderTargetDTO' + $ref: '#/definitions/CreateTargetConfigDTO' responses: "201": description: Created - summary: Set a target + summary: Set a target config tags: - - target - /target/{target}: + - target-config + /target-config/{configName}: delete: - description: Remove a target - operationId: RemoveTarget + description: Remove a target config + operationId: RemoveTargetConfig parameters: - - description: Target name + - description: Target Config name in: path - name: target + name: configName required: true type: string responses: "204": description: No Content - summary: Remove a target + summary: Remove a target config tags: - - target - /target/{target}/set-default: + - target-config + /target-config/{configName}/set-default: patch: - description: Set target to default - operationId: SetDefaultTarget + description: Set target config to default + operationId: SetDefaultTargetConfig parameters: - - description: Target name + - description: Target config name in: path - name: target + name: configName required: true type: string responses: "200": description: OK - summary: Set target to default + summary: Set target config to default tags: - - target + - target-config /workspace: get: description: List workspaces diff --git a/pkg/api/server.go b/pkg/api/server.go index bc2149fd90..eefbd397c1 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -45,7 +45,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/provider" "github.com/daytonaio/daytona/pkg/api/controllers/sample" "github.com/daytonaio/daytona/pkg/api/controllers/server" - "github.com/daytonaio/daytona/pkg/api/controllers/target" + "github.com/daytonaio/daytona/pkg/api/controllers/targetconfig" "github.com/daytonaio/daytona/pkg/api/controllers/workspace" "github.com/daytonaio/daytona/pkg/api/controllers/workspace/toolbox" @@ -247,7 +247,7 @@ func (a *ApiServer) Start() error { providerController.POST("/install", provider.InstallProvider) providerController.GET("", provider.ListProviders) providerController.POST("/:provider/uninstall", provider.UninstallProvider) - providerController.GET("/:provider/target-manifest", provider.GetTargetManifest) + providerController.GET("/:provider/target-config-manifest", provider.GetTargetConfigManifest) } containerRegistryController := protected.Group("/container-registry") @@ -268,12 +268,12 @@ func (a *ApiServer) Start() error { buildController.DELETE("/prebuild/:prebuildId", build.DeleteBuildsFromPrebuild) } - targetController := protected.Group("/target") + targetConfigController := protected.Group("/target-config") { - targetController.GET("", target.ListTargets) - targetController.PUT("", target.SetTarget) - targetController.PATCH("/:target/set-default", target.SetDefaultTarget) - targetController.DELETE("/:target", target.RemoveTarget) + targetConfigController.GET("", targetconfig.ListTargetConfigs) + targetConfigController.PUT("", targetconfig.SetTargetConfig) + targetConfigController.PATCH("/:configName/set-default", targetconfig.SetDefaultTargetConfig) + targetConfigController.DELETE("/:configName", targetconfig.RemoveTargetConfig) } logController := protected.Group("/log") diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 41fc0b9b3e..177c444d75 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -119,7 +119,7 @@ Class | Method | HTTP request | Description *ProjectConfigAPI* | [**ListProjectConfigs**](docs/ProjectConfigAPI.md#listprojectconfigs) | **Get** /project-config | List project configs *ProjectConfigAPI* | [**SetDefaultProjectConfig**](docs/ProjectConfigAPI.md#setdefaultprojectconfig) | **Patch** /project-config/{configName}/set-default | Set project config to default *ProjectConfigAPI* | [**SetProjectConfig**](docs/ProjectConfigAPI.md#setprojectconfig) | **Put** /project-config | Set project config data -*ProviderAPI* | [**GetTargetManifest**](docs/ProviderAPI.md#gettargetmanifest) | **Get** /provider/{provider}/target-manifest | Get provider target manifest +*ProviderAPI* | [**GetTargetConfigManifest**](docs/ProviderAPI.md#gettargetconfigmanifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest *ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /provider/install | Install a provider *ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /provider | List providers *ProviderAPI* | [**UninstallProvider**](docs/ProviderAPI.md#uninstallprovider) | **Post** /provider/{provider}/uninstall | Uninstall a provider @@ -128,10 +128,10 @@ Class | Method | HTTP request | Description *ServerAPI* | [**GetConfig**](docs/ServerAPI.md#getconfig) | **Get** /server/config | Get the server configuration *ServerAPI* | [**GetServerLogFiles**](docs/ServerAPI.md#getserverlogfiles) | **Get** /server/logs | List server log files *ServerAPI* | [**SetConfig**](docs/ServerAPI.md#setconfig) | **Post** /server/config | Set the server configuration -*TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets -*TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{target} | Remove a target -*TargetAPI* | [**SetDefaultTarget**](docs/TargetAPI.md#setdefaulttarget) | **Patch** /target/{target}/set-default | Set target to default -*TargetAPI* | [**SetTarget**](docs/TargetAPI.md#settarget) | **Put** /target | Set a target +*TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs +*TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configName} | Remove a target config +*TargetConfigAPI* | [**SetDefaultTargetConfig**](docs/TargetConfigAPI.md#setdefaulttargetconfig) | **Patch** /target-config/{configName}/set-default | Set target config to default +*TargetConfigAPI* | [**SetTargetConfig**](docs/TargetConfigAPI.md#settargetconfig) | **Put** /target-config | Set a target config *WorkspaceAPI* | [**CreateWorkspace**](docs/WorkspaceAPI.md#createworkspace) | **Post** /workspace | Create a workspace *WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info *WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces @@ -197,8 +197,8 @@ Class | Method | HTTP request | Description - [CreateProjectConfigDTO](docs/CreateProjectConfigDTO.md) - [CreateProjectDTO](docs/CreateProjectDTO.md) - [CreateProjectSourceDTO](docs/CreateProjectSourceDTO.md) - - [CreateProviderTargetDTO](docs/CreateProviderTargetDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) + - [CreateTargetConfigDTO](docs/CreateTargetConfigDTO.md) - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) - [DevcontainerConfig](docs/DevcontainerConfig.md) - [ExecuteRequest](docs/ExecuteRequest.md) @@ -244,9 +244,7 @@ Class | Method | HTTP request | Description - [ProjectState](docs/ProjectState.md) - [Provider](docs/Provider.md) - [ProviderProviderInfo](docs/ProviderProviderInfo.md) - - [ProviderProviderTargetProperty](docs/ProviderProviderTargetProperty.md) - - [ProviderProviderTargetPropertyType](docs/ProviderProviderTargetPropertyType.md) - - [ProviderTarget](docs/ProviderTarget.md) + - [ProviderTargetConfigPropertyType](docs/ProviderTargetConfigPropertyType.md) - [ReplaceRequest](docs/ReplaceRequest.md) - [ReplaceResult](docs/ReplaceResult.md) - [RepositoryUrl](docs/RepositoryUrl.md) @@ -260,6 +258,8 @@ Class | Method | HTTP request | Description - [SetProjectState](docs/SetProjectState.md) - [SigningMethod](docs/SigningMethod.md) - [Status](docs/Status.md) + - [TargetConfig](docs/TargetConfig.md) + - [TargetConfigProperty](docs/TargetConfigProperty.md) - [Workspace](docs/Workspace.md) - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceInfo](docs/WorkspaceInfo.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index d2e633c0f4..09b0faa58b 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -952,10 +952,10 @@ paths: tags: - provider x-codegen-request-body-name: provider - /provider/{provider}/target-manifest: + /provider/{provider}/target-config-manifest: get: - description: Get provider target manifest - operationId: GetTargetManifest + description: Get provider target config manifest + operationId: GetTargetConfigManifest parameters: - description: Provider name in: path @@ -968,9 +968,9 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/ProviderTargetManifest' + $ref: '#/components/schemas/TargetConfigManifest' description: OK - summary: Get provider target manifest + summary: Get provider target config manifest tags: - provider /provider/{provider}/uninstall: @@ -1072,48 +1072,48 @@ paths: summary: Generate a new authentication key tags: - server - /target: + /target-config: get: - description: List targets - operationId: ListTargets + description: List target configs + operationId: ListTargetConfigs responses: "200": content: application/json: schema: items: - $ref: '#/components/schemas/ProviderTarget' + $ref: '#/components/schemas/TargetConfig' type: array description: OK - summary: List targets + summary: List target configs tags: - - target + - target-config put: - description: Set a target - operationId: SetTarget + description: Set a target config + operationId: SetTargetConfig requestBody: content: '*/*': schema: - $ref: '#/components/schemas/CreateProviderTargetDTO' - description: Target to set + $ref: '#/components/schemas/CreateTargetConfigDTO' + description: Target config to set required: true responses: "201": content: {} description: Created - summary: Set a target + summary: Set a target config tags: - - target - x-codegen-request-body-name: target - /target/{target}: + - target-config + x-codegen-request-body-name: targetConfig + /target-config/{configName}: delete: - description: Remove a target - operationId: RemoveTarget + description: Remove a target config + operationId: RemoveTargetConfig parameters: - - description: Target name + - description: Target Config name in: path - name: target + name: configName required: true schema: type: string @@ -1121,17 +1121,17 @@ paths: "204": content: {} description: No Content - summary: Remove a target + summary: Remove a target config tags: - - target - /target/{target}/set-default: + - target-config + /target-config/{configName}/set-default: patch: - description: Set target to default - operationId: SetDefaultTarget + description: Set target config to default + operationId: SetDefaultTargetConfig parameters: - - description: Target name + - description: Target config name in: path - name: target + name: configName required: true schema: type: string @@ -1139,9 +1139,9 @@ paths: "200": content: {} description: OK - summary: Set target to default + summary: Set target config to default tags: - - target + - target-config /workspace: get: description: List workspaces @@ -2925,7 +2925,16 @@ components: required: - repository type: object - CreateProviderTargetDTO: + CreateSessionRequest: + example: + sessionId: sessionId + properties: + sessionId: + type: string + required: + - sessionId + type: object + CreateTargetConfigDTO: example: name: name options: options @@ -2945,17 +2954,9 @@ components: - options - providerInfo type: object - CreateSessionRequest: - example: - sessionId: sessionId - properties: - sessionId: - type: string - required: - - sessionId - type: object CreateWorkspaceDTO: example: + targetConfig: targetConfig projects: - buildConfig: cachedBuild: @@ -3007,7 +3008,6 @@ components: user: user name: name id: id - target: target properties: id: type: string @@ -3017,13 +3017,13 @@ components: items: $ref: '#/components/schemas/CreateProjectDTO' type: array - target: + targetConfig: type: string required: - id - name - projects - - target + - targetConfig type: object DevcontainerConfig: example: @@ -3791,6 +3791,7 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image + targetConfig: targetConfig envVars: key: envVars name: name @@ -3823,7 +3824,6 @@ components: sha: sha url: url user: user - target: target workspaceId: workspaceId properties: buildConfig: @@ -3842,7 +3842,7 @@ components: $ref: '#/components/schemas/GitRepository' state: $ref: '#/components/schemas/ProjectState' - target: + targetConfig: type: string user: type: string @@ -3853,7 +3853,7 @@ components: - image - name - repository - - target + - targetConfig - user - workspaceId type: object @@ -3995,35 +3995,6 @@ components: - name - version type: object - ProviderTarget: - example: - isDefault: true - name: name - options: options - providerInfo: - name: name - label: label - version: version - properties: - isDefault: - type: boolean - name: - type: string - options: - description: JSON encoded map of options - type: string - providerInfo: - $ref: '#/components/schemas/provider.ProviderInfo' - required: - - isDefault - - name - - options - - providerInfo - type: object - ProviderTargetManifest: - additionalProperties: - $ref: '#/components/schemas/provider.ProviderTargetProperty' - type: object ReplaceRequest: example: newValue: newValue @@ -4306,8 +4277,70 @@ components: - Renamed - Copied - UpdatedButUnmerged + TargetConfig: + example: + isDefault: true + name: name + options: options + providerInfo: + name: name + label: label + version: version + properties: + isDefault: + type: boolean + name: + type: string + options: + description: JSON encoded map of options + type: string + providerInfo: + $ref: '#/components/schemas/provider.ProviderInfo' + required: + - isDefault + - name + - options + - providerInfo + type: object + TargetConfigManifest: + additionalProperties: + $ref: '#/components/schemas/TargetConfigProperty' + type: object + TargetConfigProperty: + properties: + defaultValue: + description: |- + DefaultValue is converted into the appropriate type based on the Type + If the property is a FilePath, the DefaultValue is a path to a directory + type: string + description: + description: Brief description of the property + type: string + disabledPredicate: + description: |- + A regex string matched with the name of the target config to determine if the property should be disabled + If the regex matches the target config name, the property will be disabled + E.g. "^local$" will disable the property for the local target + type: string + inputMasked: + type: boolean + options: + description: Options is only used if the Type is TargetConfigPropertyTypeOption + items: + type: string + type: array + suggestions: + description: Suggestions is an optional list of auto-complete values to + assist the user while filling the field + items: + type: string + type: array + type: + $ref: '#/components/schemas/provider.TargetConfigPropertyType' + type: object Workspace: example: + targetConfig: targetConfig projects: - buildConfig: cachedBuild: @@ -4317,6 +4350,7 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image + targetConfig: targetConfig envVars: key: envVars name: name @@ -4349,7 +4383,6 @@ components: sha: sha url: url user: user - target: target workspaceId: workspaceId - buildConfig: cachedBuild: @@ -4359,6 +4392,7 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image + targetConfig: targetConfig envVars: key: envVars name: name @@ -4391,11 +4425,9 @@ components: sha: sha url: url user: user - target: target workspaceId: workspaceId name: name id: id - target: target properties: id: type: string @@ -4405,16 +4437,17 @@ components: items: $ref: '#/components/schemas/Project' type: array - target: + targetConfig: type: string required: - id - name - projects - - target + - targetConfig type: object WorkspaceDTO: example: + targetConfig: targetConfig projects: - buildConfig: cachedBuild: @@ -4424,6 +4457,7 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image + targetConfig: targetConfig envVars: key: envVars name: name @@ -4456,7 +4490,6 @@ components: sha: sha url: url user: user - target: target workspaceId: workspaceId - buildConfig: cachedBuild: @@ -4466,6 +4499,7 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image + targetConfig: targetConfig envVars: key: envVars name: name @@ -4498,7 +4532,6 @@ components: sha: sha url: url user: user - target: target workspaceId: workspaceId name: name id: id @@ -4516,7 +4549,6 @@ components: workspaceId: workspaceId providerMetadata: providerMetadata name: name - target: target properties: id: type: string @@ -4528,13 +4560,13 @@ components: items: $ref: '#/components/schemas/Project' type: array - target: + targetConfig: type: string required: - id - name - projects - - target + - targetConfig type: object WorkspaceInfo: example: @@ -4610,39 +4642,7 @@ components: - name - version type: object - provider.ProviderTargetProperty: - properties: - defaultValue: - description: |- - DefaultValue is converted into the appropriate type based on the Type - If the property is a FilePath, the DefaultValue is a path to a directory - type: string - description: - description: Brief description of the property - type: string - disabledPredicate: - description: |- - A regex string matched with the name of the target to determine if the property should be disabled - If the regex matches the target name, the property will be disabled - E.g. "^local$" will disable the property for the local target - type: string - inputMasked: - type: boolean - options: - description: Options is only used if the Type is ProviderTargetPropertyTypeOption - items: - type: string - type: array - suggestions: - description: Suggestions is an optional list of auto-complete values to - assist the user while filling the field - items: - type: string - type: array - type: - $ref: '#/components/schemas/provider.ProviderTargetPropertyType' - type: object - provider.ProviderTargetPropertyType: + provider.TargetConfigPropertyType: enum: - string - option @@ -4652,12 +4652,12 @@ components: - file-path type: string x-enum-varnames: - - ProviderTargetPropertyTypeString - - ProviderTargetPropertyTypeOption - - ProviderTargetPropertyTypeBoolean - - ProviderTargetPropertyTypeInt - - ProviderTargetPropertyTypeFloat - - ProviderTargetPropertyTypeFilePath + - TargetConfigPropertyTypeString + - TargetConfigPropertyTypeOption + - TargetConfigPropertyTypeBoolean + - TargetConfigPropertyTypeInt + - TargetConfigPropertyTypeFloat + - TargetConfigPropertyTypeFilePath FsUploadFile_request: properties: file: diff --git a/pkg/apiclient/api_provider.go b/pkg/apiclient/api_provider.go index f30b122ffd..168806cc22 100644 --- a/pkg/apiclient/api_provider.go +++ b/pkg/apiclient/api_provider.go @@ -22,27 +22,27 @@ import ( // ProviderAPIService ProviderAPI service type ProviderAPIService service -type ApiGetTargetManifestRequest struct { +type ApiGetTargetConfigManifestRequest struct { ctx context.Context ApiService *ProviderAPIService provider string } -func (r ApiGetTargetManifestRequest) Execute() (*map[string]ProviderProviderTargetProperty, *http.Response, error) { - return r.ApiService.GetTargetManifestExecute(r) +func (r ApiGetTargetConfigManifestRequest) Execute() (*map[string]TargetConfigProperty, *http.Response, error) { + return r.ApiService.GetTargetConfigManifestExecute(r) } /* -GetTargetManifest Get provider target manifest +GetTargetConfigManifest Get provider target config manifest -Get provider target manifest +Get provider target config manifest @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param provider Provider name - @return ApiGetTargetManifestRequest + @return ApiGetTargetConfigManifestRequest */ -func (a *ProviderAPIService) GetTargetManifest(ctx context.Context, provider string) ApiGetTargetManifestRequest { - return ApiGetTargetManifestRequest{ +func (a *ProviderAPIService) GetTargetConfigManifest(ctx context.Context, provider string) ApiGetTargetConfigManifestRequest { + return ApiGetTargetConfigManifestRequest{ ApiService: a, ctx: ctx, provider: provider, @@ -51,21 +51,21 @@ func (a *ProviderAPIService) GetTargetManifest(ctx context.Context, provider str // Execute executes the request // -// @return map[string]ProviderProviderTargetProperty -func (a *ProviderAPIService) GetTargetManifestExecute(r ApiGetTargetManifestRequest) (*map[string]ProviderProviderTargetProperty, *http.Response, error) { +// @return map[string]TargetConfigProperty +func (a *ProviderAPIService) GetTargetConfigManifestExecute(r ApiGetTargetConfigManifestRequest) (*map[string]TargetConfigProperty, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *map[string]ProviderProviderTargetProperty + localVarReturnValue *map[string]TargetConfigProperty ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.GetTargetManifest") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.GetTargetConfigManifest") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/provider/{provider}/target-manifest" + localVarPath := localBasePath + "/provider/{provider}/target-config-manifest" localVarPath = strings.Replace(localVarPath, "{"+"provider"+"}", url.PathEscape(parameterValueToString(r.provider, "provider")), -1) localVarHeaderParams := make(map[string]string) diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target_config.go similarity index 73% rename from pkg/apiclient/api_target.go rename to pkg/apiclient/api_target_config.go index 09ace864e4..ea4adf6662 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target_config.go @@ -19,28 +19,28 @@ import ( "strings" ) -// TargetAPIService TargetAPI service -type TargetAPIService service +// TargetConfigAPIService TargetConfigAPI service +type TargetConfigAPIService service -type ApiListTargetsRequest struct { +type ApiListTargetConfigsRequest struct { ctx context.Context - ApiService *TargetAPIService + ApiService *TargetConfigAPIService } -func (r ApiListTargetsRequest) Execute() ([]ProviderTarget, *http.Response, error) { - return r.ApiService.ListTargetsExecute(r) +func (r ApiListTargetConfigsRequest) Execute() ([]TargetConfig, *http.Response, error) { + return r.ApiService.ListTargetConfigsExecute(r) } /* -ListTargets List targets +ListTargetConfigs List target configs -List targets +List target configs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListTargetsRequest + @return ApiListTargetConfigsRequest */ -func (a *TargetAPIService) ListTargets(ctx context.Context) ApiListTargetsRequest { - return ApiListTargetsRequest{ +func (a *TargetConfigAPIService) ListTargetConfigs(ctx context.Context) ApiListTargetConfigsRequest { + return ApiListTargetConfigsRequest{ ApiService: a, ctx: ctx, } @@ -48,21 +48,21 @@ func (a *TargetAPIService) ListTargets(ctx context.Context) ApiListTargetsReques // Execute executes the request // -// @return []ProviderTarget -func (a *TargetAPIService) ListTargetsExecute(r ApiListTargetsRequest) ([]ProviderTarget, *http.Response, error) { +// @return []TargetConfig +func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigsRequest) ([]TargetConfig, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []ProviderTarget + localVarReturnValue []TargetConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.ListTargets") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.ListTargetConfigs") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target" + localVarPath := localBasePath + "/target-config" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -136,48 +136,48 @@ func (a *TargetAPIService) ListTargetsExecute(r ApiListTargetsRequest) ([]Provid return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveTargetRequest struct { +type ApiRemoveTargetConfigRequest struct { ctx context.Context - ApiService *TargetAPIService - target string + ApiService *TargetConfigAPIService + configName string } -func (r ApiRemoveTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveTargetExecute(r) +func (r ApiRemoveTargetConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.RemoveTargetConfigExecute(r) } /* -RemoveTarget Remove a target +RemoveTargetConfig Remove a target config -Remove a target +Remove a target config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param target Target name - @return ApiRemoveTargetRequest + @param configName Target Config name + @return ApiRemoveTargetConfigRequest */ -func (a *TargetAPIService) RemoveTarget(ctx context.Context, target string) ApiRemoveTargetRequest { - return ApiRemoveTargetRequest{ +func (a *TargetConfigAPIService) RemoveTargetConfig(ctx context.Context, configName string) ApiRemoveTargetConfigRequest { + return ApiRemoveTargetConfigRequest{ ApiService: a, ctx: ctx, - target: target, + configName: configName, } } // Execute executes the request -func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http.Response, error) { +func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConfigRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodDelete localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.RemoveTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.RemoveTargetConfig") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{target}" - localVarPath = strings.Replace(localVarPath, "{"+"target"+"}", url.PathEscape(parameterValueToString(r.target, "target")), -1) + localVarPath := localBasePath + "/target-config/{configName}" + localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -242,48 +242,48 @@ func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http. return localVarHTTPResponse, nil } -type ApiSetDefaultTargetRequest struct { +type ApiSetDefaultTargetConfigRequest struct { ctx context.Context - ApiService *TargetAPIService - target string + ApiService *TargetConfigAPIService + configName string } -func (r ApiSetDefaultTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.SetDefaultTargetExecute(r) +func (r ApiSetDefaultTargetConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.SetDefaultTargetConfigExecute(r) } /* -SetDefaultTarget Set target to default +SetDefaultTargetConfig Set target config to default -Set target to default +Set target config to default @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param target Target name - @return ApiSetDefaultTargetRequest + @param configName Target config name + @return ApiSetDefaultTargetConfigRequest */ -func (a *TargetAPIService) SetDefaultTarget(ctx context.Context, target string) ApiSetDefaultTargetRequest { - return ApiSetDefaultTargetRequest{ +func (a *TargetConfigAPIService) SetDefaultTargetConfig(ctx context.Context, configName string) ApiSetDefaultTargetConfigRequest { + return ApiSetDefaultTargetConfigRequest{ ApiService: a, ctx: ctx, - target: target, + configName: configName, } } // Execute executes the request -func (a *TargetAPIService) SetDefaultTargetExecute(r ApiSetDefaultTargetRequest) (*http.Response, error) { +func (a *TargetConfigAPIService) SetDefaultTargetConfigExecute(r ApiSetDefaultTargetConfigRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPatch localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetDefaultTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.SetDefaultTargetConfig") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{target}/set-default" - localVarPath = strings.Replace(localVarPath, "{"+"target"+"}", url.PathEscape(parameterValueToString(r.target, "target")), -1) + localVarPath := localBasePath + "/target-config/{configName}/set-default" + localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -348,57 +348,57 @@ func (a *TargetAPIService) SetDefaultTargetExecute(r ApiSetDefaultTargetRequest) return localVarHTTPResponse, nil } -type ApiSetTargetRequest struct { - ctx context.Context - ApiService *TargetAPIService - target *CreateProviderTargetDTO +type ApiSetTargetConfigRequest struct { + ctx context.Context + ApiService *TargetConfigAPIService + targetConfig *CreateTargetConfigDTO } -// Target to set -func (r ApiSetTargetRequest) Target(target CreateProviderTargetDTO) ApiSetTargetRequest { - r.target = &target +// Target config to set +func (r ApiSetTargetConfigRequest) TargetConfig(targetConfig CreateTargetConfigDTO) ApiSetTargetConfigRequest { + r.targetConfig = &targetConfig return r } -func (r ApiSetTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.SetTargetExecute(r) +func (r ApiSetTargetConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.SetTargetConfigExecute(r) } /* -SetTarget Set a target +SetTargetConfig Set a target config -Set a target +Set a target config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetTargetRequest + @return ApiSetTargetConfigRequest */ -func (a *TargetAPIService) SetTarget(ctx context.Context) ApiSetTargetRequest { - return ApiSetTargetRequest{ +func (a *TargetConfigAPIService) SetTargetConfig(ctx context.Context) ApiSetTargetConfigRequest { + return ApiSetTargetConfigRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *TargetAPIService) SetTargetExecute(r ApiSetTargetRequest) (*http.Response, error) { +func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.SetTargetConfig") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target" + localVarPath := localBasePath + "/target-config" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.target == nil { - return nil, reportError("target is required and must be specified") + if r.targetConfig == nil { + return nil, reportError("targetConfig is required and must be specified") } // to determine the Content-Type header @@ -419,7 +419,7 @@ func (a *TargetAPIService) SetTargetExecute(r ApiSetTargetRequest) (*http.Respon localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.target + localVarPostBody = r.targetConfig if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index dafbf109ef..33941bdb65 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -70,7 +70,7 @@ type APIClient struct { ServerAPI *ServerAPIService - TargetAPI *TargetAPIService + TargetConfigAPI *TargetConfigAPIService WorkspaceAPI *WorkspaceAPIService @@ -104,7 +104,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.ProviderAPI = (*ProviderAPIService)(&c.common) c.SampleAPI = (*SampleAPIService)(&c.common) c.ServerAPI = (*ServerAPIService)(&c.common) - c.TargetAPI = (*TargetAPIService)(&c.common) + c.TargetConfigAPI = (*TargetConfigAPIService)(&c.common) c.WorkspaceAPI = (*WorkspaceAPIService)(&c.common) c.WorkspaceToolboxAPI = (*WorkspaceToolboxAPIService)(&c.common) diff --git a/pkg/apiclient/docs/CreateProviderTargetDTO.md b/pkg/apiclient/docs/CreateTargetConfigDTO.md similarity index 62% rename from pkg/apiclient/docs/CreateProviderTargetDTO.md rename to pkg/apiclient/docs/CreateTargetConfigDTO.md index 87e2ba03a3..d657ad325f 100644 --- a/pkg/apiclient/docs/CreateProviderTargetDTO.md +++ b/pkg/apiclient/docs/CreateTargetConfigDTO.md @@ -1,4 +1,4 @@ -# CreateProviderTargetDTO +# CreateTargetConfigDTO ## Properties @@ -10,79 +10,79 @@ Name | Type | Description | Notes ## Methods -### NewCreateProviderTargetDTO +### NewCreateTargetConfigDTO -`func NewCreateProviderTargetDTO(name string, options string, providerInfo ProviderProviderInfo, ) *CreateProviderTargetDTO` +`func NewCreateTargetConfigDTO(name string, options string, providerInfo ProviderProviderInfo, ) *CreateTargetConfigDTO` -NewCreateProviderTargetDTO instantiates a new CreateProviderTargetDTO object +NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateProviderTargetDTOWithDefaults +### NewCreateTargetConfigDTOWithDefaults -`func NewCreateProviderTargetDTOWithDefaults() *CreateProviderTargetDTO` +`func NewCreateTargetConfigDTOWithDefaults() *CreateTargetConfigDTO` -NewCreateProviderTargetDTOWithDefaults instantiates a new CreateProviderTargetDTO object +NewCreateTargetConfigDTOWithDefaults instantiates a new CreateTargetConfigDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetName -`func (o *CreateProviderTargetDTO) GetName() string` +`func (o *CreateTargetConfigDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *CreateProviderTargetDTO) GetNameOk() (*string, bool)` +`func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *CreateProviderTargetDTO) SetName(v string)` +`func (o *CreateTargetConfigDTO) SetName(v string)` SetName sets Name field to given value. ### GetOptions -`func (o *CreateProviderTargetDTO) GetOptions() string` +`func (o *CreateTargetConfigDTO) GetOptions() string` GetOptions returns the Options field if non-nil, zero value otherwise. ### GetOptionsOk -`func (o *CreateProviderTargetDTO) GetOptionsOk() (*string, bool)` +`func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool)` GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetOptions -`func (o *CreateProviderTargetDTO) SetOptions(v string)` +`func (o *CreateTargetConfigDTO) SetOptions(v string)` SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *CreateProviderTargetDTO) GetProviderInfo() ProviderProviderInfo` +`func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *CreateProviderTargetDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool)` +`func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *CreateProviderTargetDTO) SetProviderInfo(v ProviderProviderInfo)` +`func (o *CreateTargetConfigDTO) SetProviderInfo(v ProviderProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/CreateWorkspaceDTO.md b/pkg/apiclient/docs/CreateWorkspaceDTO.md index 3edfafcb78..9570821789 100644 --- a/pkg/apiclient/docs/CreateWorkspaceDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceDTO.md @@ -7,13 +7,13 @@ Name | Type | Description | Notes **Id** | **string** | | **Name** | **string** | | **Projects** | [**[]CreateProjectDTO**](CreateProjectDTO.md) | | -**Target** | **string** | | +**TargetConfig** | **string** | | ## Methods ### NewCreateWorkspaceDTO -`func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, target string, ) *CreateWorkspaceDTO` +`func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, targetConfig string, ) *CreateWorkspaceDTO` NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -88,24 +88,24 @@ and a boolean to check if the value has been set. SetProjects sets Projects field to given value. -### GetTarget +### GetTargetConfig -`func (o *CreateWorkspaceDTO) GetTarget() string` +`func (o *CreateWorkspaceDTO) GetTargetConfig() string` -GetTarget returns the Target field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetTargetOk +### GetTargetConfigOk -`func (o *CreateWorkspaceDTO) GetTargetOk() (*string, bool)` +`func (o *CreateWorkspaceDTO) GetTargetConfigOk() (*string, bool)` -GetTargetOk returns a tuple with the Target field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTarget +### SetTargetConfig -`func (o *CreateWorkspaceDTO) SetTarget(v string)` +`func (o *CreateWorkspaceDTO) SetTargetConfig(v string)` -SetTarget sets Target field to given value. +SetTargetConfig sets TargetConfig field to given value. diff --git a/pkg/apiclient/docs/Project.md b/pkg/apiclient/docs/Project.md index 1e95900872..452cf655a8 100644 --- a/pkg/apiclient/docs/Project.md +++ b/pkg/apiclient/docs/Project.md @@ -11,7 +11,7 @@ Name | Type | Description | Notes **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | **State** | Pointer to [**ProjectState**](ProjectState.md) | | [optional] -**Target** | **string** | | +**TargetConfig** | **string** | | **User** | **string** | | **WorkspaceId** | **string** | | @@ -19,7 +19,7 @@ Name | Type | Description | Notes ### NewProject -`func NewProject(envVars map[string]string, image string, name string, repository GitRepository, target string, user string, workspaceId string, ) *Project` +`func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, user string, workspaceId string, ) *Project` NewProject instantiates a new Project object This constructor will assign default values to properties that have it defined, @@ -189,24 +189,24 @@ SetState sets State field to given value. HasState returns a boolean if a field has been set. -### GetTarget +### GetTargetConfig -`func (o *Project) GetTarget() string` +`func (o *Project) GetTargetConfig() string` -GetTarget returns the Target field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetTargetOk +### GetTargetConfigOk -`func (o *Project) GetTargetOk() (*string, bool)` +`func (o *Project) GetTargetConfigOk() (*string, bool)` -GetTargetOk returns a tuple with the Target field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTarget +### SetTargetConfig -`func (o *Project) SetTarget(v string)` +`func (o *Project) SetTargetConfig(v string)` -SetTarget sets Target field to given value. +SetTargetConfig sets TargetConfig field to given value. ### GetUser diff --git a/pkg/apiclient/docs/ProviderAPI.md b/pkg/apiclient/docs/ProviderAPI.md index 748cea7525..8098525c67 100644 --- a/pkg/apiclient/docs/ProviderAPI.md +++ b/pkg/apiclient/docs/ProviderAPI.md @@ -4,18 +4,18 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GetTargetManifest**](ProviderAPI.md#GetTargetManifest) | **Get** /provider/{provider}/target-manifest | Get provider target manifest +[**GetTargetConfigManifest**](ProviderAPI.md#GetTargetConfigManifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest [**InstallProvider**](ProviderAPI.md#InstallProvider) | **Post** /provider/install | Install a provider [**ListProviders**](ProviderAPI.md#ListProviders) | **Get** /provider | List providers [**UninstallProvider**](ProviderAPI.md#UninstallProvider) | **Post** /provider/{provider}/uninstall | Uninstall a provider -## GetTargetManifest +## GetTargetConfigManifest -> map[string]ProviderProviderTargetProperty GetTargetManifest(ctx, provider).Execute() +> map[string]TargetConfigProperty GetTargetConfigManifest(ctx, provider).Execute() -Get provider target manifest +Get provider target config manifest @@ -36,13 +36,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProviderAPI.GetTargetManifest(context.Background(), provider).Execute() + resp, r, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), provider).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.GetTargetManifest``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.GetTargetConfigManifest``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetTargetManifest`: map[string]ProviderProviderTargetProperty - fmt.Fprintf(os.Stdout, "Response from `ProviderAPI.GetTargetManifest`: %v\n", resp) + // response from `GetTargetConfigManifest`: map[string]TargetConfigProperty + fmt.Fprintf(os.Stdout, "Response from `ProviderAPI.GetTargetConfigManifest`: %v\n", resp) } ``` @@ -56,7 +56,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetTargetManifestRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetTargetConfigManifestRequest struct via the builder pattern Name | Type | Description | Notes @@ -65,7 +65,7 @@ Name | Type | Description | Notes ### Return type -[**map[string]ProviderProviderTargetProperty**](ProviderProviderTargetProperty.md) +[**map[string]TargetConfigProperty**](TargetConfigProperty.md) ### Authorization diff --git a/pkg/apiclient/docs/ProviderProviderTargetPropertyType.md b/pkg/apiclient/docs/ProviderProviderTargetPropertyType.md deleted file mode 100644 index 39df2ed551..0000000000 --- a/pkg/apiclient/docs/ProviderProviderTargetPropertyType.md +++ /dev/null @@ -1,21 +0,0 @@ -# ProviderProviderTargetPropertyType - -## Enum - - -* `ProviderTargetPropertyTypeString` (value: `"string"`) - -* `ProviderTargetPropertyTypeOption` (value: `"option"`) - -* `ProviderTargetPropertyTypeBoolean` (value: `"boolean"`) - -* `ProviderTargetPropertyTypeInt` (value: `"int"`) - -* `ProviderTargetPropertyTypeFloat` (value: `"float"`) - -* `ProviderTargetPropertyTypeFilePath` (value: `"file-path"`) - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/docs/ProviderTargetConfigPropertyType.md b/pkg/apiclient/docs/ProviderTargetConfigPropertyType.md new file mode 100644 index 0000000000..c3e0c6dadf --- /dev/null +++ b/pkg/apiclient/docs/ProviderTargetConfigPropertyType.md @@ -0,0 +1,21 @@ +# ProviderTargetConfigPropertyType + +## Enum + + +* `TargetConfigPropertyTypeString` (value: `"string"`) + +* `TargetConfigPropertyTypeOption` (value: `"option"`) + +* `TargetConfigPropertyTypeBoolean` (value: `"boolean"`) + +* `TargetConfigPropertyTypeInt` (value: `"int"`) + +* `TargetConfigPropertyTypeFloat` (value: `"float"`) + +* `TargetConfigPropertyTypeFilePath` (value: `"file-path"`) + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ProviderTarget.md b/pkg/apiclient/docs/TargetConfig.md similarity index 67% rename from pkg/apiclient/docs/ProviderTarget.md rename to pkg/apiclient/docs/TargetConfig.md index e4592a685d..e11cb57344 100644 --- a/pkg/apiclient/docs/ProviderTarget.md +++ b/pkg/apiclient/docs/TargetConfig.md @@ -1,4 +1,4 @@ -# ProviderTarget +# TargetConfig ## Properties @@ -11,99 +11,99 @@ Name | Type | Description | Notes ## Methods -### NewProviderTarget +### NewTargetConfig -`func NewProviderTarget(isDefault bool, name string, options string, providerInfo ProviderProviderInfo, ) *ProviderTarget` +`func NewTargetConfig(isDefault bool, name string, options string, providerInfo ProviderProviderInfo, ) *TargetConfig` -NewProviderTarget instantiates a new ProviderTarget object +NewTargetConfig instantiates a new TargetConfig object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProviderTargetWithDefaults +### NewTargetConfigWithDefaults -`func NewProviderTargetWithDefaults() *ProviderTarget` +`func NewTargetConfigWithDefaults() *TargetConfig` -NewProviderTargetWithDefaults instantiates a new ProviderTarget object +NewTargetConfigWithDefaults instantiates a new TargetConfig object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetIsDefault -`func (o *ProviderTarget) GetIsDefault() bool` +`func (o *TargetConfig) GetIsDefault() bool` GetIsDefault returns the IsDefault field if non-nil, zero value otherwise. ### GetIsDefaultOk -`func (o *ProviderTarget) GetIsDefaultOk() (*bool, bool)` +`func (o *TargetConfig) GetIsDefaultOk() (*bool, bool)` GetIsDefaultOk returns a tuple with the IsDefault field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetIsDefault -`func (o *ProviderTarget) SetIsDefault(v bool)` +`func (o *TargetConfig) SetIsDefault(v bool)` SetIsDefault sets IsDefault field to given value. ### GetName -`func (o *ProviderTarget) GetName() string` +`func (o *TargetConfig) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *ProviderTarget) GetNameOk() (*string, bool)` +`func (o *TargetConfig) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *ProviderTarget) SetName(v string)` +`func (o *TargetConfig) SetName(v string)` SetName sets Name field to given value. ### GetOptions -`func (o *ProviderTarget) GetOptions() string` +`func (o *TargetConfig) GetOptions() string` GetOptions returns the Options field if non-nil, zero value otherwise. ### GetOptionsOk -`func (o *ProviderTarget) GetOptionsOk() (*string, bool)` +`func (o *TargetConfig) GetOptionsOk() (*string, bool)` GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetOptions -`func (o *ProviderTarget) SetOptions(v string)` +`func (o *TargetConfig) SetOptions(v string)` SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *ProviderTarget) GetProviderInfo() ProviderProviderInfo` +`func (o *TargetConfig) GetProviderInfo() ProviderProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *ProviderTarget) GetProviderInfoOk() (*ProviderProviderInfo, bool)` +`func (o *TargetConfig) GetProviderInfoOk() (*ProviderProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *ProviderTarget) SetProviderInfo(v ProviderProviderInfo)` +`func (o *TargetConfig) SetProviderInfo(v ProviderProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetConfigAPI.md similarity index 60% rename from pkg/apiclient/docs/TargetAPI.md rename to pkg/apiclient/docs/TargetConfigAPI.md index d4232dba94..0092483e2e 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetConfigAPI.md @@ -1,21 +1,21 @@ -# \TargetAPI +# \TargetConfigAPI All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets -[**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{target} | Remove a target -[**SetDefaultTarget**](TargetAPI.md#SetDefaultTarget) | **Patch** /target/{target}/set-default | Set target to default -[**SetTarget**](TargetAPI.md#SetTarget) | **Put** /target | Set a target +[**ListTargetConfigs**](TargetConfigAPI.md#ListTargetConfigs) | **Get** /target-config | List target configs +[**RemoveTargetConfig**](TargetConfigAPI.md#RemoveTargetConfig) | **Delete** /target-config/{configName} | Remove a target config +[**SetDefaultTargetConfig**](TargetConfigAPI.md#SetDefaultTargetConfig) | **Patch** /target-config/{configName}/set-default | Set target config to default +[**SetTargetConfig**](TargetConfigAPI.md#SetTargetConfig) | **Put** /target-config | Set a target config -## ListTargets +## ListTargetConfigs -> []ProviderTarget ListTargets(ctx).Execute() +> []TargetConfig ListTargetConfigs(ctx).Execute() -List targets +List target configs @@ -35,13 +35,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetAPI.ListTargets(context.Background()).Execute() + resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.ListTargets``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.ListTargetConfigs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListTargets`: []ProviderTarget - fmt.Fprintf(os.Stdout, "Response from `TargetAPI.ListTargets`: %v\n", resp) + // response from `ListTargetConfigs`: []TargetConfig + fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.ListTargetConfigs`: %v\n", resp) } ``` @@ -51,12 +51,12 @@ This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiListTargetsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListTargetConfigsRequest struct via the builder pattern ### Return type -[**[]ProviderTarget**](ProviderTarget.md) +[**[]TargetConfig**](TargetConfig.md) ### Authorization @@ -72,11 +72,11 @@ Other parameters are passed through a pointer to a apiListTargetsRequest struct [[Back to README]](../README.md) -## RemoveTarget +## RemoveTargetConfig -> RemoveTarget(ctx, target).Execute() +> RemoveTargetConfig(ctx, configName).Execute() -Remove a target +Remove a target config @@ -93,13 +93,13 @@ import ( ) func main() { - target := "target_example" // string | Target name + configName := "configName_example" // string | Target Config name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.RemoveTarget(context.Background(), target).Execute() + r, err := apiClient.TargetConfigAPI.RemoveTargetConfig(context.Background(), configName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.RemoveTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.RemoveTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -111,11 +111,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**target** | **string** | Target name | +**configName** | **string** | Target Config name | ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiRemoveTargetConfigRequest struct via the builder pattern Name | Type | Description | Notes @@ -140,11 +140,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetDefaultTarget +## SetDefaultTargetConfig -> SetDefaultTarget(ctx, target).Execute() +> SetDefaultTargetConfig(ctx, configName).Execute() -Set target to default +Set target config to default @@ -161,13 +161,13 @@ import ( ) func main() { - target := "target_example" // string | Target name + configName := "configName_example" // string | Target config name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.SetDefaultTarget(context.Background(), target).Execute() + r, err := apiClient.TargetConfigAPI.SetDefaultTargetConfig(context.Background(), configName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetDefaultTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.SetDefaultTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -179,11 +179,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**target** | **string** | Target name | +**configName** | **string** | Target config name | ### Other Parameters -Other parameters are passed through a pointer to a apiSetDefaultTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetDefaultTargetConfigRequest struct via the builder pattern Name | Type | Description | Notes @@ -208,11 +208,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetTarget +## SetTargetConfig -> SetTarget(ctx).Target(target).Execute() +> SetTargetConfig(ctx).TargetConfig(targetConfig).Execute() -Set a target +Set a target config @@ -229,13 +229,13 @@ import ( ) func main() { - target := *openapiclient.NewCreateProviderTargetDTO("Name_example", "Options_example", *openapiclient.NewProviderProviderInfo("Name_example", "Version_example")) // CreateProviderTargetDTO | Target to set + targetConfig := *openapiclient.NewCreateTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewProviderProviderInfo("Name_example", "Version_example")) // CreateTargetConfigDTO | Target config to set configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.SetTarget(context.Background()).Target(target).Execute() + r, err := apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfig).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.SetTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -247,12 +247,12 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiSetTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetTargetConfigRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **target** | [**CreateProviderTargetDTO**](CreateProviderTargetDTO.md) | Target to set | + **targetConfig** | [**CreateTargetConfigDTO**](CreateTargetConfigDTO.md) | Target config to set | ### Return type diff --git a/pkg/apiclient/docs/ProviderProviderTargetProperty.md b/pkg/apiclient/docs/TargetConfigProperty.md similarity index 59% rename from pkg/apiclient/docs/ProviderProviderTargetProperty.md rename to pkg/apiclient/docs/TargetConfigProperty.md index cbc47b1dd6..b547b9e4da 100644 --- a/pkg/apiclient/docs/ProviderProviderTargetProperty.md +++ b/pkg/apiclient/docs/TargetConfigProperty.md @@ -1,4 +1,4 @@ -# ProviderProviderTargetProperty +# TargetConfigProperty ## Properties @@ -6,203 +6,203 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **DefaultValue** | Pointer to **string** | DefaultValue is converted into the appropriate type based on the Type If the property is a FilePath, the DefaultValue is a path to a directory | [optional] **Description** | Pointer to **string** | Brief description of the property | [optional] -**DisabledPredicate** | Pointer to **string** | A regex string matched with the name of the target to determine if the property should be disabled If the regex matches the target name, the property will be disabled E.g. \"^local$\" will disable the property for the local target | [optional] +**DisabledPredicate** | Pointer to **string** | A regex string matched with the name of the target config to determine if the property should be disabled If the regex matches the target config name, the property will be disabled E.g. \"^local$\" will disable the property for the local target | [optional] **InputMasked** | Pointer to **bool** | | [optional] -**Options** | Pointer to **[]string** | Options is only used if the Type is ProviderTargetPropertyTypeOption | [optional] +**Options** | Pointer to **[]string** | Options is only used if the Type is TargetConfigPropertyTypeOption | [optional] **Suggestions** | Pointer to **[]string** | Suggestions is an optional list of auto-complete values to assist the user while filling the field | [optional] -**Type** | Pointer to [**ProviderProviderTargetPropertyType**](ProviderProviderTargetPropertyType.md) | | [optional] +**Type** | Pointer to [**ProviderTargetConfigPropertyType**](ProviderTargetConfigPropertyType.md) | | [optional] ## Methods -### NewProviderProviderTargetProperty +### NewTargetConfigProperty -`func NewProviderProviderTargetProperty() *ProviderProviderTargetProperty` +`func NewTargetConfigProperty() *TargetConfigProperty` -NewProviderProviderTargetProperty instantiates a new ProviderProviderTargetProperty object +NewTargetConfigProperty instantiates a new TargetConfigProperty object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProviderProviderTargetPropertyWithDefaults +### NewTargetConfigPropertyWithDefaults -`func NewProviderProviderTargetPropertyWithDefaults() *ProviderProviderTargetProperty` +`func NewTargetConfigPropertyWithDefaults() *TargetConfigProperty` -NewProviderProviderTargetPropertyWithDefaults instantiates a new ProviderProviderTargetProperty object +NewTargetConfigPropertyWithDefaults instantiates a new TargetConfigProperty object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetDefaultValue -`func (o *ProviderProviderTargetProperty) GetDefaultValue() string` +`func (o *TargetConfigProperty) GetDefaultValue() string` GetDefaultValue returns the DefaultValue field if non-nil, zero value otherwise. ### GetDefaultValueOk -`func (o *ProviderProviderTargetProperty) GetDefaultValueOk() (*string, bool)` +`func (o *TargetConfigProperty) GetDefaultValueOk() (*string, bool)` GetDefaultValueOk returns a tuple with the DefaultValue field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDefaultValue -`func (o *ProviderProviderTargetProperty) SetDefaultValue(v string)` +`func (o *TargetConfigProperty) SetDefaultValue(v string)` SetDefaultValue sets DefaultValue field to given value. ### HasDefaultValue -`func (o *ProviderProviderTargetProperty) HasDefaultValue() bool` +`func (o *TargetConfigProperty) HasDefaultValue() bool` HasDefaultValue returns a boolean if a field has been set. ### GetDescription -`func (o *ProviderProviderTargetProperty) GetDescription() string` +`func (o *TargetConfigProperty) GetDescription() string` GetDescription returns the Description field if non-nil, zero value otherwise. ### GetDescriptionOk -`func (o *ProviderProviderTargetProperty) GetDescriptionOk() (*string, bool)` +`func (o *TargetConfigProperty) GetDescriptionOk() (*string, bool)` GetDescriptionOk returns a tuple with the Description field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDescription -`func (o *ProviderProviderTargetProperty) SetDescription(v string)` +`func (o *TargetConfigProperty) SetDescription(v string)` SetDescription sets Description field to given value. ### HasDescription -`func (o *ProviderProviderTargetProperty) HasDescription() bool` +`func (o *TargetConfigProperty) HasDescription() bool` HasDescription returns a boolean if a field has been set. ### GetDisabledPredicate -`func (o *ProviderProviderTargetProperty) GetDisabledPredicate() string` +`func (o *TargetConfigProperty) GetDisabledPredicate() string` GetDisabledPredicate returns the DisabledPredicate field if non-nil, zero value otherwise. ### GetDisabledPredicateOk -`func (o *ProviderProviderTargetProperty) GetDisabledPredicateOk() (*string, bool)` +`func (o *TargetConfigProperty) GetDisabledPredicateOk() (*string, bool)` GetDisabledPredicateOk returns a tuple with the DisabledPredicate field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDisabledPredicate -`func (o *ProviderProviderTargetProperty) SetDisabledPredicate(v string)` +`func (o *TargetConfigProperty) SetDisabledPredicate(v string)` SetDisabledPredicate sets DisabledPredicate field to given value. ### HasDisabledPredicate -`func (o *ProviderProviderTargetProperty) HasDisabledPredicate() bool` +`func (o *TargetConfigProperty) HasDisabledPredicate() bool` HasDisabledPredicate returns a boolean if a field has been set. ### GetInputMasked -`func (o *ProviderProviderTargetProperty) GetInputMasked() bool` +`func (o *TargetConfigProperty) GetInputMasked() bool` GetInputMasked returns the InputMasked field if non-nil, zero value otherwise. ### GetInputMaskedOk -`func (o *ProviderProviderTargetProperty) GetInputMaskedOk() (*bool, bool)` +`func (o *TargetConfigProperty) GetInputMaskedOk() (*bool, bool)` GetInputMaskedOk returns a tuple with the InputMasked field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetInputMasked -`func (o *ProviderProviderTargetProperty) SetInputMasked(v bool)` +`func (o *TargetConfigProperty) SetInputMasked(v bool)` SetInputMasked sets InputMasked field to given value. ### HasInputMasked -`func (o *ProviderProviderTargetProperty) HasInputMasked() bool` +`func (o *TargetConfigProperty) HasInputMasked() bool` HasInputMasked returns a boolean if a field has been set. ### GetOptions -`func (o *ProviderProviderTargetProperty) GetOptions() []string` +`func (o *TargetConfigProperty) GetOptions() []string` GetOptions returns the Options field if non-nil, zero value otherwise. ### GetOptionsOk -`func (o *ProviderProviderTargetProperty) GetOptionsOk() (*[]string, bool)` +`func (o *TargetConfigProperty) GetOptionsOk() (*[]string, bool)` GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetOptions -`func (o *ProviderProviderTargetProperty) SetOptions(v []string)` +`func (o *TargetConfigProperty) SetOptions(v []string)` SetOptions sets Options field to given value. ### HasOptions -`func (o *ProviderProviderTargetProperty) HasOptions() bool` +`func (o *TargetConfigProperty) HasOptions() bool` HasOptions returns a boolean if a field has been set. ### GetSuggestions -`func (o *ProviderProviderTargetProperty) GetSuggestions() []string` +`func (o *TargetConfigProperty) GetSuggestions() []string` GetSuggestions returns the Suggestions field if non-nil, zero value otherwise. ### GetSuggestionsOk -`func (o *ProviderProviderTargetProperty) GetSuggestionsOk() (*[]string, bool)` +`func (o *TargetConfigProperty) GetSuggestionsOk() (*[]string, bool)` GetSuggestionsOk returns a tuple with the Suggestions field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetSuggestions -`func (o *ProviderProviderTargetProperty) SetSuggestions(v []string)` +`func (o *TargetConfigProperty) SetSuggestions(v []string)` SetSuggestions sets Suggestions field to given value. ### HasSuggestions -`func (o *ProviderProviderTargetProperty) HasSuggestions() bool` +`func (o *TargetConfigProperty) HasSuggestions() bool` HasSuggestions returns a boolean if a field has been set. ### GetType -`func (o *ProviderProviderTargetProperty) GetType() ProviderProviderTargetPropertyType` +`func (o *TargetConfigProperty) GetType() ProviderTargetConfigPropertyType` GetType returns the Type field if non-nil, zero value otherwise. ### GetTypeOk -`func (o *ProviderProviderTargetProperty) GetTypeOk() (*ProviderProviderTargetPropertyType, bool)` +`func (o *TargetConfigProperty) GetTypeOk() (*ProviderTargetConfigPropertyType, bool)` GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetType -`func (o *ProviderProviderTargetProperty) SetType(v ProviderProviderTargetPropertyType)` +`func (o *TargetConfigProperty) SetType(v ProviderTargetConfigPropertyType)` SetType sets Type field to given value. ### HasType -`func (o *ProviderProviderTargetProperty) HasType() bool` +`func (o *TargetConfigProperty) HasType() bool` HasType returns a boolean if a field has been set. diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/Workspace.md index 296d9e30c9..32130e5b50 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/Workspace.md @@ -7,13 +7,13 @@ Name | Type | Description | Notes **Id** | **string** | | **Name** | **string** | | **Projects** | [**[]Project**](Project.md) | | -**Target** | **string** | | +**TargetConfig** | **string** | | ## Methods ### NewWorkspace -`func NewWorkspace(id string, name string, projects []Project, target string, ) *Workspace` +`func NewWorkspace(id string, name string, projects []Project, targetConfig string, ) *Workspace` NewWorkspace instantiates a new Workspace object This constructor will assign default values to properties that have it defined, @@ -88,24 +88,24 @@ and a boolean to check if the value has been set. SetProjects sets Projects field to given value. -### GetTarget +### GetTargetConfig -`func (o *Workspace) GetTarget() string` +`func (o *Workspace) GetTargetConfig() string` -GetTarget returns the Target field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetTargetOk +### GetTargetConfigOk -`func (o *Workspace) GetTargetOk() (*string, bool)` +`func (o *Workspace) GetTargetConfigOk() (*string, bool)` -GetTargetOk returns a tuple with the Target field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTarget +### SetTargetConfig -`func (o *Workspace) SetTarget(v string)` +`func (o *Workspace) SetTargetConfig(v string)` -SetTarget sets Target field to given value. +SetTargetConfig sets TargetConfig field to given value. diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 34e40fa02e..c523661f5a 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -37,7 +37,7 @@ import ( ) func main() { - workspace := *openapiclient.NewCreateWorkspaceDTO("Id_example", "Name_example", []openapiclient.CreateProjectDTO{*openapiclient.NewCreateProjectDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateProjectSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}, "Target_example") // CreateWorkspaceDTO | Create workspace + workspace := *openapiclient.NewCreateWorkspaceDTO("Id_example", "Name_example", []openapiclient.CreateProjectDTO{*openapiclient.NewCreateProjectDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateProjectSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}, "TargetConfig_example") // CreateWorkspaceDTO | Create workspace configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md index 9a0ce569c3..484565de01 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -8,13 +8,13 @@ Name | Type | Description | Notes **Info** | Pointer to [**WorkspaceInfo**](WorkspaceInfo.md) | | [optional] **Name** | **string** | | **Projects** | [**[]Project**](Project.md) | | -**Target** | **string** | | +**TargetConfig** | **string** | | ## Methods ### NewWorkspaceDTO -`func NewWorkspaceDTO(id string, name string, projects []Project, target string, ) *WorkspaceDTO` +`func NewWorkspaceDTO(id string, name string, projects []Project, targetConfig string, ) *WorkspaceDTO` NewWorkspaceDTO instantiates a new WorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -114,24 +114,24 @@ and a boolean to check if the value has been set. SetProjects sets Projects field to given value. -### GetTarget +### GetTargetConfig -`func (o *WorkspaceDTO) GetTarget() string` +`func (o *WorkspaceDTO) GetTargetConfig() string` -GetTarget returns the Target field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetTargetOk +### GetTargetConfigOk -`func (o *WorkspaceDTO) GetTargetOk() (*string, bool)` +`func (o *WorkspaceDTO) GetTargetConfigOk() (*string, bool)` -GetTargetOk returns a tuple with the Target field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTarget +### SetTargetConfig -`func (o *WorkspaceDTO) SetTarget(v string)` +`func (o *WorkspaceDTO) SetTargetConfig(v string)` -SetTarget sets Target field to given value. +SetTargetConfig sets TargetConfig field to given value. diff --git a/pkg/apiclient/model_create_provider_target_dto.go b/pkg/apiclient/model_create_target_config_dto.go similarity index 57% rename from pkg/apiclient/model_create_provider_target_dto.go rename to pkg/apiclient/model_create_target_config_dto.go index acd7ba8273..03616bf004 100644 --- a/pkg/apiclient/model_create_provider_target_dto.go +++ b/pkg/apiclient/model_create_target_config_dto.go @@ -16,40 +16,40 @@ import ( "fmt" ) -// checks if the CreateProviderTargetDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateProviderTargetDTO{} +// checks if the CreateTargetConfigDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateTargetConfigDTO{} -// CreateProviderTargetDTO struct for CreateProviderTargetDTO -type CreateProviderTargetDTO struct { +// CreateTargetConfigDTO struct for CreateTargetConfigDTO +type CreateTargetConfigDTO struct { Name string `json:"name"` Options string `json:"options"` ProviderInfo ProviderProviderInfo `json:"providerInfo"` } -type _CreateProviderTargetDTO CreateProviderTargetDTO +type _CreateTargetConfigDTO CreateTargetConfigDTO -// NewCreateProviderTargetDTO instantiates a new CreateProviderTargetDTO object +// NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateProviderTargetDTO(name string, options string, providerInfo ProviderProviderInfo) *CreateProviderTargetDTO { - this := CreateProviderTargetDTO{} +func NewCreateTargetConfigDTO(name string, options string, providerInfo ProviderProviderInfo) *CreateTargetConfigDTO { + this := CreateTargetConfigDTO{} this.Name = name this.Options = options this.ProviderInfo = providerInfo return &this } -// NewCreateProviderTargetDTOWithDefaults instantiates a new CreateProviderTargetDTO object +// NewCreateTargetConfigDTOWithDefaults instantiates a new CreateTargetConfigDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateProviderTargetDTOWithDefaults() *CreateProviderTargetDTO { - this := CreateProviderTargetDTO{} +func NewCreateTargetConfigDTOWithDefaults() *CreateTargetConfigDTO { + this := CreateTargetConfigDTO{} return &this } // GetName returns the Name field value -func (o *CreateProviderTargetDTO) GetName() string { +func (o *CreateTargetConfigDTO) GetName() string { if o == nil { var ret string return ret @@ -60,7 +60,7 @@ func (o *CreateProviderTargetDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *CreateProviderTargetDTO) GetNameOk() (*string, bool) { +func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -68,12 +68,12 @@ func (o *CreateProviderTargetDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *CreateProviderTargetDTO) SetName(v string) { +func (o *CreateTargetConfigDTO) SetName(v string) { o.Name = v } // GetOptions returns the Options field value -func (o *CreateProviderTargetDTO) GetOptions() string { +func (o *CreateTargetConfigDTO) GetOptions() string { if o == nil { var ret string return ret @@ -84,7 +84,7 @@ func (o *CreateProviderTargetDTO) GetOptions() string { // GetOptionsOk returns a tuple with the Options field value // and a boolean to check if the value has been set. -func (o *CreateProviderTargetDTO) GetOptionsOk() (*string, bool) { +func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool) { if o == nil { return nil, false } @@ -92,12 +92,12 @@ func (o *CreateProviderTargetDTO) GetOptionsOk() (*string, bool) { } // SetOptions sets field value -func (o *CreateProviderTargetDTO) SetOptions(v string) { +func (o *CreateTargetConfigDTO) SetOptions(v string) { o.Options = v } // GetProviderInfo returns the ProviderInfo field value -func (o *CreateProviderTargetDTO) GetProviderInfo() ProviderProviderInfo { +func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderProviderInfo { if o == nil { var ret ProviderProviderInfo return ret @@ -108,7 +108,7 @@ func (o *CreateProviderTargetDTO) GetProviderInfo() ProviderProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *CreateProviderTargetDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool) { +func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool) { if o == nil { return nil, false } @@ -116,11 +116,11 @@ func (o *CreateProviderTargetDTO) GetProviderInfoOk() (*ProviderProviderInfo, bo } // SetProviderInfo sets field value -func (o *CreateProviderTargetDTO) SetProviderInfo(v ProviderProviderInfo) { +func (o *CreateTargetConfigDTO) SetProviderInfo(v ProviderProviderInfo) { o.ProviderInfo = v } -func (o CreateProviderTargetDTO) MarshalJSON() ([]byte, error) { +func (o CreateTargetConfigDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -128,7 +128,7 @@ func (o CreateProviderTargetDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateProviderTargetDTO) ToMap() (map[string]interface{}, error) { +func (o CreateTargetConfigDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["name"] = o.Name toSerialize["options"] = o.Options @@ -136,7 +136,7 @@ func (o CreateProviderTargetDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *CreateProviderTargetDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -160,53 +160,53 @@ func (o *CreateProviderTargetDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateProviderTargetDTO := _CreateProviderTargetDTO{} + varCreateTargetConfigDTO := _CreateTargetConfigDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateProviderTargetDTO) + err = decoder.Decode(&varCreateTargetConfigDTO) if err != nil { return err } - *o = CreateProviderTargetDTO(varCreateProviderTargetDTO) + *o = CreateTargetConfigDTO(varCreateTargetConfigDTO) return err } -type NullableCreateProviderTargetDTO struct { - value *CreateProviderTargetDTO +type NullableCreateTargetConfigDTO struct { + value *CreateTargetConfigDTO isSet bool } -func (v NullableCreateProviderTargetDTO) Get() *CreateProviderTargetDTO { +func (v NullableCreateTargetConfigDTO) Get() *CreateTargetConfigDTO { return v.value } -func (v *NullableCreateProviderTargetDTO) Set(val *CreateProviderTargetDTO) { +func (v *NullableCreateTargetConfigDTO) Set(val *CreateTargetConfigDTO) { v.value = val v.isSet = true } -func (v NullableCreateProviderTargetDTO) IsSet() bool { +func (v NullableCreateTargetConfigDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateProviderTargetDTO) Unset() { +func (v *NullableCreateTargetConfigDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateProviderTargetDTO(val *CreateProviderTargetDTO) *NullableCreateProviderTargetDTO { - return &NullableCreateProviderTargetDTO{value: val, isSet: true} +func NewNullableCreateTargetConfigDTO(val *CreateTargetConfigDTO) *NullableCreateTargetConfigDTO { + return &NullableCreateTargetConfigDTO{value: val, isSet: true} } -func (v NullableCreateProviderTargetDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateTargetConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateProviderTargetDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateTargetConfigDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_create_workspace_dto.go b/pkg/apiclient/model_create_workspace_dto.go index 5392ad6fb1..53262a10cd 100644 --- a/pkg/apiclient/model_create_workspace_dto.go +++ b/pkg/apiclient/model_create_workspace_dto.go @@ -21,10 +21,10 @@ var _ MappedNullable = &CreateWorkspaceDTO{} // CreateWorkspaceDTO struct for CreateWorkspaceDTO type CreateWorkspaceDTO struct { - Id string `json:"id"` - Name string `json:"name"` - Projects []CreateProjectDTO `json:"projects"` - Target string `json:"target"` + Id string `json:"id"` + Name string `json:"name"` + Projects []CreateProjectDTO `json:"projects"` + TargetConfig string `json:"targetConfig"` } type _CreateWorkspaceDTO CreateWorkspaceDTO @@ -33,12 +33,12 @@ type _CreateWorkspaceDTO CreateWorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, target string) *CreateWorkspaceDTO { +func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, targetConfig string) *CreateWorkspaceDTO { this := CreateWorkspaceDTO{} this.Id = id this.Name = name this.Projects = projects - this.Target = target + this.TargetConfig = targetConfig return &this } @@ -122,28 +122,28 @@ func (o *CreateWorkspaceDTO) SetProjects(v []CreateProjectDTO) { o.Projects = v } -// GetTarget returns the Target field value -func (o *CreateWorkspaceDTO) GetTarget() string { +// GetTargetConfig returns the TargetConfig field value +func (o *CreateWorkspaceDTO) GetTargetConfig() string { if o == nil { var ret string return ret } - return o.Target + return o.TargetConfig } -// GetTargetOk returns a tuple with the Target field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceDTO) GetTargetOk() (*string, bool) { +func (o *CreateWorkspaceDTO) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return &o.Target, true + return &o.TargetConfig, true } -// SetTarget sets field value -func (o *CreateWorkspaceDTO) SetTarget(v string) { - o.Target = v +// SetTargetConfig sets field value +func (o *CreateWorkspaceDTO) SetTargetConfig(v string) { + o.TargetConfig = v } func (o CreateWorkspaceDTO) MarshalJSON() ([]byte, error) { @@ -159,7 +159,7 @@ func (o CreateWorkspaceDTO) ToMap() (map[string]interface{}, error) { toSerialize["id"] = o.Id toSerialize["name"] = o.Name toSerialize["projects"] = o.Projects - toSerialize["target"] = o.Target + toSerialize["targetConfig"] = o.TargetConfig return toSerialize, nil } @@ -171,7 +171,7 @@ func (o *CreateWorkspaceDTO) UnmarshalJSON(data []byte) (err error) { "id", "name", "projects", - "target", + "targetConfig", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_project.go b/pkg/apiclient/model_project.go index 95951f8077..a9ba9cb754 100644 --- a/pkg/apiclient/model_project.go +++ b/pkg/apiclient/model_project.go @@ -28,7 +28,7 @@ type Project struct { Name string `json:"name"` Repository GitRepository `json:"repository"` State *ProjectState `json:"state,omitempty"` - Target string `json:"target"` + TargetConfig string `json:"targetConfig"` User string `json:"user"` WorkspaceId string `json:"workspaceId"` } @@ -39,13 +39,13 @@ type _Project Project // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProject(envVars map[string]string, image string, name string, repository GitRepository, target string, user string, workspaceId string) *Project { +func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, user string, workspaceId string) *Project { this := Project{} this.EnvVars = envVars this.Image = image this.Name = name this.Repository = repository - this.Target = target + this.TargetConfig = targetConfig this.User = user this.WorkspaceId = workspaceId return &this @@ -251,28 +251,28 @@ func (o *Project) SetState(v ProjectState) { o.State = &v } -// GetTarget returns the Target field value -func (o *Project) GetTarget() string { +// GetTargetConfig returns the TargetConfig field value +func (o *Project) GetTargetConfig() string { if o == nil { var ret string return ret } - return o.Target + return o.TargetConfig } -// GetTargetOk returns a tuple with the Target field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *Project) GetTargetOk() (*string, bool) { +func (o *Project) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return &o.Target, true + return &o.TargetConfig, true } -// SetTarget sets field value -func (o *Project) SetTarget(v string) { - o.Target = v +// SetTargetConfig sets field value +func (o *Project) SetTargetConfig(v string) { + o.TargetConfig = v } // GetUser returns the User field value @@ -346,7 +346,7 @@ func (o Project) ToMap() (map[string]interface{}, error) { if !IsNil(o.State) { toSerialize["state"] = o.State } - toSerialize["target"] = o.Target + toSerialize["targetConfig"] = o.TargetConfig toSerialize["user"] = o.User toSerialize["workspaceId"] = o.WorkspaceId return toSerialize, nil @@ -361,7 +361,7 @@ func (o *Project) UnmarshalJSON(data []byte) (err error) { "image", "name", "repository", - "target", + "targetConfig", "user", "workspaceId", } diff --git a/pkg/apiclient/model_provider_provider_target_property_type.go b/pkg/apiclient/model_provider_provider_target_property_type.go deleted file mode 100644 index 09210e35c5..0000000000 --- a/pkg/apiclient/model_provider_provider_target_property_type.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "encoding/json" - "fmt" -) - -// ProviderProviderTargetPropertyType the model 'ProviderProviderTargetPropertyType' -type ProviderProviderTargetPropertyType string - -// List of provider.ProviderTargetPropertyType -const ( - ProviderTargetPropertyTypeString ProviderProviderTargetPropertyType = "string" - ProviderTargetPropertyTypeOption ProviderProviderTargetPropertyType = "option" - ProviderTargetPropertyTypeBoolean ProviderProviderTargetPropertyType = "boolean" - ProviderTargetPropertyTypeInt ProviderProviderTargetPropertyType = "int" - ProviderTargetPropertyTypeFloat ProviderProviderTargetPropertyType = "float" - ProviderTargetPropertyTypeFilePath ProviderProviderTargetPropertyType = "file-path" -) - -// All allowed values of ProviderProviderTargetPropertyType enum -var AllowedProviderProviderTargetPropertyTypeEnumValues = []ProviderProviderTargetPropertyType{ - "string", - "option", - "boolean", - "int", - "float", - "file-path", -} - -func (v *ProviderProviderTargetPropertyType) UnmarshalJSON(src []byte) error { - var value string - err := json.Unmarshal(src, &value) - if err != nil { - return err - } - enumTypeValue := ProviderProviderTargetPropertyType(value) - for _, existing := range AllowedProviderProviderTargetPropertyTypeEnumValues { - if existing == enumTypeValue { - *v = enumTypeValue - return nil - } - } - - return fmt.Errorf("%+v is not a valid ProviderProviderTargetPropertyType", value) -} - -// NewProviderProviderTargetPropertyTypeFromValue returns a pointer to a valid ProviderProviderTargetPropertyType -// for the value passed as argument, or an error if the value passed is not allowed by the enum -func NewProviderProviderTargetPropertyTypeFromValue(v string) (*ProviderProviderTargetPropertyType, error) { - ev := ProviderProviderTargetPropertyType(v) - if ev.IsValid() { - return &ev, nil - } else { - return nil, fmt.Errorf("invalid value '%v' for ProviderProviderTargetPropertyType: valid values are %v", v, AllowedProviderProviderTargetPropertyTypeEnumValues) - } -} - -// IsValid return true if the value is valid for the enum, false otherwise -func (v ProviderProviderTargetPropertyType) IsValid() bool { - for _, existing := range AllowedProviderProviderTargetPropertyTypeEnumValues { - if existing == v { - return true - } - } - return false -} - -// Ptr returns reference to provider.ProviderTargetPropertyType value -func (v ProviderProviderTargetPropertyType) Ptr() *ProviderProviderTargetPropertyType { - return &v -} - -type NullableProviderProviderTargetPropertyType struct { - value *ProviderProviderTargetPropertyType - isSet bool -} - -func (v NullableProviderProviderTargetPropertyType) Get() *ProviderProviderTargetPropertyType { - return v.value -} - -func (v *NullableProviderProviderTargetPropertyType) Set(val *ProviderProviderTargetPropertyType) { - v.value = val - v.isSet = true -} - -func (v NullableProviderProviderTargetPropertyType) IsSet() bool { - return v.isSet -} - -func (v *NullableProviderProviderTargetPropertyType) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableProviderProviderTargetPropertyType(val *ProviderProviderTargetPropertyType) *NullableProviderProviderTargetPropertyType { - return &NullableProviderProviderTargetPropertyType{value: val, isSet: true} -} - -func (v NullableProviderProviderTargetPropertyType) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableProviderProviderTargetPropertyType) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_provider_target_config_property_type.go b/pkg/apiclient/model_provider_target_config_property_type.go new file mode 100644 index 0000000000..b493484787 --- /dev/null +++ b/pkg/apiclient/model_provider_target_config_property_type.go @@ -0,0 +1,118 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ProviderTargetConfigPropertyType the model 'ProviderTargetConfigPropertyType' +type ProviderTargetConfigPropertyType string + +// List of provider.TargetConfigPropertyType +const ( + TargetConfigPropertyTypeString ProviderTargetConfigPropertyType = "string" + TargetConfigPropertyTypeOption ProviderTargetConfigPropertyType = "option" + TargetConfigPropertyTypeBoolean ProviderTargetConfigPropertyType = "boolean" + TargetConfigPropertyTypeInt ProviderTargetConfigPropertyType = "int" + TargetConfigPropertyTypeFloat ProviderTargetConfigPropertyType = "float" + TargetConfigPropertyTypeFilePath ProviderTargetConfigPropertyType = "file-path" +) + +// All allowed values of ProviderTargetConfigPropertyType enum +var AllowedProviderTargetConfigPropertyTypeEnumValues = []ProviderTargetConfigPropertyType{ + "string", + "option", + "boolean", + "int", + "float", + "file-path", +} + +func (v *ProviderTargetConfigPropertyType) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ProviderTargetConfigPropertyType(value) + for _, existing := range AllowedProviderTargetConfigPropertyTypeEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ProviderTargetConfigPropertyType", value) +} + +// NewProviderTargetConfigPropertyTypeFromValue returns a pointer to a valid ProviderTargetConfigPropertyType +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewProviderTargetConfigPropertyTypeFromValue(v string) (*ProviderTargetConfigPropertyType, error) { + ev := ProviderTargetConfigPropertyType(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ProviderTargetConfigPropertyType: valid values are %v", v, AllowedProviderTargetConfigPropertyTypeEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ProviderTargetConfigPropertyType) IsValid() bool { + for _, existing := range AllowedProviderTargetConfigPropertyTypeEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to provider.TargetConfigPropertyType value +func (v ProviderTargetConfigPropertyType) Ptr() *ProviderTargetConfigPropertyType { + return &v +} + +type NullableProviderTargetConfigPropertyType struct { + value *ProviderTargetConfigPropertyType + isSet bool +} + +func (v NullableProviderTargetConfigPropertyType) Get() *ProviderTargetConfigPropertyType { + return v.value +} + +func (v *NullableProviderTargetConfigPropertyType) Set(val *ProviderTargetConfigPropertyType) { + v.value = val + v.isSet = true +} + +func (v NullableProviderTargetConfigPropertyType) IsSet() bool { + return v.isSet +} + +func (v *NullableProviderTargetConfigPropertyType) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableProviderTargetConfigPropertyType(val *ProviderTargetConfigPropertyType) *NullableProviderTargetConfigPropertyType { + return &NullableProviderTargetConfigPropertyType{value: val, isSet: true} +} + +func (v NullableProviderTargetConfigPropertyType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableProviderTargetConfigPropertyType) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_provider_target.go b/pkg/apiclient/model_target_config.go similarity index 63% rename from pkg/apiclient/model_provider_target.go rename to pkg/apiclient/model_target_config.go index 2d77e6a703..faf208fb39 100644 --- a/pkg/apiclient/model_provider_target.go +++ b/pkg/apiclient/model_target_config.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the ProviderTarget type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProviderTarget{} +// checks if the TargetConfig type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TargetConfig{} -// ProviderTarget struct for ProviderTarget -type ProviderTarget struct { +// TargetConfig struct for TargetConfig +type TargetConfig struct { IsDefault bool `json:"isDefault"` Name string `json:"name"` // JSON encoded map of options @@ -28,14 +28,14 @@ type ProviderTarget struct { ProviderInfo ProviderProviderInfo `json:"providerInfo"` } -type _ProviderTarget ProviderTarget +type _TargetConfig TargetConfig -// NewProviderTarget instantiates a new ProviderTarget object +// NewTargetConfig instantiates a new TargetConfig object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProviderTarget(isDefault bool, name string, options string, providerInfo ProviderProviderInfo) *ProviderTarget { - this := ProviderTarget{} +func NewTargetConfig(isDefault bool, name string, options string, providerInfo ProviderProviderInfo) *TargetConfig { + this := TargetConfig{} this.IsDefault = isDefault this.Name = name this.Options = options @@ -43,16 +43,16 @@ func NewProviderTarget(isDefault bool, name string, options string, providerInfo return &this } -// NewProviderTargetWithDefaults instantiates a new ProviderTarget object +// NewTargetConfigWithDefaults instantiates a new TargetConfig object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProviderTargetWithDefaults() *ProviderTarget { - this := ProviderTarget{} +func NewTargetConfigWithDefaults() *TargetConfig { + this := TargetConfig{} return &this } // GetIsDefault returns the IsDefault field value -func (o *ProviderTarget) GetIsDefault() bool { +func (o *TargetConfig) GetIsDefault() bool { if o == nil { var ret bool return ret @@ -63,7 +63,7 @@ func (o *ProviderTarget) GetIsDefault() bool { // GetIsDefaultOk returns a tuple with the IsDefault field value // and a boolean to check if the value has been set. -func (o *ProviderTarget) GetIsDefaultOk() (*bool, bool) { +func (o *TargetConfig) GetIsDefaultOk() (*bool, bool) { if o == nil { return nil, false } @@ -71,12 +71,12 @@ func (o *ProviderTarget) GetIsDefaultOk() (*bool, bool) { } // SetIsDefault sets field value -func (o *ProviderTarget) SetIsDefault(v bool) { +func (o *TargetConfig) SetIsDefault(v bool) { o.IsDefault = v } // GetName returns the Name field value -func (o *ProviderTarget) GetName() string { +func (o *TargetConfig) GetName() string { if o == nil { var ret string return ret @@ -87,7 +87,7 @@ func (o *ProviderTarget) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *ProviderTarget) GetNameOk() (*string, bool) { +func (o *TargetConfig) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -95,12 +95,12 @@ func (o *ProviderTarget) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *ProviderTarget) SetName(v string) { +func (o *TargetConfig) SetName(v string) { o.Name = v } // GetOptions returns the Options field value -func (o *ProviderTarget) GetOptions() string { +func (o *TargetConfig) GetOptions() string { if o == nil { var ret string return ret @@ -111,7 +111,7 @@ func (o *ProviderTarget) GetOptions() string { // GetOptionsOk returns a tuple with the Options field value // and a boolean to check if the value has been set. -func (o *ProviderTarget) GetOptionsOk() (*string, bool) { +func (o *TargetConfig) GetOptionsOk() (*string, bool) { if o == nil { return nil, false } @@ -119,12 +119,12 @@ func (o *ProviderTarget) GetOptionsOk() (*string, bool) { } // SetOptions sets field value -func (o *ProviderTarget) SetOptions(v string) { +func (o *TargetConfig) SetOptions(v string) { o.Options = v } // GetProviderInfo returns the ProviderInfo field value -func (o *ProviderTarget) GetProviderInfo() ProviderProviderInfo { +func (o *TargetConfig) GetProviderInfo() ProviderProviderInfo { if o == nil { var ret ProviderProviderInfo return ret @@ -135,7 +135,7 @@ func (o *ProviderTarget) GetProviderInfo() ProviderProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *ProviderTarget) GetProviderInfoOk() (*ProviderProviderInfo, bool) { +func (o *TargetConfig) GetProviderInfoOk() (*ProviderProviderInfo, bool) { if o == nil { return nil, false } @@ -143,11 +143,11 @@ func (o *ProviderTarget) GetProviderInfoOk() (*ProviderProviderInfo, bool) { } // SetProviderInfo sets field value -func (o *ProviderTarget) SetProviderInfo(v ProviderProviderInfo) { +func (o *TargetConfig) SetProviderInfo(v ProviderProviderInfo) { o.ProviderInfo = v } -func (o ProviderTarget) MarshalJSON() ([]byte, error) { +func (o TargetConfig) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -155,7 +155,7 @@ func (o ProviderTarget) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProviderTarget) ToMap() (map[string]interface{}, error) { +func (o TargetConfig) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["isDefault"] = o.IsDefault toSerialize["name"] = o.Name @@ -164,7 +164,7 @@ func (o ProviderTarget) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *ProviderTarget) UnmarshalJSON(data []byte) (err error) { +func (o *TargetConfig) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -189,53 +189,53 @@ func (o *ProviderTarget) UnmarshalJSON(data []byte) (err error) { } } - varProviderTarget := _ProviderTarget{} + varTargetConfig := _TargetConfig{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varProviderTarget) + err = decoder.Decode(&varTargetConfig) if err != nil { return err } - *o = ProviderTarget(varProviderTarget) + *o = TargetConfig(varTargetConfig) return err } -type NullableProviderTarget struct { - value *ProviderTarget +type NullableTargetConfig struct { + value *TargetConfig isSet bool } -func (v NullableProviderTarget) Get() *ProviderTarget { +func (v NullableTargetConfig) Get() *TargetConfig { return v.value } -func (v *NullableProviderTarget) Set(val *ProviderTarget) { +func (v *NullableTargetConfig) Set(val *TargetConfig) { v.value = val v.isSet = true } -func (v NullableProviderTarget) IsSet() bool { +func (v NullableTargetConfig) IsSet() bool { return v.isSet } -func (v *NullableProviderTarget) Unset() { +func (v *NullableTargetConfig) Unset() { v.value = nil v.isSet = false } -func NewNullableProviderTarget(val *ProviderTarget) *NullableProviderTarget { - return &NullableProviderTarget{value: val, isSet: true} +func NewNullableTargetConfig(val *TargetConfig) *NullableTargetConfig { + return &NullableTargetConfig{value: val, isSet: true} } -func (v NullableProviderTarget) MarshalJSON() ([]byte, error) { +func (v NullableTargetConfig) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProviderTarget) UnmarshalJSON(src []byte) error { +func (v *NullableTargetConfig) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_provider_provider_target_property.go b/pkg/apiclient/model_target_config_property.go similarity index 61% rename from pkg/apiclient/model_provider_provider_target_property.go rename to pkg/apiclient/model_target_config_property.go index be99c70e05..3a7b4e6ea3 100644 --- a/pkg/apiclient/model_provider_provider_target_property.go +++ b/pkg/apiclient/model_target_config_property.go @@ -14,44 +14,44 @@ import ( "encoding/json" ) -// checks if the ProviderProviderTargetProperty type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProviderProviderTargetProperty{} +// checks if the TargetConfigProperty type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TargetConfigProperty{} -// ProviderProviderTargetProperty struct for ProviderProviderTargetProperty -type ProviderProviderTargetProperty struct { +// TargetConfigProperty struct for TargetConfigProperty +type TargetConfigProperty struct { // DefaultValue is converted into the appropriate type based on the Type If the property is a FilePath, the DefaultValue is a path to a directory DefaultValue *string `json:"defaultValue,omitempty"` // Brief description of the property Description *string `json:"description,omitempty"` - // A regex string matched with the name of the target to determine if the property should be disabled If the regex matches the target name, the property will be disabled E.g. \"^local$\" will disable the property for the local target + // A regex string matched with the name of the target config to determine if the property should be disabled If the regex matches the target config name, the property will be disabled E.g. \"^local$\" will disable the property for the local target DisabledPredicate *string `json:"disabledPredicate,omitempty"` InputMasked *bool `json:"inputMasked,omitempty"` - // Options is only used if the Type is ProviderTargetPropertyTypeOption + // Options is only used if the Type is TargetConfigPropertyTypeOption Options []string `json:"options,omitempty"` // Suggestions is an optional list of auto-complete values to assist the user while filling the field - Suggestions []string `json:"suggestions,omitempty"` - Type *ProviderProviderTargetPropertyType `json:"type,omitempty"` + Suggestions []string `json:"suggestions,omitempty"` + Type *ProviderTargetConfigPropertyType `json:"type,omitempty"` } -// NewProviderProviderTargetProperty instantiates a new ProviderProviderTargetProperty object +// NewTargetConfigProperty instantiates a new TargetConfigProperty object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProviderProviderTargetProperty() *ProviderProviderTargetProperty { - this := ProviderProviderTargetProperty{} +func NewTargetConfigProperty() *TargetConfigProperty { + this := TargetConfigProperty{} return &this } -// NewProviderProviderTargetPropertyWithDefaults instantiates a new ProviderProviderTargetProperty object +// NewTargetConfigPropertyWithDefaults instantiates a new TargetConfigProperty object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProviderProviderTargetPropertyWithDefaults() *ProviderProviderTargetProperty { - this := ProviderProviderTargetProperty{} +func NewTargetConfigPropertyWithDefaults() *TargetConfigProperty { + this := TargetConfigProperty{} return &this } // GetDefaultValue returns the DefaultValue field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetDefaultValue() string { +func (o *TargetConfigProperty) GetDefaultValue() string { if o == nil || IsNil(o.DefaultValue) { var ret string return ret @@ -61,7 +61,7 @@ func (o *ProviderProviderTargetProperty) GetDefaultValue() string { // GetDefaultValueOk returns a tuple with the DefaultValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetDefaultValueOk() (*string, bool) { +func (o *TargetConfigProperty) GetDefaultValueOk() (*string, bool) { if o == nil || IsNil(o.DefaultValue) { return nil, false } @@ -69,7 +69,7 @@ func (o *ProviderProviderTargetProperty) GetDefaultValueOk() (*string, bool) { } // HasDefaultValue returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasDefaultValue() bool { +func (o *TargetConfigProperty) HasDefaultValue() bool { if o != nil && !IsNil(o.DefaultValue) { return true } @@ -78,12 +78,12 @@ func (o *ProviderProviderTargetProperty) HasDefaultValue() bool { } // SetDefaultValue gets a reference to the given string and assigns it to the DefaultValue field. -func (o *ProviderProviderTargetProperty) SetDefaultValue(v string) { +func (o *TargetConfigProperty) SetDefaultValue(v string) { o.DefaultValue = &v } // GetDescription returns the Description field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetDescription() string { +func (o *TargetConfigProperty) GetDescription() string { if o == nil || IsNil(o.Description) { var ret string return ret @@ -93,7 +93,7 @@ func (o *ProviderProviderTargetProperty) GetDescription() string { // GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetDescriptionOk() (*string, bool) { +func (o *TargetConfigProperty) GetDescriptionOk() (*string, bool) { if o == nil || IsNil(o.Description) { return nil, false } @@ -101,7 +101,7 @@ func (o *ProviderProviderTargetProperty) GetDescriptionOk() (*string, bool) { } // HasDescription returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasDescription() bool { +func (o *TargetConfigProperty) HasDescription() bool { if o != nil && !IsNil(o.Description) { return true } @@ -110,12 +110,12 @@ func (o *ProviderProviderTargetProperty) HasDescription() bool { } // SetDescription gets a reference to the given string and assigns it to the Description field. -func (o *ProviderProviderTargetProperty) SetDescription(v string) { +func (o *TargetConfigProperty) SetDescription(v string) { o.Description = &v } // GetDisabledPredicate returns the DisabledPredicate field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetDisabledPredicate() string { +func (o *TargetConfigProperty) GetDisabledPredicate() string { if o == nil || IsNil(o.DisabledPredicate) { var ret string return ret @@ -125,7 +125,7 @@ func (o *ProviderProviderTargetProperty) GetDisabledPredicate() string { // GetDisabledPredicateOk returns a tuple with the DisabledPredicate field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetDisabledPredicateOk() (*string, bool) { +func (o *TargetConfigProperty) GetDisabledPredicateOk() (*string, bool) { if o == nil || IsNil(o.DisabledPredicate) { return nil, false } @@ -133,7 +133,7 @@ func (o *ProviderProviderTargetProperty) GetDisabledPredicateOk() (*string, bool } // HasDisabledPredicate returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasDisabledPredicate() bool { +func (o *TargetConfigProperty) HasDisabledPredicate() bool { if o != nil && !IsNil(o.DisabledPredicate) { return true } @@ -142,12 +142,12 @@ func (o *ProviderProviderTargetProperty) HasDisabledPredicate() bool { } // SetDisabledPredicate gets a reference to the given string and assigns it to the DisabledPredicate field. -func (o *ProviderProviderTargetProperty) SetDisabledPredicate(v string) { +func (o *TargetConfigProperty) SetDisabledPredicate(v string) { o.DisabledPredicate = &v } // GetInputMasked returns the InputMasked field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetInputMasked() bool { +func (o *TargetConfigProperty) GetInputMasked() bool { if o == nil || IsNil(o.InputMasked) { var ret bool return ret @@ -157,7 +157,7 @@ func (o *ProviderProviderTargetProperty) GetInputMasked() bool { // GetInputMaskedOk returns a tuple with the InputMasked field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetInputMaskedOk() (*bool, bool) { +func (o *TargetConfigProperty) GetInputMaskedOk() (*bool, bool) { if o == nil || IsNil(o.InputMasked) { return nil, false } @@ -165,7 +165,7 @@ func (o *ProviderProviderTargetProperty) GetInputMaskedOk() (*bool, bool) { } // HasInputMasked returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasInputMasked() bool { +func (o *TargetConfigProperty) HasInputMasked() bool { if o != nil && !IsNil(o.InputMasked) { return true } @@ -174,12 +174,12 @@ func (o *ProviderProviderTargetProperty) HasInputMasked() bool { } // SetInputMasked gets a reference to the given bool and assigns it to the InputMasked field. -func (o *ProviderProviderTargetProperty) SetInputMasked(v bool) { +func (o *TargetConfigProperty) SetInputMasked(v bool) { o.InputMasked = &v } // GetOptions returns the Options field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetOptions() []string { +func (o *TargetConfigProperty) GetOptions() []string { if o == nil || IsNil(o.Options) { var ret []string return ret @@ -189,7 +189,7 @@ func (o *ProviderProviderTargetProperty) GetOptions() []string { // GetOptionsOk returns a tuple with the Options field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetOptionsOk() ([]string, bool) { +func (o *TargetConfigProperty) GetOptionsOk() ([]string, bool) { if o == nil || IsNil(o.Options) { return nil, false } @@ -197,7 +197,7 @@ func (o *ProviderProviderTargetProperty) GetOptionsOk() ([]string, bool) { } // HasOptions returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasOptions() bool { +func (o *TargetConfigProperty) HasOptions() bool { if o != nil && !IsNil(o.Options) { return true } @@ -206,12 +206,12 @@ func (o *ProviderProviderTargetProperty) HasOptions() bool { } // SetOptions gets a reference to the given []string and assigns it to the Options field. -func (o *ProviderProviderTargetProperty) SetOptions(v []string) { +func (o *TargetConfigProperty) SetOptions(v []string) { o.Options = v } // GetSuggestions returns the Suggestions field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetSuggestions() []string { +func (o *TargetConfigProperty) GetSuggestions() []string { if o == nil || IsNil(o.Suggestions) { var ret []string return ret @@ -221,7 +221,7 @@ func (o *ProviderProviderTargetProperty) GetSuggestions() []string { // GetSuggestionsOk returns a tuple with the Suggestions field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetSuggestionsOk() ([]string, bool) { +func (o *TargetConfigProperty) GetSuggestionsOk() ([]string, bool) { if o == nil || IsNil(o.Suggestions) { return nil, false } @@ -229,7 +229,7 @@ func (o *ProviderProviderTargetProperty) GetSuggestionsOk() ([]string, bool) { } // HasSuggestions returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasSuggestions() bool { +func (o *TargetConfigProperty) HasSuggestions() bool { if o != nil && !IsNil(o.Suggestions) { return true } @@ -238,14 +238,14 @@ func (o *ProviderProviderTargetProperty) HasSuggestions() bool { } // SetSuggestions gets a reference to the given []string and assigns it to the Suggestions field. -func (o *ProviderProviderTargetProperty) SetSuggestions(v []string) { +func (o *TargetConfigProperty) SetSuggestions(v []string) { o.Suggestions = v } // GetType returns the Type field value if set, zero value otherwise. -func (o *ProviderProviderTargetProperty) GetType() ProviderProviderTargetPropertyType { +func (o *TargetConfigProperty) GetType() ProviderTargetConfigPropertyType { if o == nil || IsNil(o.Type) { - var ret ProviderProviderTargetPropertyType + var ret ProviderTargetConfigPropertyType return ret } return *o.Type @@ -253,7 +253,7 @@ func (o *ProviderProviderTargetProperty) GetType() ProviderProviderTargetPropert // GetTypeOk returns a tuple with the Type field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderTargetProperty) GetTypeOk() (*ProviderProviderTargetPropertyType, bool) { +func (o *TargetConfigProperty) GetTypeOk() (*ProviderTargetConfigPropertyType, bool) { if o == nil || IsNil(o.Type) { return nil, false } @@ -261,7 +261,7 @@ func (o *ProviderProviderTargetProperty) GetTypeOk() (*ProviderProviderTargetPro } // HasType returns a boolean if a field has been set. -func (o *ProviderProviderTargetProperty) HasType() bool { +func (o *TargetConfigProperty) HasType() bool { if o != nil && !IsNil(o.Type) { return true } @@ -269,12 +269,12 @@ func (o *ProviderProviderTargetProperty) HasType() bool { return false } -// SetType gets a reference to the given ProviderProviderTargetPropertyType and assigns it to the Type field. -func (o *ProviderProviderTargetProperty) SetType(v ProviderProviderTargetPropertyType) { +// SetType gets a reference to the given ProviderTargetConfigPropertyType and assigns it to the Type field. +func (o *TargetConfigProperty) SetType(v ProviderTargetConfigPropertyType) { o.Type = &v } -func (o ProviderProviderTargetProperty) MarshalJSON() ([]byte, error) { +func (o TargetConfigProperty) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -282,7 +282,7 @@ func (o ProviderProviderTargetProperty) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProviderProviderTargetProperty) ToMap() (map[string]interface{}, error) { +func (o TargetConfigProperty) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.DefaultValue) { toSerialize["defaultValue"] = o.DefaultValue @@ -308,38 +308,38 @@ func (o ProviderProviderTargetProperty) ToMap() (map[string]interface{}, error) return toSerialize, nil } -type NullableProviderProviderTargetProperty struct { - value *ProviderProviderTargetProperty +type NullableTargetConfigProperty struct { + value *TargetConfigProperty isSet bool } -func (v NullableProviderProviderTargetProperty) Get() *ProviderProviderTargetProperty { +func (v NullableTargetConfigProperty) Get() *TargetConfigProperty { return v.value } -func (v *NullableProviderProviderTargetProperty) Set(val *ProviderProviderTargetProperty) { +func (v *NullableTargetConfigProperty) Set(val *TargetConfigProperty) { v.value = val v.isSet = true } -func (v NullableProviderProviderTargetProperty) IsSet() bool { +func (v NullableTargetConfigProperty) IsSet() bool { return v.isSet } -func (v *NullableProviderProviderTargetProperty) Unset() { +func (v *NullableTargetConfigProperty) Unset() { v.value = nil v.isSet = false } -func NewNullableProviderProviderTargetProperty(val *ProviderProviderTargetProperty) *NullableProviderProviderTargetProperty { - return &NullableProviderProviderTargetProperty{value: val, isSet: true} +func NewNullableTargetConfigProperty(val *TargetConfigProperty) *NullableTargetConfigProperty { + return &NullableTargetConfigProperty{value: val, isSet: true} } -func (v NullableProviderProviderTargetProperty) MarshalJSON() ([]byte, error) { +func (v NullableTargetConfigProperty) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProviderProviderTargetProperty) UnmarshalJSON(src []byte) error { +func (v *NullableTargetConfigProperty) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_workspace.go index be046fceb2..f2d187db3d 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_workspace.go @@ -21,10 +21,10 @@ var _ MappedNullable = &Workspace{} // Workspace struct for Workspace type Workspace struct { - Id string `json:"id"` - Name string `json:"name"` - Projects []Project `json:"projects"` - Target string `json:"target"` + Id string `json:"id"` + Name string `json:"name"` + Projects []Project `json:"projects"` + TargetConfig string `json:"targetConfig"` } type _Workspace Workspace @@ -33,12 +33,12 @@ type _Workspace Workspace // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspace(id string, name string, projects []Project, target string) *Workspace { +func NewWorkspace(id string, name string, projects []Project, targetConfig string) *Workspace { this := Workspace{} this.Id = id this.Name = name this.Projects = projects - this.Target = target + this.TargetConfig = targetConfig return &this } @@ -122,28 +122,28 @@ func (o *Workspace) SetProjects(v []Project) { o.Projects = v } -// GetTarget returns the Target field value -func (o *Workspace) GetTarget() string { +// GetTargetConfig returns the TargetConfig field value +func (o *Workspace) GetTargetConfig() string { if o == nil { var ret string return ret } - return o.Target + return o.TargetConfig } -// GetTargetOk returns a tuple with the Target field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *Workspace) GetTargetOk() (*string, bool) { +func (o *Workspace) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return &o.Target, true + return &o.TargetConfig, true } -// SetTarget sets field value -func (o *Workspace) SetTarget(v string) { - o.Target = v +// SetTargetConfig sets field value +func (o *Workspace) SetTargetConfig(v string) { + o.TargetConfig = v } func (o Workspace) MarshalJSON() ([]byte, error) { @@ -159,7 +159,7 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { toSerialize["id"] = o.Id toSerialize["name"] = o.Name toSerialize["projects"] = o.Projects - toSerialize["target"] = o.Target + toSerialize["targetConfig"] = o.TargetConfig return toSerialize, nil } @@ -171,7 +171,7 @@ func (o *Workspace) UnmarshalJSON(data []byte) (err error) { "id", "name", "projects", - "target", + "targetConfig", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go index c1c33251f9..ccd4c0219c 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_workspace_dto.go @@ -21,11 +21,11 @@ var _ MappedNullable = &WorkspaceDTO{} // WorkspaceDTO struct for WorkspaceDTO type WorkspaceDTO struct { - Id string `json:"id"` - Info *WorkspaceInfo `json:"info,omitempty"` - Name string `json:"name"` - Projects []Project `json:"projects"` - Target string `json:"target"` + Id string `json:"id"` + Info *WorkspaceInfo `json:"info,omitempty"` + Name string `json:"name"` + Projects []Project `json:"projects"` + TargetConfig string `json:"targetConfig"` } type _WorkspaceDTO WorkspaceDTO @@ -34,12 +34,12 @@ type _WorkspaceDTO WorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceDTO(id string, name string, projects []Project, target string) *WorkspaceDTO { +func NewWorkspaceDTO(id string, name string, projects []Project, targetConfig string) *WorkspaceDTO { this := WorkspaceDTO{} this.Id = id this.Name = name this.Projects = projects - this.Target = target + this.TargetConfig = targetConfig return &this } @@ -155,28 +155,28 @@ func (o *WorkspaceDTO) SetProjects(v []Project) { o.Projects = v } -// GetTarget returns the Target field value -func (o *WorkspaceDTO) GetTarget() string { +// GetTargetConfig returns the TargetConfig field value +func (o *WorkspaceDTO) GetTargetConfig() string { if o == nil { var ret string return ret } - return o.Target + return o.TargetConfig } -// GetTargetOk returns a tuple with the Target field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetTargetOk() (*string, bool) { +func (o *WorkspaceDTO) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return &o.Target, true + return &o.TargetConfig, true } -// SetTarget sets field value -func (o *WorkspaceDTO) SetTarget(v string) { - o.Target = v +// SetTargetConfig sets field value +func (o *WorkspaceDTO) SetTargetConfig(v string) { + o.TargetConfig = v } func (o WorkspaceDTO) MarshalJSON() ([]byte, error) { @@ -195,7 +195,7 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { } toSerialize["name"] = o.Name toSerialize["projects"] = o.Projects - toSerialize["target"] = o.Target + toSerialize["targetConfig"] = o.TargetConfig return toSerialize, nil } @@ -207,7 +207,7 @@ func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { "id", "name", "projects", - "target", + "targetConfig", } allProperties := make(map[string]interface{}) diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 3d79239d14..1d3ef80341 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -26,7 +26,7 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/projectconfig" . "github.com/daytonaio/daytona/pkg/cmd/provider" . "github.com/daytonaio/daytona/pkg/cmd/server" - . "github.com/daytonaio/daytona/pkg/cmd/target" + . "github.com/daytonaio/daytona/pkg/cmd/targetconfig" . "github.com/daytonaio/daytona/pkg/cmd/telemetry" . "github.com/daytonaio/daytona/pkg/cmd/workspace" "github.com/daytonaio/daytona/pkg/common" @@ -65,7 +65,7 @@ func Execute() error { rootCmd.AddCommand(ApiKeyCmd) rootCmd.AddCommand(ContainerRegistryCmd) rootCmd.AddCommand(ProviderCmd) - rootCmd.AddCommand(TargetCmd) + rootCmd.AddCommand(TargetConfigCmd) rootCmd.AddCommand(configCmd) rootCmd.AddCommand(ideCmd) rootCmd.AddCommand(ProfileCmd) @@ -190,8 +190,8 @@ func RunInitialScreenFlow(cmd *cobra.Command, args []string) error { return CodeCmd.RunE(cmd, []string{}) case "git-provider add": return GitProviderAddCmd.RunE(cmd, []string{}) - case "target set": - return TargetSetCmd.RunE(cmd, []string{}) + case "target-config set": + return TargetConfigSetCmd.RunE(cmd, []string{}) case "docs": return DocsCmd.RunE(cmd, []string{}) case "help": diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index f5d15b2808..5c3c886c24 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -19,7 +19,7 @@ import ( "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/provider" provider_view "github.com/daytonaio/daytona/pkg/views/provider" - "github.com/daytonaio/daytona/pkg/views/target" + "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" ) @@ -100,12 +100,12 @@ var providerInstallCmd = &cobra.Command{ views.RenderInfoMessageBold(fmt.Sprintf("Provider %s has been successfully installed", providerToInstall.Name)) - targets, res, err := apiClient.TargetAPI.ListTargets(context.Background()).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if slices.ContainsFunc(targets, func(t apiclient.ProviderTarget) bool { + if slices.ContainsFunc(targetConfigs, func(t apiclient.TargetConfig) bool { return t.ProviderInfo.Name == providerToInstall.Name }) { return nil @@ -115,7 +115,7 @@ var providerInstallCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title("Add a Target?"). + Title("Add a Target Config?"). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -127,39 +127,39 @@ var providerInstallCmd = &cobra.Command{ } if yesFlag { - targetManifest, res, err := apiClient.ProviderAPI.GetTargetManifest(context.Background(), providerToInstall.Name).Execute() + targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), providerToInstall.Name).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - targetToSet := &target.TargetView{ + targetConfigToSet := &targetconfig.TargetConfigView{ Options: "{}", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: targetconfig.ProviderInfo{ Name: providerToInstall.Name, Version: providerToInstall.Version, }, } - err = target.NewTargetNameInput(&targetToSet.Name, []string{}) + err = targetconfig.NewTargetConfigNameInput(&targetConfigToSet.Name, []string{}) if err != nil { return err } - err = target.SetTargetForm(targetToSet, *targetManifest) + err = targetconfig.SetTargetConfigForm(targetConfigToSet, *targetConfigManifest) if err != nil { return err } - targetData := apiclient.CreateProviderTargetDTO{ - Name: targetToSet.Name, - Options: targetToSet.Options, + targetConfigData := apiclient.CreateTargetConfigDTO{ + Name: targetConfigToSet.Name, + Options: targetConfigToSet.Options, ProviderInfo: apiclient.ProviderProviderInfo{ - Name: targetToSet.ProviderInfo.Name, - Version: targetToSet.ProviderInfo.Version, + Name: targetConfigToSet.ProviderInfo.Name, + Version: targetConfigToSet.ProviderInfo.Version, }, } - res, err = apiClient.TargetAPI.SetTarget(context.Background()).Target(targetData).Execute() + res, err = apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -167,7 +167,7 @@ var providerInstallCmd = &cobra.Command{ return err } - views.RenderInfoMessage("Target set successfully") + views.RenderInfoMessage("Target Config set successfully") } return nil }, diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 3fdf0e4f72..156f27ec3c 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -34,8 +34,8 @@ import ( "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/projectconfig" - "github.com/daytonaio/daytona/pkg/server/providertargets" "github.com/daytonaio/daytona/pkg/server/registry" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" @@ -229,7 +229,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - providerTargetStore, err := db.NewProviderTargetStore(dbConnection) + targetConfigStore, err := db.NewTargetConfigStore(dbConnection) if err != nil { return nil, err } @@ -312,8 +312,8 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe c.BuilderRegistryServer = util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain) } - providerTargetService := providertargets.NewProviderTargetService(providertargets.ProviderTargetServiceConfig{ - TargetStore: providerTargetStore, + targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ + TargetConfigStore: targetConfigStore, }) apiKeyService := apikeys.NewApiKeyService(apikeys.ApiKeyServiceConfig{ @@ -323,19 +323,19 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{ - LogsDir: wsLogsDir, - ProviderTargetService: providerTargetService, - ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - DaytonaDownloadUrl: getDaytonaScriptUrl(c), - ServerUrl: headscaleUrl, - ServerVersion: version, - RegistryUrl: c.RegistryUrl, - BaseDir: c.ProvidersDir, + LogsDir: wsLogsDir, + ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + DaytonaDownloadUrl: getDaytonaScriptUrl(c), + ServerUrl: headscaleUrl, + ServerVersion: version, + RegistryUrl: c.RegistryUrl, + BaseDir: c.ProvidersDir, CreateProviderNetworkKey: func(providerName string) (string, error) { return headscaleServer.CreateAuthKey() }, - ServerPort: c.HeadscalePort, - ApiPort: c.ApiPort, + ServerPort: c.HeadscalePort, + ApiPort: c.ApiPort, + TargetConfigService: targetConfigService, }) provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ @@ -344,7 +344,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ WorkspaceStore: workspaceStore, - TargetStore: providerTargetStore, + TargetConfigStore: targetConfigStore, ApiKeyService: apiKeyService, GitProviderService: gitProviderService, ContainerRegistryService: containerRegistryService, @@ -369,7 +369,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe Config: *c, Version: version, TailscaleServer: headscaleServer, - ProviderTargetService: providerTargetService, + TargetConfigService: targetConfigService, ContainerRegistryService: containerRegistryService, BuildService: buildService, ProjectConfigService: projectConfigService, diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go deleted file mode 100644 index 2253c91081..0000000000 --- a/pkg/cmd/target/target.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var TargetCmd = &cobra.Command{ - Use: "target", - Short: "Manage provider targets", - GroupID: util.SERVER_GROUP, -} - -func init() { - TargetCmd.AddCommand(targetListCmd) - TargetCmd.AddCommand(TargetSetCmd) - TargetCmd.AddCommand(targetRemoveCmd) - TargetCmd.AddCommand(targetSetDefaultCmd) -} diff --git a/pkg/cmd/target/list.go b/pkg/cmd/targetconfig/list.go similarity index 65% rename from pkg/cmd/target/list.go rename to pkg/cmd/targetconfig/list.go index 00677a9c11..2ed76d0552 100644 --- a/pkg/cmd/target/list.go +++ b/pkg/cmd/targetconfig/list.go @@ -1,20 +1,20 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - list_view "github.com/daytonaio/daytona/pkg/views/target/list" + "github.com/daytonaio/daytona/pkg/views/targetconfig" "github.com/spf13/cobra" ) -var targetListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", - Short: "List targets", + Short: "List target configs", Args: cobra.NoArgs, Aliases: []string{"ls"}, RunE: func(cmd *cobra.Command, args []string) error { @@ -25,22 +25,22 @@ var targetListCmd = &cobra.Command{ return err } - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } if format.FormatFlag != "" { - formattedData := format.NewFormatter(targetList) + formattedData := format.NewFormatter(targetConfigs) formattedData.Print() return nil } - list_view.ListTargets(targetList) + targetconfig.ListTargetConfigs(targetConfigs) return nil }, } func init() { - format.RegisterFormatFlag(targetListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/target/remove.go b/pkg/cmd/targetconfig/remove.go similarity index 61% rename from pkg/cmd/target/remove.go rename to pkg/cmd/targetconfig/remove.go index 82bd5cc8fc..8ea6852423 100644 --- a/pkg/cmd/target/remove.go +++ b/pkg/cmd/targetconfig/remove.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "context" @@ -14,21 +14,22 @@ import ( workspace_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target" + "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + + log "github.com/sirupsen/logrus" ) var yesFlag bool -var targetRemoveCmd = &cobra.Command{ - Use: "remove [TARGET_NAME]", - Short: "Remove target", +var removeCmd = &cobra.Command{ + Use: "remove [CONFIG_NAME]", + Short: "Remove target config", Args: cobra.RangeArgs(0, 1), Aliases: []string{"rm", "delete"}, RunE: func(cmd *cobra.Command, args []string) error { - var selectedTargetName string + var selectedConfigName string ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -47,17 +48,17 @@ var targetRemoveCmd = &cobra.Command{ return err } - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(targetList) == 0 { - views_util.NotifyEmptyTargetList(false) + if len(targetConfigs) == 0 { + views_util.NotifyEmptyTargetConfigList(false) return nil } - selectedTarget, err := target.GetTargetFromPrompt(targetList, activeProfile.Name, nil, false, "Remove") + selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(targetConfigs, activeProfile.Name, nil, false, "Remove") if err != nil { if common.IsCtrlCAbort(err) { return nil @@ -66,20 +67,20 @@ var targetRemoveCmd = &cobra.Command{ } } - selectedTargetName = selectedTarget.Name + selectedConfigName = selectedTargetConfig.Name } else { - selectedTargetName = args[0] + selectedConfigName = args[0] } if yesFlag { fmt.Println("Deleting all workspaces.") - err := RemoveTargetWorkspaces(ctx, apiClient, selectedTargetName) + err := RemoveTargetConfigWorkspaces(ctx, apiClient, selectedConfigName) if err != nil { return err } } else { - var targetWorkspaceCount int + var configWorkspaceCount int workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { @@ -87,17 +88,17 @@ var targetRemoveCmd = &cobra.Command{ } for _, workspace := range workspaceList { - if workspace.Target == selectedTargetName { - targetWorkspaceCount++ + if workspace.TargetConfig == selectedConfigName { + configWorkspaceCount++ } } - if targetWorkspaceCount > 0 { - title := fmt.Sprintf("Delete %d workspaces within %s?", targetWorkspaceCount, selectedTargetName) + if configWorkspaceCount > 0 { + title := fmt.Sprintf("Delete %d workspaces within %s?", configWorkspaceCount, selectedConfigName) description := "You might not be able to easily remove these workspaces later." - if targetWorkspaceCount == 1 { - title = fmt.Sprintf("Delete %d workspace within %s?", targetWorkspaceCount, selectedTargetName) + if configWorkspaceCount == 1 { + title = fmt.Sprintf("Delete %d workspace within %s?", configWorkspaceCount, selectedConfigName) description = "You might not be able to easily remove this workspace later." } @@ -116,38 +117,38 @@ var targetRemoveCmd = &cobra.Command{ } if yesFlag { - err := RemoveTargetWorkspaces(ctx, apiClient, selectedTargetName) + err := RemoveTargetConfigWorkspaces(ctx, apiClient, selectedConfigName) if err != nil { return err } } else { - fmt.Println("Proceeding with target removal without deleting workspaces.") + fmt.Println("Proceeding with target config removal without deleting workspaces.") } } } - res, err := apiClient.TargetAPI.RemoveTarget(ctx, selectedTargetName).Execute() + res, err := apiClient.TargetConfigAPI.RemoveTargetConfig(ctx, selectedConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessageBold(fmt.Sprintf("Target %s removed successfully", selectedTargetName)) + views.RenderInfoMessageBold(fmt.Sprintf("Target config %s removed successfully", selectedConfigName)) return nil }, } func init() { - targetRemoveCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all workspaces without prompt") + removeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all workspaces without prompt") } -func RemoveTargetWorkspaces(ctx context.Context, client *apiclient.APIClient, target string) error { +func RemoveTargetConfigWorkspaces(ctx context.Context, client *apiclient.APIClient, targetConfig string) error { workspaceList, res, err := client.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } for _, workspace := range workspaceList { - if workspace.Target != target { + if workspace.TargetConfig != targetConfig { continue } err := workspace_cmd.RemoveWorkspace(ctx, client, &workspace, false) diff --git a/pkg/cmd/target/set.go b/pkg/cmd/targetconfig/set.go similarity index 68% rename from pkg/cmd/target/set.go rename to pkg/cmd/targetconfig/set.go index 7ba4de9356..88bfe7fe36 100644 --- a/pkg/cmd/target/set.go +++ b/pkg/cmd/targetconfig/set.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "context" @@ -22,8 +22,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/views" provider_view "github.com/daytonaio/daytona/pkg/views/provider" - "github.com/daytonaio/daytona/pkg/views/target" - target_view "github.com/daytonaio/daytona/pkg/views/target" + "github.com/daytonaio/daytona/pkg/views/targetconfig" "github.com/spf13/cobra" log "github.com/sirupsen/logrus" @@ -31,9 +30,9 @@ import ( var pipeFile string -var TargetSetCmd = &cobra.Command{ +var TargetConfigSetCmd = &cobra.Command{ Use: "set", - Short: "Set provider target", + Short: "Set target config", Args: cobra.NoArgs, Aliases: []string{"s", "add", "update", "register", "edit"}, RunE: func(cmd *cobra.Command, args []string) error { @@ -124,22 +123,22 @@ var TargetSetCmd = &cobra.Command{ isNewProvider = true } - targets, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - filteredTargets := []apiclient.ProviderTarget{} - for _, t := range targets { + filteredConfigs := []apiclient.TargetConfig{} + for _, t := range targetConfigs { if t.ProviderInfo.Name == selectedProvider.Name { - filteredTargets = append(filteredTargets, t) + filteredConfigs = append(filteredConfigs, t) } } - var selectedTarget *target_view.TargetView + var selectedTargetConfig *targetconfig.TargetConfigView - if !isNewProvider || len(filteredTargets) > 0 { - selectedTarget, err = target.GetTargetFromPrompt(filteredTargets, activeProfile.Name, nil, true, "Set") + if !isNewProvider || len(filteredConfigs) > 0 { + selectedTargetConfig, err = targetconfig.GetTargetConfigFromPrompt(filteredConfigs, activeProfile.Name, nil, true, "Set") if err != nil { if common.IsCtrlCAbort(err) { return nil @@ -148,15 +147,15 @@ var TargetSetCmd = &cobra.Command{ } } } else { - selectedTarget = &target_view.TargetView{ - Name: target.NewTargetName, + selectedTargetConfig = &targetconfig.TargetConfigView{ + Name: targetconfig.NewTargetConfigName, Options: "{}", } } - if selectedTarget.Name == target.NewTargetName { - selectedTarget.Name = "" - err = target.NewTargetNameInput(&selectedTarget.Name, internal_util.ArrayMap(targets, func(t apiclient.ProviderTarget) string { + if selectedTargetConfig.Name == targetconfig.NewTargetConfigName { + selectedTargetConfig.Name = "" + err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, internal_util.ArrayMap(targetConfigs, func(t apiclient.TargetConfig) string { return t.Name })) if err != nil { @@ -164,31 +163,31 @@ var TargetSetCmd = &cobra.Command{ } } - targetManifest, res, err := apiClient.ProviderAPI.GetTargetManifest(context.Background(), selectedProvider.Name).Execute() + targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedProvider.Name).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - err = target.SetTargetForm(selectedTarget, *targetManifest) + err = targetconfig.SetTargetConfigForm(selectedTargetConfig, *targetConfigManifest) if err != nil { return err } - targetData := apiclient.CreateProviderTargetDTO{ - Name: selectedTarget.Name, - Options: selectedTarget.Options, + targetConfigData := apiclient.CreateTargetConfigDTO{ + Name: selectedTargetConfig.Name, + Options: selectedTargetConfig.Options, ProviderInfo: apiclient.ProviderProviderInfo{ Name: selectedProvider.Name, Version: selectedProvider.Version, }, } - res, err = apiClient.TargetAPI.SetTarget(context.Background()).Target(targetData).Execute() + res, err = apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage("Target set successfully and will be used by default") + views.RenderInfoMessage("Target config set successfully and will be used by default") return nil }, } @@ -200,35 +199,35 @@ func handleTargetJSON(data []byte) error { if err != nil { return err } - var selectedTarget *target_view.TargetView - err = parseJSON(data, &selectedTarget) + var selectedTargetConfig *targetconfig.TargetConfigView + err = parseJSON(data, &selectedTargetConfig) if err != nil { return fmt.Errorf("failed to parse input: %w", err) } - if selectedTarget.Name == "" { + if selectedTargetConfig.Name == "" { return errors.New("invalid input: 'name' field is required") } - if selectedTarget.Options == "" { + if selectedTargetConfig.Options == "" { return errors.New("option fields are required to setup your target") } - targetManifest, res, err := apiClient.ProviderAPI.GetTargetManifest(ctx, selectedTarget.ProviderInfo.Name).Execute() + targetManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(ctx, selectedTargetConfig.ProviderInfo.Name).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - err = validateProperty(*targetManifest, selectedTarget) + err = validateProperty(*targetManifest, selectedTargetConfig) if err != nil { return err } - targetData := apiclient.CreateProviderTargetDTO{ - Name: selectedTarget.Name, - Options: selectedTarget.Options, + targetConfigData := apiclient.CreateTargetConfigDTO{ + Name: selectedTargetConfig.Name, + Options: selectedTargetConfig.Options, ProviderInfo: apiclient.ProviderProviderInfo{ - Name: selectedTarget.ProviderInfo.Name, - Version: selectedTarget.ProviderInfo.Version, + Name: selectedTargetConfig.ProviderInfo.Name, + Version: selectedTargetConfig.ProviderInfo.Version, }, } - res, err = apiClient.TargetAPI.SetTarget(ctx).Target(targetData).Execute() + res, err = apiClient.TargetConfigAPI.SetTargetConfig(ctx).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -243,14 +242,14 @@ func parseJSON(data []byte, v interface{}) error { return errors.New("input is not a valid JSON") } -func validateProperty(targetManifest map[string]apiclient.ProviderProviderTargetProperty, target *target_view.TargetView) error { +func validateProperty(targetManifest map[string]apiclient.TargetConfigProperty, targetConfig *targetconfig.TargetConfigView) error { optionMap := make(map[string]interface{}) - if err := json.Unmarshal([]byte(target.Options), &optionMap); err != nil { + if err := json.Unmarshal([]byte(targetConfig.Options), &optionMap); err != nil { return fmt.Errorf("failed to parse options JSON: %w", err) } for optionKey := range optionMap { if _, exists := targetManifest[optionKey]; !exists { - return fmt.Errorf("invalid property '%s' for target manifest '%s'", optionKey, target.Name) + return fmt.Errorf("invalid property '%s' for target manifest '%s'", optionKey, targetConfig.Name) } } @@ -267,34 +266,34 @@ func validateProperty(targetManifest map[string]apiclient.ProviderProviderTarget property := targetManifest[name] if property.DisabledPredicate != nil && *property.DisabledPredicate != "" { - if matched, err := regexp.Match(*property.DisabledPredicate, []byte(target.Name)); err == nil && matched { + if matched, err := regexp.Match(*property.DisabledPredicate, []byte(targetConfig.Name)); err == nil && matched { if !contains(property.Options, optionMap[name]) { - return fmt.Errorf("unexpected property '%s' for target manifest '%s'", name, target.Name) + return fmt.Errorf("unexpected property '%s' for target manifest '%s'", name, targetConfig.Name) } continue } } switch *property.Type { - case apiclient.ProviderTargetPropertyTypeFloat, apiclient.ProviderTargetPropertyTypeInt: + case apiclient.TargetConfigPropertyTypeFloat, apiclient.TargetConfigPropertyTypeInt: _, isNumber := optionMap[name].(float64) if !isNumber { return fmt.Errorf("invalid type for %s, expected number", name) } - case apiclient.ProviderTargetPropertyTypeString: + case apiclient.TargetConfigPropertyTypeString: _, isString := optionMap[name].(string) if !isString { return fmt.Errorf("invalid type for %s, expected string", name) } - case apiclient.ProviderTargetPropertyTypeBoolean: + case apiclient.TargetConfigPropertyTypeBoolean: _, isBool := optionMap[name].(bool) if !isBool { return fmt.Errorf("invalid type for %s, expected boolean", name) } - case apiclient.ProviderTargetPropertyTypeOption: + case apiclient.TargetConfigPropertyTypeOption: optionValue, ok := optionMap[name].(string) if !ok { return fmt.Errorf("invalid value for '%s': expected a string", name) @@ -307,10 +306,10 @@ func validateProperty(targetManifest map[string]apiclient.ProviderProviderTarget } } if !valid { - return fmt.Errorf("unexpected property '%s' for target manifest '%s' : valid properties are %v", optionValue, target.Name, property.Options) + return fmt.Errorf("unexpected property '%s' for target manifest '%s' : valid properties are %v", optionValue, targetConfig.Name, property.Options) } - case apiclient.ProviderTargetPropertyTypeFilePath: + case apiclient.TargetConfigPropertyTypeFilePath: _, isString := optionMap[name].(string) if !isString { return fmt.Errorf("invalid type for %s, expected file path string", name) @@ -333,5 +332,5 @@ func contains(slice []string, item interface{}) bool { } func init() { - TargetSetCmd.Flags().StringVarP(&pipeFile, "file", "f", "", "Path to JSON file for target configuration, use '-' to read from stdin") + TargetConfigSetCmd.Flags().StringVarP(&pipeFile, "file", "f", "", "Path to JSON file for target configuration, use '-' to read from stdin") } diff --git a/pkg/cmd/target/setdefault.go b/pkg/cmd/targetconfig/setdefault.go similarity index 58% rename from pkg/cmd/target/setdefault.go rename to pkg/cmd/targetconfig/setdefault.go index 0388c6122f..c5d520653c 100644 --- a/pkg/cmd/target/setdefault.go +++ b/pkg/cmd/targetconfig/setdefault.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "context" @@ -11,17 +11,17 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" - target_view "github.com/daytonaio/daytona/pkg/views/target" + "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" ) -var targetSetDefaultCmd = &cobra.Command{ - Use: "set-default [TARGET_NAME]", - Short: "Set target to be used by default", +var setDefaultCmd = &cobra.Command{ + Use: "set-default [CONFIG_NAME]", + Short: "Set default target config", Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { - var targetName string + var configName string ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -30,13 +30,13 @@ var targetSetDefaultCmd = &cobra.Command{ } if len(args) == 0 { - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(targetList) == 0 { - views_util.NotifyEmptyTargetList(true) + if len(targetConfigs) == 0 { + views_util.NotifyEmptyTargetConfigList(true) return nil } @@ -50,7 +50,7 @@ var targetSetDefaultCmd = &cobra.Command{ return err } - selectedTarget, err := target_view.GetTargetFromPrompt(targetList, activeProfile.Name, nil, false, "Make Default") + selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(targetConfigs, activeProfile.Name, nil, false, "Make Default") if err != nil { if common.IsCtrlCAbort(err) { return nil @@ -59,21 +59,21 @@ var targetSetDefaultCmd = &cobra.Command{ } } - if selectedTarget == nil { + if selectedTargetConfig == nil { return nil } - targetName = selectedTarget.Name + configName = selectedTargetConfig.Name } else { - targetName = args[0] + configName = args[0] } - res, err := apiClient.TargetAPI.SetDefaultTarget(ctx, targetName).Execute() + res, err := apiClient.TargetConfigAPI.SetDefaultTargetConfig(ctx, configName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage(fmt.Sprintf("Target '%s' set as default", targetName)) + views.RenderInfoMessage(fmt.Sprintf("Target config '%s' set as default", configName)) return nil }, } diff --git a/pkg/cmd/targetconfig/target_config.go b/pkg/cmd/targetconfig/target_config.go new file mode 100644 index 0000000000..a23abba3ce --- /dev/null +++ b/pkg/cmd/targetconfig/target_config.go @@ -0,0 +1,23 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfig + +import ( + "github.com/daytonaio/daytona/internal/util" + "github.com/spf13/cobra" +) + +var TargetConfigCmd = &cobra.Command{ + Use: "target-config", + Aliases: []string{"tc"}, + Short: "Manage target configs", + GroupID: util.SERVER_GROUP, +} + +func init() { + TargetConfigCmd.AddCommand(listCmd) + TargetConfigCmd.AddCommand(TargetConfigSetCmd) + TargetConfigCmd.AddCommand(removeCmd) + TargetConfigCmd.AddCommand(setDefaultCmd) +} diff --git a/pkg/cmd/workspace/create.go b/pkg/cmd/workspace/create.go index c9f7276274..635c8e0b98 100644 --- a/pkg/cmd/workspace/create.go +++ b/pkg/cmd/workspace/create.go @@ -128,18 +128,18 @@ var CreateCmd = &cobra.Command{ }, i) } - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - target, err := workspace_util.GetTarget(workspace_util.GetTargetConfig{ - Ctx: ctx, - ApiClient: apiClient, - TargetList: targetList, - ActiveProfileName: activeProfile.Name, - TargetNameFlag: targetNameFlag, - PromptUsingTUI: promptUsingTUI, + targetConfig, err := workspace_util.GetTargetConfig(workspace_util.GetTargetConfigParams{ + Ctx: ctx, + ApiClient: apiClient, + TargetConfigs: targetConfigs, + ActiveProfileName: activeProfile.Name, + TargetConfigNameFlag: targetConfigNameFlag, + PromptUsingTUI: promptUsingTUI, }) if err != nil { if common.IsCtrlCAbort(err) { @@ -160,7 +160,7 @@ var CreateCmd = &cobra.Command{ } var tsConn *tsnet.Server - if target.Name != "local" || activeProfile.Id != "default" { + if targetConfig.Name != "local" || activeProfile.Id != "default" { tsConn, err = tailscale.GetConnection(&activeProfile) if err != nil { return err @@ -174,10 +174,10 @@ var CreateCmd = &cobra.Command{ go apiclient_util.ReadWorkspaceLogs(logsContext, activeProfile, id, projectNames, true, true, nil) createdWorkspace, res, err := apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(apiclient.CreateWorkspaceDTO{ - Id: id, - Name: workspaceName, - Target: target.Name, - Projects: projects, + Id: id, + Name: workspaceName, + TargetConfig: targetConfig.Name, + Projects: projects, }).Execute() if err != nil { stopLogs() @@ -239,7 +239,7 @@ var CreateCmd = &cobra.Command{ } var nameFlag string -var targetNameFlag string +var targetConfigNameFlag string var noIdeFlag bool var blankFlag bool var multiProjectFlag bool @@ -265,7 +265,7 @@ func init() { CreateCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace name") CreateCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) - CreateCmd.Flags().StringVarP(&targetNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") + CreateCmd.Flags().StringVarP(&targetConfigNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank project without using existing configurations") CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the workspace in the IDE after workspace creation") CreateCmd.Flags().BoolVar(&multiProjectFlag, "multi-project", false, "Workspace with multiple projects/repos") @@ -470,7 +470,7 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API } func waitForDial(workspace *apiclient.Workspace, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { - if workspace.Target == "local" && (activeProfile != nil && activeProfile.Id == "default") { + if workspace.TargetConfig == "local" && (activeProfile != nil && activeProfile.Id == "default") { err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspace.Id, workspace.Projects[0].Name, gpgKey) if err != nil { return err diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index 194aa31857..adedd911ef 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -58,7 +58,7 @@ var SshProxyCmd = &cobra.Command{ return err } - if workspace.Target == "local" && profile.Id == "default" { + if workspace.TargetConfig == "local" && profile.Id == "default" { // If the workspace is local, we directly access the ssh port through the container project := workspace.Projects[0] diff --git a/pkg/cmd/workspace/util/get_target.go b/pkg/cmd/workspace/util/get_target.go deleted file mode 100644 index 49b397ed9e..0000000000 --- a/pkg/cmd/workspace/util/get_target.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package util - -import ( - "context" - "errors" - "fmt" - - "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/provider" - "github.com/daytonaio/daytona/pkg/provider/manager" - provider_view "github.com/daytonaio/daytona/pkg/views/provider" - target_view "github.com/daytonaio/daytona/pkg/views/target" -) - -type GetTargetConfig struct { - Ctx context.Context - ApiClient *apiclient.APIClient - TargetList []apiclient.ProviderTarget - ActiveProfileName string - TargetNameFlag string - PromptUsingTUI bool -} - -func GetTarget(config GetTargetConfig) (*target_view.TargetView, error) { - if config.TargetNameFlag != "" { - for _, t := range config.TargetList { - if t.Name == config.TargetNameFlag { - return util.Pointer(target_view.GetTargetViewFromTarget(t)), nil - } - } - return nil, fmt.Errorf("target '%s' not found", config.TargetNameFlag) - } - - if !config.PromptUsingTUI { - for _, t := range config.TargetList { - if t.IsDefault { - return util.Pointer(target_view.GetTargetViewFromTarget(t)), nil - } - } - } - - serverConfig, res, err := config.ApiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - providersManifest, err := manager.NewProviderManager(manager.ProviderManagerConfig{ - RegistryUrl: serverConfig.RegistryUrl, - }).GetProvidersManifest() - if err != nil { - return nil, err - } - - var providerViewList []provider_view.ProviderView - if providersManifest != nil { - providersManifestLatest := providersManifest.GetLatestVersions() - if providersManifestLatest == nil { - return nil, errors.New("could not get latest provider versions") - } - - latestProviders := provider.GetProviderListFromManifest(providersManifestLatest) - - providerViewList, err = provider.GetProviderViewOptions(config.ApiClient, latestProviders, config.Ctx) - if err != nil { - return nil, err - } - } - - selectedTarget, err := target_view.GetTargetFromPrompt(config.TargetList, config.ActiveProfileName, &providerViewList, false, "Use") - if err != nil { - return nil, err - } - - if selectedTarget.ProviderInfo.Installed == nil || *selectedTarget.ProviderInfo.Installed || selectedTarget == nil { - return selectedTarget, nil - } - - err = provider.InstallProvider(config.ApiClient, provider_view.ProviderView{ - Name: selectedTarget.ProviderInfo.Name, - Version: selectedTarget.ProviderInfo.Version, - }, providersManifest) - if err != nil { - return nil, err - } - - targetManifest, res, err := config.ApiClient.ProviderAPI.GetTargetManifest(context.Background(), selectedTarget.ProviderInfo.Name).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - selectedTarget.Name = "" - err = target_view.NewTargetNameInput(&selectedTarget.Name, util.ArrayMap(config.TargetList, func(t apiclient.ProviderTarget) string { - return t.Name - })) - if err != nil { - return nil, err - } - - err = target_view.SetTargetForm(selectedTarget, *targetManifest) - if err != nil { - return nil, err - } - - res, err = config.ApiClient.TargetAPI.SetTarget(context.Background()).Target(apiclient.CreateProviderTargetDTO{ - Name: selectedTarget.Name, - Options: selectedTarget.Options, - ProviderInfo: apiclient.ProviderProviderInfo{ - Name: selectedTarget.ProviderInfo.Name, - Version: selectedTarget.ProviderInfo.Version, - }, - }).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - return selectedTarget, nil -} diff --git a/pkg/cmd/workspace/util/get_target_config.go b/pkg/cmd/workspace/util/get_target_config.go new file mode 100644 index 0000000000..1314a74d28 --- /dev/null +++ b/pkg/cmd/workspace/util/get_target_config.go @@ -0,0 +1,122 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "context" + "errors" + "fmt" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/provider" + "github.com/daytonaio/daytona/pkg/provider/manager" + provider_view "github.com/daytonaio/daytona/pkg/views/provider" + "github.com/daytonaio/daytona/pkg/views/targetconfig" +) + +type GetTargetConfigParams struct { + Ctx context.Context + ApiClient *apiclient.APIClient + TargetConfigs []apiclient.TargetConfig + ActiveProfileName string + TargetConfigNameFlag string + PromptUsingTUI bool +} + +func GetTargetConfig(params GetTargetConfigParams) (*targetconfig.TargetConfigView, error) { + if params.TargetConfigNameFlag != "" { + for _, t := range params.TargetConfigs { + if t.Name == params.TargetConfigNameFlag { + return util.Pointer(targetconfig.ToTargetConfigView(t)), nil + } + } + return nil, fmt.Errorf("target config '%s' not found", params.TargetConfigNameFlag) + } + + if !params.PromptUsingTUI { + for _, t := range params.TargetConfigs { + if t.IsDefault { + return util.Pointer(targetconfig.ToTargetConfigView(t)), nil + } + } + } + + serverConfig, res, err := params.ApiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + providersManifest, err := manager.NewProviderManager(manager.ProviderManagerConfig{ + RegistryUrl: serverConfig.RegistryUrl, + }).GetProvidersManifest() + if err != nil { + return nil, err + } + + var providerViewList []provider_view.ProviderView + if providersManifest != nil { + providersManifestLatest := providersManifest.GetLatestVersions() + if providersManifestLatest == nil { + return nil, errors.New("could not get latest provider versions") + } + + latestProviders := provider.GetProviderListFromManifest(providersManifestLatest) + + providerViewList, err = provider.GetProviderViewOptions(params.ApiClient, latestProviders, params.Ctx) + if err != nil { + return nil, err + } + } + + selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(params.TargetConfigs, params.ActiveProfileName, &providerViewList, false, "Use") + if err != nil { + return nil, err + } + + if selectedTargetConfig.ProviderInfo.Installed == nil || *selectedTargetConfig.ProviderInfo.Installed || selectedTargetConfig == nil { + return selectedTargetConfig, nil + } + + err = provider.InstallProvider(params.ApiClient, provider_view.ProviderView{ + Name: selectedTargetConfig.ProviderInfo.Name, + Version: selectedTargetConfig.ProviderInfo.Version, + }, providersManifest) + if err != nil { + return nil, err + } + + targetConfigManifest, res, err := params.ApiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedTargetConfig.ProviderInfo.Name).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + selectedTargetConfig.Name = "" + err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, util.ArrayMap(params.TargetConfigs, func(t apiclient.TargetConfig) string { + return t.Name + })) + if err != nil { + return nil, err + } + + err = targetconfig.SetTargetConfigForm(selectedTargetConfig, *targetConfigManifest) + if err != nil { + return nil, err + } + + res, err = params.ApiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(apiclient.CreateTargetConfigDTO{ + Name: selectedTargetConfig.Name, + Options: selectedTargetConfig.Options, + ProviderInfo: apiclient.ProviderProviderInfo{ + Name: selectedTargetConfig.ProviderInfo.Name, + Version: selectedTargetConfig.ProviderInfo.Version, + }, + }).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + return selectedTargetConfig, nil +} diff --git a/pkg/db/container_registry_store.go b/pkg/db/container_registry_store.go index d4f18b9085..3ef33d7062 100644 --- a/pkg/db/container_registry_store.go +++ b/pkg/db/container_registry_store.go @@ -30,12 +30,12 @@ func (s *ContainerRegistryStore) List() ([]*containerregistry.ContainerRegistry, return nil, tx.Error } - containerregistryTargets := []*containerregistry.ContainerRegistry{} + containerRegistries := []*containerregistry.ContainerRegistry{} for _, containerRegistryDTO := range containerRegistryDTOs { - containerregistryTargets = append(containerregistryTargets, ToContainerRegistry(containerRegistryDTO)) + containerRegistries = append(containerRegistries, ToContainerRegistry(containerRegistryDTO)) } - return containerregistryTargets, nil + return containerRegistries, nil } func (s *ContainerRegistryStore) Find(server string) (*containerregistry.ContainerRegistry, error) { diff --git a/pkg/db/dto/project.go b/pkg/db/dto/project.go index 04a34d4372..543f3925a0 100644 --- a/pkg/db/dto/project.go +++ b/pkg/db/dto/project.go @@ -58,7 +58,7 @@ type ProjectDTO struct { Build *ProjectBuildDTO `json:"build,omitempty" gorm:"serializer:json"` Repository RepositoryDTO `json:"repository" gorm:"serializer:json"` WorkspaceId string `json:"workspaceId"` - Target string `json:"target"` + TargetConfig string `json:"targetConfig"` ApiKey string `json:"apiKey"` State *ProjectStateDTO `json:"state,omitempty" gorm:"serializer:json"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` @@ -72,7 +72,7 @@ func ToProjectDTO(project *project.Project) ProjectDTO { Build: ToProjectBuildDTO(project.BuildConfig), Repository: ToRepositoryDTO(project.Repository), WorkspaceId: project.WorkspaceId, - Target: project.Target, + TargetConfig: project.TargetConfig, State: ToProjectStateDTO(project.State), ApiKey: project.ApiKey, GitProviderConfigId: project.GitProviderConfigId, @@ -164,7 +164,7 @@ func ToProject(projectDTO ProjectDTO) *project.Project { BuildConfig: ToProjectBuild(projectDTO.Build), Repository: ToRepository(projectDTO.Repository), WorkspaceId: projectDTO.WorkspaceId, - Target: projectDTO.Target, + TargetConfig: projectDTO.TargetConfig, State: ToProjectState(projectDTO.State), ApiKey: projectDTO.ApiKey, GitProviderConfigId: projectDTO.GitProviderConfigId, diff --git a/pkg/db/dto/provider_target.go b/pkg/db/dto/provider_target.go deleted file mode 100644 index 53f03752e6..0000000000 --- a/pkg/db/dto/provider_target.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import "github.com/daytonaio/daytona/pkg/provider" - -type ProviderTargetDTO struct { - Name string `json:"name" gorm:"primaryKey"` - ProviderName string `json:"providerName"` - ProviderLabel *string `json:"providerLabel,omitempty"` - ProviderVersion string `json:"providerVersion"` - Options string `json:"options"` - IsDefault bool `json:"isDefault"` -} - -func ToProviderTargetDTO(providerTarget *provider.ProviderTarget) ProviderTargetDTO { - return ProviderTargetDTO{ - Name: providerTarget.Name, - ProviderName: providerTarget.ProviderInfo.Name, - ProviderLabel: providerTarget.ProviderInfo.Label, - ProviderVersion: providerTarget.ProviderInfo.Version, - Options: providerTarget.Options, - IsDefault: providerTarget.IsDefault, - } -} - -func ToProviderTarget(providerTargetDTO ProviderTargetDTO) *provider.ProviderTarget { - return &provider.ProviderTarget{ - Name: providerTargetDTO.Name, - ProviderInfo: provider.ProviderInfo{ - Name: providerTargetDTO.ProviderName, - Label: providerTargetDTO.ProviderLabel, - Version: providerTargetDTO.ProviderVersion, - }, - Options: providerTargetDTO.Options, - IsDefault: providerTargetDTO.IsDefault, - } -} diff --git a/pkg/db/dto/target_config.go b/pkg/db/dto/target_config.go new file mode 100644 index 0000000000..feb6c2fc03 --- /dev/null +++ b/pkg/db/dto/target_config.go @@ -0,0 +1,39 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import "github.com/daytonaio/daytona/pkg/provider" + +type TargetConfigDTO struct { + Name string `json:"name" gorm:"primaryKey"` + ProviderName string `json:"providerName"` + ProviderLabel *string `json:"providerLabel,omitempty"` + ProviderVersion string `json:"providerVersion"` + Options string `json:"options"` + IsDefault bool `json:"isDefault"` +} + +func ToTargetConfigDTO(targetConfig *provider.TargetConfig) TargetConfigDTO { + return TargetConfigDTO{ + Name: targetConfig.Name, + ProviderName: targetConfig.ProviderInfo.Name, + ProviderLabel: targetConfig.ProviderInfo.Label, + ProviderVersion: targetConfig.ProviderInfo.Version, + Options: targetConfig.Options, + IsDefault: targetConfig.IsDefault, + } +} + +func ToTargetConfig(targetConfigDTO TargetConfigDTO) *provider.TargetConfig { + return &provider.TargetConfig{ + Name: targetConfigDTO.Name, + ProviderInfo: provider.ProviderInfo{ + Name: targetConfigDTO.ProviderName, + Label: targetConfigDTO.ProviderLabel, + Version: targetConfigDTO.ProviderVersion, + }, + Options: targetConfigDTO.Options, + IsDefault: targetConfigDTO.IsDefault, + } +} diff --git a/pkg/db/dto/workspace.go b/pkg/db/dto/workspace.go index 09976cf243..4f800c5bc5 100644 --- a/pkg/db/dto/workspace.go +++ b/pkg/db/dto/workspace.go @@ -10,11 +10,11 @@ import ( ) type WorkspaceDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name" gorm:"unique"` - Target string `json:"target"` - ApiKey string `json:"apiKey"` - Projects []ProjectDTO `gorm:"serializer:json"` + Id string `gorm:"primaryKey"` + Name string `json:"name" gorm:"unique"` + TargetConfig string `json:"config"` + ApiKey string `json:"apiKey"` + Projects []ProjectDTO `gorm:"serializer:json"` } func (w WorkspaceDTO) GetProject(name string) (*ProjectDTO, error) { @@ -29,10 +29,10 @@ func (w WorkspaceDTO) GetProject(name string) (*ProjectDTO, error) { func ToWorkspaceDTO(workspace *workspace.Workspace) WorkspaceDTO { workspaceDTO := WorkspaceDTO{ - Id: workspace.Id, - Name: workspace.Name, - Target: workspace.Target, - ApiKey: workspace.ApiKey, + Id: workspace.Id, + Name: workspace.Name, + TargetConfig: workspace.TargetConfig, + ApiKey: workspace.ApiKey, } for _, project := range workspace.Projects { @@ -44,10 +44,10 @@ func ToWorkspaceDTO(workspace *workspace.Workspace) WorkspaceDTO { func ToWorkspace(workspaceDTO WorkspaceDTO) *workspace.Workspace { workspace := workspace.Workspace{ - Id: workspaceDTO.Id, - Name: workspaceDTO.Name, - Target: workspaceDTO.Target, - ApiKey: workspaceDTO.ApiKey, + Id: workspaceDTO.Id, + Name: workspaceDTO.Name, + TargetConfig: workspaceDTO.TargetConfig, + ApiKey: workspaceDTO.ApiKey, } for _, projectDTO := range workspaceDTO.Projects { diff --git a/pkg/db/provider_target_store.go b/pkg/db/provider_target_store.go deleted file mode 100644 index a0efda39d8..0000000000 --- a/pkg/db/provider_target_store.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "gorm.io/gorm" - - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/provider" -) - -type ProviderTargetStore struct { - db *gorm.DB -} - -func NewProviderTargetStore(db *gorm.DB) (*ProviderTargetStore, error) { - err := db.AutoMigrate(&ProviderTargetDTO{}) - if err != nil { - return nil, err - } - - return &ProviderTargetStore{db: db}, nil -} - -func (s *ProviderTargetStore) List(filter *provider.TargetFilter) ([]*provider.ProviderTarget, error) { - targetDTOs := []ProviderTargetDTO{} - tx := processTargetFilters(s.db, filter).Find(&targetDTOs) - - if tx.Error != nil { - return nil, tx.Error - } - - targets := []*provider.ProviderTarget{} - for _, targetDTO := range targetDTOs { - targets = append(targets, ToProviderTarget(targetDTO)) - } - - return targets, nil -} - -func (s *ProviderTargetStore) Find(filter *provider.TargetFilter) (*provider.ProviderTarget, error) { - targetDTO := ProviderTargetDTO{} - tx := processTargetFilters(s.db, filter).First(&targetDTO) - - if tx.Error != nil { - if IsRecordNotFound(tx.Error) { - return nil, provider.ErrTargetNotFound - } - return nil, tx.Error - } - - return ToProviderTarget(targetDTO), nil -} - -func (s *ProviderTargetStore) Save(target *provider.ProviderTarget) error { - tx := s.db.Save(ToProviderTargetDTO(target)) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (s *ProviderTargetStore) Delete(target *provider.ProviderTarget) error { - tx := s.db.Delete(ToProviderTargetDTO(target)) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return provider.ErrTargetNotFound - } - - return nil -} - -func processTargetFilters(tx *gorm.DB, filter *provider.TargetFilter) *gorm.DB { - if filter != nil { - if filter.Name != nil { - tx = tx.Where("name = ?", *filter.Name) - } - if filter.Default != nil { - tx = tx.Where("is_default = ?", *filter.Default) - } - } - - return tx -} diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go new file mode 100644 index 0000000000..59be63cd7e --- /dev/null +++ b/pkg/db/target_config_store.go @@ -0,0 +1,86 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + + "github.com/daytonaio/daytona/internal/util" + . "github.com/daytonaio/daytona/pkg/db/dto" + "github.com/daytonaio/daytona/pkg/provider" +) + +type TargetConfigStore struct { + db *gorm.DB +} + +func NewTargetConfigStore(db *gorm.DB) (*TargetConfigStore, error) { + err := db.AutoMigrate(&TargetConfigDTO{}) + if err != nil { + return nil, err + } + + return &TargetConfigStore{db: db}, nil +} + +func (s *TargetConfigStore) List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { + targetConfigDTOs := []TargetConfigDTO{} + tx := processTargetConfigFilters(s.db, filter).Find(&targetConfigDTOs) + + if tx.Error != nil { + return nil, tx.Error + } + + return util.ArrayMap(targetConfigDTOs, func(targetConfigDTO TargetConfigDTO) *provider.TargetConfig { + return ToTargetConfig(targetConfigDTO) + }), nil +} + +func (s *TargetConfigStore) Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) { + targetConfigDTO := TargetConfigDTO{} + tx := processTargetConfigFilters(s.db, filter).First(&targetConfigDTO) + + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, provider.ErrTargetConfigNotFound + } + return nil, tx.Error + } + + return ToTargetConfig(targetConfigDTO), nil +} + +func (s *TargetConfigStore) Save(targetConfig *provider.TargetConfig) error { + tx := s.db.Save(ToTargetConfigDTO(targetConfig)) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *TargetConfigStore) Delete(targetConfig *provider.TargetConfig) error { + tx := s.db.Delete(ToTargetConfigDTO(targetConfig)) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return provider.ErrTargetConfigNotFound + } + + return nil +} + +func processTargetConfigFilters(tx *gorm.DB, filter *provider.TargetConfigFilter) *gorm.DB { + if filter != nil { + if filter.Name != nil { + tx = tx.Where("name = ?", *filter.Name) + } + if filter.Default != nil { + tx = tx.Where("is_default = ?", *filter.Default) + } + } + + return tx +} diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index ac9bdd045b..c886146155 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -22,17 +22,17 @@ var project1 = &project.Project{ Url: "https://github.com/daytonaio/daytona", Name: "daytona", }, - BuildConfig: &buildconfig.BuildConfig{}, - Image: "test-image:tag", - User: "test-user", - WorkspaceId: "123", - Target: "test", + Image: "test-image:tag", + User: "test-user", + WorkspaceId: "123", + TargetConfig: "local", + BuildConfig: &buildconfig.BuildConfig{}, } var workspace1 = &workspace.Workspace{ - Id: "123", - Name: "test", - Target: "test", + Id: "123", + Name: "test", + TargetConfig: "local", Projects: []*project.Project{ project1, }, diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go index c016b24a1e..781c8e3025 100644 --- a/pkg/docker/info_test.go +++ b/pkg/docker/info_test.go @@ -46,9 +46,9 @@ func (s *DockerClientTestSuite) TestGetProjectInfo() { func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { workspaceWithoutProjects := &workspace.Workspace{ - Id: "123", - Name: "test", - Target: "local", + Id: "123", + Name: "test", + TargetConfig: "local", } wsInfo, err := s.dockerClient.GetWorkspaceInfo(workspaceWithoutProjects) diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index 6f554f3af0..d5bee641bb 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -16,7 +16,7 @@ import ( "github.com/daytonaio/daytona/internal/util" os_util "github.com/daytonaio/daytona/pkg/os" . "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/server/providertargets" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/shirou/gopsutil/process" @@ -54,7 +54,7 @@ type ProviderManagerConfig struct { ServerVersion string ApiUrl string LogsDir string - ProviderTargetService providertargets.IProviderTargetService + TargetConfigService targetconfigs.ITargetConfigService RegistryUrl string BaseDir string CreateProviderNetworkKey func(providerName string) (string, error) @@ -70,7 +70,7 @@ func NewProviderManager(config ProviderManagerConfig) *ProviderManager { serverVersion: config.ServerVersion, apiUrl: config.ApiUrl, logsDir: config.LogsDir, - providerTargetService: config.ProviderTargetService, + targetConfigService: config.TargetConfigService, registryUrl: config.RegistryUrl, baseDir: config.BaseDir, createProviderNetworkKey: config.CreateProviderNetworkKey, @@ -88,7 +88,7 @@ type ProviderManager struct { serverPort uint32 apiPort uint32 logsDir string - providerTargetService providertargets.IProviderTargetService + targetConfigService targetconfigs.ITargetConfigService registryUrl string baseDir string createProviderNetworkKey func(providerName string) (string, error) @@ -148,28 +148,28 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool return fmt.Errorf("failed to get provider: %w", err) } - existingTargets, err := m.providerTargetService.Map() + existingTargetConfigs, err := m.targetConfigService.Map() if err != nil { - return errors.New("failed to get targets: " + err.Error()) + return errors.New("failed to get target configs: " + err.Error()) } - presetTargets, err := (*p).GetPresetTargets() + presetTargetConfigs, err := (*p).GetPresetTargetConfigs() if err != nil { - return errors.New("failed to get preset targets: " + err.Error()) + return errors.New("failed to get preset target configs: " + err.Error()) } - log.Infof("Setting preset targets for %s", pluginRef.name) - for _, target := range *presetTargets { - if _, ok := existingTargets[target.Name]; ok { - log.Infof("Target %s already exists. Skipping...", target.Name) + log.Infof("Setting preset target configs for %s", pluginRef.name) + for _, targetConfig := range *presetTargetConfigs { + if _, ok := existingTargetConfigs[targetConfig.Name]; ok { + log.Infof("Target config %s already exists. Skipping...", targetConfig.Name) continue } - err := m.providerTargetService.Save(&target) + err := m.targetConfigService.Save(&targetConfig) if err != nil { - log.Errorf("Failed to set target %s: %s", target.Name, err) + log.Errorf("Failed to set target %s: %s", targetConfig.Name, err) } else { - log.Infof("Target %s set", target.Name) + log.Infof("Target %s set", targetConfig.Name) } } log.Infof("Preset targets set for %s", pluginRef.name) diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index a3fcfcd696..8b2557a304 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -17,8 +17,8 @@ type Provider interface { GetInfo() (ProviderInfo, error) CheckRequirements() (*[]RequirementStatus, error) - GetTargetManifest() (*ProviderTargetManifest, error) - GetPresetTargets() (*[]ProviderTarget, error) + GetTargetConfigManifest() (*TargetConfigManifest, error) + GetPresetTargetConfigs() (*[]TargetConfig, error) CreateWorkspace(*WorkspaceRequest) (*util.Empty, error) StartWorkspace(*WorkspaceRequest) (*util.Empty, error) diff --git a/pkg/provider/rpc_client.go b/pkg/provider/rpc_client.go index 86f3e8650d..e9f619db44 100644 --- a/pkg/provider/rpc_client.go +++ b/pkg/provider/rpc_client.go @@ -32,16 +32,16 @@ func (m *ProviderRPCClient) CheckRequirements() (*[]RequirementStatus, error) { return &result, err } -func (m *ProviderRPCClient) GetTargetManifest() (*ProviderTargetManifest, error) { - var resp ProviderTargetManifest - err := m.client.Call("Plugin.GetTargetManifest", new(interface{}), &resp) +func (m *ProviderRPCClient) GetTargetConfigManifest() (*TargetConfigManifest, error) { + var resp TargetConfigManifest + err := m.client.Call("Plugin.GetTargetConfigManifest", new(interface{}), &resp) return &resp, err } -func (m *ProviderRPCClient) GetPresetTargets() (*[]ProviderTarget, error) { - var resp []ProviderTarget - err := m.client.Call("Plugin.GetPresetTargets", new(interface{}), &resp) +func (m *ProviderRPCClient) GetPresetTargetConfigs() (*[]TargetConfig, error) { + var resp []TargetConfig + err := m.client.Call("Plugin.GetPresetTargetConfigs", new(interface{}), &resp) return &resp, err } diff --git a/pkg/provider/rpc_server.go b/pkg/provider/rpc_server.go index 251ae926d8..7b3dc624f1 100644 --- a/pkg/provider/rpc_server.go +++ b/pkg/provider/rpc_server.go @@ -37,23 +37,23 @@ func (m *ProviderRPCServer) CheckRequirements(arg interface{}, resp *[]Requireme return nil } -func (m *ProviderRPCServer) GetTargetManifest(arg interface{}, resp *ProviderTargetManifest) error { - targetManifest, err := m.Impl.GetTargetManifest() +func (m *ProviderRPCServer) GetTargetConfigManifest(arg interface{}, resp *TargetConfigManifest) error { + targetConfigManifest, err := m.Impl.GetTargetConfigManifest() if err != nil { return err } - *resp = *targetManifest + *resp = *targetConfigManifest return nil } -func (m *ProviderRPCServer) GetPresetTargets(arg interface{}, resp *[]ProviderTarget) error { - targets, err := m.Impl.GetPresetTargets() +func (m *ProviderRPCServer) GetPresetTargetConfigs(arg interface{}, resp *[]TargetConfig) error { + targetConfigs, err := m.Impl.GetPresetTargetConfigs() if err != nil { return err } - *resp = *targets + *resp = *targetConfigs return nil } diff --git a/pkg/provider/store.go b/pkg/provider/store.go index 82aa0a2d6b..fcb66aec6f 100644 --- a/pkg/provider/store.go +++ b/pkg/provider/store.go @@ -5,22 +5,22 @@ package provider import "errors" -type TargetFilter struct { +type TargetConfigFilter struct { Name *string Default *bool } -type TargetStore interface { - List(filter *TargetFilter) ([]*ProviderTarget, error) - Find(filter *TargetFilter) (*ProviderTarget, error) - Save(target *ProviderTarget) error - Delete(target *ProviderTarget) error +type TargetConfigStore interface { + List(filter *TargetConfigFilter) ([]*TargetConfig, error) + Find(filter *TargetConfigFilter) (*TargetConfig, error) + Save(targetConfig *TargetConfig) error + Delete(targetConfig *TargetConfig) error } var ( - ErrTargetNotFound = errors.New("target not found") + ErrTargetConfigNotFound = errors.New("target config not found") ) -func IsTargetNotFound(err error) bool { - return err.Error() == ErrTargetNotFound.Error() +func IsTargetConfigNotFound(err error) bool { + return err.Error() == ErrTargetConfigNotFound.Error() } diff --git a/pkg/provider/types.go b/pkg/provider/types.go index dea970bbb4..2f8d6c91ae 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -32,12 +32,12 @@ type InitializeProviderRequest struct { } type WorkspaceRequest struct { - TargetOptions string - Workspace *workspace.Workspace + TargetConfigOptions string + Workspace *workspace.Workspace } type ProjectRequest struct { - TargetOptions string + TargetConfigOptions string ContainerRegistry *containerregistry.ContainerRegistry Project *project.Project GitProviderConfig *gitprovider.GitProviderConfig @@ -45,32 +45,32 @@ type ProjectRequest struct { BuilderContainerRegistry *containerregistry.ContainerRegistry } -type ProviderTarget struct { +type TargetConfig struct { Name string `json:"name" validate:"required"` ProviderInfo ProviderInfo `json:"providerInfo" validate:"required"` // JSON encoded map of options Options string `json:"options" validate:"required"` IsDefault bool `json:"isDefault" validate:"required"` -} // @name ProviderTarget +} // @name TargetConfig -type ProviderTargetManifest map[string]ProviderTargetProperty // @name ProviderTargetManifest +type TargetConfigManifest map[string]TargetConfigProperty // @name TargetConfigManifest -type ProviderTargetPropertyType string +type TargetConfigPropertyType string const ( - ProviderTargetPropertyTypeString ProviderTargetPropertyType = "string" - ProviderTargetPropertyTypeOption ProviderTargetPropertyType = "option" - ProviderTargetPropertyTypeBoolean ProviderTargetPropertyType = "boolean" - ProviderTargetPropertyTypeInt ProviderTargetPropertyType = "int" - ProviderTargetPropertyTypeFloat ProviderTargetPropertyType = "float" - ProviderTargetPropertyTypeFilePath ProviderTargetPropertyType = "file-path" + TargetConfigPropertyTypeString TargetConfigPropertyType = "string" + TargetConfigPropertyTypeOption TargetConfigPropertyType = "option" + TargetConfigPropertyTypeBoolean TargetConfigPropertyType = "boolean" + TargetConfigPropertyTypeInt TargetConfigPropertyType = "int" + TargetConfigPropertyTypeFloat TargetConfigPropertyType = "float" + TargetConfigPropertyTypeFilePath TargetConfigPropertyType = "file-path" ) -type ProviderTargetProperty struct { - Type ProviderTargetPropertyType +type TargetConfigProperty struct { + Type TargetConfigPropertyType InputMasked bool - // A regex string matched with the name of the target to determine if the property should be disabled - // If the regex matches the target name, the property will be disabled + // A regex string matched with the name of the target config to determine if the property should be disabled + // If the regex matches the target config name, the property will be disabled // E.g. "^local$" will disable the property for the local target DisabledPredicate string // DefaultValue is converted into the appropriate type based on the Type @@ -78,11 +78,11 @@ type ProviderTargetProperty struct { DefaultValue string // Brief description of the property Description string - // Options is only used if the Type is ProviderTargetPropertyTypeOption + // Options is only used if the Type is TargetConfigPropertyTypeOption Options []string // Suggestions is an optional list of auto-complete values to assist the user while filling the field Suggestions []string -} +} // @name TargetConfigProperty type RequirementStatus struct { Name string diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index dcd577844a..b70ca674b7 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -8,28 +8,28 @@ import ( "github.com/daytonaio/daytona/pkg/workspace" ) -func (p *Provisioner) CreateWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) +func (p *Provisioner) CreateWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ - TargetOptions: target.Options, - Workspace: workspace, + TargetConfigOptions: targetConfig.Options, + Workspace: workspace, }) return err } func (p *Provisioner) CreateProject(params ProjectParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.TargetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).CreateProject(&provider.ProjectRequest{ - TargetOptions: params.Target.Options, + TargetConfigOptions: params.TargetConfig.Options, Project: params.Project, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index 4e965bf79d..4c49d20284 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -9,29 +9,29 @@ import ( "github.com/daytonaio/daytona/pkg/workspace/project" ) -func (p *Provisioner) DestroyWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) +func (p *Provisioner) DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).DestroyWorkspace(&provider.WorkspaceRequest{ - TargetOptions: target.Options, - Workspace: workspace, + TargetConfigOptions: targetConfig.Options, + Workspace: workspace, }) return err } -func (p *Provisioner) DestroyProject(proj *project.Project, target *provider.ProviderTarget) error { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) +func (p *Provisioner) DestroyProject(proj *project.Project, targetConfig *provider.TargetConfig) error { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).DestroyProject(&provider.ProjectRequest{ - TargetOptions: target.Options, - Project: proj, + TargetConfigOptions: targetConfig.Options, + Project: proj, }) return err diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go index e926908c10..25d1ba2a7e 100644 --- a/pkg/provisioner/info.go +++ b/pkg/provisioner/info.go @@ -16,19 +16,19 @@ type InfoResult struct { } // Gets the workspace info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, ws *workspace.Workspace, target *provider.ProviderTarget) (*workspace.WorkspaceInfo, error) { +func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, ws *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { ch := make(chan InfoResult, 1) go func() { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { ch <- InfoResult{nil, err} return } info, err := (*targetProvider).GetWorkspaceInfo(&provider.WorkspaceRequest{ - TargetOptions: target.Options, - Workspace: ws, + TargetConfigOptions: targetConfig.Options, + Workspace: ws, }) ch <- InfoResult{info, err} diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index e40d47a702..83b2b19d5a 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -16,7 +16,7 @@ import ( type ProjectParams struct { Project *project.Project - Target *provider.ProviderTarget + TargetConfig *provider.TargetConfig ContainerRegistry *containerregistry.ContainerRegistry GitProviderConfig *gitprovider.GitProviderConfig BuilderImage string @@ -25,14 +25,14 @@ type ProjectParams struct { type IProvisioner interface { CreateProject(params ProjectParams) error - CreateWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error - DestroyProject(project *project.Project, target *provider.ProviderTarget) error - DestroyWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error - GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, target *provider.ProviderTarget) (*workspace.WorkspaceInfo, error) + CreateWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error + DestroyProject(project *project.Project, targetConfig *provider.TargetConfig) error + DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error + GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) StartProject(params ProjectParams) error - StartWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error - StopProject(project *project.Project, target *provider.ProviderTarget) error - StopWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error + StartWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error + StopProject(project *project.Project, targetConfig *provider.TargetConfig) error + StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error } type ProvisionerConfig struct { diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index 50033ddab3..79fe3e6b8a 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -8,28 +8,28 @@ import ( "github.com/daytonaio/daytona/pkg/workspace" ) -func (p *Provisioner) StartWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) +func (p *Provisioner) StartWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ - TargetOptions: target.Options, - Workspace: workspace, + TargetConfigOptions: targetConfig.Options, + Workspace: workspace, }) return err } func (p *Provisioner) StartProject(params ProjectParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.TargetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StartProject(&provider.ProjectRequest{ - TargetOptions: params.Target.Options, + TargetConfigOptions: params.TargetConfig.Options, Project: params.Project, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index 28f21c97ce..b8b29316cd 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -9,29 +9,29 @@ import ( "github.com/daytonaio/daytona/pkg/workspace/project" ) -func (p *Provisioner) StopWorkspace(workspace *workspace.Workspace, target *provider.ProviderTarget) error { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) +func (p *Provisioner) StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StopWorkspace(&provider.WorkspaceRequest{ - TargetOptions: target.Options, - Workspace: workspace, + TargetConfigOptions: targetConfig.Options, + Workspace: workspace, }) return err } -func (p *Provisioner) StopProject(proj *project.Project, target *provider.ProviderTarget) error { - targetProvider, err := p.providerManager.GetProvider(target.ProviderInfo.Name) +func (p *Provisioner) StopProject(proj *project.Project, targetConfig *provider.TargetConfig) error { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StopProject(&provider.ProjectRequest{ - TargetOptions: target.Options, - Project: proj, + TargetConfigOptions: targetConfig.Options, + Project: proj, }) return err diff --git a/pkg/server/providertargets/service.go b/pkg/server/providertargets/service.go deleted file mode 100644 index 4a2f22834c..0000000000 --- a/pkg/server/providertargets/service.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package providertargets - -import ( - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/provider" -) - -type IProviderTargetService interface { - Delete(target *provider.ProviderTarget) error - Find(filter *provider.TargetFilter) (*provider.ProviderTarget, error) - List(filter *provider.TargetFilter) ([]*provider.ProviderTarget, error) - Map() (map[string]*provider.ProviderTarget, error) - Save(target *provider.ProviderTarget) error - SetDefault(target *provider.ProviderTarget) error -} - -type ProviderTargetServiceConfig struct { - TargetStore provider.TargetStore -} - -type ProviderTargetService struct { - targetStore provider.TargetStore -} - -func NewProviderTargetService(config ProviderTargetServiceConfig) IProviderTargetService { - return &ProviderTargetService{ - targetStore: config.TargetStore, - } -} - -func (s *ProviderTargetService) List(filter *provider.TargetFilter) ([]*provider.ProviderTarget, error) { - return s.targetStore.List(filter) -} - -func (s *ProviderTargetService) Map() (map[string]*provider.ProviderTarget, error) { - list, err := s.targetStore.List(nil) - if err != nil { - return nil, err - } - - targets := make(map[string]*provider.ProviderTarget) - for _, target := range list { - targets[target.Name] = target - } - - return targets, nil -} - -func (s *ProviderTargetService) Find(filter *provider.TargetFilter) (*provider.ProviderTarget, error) { - return s.targetStore.Find(filter) -} - -func (s *ProviderTargetService) Save(target *provider.ProviderTarget) error { - err := s.targetStore.Save(target) - if err != nil { - return err - } - - return s.SetDefault(target) -} - -func (s *ProviderTargetService) Delete(target *provider.ProviderTarget) error { - return s.targetStore.Delete(target) -} - -func (s *ProviderTargetService) SetDefault(target *provider.ProviderTarget) error { - currentTarget, err := s.Find(&provider.TargetFilter{ - Name: &target.Name, - }) - if err != nil { - return err - } - - defaultTarget, err := s.Find(&provider.TargetFilter{ - Default: util.Pointer(true), - }) - if err != nil && err != provider.ErrTargetNotFound { - return err - } - - if defaultTarget != nil { - defaultTarget.IsDefault = false - err := s.targetStore.Save(defaultTarget) - if err != nil { - return err - } - } - - currentTarget.IsDefault = true - return s.targetStore.Save(currentTarget) -} diff --git a/pkg/server/providertargets/service_test.go b/pkg/server/providertargets/service_test.go deleted file mode 100644 index 05a14bdbb1..0000000000 --- a/pkg/server/providertargets/service_test.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package providertargets_test - -import ( - "testing" - - "github.com/daytonaio/daytona/internal/testing/provider/targets" - "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/server/providertargets" - "github.com/stretchr/testify/suite" -) - -var providerTarget1 *provider.ProviderTarget = &provider.ProviderTarget{ - Name: "target1", - ProviderInfo: provider.ProviderInfo{ - Name: "provider1", - Version: "v1", - }, - Options: "", -} - -var providerTarget2 *provider.ProviderTarget = &provider.ProviderTarget{ - Name: "target2", - ProviderInfo: provider.ProviderInfo{ - Name: "provider2", - Version: "v1", - }, - Options: "", -} - -var providerTarget3 *provider.ProviderTarget = &provider.ProviderTarget{ - Name: "target3", - ProviderInfo: provider.ProviderInfo{ - Name: "provider1", - Version: "v1", - }, - Options: "", -} - -var providerTarget4 *provider.ProviderTarget = &provider.ProviderTarget{ - Name: "new-target", - ProviderInfo: provider.ProviderInfo{ - Name: "provider2", - Version: "v1", - }, - Options: "", -} - -var expectedProviderTargets []*provider.ProviderTarget -var expectedProviderTargetsMap map[string]*provider.ProviderTarget - -type ProviderTargetServiceTestSuite struct { - suite.Suite - providerTargetService providertargets.IProviderTargetService - targetStore provider.TargetStore -} - -func NewProviderTargetServiceTestSuite() *ProviderTargetServiceTestSuite { - return &ProviderTargetServiceTestSuite{} -} - -func (s *ProviderTargetServiceTestSuite) SetupTest() { - expectedProviderTargets = []*provider.ProviderTarget{ - providerTarget1, providerTarget2, providerTarget3, - } - - expectedProviderTargetsMap = map[string]*provider.ProviderTarget{ - providerTarget1.Name: providerTarget1, - providerTarget2.Name: providerTarget2, - providerTarget3.Name: providerTarget3, - } - - s.targetStore = targets.NewInMemoryTargetStore() - s.providerTargetService = providertargets.NewProviderTargetService(providertargets.ProviderTargetServiceConfig{ - TargetStore: s.targetStore, - }) - - for _, target := range expectedProviderTargets { - _ = s.providerTargetService.Save(target) - } -} - -func TestProviderTargetService(t *testing.T) { - suite.Run(t, NewProviderTargetServiceTestSuite()) -} - -func (s *ProviderTargetServiceTestSuite) TestList() { - require := s.Require() - - providerTargets, err := s.providerTargetService.List(nil) - require.Nil(err) - require.ElementsMatch(expectedProviderTargets, providerTargets) -} - -func (s *ProviderTargetServiceTestSuite) TestMap() { - require := s.Require() - - providerTargetsMap, err := s.providerTargetService.Map() - require.Nil(err) - require.Equal(expectedProviderTargetsMap, providerTargetsMap) -} - -func (s *ProviderTargetServiceTestSuite) TestFind() { - require := s.Require() - - providerTarget, err := s.providerTargetService.Find(&provider.TargetFilter{ - Name: &providerTarget1.Name, - }) - require.Nil(err) - require.Equal(providerTarget1, providerTarget) -} - -func (s *ProviderTargetServiceTestSuite) TestSetDefault() { - require := s.Require() - - err := s.providerTargetService.SetDefault(providerTarget2) - require.Nil(err) - - providerTarget, err := s.providerTargetService.Find(&provider.TargetFilter{ - Name: &providerTarget2.Name, - }) - require.Nil(err) - - require.Equal(providerTarget2, providerTarget) -} - -func (s *ProviderTargetServiceTestSuite) TestSave() { - expectedProviderTargets = append(expectedProviderTargets, providerTarget4) - - require := s.Require() - - err := s.providerTargetService.Save(providerTarget4) - require.Nil(err) - - providerTargets, err := s.providerTargetService.List(nil) - require.Nil(err) - require.ElementsMatch(expectedProviderTargets, providerTargets) -} - -func (s *ProviderTargetServiceTestSuite) TestDelete() { - expectedProviderTargets = expectedProviderTargets[:2] - - require := s.Require() - - err := s.providerTargetService.Delete(providerTarget3) - require.Nil(err) - - providerTargets, err := s.providerTargetService.List(nil) - require.Nil(err) - require.ElementsMatch(expectedProviderTargets, providerTargets) -} diff --git a/pkg/server/server.go b/pkg/server/server.go index 5c960cb05f..a3eb04481f 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/projectconfig" - "github.com/daytonaio/daytona/pkg/server/providertargets" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/hashicorp/go-plugin" @@ -26,7 +26,7 @@ type ServerInstanceConfig struct { Config Config Version string TailscaleServer TailscaleServer - ProviderTargetService providertargets.IProviderTargetService + TargetConfigService targetconfigs.ITargetConfigService ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService ProjectConfigService projectconfig.IProjectConfigService @@ -55,7 +55,7 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { config: serverConfig.Config, Version: serverConfig.Version, TailscaleServer: serverConfig.TailscaleServer, - ProviderTargetService: serverConfig.ProviderTargetService, + TargetConfigService: serverConfig.TargetConfigService, ContainerRegistryService: serverConfig.ContainerRegistryService, BuildService: serverConfig.BuildService, ProjectConfigService: serverConfig.ProjectConfigService, @@ -77,7 +77,7 @@ type Server struct { config Config Version string TailscaleServer TailscaleServer - ProviderTargetService providertargets.IProviderTargetService + TargetConfigService targetconfigs.ITargetConfigService ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService ProjectConfigService projectconfig.IProjectConfigService diff --git a/pkg/server/providertargets/dto/providertargets.go b/pkg/server/targetconfigs/dto/target_config.go similarity index 83% rename from pkg/server/providertargets/dto/providertargets.go rename to pkg/server/targetconfigs/dto/target_config.go index fc2e6411cc..97671f5b61 100644 --- a/pkg/server/providertargets/dto/providertargets.go +++ b/pkg/server/targetconfigs/dto/target_config.go @@ -5,8 +5,8 @@ package dto import "github.com/daytonaio/daytona/pkg/provider" -type CreateProviderTargetDTO struct { +type CreateTargetConfigDTO struct { Name string `json:"name" validate:"required"` ProviderInfo provider.ProviderInfo `json:"providerInfo" validate:"required"` Options string `json:"options" validate:"required"` -} // @name CreateProviderTargetDTO +} // @name CreateTargetConfigDTO diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go new file mode 100644 index 0000000000..8eaf81e85f --- /dev/null +++ b/pkg/server/targetconfigs/service.go @@ -0,0 +1,94 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfigs + +import ( + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/provider" +) + +type ITargetConfigService interface { + Delete(targetConfig *provider.TargetConfig) error + Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) + List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) + Map() (map[string]*provider.TargetConfig, error) + Save(targetConfig *provider.TargetConfig) error + SetDefault(targetConfig *provider.TargetConfig) error +} + +type TargetConfigServiceConfig struct { + TargetConfigStore provider.TargetConfigStore +} + +type TargetConfigService struct { + targetConfigStore provider.TargetConfigStore +} + +func NewTargetConfigService(config TargetConfigServiceConfig) ITargetConfigService { + return &TargetConfigService{ + targetConfigStore: config.TargetConfigStore, + } +} + +func (s *TargetConfigService) List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { + return s.targetConfigStore.List(filter) +} + +func (s *TargetConfigService) Map() (map[string]*provider.TargetConfig, error) { + list, err := s.targetConfigStore.List(nil) + if err != nil { + return nil, err + } + + targetConfigs := make(map[string]*provider.TargetConfig) + for _, targetConfig := range list { + targetConfigs[targetConfig.Name] = targetConfig + } + + return targetConfigs, nil +} + +func (s *TargetConfigService) Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) { + return s.targetConfigStore.Find(filter) +} + +func (s *TargetConfigService) Save(targetConfig *provider.TargetConfig) error { + err := s.targetConfigStore.Save(targetConfig) + if err != nil { + return err + } + + return s.SetDefault(targetConfig) +} + +func (s *TargetConfigService) Delete(targetConfig *provider.TargetConfig) error { + return s.targetConfigStore.Delete(targetConfig) +} + +func (s *TargetConfigService) SetDefault(targetConfig *provider.TargetConfig) error { + currentConfig, err := s.Find(&provider.TargetConfigFilter{ + Name: &targetConfig.Name, + }) + if err != nil { + return err + } + + defaultConfig, err := s.Find(&provider.TargetConfigFilter{ + Default: util.Pointer(true), + }) + if err != nil && err != provider.ErrTargetConfigNotFound { + return err + } + + if defaultConfig != nil { + defaultConfig.IsDefault = false + err := s.targetConfigStore.Save(defaultConfig) + if err != nil { + return err + } + } + + currentConfig.IsDefault = true + return s.targetConfigStore.Save(currentConfig) +} diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go new file mode 100644 index 0000000000..83b8c22d2e --- /dev/null +++ b/pkg/server/targetconfigs/service_test.go @@ -0,0 +1,153 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfigs_test + +import ( + "testing" + + t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/stretchr/testify/suite" +) + +var targetConfig1 *provider.TargetConfig = &provider.TargetConfig{ + Name: "targetConfig1", + ProviderInfo: provider.ProviderInfo{ + Name: "provider1", + Version: "v1", + }, + Options: "", +} + +var targetConfig2 *provider.TargetConfig = &provider.TargetConfig{ + Name: "targetConfig2", + ProviderInfo: provider.ProviderInfo{ + Name: "provider2", + Version: "v1", + }, + Options: "", +} + +var targetConfig3 *provider.TargetConfig = &provider.TargetConfig{ + Name: "targetConfig3", + ProviderInfo: provider.ProviderInfo{ + Name: "provider1", + Version: "v1", + }, + Options: "", +} + +var targetConfig4 *provider.TargetConfig = &provider.TargetConfig{ + Name: "newTargetConfig", + ProviderInfo: provider.ProviderInfo{ + Name: "provider2", + Version: "v1", + }, + Options: "", +} + +var expectedConfigs []*provider.TargetConfig +var expectedConfigMap map[string]*provider.TargetConfig + +type TargetConfigServiceTestSuite struct { + suite.Suite + targetConfigService targetconfigs.ITargetConfigService + targetConfigStore provider.TargetConfigStore +} + +func NewTargetConfigServiceTestSuite() *TargetConfigServiceTestSuite { + return &TargetConfigServiceTestSuite{} +} + +func (s *TargetConfigServiceTestSuite) SetupTest() { + expectedConfigs = []*provider.TargetConfig{ + targetConfig1, targetConfig2, targetConfig3, + } + + expectedConfigMap = map[string]*provider.TargetConfig{ + targetConfig1.Name: targetConfig1, + targetConfig2.Name: targetConfig2, + targetConfig3.Name: targetConfig3, + } + + s.targetConfigStore = t_targetconfigs.NewInMemoryTargetConfigStore() + s.targetConfigService = targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ + TargetConfigStore: s.targetConfigStore, + }) + + for _, targetConfig := range expectedConfigs { + _ = s.targetConfigService.Save(targetConfig) + } +} + +func TestTargetConfigService(t *testing.T) { + suite.Run(t, NewTargetConfigServiceTestSuite()) +} + +func (s *TargetConfigServiceTestSuite) TestList() { + require := s.Require() + + targetConfigs, err := s.targetConfigService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedConfigs, targetConfigs) +} + +func (s *TargetConfigServiceTestSuite) TestMap() { + require := s.Require() + + targetConfigsMap, err := s.targetConfigService.Map() + require.Nil(err) + require.Equal(expectedConfigMap, targetConfigsMap) +} + +func (s *TargetConfigServiceTestSuite) TestFind() { + require := s.Require() + + targetConfig, err := s.targetConfigService.Find(&provider.TargetConfigFilter{ + Name: &targetConfig1.Name, + }) + require.Nil(err) + require.Equal(targetConfig1, targetConfig) +} + +func (s *TargetConfigServiceTestSuite) TestSetDefault() { + require := s.Require() + + err := s.targetConfigService.SetDefault(targetConfig2) + require.Nil(err) + + targetConfig, err := s.targetConfigService.Find(&provider.TargetConfigFilter{ + Name: &targetConfig2.Name, + }) + require.Nil(err) + + require.Equal(targetConfig2, targetConfig) +} + +func (s *TargetConfigServiceTestSuite) TestSave() { + expectedConfigs = append(expectedConfigs, targetConfig4) + + require := s.Require() + + err := s.targetConfigService.Save(targetConfig4) + require.Nil(err) + + targetConfigs, err := s.targetConfigService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedConfigs, targetConfigs) +} + +func (s *TargetConfigServiceTestSuite) TestDelete() { + expectedConfigs = expectedConfigs[:2] + + require := s.Require() + + err := s.targetConfigService.Delete(targetConfig3) + require.Nil(err) + + targetConfigs, err := s.targetConfigService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedConfigs, targetConfigs) +} diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index acb5afa54d..2ccd6fd4c2 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -57,9 +57,9 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo } w := &workspace.Workspace{ - Id: req.Id, - Name: req.Name, - Target: req.Target, + Id: req.Id, + Name: req.Name, + TargetConfig: req.TargetConfig, } apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, w.Id) @@ -124,7 +124,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo p.WorkspaceId = w.Id p.ApiKey = apiKey - p.Target = w.Target + p.TargetConfig = w.TargetConfig w.Projects = append(w.Projects, p) } @@ -133,12 +133,12 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo return nil, err } - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &w.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) if err != nil { return w, err } - w, err = s.createWorkspace(ctx, w, target) + w, err = s.createWorkspace(ctx, w, targetConfig) if !telemetry.TelemetryEnabled(ctx) { return w, err @@ -146,7 +146,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w, target) + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w, targetConfig) event := telemetry.ServerEventWorkspaceCreated if err != nil { telemetryProps["error"] = err.Error() @@ -160,7 +160,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo return w, err } -func (s *WorkspaceService) createProject(p *project.Project, target *provider.ProviderTarget, logWriter io.Writer) error { +func (s *WorkspaceService) createProject(p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { logWriter.Write([]byte(fmt.Sprintf("Creating project %s\n", p.Name))) cr, err := s.containerRegistryService.FindByImageName(p.Image) @@ -184,7 +184,7 @@ func (s *WorkspaceService) createProject(p *project.Project, target *provider.Pr err = s.provisioner.CreateProject(provisioner.ProjectParams{ Project: p, - Target: target, + TargetConfig: targetConfig, ContainerRegistry: cr, GitProviderConfig: gc, BuilderImage: s.builderImage, @@ -199,7 +199,7 @@ func (s *WorkspaceService) createProject(p *project.Project, target *provider.Pr return nil } -func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Workspace, target *provider.ProviderTarget) (*workspace.Workspace, error) { +func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.Workspace, error) { wsLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, logs.LogSourceServer) defer wsLogger.Close() @@ -212,7 +212,7 @@ func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Wo ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err := s.provisioner.CreateWorkspace(ws, target) + err := s.provisioner.CreateWorkspace(ws, targetConfig) if err != nil { return nil, err } @@ -243,7 +243,7 @@ func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Wo return nil, err } - err = s.createProject(p, target, projectLogger) + err = s.createProject(p, targetConfig, projectLogger) if err != nil { return nil, err } @@ -251,7 +251,7 @@ func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Wo wsLogger.Write([]byte("Workspace creation complete. Pending start...\n")) - err = s.startWorkspace(ctx, ws, target, wsLogger) + err = s.startWorkspace(ctx, ws, targetConfig, wsLogger) if err != nil { return nil, err } diff --git a/pkg/server/workspaces/dto/workspace.go b/pkg/server/workspaces/dto/workspace.go index a5fea289ad..b6c02c857d 100644 --- a/pkg/server/workspaces/dto/workspace.go +++ b/pkg/server/workspaces/dto/workspace.go @@ -21,10 +21,10 @@ type ProjectDTO struct { } // @name ProjectDTO type CreateWorkspaceDTO struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - Target string `json:"target" validate:"required"` - Projects []CreateProjectDTO `json:"projects" validate:"required,gt=0,dive"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` + Projects []CreateProjectDTO `json:"projects" validate:"required,gt=0,dive"` } // @name CreateWorkspaceDTO type CreateProjectDTO struct { diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index 3b705e2461..b21d83979b 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -29,7 +29,7 @@ func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, return &response, nil } - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &ws.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &ws.TargetConfig}) if err != nil { return nil, err } @@ -40,7 +40,7 @@ func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, resultCh := make(chan provisioner.InfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws, target) + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws, targetConfig) resultCh <- provisioner.InfoResult{Info: workspaceInfo, Err: err} }() diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index 996bb6bc39..589bfa9a21 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -35,9 +35,9 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] go func(i int) { defer wg.Done() - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &w.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) if err != nil { - log.Error(fmt.Errorf("failed to get target for %s", w.Target)) + log.Error(fmt.Errorf("failed to get target config for %s", w.TargetConfig)) return } @@ -47,7 +47,7 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] resultCh := make(chan provisioner.InfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, w, target) + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, w, targetConfig) resultCh <- provisioner.InfoResult{Info: workspaceInfo, Err: err} }() diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index bda3117d2b..f635e95c54 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -21,20 +21,20 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri log.Infof("Destroying workspace %s", workspace.Id) - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &workspace.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &workspace.TargetConfig}) if err != nil { return err } for _, project := range workspace.Projects { // todo: go routines - err := s.provisioner.DestroyProject(project, target) + err := s.provisioner.DestroyProject(project, targetConfig) if err != nil { return err } } - err = s.provisioner.DestroyWorkspace(workspace, target) + err = s.provisioner.DestroyWorkspace(workspace, targetConfig) if err != nil { return err } @@ -74,7 +74,7 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, target) + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, targetConfig) event := telemetry.ServerEventWorkspaceDestroyed if err != nil { telemetryProps["error"] = err.Error() @@ -97,17 +97,17 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId log.Infof("Destroying workspace %s", workspace.Id) - target, _ := s.targetStore.Find(&provider.TargetFilter{Name: &workspace.Target}) + targetConfig, _ := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &workspace.TargetConfig}) for _, project := range workspace.Projects { // todo: go routines - err := s.provisioner.DestroyProject(project, target) + err := s.provisioner.DestroyProject(project, targetConfig) if err != nil { log.Error(err) } } - err = s.provisioner.DestroyWorkspace(workspace, target) + err = s.provisioner.DestroyWorkspace(workspace, targetConfig) if err != nil { log.Error(err) } @@ -138,7 +138,7 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, target) + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, targetConfig) event := telemetry.ServerEventWorkspaceDestroyed if err != nil { telemetryProps["error"] = err.Error() diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index 21a131e1f4..508ead25d5 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -37,13 +37,13 @@ type IWorkspaceService interface { StopWorkspace(ctx context.Context, workspaceId string) error } -type targetStore interface { - Find(filter *provider.TargetFilter) (*provider.ProviderTarget, error) +type targetConfigStore interface { + Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) } type WorkspaceServiceConfig struct { WorkspaceStore workspace.Store - TargetStore targetStore + TargetConfigStore targetConfigStore ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService ProjectConfigService projectconfig.IProjectConfigService @@ -63,7 +63,7 @@ type WorkspaceServiceConfig struct { func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { return &WorkspaceService{ workspaceStore: config.WorkspaceStore, - targetStore: config.TargetStore, + targetConfigStore: config.TargetConfigStore, containerRegistryService: config.ContainerRegistryService, buildService: config.BuildService, projectConfigService: config.ProjectConfigService, @@ -83,7 +83,7 @@ func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { type WorkspaceService struct { workspaceStore workspace.Store - targetStore targetStore + targetConfigStore targetConfigStore containerRegistryService containerregistries.IContainerRegistryService buildService builds.IBuildService projectConfigService projectconfig.IProjectConfigService diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index d0d01d07c2..b65149a7ac 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - t_targets "github.com/daytonaio/daytona/internal/testing/provider/targets" + t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" "github.com/daytonaio/daytona/internal/testing/server/workspaces/mocks" "github.com/daytonaio/daytona/internal/util" @@ -34,8 +34,8 @@ const serverVersion = "0.0.0-test" const defaultProjectUser = "daytona" const defaultProjectImage = "daytonaio/workspace-project:latest" -var target = provider.ProviderTarget{ - Name: "test-target", +var targetConfig = provider.TargetConfig{ + Name: "test-target-config", ProviderInfo: provider.ProviderInfo{ Name: "test-provider", Version: "test", @@ -56,9 +56,9 @@ var gitProviderConfig = gitprovider.GitProviderConfig{ } var createWorkspaceDto = dto.CreateWorkspaceDTO{ - Name: "test", - Id: "test", - Target: target.Name, + Name: "test", + Id: "test", + TargetConfig: targetConfig.Name, Projects: []dto.CreateProjectDTO{ { Name: "project1", @@ -102,8 +102,8 @@ func TestWorkspaceService(t *testing.T) { projectConfigService := mocks.NewMockProjectConfigService() - targetStore := t_targets.NewInMemoryTargetStore() - err := targetStore.Save(&target) + targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() + err := targetConfigStore.Save(&targetConfig) require.Nil(t, err) apiKeyService := mocks.NewMockApiKeyService() @@ -115,7 +115,7 @@ func TestWorkspaceService(t *testing.T) { service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ WorkspaceStore: workspaceStore, - TargetStore: targetStore, + TargetConfigStore: targetConfigStore, ServerApiUrl: serverApiUrl, ServerUrl: serverUrl, ServerVersion: serverVersion, @@ -135,8 +135,8 @@ func TestWorkspaceService(t *testing.T) { containerRegistryService.On("FindByImageName", defaultProjectImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) - mockProvisioner.On("CreateWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("StartWorkspace", mock.Anything, &target).Return(nil) + mockProvisioner.On("CreateWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Generate", apikey.ApiKeyTypeWorkspace, createWorkspaceDto.Id).Return(createWorkspaceDto.Id, nil) gitProviderService.On("GetLastCommitSha", createWorkspaceDto.Projects[0].Source.Repository).Return("123", nil) @@ -154,7 +154,7 @@ func TestWorkspaceService(t *testing.T) { ApiKey: createWorkspaceDto.Projects[0].Name, GitProviderConfigId: createWorkspaceDto.Projects[0].GitProviderConfigId, WorkspaceId: createWorkspaceDto.Id, - Target: createWorkspaceDto.Target, + TargetConfig: createWorkspaceDto.TargetConfig, } proj.EnvVars = project.GetProjectEnvVars(proj, project.ProjectEnvVarParams{ @@ -166,7 +166,7 @@ func TestWorkspaceService(t *testing.T) { mockProvisioner.On("CreateProject", provisioner.ProjectParams{ Project: proj, - Target: &target, + TargetConfig: &targetConfig, ContainerRegistry: containerRegistry, GitProviderConfig: &gitProviderConfig, BuilderImage: defaultProjectImage, @@ -174,7 +174,7 @@ func TestWorkspaceService(t *testing.T) { }).Return(nil) mockProvisioner.On("StartProject", provisioner.ProjectParams{ Project: proj, - Target: &target, + TargetConfig: &targetConfig, ContainerRegistry: containerRegistry, GitProviderConfig: &gitProviderConfig, BuilderImage: defaultProjectImage, @@ -207,7 +207,7 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("GetWorkspace", func(t *testing.T) { - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &target).Return(&workspaceInfo, nil) + mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &targetConfig).Return(&workspaceInfo, nil) workspace, err := service.GetWorkspace(ctx, createWorkspaceDto.Id, true) @@ -225,7 +225,7 @@ func TestWorkspaceService(t *testing.T) { t.Run("ListWorkspaces", func(t *testing.T) { verbose := false - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &target).Return(&workspaceInfo, nil) + mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &targetConfig).Return(&workspaceInfo, nil) workspaces, err := service.ListWorkspaces(ctx, verbose) @@ -239,7 +239,7 @@ func TestWorkspaceService(t *testing.T) { t.Run("ListWorkspaces - verbose", func(t *testing.T) { verbose := true - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &target).Return(&workspaceInfo, nil) + mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &targetConfig).Return(&workspaceInfo, nil) workspaces, err := service.ListWorkspaces(ctx, verbose) @@ -252,8 +252,8 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("StartWorkspace", func(t *testing.T) { - mockProvisioner.On("StartWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("StartProject", mock.Anything).Return(nil) + mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartProject", mock.Anything, &targetConfig).Return(nil) err := service.StartWorkspace(ctx, createWorkspaceDto.Id) @@ -261,8 +261,8 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("StartProject", func(t *testing.T) { - mockProvisioner.On("StartWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("StartProject", mock.Anything).Return(nil) + mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartProject", mock.Anything, &targetConfig).Return(nil) err := service.StartProject(ctx, createWorkspaceDto.Id, createWorkspaceDto.Projects[0].Name) @@ -270,8 +270,8 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("StopWorkspace", func(t *testing.T) { - mockProvisioner.On("StopWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("StopProject", mock.Anything, &target).Return(nil) + mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopProject", mock.Anything, &targetConfig).Return(nil) err := service.StopWorkspace(ctx, createWorkspaceDto.Id) @@ -279,8 +279,8 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("StopProject", func(t *testing.T) { - mockProvisioner.On("StopWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("StopProject", mock.Anything, &target).Return(nil) + mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopProject", mock.Anything, &targetConfig).Return(nil) err := service.StopProject(ctx, createWorkspaceDto.Id, createWorkspaceDto.Projects[0].Name) @@ -288,8 +288,8 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("RemoveWorkspace", func(t *testing.T) { - mockProvisioner.On("DestroyWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("DestroyProject", mock.Anything, &target).Return(nil) + mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyProject", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveWorkspace(ctx, createWorkspaceDto.Id) @@ -301,11 +301,11 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("ForceRemoveWorkspace", func(t *testing.T) { - err := workspaceStore.Save(&workspace.Workspace{Id: createWorkspaceDto.Id, Target: target.Name}) + err := workspaceStore.Save(&workspace.Workspace{Id: createWorkspaceDto.Id, TargetConfig: targetConfig.Name}) require.Nil(t, err) - mockProvisioner.On("DestroyWorkspace", mock.Anything, &target).Return(nil) - mockProvisioner.On("DestroyProject", mock.Anything, &target).Return(nil) + mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyProject", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveWorkspace(ctx, createWorkspaceDto.Id) @@ -347,7 +347,7 @@ func workspaceEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace *worksp require.Equal(t, req.Id, workspace.Id) require.Equal(t, req.Name, workspace.Name) - require.Equal(t, req.Target, workspace.Target) + require.Equal(t, req.TargetConfig, workspace.TargetConfig) for i, project := range workspace.Projects { require.Equal(t, req.Projects[i].Name, project.Name) @@ -355,7 +355,7 @@ func workspaceEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace *worksp require.Equal(t, req.Projects[i].Source.Repository.Url, project.Repository.Url) require.Equal(t, req.Projects[i].Source.Repository.Name, project.Repository.Name) require.Equal(t, project.ApiKey, project.Name) - require.Equal(t, project.Target, req.Target) + require.Equal(t, project.TargetConfig, req.TargetConfig) require.Equal(t, project.Image, projectImage) } } @@ -365,7 +365,7 @@ func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto. require.Equal(t, req.Id, workspace.Id) require.Equal(t, req.Name, workspace.Name) - require.Equal(t, req.Target, workspace.Target) + require.Equal(t, req.TargetConfig, workspace.TargetConfig) if verbose { require.Equal(t, workspace.Info.Name, workspaceInfo.Name) @@ -380,7 +380,7 @@ func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto. require.Equal(t, req.Projects[i].Source.Repository.Url, project.Repository.Url) require.Equal(t, req.Projects[i].Source.Repository.Name, project.Repository.Name) require.Equal(t, project.ApiKey, project.Name) - require.Equal(t, project.Target, req.Target) + require.Equal(t, project.TargetConfig, req.TargetConfig) require.Equal(t, project.Image, projectImage) if verbose { diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index a92fe3cf87..5695e8573f 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -27,7 +27,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin return ErrWorkspaceNotFound } - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &w.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) if err != nil { return err } @@ -37,7 +37,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin wsLogWriter := io.MultiWriter(&util.InfoLogWriter{}, workspaceLogger) - err = s.startWorkspace(ctx, w, target, wsLogWriter) + err = s.startWorkspace(ctx, w, targetConfig, wsLogWriter) if !telemetry.TelemetryEnabled(ctx) { return err @@ -45,7 +45,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w, target) + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w, targetConfig) event := telemetry.ServerEventWorkspaceStarted if err != nil { telemetryProps["error"] = err.Error() @@ -70,7 +70,7 @@ func (s *WorkspaceService) StartProject(ctx context.Context, workspaceId, projec return ErrProjectNotFound } - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &w.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) if err != nil { return err } @@ -78,10 +78,10 @@ func (s *WorkspaceService) StartProject(ctx context.Context, workspaceId, projec projectLogger := s.loggerFactory.CreateProjectLogger(w.Id, project.Name, logs.LogSourceServer) defer projectLogger.Close() - return s.startProject(ctx, project, target, projectLogger) + return s.startProject(ctx, project, targetConfig, projectLogger) } -func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Workspace, target *provider.ProviderTarget, wsLogWriter io.Writer) error { +func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Workspace, targetConfig *provider.TargetConfig, wsLogWriter io.Writer) error { wsLogWriter.Write([]byte("Starting workspace\n")) ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ @@ -91,7 +91,7 @@ func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Wor ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err := s.provisioner.StartWorkspace(ws, target) + err := s.provisioner.StartWorkspace(ws, targetConfig) if err != nil { return err } @@ -100,7 +100,7 @@ func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Wor projectLogger := s.loggerFactory.CreateProjectLogger(ws.Id, project.Name, logs.LogSourceServer) defer projectLogger.Close() - err = s.startProject(ctx, project, target, projectLogger) + err = s.startProject(ctx, project, targetConfig, projectLogger) if err != nil { return err } @@ -111,7 +111,7 @@ func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Wor return nil } -func (s *WorkspaceService) startProject(ctx context.Context, p *project.Project, target *provider.ProviderTarget, logWriter io.Writer) error { +func (s *WorkspaceService) startProject(ctx context.Context, p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { logWriter.Write([]byte(fmt.Sprintf("Starting project %s\n", p.Name))) projectToStart := *p @@ -143,7 +143,7 @@ func (s *WorkspaceService) startProject(ctx context.Context, p *project.Project, err = s.provisioner.StartProject(provisioner.ProjectParams{ Project: &projectToStart, - Target: target, + TargetConfig: targetConfig, ContainerRegistry: cr, GitProviderConfig: gc, BuilderImage: s.builderImage, diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 83344bb5d7..2c521ac4e8 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -18,14 +18,14 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string return ErrWorkspaceNotFound } - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &workspace.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &workspace.TargetConfig}) if err != nil { return err } for _, project := range workspace.Projects { // todo: go routines - err := s.provisioner.StopProject(project, target) + err := s.provisioner.StopProject(project, targetConfig) if err != nil { return err } @@ -35,7 +35,7 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string } } - err = s.provisioner.StopWorkspace(workspace, target) + err = s.provisioner.StopWorkspace(workspace, targetConfig) if err == nil { err = s.workspaceStore.Save(workspace) } @@ -46,7 +46,7 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, target) + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, targetConfig) event := telemetry.ServerEventWorkspaceStopped if err != nil { telemetryProps["error"] = err.Error() @@ -71,12 +71,12 @@ func (s *WorkspaceService) StopProject(ctx context.Context, workspaceId, project return ErrProjectNotFound } - target, err := s.targetStore.Find(&provider.TargetFilter{Name: &w.Target}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) if err != nil { return err } - err = s.provisioner.StopProject(project, target) + err = s.provisioner.StopProject(project, targetConfig) if err != nil { return err } diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index c32b006445..5614dfbf9e 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -33,7 +33,7 @@ const ( ServerEventWorkspaceStopError ServerEvent = "server_workspace_stopped_error" ) -func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace, target *provider.ProviderTarget) map[string]interface{} { +func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) map[string]interface{} { props := map[string]interface{}{} sessionId := SessionId(ctx) @@ -70,10 +70,10 @@ func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace, props["workspace_builders"] = builders } - if target != nil { - props["target_name"] = target.Name - props["target_provider"] = target.ProviderInfo.Name - props["target_provider_version"] = target.ProviderInfo.Version + if targetConfig != nil { + props["target_name"] = targetConfig.Name + props["target_provider"] = targetConfig.ProviderInfo.Name + props["target_provider_version"] = targetConfig.ProviderInfo.Version } return props diff --git a/pkg/views/initial/view.go b/pkg/views/initial/view.go index e05b796de9..88b033e914 100644 --- a/pkg/views/initial/view.go +++ b/pkg/views/initial/view.go @@ -69,7 +69,7 @@ var commandViews []CommandView = []CommandView{ {Command: "create", Name: "daytona create", Desc: "(create a new workspace)"}, {Command: "code", Name: "daytona code", Desc: "(open a workspace in your preferred IDE)"}, {Command: "git-provider add", Name: "daytona git-provider add", Desc: "(register a Git provider account)"}, - {Command: "target set", Name: "daytona target set", Desc: "(run workspaces on a remote machine)"}, + {Command: "target-config set", Name: "daytona target-config set", Desc: "(run workspaces on a remote machine)"}, {Command: "docs", Name: "daytona docs", Desc: "(open Daytona docs in default browser)\n"}, {Command: "help", Name: "view all commands", Desc: ""}, } diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go deleted file mode 100644 index 1d45ce2064..0000000000 --- a/pkg/views/target/list/view.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "fmt" - "sort" - - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/util" - views_util "github.com/daytonaio/daytona/pkg/views/util" -) - -type rowData struct { - Target string - Provider string - IsDefault string - Options string -} - -func ListTargets(targetList []apiclient.ProviderTarget) { - if len(targetList) == 0 { - views_util.NotifyEmptyTargetList(true) - return - } - - sortTargets(&targetList) - - data := [][]string{} - - for _, target := range targetList { - data = append(data, getRowFromRowData(&target)) - } - - table := util.GetTableView(data, []string{ - "Target", "Provider", "Default", "Options", - }, nil, func() { - renderUnstyledList(targetList) - }) - - fmt.Println(table) -} - -func getRowFromRowData(target *apiclient.ProviderTarget) []string { - var isDefault string - var data rowData - - data.Target = target.Name - data.Provider = target.ProviderInfo.Name - data.Options = target.Options - - if target.IsDefault { - isDefault = views.ActiveStyle.Render("Yes") - } else { - isDefault = views.InactiveStyle.Render("/") - } - - row := []string{ - views.NameStyle.Render(data.Target), - views.DefaultRowDataStyle.Render(data.Provider), - isDefault, - views.DefaultRowDataStyle.Render(data.Options), - } - - return row -} - -func sortTargets(targets *[]apiclient.ProviderTarget) { - sort.Slice(*targets, func(i, j int) bool { - t1 := (*targets)[i] - t2 := (*targets)[j] - return t1.ProviderInfo.Name < t2.ProviderInfo.Name - }) -} - -func renderUnstyledList(targetList []apiclient.ProviderTarget) { - output := "\n" - - for _, target := range targetList { - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Target Name: "), target.Name) + "\n\n" - - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Target Provider: "), target.ProviderInfo.Name) + "\n\n" - - if target.IsDefault { - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default: "), "Yes") + "\n\n" - } - - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Target Options: "), target.Options) + "\n\n" - - if target.Name != targetList[len(targetList)-1].Name { - output += views.SeparatorString + "\n\n" - } - } - - fmt.Println(output) -} diff --git a/pkg/views/targetconfig/list.go b/pkg/views/targetconfig/list.go new file mode 100644 index 0000000000..ae8793fc9c --- /dev/null +++ b/pkg/views/targetconfig/list.go @@ -0,0 +1,92 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfig + +import ( + "fmt" + "sort" + + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/util" +) + +type rowData struct { + ConfigName string + Provider string + IsDefault string + Options string +} + +func ListTargetConfigs(targetConfigs []apiclient.TargetConfig) { + sortTargetConfigs(&targetConfigs) + + data := [][]string{} + + for _, targetConfig := range targetConfigs { + data = append(data, getRowFromRowData(&targetConfig)) + } + + table := util.GetTableView(data, []string{ + "Name", "Provider", "Default", "Options", + }, nil, func() { + renderUnstyledList(targetConfigs) + }) + + fmt.Println(table) +} + +func getRowFromRowData(targetConfig *apiclient.TargetConfig) []string { + var isDefault string + var data rowData + + data.ConfigName = targetConfig.Name + data.Provider = targetConfig.ProviderInfo.Name + data.Options = targetConfig.Options + + if targetConfig.IsDefault { + isDefault = views.ActiveStyle.Render("Yes") + } else { + isDefault = views.InactiveStyle.Render("/") + } + + row := []string{ + views.NameStyle.Render(data.ConfigName), + views.DefaultRowDataStyle.Render(data.Provider), + isDefault, + views.DefaultRowDataStyle.Render(data.Options), + } + + return row +} + +func sortTargetConfigs(targetConfigs *[]apiclient.TargetConfig) { + sort.Slice(*targetConfigs, func(i, j int) bool { + t1 := (*targetConfigs)[i] + t2 := (*targetConfigs)[j] + return t1.ProviderInfo.Name < t2.ProviderInfo.Name + }) +} + +func renderUnstyledList(targetConfigs []apiclient.TargetConfig) { + output := "\n" + + for _, targetConfig := range targetConfigs { + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Name: "), targetConfig.Name) + "\n\n" + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Provider: "), targetConfig.ProviderInfo.Name) + "\n\n" + + if targetConfig.IsDefault { + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default: "), "Yes") + "\n\n" + } + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Options: "), targetConfig.Options) + "\n\n" + + if targetConfig.Name != targetConfigs[len(targetConfigs)-1].Name { + output += views.SeparatorString + "\n\n" + } + } + + fmt.Println(output) +} diff --git a/pkg/views/target/select.go b/pkg/views/targetconfig/select.go similarity index 62% rename from pkg/views/target/select.go rename to pkg/views/targetconfig/select.go index d3f9a345b3..ce4650092e 100644 --- a/pkg/views/target/select.go +++ b/pkg/views/targetconfig/select.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "fmt" @@ -15,9 +15,9 @@ import ( "github.com/daytonaio/daytona/pkg/views/provider" ) -const NewTargetName = "+ New Target" +const NewTargetConfigName = "+ New Target Config" -type TargetView struct { +type TargetConfigView struct { Name string Options string IsDefault bool @@ -30,18 +30,18 @@ type ProviderInfo struct { Installed *bool } -func GetTargetFromPrompt(targets []apiclient.ProviderTarget, activeProfileName string, providerViewList *[]provider.ProviderView, withNewTarget bool, actionVerb string) (*TargetView, error) { - items := util.ArrayMap(targets, func(t apiclient.ProviderTarget) list.Item { +func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activeProfileName string, providerViewList *[]provider.ProviderView, withNewTargetConfig bool, actionVerb string) (*TargetConfigView, error) { + items := util.ArrayMap(targetConfigs, func(t apiclient.TargetConfig) list.Item { return item{ - target: GetTargetViewFromTarget(t), + targetConfig: ToTargetConfigView(t), } }) - if withNewTarget { - name := NewTargetName + if withNewTargetConfig { + name := NewTargetConfigName options := "{}" items = append(items, item{ - target: TargetView{ + targetConfig: TargetConfigView{ Name: name, Options: options, }, @@ -62,8 +62,8 @@ func GetTargetFromPrompt(targets []apiclient.ProviderTarget, activeProfileName s } items = append(items, item{ - target: TargetView{ - Name: fmt.Sprintf("Add a %s Provider Target", label), + targetConfig: TargetConfigView{ + Name: fmt.Sprintf("Add a %s Target Config", label), Options: "{}", ProviderInfo: ProviderInfo{ Name: providerView.Name, @@ -77,7 +77,7 @@ func GetTargetFromPrompt(targets []apiclient.ProviderTarget, activeProfileName s l := views.GetStyledSelectList(items) m := model{list: l} - m.list.Title = views.GetStyledMainTitle("Choose a Target To " + actionVerb) + m.list.Title = views.GetStyledMainTitle("Choose a Target Config To " + actionVerb) m.footer = views.GetListFooter(activeProfileName, views.DefaultListFooterPadding) p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() @@ -92,14 +92,14 @@ func GetTargetFromPrompt(targets []apiclient.ProviderTarget, activeProfileName s return nil, common.ErrCtrlCAbort } -func GetTargetViewFromTarget(target apiclient.ProviderTarget) TargetView { - return TargetView{ - Name: target.Name, - Options: target.Options, - IsDefault: target.IsDefault, +func ToTargetConfigView(targetConfig apiclient.TargetConfig) TargetConfigView { + return TargetConfigView{ + Name: targetConfig.Name, + Options: targetConfig.Options, + IsDefault: targetConfig.IsDefault, ProviderInfo: ProviderInfo{ - Name: target.ProviderInfo.Name, - Version: target.ProviderInfo.Version, + Name: targetConfig.ProviderInfo.Name, + Version: targetConfig.ProviderInfo.Version, }, } } diff --git a/pkg/views/target/set.go b/pkg/views/targetconfig/set.go similarity index 77% rename from pkg/views/target/set.go rename to pkg/views/targetconfig/set.go index 4114143033..84abd39ff9 100644 --- a/pkg/views/target/set.go +++ b/pkg/views/targetconfig/set.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "encoding/json" @@ -22,16 +22,16 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func NewTargetNameInput(targetName *string, existingTargetNames []string) error { +func NewTargetConfigNameInput(name *string, existingNames []string) error { input := huh.NewInput(). Title("Name"). - Value(targetName). + Value(name). Validate(func(s string) error { if s == "" { return errors.New("Name cannot be empty") } - if slices.Contains(existingTargetNames, s) { - return errors.New("Target with the same name already exists") + if slices.Contains(existingNames, s) { + return errors.New("Target config with the same name already exists") } return nil }) @@ -44,32 +44,32 @@ func NewTargetNameInput(targetName *string, existingTargetNames []string) error return nil } -func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.ProviderProviderTargetProperty) error { - fields := make([]huh.Field, 0, len(targetManifest)) +func SetTargetConfigForm(targetConfig *TargetConfigView, targetConfigManifest map[string]apiclient.TargetConfigProperty) error { + fields := make([]huh.Field, 0, len(targetConfigManifest)) groups := []*huh.Group{} options := make(map[string]interface{}) - err := json.Unmarshal([]byte(target.Options), &options) + err := json.Unmarshal([]byte(targetConfig.Options), &options) if err != nil { return err } - sortedKeys := make([]string, 0, len(targetManifest)) - for k := range targetManifest { + sortedKeys := make([]string, 0, len(targetConfigManifest)) + for k := range targetConfigManifest { sortedKeys = append(sortedKeys, k) } sort.Strings(sortedKeys) for _, name := range sortedKeys { - property := targetManifest[name] + property := targetConfigManifest[name] if property.DisabledPredicate != nil && *property.DisabledPredicate != "" { - if matched, err := regexp.Match(*property.DisabledPredicate, []byte(target.Name)); err == nil && matched { + if matched, err := regexp.Match(*property.DisabledPredicate, []byte(targetConfig.Name)); err == nil && matched { continue } } switch *property.Type { - case apiclient.ProviderTargetPropertyTypeFloat, apiclient.ProviderTargetPropertyTypeInt: + case apiclient.TargetConfigPropertyTypeFloat, apiclient.TargetConfigPropertyTypeInt: var initialValue *string floatValue, ok := options[name].(float64) if ok { @@ -80,7 +80,7 @@ func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.Provi input, value := getInput(name, property, initialValue) fields = append(fields, input) options[name] = value - case apiclient.ProviderTargetPropertyTypeString: + case apiclient.TargetConfigPropertyTypeString: var initialValue *string v, ok := options[name].(string) if ok { @@ -90,7 +90,7 @@ func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.Provi input, value := getInput(name, property, initialValue) fields = append(fields, input) options[name] = value - case apiclient.ProviderTargetPropertyTypeBoolean: + case apiclient.TargetConfigPropertyTypeBoolean: var initialValue *bool v, ok := options[name].(bool) if ok { @@ -100,7 +100,7 @@ func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.Provi confirm, value := getConfirm(name, property, initialValue) fields = append(fields, confirm) options[name] = value - case apiclient.ProviderTargetPropertyTypeOption: + case apiclient.TargetConfigPropertyTypeOption: var initialValue *string v, ok := options[name].(string) if ok { @@ -110,7 +110,7 @@ func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.Provi selectField, value := getSelect(name, property, initialValue) fields = append(fields, selectField) options[name] = value - case apiclient.ProviderTargetPropertyTypeFilePath: + case apiclient.TargetConfigPropertyTypeFilePath: var initialValue *string v, ok := options[name].(string) if ok { @@ -128,24 +128,24 @@ func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.Provi return err } - for name, property := range targetManifest { + for name, property := range targetConfigManifest { if property.DisabledPredicate != nil && *property.DisabledPredicate != "" { - if matched, err := regexp.Match(*property.DisabledPredicate, []byte(target.Name)); err == nil && matched { + if matched, err := regexp.Match(*property.DisabledPredicate, []byte(targetConfig.Name)); err == nil && matched { continue } } switch *property.Type { - case apiclient.ProviderTargetPropertyTypeInt: + case apiclient.TargetConfigPropertyTypeInt: options[name], err = strconv.Atoi(*options[name].(*string)) if err != nil { return err } - case apiclient.ProviderTargetPropertyTypeFloat: + case apiclient.TargetConfigPropertyTypeFloat: options[name], err = strconv.ParseFloat(*options[name].(*string), 64) if err != nil { return err } - case apiclient.ProviderTargetPropertyTypeFilePath: + case apiclient.TargetConfigPropertyTypeFilePath: if *options[name].(*string) == "none" { delete(options, name) } @@ -158,11 +158,11 @@ func SetTargetForm(target *TargetView, targetManifest map[string]apiclient.Provi } content := string(jsonContent) - target.Options = content + targetConfig.Options = content return nil } -func getInput(name string, property apiclient.ProviderProviderTargetProperty, initialValue *string) (*huh.Input, *string) { +func getInput(name string, property apiclient.TargetConfigProperty, initialValue *string) (*huh.Input, *string) { value := property.DefaultValue if initialValue != nil { value = initialValue @@ -174,10 +174,10 @@ func getInput(name string, property apiclient.ProviderProviderTargetProperty, in Value(value). Validate(func(s string) error { switch *property.Type { - case apiclient.ProviderTargetPropertyTypeInt: + case apiclient.TargetConfigPropertyTypeInt: _, err := strconv.Atoi(s) return err - case apiclient.ProviderTargetPropertyTypeFloat: + case apiclient.TargetConfigPropertyTypeFloat: _, err := strconv.ParseFloat(s, 64) return err } @@ -195,7 +195,7 @@ func getInput(name string, property apiclient.ProviderProviderTargetProperty, in return input, value } -func getSelect(name string, property apiclient.ProviderProviderTargetProperty, initialValue *string) (*huh.Select[string], *string) { +func getSelect(name string, property apiclient.TargetConfigProperty, initialValue *string) (*huh.Select[string], *string) { value := property.DefaultValue if initialValue != nil { value = initialValue @@ -210,7 +210,7 @@ func getSelect(name string, property apiclient.ProviderProviderTargetProperty, i Value(value), value } -func getConfirm(name string, property apiclient.ProviderProviderTargetProperty, initialValue *bool) (*huh.Confirm, *bool) { +func getConfirm(name string, property apiclient.TargetConfigProperty, initialValue *bool) (*huh.Confirm, *bool) { value := false if property.DefaultValue != nil && *property.DefaultValue == "true" { value = true @@ -225,7 +225,7 @@ func getConfirm(name string, property apiclient.ProviderProviderTargetProperty, Value(&value), &value } -func getFilePicker(name string, property apiclient.ProviderProviderTargetProperty, initialValue *string) ([]*huh.Group, *string) { +func getFilePicker(name string, property apiclient.TargetConfigProperty, initialValue *string) ([]*huh.Group, *string) { dirPath := "~" if property.DefaultValue != nil { diff --git a/pkg/views/target/view.go b/pkg/views/targetconfig/view.go similarity index 77% rename from pkg/views/target/view.go rename to pkg/views/targetconfig/view.go index d63112ef3b..3449bf2f78 100644 --- a/pkg/views/target/view.go +++ b/pkg/views/targetconfig/view.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package targetconfig import ( "os" @@ -13,33 +13,33 @@ import ( ) type item struct { - target TargetView + targetConfig TargetConfigView } func (i item) Title() string { - title := i.target.Name + title := i.targetConfig.Name - if i.target.IsDefault { + if i.targetConfig.IsDefault { title += " (default)" } return title } func (i item) Description() string { - desc := i.target.ProviderInfo.Name - if i.target.ProviderInfo.Installed != nil { - if !*i.target.ProviderInfo.Installed { + desc := i.targetConfig.ProviderInfo.Name + if i.targetConfig.ProviderInfo.Installed != nil { + if !*i.targetConfig.ProviderInfo.Installed { desc += " (needs installing)" } } return desc } -func (i item) FilterValue() string { return i.target.Name } +func (i item) FilterValue() string { return i.targetConfig.Name } type model struct { list list.Model - choice *TargetView + choice *TargetConfigView footer string } @@ -57,7 +57,7 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "enter": i, ok := m.list.SelectedItem().(item) if ok { - m.choice = &i.target + m.choice = &i.targetConfig } return m, tea.Quit } diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index 47ee648c78..a94807686e 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -19,10 +19,10 @@ func NotifyEmptyGitProviderList(tip bool) { } } -func NotifyEmptyTargetList(tip bool) { - views.RenderInfoMessageBold("No targets found") +func NotifyEmptyTargetConfigList(tip bool) { + views.RenderInfoMessageBold("No target configs found") if tip { - views.RenderTip("Use 'daytona target set' to add a target") + views.RenderTip("Use 'daytona target-config set' to add a target config") } } diff --git a/pkg/views/util/help.go b/pkg/views/util/help.go index 5de8f42ad0..507d24daa0 100644 --- a/pkg/views/util/help.go +++ b/pkg/views/util/help.go @@ -39,7 +39,7 @@ func getLongDescriptionText() string { " Use the following commands to get started:\n\n" + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "1) daytona server", "Start the Daytona Server process locally\n") + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "2) daytona git-providers add", "Register a Git provider of your choice\n") + - fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "3) daytona target set", "Set a target to spin up your Dev Environments on\n") + + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "3) daytona target-config set", "Set a target config to spin up your Dev Environments on\n") + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "4) daytona ide", "Choose the default IDE\n") + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "5) daytona whoami", "Show information about the currently logged in user\n") + fmt.Sprintf(" \n%s\x1b[1m%s\x1b[0m\n\n", "That's it! Start coding - ", "daytona create") @@ -58,7 +58,7 @@ func getLongDescriptionFull() string { fmt.Sprintf("%s\n", " @@@@ @@ @@@@@@@@@@@ ") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@@@@ @@@ ", helpDescriptionLabelWidthWithSigil, "1) daytona server", "Start the Daytona Server process locally\n") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@ ", helpDescriptionLabelWidthWithSigil, "2) daytona git-providers add", "Register a Git provider of your choice\n") + - fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@@@@ ", helpDescriptionLabelWidthWithSigil, "3) daytona target set", "Set a target to spin up your Dev Environments\n") + + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@@@@ ", helpDescriptionLabelWidthWithSigil, "3) daytona target-config set", "Set a target config to spin up your Dev Environments\n") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@ @@@@@@@@@ ", helpDescriptionLabelWidthWithSigil, "4) daytona ide", "Choose the default IDE\n") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@@@@@ @@@@@@@@ @@ ", helpDescriptionLabelWidthWithSigil, "5) daytona whoami", "Show information about the currently logged in user\n") + fmt.Sprintf("%s\n", " @@@@@@@@@@@@@@@@@@ ") + diff --git a/pkg/views/util/table.go b/pkg/views/util/table.go index fdff0c49f2..4a54e15278 100644 --- a/pkg/views/util/table.go +++ b/pkg/views/util/table.go @@ -16,7 +16,7 @@ import ( var AdditionalPropertyPadding = " " -// Left border, BaseTableStyle padding left, additional padding for workspace name and target, BaseTableStyle padding right, BaseCellStyle padding right, right border +// Left border, BaseTableStyle padding left, additional padding for workspace name and target config, BaseTableStyle padding right, BaseCellStyle padding right, right border var RowWhiteSpace = 1 + 4 + len(AdditionalPropertyPadding)*2 + 4 + 4 + 1 var ArbitrarySpace = 10 diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go index 7a7e198386..7ac3a243a4 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/workspace/info/view.go @@ -102,7 +102,7 @@ func getSingleProjectOutput(project *apiclient.Project, isCreationView bool) str output += getInfoLinePrNumber(project.Repository.PrNumber, project.Repository, project.State) if !isCreationView { - output += getInfoLine("Target", project.Target) + "\n" + output += getInfoLine("Target Config", project.TargetConfig) + "\n" } output += getInfoLine("Repository", repositoryUrl) @@ -125,7 +125,7 @@ func getProjectsOutputs(projects []apiclient.Project, isCreationView bool) strin output += getInfoLinePrNumber(project.Repository.PrNumber, project.Repository, project.State) if !isCreationView { - output += getInfoLine("Target", project.Target) + output += getInfoLine("Target Config", project.TargetConfig) } output += getInfoLine("Repository", project.Repository.Url) if project.Name != projects[len(projects)-1].Name { diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index 52aef25c1e..52d7283864 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -16,12 +16,12 @@ import ( ) type RowData struct { - Name string - Repository string - Target string - Status string - Created string - Branch string + Name string + Repository string + TargetConfig string + Status string + Created string + Branch string } func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { @@ -32,7 +32,7 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders SortWorkspaces(&workspaceList, verbose) - headers := []string{"Workspace", "Repository", "Target", "Status", "Created", "Branch"} + headers := []string{"Workspace", "Repository", "Target Config", "Status", "Created", "Branch"} data := [][]string{} @@ -106,7 +106,7 @@ func getRowFromRowData(rowData RowData, isMultiProjectAccordion bool) []string { row := []string{ views.NameStyle.Render(rowData.Name), views.DefaultRowDataStyle.Render(rowData.Repository), - views.DefaultRowDataStyle.Render(rowData.Target), + views.DefaultRowDataStyle.Render(rowData.TargetConfig), state, views.DefaultRowDataStyle.Render(rowData.Created), views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(rowData.Branch)), @@ -154,7 +154,7 @@ func getWorkspaceTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProvid rowData.Branch = workspace.Projects[0].Repository.Branch } - rowData.Target = workspace.Target + views_util.AdditionalPropertyPadding + rowData.TargetConfig = workspace.TargetConfig + views_util.AdditionalPropertyPadding if workspace.Info != nil && workspace.Info.Projects != nil && len(workspace.Info.Projects) > 0 { rowData.Created = util.FormatTimestamp(workspace.Info.Projects[0].Created) @@ -172,7 +172,7 @@ func getProjectTableRowData(workspaceDTO apiclient.WorkspaceDTO, project apiclie rowData.Repository = util.GetRepositorySlugFromUrl(project.Repository.Url, specifyGitProviders) rowData.Branch = project.Repository.Branch - rowData.Target = project.Target + views_util.AdditionalPropertyPadding + rowData.TargetConfig = project.TargetConfig + views_util.AdditionalPropertyPadding if project.State != nil && project.State.Uptime > 0 { rowData.Status = util.FormatUptime(project.State.Uptime) diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/workspace/selection/view.go index 5e08d8d69c..35b2d000ef 100644 --- a/pkg/views/workspace/selection/view.go +++ b/pkg/views/workspace/selection/view.go @@ -38,20 +38,20 @@ var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). Render type item[T any] struct { - id, title, desc, createdTime, uptime, target string - choiceProperty T - isMarked bool - isMultipleSelect bool - action string + id, title, desc, createdTime, uptime, targetConfig string + choiceProperty T + isMarked bool + isMultipleSelect bool + action string } -func (i item[T]) Title() string { return i.title } -func (i item[T]) Id() string { return i.id } -func (i item[T]) Description() string { return i.desc } -func (i item[T]) FilterValue() string { return i.title } -func (i item[T]) CreatedTime() string { return i.createdTime } -func (i item[T]) Uptime() string { return i.uptime } -func (i item[T]) Target() string { return i.target } +func (i item[T]) Title() string { return i.title } +func (i item[T]) Id() string { return i.id } +func (i item[T]) Description() string { return i.desc } +func (i item[T]) FilterValue() string { return i.title } +func (i item[T]) CreatedTime() string { return i.createdTime } +func (i item[T]) Uptime() string { return i.uptime } +func (i item[T]) TargetConfig() string { return i.targetConfig } type model[T any] struct { list list.Model @@ -149,8 +149,8 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) title := baseStyles.Render(i.Title()) - idWithTargetString := fmt.Sprintf("%s (%s)", i.Id(), i.Target()) - idWithTarget := baseStyles.Foreground(views.Gray).Render(idWithTargetString) + idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetConfig()) + idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) description := baseStyles.Render(i.Description()) // Add the created/updated time if it's available @@ -168,7 +168,7 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l // Adjust styles as the user moves through the menu if isSelected { title = selectedStyles.Foreground(views.Green).Render(i.Title()) - idWithTarget = selectedStyles.Foreground(views.Gray).Render(idWithTargetString) + idWithTargetConfig = selectedStyles.Foreground(views.Gray).Render(idWithTargetConfigString) description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) timeString = timeStyles.Foreground(views.DimmedGreen).Render(timeString) } @@ -176,7 +176,7 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l // Render to the terminal s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, timeString)) s.WriteRune('\n') - s.WriteString(idWithTarget) + s.WriteString(idWithTargetConfig) s.WriteRune('\n') s.WriteString(description) s.WriteRune('\n') diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go index 231820a579..f82a95b072 100644 --- a/pkg/views/workspace/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -58,7 +58,7 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect desc: strings.Join(projectsInfo, ", "), createdTime: createdTime, uptime: uptime, - target: workspace.Target, + targetConfig: workspace.TargetConfig, choiceProperty: workspace, } diff --git a/pkg/workspace/project/project.go b/pkg/workspace/project/project.go index c3505017b4..1eaebec910 100644 --- a/pkg/workspace/project/project.go +++ b/pkg/workspace/project/project.go @@ -20,7 +20,7 @@ type Project struct { EnvVars map[string]string `json:"envVars" validate:"required"` WorkspaceId string `json:"workspaceId" validate:"required"` ApiKey string `json:"-"` - Target string `json:"target" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` State *ProjectState `json:"state,omitempty" validate:"optional"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` } // @name Project diff --git a/pkg/workspace/workspace.go b/pkg/workspace/workspace.go index adf5e75108..38f1f421ea 100644 --- a/pkg/workspace/workspace.go +++ b/pkg/workspace/workspace.go @@ -10,12 +10,12 @@ import ( ) type Workspace struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - Projects []*project.Project `json:"projects" validate:"required"` - Target string `json:"target" validate:"required"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"-"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + Projects []*project.Project `json:"projects" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` + ApiKey string `json:"-"` + EnvVars map[string]string `json:"-"` } // @name Workspace type WorkspaceInfo struct { From dcd8b1bfeee8d4b82f34cc5a3e4fccc7f91d211e Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 25 Oct 2024 17:15:53 +0200 Subject: [PATCH 02/76] refactor: rename Workspace to Target (#1297) BREAKING CHANGE: - renamed all occurrences of Workspace to Target - renamed all relevant functions, methods and commands - changed the provider interface to use Target instead of Workspace Signed-off-by: Toma Puljak --- .devcontainer/devcontainer.json | 2 +- .vscode/launch.json | 4 +- README.md | 268 +++++++------- cmd/daytona/config/ssh_file.go | 52 ++- cmd/daytona/main.go | 6 +- .../{workspace_mode => agent_mode}/daytona.md | 8 +- .../daytona_agent.md | 2 +- .../daytona_agent_logs.md | 0 .../daytona_autocomplete.md | 2 +- .../daytona_docs.md | 2 +- .../daytona_expose.md | 2 +- .../daytona_forward.md | 2 +- .../daytona_info.md | 2 +- .../daytona_list.md | 4 +- docs/agent_mode/daytona_logs.md | 25 ++ .../daytona_restart.md | 2 +- .../daytona_start.md | 2 +- .../daytona_stop.md | 2 +- .../daytona_version.md | 2 +- docs/daytona.md | 20 +- docs/daytona_code.md | 4 +- docs/daytona_create.md | 8 +- docs/daytona_delete.md | 8 +- docs/daytona_env.md | 2 +- docs/daytona_env_list.md | 2 +- docs/daytona_env_set.md | 2 +- docs/daytona_forward.md | 2 +- docs/daytona_info.md | 4 +- docs/daytona_list.md | 2 +- docs/daytona_logs.md | 8 +- docs/daytona_purge.md | 4 +- docs/daytona_restart.md | 6 +- docs/daytona_ssh.md | 2 +- docs/daytona_start.md | 10 +- docs/daytona_stop.md | 8 +- docs/daytona_target-config_remove.md | 2 +- docs/workspace_mode/daytona_logs.md | 25 -- .../daytona.yaml | 8 +- .../daytona_agent.yaml | 2 +- .../daytona_agent_logs.yaml | 0 .../daytona_autocomplete.yaml | 2 +- .../daytona_docs.yaml | 2 +- .../daytona_expose.yaml | 2 +- .../daytona_forward.yaml | 2 +- .../daytona_info.yaml | 2 +- .../daytona_list.yaml | 4 +- .../daytona_logs.yaml | 10 +- .../daytona_restart.yaml | 2 +- .../daytona_start.yaml | 2 +- .../daytona_stop.yaml | 2 +- .../daytona_version.yaml | 2 +- hack/docs/daytona.yaml | 20 +- hack/docs/daytona_code.yaml | 4 +- hack/docs/daytona_create.yaml | 9 +- hack/docs/daytona_delete.yaml | 8 +- hack/docs/daytona_env.yaml | 2 +- hack/docs/daytona_env_list.yaml | 2 +- hack/docs/daytona_env_set.yaml | 2 +- hack/docs/daytona_forward.yaml | 2 +- hack/docs/daytona_info.yaml | 4 +- hack/docs/daytona_list.yaml | 2 +- hack/docs/daytona_logs.yaml | 8 +- hack/docs/daytona_purge.yaml | 4 +- hack/docs/daytona_restart.yaml | 6 +- hack/docs/daytona_ssh.yaml | 2 +- hack/docs/daytona_start.yaml | 10 +- hack/docs/daytona_stop.yaml | 8 +- hack/docs/daytona_target-config_remove.yaml | 2 +- hack/generate-cli-docs.sh | 4 +- .../.devcontainer/devcontainer.json | 4 +- internal/{workspace_mode.go => agent_mode.go} | 6 +- internal/cmd/tailscale/forward.go | 6 +- internal/testing/agent/mocks/apiserver.go | 10 +- internal/testing/docker/mocks/client.go | 16 +- internal/testing/git/mocks/gitservice.go | 2 +- internal/testing/logger/mocks/logger.go | 8 +- .../testing/server/projectconfig/store.go | 2 +- .../mocks/api_key_service.go | 2 +- .../mocks/build_service.go | 0 .../{workspaces => targets}/mocks/builder.go | 4 +- .../mocks/container_registry_service.go | 0 .../mocks/git_provider_service.go | 0 .../mocks/project_config.go | 4 +- .../mocks/project_config_service.go | 2 +- .../mocks/provisioner.go | 24 +- .../mocks/scheduler.go | 0 internal/testing/server/targets/store.go | 51 +++ internal/testing/server/workspaces/store.go | 53 --- internal/util/apiclient/api_client.go | 22 +- internal/util/apiclient/conversion/project.go | 10 +- .../util/apiclient/websocket_log_reader.go | 22 +- internal/util/cmd.go | 6 +- internal/util/path.go | 14 +- internal/util/{workspace.go => target.go} | 0 pkg/agent/agent.go | 8 +- pkg/agent/agent_test.go | 12 +- pkg/agent/config/config.go | 6 +- pkg/agent/log.go | 2 +- pkg/api/controllers/build/build.go | 2 +- pkg/api/controllers/log/websocket.go | 14 +- .../projectconfig/prebuild/prebuild.go | 2 +- .../prebuild/process_git_event.go | 2 +- .../projectconfig/project_config.go | 2 +- pkg/api/controllers/target/create.go | 49 +++ .../{workspace => target}/dto/dto.go | 2 +- .../{workspace => target}/project.go | 18 +- .../{workspace => target}/start.go | 34 +- .../controllers/{workspace => target}/stop.go | 34 +- .../workspace.go => target/target.go} | 72 ++-- pkg/api/controllers/workspace/create.go | 48 --- pkg/api/docs/docs.go | 282 +++++++-------- pkg/api/docs/swagger.json | 282 +++++++-------- pkg/api/docs/swagger.yaml | 258 +++++++------- pkg/api/middlewares/auth.go | 4 +- pkg/api/middlewares/project.go | 2 +- pkg/api/middlewares/telemetry.go | 6 +- pkg/api/server.go | 30 +- pkg/apiclient/README.md | 26 +- pkg/apiclient/api/openapi.yaml | 334 +++++++++--------- pkg/apiclient/api_prebuild.go | 12 +- .../{api_workspace.go => api_target.go} | 326 ++++++++--------- pkg/apiclient/client.go | 6 +- pkg/apiclient/docs/ApikeyApiKeyType.md | 2 +- ...eateWorkspaceDTO.md => CreateTargetDTO.md} | 38 +- pkg/apiclient/docs/PrebuildAPI.md | 8 +- pkg/apiclient/docs/Project.md | 40 +-- pkg/apiclient/docs/ProjectInfo.md | 22 +- .../docs/{Workspace.md => Target.md} | 38 +- .../docs/{WorkspaceAPI.md => TargetAPI.md} | 160 ++++----- .../docs/{WorkspaceDTO.md => TargetDTO.md} | 48 +-- .../docs/{WorkspaceInfo.md => TargetInfo.md} | 34 +- pkg/apiclient/model_apikey_api_key_type.go | 8 +- ...pace_dto.go => model_create_target_dto.go} | 78 ++-- pkg/apiclient/model_project.go | 46 +-- pkg/apiclient/model_project_info.go | 28 +- .../{model_workspace.go => model_target.go} | 78 ++-- ...l_workspace_dto.go => model_target_dto.go} | 102 +++--- ...workspace_info.go => model_target_info.go} | 74 ++-- pkg/apikey/apikey.go | 6 +- pkg/build/build.go | 4 +- pkg/build/builder_test.go | 2 +- pkg/build/detect/detect.go | 2 +- pkg/build/runner_test.go | 2 +- pkg/build/store.go | 2 +- pkg/cmd/agent/agent.go | 6 +- pkg/cmd/agentmode/agent_mode.go | 71 ++++ .../{workspacemode => agentmode}/expose.go | 4 +- .../{workspacemode => agentmode}/forward.go | 6 +- .../{workspacemode => agentmode}/git_cred.go | 6 +- pkg/cmd/{workspacemode => agentmode}/info.go | 16 +- .../{workspacemode => agentmode}/restart.go | 12 +- pkg/cmd/{workspacemode => agentmode}/start.go | 8 +- pkg/cmd/{workspacemode => agentmode}/stop.go | 12 +- pkg/cmd/build/build.go | 2 +- pkg/cmd/build/delete.go | 2 +- pkg/cmd/build/info.go | 2 +- pkg/cmd/build/logs.go | 2 +- pkg/cmd/build/run.go | 6 +- pkg/cmd/cmd.go | 6 +- pkg/cmd/gitprovider/delete.go | 2 +- pkg/cmd/gitprovider/update.go | 2 +- pkg/cmd/logs.go | 52 +-- pkg/cmd/ports/forward.go | 20 +- pkg/cmd/prebuild/add.go | 6 +- pkg/cmd/prebuild/delete.go | 2 +- pkg/cmd/prebuild/info.go | 2 +- pkg/cmd/prebuild/prebuild.go | 2 +- pkg/cmd/prebuild/update.go | 2 +- pkg/cmd/profiledata/env/env.go | 2 +- pkg/cmd/projectconfig/add.go | 22 +- pkg/cmd/projectconfig/delete.go | 2 +- pkg/cmd/projectconfig/info.go | 2 +- pkg/cmd/projectconfig/projectconfig.go | 2 +- pkg/cmd/projectconfig/setdefault.go | 2 +- pkg/cmd/projectconfig/update.go | 4 +- pkg/cmd/purge.go | 4 +- pkg/cmd/server/serve.go | 16 +- pkg/cmd/{workspace => target}/code.go | 103 +++--- pkg/cmd/{workspace => target}/create.go | 106 +++--- pkg/cmd/{workspace => target}/delete.go | 88 +++-- pkg/cmd/{workspace => target}/info.go | 32 +- pkg/cmd/{workspace => target}/list.go | 14 +- pkg/cmd/{workspace => target}/restart.go | 42 +-- pkg/cmd/{workspace => target}/ssh-proxy.go | 22 +- pkg/cmd/{workspace => target}/ssh.go | 48 +-- pkg/cmd/{workspace => target}/start.go | 134 +++---- pkg/cmd/target/stop.go | 188 ++++++++++ .../util/add_from_config.go | 0 .../util/branch_wizard.go | 2 +- .../util/creation_data.go | 4 +- .../util/get_target_config.go | 0 .../util/repository_wizard.go | 4 +- .../workspace.go => target/util/target.go} | 10 +- pkg/cmd/targetconfig/remove.go | 48 +-- pkg/cmd/workspace/stop.go | 188 ---------- pkg/cmd/workspacemode/workspace_mode.go | 71 ---- pkg/db/build_store.go | 2 +- pkg/db/dto/build.go | 2 +- pkg/db/dto/project.go | 10 +- pkg/db/dto/project_config.go | 2 +- pkg/db/dto/target.go | 58 +++ pkg/db/dto/workspace.go | 58 --- pkg/db/project_config_store.go | 2 +- pkg/db/target_store.go | 73 ++++ pkg/db/workspace_store.go | 73 ---- pkg/docker/README.md | 11 +- pkg/docker/client.go | 16 +- pkg/docker/client_test.go | 10 +- pkg/docker/create.go | 14 +- pkg/docker/create_devcontainer.go | 2 +- pkg/docker/create_image.go | 10 +- pkg/docker/create_test.go | 10 +- pkg/docker/destroy.go | 10 +- pkg/docker/destroy_test.go | 8 +- pkg/docker/info.go | 20 +- pkg/docker/info_test.go | 12 +- pkg/docker/start.go | 2 +- pkg/docker/start_devcontainer.go | 2 +- pkg/docker/stop.go | 2 +- pkg/git/service.go | 2 +- pkg/ide/browser.go | 10 +- pkg/ide/cursor.go | 6 +- pkg/ide/fleet.go | 6 +- pkg/ide/jetbrains.go | 8 +- pkg/ide/jupyter.go | 18 +- pkg/ide/positron.go | 6 +- pkg/ide/terminal.go | 6 +- pkg/ide/vscode-insiders.go | 6 +- pkg/ide/vscode.go | 6 +- pkg/ide/vscodium-insiders.go | 6 +- pkg/ide/vscodium.go | 6 +- pkg/ide/windsurf.go | 6 +- pkg/ide/zed.go | 6 +- pkg/logs/logger.go | 20 +- pkg/logs/project.go | 18 +- pkg/logs/{workspace.go => target.go} | 44 +-- pkg/provider/provider.go | 14 +- pkg/provider/rpc_client.go | 26 +- pkg/provider/rpc_server.go | 24 +- pkg/provider/types.go | 8 +- pkg/provisioner/create.go | 8 +- pkg/provisioner/destroy.go | 10 +- pkg/provisioner/info.go | 12 +- pkg/provisioner/provisioner.go | 15 +- pkg/provisioner/start.go | 8 +- pkg/provisioner/stop.go | 10 +- pkg/server/apikeys/service.go | 2 +- pkg/server/apikeys/validate.go | 4 +- pkg/server/apikeys/validate_test.go | 12 +- pkg/server/builds/dto/builds.go | 2 +- pkg/server/builds/service.go | 2 +- pkg/server/builds/service_test.go | 4 +- pkg/server/config.go | 2 +- pkg/server/gitproviders/remove.go | 2 +- pkg/server/gitproviders/service.go | 2 +- pkg/server/projectconfig/dto/projectconfig.go | 2 +- pkg/server/projectconfig/prebuild.go | 4 +- pkg/server/projectconfig/prebuild_test.go | 2 +- pkg/server/projectconfig/service.go | 2 +- pkg/server/projectconfig/service_test.go | 4 +- pkg/server/purge.go | 14 +- pkg/server/server.go | 8 +- pkg/server/{workspaces => targets}/create.go | 88 ++--- .../workspace.go => targets/dto/target.go} | 18 +- pkg/server/targets/error.go | 17 + pkg/server/{workspaces => targets}/get.go | 26 +- pkg/server/{workspaces => targets}/list.go | 28 +- pkg/server/targets/remove.go | 153 ++++++++ pkg/server/{workspaces => targets}/service.go | 65 ++-- .../{workspaces => targets}/service_test.go | 215 ++++++----- pkg/server/{workspaces => targets}/start.go | 48 +-- pkg/server/{workspaces => targets}/stop.go | 30 +- pkg/server/workspaces/error.go | 33 -- pkg/server/workspaces/remove.go | 153 -------- .../project/buildconfig/config.go | 0 .../project/config/config.go | 2 +- .../project/config/prebuild.go | 0 .../project/config/store.go | 0 .../project/containerconfig/config.go | 0 pkg/{workspace => target}/project/project.go | 14 +- pkg/target/store.go | 21 ++ .../workspace.go => target/target.go} | 24 +- pkg/telemetry/server_events.go | 36 +- pkg/views/ide/code.go | 4 +- .../{start_workspace.go => start_target.go} | 4 +- pkg/views/logs/display.go | 6 +- .../create/configuration.go | 2 +- .../{workspace => target}/create/summary.go | 0 .../{workspace => target}/create/view.go | 0 pkg/views/{workspace => target}/info/view.go | 16 +- pkg/views/{workspace => target}/list/view.go | 84 ++--- .../{workspace => target}/selection/branch.go | 1 - .../{workspace => target}/selection/build.go | 0 .../selection/checkout.go | 0 .../{workspace => target}/selection/common.go | 0 .../selection/gitprovider.go | 1 - .../selection/gitproviderconfig.go | 0 .../selection/namespace.go | 1 - .../selection/prebuild.go | 0 .../selection/project.go | 0 .../selection/projectconfig.go | 0 .../selection/projectrequest.go | 0 .../selection/pullrequest.go | 1 - .../selection/repository.go | 1 - .../{workspace => target}/selection/sample.go | 1 - pkg/views/target/selection/target.go | 147 ++++++++ .../{workspace => target}/selection/view.go | 14 +- pkg/views/util/empty_list.go | 6 +- pkg/views/util/table.go | 2 +- pkg/views/workspace/selection/workspace.go | 147 -------- pkg/workspace/store.go | 21 -- 311 files changed, 3618 insertions(+), 3629 deletions(-) rename docs/{workspace_mode => agent_mode}/daytona.md (81%) rename docs/{workspace_mode => agent_mode}/daytona_agent.md (81%) rename docs/{workspace_mode => agent_mode}/daytona_agent_logs.md (100%) rename docs/{workspace_mode => agent_mode}/daytona_autocomplete.md (77%) rename docs/{workspace_mode => agent_mode}/daytona_docs.md (74%) rename docs/{workspace_mode => agent_mode}/daytona_expose.md (78%) rename docs/{workspace_mode => agent_mode}/daytona_forward.md (73%) rename docs/{workspace_mode => agent_mode}/daytona_info.md (77%) rename docs/{workspace_mode => agent_mode}/daytona_list.md (76%) create mode 100644 docs/agent_mode/daytona_logs.md rename docs/{workspace_mode => agent_mode}/daytona_restart.md (70%) rename docs/{workspace_mode => agent_mode}/daytona_start.md (70%) rename docs/{workspace_mode => agent_mode}/daytona_stop.md (69%) rename docs/{workspace_mode => agent_mode}/daytona_version.md (71%) delete mode 100644 docs/workspace_mode/daytona_logs.md rename hack/docs/{workspace_mode => agent_mode}/daytona.yaml (80%) rename hack/docs/{workspace_mode => agent_mode}/daytona_agent.yaml (84%) rename hack/docs/{workspace_mode => agent_mode}/daytona_agent_logs.yaml (100%) rename hack/docs/{workspace_mode => agent_mode}/daytona_autocomplete.yaml (80%) rename hack/docs/{workspace_mode => agent_mode}/daytona_docs.yaml (78%) rename hack/docs/{workspace_mode => agent_mode}/daytona_expose.yaml (82%) rename hack/docs/{workspace_mode => agent_mode}/daytona_forward.yaml (77%) rename hack/docs/{workspace_mode => agent_mode}/daytona_info.yaml (82%) rename hack/docs/{workspace_mode => agent_mode}/daytona_list.yaml (80%) rename hack/docs/{workspace_mode => agent_mode}/daytona_logs.yaml (55%) rename hack/docs/{workspace_mode => agent_mode}/daytona_restart.yaml (75%) rename hack/docs/{workspace_mode => agent_mode}/daytona_start.yaml (74%) rename hack/docs/{workspace_mode => agent_mode}/daytona_stop.yaml (74%) rename hack/docs/{workspace_mode => agent_mode}/daytona_version.yaml (75%) rename internal/{workspace_mode.go => agent_mode.go} (67%) rename internal/testing/server/{workspaces => targets}/mocks/api_key_service.go (93%) rename internal/testing/server/{workspaces => targets}/mocks/build_service.go (100%) rename internal/testing/server/{workspaces => targets}/mocks/builder.go (92%) rename internal/testing/server/{workspaces => targets}/mocks/container_registry_service.go (100%) rename internal/testing/server/{workspaces => targets}/mocks/git_provider_service.go (100%) rename internal/testing/server/{workspaces => targets}/mocks/project_config.go (74%) rename internal/testing/server/{workspaces => targets}/mocks/project_config_service.go (97%) rename internal/testing/server/{workspaces => targets}/mocks/provisioner.go (53%) rename internal/testing/server/{workspaces => targets}/mocks/scheduler.go (100%) create mode 100644 internal/testing/server/targets/store.go delete mode 100644 internal/testing/server/workspaces/store.go rename internal/util/{workspace.go => target.go} (100%) create mode 100644 pkg/api/controllers/target/create.go rename pkg/api/controllers/{workspace => target}/dto/dto.go (85%) rename pkg/api/controllers/{workspace => target}/project.go (67%) rename pkg/api/controllers/{workspace => target}/start.go (51%) rename pkg/api/controllers/{workspace => target}/stop.go (51%) rename pkg/api/controllers/{workspace/workspace.go => target/target.go} (53%) delete mode 100644 pkg/api/controllers/workspace/create.go rename pkg/apiclient/{api_workspace.go => api_target.go} (75%) rename pkg/apiclient/docs/{CreateWorkspaceDTO.md => CreateTargetDTO.md} (64%) rename pkg/apiclient/docs/{Workspace.md => Target.md} (70%) rename pkg/apiclient/docs/{WorkspaceAPI.md => TargetAPI.md} (62%) rename pkg/apiclient/docs/{WorkspaceDTO.md => TargetDTO.md} (66%) rename pkg/apiclient/docs/{WorkspaceInfo.md => TargetInfo.md} (68%) rename pkg/apiclient/{model_create_workspace_dto.go => model_create_target_dto.go} (61%) rename pkg/apiclient/{model_workspace.go => model_target.go} (66%) rename pkg/apiclient/{model_workspace_dto.go => model_target_dto.go} (61%) rename pkg/apiclient/{model_workspace_info.go => model_target_info.go} (65%) create mode 100644 pkg/cmd/agentmode/agent_mode.go rename pkg/cmd/{workspacemode => agentmode}/expose.go (94%) rename pkg/cmd/{workspacemode => agentmode}/forward.go (80%) rename pkg/cmd/{workspacemode => agentmode}/git_cred.go (92%) rename pkg/cmd/{workspacemode => agentmode}/info.go (69%) rename pkg/cmd/{workspacemode => agentmode}/restart.go (59%) rename pkg/cmd/{workspacemode => agentmode}/start.go (76%) rename pkg/cmd/{workspacemode => agentmode}/stop.go (60%) rename pkg/cmd/{workspace => target}/code.go (51%) rename pkg/cmd/{workspace => target}/create.go (78%) rename pkg/cmd/{workspace => target}/delete.go (53%) rename pkg/cmd/{workspace => target}/info.go (63%) rename pkg/cmd/{workspace => target}/list.go (78%) rename pkg/cmd/{workspace => target}/restart.go (52%) rename pkg/cmd/{workspace => target}/ssh-proxy.go (82%) rename pkg/cmd/{workspace => target}/ssh.go (78%) rename pkg/cmd/{workspace => target}/start.go (55%) create mode 100644 pkg/cmd/target/stop.go rename pkg/cmd/{workspace => target}/util/add_from_config.go (100%) rename pkg/cmd/{workspace => target}/util/branch_wizard.go (99%) rename pkg/cmd/{workspace => target}/util/creation_data.go (98%) rename pkg/cmd/{workspace => target}/util/get_target_config.go (100%) rename pkg/cmd/{workspace => target}/util/repository_wizard.go (98%) rename pkg/cmd/{workspace/util/workspace.go => target/util/target.go} (90%) delete mode 100644 pkg/cmd/workspace/stop.go delete mode 100644 pkg/cmd/workspacemode/workspace_mode.go create mode 100644 pkg/db/dto/target.go delete mode 100644 pkg/db/dto/workspace.go create mode 100644 pkg/db/target_store.go delete mode 100644 pkg/db/workspace_store.go rename pkg/logs/{workspace.go => target.go} (54%) rename pkg/server/{workspaces => targets}/create.go (70%) rename pkg/server/{workspaces/dto/workspace.go => targets/dto/target.go} (79%) create mode 100644 pkg/server/targets/error.go rename pkg/server/{workspaces => targets}/get.go (51%) rename pkg/server/{workspaces => targets}/list.go (52%) create mode 100644 pkg/server/targets/remove.go rename pkg/server/{workspaces => targets}/service.go (59%) rename pkg/server/{workspaces => targets}/service_test.go (51%) rename pkg/server/{workspaces => targets}/start.go (66%) rename pkg/server/{workspaces => targets}/stop.go (64%) delete mode 100644 pkg/server/workspaces/error.go delete mode 100644 pkg/server/workspaces/remove.go rename pkg/{workspace => target}/project/buildconfig/config.go (100%) rename pkg/{workspace => target}/project/config/config.go (97%) rename pkg/{workspace => target}/project/config/prebuild.go (100%) rename pkg/{workspace => target}/project/config/store.go (100%) rename pkg/{workspace => target}/project/containerconfig/config.go (100%) rename pkg/{workspace => target}/project/project.go (89%) create mode 100644 pkg/target/store.go rename pkg/{workspace/workspace.go => target/target.go} (71%) rename pkg/views/ide/{start_workspace.go => start_target.go} (75%) rename pkg/views/{workspace => target}/create/configuration.go (99%) rename pkg/views/{workspace => target}/create/summary.go (100%) rename pkg/views/{workspace => target}/create/view.go (100%) rename pkg/views/{workspace => target}/info/view.go (91%) rename pkg/views/{workspace => target}/list/view.go (51%) rename pkg/views/{workspace => target}/selection/branch.go (96%) rename pkg/views/{workspace => target}/selection/build.go (100%) rename pkg/views/{workspace => target}/selection/checkout.go (100%) rename pkg/views/{workspace => target}/selection/common.go (100%) rename pkg/views/{workspace => target}/selection/gitprovider.go (96%) rename pkg/views/{workspace => target}/selection/gitproviderconfig.go (100%) rename pkg/views/{workspace => target}/selection/namespace.go (96%) rename pkg/views/{workspace => target}/selection/prebuild.go (100%) rename pkg/views/{workspace => target}/selection/project.go (100%) rename pkg/views/{workspace => target}/selection/projectconfig.go (100%) rename pkg/views/{workspace => target}/selection/projectrequest.go (100%) rename pkg/views/{workspace => target}/selection/pullrequest.go (97%) rename pkg/views/{workspace => target}/selection/repository.go (97%) rename pkg/views/{workspace => target}/selection/sample.go (94%) create mode 100644 pkg/views/target/selection/target.go rename pkg/views/{workspace => target}/selection/view.go (92%) delete mode 100644 pkg/views/workspace/selection/workspace.go delete mode 100644 pkg/workspace/store.go diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 574f665c4c..0f31d05a16 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ "LOG_LEVEL": "debug", "DAYTONA_SERVER_MODE": "development", "CGO_ENABLED": "0", - "DAYTONA_WS_ID": "" + "DAYTONA_TARGET_ID": "" }, "postCreateCommand": ".devcontainer/postcreate.sh", "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", diff --git a/.vscode/launch.json b/.vscode/launch.json index 8b084fb550..2c09a89c3c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,8 +12,8 @@ "program": "${workspaceFolder}/cmd/daytona", "console": "integratedTerminal", "env": { - "DAYTONA_WS_ID": "WS_ID", - "DAYTONA_WS_PROJECT_NAME": "PROJECT_NAME", + "DAYTONA_TARGET_ID": "TARGET_ID", + "DAYTONA_PROJECT_NAME": "PROJECT_NAME", "DAYTONA_SERVER_URL": "http://localhost:3986", "DAYTONA_SERVER_API_KEY": "1234567890", }, diff --git a/README.md b/README.md index e81007ff7d..46327dea04 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,12 @@ -

The Open Source Development Environment Manager

Set up a development environment on any infrastructure, with a single command.

-

Documentation · @@ -50,24 +48,30 @@ Set up a development environment on any infrastructure, with a single command.

## Features -* __Single Command__: Activate a fully configured development environment with a single command. -* __Runs everywhere__: spin up your development environment on any machine — whether it's local, remote, cloud-based, physical server, or a VM & any architecture x86 or ARM. -* __Configuration File Support__: Initially support for [dev container](https://containers.dev/), ability to expand to DevFile, Nix & Flox (Contributions welcome here!). -* __Prebuilds System__: Drastically improve environment setup times (Contributions welcome here!). -* __IDE Support__ : Seamlessly supports [VS Code](https://github.com/microsoft/vscode) & [JetBrains](https://www.jetbrains.com/remote-development/gateway/) locally, ready to use without configuration. Includes a built-in Web IDE for added convenience. -* __Git Provider Integration__: GitHub, GitLab, Bitbucket, Bitbucket Server, Gitea, Gitness, Azure DevOps, AWS CodeCommit, Gogs & Gitee can be connected, allowing easy repo branch or PR pull and commit back from the workspaces. -* __Multiple Project Workspace__: Support for multiple project repositories in the same workspace, making it easy to develop using a micro-service architecture. -* __Reverse Proxy Integration__: Enable collaboration and streamline feedback loops by leveraging reverse proxy functionality. Access preview ports and the Web IDE seamlessly, even behind firewalls. -* __Extensibility__: Enable extensibility with plugin or provider development. Moreover, in any dynamic language, not just Go(Contributions welcome here!). -* __Security__: Automatically creates a VPN connection between the client machine and the development environment, ensuring a fully secure connection. -* __All Ports__: The VPN connection enables access to all ports on the development environments, removing the need to setup port forwards over SSH connection. -* __Works on my Machine__: Never experience it again. + +- **Single Command**: Activate a fully configured development environment with a single command. +- **Runs everywhere**: spin up your development environment on any machine — whether it's local, remote, cloud-based, physical server, or a VM & any architecture x86 or ARM. +- **Configuration File Support**: Initially support for [dev container](https://containers.dev/), ability to expand to DevFile, Nix & Flox (Contributions welcome here!). +- **Prebuilds System**: Drastically improve environment setup times (Contributions welcome here!). +- **IDE Support** : Seamlessly supports [VS Code](https://github.com/microsoft/vscode) & [JetBrains](https://www.jetbrains.com/remote-development/gateway/) locally, ready to use without configuration. Includes a built-in Web IDE for added convenience. +- **Git Provider Integration**: GitHub, GitLab, Bitbucket, Bitbucket Server, Gitea, Gitness, Azure DevOps, AWS CodeCommit, Gogs & Gitee can be connected, allowing easy repo branch or PR pull and commit back from the targets. +- **Multiple Project Targets**: Support for multiple project repositories in the same target, making it easy to develop using a micro-service architecture. +- **Reverse Proxy Integration**: Enable collaboration and streamline feedback loops by leveraging reverse proxy functionality. Access preview ports and the Web IDE seamlessly, even behind firewalls. +- **Extensibility**: Enable extensibility with plugin or provider development. Moreover, in any dynamic language, not just Go (Contributions welcome here!). +- **Security**: Automatically creates a VPN connection between the client machine and the development environment, ensuring a fully secure connection. +- **All Ports**: The VPN connection enables access to all ports on the development environments, removing the need to setup port forwards over SSH connection. +- **Works on my Machine**: Never experience it again. + ## Quick Start + ### Mac / Linux + ```bash curl -sfL https://download.daytona.io/daytona/install.sh | sudo bash && daytona server -y && daytona ``` + ### Windows +
Windows PowerShell This command downloads and installs Daytona and runs the Daytona Server: @@ -90,14 +94,15 @@ daytona create **Start coding.** ----- +---
## Why Daytona? + Daytona is a radically simple open source development environment manager. -Setting up development environments has become increasingly challenging over time, especially when aiming to set up remotely, where the complexity increases by an order of magnitude. The process is so complex that we've compiled a [comprehensive guide](https://www.daytona.io/dotfiles/diy-guide-to-transform-any-machine-into-a-codespace) detailing all the necessary steps to set one up—spanning __5,000 words__, __7 steps__, and requiring anywhere from 15 to __45 minutes__. +Setting up development environments has become increasingly challenging over time, especially when aiming to set up remotely, where the complexity increases by an order of magnitude. The process is so complex that we've compiled a [comprehensive guide](https://www.daytona.io/dotfiles/diy-guide-to-transform-any-machine-into-a-codespace) detailing all the necessary steps to set one up—spanning **5,000 words**, **7 steps**, and requiring anywhere from 15 to **45 minutes**. This complexity is unnecessary. @@ -107,29 +112,25 @@ Daytona automates the entire process; provisioning the instance, interpreting an As a developer, you can immediately start focusing on what matters most—your code. - - ## Backstory + We spent most of our careers building cloud development environments. In 2009, we launched what was likely the first commercial [Cloud IDE](https://codeanywhere.com) project. At that time, technology was lacking, forcing us to develop everything from scratch—the IDE, the environment orchestrator, and almost everything else. A lot of people were interested, and over 2.5 million developers signed up! But we were too early, and we asked too much from our users to change how they worked. Now, 15 years since its inception, we have noticed quite a few things. First, the technology we wished for back then exists now. Second, approximately 50% of developers work in remote dev environments, and third, and most importantly, setting up development environments has become more complex than ever, both locally and to a greater magnitude for remote. So, we took everything we learned and decided to solve these issues once and for all as a fully open-source project. Our goal was to create a single binary that allows you to set up a development environment anywhere you wish, completely free, and finally fulfill the promise that many have attempted to make. - - - - - ## Getting Started + ### Requirements -Before starting the installation script, please go over all the necessary requirements: -- __Hardware Resources__: Depending on the project requirements, ensure your machine has sufficient resources. Minimum hardware specification is 1cpu, 2GB of RAM and 10GB of disk space. -- __Docker__: Ensure [Docker](https://www.docker.com/products/docker-desktop/) is installed and running. +Before starting the installation script, please go over all the necessary requirements: +- **Hardware Resources**: Depending on the project requirements, ensure your machine has sufficient resources. Minimum hardware specification is 1cpu, 2GB of RAM and 10GB of disk space. +- **Docker**: Ensure [Docker](https://www.docker.com/products/docker-desktop/) is installed and running. ### Installing Daytona + Daytona allows you to manage your Development Environments using the Daytona CLI. To install it, please execute the following command: ```bash @@ -139,59 +140,67 @@ curl -sf -L https://download.daytona.io/daytona/install.sh | sudo bash # OR if you want to install Daytona to some other path where you don`t need sudo # curl -sf -L https://download.daytona.io/daytona/install.sh | DAYTONA_PATH=/home/user/bin bash ``` +
Manual installation If you don't want to use the provided script, download the binary directly from the URL for your specific OS: - ```bash - curl -sf -L https://download.daytona.io/daytona/latest/daytona-darwin-amd64 -o daytona - curl -sf -L https://download.daytona.io/daytona/latest/daytona-darwin-arm64 -o daytona - curl -sf -L https://download.daytona.io/daytona/latest/daytona-linux-amd64 -o daytona - curl -sf -L https://download.daytona.io/daytona/latest/daytona-linux-arm64 -o daytona - curl -sf -L https://download.daytona.io/daytona/latest/daytona-windows-amd64.exe -o daytona - curl -sf -L https://download.daytona.io/daytona/latest/daytona-windows-arm64.exe -o daytona - ``` - Make sure that path where `daytona` binary is downloaded is in your system PATH. -
+```bash +curl -sf -L https://download.daytona.io/daytona/latest/daytona-darwin-amd64 -o daytona +curl -sf -L https://download.daytona.io/daytona/latest/daytona-darwin-arm64 -o daytona +curl -sf -L https://download.daytona.io/daytona/latest/daytona-linux-amd64 -o daytona +curl -sf -L https://download.daytona.io/daytona/latest/daytona-linux-arm64 -o daytona +curl -sf -L https://download.daytona.io/daytona/latest/daytona-windows-amd64.exe -o daytona +curl -sf -L https://download.daytona.io/daytona/latest/daytona-windows-arm64.exe -o daytona +``` +Make sure that path where `daytona` binary is downloaded is in your system PATH. +
### Initializing Daytona + To initialize Daytona, follow these steps: -__1. Start the Daytona Server:__ +**1. Start the Daytona Server:** This initiates the Daytona Server in daemon mode. Use the command: + ```bash daytona server ``` -__2. Add Your Git Provider of Choice:__ + +**2. Add Your Git Provider of Choice:** Daytona supports GitHub, GitLab, Bitbucket, Bitbucket Server, Gitea, Gitness, AWS CodeCommit, Azure DevOps and Gogs. To add them to your profile, use the command: + ```bash daytona git-providers add ``` + Follow the steps provided. -__3. Add Your Provider Target:__ +**3. Add Your Provider Target:** This step is for choosing where to deploy Development Environments. By default, Daytona includes a Docker provider to spin up environments on your local machine. For remote development environments, use the command: + ```bash daytona target set ``` + Following the steps this command adds SSH machines to your targets. -__4. Choose Your Default IDE:__ +**4. Choose Your Default IDE:** The default setting for Daytona is VS Code locally. If you prefer, you can switch to VS Code - Browser or any IDE from the JetBrains portfolio using the command: + ```bash daytona ide ``` -Now that you have installed and initialized Daytona, you can proceed to setting up your development environments and start coding instantly. - - - +Now that you have installed and initialized Daytona, you can proceed to setting up your development environments and start coding instantly. ### Creating Dev Environments + Creating development environments with Daytona is a straightforward process, accomplished with just one command: + ```bash daytona create ``` @@ -199,10 +208,12 @@ daytona create You can add the `--no-ide` flag if you don't wish to open the IDE immediately after creating the environment. Upon executing this command, you will be prompted with two questions: + 1. Choose the provider to decide where to create a dev environment. 2. Select or type the Git repository you wish to use to create a dev environment. After making your selections, press enter, and Daytona will handle the rest. All that remains for you to do is to execute the following command to open your default IDE: + ```bash daytona code ``` @@ -210,11 +221,13 @@ daytona code This command opens your development environment in your preferred IDE, allowing you to start coding instantly. ### Stopping the Daytona Server: + ```bash daytona server stop ``` ### Restarting the Daytona Server: + ```bash daytona server restart ``` @@ -223,42 +236,39 @@ daytona server restart Daytona offers flexibility for extension through the creation of plugins and providers. - ### Providers + Daytona is designed to be infrastructure-agnostic, capable of creating and managing development environments across various platforms. Providers are the components that encapsulate the logic for provisioning compute resources on a specific target platform. They allow for the configuration of different targets within a single provider, enabling, for instance, multiple AWS profiles within an AWS provider. How does it work? When executing the `daytona create` command, Daytona communicates the environment details to the selected provider, which then provisions the necessary compute resources. Once provisioned, Daytona sets up the environment on these resources, allowing the user to interact with the environment seamlessly. Providers are independent projects that adhere to the Daytona Provider interface. They can be developed in nearly any major programming language. More details coming soon. - ### Plugins + Plugins enhance Daytona's core functionalities by adding new CLI commands, API methods, or services within the development environments. They offer configurable settings to tailor the plugin's behavior to the user's needs. Similar to providers, plugins are independent projects that conform to the Daytona Plugin interface and can be developed in a wide range of programming languages. More details coming soon. - - - ## Contributing To Daytona We welcome contributions to Daytona! Whether you're fixing bugs, improving documentation, suggesting new features, or reporting issues, your help is greatly appreciated. ### Open Source Licensing -Daytona is Open Source under the [Apache License 2.0](LICENSE), and is the [copyright of its contributors](NOTICE). +Daytona is Open Source under the [Apache License 2.0](LICENSE), and is the [copyright of its contributors](NOTICE). If you would like to contribute to the software, you must: - 1. **Read the Developer Certificate of Origin Version 1.1** +1. **Read the Developer Certificate of Origin Version 1.1** - Please review the [Developer Certificate of Origin Version 1.1](https://developercertificate.org/) to understand the contribution requirements. + Please review the [Developer Certificate of Origin Version 1.1](https://developercertificate.org/) to understand the contribution requirements. - 2. **Sign all commits to the Daytona project** +2. **Sign all commits to the Daytona project** - Ensure that all your commits are signed to comply with the Daytona project's contribution policies. + Ensure that all your commits are signed to comply with the Daytona project's contribution policies. - This ensures that users, distributors, and other contributors can rely on all the software related to Daytona being contributed under the terms of the [Apache License 2.0](LICENSE). No contributions will be accepted without following this process. + This ensures that users, distributors, and other contributors can rely on all the software related to Daytona being contributed under the terms of the [Apache License 2.0](LICENSE). No contributions will be accepted without following this process. ### Ways to Contribute @@ -268,19 +278,19 @@ Creating issues is a valuable way to contribute by reporting bugs, suggesting fe Before creating a new issue, search the existing issues [here](https://github.com/daytonaio/daytona/issues) to see if your concern has already been addressed. -* If no existing issue matches your contribution, follow these steps: - 1. **Identify the Type of Issue** - * **Bug Report:** If you encounter unexpected behavior or errors. - * **Feature Request:** If you have an idea for a new feature or improvement. - * **Documentation Improvement:** If you notice gaps or areas for improvement in the documentation. - 1. **Create a new issue** - * Navigate to Issues: Go to the Issues tab [here](https://github.com/daytonaio/daytona/issues). - * Click on "New Issue": Choose the appropriate template (Bug Report, Feature Request, etc.) if available. - * Fill Out the Issue Template: Provide a clear and concise description of the issue, including steps to reproduce (for bugs) or detailed feature descriptions. - * Submit the Issue: Click "Submit new issue" to create the issue. - 1. **Engage with the Community** - * **Respond to Feedback:** Be prepared to provide additional information or clarification if maintainers or other contributors have questions. - * **Collaborate on Solutions:** If you have ideas for resolving the issue, share them in the comments. +- If no existing issue matches your contribution, follow these steps: + 1. **Identify the Type of Issue** + - **Bug Report:** If you encounter unexpected behavior or errors. + - **Feature Request:** If you have an idea for a new feature or improvement. + - **Documentation Improvement:** If you notice gaps or areas for improvement in the documentation. + 1. **Create a new issue** + - Navigate to Issues: Go to the Issues tab [here](https://github.com/daytonaio/daytona/issues). + - Click on "New Issue": Choose the appropriate template (Bug Report, Feature Request, etc.) if available. + - Fill Out the Issue Template: Provide a clear and concise description of the issue, including steps to reproduce (for bugs) or detailed feature descriptions. + - Submit the Issue: Click "Submit new issue" to create the issue. + 1. **Engage with the Community** + - **Respond to Feedback:** Be prepared to provide additional information or clarification if maintainers or other contributors have questions. + - **Collaborate on Solutions:** If you have ideas for resolving the issue, share them in the comments. ### 2. Contributing Code @@ -288,101 +298,107 @@ If you're interested in contributing code to Daytona, follow these steps: 1. **Fork the Daytona repository** - [Fork](https://github.com/daytonaio/daytona/fork) the GitHub repository to create your own copy of the repository. - + [Fork](https://github.com/daytonaio/daytona/fork) the GitHub repository to create your own copy of the repository. + 1. **Add a GitHub provider (if not already registered)** - Before creating your workspace, ensure that you have a GitHub provider registered. If not, run: - ```bash - daytona git-provider add - ``` + Before creating your workspace, ensure that you have a GitHub provider registered. If not, run: + + ```bash + daytona git-provider add + ``` 1. **Create a Workspace with Daytona** - Use the Daytona CLI to create a workspace for your forked repository. Replace YOUR-FORK-URL with the URL of your forked repository. - ```bash - daytona create YOUR-FORK-URL - ``` -1. **Create a new branch** - - Once in the development container, create a new branch for your changes: - ```bash - git checkout -b my-new-feature - ``` + Use the Daytona CLI to create a workspace for your forked repository. Replace YOUR-FORK-URL with the URL of your forked repository. + + ```bash + daytona create YOUR-FORK-URL + ``` + +1. **Create a new branch** + + Once in the development container, create a new branch for your changes: + + ```bash + git checkout -b my-new-feature + ``` 1. **Running Daytona in development mode** - A `dtn` alias is automatically created inside the Workspace. You can use it to compile and run daytona. - For example: - ```bash - dtn serve - ``` + A `dtn` alias is automatically created inside the Workspace. You can use it to compile and run daytona. + For example: + + ```bash + dtn serve + ``` 1. **Make changes to the project** - Prepare your changes and ensure your commits are descriptive. The document contains an optional commit template, if desired. + Prepare your changes and ensure your commits are descriptive. The document contains an optional commit template, if desired. 1. **Test your changes** - Ensure to test your changes by running the project locally. - Run the following command in the daytona root directory to run the tests: - - ```bash - go test ./... - ``` + Ensure to test your changes by running the project locally. + Run the following command in the daytona root directory to run the tests: + + ```bash + go test ./... + ``` 1. **Generate docs** - Ensure to generate new docs after making command related changes, by running ./hack/generate-cli-docs.sh in the daytona root directory. + Ensure to generate new docs after making command related changes, by running ./hack/generate-cli-docs.sh in the daytona root directory. - ```bash - ./hack/generate-cli-docs.sh - ``` + ```bash + ./hack/generate-cli-docs.sh + ``` 1. **Generate new API client** - Ensure to generate a new API client after making changes related to the API spec. - Run the following command in the daytona root directory: + Ensure to generate a new API client after making changes related to the API spec. + Run the following command in the daytona root directory: - ```bash - ./hack/swagger.sh - ``` + ```bash + ./hack/swagger.sh + ``` 1. **Check for lint errors** - Ensure that you have no lint errors. We use golangci-lint as our linter which is automatically installed. - Run the following command in the daytona root directory to check for linting errors: + Ensure that you have no lint errors. We use golangci-lint as our linter which is automatically installed. + Run the following command in the daytona root directory to check for linting errors: - ```bash - golangci-lint run - ``` + ```bash + golangci-lint run + ``` 1. **Sign off on your commits** - Ensure that you sign off on all your commits to comply with the DCO v1.1. We have more details in [Prepare your changes](https://github.com/daytonaio/daytona/blob/main/PREPARING_YOUR_CHANGES.md). + Ensure that you sign off on all your commits to comply with the DCO v1.1. We have more details in [Prepare your changes](https://github.com/daytonaio/daytona/blob/main/PREPARING_YOUR_CHANGES.md). - To sign off on your Git commits more easily, you can use the -s or --signoff option when making a commit. This adds a "Signed-off-by" line to your commit message automatically, which is required to comply with the DCO v1.1. + To sign off on your Git commits more easily, you can use the -s or --signoff option when making a commit. This adds a "Signed-off-by" line to your commit message automatically, which is required to comply with the DCO v1.1. - Here's how you can do it: + Here's how you can do it: - ```bash - git commit -s -m "Your commit message" - ``` - This command adds the necessary sign-off to your commit without needing to rebase later. + ```bash + git commit -s -m "Your commit message" + ``` - If you've already made commits without the sign-off, you can add it retrospectively by rebasing: + This command adds the necessary sign-off to your commit without needing to rebase later. - ```bash - git rebase HEAD~1 --signoff - git push --force-with-lease origin my-new-feature - ``` + If you've already made commits without the sign-off, you can add it retrospectively by rebasing: + + ```bash + git rebase HEAD~1 --signoff + git push --force-with-lease origin my-new-feature + ``` 1. **Push your changes and create a pull request** - Push your changes to your forked repository and create a pull request from your branch in your forked repository to the main Daytona repository. - If you're new to GitHub, read about [pull requests](https://help.github.com/articles/about-pull-requests/). You are welcome to submit your pull request for commentary or review before it is complete by creating a [draft pull request](https://help.github.com/en/articles/about-pull-requests#draft-pull-requests). Please include specific questions or items you'd like feedback on. + Push your changes to your forked repository and create a pull request from your branch in your forked repository to the main Daytona repository. + If you're new to GitHub, read about [pull requests](https://help.github.com/articles/about-pull-requests/). You are welcome to submit your pull request for commentary or review before it is complete by creating a [draft pull request](https://help.github.com/en/articles/about-pull-requests#draft-pull-requests). Please include specific questions or items you'd like feedback on. 1. **Wait for review** - A Daytona team member will take a look at your PR and either merge, comment, and/or assign someone for review. + A Daytona team member will take a look at your PR and either merge, comment, and/or assign someone for review. ## License @@ -398,11 +414,9 @@ You can read more in our [packinging guidelines](PACKAGING.md). ## Code of Conduct - This project has adapted the Code of Conduct from the [Contributor Covenant](https://www.contributor-covenant.org/). For more information see the [Code of Conduct](CODE_OF_CONDUCT.md) or contact [codeofconduct@daytona.io.](mailto:codeofconduct@daytona.io) with any additional questions or comments. ## Questions - For more information on how to use and develop Daytona, talk to us on [Slack](https://go.daytona.io/slack). diff --git a/cmd/daytona/config/ssh_file.go b/cmd/daytona/config/ssh_file.go index b147bd07cf..ab3b9bdc1c 100644 --- a/cmd/daytona/config/ssh_file.go +++ b/cmd/daytona/config/ssh_file.go @@ -114,21 +114,21 @@ func UnlinkSshFiles() error { // Add ssh entry -func generateSshConfigEntry(profileId, workspaceId, projectName, knownHostsPath string, gpgForward bool) (string, error) { +func generateSshConfigEntry(profileId, targetId, projectName, knownHostsPath string, gpgForward bool) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } tab := "\t" - projectHostname := GetProjectHostname(profileId, workspaceId, projectName) + projectHostname := GetProjectHostname(profileId, targetId, projectName) config := fmt.Sprintf("Host %s\n"+ tab+"User daytona\n"+ tab+"StrictHostKeyChecking no\n"+ tab+"UserKnownHostsFile %s\n"+ tab+"ProxyCommand \"%s\" ssh-proxy %s %s %s\n"+ - tab+"ForwardAgent yes\n", projectHostname, knownHostsPath, daytonaPath, profileId, workspaceId, projectName) + tab+"ForwardAgent yes\n", projectHostname, knownHostsPath, daytonaPath, profileId, targetId, projectName) if gpgForward { localSocket, err := getLocalGPGSocket() @@ -153,7 +153,7 @@ func generateSshConfigEntry(profileId, workspaceId, projectName, knownHostsPath return config, nil } -func EnsureSshConfigEntryAdded(profileId, workspaceName, projectName string, gpgKey string) error { +func EnsureSshConfigEntryAdded(profileId, targetName, projectName string, gpgKey string) error { err := ensureSshFilesLinked() if err != nil { return err @@ -164,16 +164,17 @@ func EnsureSshConfigEntryAdded(profileId, workspaceName, projectName string, gpg knownHostsFile := getKnownHostsFile() + // Read existing content from the file existingContent, err := ReadSshConfig(configPath) - if err != nil { + if err != nil && !os.IsNotExist(err) { return err } var configGenerated bool - regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, workspaceName, projectName)) - regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, workspaceName, projectName)) + regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, targetName, projectName)) + regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, targetName, projectName)) if !regexWithoutGPG.MatchString(existingContent) { - newContent, err := appendSshConfigEntry(configPath, profileId, workspaceName, projectName, knownHostsFile, false, existingContent) + newContent, err := appendSshConfigEntry(configPath, profileId, targetName, projectName, knownHostsFile, false, existingContent) if err != nil { return err } @@ -182,12 +183,12 @@ func EnsureSshConfigEntryAdded(profileId, workspaceName, projectName string, gpg } if gpgKey != "" && !regexWithGPG.MatchString(existingContent) { - _, err := appendSshConfigEntry(configPath, profileId, workspaceName, projectName, knownHostsFile, true, existingContent) + _, err := appendSshConfigEntry(configPath, profileId, targetName, projectName, knownHostsFile, true, existingContent) if err != nil { return err } - projectHostname := GetProjectHostname(profileId, workspaceName, projectName) + projectHostname := GetProjectHostname(profileId, targetName, projectName) err = ExportGPGKey(gpgKey, projectHostname) if err != nil { return err @@ -197,11 +198,11 @@ func EnsureSshConfigEntryAdded(profileId, workspaceName, projectName string, gpg } if !configGenerated { - updatedContent, err := regenerateProxyCommand(existingContent, profileId, workspaceName, projectName) + updatedContent, err := regenerateProxyCommand(existingContent, profileId, targetName, projectName) if err != nil { return err } - err = UpdateWorkspaceSshEntry(profileId, workspaceName, projectName, updatedContent) + err = UpdateWorkspaceSshEntry(profileId, targetName, projectName, updatedContent) if err != nil { return err } @@ -236,8 +237,8 @@ func getKnownHostsFile() string { return "/dev/null" } -func appendSshConfigEntry(configPath, profileId, workspaceId, projectName, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { - data, err := generateSshConfigEntry(profileId, workspaceId, projectName, knownHostsFile, gpgForward) +func appendSshConfigEntry(configPath, profileId, targetId, projectName, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { + data, err := generateSshConfigEntry(profileId, targetId, projectName, knownHostsFile, gpgForward) if err != nil { return "", err } @@ -248,7 +249,7 @@ func appendSshConfigEntry(configPath, profileId, workspaceId, projectName, known } // We want to remove the config entry gpg counterpart - configCounterpart, err := generateSshConfigEntry(profileId, workspaceId, projectName, knownHostsFile, !gpgForward) + configCounterpart, err := generateSshConfigEntry(profileId, targetId, projectName, knownHostsFile, !gpgForward) if err != nil { return "", err } @@ -327,7 +328,8 @@ func writeSshConfig(configPath, newContent string) error { return nil } -func RemoveWorkspaceSshEntries(profileId, workspaceId, projectName string) error { +// RemoveTargetSshEntries removes all SSH entries for a given profileId and targetId +func RemoveTargetSshEntries(profileId, targetId string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -337,8 +339,7 @@ func RemoveWorkspaceSshEntries(profileId, workspaceId, projectName string) error return err } - hostLine := fmt.Sprintf("Host %s", GetProjectHostname(profileId, workspaceId, projectName)) - regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) + regex := regexp.MustCompile(fmt.Sprintf(`Host %s-%s-\w+\s*\n(?:\t.*\n?)*`, profileId, targetId)) contentToDelete := regex.FindString(existingContent) if contentToDelete == "" { return nil @@ -348,15 +349,10 @@ func RemoveWorkspaceSshEntries(profileId, workspaceId, projectName string) error newContent = strings.TrimSpace(newContent) // Write the updated content back to the config file - err = writeSshConfig(configPath, newContent) - if err != nil { - return err - } - - return nil + return writeSshConfig(configPath, newContent) } -func UpdateWorkspaceSshEntry(profileId, workspaceId, projectName, updatedContent string) error { +func UpdateWorkspaceSshEntry(profileId, targetId, projectName, updatedContent string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -365,7 +361,7 @@ func UpdateWorkspaceSshEntry(profileId, workspaceId, projectName, updatedContent return err } - hostLine := fmt.Sprintf("Host %s", GetProjectHostname(profileId, workspaceId, projectName)) + hostLine := fmt.Sprintf("Host %s", GetProjectHostname(profileId, targetId, projectName)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) oldContent := regex.FindString(existingContent) if oldContent == "" { @@ -381,8 +377,8 @@ func UpdateWorkspaceSshEntry(profileId, workspaceId, projectName, updatedContent return nil } -func GetProjectHostname(profileId, workspaceId, projectName string) string { - return fmt.Sprintf("%s-%s-%s", profileId, workspaceId, projectName) +func GetProjectHostname(profileId, targetId, projectName string) string { + return fmt.Sprintf("%s-%s-%s", profileId, targetId, projectName) } func init() { diff --git a/cmd/daytona/main.go b/cmd/daytona/main.go index 9830581c07..a768a4bda3 100644 --- a/cmd/daytona/main.go +++ b/cmd/daytona/main.go @@ -12,15 +12,15 @@ import ( "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/cmd" - "github.com/daytonaio/daytona/pkg/cmd/workspacemode" + "github.com/daytonaio/daytona/pkg/cmd/agentmode" "github.com/rs/zerolog" zlog "github.com/rs/zerolog/log" log "github.com/sirupsen/logrus" ) func main() { - if internal.WorkspaceMode() { - err := workspacemode.Execute() + if internal.AgentMode() { + err := agentmode.Execute() if err != nil { log.Fatal(err) } diff --git a/docs/workspace_mode/daytona.md b/docs/agent_mode/daytona.md similarity index 81% rename from docs/workspace_mode/daytona.md rename to docs/agent_mode/daytona.md index 2719fb1581..d27930f6ef 100644 --- a/docs/workspace_mode/daytona.md +++ b/docs/agent_mode/daytona.md @@ -1,10 +1,10 @@ ## daytona -Use the Daytona CLI to manage your workspace +Daytona is a Dev Environment Manager ### Synopsis -Use the Daytona CLI to manage your workspace +Daytona is a Dev Environment Manager ``` daytona [flags] @@ -25,8 +25,8 @@ daytona [flags] * [daytona expose](daytona_expose.md) - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project * [daytona forward](daytona_forward.md) - Forward a port publicly via an URL * [daytona info](daytona_info.md) - Show project info -* [daytona list](daytona_list.md) - List workspaces -* [daytona logs](daytona_logs.md) - View logs for a workspace/project +* [daytona list](daytona_list.md) - List targets +* [daytona logs](daytona_logs.md) - View logs for a target/project * [daytona restart](daytona_restart.md) - Restart the project * [daytona start](daytona_start.md) - Start the project * [daytona stop](daytona_stop.md) - Stop the project diff --git a/docs/workspace_mode/daytona_agent.md b/docs/agent_mode/daytona_agent.md similarity index 81% rename from docs/workspace_mode/daytona_agent.md rename to docs/agent_mode/daytona_agent.md index 0a1f1e81fd..7c19d6cdae 100644 --- a/docs/workspace_mode/daytona_agent.md +++ b/docs/agent_mode/daytona_agent.md @@ -20,6 +20,6 @@ daytona agent [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager * [daytona agent logs](daytona_agent_logs.md) - Output Daytona Agent logs diff --git a/docs/workspace_mode/daytona_agent_logs.md b/docs/agent_mode/daytona_agent_logs.md similarity index 100% rename from docs/workspace_mode/daytona_agent_logs.md rename to docs/agent_mode/daytona_agent_logs.md diff --git a/docs/workspace_mode/daytona_autocomplete.md b/docs/agent_mode/daytona_autocomplete.md similarity index 77% rename from docs/workspace_mode/daytona_autocomplete.md rename to docs/agent_mode/daytona_autocomplete.md index 4689ddb46a..2a2d749125 100644 --- a/docs/workspace_mode/daytona_autocomplete.md +++ b/docs/agent_mode/daytona_autocomplete.md @@ -14,5 +14,5 @@ daytona autocomplete [bash|zsh|fish|powershell] [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_docs.md b/docs/agent_mode/daytona_docs.md similarity index 74% rename from docs/workspace_mode/daytona_docs.md rename to docs/agent_mode/daytona_docs.md index 62f73691da..612505ce71 100644 --- a/docs/workspace_mode/daytona_docs.md +++ b/docs/agent_mode/daytona_docs.md @@ -14,5 +14,5 @@ daytona docs [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_expose.md b/docs/agent_mode/daytona_expose.md similarity index 78% rename from docs/workspace_mode/daytona_expose.md rename to docs/agent_mode/daytona_expose.md index 16a3b1dc89..7281642f6f 100644 --- a/docs/workspace_mode/daytona_expose.md +++ b/docs/agent_mode/daytona_expose.md @@ -14,5 +14,5 @@ daytona expose [PORT] [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_forward.md b/docs/agent_mode/daytona_forward.md similarity index 73% rename from docs/workspace_mode/daytona_forward.md rename to docs/agent_mode/daytona_forward.md index 484087da37..926b4ae0d3 100644 --- a/docs/workspace_mode/daytona_forward.md +++ b/docs/agent_mode/daytona_forward.md @@ -14,5 +14,5 @@ daytona forward [PORT] [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_info.md b/docs/agent_mode/daytona_info.md similarity index 77% rename from docs/workspace_mode/daytona_info.md rename to docs/agent_mode/daytona_info.md index 4fc31aece4..b91c6f9401 100644 --- a/docs/workspace_mode/daytona_info.md +++ b/docs/agent_mode/daytona_info.md @@ -20,5 +20,5 @@ daytona info [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_list.md b/docs/agent_mode/daytona_list.md similarity index 76% rename from docs/workspace_mode/daytona_list.md rename to docs/agent_mode/daytona_list.md index 44ce1885a0..9bf836328a 100644 --- a/docs/workspace_mode/daytona_list.md +++ b/docs/agent_mode/daytona_list.md @@ -1,6 +1,6 @@ ## daytona list -List workspaces +List targets ``` daytona list [flags] @@ -21,5 +21,5 @@ daytona list [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/agent_mode/daytona_logs.md b/docs/agent_mode/daytona_logs.md new file mode 100644 index 0000000000..219a5a2701 --- /dev/null +++ b/docs/agent_mode/daytona_logs.md @@ -0,0 +1,25 @@ +## daytona logs + +View logs for a target/project + +``` +daytona logs [TARGET] [PROJECT_NAME] [flags] +``` + +### Options + +``` + -f, --follow Follow logs + -w, --target View target logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/workspace_mode/daytona_restart.md b/docs/agent_mode/daytona_restart.md similarity index 70% rename from docs/workspace_mode/daytona_restart.md rename to docs/agent_mode/daytona_restart.md index 3656356199..f1795f7416 100644 --- a/docs/workspace_mode/daytona_restart.md +++ b/docs/agent_mode/daytona_restart.md @@ -14,5 +14,5 @@ daytona restart [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_start.md b/docs/agent_mode/daytona_start.md similarity index 70% rename from docs/workspace_mode/daytona_start.md rename to docs/agent_mode/daytona_start.md index 9001876aa5..b100222779 100644 --- a/docs/workspace_mode/daytona_start.md +++ b/docs/agent_mode/daytona_start.md @@ -14,5 +14,5 @@ daytona start [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_stop.md b/docs/agent_mode/daytona_stop.md similarity index 69% rename from docs/workspace_mode/daytona_stop.md rename to docs/agent_mode/daytona_stop.md index 10c858197d..ea71d28747 100644 --- a/docs/workspace_mode/daytona_stop.md +++ b/docs/agent_mode/daytona_stop.md @@ -14,5 +14,5 @@ daytona stop [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/workspace_mode/daytona_version.md b/docs/agent_mode/daytona_version.md similarity index 71% rename from docs/workspace_mode/daytona_version.md rename to docs/agent_mode/daytona_version.md index 0e8e0ed22c..2f0f9fb6a6 100644 --- a/docs/workspace_mode/daytona_version.md +++ b/docs/agent_mode/daytona_version.md @@ -14,5 +14,5 @@ daytona version [flags] ### SEE ALSO -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace +* [daytona](daytona.md) - Daytona is a Dev Environment Manager diff --git a/docs/daytona.md b/docs/daytona.md index 11323cf20a..9769e1d3bd 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -22,30 +22,30 @@ daytona [flags] * [daytona api-key](daytona_api-key.md) - Api Key commands * [daytona autocomplete](daytona_autocomplete.md) - Adds a completion script for your shell environment * [daytona build](daytona_build.md) - Manage builds -* [daytona code](daytona_code.md) - Open a workspace in your preferred IDE +* [daytona code](daytona_code.md) - Open a target in your preferred IDE * [daytona config](daytona_config.md) - Output Daytona configuration * [daytona container-registry](daytona_container-registry.md) - Manage container registries -* [daytona create](daytona_create.md) - Create a workspace -* [daytona delete](daytona_delete.md) - Delete a workspace +* [daytona create](daytona_create.md) - Create a target +* [daytona delete](daytona_delete.md) - Delete a target * [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all workspaces +* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and projects * [daytona forward](daytona_forward.md) - Forward a port from a project to your local machine * [daytona git-providers](daytona_git-providers.md) - Manage Git providers * [daytona ide](daytona_ide.md) - Choose the default IDE -* [daytona info](daytona_info.md) - Show workspace info -* [daytona list](daytona_list.md) - List workspaces -* [daytona logs](daytona_logs.md) - View logs for a workspace/project +* [daytona info](daytona_info.md) - Show target info +* [daytona list](daytona_list.md) - List targets +* [daytona logs](daytona_logs.md) - View logs for a target/project * [daytona prebuild](daytona_prebuild.md) - Manage prebuilds * [daytona profile](daytona_profile.md) - Manage profiles * [daytona project-config](daytona_project-config.md) - Manage project configs * [daytona provider](daytona_provider.md) - Manage providers * [daytona purge](daytona_purge.md) - Purges all Daytona data from the current device -* [daytona restart](daytona_restart.md) - Restart a workspace +* [daytona restart](daytona_restart.md) - Restart a target * [daytona serve](daytona_serve.md) - Run the server process in the current terminal session * [daytona server](daytona_server.md) - Start the server process in daemon mode * [daytona ssh](daytona_ssh.md) - SSH into a project using the terminal -* [daytona start](daytona_start.md) - Start a workspace -* [daytona stop](daytona_stop.md) - Stop a workspace +* [daytona start](daytona_start.md) - Start a target +* [daytona stop](daytona_stop.md) - Stop a target * [daytona target-config](daytona_target-config.md) - Manage target configs * [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection * [daytona update](daytona_update.md) - Update Daytona CLI diff --git a/docs/daytona_code.md b/docs/daytona_code.md index a37f6d179b..6b59d791cf 100644 --- a/docs/daytona_code.md +++ b/docs/daytona_code.md @@ -1,9 +1,9 @@ ## daytona code -Open a workspace in your preferred IDE +Open a target in your preferred IDE ``` -daytona code [WORKSPACE] [PROJECT] [flags] +daytona code [TARGET] [PROJECT] [flags] ``` ### Options diff --git a/docs/daytona_create.md b/docs/daytona_create.md index 03f852d4df..ada0f9ee66 100644 --- a/docs/daytona_create.md +++ b/docs/daytona_create.md @@ -1,6 +1,6 @@ ## daytona create -Create a workspace +Create a target ``` daytona create [REPOSITORY_URL | PROJECT_CONFIG_NAME]... [flags] @@ -19,9 +19,9 @@ daytona create [REPOSITORY_URL | PROJECT_CONFIG_NAME]... [flags] --git-provider-config string Specify the Git provider configuration ID or alias -i, --ide string Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) --manual Manually enter the Git repository - --multi-project Workspace with multiple projects/repos - --name string Specify the workspace name - -n, --no-ide Do not open the workspace in the IDE after workspace creation + --multi-project Target with multiple projects/repos + --name string Specify the target name + -n, --no-ide Do not open the target in the IDE after target creation -t, --target string Specify the target (e.g. 'local') -y, --yes Automatically confirm any prompts ``` diff --git a/docs/daytona_delete.md b/docs/daytona_delete.md index 33e0cdfb89..2339118824 100644 --- a/docs/daytona_delete.md +++ b/docs/daytona_delete.md @@ -1,16 +1,16 @@ ## daytona delete -Delete a workspace +Delete a target ``` -daytona delete [WORKSPACE] [flags] +daytona delete [TARGET] [flags] ``` ### Options ``` - -a, --all Delete all workspaces - -f, --force Delete a workspace by force + -a, --all Delete all targets + -f, --force Delete a target by force -y, --yes Confirm deletion without prompt ``` diff --git a/docs/daytona_env.md b/docs/daytona_env.md index e036aa4314..eaa09464d1 100644 --- a/docs/daytona_env.md +++ b/docs/daytona_env.md @@ -1,6 +1,6 @@ ## daytona env -Manage profile environment variables that are added to all workspaces +Manage profile environment variables that are added to all targets and projects ### Options inherited from parent commands diff --git a/docs/daytona_env_list.md b/docs/daytona_env_list.md index 86b0c1125c..abb49fff04 100644 --- a/docs/daytona_env_list.md +++ b/docs/daytona_env_list.md @@ -20,5 +20,5 @@ daytona env list [flags] ### SEE ALSO -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all workspaces +* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and projects diff --git a/docs/daytona_env_set.md b/docs/daytona_env_set.md index ac7ed3dd5b..24697cc2c9 100644 --- a/docs/daytona_env_set.md +++ b/docs/daytona_env_set.md @@ -14,5 +14,5 @@ daytona env set [KEY=VALUE]... [flags] ### SEE ALSO -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all workspaces +* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and projects diff --git a/docs/daytona_forward.md b/docs/daytona_forward.md index 46f78cb721..f7a6d4f299 100644 --- a/docs/daytona_forward.md +++ b/docs/daytona_forward.md @@ -3,7 +3,7 @@ Forward a port from a project to your local machine ``` -daytona forward [PORT] [WORKSPACE] [PROJECT] [flags] +daytona forward [PORT] [TARGET] [PROJECT] [flags] ``` ### Options diff --git a/docs/daytona_info.md b/docs/daytona_info.md index 1d699e24a0..8ae541bb98 100644 --- a/docs/daytona_info.md +++ b/docs/daytona_info.md @@ -1,9 +1,9 @@ ## daytona info -Show workspace info +Show target info ``` -daytona info [WORKSPACE] [flags] +daytona info [TARGET] [flags] ``` ### Options diff --git a/docs/daytona_list.md b/docs/daytona_list.md index ea33021b05..9bf836328a 100644 --- a/docs/daytona_list.md +++ b/docs/daytona_list.md @@ -1,6 +1,6 @@ ## daytona list -List workspaces +List targets ``` daytona list [flags] diff --git a/docs/daytona_logs.md b/docs/daytona_logs.md index 37aec822e8..219a5a2701 100644 --- a/docs/daytona_logs.md +++ b/docs/daytona_logs.md @@ -1,16 +1,16 @@ ## daytona logs -View logs for a workspace/project +View logs for a target/project ``` -daytona logs [WORKSPACE] [PROJECT_NAME] [flags] +daytona logs [TARGET] [PROJECT_NAME] [flags] ``` ### Options ``` - -f, --follow Follow logs - -w, --workspace View workspace logs + -f, --follow Follow logs + -w, --target View target logs ``` ### Options inherited from parent commands diff --git a/docs/daytona_purge.md b/docs/daytona_purge.md index 0084e0a5e5..b34cf5c858 100644 --- a/docs/daytona_purge.md +++ b/docs/daytona_purge.md @@ -4,7 +4,7 @@ Purges all Daytona data from the current device ### Synopsis -Purges all Daytona data from the current device - including all workspaces, configuration files, and SSH files. This command is irreversible. +Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. ``` daytona purge [flags] @@ -13,7 +13,7 @@ daytona purge [flags] ### Options ``` - -f, --force Delete all workspaces by force + -f, --force Delete all targets by force -y, --yes Execute purge without prompt ``` diff --git a/docs/daytona_restart.md b/docs/daytona_restart.md index bdbcac3bfa..b42a1d574e 100644 --- a/docs/daytona_restart.md +++ b/docs/daytona_restart.md @@ -1,15 +1,15 @@ ## daytona restart -Restart a workspace +Restart a target ``` -daytona restart [WORKSPACE] [flags] +daytona restart [TARGET] [flags] ``` ### Options ``` - -p, --project string Restart a single project in the workspace (project name) + -p, --project string Restart a single project in the target (project name) ``` ### Options inherited from parent commands diff --git a/docs/daytona_ssh.md b/docs/daytona_ssh.md index bebc98cf93..c455b5e7d5 100644 --- a/docs/daytona_ssh.md +++ b/docs/daytona_ssh.md @@ -3,7 +3,7 @@ SSH into a project using the terminal ``` -daytona ssh [WORKSPACE] [PROJECT] [CMD...] [flags] +daytona ssh [TARGET] [PROJECT] [CMD...] [flags] ``` ### Options diff --git a/docs/daytona_start.md b/docs/daytona_start.md index 3680dafb9a..7667c9abaf 100644 --- a/docs/daytona_start.md +++ b/docs/daytona_start.md @@ -1,17 +1,17 @@ ## daytona start -Start a workspace +Start a target ``` -daytona start [WORKSPACE] [flags] +daytona start [TARGET] [flags] ``` ### Options ``` - -a, --all Start all workspaces - -c, --code Open the workspace in the IDE after workspace start - -p, --project string Start a single project in the workspace (project name) + -a, --all Start all targets + -c, --code Open the target in the IDE after target start + -p, --project string Start a single project in the target (project name) -y, --yes Automatically confirm any prompts ``` diff --git a/docs/daytona_stop.md b/docs/daytona_stop.md index 864aa738a6..387bdb4653 100644 --- a/docs/daytona_stop.md +++ b/docs/daytona_stop.md @@ -1,16 +1,16 @@ ## daytona stop -Stop a workspace +Stop a target ``` -daytona stop [WORKSPACE] [flags] +daytona stop [TARGET] [flags] ``` ### Options ``` - -a, --all Stop all workspaces - -p, --project string Stop a single project in the workspace (project name) + -a, --all Stop all targets + -p, --project string Stop a single project in the target (project name) ``` ### Options inherited from parent commands diff --git a/docs/daytona_target-config_remove.md b/docs/daytona_target-config_remove.md index 93e7c60e5b..aebe62cfb7 100644 --- a/docs/daytona_target-config_remove.md +++ b/docs/daytona_target-config_remove.md @@ -9,7 +9,7 @@ daytona target-config remove [CONFIG_NAME] [flags] ### Options ``` - -y, --yes Confirm deletion of all workspaces without prompt + -y, --yes Confirm deletion of all targets without prompt ``` ### Options inherited from parent commands diff --git a/docs/workspace_mode/daytona_logs.md b/docs/workspace_mode/daytona_logs.md deleted file mode 100644 index f8ea76bf48..0000000000 --- a/docs/workspace_mode/daytona_logs.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona logs - -View logs for a workspace/project - -``` -daytona logs [WORKSPACE] [PROJECT_NAME] [flags] -``` - -### Options - -``` - -f, --follow Follow logs - -w, --workspace View workspace logs -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Use the Daytona CLI to manage your workspace - diff --git a/hack/docs/workspace_mode/daytona.yaml b/hack/docs/agent_mode/daytona.yaml similarity index 80% rename from hack/docs/workspace_mode/daytona.yaml rename to hack/docs/agent_mode/daytona.yaml index 6ebcdd6cb7..a1d9e10e33 100644 --- a/hack/docs/workspace_mode/daytona.yaml +++ b/hack/docs/agent_mode/daytona.yaml @@ -1,6 +1,6 @@ name: daytona -synopsis: Use the Daytona CLI to manage your workspace -description: Use the Daytona CLI to manage your workspace +synopsis: Daytona is a Dev Environment Manager +description: Daytona is a Dev Environment Manager usage: daytona [flags] options: - name: help @@ -17,8 +17,8 @@ see_also: - daytona expose - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project - daytona forward - Forward a port publicly via an URL - daytona info - Show project info - - daytona list - List workspaces - - daytona logs - View logs for a workspace/project + - daytona list - List targets + - daytona logs - View logs for a target/project - daytona restart - Restart the project - daytona start - Start the project - daytona stop - Stop the project diff --git a/hack/docs/workspace_mode/daytona_agent.yaml b/hack/docs/agent_mode/daytona_agent.yaml similarity index 84% rename from hack/docs/workspace_mode/daytona_agent.yaml rename to hack/docs/agent_mode/daytona_agent.yaml index 695c8062af..5034cc17be 100644 --- a/hack/docs/workspace_mode/daytona_agent.yaml +++ b/hack/docs/agent_mode/daytona_agent.yaml @@ -10,5 +10,5 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager - daytona agent logs - Output Daytona Agent logs diff --git a/hack/docs/workspace_mode/daytona_agent_logs.yaml b/hack/docs/agent_mode/daytona_agent_logs.yaml similarity index 100% rename from hack/docs/workspace_mode/daytona_agent_logs.yaml rename to hack/docs/agent_mode/daytona_agent_logs.yaml diff --git a/hack/docs/workspace_mode/daytona_autocomplete.yaml b/hack/docs/agent_mode/daytona_autocomplete.yaml similarity index 80% rename from hack/docs/workspace_mode/daytona_autocomplete.yaml rename to hack/docs/agent_mode/daytona_autocomplete.yaml index e0efb0960c..3d7cd97846 100644 --- a/hack/docs/workspace_mode/daytona_autocomplete.yaml +++ b/hack/docs/agent_mode/daytona_autocomplete.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_docs.yaml b/hack/docs/agent_mode/daytona_docs.yaml similarity index 78% rename from hack/docs/workspace_mode/daytona_docs.yaml rename to hack/docs/agent_mode/daytona_docs.yaml index 9e1a0a1a92..2eb2502768 100644 --- a/hack/docs/workspace_mode/daytona_docs.yaml +++ b/hack/docs/agent_mode/daytona_docs.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_expose.yaml b/hack/docs/agent_mode/daytona_expose.yaml similarity index 82% rename from hack/docs/workspace_mode/daytona_expose.yaml rename to hack/docs/agent_mode/daytona_expose.yaml index ea5759cc4f..dafc5ce601 100644 --- a/hack/docs/workspace_mode/daytona_expose.yaml +++ b/hack/docs/agent_mode/daytona_expose.yaml @@ -7,4 +7,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_forward.yaml b/hack/docs/agent_mode/daytona_forward.yaml similarity index 77% rename from hack/docs/workspace_mode/daytona_forward.yaml rename to hack/docs/agent_mode/daytona_forward.yaml index dad403fea1..a6b70eea12 100644 --- a/hack/docs/workspace_mode/daytona_forward.yaml +++ b/hack/docs/agent_mode/daytona_forward.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_info.yaml b/hack/docs/agent_mode/daytona_info.yaml similarity index 82% rename from hack/docs/workspace_mode/daytona_info.yaml rename to hack/docs/agent_mode/daytona_info.yaml index 68cdd2e178..401c578dbc 100644 --- a/hack/docs/workspace_mode/daytona_info.yaml +++ b/hack/docs/agent_mode/daytona_info.yaml @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_list.yaml b/hack/docs/agent_mode/daytona_list.yaml similarity index 80% rename from hack/docs/workspace_mode/daytona_list.yaml rename to hack/docs/agent_mode/daytona_list.yaml index b55d1225f5..08be0d7c58 100644 --- a/hack/docs/workspace_mode/daytona_list.yaml +++ b/hack/docs/agent_mode/daytona_list.yaml @@ -1,5 +1,5 @@ name: daytona list -synopsis: List workspaces +synopsis: List targets usage: daytona list [flags] options: - name: format @@ -14,4 +14,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_logs.yaml b/hack/docs/agent_mode/daytona_logs.yaml similarity index 55% rename from hack/docs/workspace_mode/daytona_logs.yaml rename to hack/docs/agent_mode/daytona_logs.yaml index 9fe68b0093..d045665711 100644 --- a/hack/docs/workspace_mode/daytona_logs.yaml +++ b/hack/docs/agent_mode/daytona_logs.yaml @@ -1,18 +1,18 @@ name: daytona logs -synopsis: View logs for a workspace/project -usage: daytona logs [WORKSPACE] [PROJECT_NAME] [flags] +synopsis: View logs for a target/project +usage: daytona logs [TARGET] [PROJECT_NAME] [flags] options: - name: follow shorthand: f default_value: "false" usage: Follow logs - - name: workspace + - name: target shorthand: w default_value: "false" - usage: View workspace logs + usage: View target logs inherited_options: - name: help default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_restart.yaml b/hack/docs/agent_mode/daytona_restart.yaml similarity index 75% rename from hack/docs/workspace_mode/daytona_restart.yaml rename to hack/docs/agent_mode/daytona_restart.yaml index 66b72c1775..0acef2905d 100644 --- a/hack/docs/workspace_mode/daytona_restart.yaml +++ b/hack/docs/agent_mode/daytona_restart.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_start.yaml b/hack/docs/agent_mode/daytona_start.yaml similarity index 74% rename from hack/docs/workspace_mode/daytona_start.yaml rename to hack/docs/agent_mode/daytona_start.yaml index b641246389..4dbd1585ca 100644 --- a/hack/docs/workspace_mode/daytona_start.yaml +++ b/hack/docs/agent_mode/daytona_start.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_stop.yaml b/hack/docs/agent_mode/daytona_stop.yaml similarity index 74% rename from hack/docs/workspace_mode/daytona_stop.yaml rename to hack/docs/agent_mode/daytona_stop.yaml index eda52d2732..bdcaa8361e 100644 --- a/hack/docs/workspace_mode/daytona_stop.yaml +++ b/hack/docs/agent_mode/daytona_stop.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/workspace_mode/daytona_version.yaml b/hack/docs/agent_mode/daytona_version.yaml similarity index 75% rename from hack/docs/workspace_mode/daytona_version.yaml rename to hack/docs/agent_mode/daytona_version.yaml index 3557221589..02035a7170 100644 --- a/hack/docs/workspace_mode/daytona_version.yaml +++ b/hack/docs/agent_mode/daytona_version.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona - Use the Daytona CLI to manage your workspace + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 1ea45ce8ac..7d100277f0 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -14,30 +14,30 @@ see_also: - daytona api-key - Api Key commands - daytona autocomplete - Adds a completion script for your shell environment - daytona build - Manage builds - - daytona code - Open a workspace in your preferred IDE + - daytona code - Open a target in your preferred IDE - daytona config - Output Daytona configuration - daytona container-registry - Manage container registries - - daytona create - Create a workspace - - daytona delete - Delete a workspace + - daytona create - Create a target + - daytona delete - Delete a target - daytona docs - Opens the Daytona documentation in your default browser. - - daytona env - Manage profile environment variables that are added to all workspaces + - daytona env - Manage profile environment variables that are added to all targets and projects - daytona forward - Forward a port from a project to your local machine - daytona git-providers - Manage Git providers - daytona ide - Choose the default IDE - - daytona info - Show workspace info - - daytona list - List workspaces - - daytona logs - View logs for a workspace/project + - daytona info - Show target info + - daytona list - List targets + - daytona logs - View logs for a target/project - daytona prebuild - Manage prebuilds - daytona profile - Manage profiles - daytona project-config - Manage project configs - daytona provider - Manage providers - daytona purge - Purges all Daytona data from the current device - - daytona restart - Restart a workspace + - daytona restart - Restart a target - daytona serve - Run the server process in the current terminal session - daytona server - Start the server process in daemon mode - daytona ssh - SSH into a project using the terminal - - daytona start - Start a workspace - - daytona stop - Stop a workspace + - daytona start - Start a target + - daytona stop - Stop a target - daytona target-config - Manage target configs - daytona telemetry - Manage telemetry collection - daytona update - Update Daytona CLI diff --git a/hack/docs/daytona_code.yaml b/hack/docs/daytona_code.yaml index 049123a7d7..264fc64e7d 100644 --- a/hack/docs/daytona_code.yaml +++ b/hack/docs/daytona_code.yaml @@ -1,6 +1,6 @@ name: daytona code -synopsis: Open a workspace in your preferred IDE -usage: daytona code [WORKSPACE] [PROJECT] [flags] +synopsis: Open a target in your preferred IDE +usage: daytona code [TARGET] [PROJECT] [flags] options: - name: ide shorthand: i diff --git a/hack/docs/daytona_create.yaml b/hack/docs/daytona_create.yaml index d8afd7b6ab..8e48bddded 100644 --- a/hack/docs/daytona_create.yaml +++ b/hack/docs/daytona_create.yaml @@ -1,5 +1,5 @@ name: daytona create -synopsis: Create a workspace +synopsis: Create a target usage: daytona create [REPOSITORY_URL | PROJECT_CONFIG_NAME]... [flags] options: - name: blank @@ -34,14 +34,13 @@ options: usage: Manually enter the Git repository - name: multi-project default_value: "false" - usage: Workspace with multiple projects/repos + usage: Target with multiple projects/repos - name: name - usage: Specify the workspace name + usage: Specify the target name - name: no-ide shorthand: "n" default_value: "false" - usage: | - Do not open the workspace in the IDE after workspace creation + usage: Do not open the target in the IDE after target creation - name: target shorthand: t usage: Specify the target (e.g. 'local') diff --git a/hack/docs/daytona_delete.yaml b/hack/docs/daytona_delete.yaml index f7e3545122..2b800708da 100644 --- a/hack/docs/daytona_delete.yaml +++ b/hack/docs/daytona_delete.yaml @@ -1,15 +1,15 @@ name: daytona delete -synopsis: Delete a workspace -usage: daytona delete [WORKSPACE] [flags] +synopsis: Delete a target +usage: daytona delete [TARGET] [flags] options: - name: all shorthand: a default_value: "false" - usage: Delete all workspaces + usage: Delete all targets - name: force shorthand: f default_value: "false" - usage: Delete a workspace by force + usage: Delete a target by force - name: "yes" shorthand: "y" default_value: "false" diff --git a/hack/docs/daytona_env.yaml b/hack/docs/daytona_env.yaml index 8b53a3511c..bffc8dabb3 100644 --- a/hack/docs/daytona_env.yaml +++ b/hack/docs/daytona_env.yaml @@ -1,6 +1,6 @@ name: daytona env synopsis: | - Manage profile environment variables that are added to all workspaces + Manage profile environment variables that are added to all targets and projects inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_env_list.yaml b/hack/docs/daytona_env_list.yaml index a199339142..d74f46a61a 100644 --- a/hack/docs/daytona_env_list.yaml +++ b/hack/docs/daytona_env_list.yaml @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona env - Manage profile environment variables that are added to all workspaces + - daytona env - Manage profile environment variables that are added to all targets and projects diff --git a/hack/docs/daytona_env_set.yaml b/hack/docs/daytona_env_set.yaml index de033d3165..e082b96d6d 100644 --- a/hack/docs/daytona_env_set.yaml +++ b/hack/docs/daytona_env_set.yaml @@ -6,4 +6,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona env - Manage profile environment variables that are added to all workspaces + - daytona env - Manage profile environment variables that are added to all targets and projects diff --git a/hack/docs/daytona_forward.yaml b/hack/docs/daytona_forward.yaml index 2b1e418dea..7b95869f20 100644 --- a/hack/docs/daytona_forward.yaml +++ b/hack/docs/daytona_forward.yaml @@ -1,6 +1,6 @@ name: daytona forward synopsis: Forward a port from a project to your local machine -usage: daytona forward [PORT] [WORKSPACE] [PROJECT] [flags] +usage: daytona forward [PORT] [TARGET] [PROJECT] [flags] options: - name: public default_value: "false" diff --git a/hack/docs/daytona_info.yaml b/hack/docs/daytona_info.yaml index e638f0b36b..6c96f1013e 100644 --- a/hack/docs/daytona_info.yaml +++ b/hack/docs/daytona_info.yaml @@ -1,6 +1,6 @@ name: daytona info -synopsis: Show workspace info -usage: daytona info [WORKSPACE] [flags] +synopsis: Show target info +usage: daytona info [TARGET] [flags] options: - name: format shorthand: f diff --git a/hack/docs/daytona_list.yaml b/hack/docs/daytona_list.yaml index e4efaaea82..08be0d7c58 100644 --- a/hack/docs/daytona_list.yaml +++ b/hack/docs/daytona_list.yaml @@ -1,5 +1,5 @@ name: daytona list -synopsis: List workspaces +synopsis: List targets usage: daytona list [flags] options: - name: format diff --git a/hack/docs/daytona_logs.yaml b/hack/docs/daytona_logs.yaml index 2394b7e87a..d045665711 100644 --- a/hack/docs/daytona_logs.yaml +++ b/hack/docs/daytona_logs.yaml @@ -1,15 +1,15 @@ name: daytona logs -synopsis: View logs for a workspace/project -usage: daytona logs [WORKSPACE] [PROJECT_NAME] [flags] +synopsis: View logs for a target/project +usage: daytona logs [TARGET] [PROJECT_NAME] [flags] options: - name: follow shorthand: f default_value: "false" usage: Follow logs - - name: workspace + - name: target shorthand: w default_value: "false" - usage: View workspace logs + usage: View target logs inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_purge.yaml b/hack/docs/daytona_purge.yaml index d79b020079..7d28219871 100644 --- a/hack/docs/daytona_purge.yaml +++ b/hack/docs/daytona_purge.yaml @@ -1,13 +1,13 @@ name: daytona purge synopsis: Purges all Daytona data from the current device description: | - Purges all Daytona data from the current device - including all workspaces, configuration files, and SSH files. This command is irreversible. + Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. usage: daytona purge [flags] options: - name: force shorthand: f default_value: "false" - usage: Delete all workspaces by force + usage: Delete all targets by force - name: "yes" shorthand: "y" default_value: "false" diff --git a/hack/docs/daytona_restart.yaml b/hack/docs/daytona_restart.yaml index 264482dfd8..ba3d9d6253 100644 --- a/hack/docs/daytona_restart.yaml +++ b/hack/docs/daytona_restart.yaml @@ -1,10 +1,10 @@ name: daytona restart -synopsis: Restart a workspace -usage: daytona restart [WORKSPACE] [flags] +synopsis: Restart a target +usage: daytona restart [TARGET] [flags] options: - name: project shorthand: p - usage: Restart a single project in the workspace (project name) + usage: Restart a single project in the target (project name) inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_ssh.yaml b/hack/docs/daytona_ssh.yaml index 7bee33b3b5..242b06d421 100644 --- a/hack/docs/daytona_ssh.yaml +++ b/hack/docs/daytona_ssh.yaml @@ -1,6 +1,6 @@ name: daytona ssh synopsis: SSH into a project using the terminal -usage: daytona ssh [WORKSPACE] [PROJECT] [CMD...] [flags] +usage: daytona ssh [TARGET] [PROJECT] [CMD...] [flags] options: - name: edit shorthand: e diff --git a/hack/docs/daytona_start.yaml b/hack/docs/daytona_start.yaml index 67321ae0b9..b51ca5e180 100644 --- a/hack/docs/daytona_start.yaml +++ b/hack/docs/daytona_start.yaml @@ -1,18 +1,18 @@ name: daytona start -synopsis: Start a workspace -usage: daytona start [WORKSPACE] [flags] +synopsis: Start a target +usage: daytona start [TARGET] [flags] options: - name: all shorthand: a default_value: "false" - usage: Start all workspaces + usage: Start all targets - name: code shorthand: c default_value: "false" - usage: Open the workspace in the IDE after workspace start + usage: Open the target in the IDE after target start - name: project shorthand: p - usage: Start a single project in the workspace (project name) + usage: Start a single project in the target (project name) - name: "yes" shorthand: "y" default_value: "false" diff --git a/hack/docs/daytona_stop.yaml b/hack/docs/daytona_stop.yaml index e257217fd5..7235fb8771 100644 --- a/hack/docs/daytona_stop.yaml +++ b/hack/docs/daytona_stop.yaml @@ -1,14 +1,14 @@ name: daytona stop -synopsis: Stop a workspace -usage: daytona stop [WORKSPACE] [flags] +synopsis: Stop a target +usage: daytona stop [TARGET] [flags] options: - name: all shorthand: a default_value: "false" - usage: Stop all workspaces + usage: Stop all targets - name: project shorthand: p - usage: Stop a single project in the workspace (project name) + usage: Stop a single project in the target (project name) inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_target-config_remove.yaml b/hack/docs/daytona_target-config_remove.yaml index e9f4a6e74e..8ee216a64d 100644 --- a/hack/docs/daytona_target-config_remove.yaml +++ b/hack/docs/daytona_target-config_remove.yaml @@ -5,7 +5,7 @@ options: - name: "yes" shorthand: "y" default_value: "false" - usage: Confirm deletion of all workspaces without prompt + usage: Confirm deletion of all targets without prompt inherited_options: - name: help default_value: "false" diff --git a/hack/generate-cli-docs.sh b/hack/generate-cli-docs.sh index a9504fc1bc..04239cb907 100755 --- a/hack/generate-cli-docs.sh +++ b/hack/generate-cli-docs.sh @@ -7,5 +7,5 @@ rm -rf docs hack/docs # Generate default CLI documentation files in folder "docs" go run cmd/daytona/main.go generate-docs -# Generate workspace mode documentation files in folder "docs/workspace_mode" -DAYTONA_WS_ID=foo go run cmd/daytona/main.go generate-docs --directory docs/workspace_mode \ No newline at end of file +# Generate agent mode documentation files in folder "docs/agent_mode" +DAYTONA_TARGET_ID=foo go run cmd/daytona/main.go generate-docs --directory docs/agent_mode \ No newline at end of file diff --git a/hack/project_image/.devcontainer/devcontainer.json b/hack/project_image/.devcontainer/devcontainer.json index 2413e8dab0..1ef04574f3 100644 --- a/hack/project_image/.devcontainer/devcontainer.json +++ b/hack/project_image/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "Daytona Workspace Project", + "name": "Daytona", "build": { "context": "..", "dockerfile": "../Dockerfile" @@ -58,4 +58,4 @@ "ghcr.io/wxw-matt/devcontainer-features/command_runner:latest" ], "remoteUser": "daytona" -} +} \ No newline at end of file diff --git a/internal/workspace_mode.go b/internal/agent_mode.go similarity index 67% rename from internal/workspace_mode.go rename to internal/agent_mode.go index 0e648b25e3..8faf824ba2 100644 --- a/internal/workspace_mode.go +++ b/internal/agent_mode.go @@ -5,13 +5,13 @@ package internal import "os" -func WorkspaceMode() bool { +func AgentMode() bool { _, devEnv := os.LookupEnv("DAYTONA_DEV") if devEnv { return false } - val, wsMode := os.LookupEnv("DAYTONA_WS_ID") - if wsMode && val != "" { + val, agentMode := os.LookupEnv("DAYTONA_TARGET_ID") + if agentMode && val != "" { return true } return false diff --git a/internal/cmd/tailscale/forward.go b/internal/cmd/tailscale/forward.go index d03e06eb80..4562966db4 100644 --- a/internal/cmd/tailscale/forward.go +++ b/internal/cmd/tailscale/forward.go @@ -11,11 +11,11 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "tailscale.com/tsnet" ) -func ForwardPort(workspaceId, projectName string, targetPort uint16, profile config.Profile) (*uint16, chan error) { +func ForwardPort(targetId, projectName string, targetPort uint16, profile config.Profile) (*uint16, chan error) { hostPort := targetPort errChan := make(chan error) var err error @@ -47,7 +47,7 @@ func ForwardPort(workspaceId, projectName string, targetPort uint16, profile con return } - targetUrl := fmt.Sprintf("%s:%d", project.GetProjectHostname(workspaceId, projectName), targetPort) + targetUrl := fmt.Sprintf("%s:%d", project.GetProjectHostname(targetId, projectName), targetPort) go handlePortConnection(conn, tsConn, targetUrl, errChan) } diff --git a/internal/testing/agent/mocks/apiserver.go b/internal/testing/agent/mocks/apiserver.go index b73034d839..79b224ddb5 100644 --- a/internal/testing/agent/mocks/apiserver.go +++ b/internal/testing/agent/mocks/apiserver.go @@ -12,11 +12,11 @@ import ( "testing" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" "github.com/gin-gonic/gin" ) -func NewMockRestServer(t *testing.T, workspace *workspace.Workspace) *httptest.Server { +func NewMockRestServer(t *testing.T, target *target.Target) *httptest.Server { router := gin.Default() serverController := router.Group("/server") { @@ -37,10 +37,10 @@ func NewMockRestServer(t *testing.T, workspace *workspace.Workspace) *httptest.S }) } - workspaceController := router.Group("/workspace") + targetController := router.Group("/target") { - workspaceController.GET("/:workspaceId", func(ctx *gin.Context) { - ctx.JSON(http.StatusOK, workspace) + targetController.GET("/:targetId", func(ctx *gin.Context) { + ctx.JSON(http.StatusOK, target) }) } diff --git a/internal/testing/docker/mocks/client.go b/internal/testing/docker/mocks/client.go index 721f90201c..69c34bc4fe 100644 --- a/internal/testing/docker/mocks/client.go +++ b/internal/testing/docker/mocks/client.go @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/mock" ) @@ -30,8 +30,8 @@ func (c *MockClient) CreateProject(p *project.Project, serverDownloadUrl string, return args.Error(0) } -func (c *MockClient) CreateWorkspace(workspace *workspace.Workspace, logWriter io.Writer) error { - args := c.Called(workspace, logWriter) +func (c *MockClient) CreateTarget(target *target.Target, logWriter io.Writer) error { + args := c.Called(target, logWriter) return args.Error(0) } @@ -40,8 +40,8 @@ func (c *MockClient) DestroyProject(p *project.Project) error { return args.Error(0) } -func (c *MockClient) DestroyWorkspace(workspace *workspace.Workspace) error { - args := c.Called(workspace) +func (c *MockClient) DestroyTarget(target *target.Target) error { + args := c.Called(target) return args.Error(0) } @@ -60,9 +60,9 @@ func (c *MockClient) GetProjectInfo(p *project.Project) (*project.ProjectInfo, e return args.Get(0).(*project.ProjectInfo), args.Error(1) } -func (c *MockClient) GetWorkspaceInfo(ws *workspace.Workspace) (*workspace.WorkspaceInfo, error) { +func (c *MockClient) GetTargetInfo(ws *target.Target) (*target.TargetInfo, error) { args := c.Called(ws) - return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) + return args.Get(0).(*target.TargetInfo), args.Error(1) } func (c *MockClient) GetProjectContainerName(p *project.Project) string { diff --git a/internal/testing/git/mocks/gitservice.go b/internal/testing/git/mocks/gitservice.go index 99ea2a30a8..02d67e19b9 100644 --- a/internal/testing/git/mocks/gitservice.go +++ b/internal/testing/git/mocks/gitservice.go @@ -7,7 +7,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/logger/mocks/logger.go b/internal/testing/logger/mocks/logger.go index 9ffb1bebfe..ab65d90929 100644 --- a/internal/testing/logger/mocks/logger.go +++ b/internal/testing/logger/mocks/logger.go @@ -20,11 +20,11 @@ type MockLoggerFactory struct { mock.Mock } -func (f *MockLoggerFactory) CreateWorkspaceLogger(workspaceId string, source logs.LogSource) logs.Logger { +func (f *MockLoggerFactory) CreateTargetLogger(targetId string, source logs.LogSource) logs.Logger { return &mockLogger{} } -func (f *MockLoggerFactory) CreateProjectLogger(workspaceId, projectName string, source logs.LogSource) logs.Logger { +func (f *MockLoggerFactory) CreateProjectLogger(targetId, projectName string, source logs.LogSource) logs.Logger { return &mockLogger{} } @@ -32,11 +32,11 @@ func (f *MockLoggerFactory) CreateBuildLogger(projectName, hash string, source l return &mockLogger{} } -func (f *MockLoggerFactory) CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) { +func (f *MockLoggerFactory) CreateTargetLogReader(targetId string) (io.Reader, error) { return nil, nil } -func (f *MockLoggerFactory) CreateProjectLogReader(workspaceId, projectName string) (io.Reader, error) { +func (f *MockLoggerFactory) CreateProjectLogReader(targetId, projectName string) (io.Reader, error) { return nil, nil } diff --git a/internal/testing/server/projectconfig/store.go b/internal/testing/server/projectconfig/store.go index b2f19e60e7..ec7d983648 100644 --- a/internal/testing/server/projectconfig/store.go +++ b/internal/testing/server/projectconfig/store.go @@ -8,7 +8,7 @@ package projectconfig import ( "fmt" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" ) type InMemoryProjectConfigStore struct { diff --git a/internal/testing/server/workspaces/mocks/api_key_service.go b/internal/testing/server/targets/mocks/api_key_service.go similarity index 93% rename from internal/testing/server/workspaces/mocks/api_key_service.go rename to internal/testing/server/targets/mocks/api_key_service.go index dfdfccc7ea..779d44d9e5 100644 --- a/internal/testing/server/workspaces/mocks/api_key_service.go +++ b/internal/testing/server/targets/mocks/api_key_service.go @@ -33,7 +33,7 @@ func (s *mockApiKeyService) IsValidApiKey(apiKey string) bool { return args.Bool(0) } -func (s *mockApiKeyService) IsWorkspaceApiKey(apiKey string) bool { +func (s *mockApiKeyService) IsTargetApiKey(apiKey string) bool { args := s.Called(apiKey) return args.Bool(0) } diff --git a/internal/testing/server/workspaces/mocks/build_service.go b/internal/testing/server/targets/mocks/build_service.go similarity index 100% rename from internal/testing/server/workspaces/mocks/build_service.go rename to internal/testing/server/targets/mocks/build_service.go diff --git a/internal/testing/server/workspaces/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go similarity index 92% rename from internal/testing/server/workspaces/mocks/builder.go rename to internal/testing/server/targets/mocks/builder.go index 19981d217d..39648faeb6 100644 --- a/internal/testing/server/workspaces/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/containerconfig" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/server/workspaces/mocks/container_registry_service.go b/internal/testing/server/targets/mocks/container_registry_service.go similarity index 100% rename from internal/testing/server/workspaces/mocks/container_registry_service.go rename to internal/testing/server/targets/mocks/container_registry_service.go diff --git a/internal/testing/server/workspaces/mocks/git_provider_service.go b/internal/testing/server/targets/mocks/git_provider_service.go similarity index 100% rename from internal/testing/server/workspaces/mocks/git_provider_service.go rename to internal/testing/server/targets/mocks/git_provider_service.go diff --git a/internal/testing/server/workspaces/mocks/project_config.go b/internal/testing/server/targets/mocks/project_config.go similarity index 74% rename from internal/testing/server/workspaces/mocks/project_config.go rename to internal/testing/server/targets/mocks/project_config.go index f6e58ee498..2c29bd2555 100644 --- a/internal/testing/server/workspaces/mocks/project_config.go +++ b/internal/testing/server/targets/mocks/project_config.go @@ -6,8 +6,8 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/config" ) var MockProjectConfig = config.ProjectConfig{ diff --git a/internal/testing/server/workspaces/mocks/project_config_service.go b/internal/testing/server/targets/mocks/project_config_service.go similarity index 97% rename from internal/testing/server/workspaces/mocks/project_config_service.go rename to internal/testing/server/targets/mocks/project_config_service.go index 31301edcbf..90ba2fc330 100644 --- a/internal/testing/server/workspaces/mocks/project_config_service.go +++ b/internal/testing/server/targets/mocks/project_config_service.go @@ -8,7 +8,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/server/workspaces/mocks/provisioner.go b/internal/testing/server/targets/mocks/provisioner.go similarity index 53% rename from internal/testing/server/workspaces/mocks/provisioner.go rename to internal/testing/server/targets/mocks/provisioner.go index e4567f58df..1febda9885 100644 --- a/internal/testing/server/workspaces/mocks/provisioner.go +++ b/internal/testing/server/targets/mocks/provisioner.go @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/stretchr/testify/mock" ) @@ -28,8 +28,8 @@ func (p *mockProvisioner) CreateProject(params provisioner.ProjectParams) error return args.Error(0) } -func (p *mockProvisioner) CreateWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { - args := p.Called(workspace, targetConfig) +func (p *mockProvisioner) CreateTarget(target *target.Target, targetConfig *provider.TargetConfig) error { + args := p.Called(target, targetConfig) return args.Error(0) } @@ -38,14 +38,14 @@ func (p *mockProvisioner) DestroyProject(proj *project.Project, targetConfig *pr return args.Error(0) } -func (p *mockProvisioner) DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { - args := p.Called(workspace, targetConfig) +func (p *mockProvisioner) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error { + args := p.Called(target, targetConfig) return args.Error(0) } -func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { +func (p *mockProvisioner) GetTargetInfo(ctx context.Context, w *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) { args := p.Called(ctx, w, targetConfig) - return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) + return args.Get(0).(*target.TargetInfo), args.Error(1) } func (p *mockProvisioner) StartProject(params provisioner.ProjectParams) error { @@ -53,8 +53,8 @@ func (p *mockProvisioner) StartProject(params provisioner.ProjectParams) error { return args.Error(0) } -func (p *mockProvisioner) StartWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { - args := p.Called(workspace, targetConfig) +func (p *mockProvisioner) StartTarget(target *target.Target, targetConfig *provider.TargetConfig) error { + args := p.Called(target, targetConfig) return args.Error(0) } @@ -63,7 +63,7 @@ func (p *mockProvisioner) StopProject(proj *project.Project, targetConfig *provi return args.Error(0) } -func (p *mockProvisioner) StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { - args := p.Called(workspace, targetConfig) +func (p *mockProvisioner) StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error { + args := p.Called(target, targetConfig) return args.Error(0) } diff --git a/internal/testing/server/workspaces/mocks/scheduler.go b/internal/testing/server/targets/mocks/scheduler.go similarity index 100% rename from internal/testing/server/workspaces/mocks/scheduler.go rename to internal/testing/server/targets/mocks/scheduler.go diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go new file mode 100644 index 0000000000..f835a7e988 --- /dev/null +++ b/internal/testing/server/targets/store.go @@ -0,0 +1,51 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import "github.com/daytonaio/daytona/pkg/target" + +type InMemoryTargetStore struct { + targets map[string]*target.Target +} + +func NewInMemoryTargetStore() target.Store { + return &InMemoryTargetStore{ + targets: make(map[string]*target.Target), + } +} + +func (s *InMemoryTargetStore) List() ([]*target.Target, error) { + targets := []*target.Target{} + for _, t := range s.targets { + targets = append(targets, t) + } + + return targets, nil +} + +func (s *InMemoryTargetStore) Find(idOrName string) (*target.Target, error) { + t, ok := s.targets[idOrName] + if !ok { + for _, w := range s.targets { + if w.Name == idOrName { + return w, nil + } + } + return nil, target.ErrTargetNotFound + } + + return t, nil +} + +func (s *InMemoryTargetStore) Save(target *target.Target) error { + s.targets[target.Id] = target + return nil +} + +func (s *InMemoryTargetStore) Delete(target *target.Target) error { + delete(s.targets, target.Id) + return nil +} diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go deleted file mode 100644 index ca31f0e8bc..0000000000 --- a/internal/testing/server/workspaces/store.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaces - -import ( - "github.com/daytonaio/daytona/pkg/workspace" -) - -type InMemoryWorkspaceStore struct { - workspaces map[string]*workspace.Workspace -} - -func NewInMemoryWorkspaceStore() workspace.Store { - return &InMemoryWorkspaceStore{ - workspaces: make(map[string]*workspace.Workspace), - } -} - -func (s *InMemoryWorkspaceStore) List() ([]*workspace.Workspace, error) { - workspaces := []*workspace.Workspace{} - for _, w := range s.workspaces { - workspaces = append(workspaces, w) - } - - return workspaces, nil -} - -func (s *InMemoryWorkspaceStore) Find(idOrName string) (*workspace.Workspace, error) { - ws, ok := s.workspaces[idOrName] - if !ok { - for _, w := range s.workspaces { - if w.Name == idOrName { - return w, nil - } - } - return nil, workspace.ErrWorkspaceNotFound - } - - return ws, nil -} - -func (s *InMemoryWorkspaceStore) Save(workspace *workspace.Workspace) error { - s.workspaces[workspace.Id] = workspace - return nil -} - -func (s *InMemoryWorkspaceStore) Delete(workspace *workspace.Workspace) error { - delete(s.workspaces, workspace.Id) - return nil -} diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index 937dc7684f..7310a98ea3 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -61,7 +61,7 @@ func GetApiClient(profile *config.Profile) (*apiclient.APIClient, error) { clientConfig.AddDefaultHeader(telemetry.ENABLED_HEADER, "true") clientConfig.AddDefaultHeader(telemetry.SESSION_ID_HEADER, internal.SESSION_ID) clientConfig.AddDefaultHeader(telemetry.CLIENT_ID_HEADER, config.GetClientId()) - if internal.WorkspaceMode() { + if internal.AgentMode() { clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_PROJECT_SOURCE)) } else { clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_SOURCE)) @@ -115,7 +115,7 @@ func GetAgentApiClient(apiUrl, apiKey, clientId string, telemetryEnabled bool) ( return apiClient, nil } -func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceDTO, error) { +func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, error) { ctx := context.Background() apiClient, err := GetApiClient(nil) @@ -123,15 +123,15 @@ func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceD return nil, err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceNameOrId).Verbose(verbose).Execute() + target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetNameOrId).Verbose(verbose).Execute() if err != nil { return nil, HandleErrorResponse(res, err) } - return workspace, nil + return target, nil } -func GetFirstWorkspaceProjectName(workspaceId string, projectName string, profile *config.Profile) (string, error) { +func GetFirstProjectName(targetId string, projectName string, profile *config.Profile) (string, error) { ctx := context.Background() apiClient, err := GetApiClient(profile) @@ -139,24 +139,24 @@ func GetFirstWorkspaceProjectName(workspaceId string, projectName string, profil return "", err } - wsInfo, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() if err != nil { return "", HandleErrorResponse(res, err) } if projectName == "" { - if len(wsInfo.Projects) == 0 { - return "", errors.New("no projects found in workspace") + if len(targetInfo.Projects) == 0 { + return "", errors.New("no projects found in target") } - return wsInfo.Projects[0].Name, nil + return targetInfo.Projects[0].Name, nil } - for _, project := range wsInfo.Projects { + for _, project := range targetInfo.Projects { if project.Name == projectName { return project.Name, nil } } - return "", errors.New("project not found in workspace") + return "", errors.New("project not found in target") } diff --git a/internal/util/apiclient/conversion/project.go b/internal/util/apiclient/conversion/project.go index d7290b1061..916f6472d0 100644 --- a/internal/util/apiclient/conversion/project.go +++ b/internal/util/apiclient/conversion/project.go @@ -7,10 +7,10 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" pc_dto "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - project_dto "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/workspace/project" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + project_dto "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/config" ) func ToProject(projectDTO *apiclient.Project) *project.Project { @@ -56,7 +56,7 @@ func ToProject(projectDTO *apiclient.Project) *project.Project { BuildConfig: projectBuild, Repository: repository, TargetConfig: projectDTO.TargetConfig, - WorkspaceId: projectDTO.WorkspaceId, + TargetId: projectDTO.TargetId, State: projectState, GitProviderConfigId: projectDTO.GitProviderConfigId, } diff --git a/internal/util/apiclient/websocket_log_reader.go b/internal/util/apiclient/websocket_log_reader.go index c60ddf07ff..aeebf0c004 100644 --- a/internal/util/apiclient/websocket_log_reader.go +++ b/internal/util/apiclient/websocket_log_reader.go @@ -16,17 +16,17 @@ import ( log "github.com/sirupsen/logrus" ) -var workspaceLogsStarted bool +var targetLogsStarted bool -func ReadWorkspaceLogs(ctx context.Context, activeProfile config.Profile, workspaceId string, projectNames []string, follow, showWorkspaceLogs bool, from *time.Time) { +func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId string, projectNames []string, follow, showTargetLogs bool, from *time.Time) { var wg sync.WaitGroup query := "" if follow { query = "follow=true" } - if !showWorkspaceLogs { - workspaceLogsStarted = true + if !showTargetLogs { + targetLogsStarted = true } logs_view.CalculateLongestPrefixLength(projectNames) @@ -36,13 +36,13 @@ func ReadWorkspaceLogs(ctx context.Context, activeProfile config.Profile, worksp defer wg.Done() for { - // Make sure workspace logs started before showing any project logs - if !workspaceLogsStarted { + // Make sure target logs started before showing any project logs + if !targetLogsStarted { time.Sleep(250 * time.Millisecond) continue } - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s/%s", workspaceId, projectName), &activeProfile, &query) + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s/%s", targetId, projectName), &activeProfile, &query) // We want to retry getting the logs if it fails if err != nil { log.Trace(HandleErrorResponse(res, err)) @@ -57,9 +57,9 @@ func ReadWorkspaceLogs(ctx context.Context, activeProfile config.Profile, worksp }(projectName, from) } - if showWorkspaceLogs { + if showTargetLogs { for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s", workspaceId), &activeProfile, &query) + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", targetId), &activeProfile, &query) // We want to retry getting the logs if it fails if err != nil { log.Trace(HandleErrorResponse(res, err)) @@ -148,8 +148,8 @@ func readJSONLog(ctx context.Context, ws *websocket.Conn, index int, from *time. } } - if !workspaceLogsStarted && index == logs_view.STATIC_INDEX { - workspaceLogsStarted = true + if !targetLogsStarted && index == logs_view.STATIC_INDEX { + targetLogsStarted = true } } } diff --git a/internal/util/cmd.go b/internal/util/cmd.go index fa0868ee7c..d34be9d4f6 100644 --- a/internal/util/cmd.go +++ b/internal/util/cmd.go @@ -4,7 +4,7 @@ package util const ( - WORKSPACE_GROUP = "workspace" - SERVER_GROUP = "server" - PROFILE_GROUP = "profile" + TARGET_GROUP = "target" + SERVER_GROUP = "server" + PROFILE_GROUP = "profile" ) diff --git a/internal/util/path.go b/internal/util/path.go index 482cf6075e..2df3482292 100644 --- a/internal/util/path.go +++ b/internal/util/path.go @@ -11,13 +11,13 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func GetHomeDir(activeProfile config.Profile, workspaceId string, projectName string, gpgKey string) (string, error) { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, projectName, gpgKey) +func GetHomeDir(activeProfile config.Profile, targetId string, projectName string, gpgKey string) (string, error) { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) if err != nil { return "", err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) homeDir, err := exec.Command("ssh", projectHostname, "echo", "$HOME").Output() if err != nil { @@ -27,13 +27,13 @@ func GetHomeDir(activeProfile config.Profile, workspaceId string, projectName st return strings.TrimRight(string(homeDir), "\n"), nil } -func GetProjectDir(activeProfile config.Profile, workspaceId string, projectName string, gpgKey string) (string, error) { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, projectName, gpgKey) +func GetProjectDir(activeProfile config.Profile, targetId string, projectName string, gpgKey string) (string, error) { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) if err != nil { return "", err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) daytonaProjectDir, err := exec.Command("ssh", projectHostname, "echo", "$DAYTONA_PROJECT_DIR").Output() if err != nil { @@ -44,7 +44,7 @@ func GetProjectDir(activeProfile config.Profile, workspaceId string, projectName return strings.TrimRight(string(daytonaProjectDir), "\n"), nil } - homeDir, err := GetHomeDir(activeProfile, workspaceId, projectName, gpgKey) + homeDir, err := GetHomeDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return "", err } diff --git a/internal/util/workspace.go b/internal/util/target.go similarity index 100% rename from internal/util/workspace.go rename to internal/util/target.go diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index efb0bdcc82..1be2c55a9b 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -19,7 +19,7 @@ import ( agent_config "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/go-git/go-git/v5/plumbing/transport/http" log "github.com/sirupsen/logrus" ) @@ -165,12 +165,12 @@ func (a *Agent) getProject() (*project.Project, error) { return nil, err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, a.Config.WorkspaceId).Execute() + target, res, err := apiClient.TargetAPI.GetTarget(ctx, a.Config.TargetId).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - for _, project := range workspace.Projects { + for _, project := range target.Projects { if project.Name == a.Config.ProjectName { return conversion.ToProject(&project), nil } @@ -264,7 +264,7 @@ func (a *Agent) updateProjectState() error { } uptime := a.uptime() - res, err := apiClient.WorkspaceAPI.SetProjectState(context.Background(), a.Config.WorkspaceId, a.Config.ProjectName).SetState(apiclient.SetProjectState{ + res, err := apiClient.TargetAPI.SetProjectState(context.Background(), a.Config.TargetId, a.Config.ProjectName).SetState(apiclient.SetProjectState{ Uptime: uptime, GitStatus: conversion.ToGitStatusDTO(gitStatus), }).Execute() diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 472fcd94a0..5a1760975d 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -16,8 +16,8 @@ import ( "github.com/daytonaio/daytona/pkg/agent" "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) var project1 = &project.Project{ @@ -27,7 +27,7 @@ var project1 = &project.Project{ Url: "https://github.com/daytonaio/daytona", Name: "daytona", }, - WorkspaceId: "123", + TargetId: "123", TargetConfig: "local", State: &project.ProjectState{ UpdatedAt: "123", @@ -36,7 +36,7 @@ var project1 = &project.Project{ }, } -var workspace1 = &workspace.Workspace{ +var target1 = &target.Target{ Id: "123", Name: "test", TargetConfig: "local", @@ -56,7 +56,7 @@ var gitStatus1 = &project.GitStatus{ } var mockConfig = &config.Config{ - WorkspaceId: workspace1.Id, + TargetId: target1.Id, ProjectName: project1.Name, Server: config.DaytonaServerConfig{ ApiKey: "test-api-key", @@ -68,7 +68,7 @@ func TestAgent(t *testing.T) { buf := bytes.Buffer{} log.SetOutput(&buf) - apiServer := mocks.NewMockRestServer(t, workspace1) + apiServer := mocks.NewMockRestServer(t, target1) defer apiServer.Close() mockConfig.Server.ApiUrl = apiServer.URL diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index 4be2825835..613b35d249 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -23,8 +23,8 @@ type DaytonaServerConfig struct { type Config struct { ProjectDir string ClientId string `envconfig:"DAYTONA_CLIENT_ID" validate:"required"` - ProjectName string `envconfig:"DAYTONA_WS_PROJECT_NAME"` - WorkspaceId string `envconfig:"DAYTONA_WS_ID" validate:"required"` + ProjectName string `envconfig:"DAYTONA_PROJECT_NAME"` + TargetId string `envconfig:"DAYTONA_TARGET_ID" validate:"required"` LogFilePath *string `envconfig:"DAYTONA_AGENT_LOG_FILE_PATH"` Server DaytonaServerConfig Mode Mode @@ -67,7 +67,7 @@ func GetConfig(mode Mode) (*Config, error) { if config.Mode == ModeProject { if config.ProjectName == "" { - return nil, errors.New("DAYTONA_WS_PROJECT_NAME is required in project mode") + return nil, errors.New("DAYTONA_PROJECT_NAME is required in project mode") } } diff --git a/pkg/agent/log.go b/pkg/agent/log.go index 61337ab7c6..85c7a3ef1c 100644 --- a/pkg/agent/log.go +++ b/pkg/agent/log.go @@ -28,7 +28,7 @@ func (f *logFormatter) Format(entry *log.Entry) ([]byte, error) { } // Return the original message without log decoration - // We don't want decoration to show up in the workspace creation logs + // We don't want decoration to show up in the target creation logs return []byte(entry.Message + "\n"), nil } diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index 36ea2f8d51..ebd32cc888 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server" builds_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" "github.com/gin-gonic/gin" ) diff --git a/pkg/api/controllers/log/websocket.go b/pkg/api/controllers/log/websocket.go index e5c23f2c0d..12447ba208 100644 --- a/pkg/api/controllers/log/websocket.go +++ b/pkg/api/controllers/log/websocket.go @@ -143,8 +143,8 @@ func ReadServerLog(ginCtx *gin.Context) { ReadLog(ginCtx, reader, util.ReadLog, writeToWs) } -func ReadWorkspaceLog(ginCtx *gin.Context) { - workspaceId := ginCtx.Param("workspaceId") +func ReadTargetLog(ginCtx *gin.Context) { + targetId := ginCtx.Param("targetId") retryQuery := ginCtx.DefaultQuery("retry", "true") retry := retryQuery == "true" @@ -152,7 +152,7 @@ func ReadWorkspaceLog(ginCtx *gin.Context) { if retry { for { - wsLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(workspaceId) + wsLogReader, err := server.TargetService.GetTargetLogReader(targetId) if err == nil { ReadLog(ginCtx, wsLogReader, util.ReadJSONLog, writeJSONToWs) return @@ -161,7 +161,7 @@ func ReadWorkspaceLog(ginCtx *gin.Context) { } } - wsLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(workspaceId) + wsLogReader, err := server.TargetService.GetTargetLogReader(targetId) if err != nil { ginCtx.AbortWithError(http.StatusInternalServerError, err) return @@ -171,7 +171,7 @@ func ReadWorkspaceLog(ginCtx *gin.Context) { } func ReadProjectLog(ginCtx *gin.Context) { - workspaceId := ginCtx.Param("workspaceId") + targetId := ginCtx.Param("targetId") projectName := ginCtx.Param("projectName") retryQuery := ginCtx.DefaultQuery("retry", "true") retry := retryQuery == "true" @@ -180,7 +180,7 @@ func ReadProjectLog(ginCtx *gin.Context) { if retry { for { - projectLogReader, err := server.WorkspaceService.GetProjectLogReader(workspaceId, projectName) + projectLogReader, err := server.TargetService.GetProjectLogReader(targetId, projectName) if err == nil { ReadLog(ginCtx, projectLogReader, util.ReadJSONLog, writeJSONToWs) return @@ -189,7 +189,7 @@ func ReadProjectLog(ginCtx *gin.Context) { } } - projectLogReader, err := server.WorkspaceService.GetProjectLogReader(workspaceId, projectName) + projectLogReader, err := server.TargetService.GetProjectLogReader(targetId, projectName) if err != nil { ginCtx.AbortWithError(http.StatusInternalServerError, err) return diff --git a/pkg/api/controllers/projectconfig/prebuild/prebuild.go b/pkg/api/controllers/projectconfig/prebuild/prebuild.go index 6bc2881f37..c9437e2948 100644 --- a/pkg/api/controllers/projectconfig/prebuild/prebuild.go +++ b/pkg/api/controllers/projectconfig/prebuild/prebuild.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" "github.com/gin-gonic/gin" ) diff --git a/pkg/api/controllers/projectconfig/prebuild/process_git_event.go b/pkg/api/controllers/projectconfig/prebuild/process_git_event.go index 08c656007e..1d1abeae65 100644 --- a/pkg/api/controllers/projectconfig/prebuild/process_git_event.go +++ b/pkg/api/controllers/projectconfig/prebuild/process_git_event.go @@ -17,7 +17,7 @@ import ( // @Tags prebuild // @Summary ProcessGitEvent // @Description ProcessGitEvent -// @Param workspace body interface{} true "Webhook event" +// @Param body body interface{} true "Webhook event" // @Success 200 // @Router /project-config/prebuild/process-git-event [post] // diff --git a/pkg/api/controllers/projectconfig/project_config.go b/pkg/api/controllers/projectconfig/project_config.go index 15d7584ee0..30689f4e5f 100644 --- a/pkg/api/controllers/projectconfig/project_config.go +++ b/pkg/api/controllers/projectconfig/project_config.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go new file mode 100644 index 0000000000..75f943edd6 --- /dev/null +++ b/pkg/api/controllers/target/create.go @@ -0,0 +1,49 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "errors" + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/gin-gonic/gin" +) + +// CreateTarget godoc +// +// @Tags target +// @Summary Create a target +// @Description Create a target +// @Param target body CreateTargetDTO true "Create target" +// @Produce json +// @Success 200 {object} Target +// @Router /target [post] +// +// @id CreateTarget +func CreateTarget(ctx *gin.Context) { + var createTargetReq dto.CreateTargetDTO + err := ctx.BindJSON(&createTargetReq) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + w, err := server.TargetService.CreateTarget(ctx.Request.Context(), createTargetReq) + if err != nil { + if errors.Is(err, targets.ErrTargetAlreadyExists) { + ctx.AbortWithError(http.StatusConflict, fmt.Errorf("target already exists: %w", err)) + return + } + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create target: %w", err)) + return + } + + ctx.JSON(200, w) +} diff --git a/pkg/api/controllers/workspace/dto/dto.go b/pkg/api/controllers/target/dto/dto.go similarity index 85% rename from pkg/api/controllers/workspace/dto/dto.go rename to pkg/api/controllers/target/dto/dto.go index ae4501c0b4..2b821b7572 100644 --- a/pkg/api/controllers/workspace/dto/dto.go +++ b/pkg/api/controllers/target/dto/dto.go @@ -4,7 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" ) type SetProjectState struct { diff --git a/pkg/api/controllers/workspace/project.go b/pkg/api/controllers/target/project.go similarity index 67% rename from pkg/api/controllers/workspace/project.go rename to pkg/api/controllers/target/project.go index 1a1ee34209..2f17205df5 100644 --- a/pkg/api/controllers/workspace/project.go +++ b/pkg/api/controllers/target/project.go @@ -1,33 +1,33 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "fmt" "net/http" "time" - "github.com/daytonaio/daytona/pkg/api/controllers/workspace/dto" + "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/gin-gonic/gin" ) // SetProjectState godoc // -// @Tags workspace +// @Tags target // @Summary Set project state // @Description Set project state -// @Param workspaceId path string true "Workspace ID or Name" +// @Param targetId path string true "Target ID or Name" // @Param projectId path string true "Project ID" // @Param setState body SetProjectState true "Set State" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/state [post] +// @Router /target/{targetId}/{projectId}/state [post] // // @id SetProjectState func SetProjectState(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") + targetId := ctx.Param("targetId") projectId := ctx.Param("projectId") var setProjectStateDTO dto.SetProjectState @@ -39,13 +39,13 @@ func SetProjectState(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.WorkspaceService.SetProjectState(workspaceId, projectId, &project.ProjectState{ + _, err = server.TargetService.SetProjectState(targetId, projectId, &project.ProjectState{ Uptime: setProjectStateDTO.Uptime, UpdatedAt: time.Now().Format(time.RFC1123), GitStatus: setProjectStateDTO.GitStatus, }) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %w", workspaceId, err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop target %s: %w", targetId, err)) return } diff --git a/pkg/api/controllers/workspace/start.go b/pkg/api/controllers/target/start.go similarity index 51% rename from pkg/api/controllers/workspace/start.go rename to pkg/api/controllers/target/start.go index e34d6c54ce..a0bea25bc9 100644 --- a/pkg/api/controllers/workspace/start.go +++ b/pkg/api/controllers/target/start.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "fmt" @@ -11,24 +11,24 @@ import ( "github.com/gin-gonic/gin" ) -// StartWorkspace godoc +// StartTarget godoc // -// @Tags workspace -// @Summary Start workspace -// @Description Start workspace -// @Param workspaceId path string true "Workspace ID or Name" +// @Tags target +// @Summary Start target +// @Description Start target +// @Param targetId path string true "Target ID or Name" // @Success 200 -// @Router /workspace/{workspaceId}/start [post] +// @Router /target/{targetId}/start [post] // -// @id StartWorkspace -func StartWorkspace(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") +// @id StartTarget +func StartTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") server := server.GetInstance(nil) - err := server.WorkspaceService.StartWorkspace(ctx.Request.Context(), workspaceId) + err := server.TargetService.StartTarget(ctx.Request.Context(), targetId) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start workspace %s: %w", workspaceId, err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start target %s: %w", targetId, err)) return } @@ -37,22 +37,22 @@ func StartWorkspace(ctx *gin.Context) { // StartProject godoc // -// @Tags workspace +// @Tags target // @Summary Start project // @Description Start project -// @Param workspaceId path string true "Workspace ID or Name" +// @Param targetId path string true "Target ID or Name" // @Param projectId path string true "Project ID" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/start [post] +// @Router /target/{targetId}/{projectId}/start [post] // // @id StartProject func StartProject(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") + targetId := ctx.Param("targetId") projectId := ctx.Param("projectId") server := server.GetInstance(nil) - err := server.WorkspaceService.StartProject(ctx.Request.Context(), workspaceId, projectId) + err := server.TargetService.StartProject(ctx.Request.Context(), targetId, projectId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start project %s: %w", projectId, err)) return diff --git a/pkg/api/controllers/workspace/stop.go b/pkg/api/controllers/target/stop.go similarity index 51% rename from pkg/api/controllers/workspace/stop.go rename to pkg/api/controllers/target/stop.go index f738fd496e..b16a72344c 100644 --- a/pkg/api/controllers/workspace/stop.go +++ b/pkg/api/controllers/target/stop.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "fmt" @@ -11,24 +11,24 @@ import ( "github.com/gin-gonic/gin" ) -// StopWorkspace godoc +// StopTarget godoc // -// @Tags workspace -// @Summary Stop workspace -// @Description Stop workspace -// @Param workspaceId path string true "Workspace ID or Name" +// @Tags target +// @Summary Stop target +// @Description Stop target +// @Param targetId path string true "Target ID or Name" // @Success 200 -// @Router /workspace/{workspaceId}/stop [post] +// @Router /target/{targetId}/stop [post] // -// @id StopWorkspace -func StopWorkspace(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") +// @id StopTarget +func StopTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") server := server.GetInstance(nil) - err := server.WorkspaceService.StopWorkspace(ctx.Request.Context(), workspaceId) + err := server.TargetService.StopTarget(ctx.Request.Context(), targetId) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %w", workspaceId, err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop target %s: %w", targetId, err)) return } @@ -37,22 +37,22 @@ func StopWorkspace(ctx *gin.Context) { // StopProject godoc // -// @Tags workspace +// @Tags target // @Summary Stop project // @Description Stop project -// @Param workspaceId path string true "Workspace ID or Name" +// @Param targetId path string true "Target ID or Name" // @Param projectId path string true "Project ID" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/stop [post] +// @Router /target/{targetId}/{projectId}/stop [post] // // @id StopProject func StopProject(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") + targetId := ctx.Param("targetId") projectId := ctx.Param("projectId") server := server.GetInstance(nil) - err := server.WorkspaceService.StopProject(ctx.Request.Context(), workspaceId, projectId) + err := server.TargetService.StopProject(ctx.Request.Context(), targetId, projectId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop project %s: %w", projectId, err)) return diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/target/target.go similarity index 53% rename from pkg/api/controllers/workspace/workspace.go rename to pkg/api/controllers/target/target.go index 7af518f924..c69e479bbf 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/target/target.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "errors" @@ -13,20 +13,20 @@ import ( "github.com/gin-gonic/gin" ) -// GetWorkspace godoc +// GetTarget godoc // -// @Tags workspace -// @Summary Get workspace info -// @Description Get workspace info +// @Tags target +// @Summary Get target info +// @Description Get target info // @Produce json -// @Param workspaceId path string true "Workspace ID or Name" +// @Param targetId path string true "Target ID or Name" // @Param verbose query bool false "Verbose" -// @Success 200 {object} WorkspaceDTO -// @Router /workspace/{workspaceId} [get] +// @Success 200 {object} TargetDTO +// @Router /target/{targetId} [get] // -// @id GetWorkspace -func GetWorkspace(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") +// @id GetTarget +func GetTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") verboseQuery := ctx.Query("verbose") verbose := false var err error @@ -41,27 +41,27 @@ func GetWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, verbose) + w, err := server.TargetService.GetTarget(ctx.Request.Context(), targetId, verbose) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get target: %w", err)) return } ctx.JSON(200, w) } -// ListWorkspaces godoc +// ListTargets godoc // -// @Tags workspace -// @Summary List workspaces -// @Description List workspaces +// @Tags target +// @Summary List targets +// @Description List targets // @Produce json -// @Success 200 {array} WorkspaceDTO -// @Router /workspace [get] +// @Success 200 {array} TargetDTO +// @Router /target [get] // @Param verbose query bool false "Verbose" // -// @id ListWorkspaces -func ListWorkspaces(ctx *gin.Context) { +// @id ListTargets +func ListTargets(ctx *gin.Context) { verboseQuery := ctx.Query("verbose") verbose := false var err error @@ -76,28 +76,28 @@ func ListWorkspaces(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), verbose) + targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), verbose) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspaces: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list targets: %w", err)) return } - ctx.JSON(200, workspaceList) + ctx.JSON(200, targetList) } -// RemoveWorkspace godoc +// RemoveTarget godoc // -// @Tags workspace -// @Summary Remove workspace -// @Description Remove workspace -// @Param workspaceId path string true "Workspace ID" +// @Tags target +// @Summary Remove target +// @Description Remove target +// @Param targetId path string true "Target ID" // @Param force query bool false "Force" // @Success 200 -// @Router /workspace/{workspaceId} [delete] +// @Router /target/{targetId} [delete] // -// @id RemoveWorkspace -func RemoveWorkspace(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") +// @id RemoveTarget +func RemoveTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") forceQuery := ctx.Query("force") var err error force := false @@ -113,13 +113,13 @@ func RemoveWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) if force { - err = server.WorkspaceService.ForceRemoveWorkspace(ctx.Request.Context(), workspaceId) + err = server.TargetService.ForceRemoveTarget(ctx.Request.Context(), targetId) } else { - err = server.WorkspaceService.RemoveWorkspace(ctx.Request.Context(), workspaceId) + err = server.TargetService.RemoveTarget(ctx.Request.Context(), targetId) } if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove workspace: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target: %w", err)) return } diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go deleted file mode 100644 index 58cd980dba..0000000000 --- a/pkg/api/controllers/workspace/create.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspace - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/gin-gonic/gin" -) - -// CreateWorkspace godoc -// -// @Tags workspace -// @Summary Create a workspace -// @Description Create a workspace -// @Param workspace body CreateWorkspaceDTO true "Create workspace" -// @Produce json -// @Success 200 {object} Workspace -// @Router /workspace [post] -// -// @id CreateWorkspace -func CreateWorkspace(ctx *gin.Context) { - var createWorkspaceReq dto.CreateWorkspaceDTO - err := ctx.BindJSON(&createWorkspaceReq) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - - w, err := server.WorkspaceService.CreateWorkspace(ctx.Request.Context(), createWorkspaceReq) - if err != nil { - if workspaces.IsWorkspaceAlreadyExists(err) { - ctx.AbortWithError(http.StatusConflict, fmt.Errorf("workspace already exists: %w", err)) - return - } - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create workspace: %w", err)) - return - } - - ctx.JSON(200, w) -} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index e33828f245..ed4fb11678 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1037,7 +1037,7 @@ const docTemplate = `{ "parameters": [ { "description": "Webhook event", - "name": "workspace", + "name": "body", "in": "body", "required": true, "schema": { @@ -1509,6 +1509,68 @@ const docTemplate = `{ } } }, + "/target": { + "get": { + "description": "List targets", + "produces": [ + "application/json" + ], + "tags": [ + "target" + ], + "summary": "List targets", + "operationId": "ListTargets", + "parameters": [ + { + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TargetDTO" + } + } + } + } + }, + "post": { + "description": "Create a target", + "produces": [ + "application/json" + ], + "tags": [ + "target" + ], + "summary": "Create a target", + "operationId": "CreateTarget", + "parameters": [ + { + "description": "Create target", + "name": "target", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateTargetDTO" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Target" + } + } + } + } + }, "/target-config": { "get": { "description": "List target configs", @@ -1605,84 +1667,22 @@ const docTemplate = `{ } } }, - "/workspace": { - "get": { - "description": "List workspaces", - "produces": [ - "application/json" - ], - "tags": [ - "workspace" - ], - "summary": "List workspaces", - "operationId": "ListWorkspaces", - "parameters": [ - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/WorkspaceDTO" - } - } - } - } - }, - "post": { - "description": "Create a workspace", - "produces": [ - "application/json" - ], - "tags": [ - "workspace" - ], - "summary": "Create a workspace", - "operationId": "CreateWorkspace", - "parameters": [ - { - "description": "Create workspace", - "name": "workspace", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/CreateWorkspaceDTO" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/Workspace" - } - } - } - } - }, - "/workspace/{workspaceId}": { + "/target/{targetId}": { "get": { - "description": "Get workspace info", + "description": "Get target info", "produces": [ "application/json" ], "tags": [ - "workspace" + "target" ], - "summary": "Get workspace info", - "operationId": "GetWorkspace", + "summary": "Get target info", + "operationId": "GetTarget", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -1697,23 +1697,23 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceDTO" + "$ref": "#/definitions/TargetDTO" } } } }, "delete": { - "description": "Remove workspace", + "description": "Remove target", "tags": [ - "workspace" + "target" ], - "summary": "Remove workspace", - "operationId": "RemoveWorkspace", + "summary": "Remove target", + "operationId": "RemoveTarget", "parameters": [ { "type": "string", - "description": "Workspace ID", - "name": "workspaceId", + "description": "Target ID", + "name": "targetId", "in": "path", "required": true }, @@ -1731,19 +1731,19 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/start": { + "/target/{targetId}/start": { "post": { - "description": "Start workspace", + "description": "Start target", "tags": [ - "workspace" + "target" ], - "summary": "Start workspace", - "operationId": "StartWorkspace", + "summary": "Start target", + "operationId": "StartTarget", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } @@ -1755,19 +1755,19 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/stop": { + "/target/{targetId}/stop": { "post": { - "description": "Stop workspace", + "description": "Stop target", "tags": [ - "workspace" + "target" ], - "summary": "Stop workspace", - "operationId": "StopWorkspace", + "summary": "Stop target", + "operationId": "StopTarget", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } @@ -1779,19 +1779,19 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/start": { + "/target/{targetId}/{projectId}/start": { "post": { "description": "Start project", "tags": [ - "workspace" + "target" ], "summary": "Start project", "operationId": "StartProject", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -1810,19 +1810,19 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/state": { + "/target/{targetId}/{projectId}/state": { "post": { "description": "Set project state", "tags": [ - "workspace" + "target" ], "summary": "Set project state", "operationId": "SetProjectState", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -1850,19 +1850,19 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/stop": { + "/target/{targetId}/{projectId}/stop": { "post": { "description": "Stop project", "tags": [ - "workspace" + "target" ], "summary": "Stop project", "operationId": "StopProject", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -3832,7 +3832,7 @@ const docTemplate = `{ } } }, - "CreateWorkspaceDTO": { + "CreateTargetDTO": { "type": "object", "required": [ "id", @@ -4663,8 +4663,8 @@ const docTemplate = `{ "name", "repository", "targetConfig", - "user", - "workspaceId" + "targetId", + "user" ], "properties": { "buildConfig": { @@ -4694,10 +4694,10 @@ const docTemplate = `{ "targetConfig": { "type": "string" }, - "user": { + "targetId": { "type": "string" }, - "workspaceId": { + "user": { "type": "string" } } @@ -4762,7 +4762,7 @@ const docTemplate = `{ "created", "isRunning", "name", - "workspaceId" + "targetId" ], "properties": { "created": { @@ -4777,7 +4777,7 @@ const docTemplate = `{ "providerMetadata": { "type": "string" }, - "workspaceId": { + "targetId": { "type": "string" } } @@ -5097,6 +5097,32 @@ const docTemplate = `{ "UpdatedButUnmerged" ] }, + "Target": { + "type": "object", + "required": [ + "id", + "name", + "projects", + "targetConfig" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "projects": { + "type": "array", + "items": { + "$ref": "#/definitions/Project" + } + }, + "targetConfig": { + "type": "string" + } + } + }, "TargetConfig": { "type": "object", "required": [ @@ -5164,33 +5190,7 @@ const docTemplate = `{ } } }, - "Workspace": { - "type": "object", - "required": [ - "id", - "name", - "projects", - "targetConfig" - ], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "projects": { - "type": "array", - "items": { - "$ref": "#/definitions/Project" - } - }, - "targetConfig": { - "type": "string" - } - } - }, - "WorkspaceDTO": { + "TargetDTO": { "type": "object", "required": [ "id", @@ -5203,7 +5203,7 @@ const docTemplate = `{ "type": "string" }, "info": { - "$ref": "#/definitions/WorkspaceInfo" + "$ref": "#/definitions/TargetInfo" }, "name": { "type": "string" @@ -5219,7 +5219,7 @@ const docTemplate = `{ } } }, - "WorkspaceInfo": { + "TargetInfo": { "type": "object", "required": [ "name", @@ -5245,12 +5245,12 @@ const docTemplate = `{ "enum": [ "client", "project", - "workspace" + "target" ], "x-enum-varnames": [ "ApiKeyTypeClient", "ApiKeyTypeProject", - "ApiKeyTypeWorkspace" + "ApiKeyTypeTarget" ] }, "build.BuildState": { diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 99c99ea854..506c4daaf6 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1034,7 +1034,7 @@ "parameters": [ { "description": "Webhook event", - "name": "workspace", + "name": "body", "in": "body", "required": true, "schema": { @@ -1506,6 +1506,68 @@ } } }, + "/target": { + "get": { + "description": "List targets", + "produces": [ + "application/json" + ], + "tags": [ + "target" + ], + "summary": "List targets", + "operationId": "ListTargets", + "parameters": [ + { + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TargetDTO" + } + } + } + } + }, + "post": { + "description": "Create a target", + "produces": [ + "application/json" + ], + "tags": [ + "target" + ], + "summary": "Create a target", + "operationId": "CreateTarget", + "parameters": [ + { + "description": "Create target", + "name": "target", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateTargetDTO" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/Target" + } + } + } + } + }, "/target-config": { "get": { "description": "List target configs", @@ -1602,84 +1664,22 @@ } } }, - "/workspace": { - "get": { - "description": "List workspaces", - "produces": [ - "application/json" - ], - "tags": [ - "workspace" - ], - "summary": "List workspaces", - "operationId": "ListWorkspaces", - "parameters": [ - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/WorkspaceDTO" - } - } - } - } - }, - "post": { - "description": "Create a workspace", - "produces": [ - "application/json" - ], - "tags": [ - "workspace" - ], - "summary": "Create a workspace", - "operationId": "CreateWorkspace", - "parameters": [ - { - "description": "Create workspace", - "name": "workspace", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/CreateWorkspaceDTO" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/Workspace" - } - } - } - } - }, - "/workspace/{workspaceId}": { + "/target/{targetId}": { "get": { - "description": "Get workspace info", + "description": "Get target info", "produces": [ "application/json" ], "tags": [ - "workspace" + "target" ], - "summary": "Get workspace info", - "operationId": "GetWorkspace", + "summary": "Get target info", + "operationId": "GetTarget", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -1694,23 +1694,23 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceDTO" + "$ref": "#/definitions/TargetDTO" } } } }, "delete": { - "description": "Remove workspace", + "description": "Remove target", "tags": [ - "workspace" + "target" ], - "summary": "Remove workspace", - "operationId": "RemoveWorkspace", + "summary": "Remove target", + "operationId": "RemoveTarget", "parameters": [ { "type": "string", - "description": "Workspace ID", - "name": "workspaceId", + "description": "Target ID", + "name": "targetId", "in": "path", "required": true }, @@ -1728,19 +1728,19 @@ } } }, - "/workspace/{workspaceId}/start": { + "/target/{targetId}/start": { "post": { - "description": "Start workspace", + "description": "Start target", "tags": [ - "workspace" + "target" ], - "summary": "Start workspace", - "operationId": "StartWorkspace", + "summary": "Start target", + "operationId": "StartTarget", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } @@ -1752,19 +1752,19 @@ } } }, - "/workspace/{workspaceId}/stop": { + "/target/{targetId}/stop": { "post": { - "description": "Stop workspace", + "description": "Stop target", "tags": [ - "workspace" + "target" ], - "summary": "Stop workspace", - "operationId": "StopWorkspace", + "summary": "Stop target", + "operationId": "StopTarget", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } @@ -1776,19 +1776,19 @@ } } }, - "/workspace/{workspaceId}/{projectId}/start": { + "/target/{targetId}/{projectId}/start": { "post": { "description": "Start project", "tags": [ - "workspace" + "target" ], "summary": "Start project", "operationId": "StartProject", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -1807,19 +1807,19 @@ } } }, - "/workspace/{workspaceId}/{projectId}/state": { + "/target/{targetId}/{projectId}/state": { "post": { "description": "Set project state", "tags": [ - "workspace" + "target" ], "summary": "Set project state", "operationId": "SetProjectState", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -1847,19 +1847,19 @@ } } }, - "/workspace/{workspaceId}/{projectId}/stop": { + "/target/{targetId}/{projectId}/stop": { "post": { "description": "Stop project", "tags": [ - "workspace" + "target" ], "summary": "Stop project", "operationId": "StopProject", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", - "name": "workspaceId", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true }, @@ -3829,7 +3829,7 @@ } } }, - "CreateWorkspaceDTO": { + "CreateTargetDTO": { "type": "object", "required": [ "id", @@ -4660,8 +4660,8 @@ "name", "repository", "targetConfig", - "user", - "workspaceId" + "targetId", + "user" ], "properties": { "buildConfig": { @@ -4691,10 +4691,10 @@ "targetConfig": { "type": "string" }, - "user": { + "targetId": { "type": "string" }, - "workspaceId": { + "user": { "type": "string" } } @@ -4759,7 +4759,7 @@ "created", "isRunning", "name", - "workspaceId" + "targetId" ], "properties": { "created": { @@ -4774,7 +4774,7 @@ "providerMetadata": { "type": "string" }, - "workspaceId": { + "targetId": { "type": "string" } } @@ -5094,6 +5094,32 @@ "UpdatedButUnmerged" ] }, + "Target": { + "type": "object", + "required": [ + "id", + "name", + "projects", + "targetConfig" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "projects": { + "type": "array", + "items": { + "$ref": "#/definitions/Project" + } + }, + "targetConfig": { + "type": "string" + } + } + }, "TargetConfig": { "type": "object", "required": [ @@ -5161,33 +5187,7 @@ } } }, - "Workspace": { - "type": "object", - "required": [ - "id", - "name", - "projects", - "targetConfig" - ], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "projects": { - "type": "array", - "items": { - "$ref": "#/definitions/Project" - } - }, - "targetConfig": { - "type": "string" - } - } - }, - "WorkspaceDTO": { + "TargetDTO": { "type": "object", "required": [ "id", @@ -5200,7 +5200,7 @@ "type": "string" }, "info": { - "$ref": "#/definitions/WorkspaceInfo" + "$ref": "#/definitions/TargetInfo" }, "name": { "type": "string" @@ -5216,7 +5216,7 @@ } } }, - "WorkspaceInfo": { + "TargetInfo": { "type": "object", "required": [ "name", @@ -5242,12 +5242,12 @@ "enum": [ "client", "project", - "workspace" + "target" ], "x-enum-varnames": [ "ApiKeyTypeClient", "ApiKeyTypeProject", - "ApiKeyTypeWorkspace" + "ApiKeyTypeTarget" ] }, "build.BuildState": { diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 17ace20c20..51f2701f9f 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -256,7 +256,7 @@ definitions: - options - providerInfo type: object - CreateWorkspaceDTO: + CreateTargetDTO: properties: id: type: string @@ -837,9 +837,9 @@ definitions: $ref: '#/definitions/ProjectState' targetConfig: type: string - user: + targetId: type: string - workspaceId: + user: type: string required: - envVars @@ -847,8 +847,8 @@ definitions: - name - repository - targetConfig + - targetId - user - - workspaceId type: object ProjectConfig: properties: @@ -897,13 +897,13 @@ definitions: type: string providerMetadata: type: string - workspaceId: + targetId: type: string required: - created - isRunning - name - - workspaceId + - targetId type: object ProjectState: properties: @@ -1123,6 +1123,24 @@ definitions: - Renamed - Copied - UpdatedButUnmerged + Target: + properties: + id: + type: string + name: + type: string + projects: + items: + $ref: '#/definitions/Project' + type: array + targetConfig: + type: string + required: + - id + - name + - projects + - targetConfig + type: object TargetConfig: properties: isDefault: @@ -1176,30 +1194,12 @@ definitions: type: $ref: '#/definitions/provider.TargetConfigPropertyType' type: object - Workspace: - properties: - id: - type: string - name: - type: string - projects: - items: - $ref: '#/definitions/Project' - type: array - targetConfig: - type: string - required: - - id - - name - - projects - - targetConfig - type: object - WorkspaceDTO: + TargetDTO: properties: id: type: string info: - $ref: '#/definitions/WorkspaceInfo' + $ref: '#/definitions/TargetInfo' name: type: string projects: @@ -1214,7 +1214,7 @@ definitions: - projects - targetConfig type: object - WorkspaceInfo: + TargetInfo: properties: name: type: string @@ -1232,12 +1232,12 @@ definitions: enum: - client - project - - workspace + - target type: string x-enum-varnames: - ApiKeyTypeClient - ApiKeyTypeProject - - ApiKeyTypeWorkspace + - ApiKeyTypeTarget build.BuildState: enum: - pending-run @@ -2130,7 +2130,7 @@ paths: parameters: - description: Webhook event in: body - name: workspace + name: body required: true schema: type: object @@ -2293,6 +2293,47 @@ paths: summary: Generate a new authentication key tags: - server + /target: + get: + description: List targets + operationId: ListTargets + parameters: + - description: Verbose + in: query + name: verbose + type: boolean + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/TargetDTO' + type: array + summary: List targets + tags: + - target + post: + description: Create a target + operationId: CreateTarget + parameters: + - description: Create target + in: body + name: target + required: true + schema: + $ref: '#/definitions/CreateTargetDTO' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/Target' + summary: Create a target + tags: + - target /target-config: get: description: List target configs @@ -2357,55 +2398,14 @@ paths: summary: Set target config to default tags: - target-config - /workspace: - get: - description: List workspaces - operationId: ListWorkspaces - parameters: - - description: Verbose - in: query - name: verbose - type: boolean - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/WorkspaceDTO' - type: array - summary: List workspaces - tags: - - workspace - post: - description: Create a workspace - operationId: CreateWorkspace - parameters: - - description: Create workspace - in: body - name: workspace - required: true - schema: - $ref: '#/definitions/CreateWorkspaceDTO' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/Workspace' - summary: Create a workspace - tags: - - workspace - /workspace/{workspaceId}: + /target/{targetId}: delete: - description: Remove workspace - operationId: RemoveWorkspace + description: Remove target + operationId: RemoveTarget parameters: - - description: Workspace ID + - description: Target ID in: path - name: workspaceId + name: targetId required: true type: string - description: Force @@ -2415,16 +2415,16 @@ paths: responses: "200": description: OK - summary: Remove workspace + summary: Remove target tags: - - workspace + - target get: - description: Get workspace info - operationId: GetWorkspace + description: Get target info + operationId: GetTarget parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true type: string - description: Verbose @@ -2437,18 +2437,18 @@ paths: "200": description: OK schema: - $ref: '#/definitions/WorkspaceDTO' - summary: Get workspace info + $ref: '#/definitions/TargetDTO' + summary: Get target info tags: - - workspace - /workspace/{workspaceId}/{projectId}/start: + - target + /target/{targetId}/{projectId}/start: post: description: Start project operationId: StartProject parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true type: string - description: Project ID @@ -2461,15 +2461,15 @@ paths: description: OK summary: Start project tags: - - workspace - /workspace/{workspaceId}/{projectId}/state: + - target + /target/{targetId}/{projectId}/state: post: description: Set project state operationId: SetProjectState parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true type: string - description: Project ID @@ -2488,15 +2488,15 @@ paths: description: OK summary: Set project state tags: - - workspace - /workspace/{workspaceId}/{projectId}/stop: + - target + /target/{targetId}/{projectId}/stop: post: description: Stop project operationId: StopProject parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true type: string - description: Project ID @@ -2509,7 +2509,39 @@ paths: description: OK summary: Stop project tags: - - workspace + - target + /target/{targetId}/start: + post: + description: Start target + operationId: StartTarget + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + type: string + responses: + "200": + description: OK + summary: Start target + tags: + - target + /target/{targetId}/stop: + post: + description: Stop target + operationId: StopTarget + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + type: string + responses: + "200": + description: OK + summary: Stop target + tags: + - target /workspace/{workspaceId}/{projectId}/toolbox/files: delete: description: Delete file inside workspace project @@ -3584,38 +3616,6 @@ paths: summary: Get project dir tags: - workspace toolbox - /workspace/{workspaceId}/start: - post: - description: Start workspace - operationId: StartWorkspace - parameters: - - description: Workspace ID or Name - in: path - name: workspaceId - required: true - type: string - responses: - "200": - description: OK - summary: Start workspace - tags: - - workspace - /workspace/{workspaceId}/stop: - post: - description: Stop workspace - operationId: StopWorkspace - parameters: - - description: Workspace ID or Name - in: path - name: workspaceId - required: true - type: string - responses: - "200": - description: OK - summary: Stop workspace - tags: - - workspace schemes: - http security: diff --git a/pkg/api/middlewares/auth.go b/pkg/api/middlewares/auth.go index 441b7144ec..ff47bd21bf 100644 --- a/pkg/api/middlewares/auth.go +++ b/pkg/api/middlewares/auth.go @@ -35,8 +35,8 @@ func AuthMiddleware() gin.HandlerFunc { apiKeyType := apikey.ApiKeyTypeClient - if server.ApiKeyService.IsWorkspaceApiKey(token) { - apiKeyType = apikey.ApiKeyTypeWorkspace + if server.ApiKeyService.IsTargetApiKey(token) { + apiKeyType = apikey.ApiKeyTypeTarget } else if server.ApiKeyService.IsProjectApiKey(token) { apiKeyType = apikey.ApiKeyTypeProject } diff --git a/pkg/api/middlewares/project.go b/pkg/api/middlewares/project.go index 5e03371218..1a347c4299 100644 --- a/pkg/api/middlewares/project.go +++ b/pkg/api/middlewares/project.go @@ -26,7 +26,7 @@ func ProjectAuthMiddleware() gin.HandlerFunc { server := server.GetInstance(nil) - if !server.ApiKeyService.IsProjectApiKey(token) && !server.ApiKeyService.IsWorkspaceApiKey(token) { + if !server.ApiKeyService.IsProjectApiKey(token) && !server.ApiKeyService.IsTargetApiKey(token) { ctx.AbortWithError(401, errors.New("unauthorized")) } diff --git a/pkg/api/middlewares/telemetry.go b/pkg/api/middlewares/telemetry.go index b987ced390..9facdd364d 100644 --- a/pkg/api/middlewares/telemetry.go +++ b/pkg/api/middlewares/telemetry.go @@ -17,9 +17,9 @@ import ( ) var ignorePaths = map[string]bool{ - "/health": true, - "/workspace/:workspaceId/:projectId/state": true, - "/server/network-key": true, + "/health": true, + "/target/:targetId/:projectId/state": true, + "/server/network-key": true, } func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.HandlerFunc { diff --git a/pkg/api/server.go b/pkg/api/server.go index eefbd397c1..9ab5a8c58c 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -45,8 +45,8 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/provider" "github.com/daytonaio/daytona/pkg/api/controllers/sample" "github.com/daytonaio/daytona/pkg/api/controllers/server" + "github.com/daytonaio/daytona/pkg/api/controllers/target" "github.com/daytonaio/daytona/pkg/api/controllers/targetconfig" - "github.com/daytonaio/daytona/pkg/api/controllers/workspace" "github.com/daytonaio/daytona/pkg/api/controllers/workspace/toolbox" "github.com/gin-gonic/gin" @@ -140,18 +140,9 @@ func (a *ApiServer) Start() error { binaryController.GET("/:version/:binaryName", binary.GetBinary) } - workspaceController := protected.Group("/workspace") + targetController := protected.Group("/target") { - workspaceController.GET("/:workspaceId", workspace.GetWorkspace) - workspaceController.GET("", workspace.ListWorkspaces) - workspaceController.POST("", workspace.CreateWorkspace) - workspaceController.POST("/:workspaceId/start", workspace.StartWorkspace) - workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) - workspaceController.DELETE("/:workspaceId", workspace.RemoveWorkspace) - workspaceController.POST("/:workspaceId/:projectId/start", workspace.StartProject) - workspaceController.POST("/:workspaceId/:projectId/stop", workspace.StopProject) - - toolboxController := workspaceController.Group("/:workspaceId/:projectId/toolbox") + toolboxController := targetController.Group("/:targetId/:projectId/toolbox") { toolboxController.GET("/project-dir", toolbox.GetProjectDir) @@ -212,6 +203,15 @@ func (a *ApiServer) Start() error { lspController.POST("/stop", toolbox.LspStop) } } + + targetController.GET("/:targetId", target.GetTarget) + targetController.GET("", target.ListTargets) + targetController.POST("", target.CreateTarget) + targetController.POST("/:targetId/start", target.StartTarget) + targetController.POST("/:targetId/stop", target.StopTarget) + targetController.DELETE("/:targetId", target.RemoveTarget) + targetController.POST("/:targetId/:projectId/start", target.StartProject) + targetController.POST("/:targetId/:projectId/stop", target.StopProject) } projectConfigController := protected.Group("/project-config") @@ -279,8 +279,8 @@ func (a *ApiServer) Start() error { logController := protected.Group("/log") { logController.GET("/server", log_controller.ReadServerLog) - logController.GET("/workspace/:workspaceId", log_controller.ReadWorkspaceLog) - logController.GET("/workspace/:workspaceId/:projectName", log_controller.ReadProjectLog) + logController.GET("/target/:targetId", log_controller.ReadTargetLog) + logController.GET("/target/:targetId/:projectName", log_controller.ReadProjectLog) logController.GET("/build/:buildId", log_controller.ReadBuildLog) } @@ -323,7 +323,7 @@ func (a *ApiServer) Start() error { projectGroup := protected.Group("/") projectGroup.Use(middlewares.ProjectAuthMiddleware()) { - projectGroup.POST(workspaceController.BasePath()+"/:workspaceId/:projectId/state", workspace.SetProjectState) + projectGroup.POST(targetController.BasePath()+"/:targetId/:projectId/state", target.SetProjectState) } a.httpServer = &http.Server{ diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 177c444d75..210b5054f6 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -128,19 +128,19 @@ Class | Method | HTTP request | Description *ServerAPI* | [**GetConfig**](docs/ServerAPI.md#getconfig) | **Get** /server/config | Get the server configuration *ServerAPI* | [**GetServerLogFiles**](docs/ServerAPI.md#getserverlogfiles) | **Get** /server/logs | List server log files *ServerAPI* | [**SetConfig**](docs/ServerAPI.md#setconfig) | **Post** /server/config | Set the server configuration +*TargetAPI* | [**CreateTarget**](docs/TargetAPI.md#createtarget) | **Post** /target | Create a target +*TargetAPI* | [**GetTarget**](docs/TargetAPI.md#gettarget) | **Get** /target/{targetId} | Get target info +*TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets +*TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target +*TargetAPI* | [**SetProjectState**](docs/TargetAPI.md#setprojectstate) | **Post** /target/{targetId}/{projectId}/state | Set project state +*TargetAPI* | [**StartProject**](docs/TargetAPI.md#startproject) | **Post** /target/{targetId}/{projectId}/start | Start project +*TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target +*TargetAPI* | [**StopProject**](docs/TargetAPI.md#stopproject) | **Post** /target/{targetId}/{projectId}/stop | Stop project +*TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs *TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configName} | Remove a target config *TargetConfigAPI* | [**SetDefaultTargetConfig**](docs/TargetConfigAPI.md#setdefaulttargetconfig) | **Patch** /target-config/{configName}/set-default | Set target config to default *TargetConfigAPI* | [**SetTargetConfig**](docs/TargetConfigAPI.md#settargetconfig) | **Put** /target-config | Set a target config -*WorkspaceAPI* | [**CreateWorkspace**](docs/WorkspaceAPI.md#createworkspace) | **Post** /workspace | Create a workspace -*WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info -*WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces -*WorkspaceAPI* | [**RemoveWorkspace**](docs/WorkspaceAPI.md#removeworkspace) | **Delete** /workspace/{workspaceId} | Remove workspace -*WorkspaceAPI* | [**SetProjectState**](docs/WorkspaceAPI.md#setprojectstate) | **Post** /workspace/{workspaceId}/{projectId}/state | Set project state -*WorkspaceAPI* | [**StartProject**](docs/WorkspaceAPI.md#startproject) | **Post** /workspace/{workspaceId}/{projectId}/start | Start project -*WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace -*WorkspaceAPI* | [**StopProject**](docs/WorkspaceAPI.md#stopproject) | **Post** /workspace/{workspaceId}/{projectId}/stop | Stop project -*WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace *WorkspaceToolboxAPI* | [**CreateSession**](docs/WorkspaceToolboxAPI.md#createsession) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/session | Create exec session *WorkspaceToolboxAPI* | [**DeleteSession**](docs/WorkspaceToolboxAPI.md#deletesession) | **Delete** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId} | Delete session *WorkspaceToolboxAPI* | [**FsCreateFolder**](docs/WorkspaceToolboxAPI.md#fscreatefolder) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/folder | Create folder @@ -199,7 +199,7 @@ Class | Method | HTTP request | Description - [CreateProjectSourceDTO](docs/CreateProjectSourceDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) - [CreateTargetConfigDTO](docs/CreateTargetConfigDTO.md) - - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) + - [CreateTargetDTO](docs/CreateTargetDTO.md) - [DevcontainerConfig](docs/DevcontainerConfig.md) - [ExecuteRequest](docs/ExecuteRequest.md) - [ExecuteResponse](docs/ExecuteResponse.md) @@ -258,11 +258,11 @@ Class | Method | HTTP request | Description - [SetProjectState](docs/SetProjectState.md) - [SigningMethod](docs/SigningMethod.md) - [Status](docs/Status.md) + - [Target](docs/Target.md) - [TargetConfig](docs/TargetConfig.md) - [TargetConfigProperty](docs/TargetConfigProperty.md) - - [Workspace](docs/Workspace.md) - - [WorkspaceDTO](docs/WorkspaceDTO.md) - - [WorkspaceInfo](docs/WorkspaceInfo.md) + - [TargetDTO](docs/TargetDTO.md) + - [TargetInfo](docs/TargetInfo.md) ## Documentation For Authorization diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 09b0faa58b..15f9fb1d26 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -749,7 +749,7 @@ paths: summary: ProcessGitEvent tags: - prebuild - x-codegen-request-body-name: workspace + x-codegen-request-body-name: body /project-config/{configName}: delete: description: Delete project config data @@ -1072,6 +1072,49 @@ paths: summary: Generate a new authentication key tags: - server + /target: + get: + description: List targets + operationId: ListTargets + parameters: + - description: Verbose + in: query + name: verbose + schema: + type: boolean + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/TargetDTO' + type: array + description: OK + summary: List targets + tags: + - target + post: + description: Create a target + operationId: CreateTarget + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/CreateTargetDTO' + description: Create target + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/Target' + description: OK + summary: Create a target + tags: + - target + x-codegen-request-body-name: target /target-config: get: description: List target configs @@ -1142,57 +1185,14 @@ paths: summary: Set target config to default tags: - target-config - /workspace: - get: - description: List workspaces - operationId: ListWorkspaces - parameters: - - description: Verbose - in: query - name: verbose - schema: - type: boolean - responses: - "200": - content: - application/json: - schema: - items: - $ref: '#/components/schemas/WorkspaceDTO' - type: array - description: OK - summary: List workspaces - tags: - - workspace - post: - description: Create a workspace - operationId: CreateWorkspace - requestBody: - content: - '*/*': - schema: - $ref: '#/components/schemas/CreateWorkspaceDTO' - description: Create workspace - required: true - responses: - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/Workspace' - description: OK - summary: Create a workspace - tags: - - workspace - x-codegen-request-body-name: workspace - /workspace/{workspaceId}: + /target/{targetId}: delete: - description: Remove workspace - operationId: RemoveWorkspace + description: Remove target + operationId: RemoveTarget parameters: - - description: Workspace ID + - description: Target ID in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1205,16 +1205,16 @@ paths: "200": content: {} description: OK - summary: Remove workspace + summary: Remove target tags: - - workspace + - target get: - description: Get workspace info - operationId: GetWorkspace + description: Get target info + operationId: GetTarget parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1228,19 +1228,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/WorkspaceDTO' + $ref: '#/components/schemas/TargetDTO' description: OK - summary: Get workspace info + summary: Get target info tags: - - workspace - /workspace/{workspaceId}/start: + - target + /target/{targetId}/start: post: - description: Start workspace - operationId: StartWorkspace + description: Start target + operationId: StartTarget parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1248,17 +1248,17 @@ paths: "200": content: {} description: OK - summary: Start workspace + summary: Start target tags: - - workspace - /workspace/{workspaceId}/stop: + - target + /target/{targetId}/stop: post: - description: Stop workspace - operationId: StopWorkspace + description: Stop target + operationId: StopTarget parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1266,17 +1266,17 @@ paths: "200": content: {} description: OK - summary: Stop workspace + summary: Stop target tags: - - workspace - /workspace/{workspaceId}/{projectId}/start: + - target + /target/{targetId}/{projectId}/start: post: description: Start project operationId: StartProject parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1292,15 +1292,15 @@ paths: description: OK summary: Start project tags: - - workspace - /workspace/{workspaceId}/{projectId}/state: + - target + /target/{targetId}/{projectId}/state: post: description: Set project state operationId: SetProjectState parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1323,16 +1323,16 @@ paths: description: OK summary: Set project state tags: - - workspace + - target x-codegen-request-body-name: setState - /workspace/{workspaceId}/{projectId}/stop: + /target/{targetId}/{projectId}/stop: post: description: Stop project operationId: StopProject parameters: - - description: Workspace ID or Name + - description: Target ID or Name in: path - name: workspaceId + name: targetId required: true schema: type: string @@ -1348,7 +1348,7 @@ paths: description: OK summary: Stop project tags: - - workspace + - target /workspace/{workspaceId}/{projectId}/toolbox/files: delete: description: Delete file inside workspace project @@ -2954,7 +2954,7 @@ components: - options - providerInfo type: object - CreateWorkspaceDTO: + CreateTargetDTO: example: targetConfig: targetConfig projects: @@ -3792,6 +3792,7 @@ components: gitProviderConfigId: gitProviderConfigId image: image targetConfig: targetConfig + targetId: targetId envVars: key: envVars name: name @@ -3824,7 +3825,6 @@ components: sha: sha url: url user: user - workspaceId: workspaceId properties: buildConfig: $ref: '#/components/schemas/BuildConfig' @@ -3844,9 +3844,9 @@ components: $ref: '#/components/schemas/ProjectState' targetConfig: type: string - user: + targetId: type: string - workspaceId: + user: type: string required: - envVars @@ -3854,8 +3854,8 @@ components: - name - repository - targetConfig + - targetId - user - - workspaceId type: object ProjectConfig: example: @@ -3929,10 +3929,10 @@ components: ProjectInfo: example: providerMetadata: providerMetadata + targetId: targetId isRunning: true created: created name: name - workspaceId: workspaceId properties: created: type: string @@ -3942,13 +3942,13 @@ components: type: string providerMetadata: type: string - workspaceId: + targetId: type: string required: - created - isRunning - name - - workspaceId + - targetId type: object ProjectState: example: @@ -4277,68 +4277,7 @@ components: - Renamed - Copied - UpdatedButUnmerged - TargetConfig: - example: - isDefault: true - name: name - options: options - providerInfo: - name: name - label: label - version: version - properties: - isDefault: - type: boolean - name: - type: string - options: - description: JSON encoded map of options - type: string - providerInfo: - $ref: '#/components/schemas/provider.ProviderInfo' - required: - - isDefault - - name - - options - - providerInfo - type: object - TargetConfigManifest: - additionalProperties: - $ref: '#/components/schemas/TargetConfigProperty' - type: object - TargetConfigProperty: - properties: - defaultValue: - description: |- - DefaultValue is converted into the appropriate type based on the Type - If the property is a FilePath, the DefaultValue is a path to a directory - type: string - description: - description: Brief description of the property - type: string - disabledPredicate: - description: |- - A regex string matched with the name of the target config to determine if the property should be disabled - If the regex matches the target config name, the property will be disabled - E.g. "^local$" will disable the property for the local target - type: string - inputMasked: - type: boolean - options: - description: Options is only used if the Type is TargetConfigPropertyTypeOption - items: - type: string - type: array - suggestions: - description: Suggestions is an optional list of auto-complete values to - assist the user while filling the field - items: - type: string - type: array - type: - $ref: '#/components/schemas/provider.TargetConfigPropertyType' - type: object - Workspace: + Target: example: targetConfig: targetConfig projects: @@ -4351,6 +4290,7 @@ components: gitProviderConfigId: gitProviderConfigId image: image targetConfig: targetConfig + targetId: targetId envVars: key: envVars name: name @@ -4383,7 +4323,6 @@ components: sha: sha url: url user: user - workspaceId: workspaceId - buildConfig: cachedBuild: image: image @@ -4393,6 +4332,7 @@ components: gitProviderConfigId: gitProviderConfigId image: image targetConfig: targetConfig + targetId: targetId envVars: key: envVars name: name @@ -4425,7 +4365,6 @@ components: sha: sha url: url user: user - workspaceId: workspaceId name: name id: id properties: @@ -4445,7 +4384,68 @@ components: - projects - targetConfig type: object - WorkspaceDTO: + TargetConfig: + example: + isDefault: true + name: name + options: options + providerInfo: + name: name + label: label + version: version + properties: + isDefault: + type: boolean + name: + type: string + options: + description: JSON encoded map of options + type: string + providerInfo: + $ref: '#/components/schemas/provider.ProviderInfo' + required: + - isDefault + - name + - options + - providerInfo + type: object + TargetConfigManifest: + additionalProperties: + $ref: '#/components/schemas/TargetConfigProperty' + type: object + TargetConfigProperty: + properties: + defaultValue: + description: |- + DefaultValue is converted into the appropriate type based on the Type + If the property is a FilePath, the DefaultValue is a path to a directory + type: string + description: + description: Brief description of the property + type: string + disabledPredicate: + description: |- + A regex string matched with the name of the target config to determine if the property should be disabled + If the regex matches the target config name, the property will be disabled + E.g. "^local$" will disable the property for the local target + type: string + inputMasked: + type: boolean + options: + description: Options is only used if the Type is TargetConfigPropertyTypeOption + items: + type: string + type: array + suggestions: + description: Suggestions is an optional list of auto-complete values to + assist the user while filling the field + items: + type: string + type: array + type: + $ref: '#/components/schemas/provider.TargetConfigPropertyType' + type: object + TargetDTO: example: targetConfig: targetConfig projects: @@ -4458,6 +4458,7 @@ components: gitProviderConfigId: gitProviderConfigId image: image targetConfig: targetConfig + targetId: targetId envVars: key: envVars name: name @@ -4490,7 +4491,6 @@ components: sha: sha url: url user: user - workspaceId: workspaceId - buildConfig: cachedBuild: image: image @@ -4500,6 +4500,7 @@ components: gitProviderConfigId: gitProviderConfigId image: image targetConfig: targetConfig + targetId: targetId envVars: key: envVars name: name @@ -4532,28 +4533,27 @@ components: sha: sha url: url user: user - workspaceId: workspaceId name: name id: id info: projects: - providerMetadata: providerMetadata + targetId: targetId isRunning: true created: created name: name - workspaceId: workspaceId - providerMetadata: providerMetadata + targetId: targetId isRunning: true created: created name: name - workspaceId: workspaceId providerMetadata: providerMetadata name: name properties: id: type: string info: - $ref: '#/components/schemas/WorkspaceInfo' + $ref: '#/components/schemas/TargetInfo' name: type: string projects: @@ -4568,19 +4568,19 @@ components: - projects - targetConfig type: object - WorkspaceInfo: + TargetInfo: example: projects: - providerMetadata: providerMetadata + targetId: targetId isRunning: true created: created name: name - workspaceId: workspaceId - providerMetadata: providerMetadata + targetId: targetId isRunning: true created: created name: name - workspaceId: workspaceId providerMetadata: providerMetadata name: name properties: @@ -4600,12 +4600,12 @@ components: enum: - client - project - - workspace + - target type: string x-enum-varnames: - ApiKeyTypeClient - ApiKeyTypeProject - - ApiKeyTypeWorkspace + - ApiKeyTypeTarget build.BuildState: enum: - pending-run diff --git a/pkg/apiclient/api_prebuild.go b/pkg/apiclient/api_prebuild.go index 388f9078cb..a6ce2bf687 100644 --- a/pkg/apiclient/api_prebuild.go +++ b/pkg/apiclient/api_prebuild.go @@ -499,12 +499,12 @@ func (a *PrebuildAPIService) ListPrebuildsForProjectConfigExecute(r ApiListPrebu type ApiProcessGitEventRequest struct { ctx context.Context ApiService *PrebuildAPIService - workspace *map[string]interface{} + body *map[string]interface{} } // Webhook event -func (r ApiProcessGitEventRequest) Workspace(workspace map[string]interface{}) ApiProcessGitEventRequest { - r.workspace = &workspace +func (r ApiProcessGitEventRequest) Body(body map[string]interface{}) ApiProcessGitEventRequest { + r.body = &body return r } @@ -545,8 +545,8 @@ func (a *PrebuildAPIService) ProcessGitEventExecute(r ApiProcessGitEventRequest) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.workspace == nil { - return nil, reportError("workspace is required and must be specified") + if r.body == nil { + return nil, reportError("body is required and must be specified") } // to determine the Content-Type header @@ -567,7 +567,7 @@ func (a *PrebuildAPIService) ProcessGitEventExecute(r ApiProcessGitEventRequest) localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.workspace + localVarPostBody = r.body if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_target.go similarity index 75% rename from pkg/apiclient/api_workspace.go rename to pkg/apiclient/api_target.go index a202e49d42..4472aedc6b 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_target.go @@ -19,35 +19,35 @@ import ( "strings" ) -// WorkspaceAPIService WorkspaceAPI service -type WorkspaceAPIService service +// TargetAPIService TargetAPI service +type TargetAPIService service -type ApiCreateWorkspaceRequest struct { +type ApiCreateTargetRequest struct { ctx context.Context - ApiService *WorkspaceAPIService - workspace *CreateWorkspaceDTO + ApiService *TargetAPIService + target *CreateTargetDTO } -// Create workspace -func (r ApiCreateWorkspaceRequest) Workspace(workspace CreateWorkspaceDTO) ApiCreateWorkspaceRequest { - r.workspace = &workspace +// Create target +func (r ApiCreateTargetRequest) Target(target CreateTargetDTO) ApiCreateTargetRequest { + r.target = &target return r } -func (r ApiCreateWorkspaceRequest) Execute() (*Workspace, *http.Response, error) { - return r.ApiService.CreateWorkspaceExecute(r) +func (r ApiCreateTargetRequest) Execute() (*Target, *http.Response, error) { + return r.ApiService.CreateTargetExecute(r) } /* -CreateWorkspace Create a workspace +CreateTarget Create a target -Create a workspace +Create a target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiCreateWorkspaceRequest + @return ApiCreateTargetRequest */ -func (a *WorkspaceAPIService) CreateWorkspace(ctx context.Context) ApiCreateWorkspaceRequest { - return ApiCreateWorkspaceRequest{ +func (a *TargetAPIService) CreateTarget(ctx context.Context) ApiCreateTargetRequest { + return ApiCreateTargetRequest{ ApiService: a, ctx: ctx, } @@ -55,27 +55,27 @@ func (a *WorkspaceAPIService) CreateWorkspace(ctx context.Context) ApiCreateWork // Execute executes the request // -// @return Workspace -func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest) (*Workspace, *http.Response, error) { +// @return Target +func (a *TargetAPIService) CreateTargetExecute(r ApiCreateTargetRequest) (*Target, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile - localVarReturnValue *Workspace + localVarReturnValue *Target ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.CreateWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.CreateTarget") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace" + localVarPath := localBasePath + "/target" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.workspace == nil { - return localVarReturnValue, nil, reportError("workspace is required and must be specified") + if r.target == nil { + return localVarReturnValue, nil, reportError("target is required and must be specified") } // to determine the Content-Type header @@ -96,7 +96,7 @@ func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.workspace + localVarPostBody = r.target if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -148,58 +148,58 @@ func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetWorkspaceRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - verbose *bool +type ApiGetTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + verbose *bool } // Verbose -func (r ApiGetWorkspaceRequest) Verbose(verbose bool) ApiGetWorkspaceRequest { +func (r ApiGetTargetRequest) Verbose(verbose bool) ApiGetTargetRequest { r.verbose = &verbose return r } -func (r ApiGetWorkspaceRequest) Execute() (*WorkspaceDTO, *http.Response, error) { - return r.ApiService.GetWorkspaceExecute(r) +func (r ApiGetTargetRequest) Execute() (*TargetDTO, *http.Response, error) { + return r.ApiService.GetTargetExecute(r) } /* -GetWorkspace Get workspace info +GetTarget Get target info -Get workspace info +Get target info @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name - @return ApiGetWorkspaceRequest + @param targetId Target ID or Name + @return ApiGetTargetRequest */ -func (a *WorkspaceAPIService) GetWorkspace(ctx context.Context, workspaceId string) ApiGetWorkspaceRequest { - return ApiGetWorkspaceRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, +func (a *TargetAPIService) GetTarget(ctx context.Context, targetId string) ApiGetTargetRequest { + return ApiGetTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, } } // Execute executes the request // -// @return WorkspaceDTO -func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*WorkspaceDTO, *http.Response, error) { +// @return TargetDTO +func (a *TargetAPIService) GetTargetExecute(r ApiGetTargetRequest) (*TargetDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *WorkspaceDTO + localVarReturnValue *TargetDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.GetWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.GetTarget") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -276,32 +276,32 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListWorkspacesRequest struct { +type ApiListTargetsRequest struct { ctx context.Context - ApiService *WorkspaceAPIService + ApiService *TargetAPIService verbose *bool } // Verbose -func (r ApiListWorkspacesRequest) Verbose(verbose bool) ApiListWorkspacesRequest { +func (r ApiListTargetsRequest) Verbose(verbose bool) ApiListTargetsRequest { r.verbose = &verbose return r } -func (r ApiListWorkspacesRequest) Execute() ([]WorkspaceDTO, *http.Response, error) { - return r.ApiService.ListWorkspacesExecute(r) +func (r ApiListTargetsRequest) Execute() ([]TargetDTO, *http.Response, error) { + return r.ApiService.ListTargetsExecute(r) } /* -ListWorkspaces List workspaces +ListTargets List targets -List workspaces +List targets @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListWorkspacesRequest + @return ApiListTargetsRequest */ -func (a *WorkspaceAPIService) ListWorkspaces(ctx context.Context) ApiListWorkspacesRequest { - return ApiListWorkspacesRequest{ +func (a *TargetAPIService) ListTargets(ctx context.Context) ApiListTargetsRequest { + return ApiListTargetsRequest{ ApiService: a, ctx: ctx, } @@ -309,21 +309,21 @@ func (a *WorkspaceAPIService) ListWorkspaces(ctx context.Context) ApiListWorkspa // Execute executes the request // -// @return []WorkspaceDTO -func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) ([]WorkspaceDTO, *http.Response, error) { +// @return []TargetDTO +func (a *TargetAPIService) ListTargetsExecute(r ApiListTargetsRequest) ([]TargetDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []WorkspaceDTO + localVarReturnValue []TargetDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.ListWorkspaces") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.ListTargets") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace" + localVarPath := localBasePath + "/target" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -400,55 +400,55 @@ func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveWorkspaceRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - force *bool +type ApiRemoveTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + force *bool } // Force -func (r ApiRemoveWorkspaceRequest) Force(force bool) ApiRemoveWorkspaceRequest { +func (r ApiRemoveTargetRequest) Force(force bool) ApiRemoveTargetRequest { r.force = &force return r } -func (r ApiRemoveWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveWorkspaceExecute(r) +func (r ApiRemoveTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.RemoveTargetExecute(r) } /* -RemoveWorkspace Remove workspace +RemoveTarget Remove target -Remove workspace +Remove target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID - @return ApiRemoveWorkspaceRequest + @param targetId Target ID + @return ApiRemoveTargetRequest */ -func (a *WorkspaceAPIService) RemoveWorkspace(ctx context.Context, workspaceId string) ApiRemoveWorkspaceRequest { - return ApiRemoveWorkspaceRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, +func (a *TargetAPIService) RemoveTarget(ctx context.Context, targetId string) ApiRemoveTargetRequest { + return ApiRemoveTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, } } // Execute executes the request -func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest) (*http.Response, error) { +func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodDelete localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.RemoveWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.RemoveTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -517,11 +517,11 @@ func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest } type ApiSetProjectStateRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - projectId string - setState *SetProjectState + ctx context.Context + ApiService *TargetAPIService + targetId string + projectId string + setState *SetProjectState } // Set State @@ -540,34 +540,34 @@ SetProjectState Set project state Set project state @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name + @param targetId Target ID or Name @param projectId Project ID @return ApiSetProjectStateRequest */ -func (a *WorkspaceAPIService) SetProjectState(ctx context.Context, workspaceId string, projectId string) ApiSetProjectStateRequest { +func (a *TargetAPIService) SetProjectState(ctx context.Context, targetId string, projectId string) ApiSetProjectStateRequest { return ApiSetProjectStateRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, - projectId: projectId, + ApiService: a, + ctx: ctx, + targetId: targetId, + projectId: projectId, } } // Execute executes the request -func (a *WorkspaceAPIService) SetProjectStateExecute(r ApiSetProjectStateRequest) (*http.Response, error) { +func (a *TargetAPIService) SetProjectStateExecute(r ApiSetProjectStateRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.SetProjectState") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetProjectState") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/state" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}/{projectId}/state" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) @@ -639,10 +639,10 @@ func (a *WorkspaceAPIService) SetProjectStateExecute(r ApiSetProjectStateRequest } type ApiStartProjectRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - projectId string + ctx context.Context + ApiService *TargetAPIService + targetId string + projectId string } func (r ApiStartProjectRequest) Execute() (*http.Response, error) { @@ -655,34 +655,34 @@ StartProject Start project Start project @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name + @param targetId Target ID or Name @param projectId Project ID @return ApiStartProjectRequest */ -func (a *WorkspaceAPIService) StartProject(ctx context.Context, workspaceId string, projectId string) ApiStartProjectRequest { +func (a *TargetAPIService) StartProject(ctx context.Context, targetId string, projectId string) ApiStartProjectRequest { return ApiStartProjectRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, - projectId: projectId, + ApiService: a, + ctx: ctx, + targetId: targetId, + projectId: projectId, } } // Execute executes the request -func (a *WorkspaceAPIService) StartProjectExecute(r ApiStartProjectRequest) (*http.Response, error) { +func (a *TargetAPIService) StartProjectExecute(r ApiStartProjectRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StartProject") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartProject") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/start" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}/{projectId}/start" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) @@ -748,48 +748,48 @@ func (a *WorkspaceAPIService) StartProjectExecute(r ApiStartProjectRequest) (*ht return localVarHTTPResponse, nil } -type ApiStartWorkspaceRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string +type ApiStartTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string } -func (r ApiStartWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.StartWorkspaceExecute(r) +func (r ApiStartTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.StartTargetExecute(r) } /* -StartWorkspace Start workspace +StartTarget Start target -Start workspace +Start target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name - @return ApiStartWorkspaceRequest + @param targetId Target ID or Name + @return ApiStartTargetRequest */ -func (a *WorkspaceAPIService) StartWorkspace(ctx context.Context, workspaceId string) ApiStartWorkspaceRequest { - return ApiStartWorkspaceRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, +func (a *TargetAPIService) StartTarget(ctx context.Context, targetId string) ApiStartTargetRequest { + return ApiStartTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, } } // Execute executes the request -func (a *WorkspaceAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) (*http.Response, error) { +func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StartWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/start" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}/start" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -855,10 +855,10 @@ func (a *WorkspaceAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) } type ApiStopProjectRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - projectId string + ctx context.Context + ApiService *TargetAPIService + targetId string + projectId string } func (r ApiStopProjectRequest) Execute() (*http.Response, error) { @@ -871,34 +871,34 @@ StopProject Stop project Stop project @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name + @param targetId Target ID or Name @param projectId Project ID @return ApiStopProjectRequest */ -func (a *WorkspaceAPIService) StopProject(ctx context.Context, workspaceId string, projectId string) ApiStopProjectRequest { +func (a *TargetAPIService) StopProject(ctx context.Context, targetId string, projectId string) ApiStopProjectRequest { return ApiStopProjectRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, - projectId: projectId, + ApiService: a, + ctx: ctx, + targetId: targetId, + projectId: projectId, } } // Execute executes the request -func (a *WorkspaceAPIService) StopProjectExecute(r ApiStopProjectRequest) (*http.Response, error) { +func (a *TargetAPIService) StopProjectExecute(r ApiStopProjectRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StopProject") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopProject") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/stop" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}/{projectId}/stop" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) @@ -964,48 +964,48 @@ func (a *WorkspaceAPIService) StopProjectExecute(r ApiStopProjectRequest) (*http return localVarHTTPResponse, nil } -type ApiStopWorkspaceRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string +type ApiStopTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string } -func (r ApiStopWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.StopWorkspaceExecute(r) +func (r ApiStopTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.StopTargetExecute(r) } /* -StopWorkspace Stop workspace +StopTarget Stop target -Stop workspace +Stop target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name - @return ApiStopWorkspaceRequest + @param targetId Target ID or Name + @return ApiStopTargetRequest */ -func (a *WorkspaceAPIService) StopWorkspace(ctx context.Context, workspaceId string) ApiStopWorkspaceRequest { - return ApiStopWorkspaceRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, +func (a *TargetAPIService) StopTarget(ctx context.Context, targetId string) ApiStopTargetRequest { + return ApiStopTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, } } // Execute executes the request -func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (*http.Response, error) { +func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StopWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/stop" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/target/{targetId}/stop" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index 33941bdb65..b709600808 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -70,9 +70,9 @@ type APIClient struct { ServerAPI *ServerAPIService - TargetConfigAPI *TargetConfigAPIService + TargetAPI *TargetAPIService - WorkspaceAPI *WorkspaceAPIService + TargetConfigAPI *TargetConfigAPIService WorkspaceToolboxAPI *WorkspaceToolboxAPIService } @@ -104,8 +104,8 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.ProviderAPI = (*ProviderAPIService)(&c.common) c.SampleAPI = (*SampleAPIService)(&c.common) c.ServerAPI = (*ServerAPIService)(&c.common) + c.TargetAPI = (*TargetAPIService)(&c.common) c.TargetConfigAPI = (*TargetConfigAPIService)(&c.common) - c.WorkspaceAPI = (*WorkspaceAPIService)(&c.common) c.WorkspaceToolboxAPI = (*WorkspaceToolboxAPIService)(&c.common) return c diff --git a/pkg/apiclient/docs/ApikeyApiKeyType.md b/pkg/apiclient/docs/ApikeyApiKeyType.md index 7977b92f28..57fc1a3a8f 100644 --- a/pkg/apiclient/docs/ApikeyApiKeyType.md +++ b/pkg/apiclient/docs/ApikeyApiKeyType.md @@ -7,7 +7,7 @@ * `ApiKeyTypeProject` (value: `"project"`) -* `ApiKeyTypeWorkspace` (value: `"workspace"`) +* `ApiKeyTypeTarget` (value: `"target"`) [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/CreateWorkspaceDTO.md b/pkg/apiclient/docs/CreateTargetDTO.md similarity index 64% rename from pkg/apiclient/docs/CreateWorkspaceDTO.md rename to pkg/apiclient/docs/CreateTargetDTO.md index 9570821789..7b53c79eb2 100644 --- a/pkg/apiclient/docs/CreateWorkspaceDTO.md +++ b/pkg/apiclient/docs/CreateTargetDTO.md @@ -1,4 +1,4 @@ -# CreateWorkspaceDTO +# CreateTargetDTO ## Properties @@ -11,99 +11,99 @@ Name | Type | Description | Notes ## Methods -### NewCreateWorkspaceDTO +### NewCreateTargetDTO -`func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, targetConfig string, ) *CreateWorkspaceDTO` +`func NewCreateTargetDTO(id string, name string, projects []CreateProjectDTO, targetConfig string, ) *CreateTargetDTO` -NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object +NewCreateTargetDTO instantiates a new CreateTargetDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateWorkspaceDTOWithDefaults +### NewCreateTargetDTOWithDefaults -`func NewCreateWorkspaceDTOWithDefaults() *CreateWorkspaceDTO` +`func NewCreateTargetDTOWithDefaults() *CreateTargetDTO` -NewCreateWorkspaceDTOWithDefaults instantiates a new CreateWorkspaceDTO object +NewCreateTargetDTOWithDefaults instantiates a new CreateTargetDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetId -`func (o *CreateWorkspaceDTO) GetId() string` +`func (o *CreateTargetDTO) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *CreateWorkspaceDTO) GetIdOk() (*string, bool)` +`func (o *CreateTargetDTO) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *CreateWorkspaceDTO) SetId(v string)` +`func (o *CreateTargetDTO) SetId(v string)` SetId sets Id field to given value. ### GetName -`func (o *CreateWorkspaceDTO) GetName() string` +`func (o *CreateTargetDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *CreateWorkspaceDTO) GetNameOk() (*string, bool)` +`func (o *CreateTargetDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *CreateWorkspaceDTO) SetName(v string)` +`func (o *CreateTargetDTO) SetName(v string)` SetName sets Name field to given value. ### GetProjects -`func (o *CreateWorkspaceDTO) GetProjects() []CreateProjectDTO` +`func (o *CreateTargetDTO) GetProjects() []CreateProjectDTO` GetProjects returns the Projects field if non-nil, zero value otherwise. ### GetProjectsOk -`func (o *CreateWorkspaceDTO) GetProjectsOk() (*[]CreateProjectDTO, bool)` +`func (o *CreateTargetDTO) GetProjectsOk() (*[]CreateProjectDTO, bool)` GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProjects -`func (o *CreateWorkspaceDTO) SetProjects(v []CreateProjectDTO)` +`func (o *CreateTargetDTO) SetProjects(v []CreateProjectDTO)` SetProjects sets Projects field to given value. ### GetTargetConfig -`func (o *CreateWorkspaceDTO) GetTargetConfig() string` +`func (o *CreateTargetDTO) GetTargetConfig() string` GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. ### GetTargetConfigOk -`func (o *CreateWorkspaceDTO) GetTargetConfigOk() (*string, bool)` +`func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool)` GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetTargetConfig -`func (o *CreateWorkspaceDTO) SetTargetConfig(v string)` +`func (o *CreateTargetDTO) SetTargetConfig(v string)` SetTargetConfig sets TargetConfig field to given value. diff --git a/pkg/apiclient/docs/PrebuildAPI.md b/pkg/apiclient/docs/PrebuildAPI.md index a1dc453e86..5c98f91247 100644 --- a/pkg/apiclient/docs/PrebuildAPI.md +++ b/pkg/apiclient/docs/PrebuildAPI.md @@ -292,7 +292,7 @@ Name | Type | Description | Notes ## ProcessGitEvent -> ProcessGitEvent(ctx).Workspace(workspace).Execute() +> ProcessGitEvent(ctx).Body(body).Execute() ProcessGitEvent @@ -311,11 +311,11 @@ import ( ) func main() { - workspace := map[string]interface{}{ ... } // map[string]interface{} | Webhook event + body := map[string]interface{}{ ... } // map[string]interface{} | Webhook event configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.PrebuildAPI.ProcessGitEvent(context.Background()).Workspace(workspace).Execute() + r, err := apiClient.PrebuildAPI.ProcessGitEvent(context.Background()).Body(body).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.ProcessGitEvent``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -334,7 +334,7 @@ Other parameters are passed through a pointer to a apiProcessGitEventRequest str Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **workspace** | **map[string]interface{}** | Webhook event | + **body** | **map[string]interface{}** | Webhook event | ### Return type diff --git a/pkg/apiclient/docs/Project.md b/pkg/apiclient/docs/Project.md index 452cf655a8..b4af3ca024 100644 --- a/pkg/apiclient/docs/Project.md +++ b/pkg/apiclient/docs/Project.md @@ -12,14 +12,14 @@ Name | Type | Description | Notes **Repository** | [**GitRepository**](GitRepository.md) | | **State** | Pointer to [**ProjectState**](ProjectState.md) | | [optional] **TargetConfig** | **string** | | +**TargetId** | **string** | | **User** | **string** | | -**WorkspaceId** | **string** | | ## Methods ### NewProject -`func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, user string, workspaceId string, ) *Project` +`func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string, ) *Project` NewProject instantiates a new Project object This constructor will assign default values to properties that have it defined, @@ -209,44 +209,44 @@ and a boolean to check if the value has been set. SetTargetConfig sets TargetConfig field to given value. -### GetUser +### GetTargetId -`func (o *Project) GetUser() string` +`func (o *Project) GetTargetId() string` -GetUser returns the User field if non-nil, zero value otherwise. +GetTargetId returns the TargetId field if non-nil, zero value otherwise. -### GetUserOk +### GetTargetIdOk -`func (o *Project) GetUserOk() (*string, bool)` +`func (o *Project) GetTargetIdOk() (*string, bool)` -GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetUser +### SetTargetId -`func (o *Project) SetUser(v string)` +`func (o *Project) SetTargetId(v string)` -SetUser sets User field to given value. +SetTargetId sets TargetId field to given value. -### GetWorkspaceId +### GetUser -`func (o *Project) GetWorkspaceId() string` +`func (o *Project) GetUser() string` -GetWorkspaceId returns the WorkspaceId field if non-nil, zero value otherwise. +GetUser returns the User field if non-nil, zero value otherwise. -### GetWorkspaceIdOk +### GetUserOk -`func (o *Project) GetWorkspaceIdOk() (*string, bool)` +`func (o *Project) GetUserOk() (*string, bool)` -GetWorkspaceIdOk returns a tuple with the WorkspaceId field if it's non-nil, zero value otherwise +GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetWorkspaceId +### SetUser -`func (o *Project) SetWorkspaceId(v string)` +`func (o *Project) SetUser(v string)` -SetWorkspaceId sets WorkspaceId field to given value. +SetUser sets User field to given value. diff --git a/pkg/apiclient/docs/ProjectInfo.md b/pkg/apiclient/docs/ProjectInfo.md index 78cd60e751..7e37997184 100644 --- a/pkg/apiclient/docs/ProjectInfo.md +++ b/pkg/apiclient/docs/ProjectInfo.md @@ -8,13 +8,13 @@ Name | Type | Description | Notes **IsRunning** | **bool** | | **Name** | **string** | | **ProviderMetadata** | Pointer to **string** | | [optional] -**WorkspaceId** | **string** | | +**TargetId** | **string** | | ## Methods ### NewProjectInfo -`func NewProjectInfo(created string, isRunning bool, name string, workspaceId string, ) *ProjectInfo` +`func NewProjectInfo(created string, isRunning bool, name string, targetId string, ) *ProjectInfo` NewProjectInfo instantiates a new ProjectInfo object This constructor will assign default values to properties that have it defined, @@ -114,24 +114,24 @@ SetProviderMetadata sets ProviderMetadata field to given value. HasProviderMetadata returns a boolean if a field has been set. -### GetWorkspaceId +### GetTargetId -`func (o *ProjectInfo) GetWorkspaceId() string` +`func (o *ProjectInfo) GetTargetId() string` -GetWorkspaceId returns the WorkspaceId field if non-nil, zero value otherwise. +GetTargetId returns the TargetId field if non-nil, zero value otherwise. -### GetWorkspaceIdOk +### GetTargetIdOk -`func (o *ProjectInfo) GetWorkspaceIdOk() (*string, bool)` +`func (o *ProjectInfo) GetTargetIdOk() (*string, bool)` -GetWorkspaceIdOk returns a tuple with the WorkspaceId field if it's non-nil, zero value otherwise +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetWorkspaceId +### SetTargetId -`func (o *ProjectInfo) SetWorkspaceId(v string)` +`func (o *ProjectInfo) SetTargetId(v string)` -SetWorkspaceId sets WorkspaceId field to given value. +SetTargetId sets TargetId field to given value. diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/Target.md similarity index 70% rename from pkg/apiclient/docs/Workspace.md rename to pkg/apiclient/docs/Target.md index 32130e5b50..b73a3981f8 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/Target.md @@ -1,4 +1,4 @@ -# Workspace +# Target ## Properties @@ -11,99 +11,99 @@ Name | Type | Description | Notes ## Methods -### NewWorkspace +### NewTarget -`func NewWorkspace(id string, name string, projects []Project, targetConfig string, ) *Workspace` +`func NewTarget(id string, name string, projects []Project, targetConfig string, ) *Target` -NewWorkspace instantiates a new Workspace object +NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceWithDefaults +### NewTargetWithDefaults -`func NewWorkspaceWithDefaults() *Workspace` +`func NewTargetWithDefaults() *Target` -NewWorkspaceWithDefaults instantiates a new Workspace object +NewTargetWithDefaults instantiates a new Target object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetId -`func (o *Workspace) GetId() string` +`func (o *Target) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *Workspace) GetIdOk() (*string, bool)` +`func (o *Target) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *Workspace) SetId(v string)` +`func (o *Target) SetId(v string)` SetId sets Id field to given value. ### GetName -`func (o *Workspace) GetName() string` +`func (o *Target) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *Workspace) GetNameOk() (*string, bool)` +`func (o *Target) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *Workspace) SetName(v string)` +`func (o *Target) SetName(v string)` SetName sets Name field to given value. ### GetProjects -`func (o *Workspace) GetProjects() []Project` +`func (o *Target) GetProjects() []Project` GetProjects returns the Projects field if non-nil, zero value otherwise. ### GetProjectsOk -`func (o *Workspace) GetProjectsOk() (*[]Project, bool)` +`func (o *Target) GetProjectsOk() (*[]Project, bool)` GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProjects -`func (o *Workspace) SetProjects(v []Project)` +`func (o *Target) SetProjects(v []Project)` SetProjects sets Projects field to given value. ### GetTargetConfig -`func (o *Workspace) GetTargetConfig() string` +`func (o *Target) GetTargetConfig() string` GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. ### GetTargetConfigOk -`func (o *Workspace) GetTargetConfigOk() (*string, bool)` +`func (o *Target) GetTargetConfigOk() (*string, bool)` GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetTargetConfig -`func (o *Workspace) SetTargetConfig(v string)` +`func (o *Target) SetTargetConfig(v string)` SetTargetConfig sets TargetConfig field to given value. diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/TargetAPI.md similarity index 62% rename from pkg/apiclient/docs/WorkspaceAPI.md rename to pkg/apiclient/docs/TargetAPI.md index c523661f5a..60376ebf4d 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -1,26 +1,26 @@ -# \WorkspaceAPI +# \TargetAPI All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**CreateWorkspace**](WorkspaceAPI.md#CreateWorkspace) | **Post** /workspace | Create a workspace -[**GetWorkspace**](WorkspaceAPI.md#GetWorkspace) | **Get** /workspace/{workspaceId} | Get workspace info -[**ListWorkspaces**](WorkspaceAPI.md#ListWorkspaces) | **Get** /workspace | List workspaces -[**RemoveWorkspace**](WorkspaceAPI.md#RemoveWorkspace) | **Delete** /workspace/{workspaceId} | Remove workspace -[**SetProjectState**](WorkspaceAPI.md#SetProjectState) | **Post** /workspace/{workspaceId}/{projectId}/state | Set project state -[**StartProject**](WorkspaceAPI.md#StartProject) | **Post** /workspace/{workspaceId}/{projectId}/start | Start project -[**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace -[**StopProject**](WorkspaceAPI.md#StopProject) | **Post** /workspace/{workspaceId}/{projectId}/stop | Stop project -[**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +[**CreateTarget**](TargetAPI.md#CreateTarget) | **Post** /target | Create a target +[**GetTarget**](TargetAPI.md#GetTarget) | **Get** /target/{targetId} | Get target info +[**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets +[**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target +[**SetProjectState**](TargetAPI.md#SetProjectState) | **Post** /target/{targetId}/{projectId}/state | Set project state +[**StartProject**](TargetAPI.md#StartProject) | **Post** /target/{targetId}/{projectId}/start | Start project +[**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target +[**StopProject**](TargetAPI.md#StopProject) | **Post** /target/{targetId}/{projectId}/stop | Stop project +[**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target -## CreateWorkspace +## CreateTarget -> Workspace CreateWorkspace(ctx).Workspace(workspace).Execute() +> Target CreateTarget(ctx).Target(target).Execute() -Create a workspace +Create a target @@ -37,17 +37,17 @@ import ( ) func main() { - workspace := *openapiclient.NewCreateWorkspaceDTO("Id_example", "Name_example", []openapiclient.CreateProjectDTO{*openapiclient.NewCreateProjectDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateProjectSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}, "TargetConfig_example") // CreateWorkspaceDTO | Create workspace + target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", []openapiclient.CreateProjectDTO{*openapiclient.NewCreateProjectDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateProjectSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}, "TargetConfig_example") // CreateTargetDTO | Create target configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.CreateWorkspace(context.Background()).Workspace(workspace).Execute() + resp, r, err := apiClient.TargetAPI.CreateTarget(context.Background()).Target(target).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.CreateWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.CreateTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `CreateWorkspace`: Workspace - fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.CreateWorkspace`: %v\n", resp) + // response from `CreateTarget`: Target + fmt.Fprintf(os.Stdout, "Response from `TargetAPI.CreateTarget`: %v\n", resp) } ``` @@ -57,16 +57,16 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiCreateWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiCreateTargetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **workspace** | [**CreateWorkspaceDTO**](CreateWorkspaceDTO.md) | Create workspace | + **target** | [**CreateTargetDTO**](CreateTargetDTO.md) | Create target | ### Return type -[**Workspace**](Workspace.md) +[**Target**](Target.md) ### Authorization @@ -82,11 +82,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetWorkspace +## GetTarget -> WorkspaceDTO GetWorkspace(ctx, workspaceId).Verbose(verbose).Execute() +> TargetDTO GetTarget(ctx, targetId).Verbose(verbose).Execute() -Get workspace info +Get target info @@ -103,18 +103,18 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + targetId := "targetId_example" // string | Target ID or Name verbose := true // bool | Verbose (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.GetWorkspace(context.Background(), workspaceId).Verbose(verbose).Execute() + resp, r, err := apiClient.TargetAPI.GetTarget(context.Background(), targetId).Verbose(verbose).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.GetWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.GetTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetWorkspace`: WorkspaceDTO - fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.GetWorkspace`: %v\n", resp) + // response from `GetTarget`: TargetDTO + fmt.Fprintf(os.Stdout, "Response from `TargetAPI.GetTarget`: %v\n", resp) } ``` @@ -124,11 +124,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**targetId** | **string** | Target ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiGetWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetTargetRequest struct via the builder pattern Name | Type | Description | Notes @@ -138,7 +138,7 @@ Name | Type | Description | Notes ### Return type -[**WorkspaceDTO**](WorkspaceDTO.md) +[**TargetDTO**](TargetDTO.md) ### Authorization @@ -154,11 +154,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## ListWorkspaces +## ListTargets -> []WorkspaceDTO ListWorkspaces(ctx).Verbose(verbose).Execute() +> []TargetDTO ListTargets(ctx).Verbose(verbose).Execute() -List workspaces +List targets @@ -179,13 +179,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Verbose(verbose).Execute() + resp, r, err := apiClient.TargetAPI.ListTargets(context.Background()).Verbose(verbose).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.ListWorkspaces``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.ListTargets``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListWorkspaces`: []WorkspaceDTO - fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.ListWorkspaces`: %v\n", resp) + // response from `ListTargets`: []TargetDTO + fmt.Fprintf(os.Stdout, "Response from `TargetAPI.ListTargets`: %v\n", resp) } ``` @@ -195,7 +195,7 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiListWorkspacesRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListTargetsRequest struct via the builder pattern Name | Type | Description | Notes @@ -204,7 +204,7 @@ Name | Type | Description | Notes ### Return type -[**[]WorkspaceDTO**](WorkspaceDTO.md) +[**[]TargetDTO**](TargetDTO.md) ### Authorization @@ -220,11 +220,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## RemoveWorkspace +## RemoveTarget -> RemoveWorkspace(ctx, workspaceId).Force(force).Execute() +> RemoveTarget(ctx, targetId).Force(force).Execute() -Remove workspace +Remove target @@ -241,14 +241,14 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID + targetId := "targetId_example" // string | Target ID force := true // bool | Force (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.RemoveWorkspace(context.Background(), workspaceId).Force(force).Execute() + r, err := apiClient.TargetAPI.RemoveTarget(context.Background(), targetId).Force(force).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.RemoveWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.RemoveTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -260,11 +260,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID | +**targetId** | **string** | Target ID | ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiRemoveTargetRequest struct via the builder pattern Name | Type | Description | Notes @@ -292,7 +292,7 @@ Name | Type | Description | Notes ## SetProjectState -> SetProjectState(ctx, workspaceId, projectId).SetState(setState).Execute() +> SetProjectState(ctx, targetId, projectId).SetState(setState).Execute() Set project state @@ -311,15 +311,15 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + targetId := "targetId_example" // string | Target ID or Name projectId := "projectId_example" // string | Project ID setState := *openapiclient.NewSetProjectState(int32(123)) // SetProjectState | Set State configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.SetProjectState(context.Background(), workspaceId, projectId).SetState(setState).Execute() + r, err := apiClient.TargetAPI.SetProjectState(context.Background(), targetId, projectId).SetState(setState).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.SetProjectState``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetProjectState``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -331,7 +331,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**targetId** | **string** | Target ID or Name | **projectId** | **string** | Project ID | ### Other Parameters @@ -365,7 +365,7 @@ Name | Type | Description | Notes ## StartProject -> StartProject(ctx, workspaceId, projectId).Execute() +> StartProject(ctx, targetId, projectId).Execute() Start project @@ -384,14 +384,14 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + targetId := "targetId_example" // string | Target ID or Name projectId := "projectId_example" // string | Project ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.StartProject(context.Background(), workspaceId, projectId).Execute() + r, err := apiClient.TargetAPI.StartProject(context.Background(), targetId, projectId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StartProject``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartProject``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -403,7 +403,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**targetId** | **string** | Target ID or Name | **projectId** | **string** | Project ID | ### Other Parameters @@ -434,11 +434,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StartWorkspace +## StartTarget -> StartWorkspace(ctx, workspaceId).Execute() +> StartTarget(ctx, targetId).Execute() -Start workspace +Start target @@ -455,13 +455,13 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + targetId := "targetId_example" // string | Target ID or Name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.StartWorkspace(context.Background(), workspaceId).Execute() + r, err := apiClient.TargetAPI.StartTarget(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StartWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -473,11 +473,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**targetId** | **string** | Target ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiStartWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStartTargetRequest struct via the builder pattern Name | Type | Description | Notes @@ -504,7 +504,7 @@ Name | Type | Description | Notes ## StopProject -> StopProject(ctx, workspaceId, projectId).Execute() +> StopProject(ctx, targetId, projectId).Execute() Stop project @@ -523,14 +523,14 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + targetId := "targetId_example" // string | Target ID or Name projectId := "projectId_example" // string | Project ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.StopProject(context.Background(), workspaceId, projectId).Execute() + r, err := apiClient.TargetAPI.StopProject(context.Background(), targetId, projectId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StopProject``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopProject``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -542,7 +542,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**targetId** | **string** | Target ID or Name | **projectId** | **string** | Project ID | ### Other Parameters @@ -573,11 +573,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StopWorkspace +## StopTarget -> StopWorkspace(ctx, workspaceId).Execute() +> StopTarget(ctx, targetId).Execute() -Stop workspace +Stop target @@ -594,13 +594,13 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + targetId := "targetId_example" // string | Target ID or Name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.StopWorkspace(context.Background(), workspaceId).Execute() + r, err := apiClient.TargetAPI.StopTarget(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StopWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -612,11 +612,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**targetId** | **string** | Target ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiStopWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStopTargetRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/TargetDTO.md similarity index 66% rename from pkg/apiclient/docs/WorkspaceDTO.md rename to pkg/apiclient/docs/TargetDTO.md index 484565de01..7694b2dd6c 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -1,135 +1,135 @@ -# WorkspaceDTO +# TargetDTO ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Id** | **string** | | -**Info** | Pointer to [**WorkspaceInfo**](WorkspaceInfo.md) | | [optional] +**Info** | Pointer to [**TargetInfo**](TargetInfo.md) | | [optional] **Name** | **string** | | **Projects** | [**[]Project**](Project.md) | | **TargetConfig** | **string** | | ## Methods -### NewWorkspaceDTO +### NewTargetDTO -`func NewWorkspaceDTO(id string, name string, projects []Project, targetConfig string, ) *WorkspaceDTO` +`func NewTargetDTO(id string, name string, projects []Project, targetConfig string, ) *TargetDTO` -NewWorkspaceDTO instantiates a new WorkspaceDTO object +NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceDTOWithDefaults +### NewTargetDTOWithDefaults -`func NewWorkspaceDTOWithDefaults() *WorkspaceDTO` +`func NewTargetDTOWithDefaults() *TargetDTO` -NewWorkspaceDTOWithDefaults instantiates a new WorkspaceDTO object +NewTargetDTOWithDefaults instantiates a new TargetDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetId -`func (o *WorkspaceDTO) GetId() string` +`func (o *TargetDTO) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *WorkspaceDTO) GetIdOk() (*string, bool)` +`func (o *TargetDTO) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *WorkspaceDTO) SetId(v string)` +`func (o *TargetDTO) SetId(v string)` SetId sets Id field to given value. ### GetInfo -`func (o *WorkspaceDTO) GetInfo() WorkspaceInfo` +`func (o *TargetDTO) GetInfo() TargetInfo` GetInfo returns the Info field if non-nil, zero value otherwise. ### GetInfoOk -`func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool)` +`func (o *TargetDTO) GetInfoOk() (*TargetInfo, bool)` GetInfoOk returns a tuple with the Info field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetInfo -`func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo)` +`func (o *TargetDTO) SetInfo(v TargetInfo)` SetInfo sets Info field to given value. ### HasInfo -`func (o *WorkspaceDTO) HasInfo() bool` +`func (o *TargetDTO) HasInfo() bool` HasInfo returns a boolean if a field has been set. ### GetName -`func (o *WorkspaceDTO) GetName() string` +`func (o *TargetDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *WorkspaceDTO) GetNameOk() (*string, bool)` +`func (o *TargetDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *WorkspaceDTO) SetName(v string)` +`func (o *TargetDTO) SetName(v string)` SetName sets Name field to given value. ### GetProjects -`func (o *WorkspaceDTO) GetProjects() []Project` +`func (o *TargetDTO) GetProjects() []Project` GetProjects returns the Projects field if non-nil, zero value otherwise. ### GetProjectsOk -`func (o *WorkspaceDTO) GetProjectsOk() (*[]Project, bool)` +`func (o *TargetDTO) GetProjectsOk() (*[]Project, bool)` GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProjects -`func (o *WorkspaceDTO) SetProjects(v []Project)` +`func (o *TargetDTO) SetProjects(v []Project)` SetProjects sets Projects field to given value. ### GetTargetConfig -`func (o *WorkspaceDTO) GetTargetConfig() string` +`func (o *TargetDTO) GetTargetConfig() string` GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. ### GetTargetConfigOk -`func (o *WorkspaceDTO) GetTargetConfigOk() (*string, bool)` +`func (o *TargetDTO) GetTargetConfigOk() (*string, bool)` GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetTargetConfig -`func (o *WorkspaceDTO) SetTargetConfig(v string)` +`func (o *TargetDTO) SetTargetConfig(v string)` SetTargetConfig sets TargetConfig field to given value. diff --git a/pkg/apiclient/docs/WorkspaceInfo.md b/pkg/apiclient/docs/TargetInfo.md similarity index 68% rename from pkg/apiclient/docs/WorkspaceInfo.md rename to pkg/apiclient/docs/TargetInfo.md index e0468ccaf0..ffed91f68e 100644 --- a/pkg/apiclient/docs/WorkspaceInfo.md +++ b/pkg/apiclient/docs/TargetInfo.md @@ -1,4 +1,4 @@ -# WorkspaceInfo +# TargetInfo ## Properties @@ -10,85 +10,85 @@ Name | Type | Description | Notes ## Methods -### NewWorkspaceInfo +### NewTargetInfo -`func NewWorkspaceInfo(name string, projects []ProjectInfo, ) *WorkspaceInfo` +`func NewTargetInfo(name string, projects []ProjectInfo, ) *TargetInfo` -NewWorkspaceInfo instantiates a new WorkspaceInfo object +NewTargetInfo instantiates a new TargetInfo object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceInfoWithDefaults +### NewTargetInfoWithDefaults -`func NewWorkspaceInfoWithDefaults() *WorkspaceInfo` +`func NewTargetInfoWithDefaults() *TargetInfo` -NewWorkspaceInfoWithDefaults instantiates a new WorkspaceInfo object +NewTargetInfoWithDefaults instantiates a new TargetInfo object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetName -`func (o *WorkspaceInfo) GetName() string` +`func (o *TargetInfo) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *WorkspaceInfo) GetNameOk() (*string, bool)` +`func (o *TargetInfo) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *WorkspaceInfo) SetName(v string)` +`func (o *TargetInfo) SetName(v string)` SetName sets Name field to given value. ### GetProjects -`func (o *WorkspaceInfo) GetProjects() []ProjectInfo` +`func (o *TargetInfo) GetProjects() []ProjectInfo` GetProjects returns the Projects field if non-nil, zero value otherwise. ### GetProjectsOk -`func (o *WorkspaceInfo) GetProjectsOk() (*[]ProjectInfo, bool)` +`func (o *TargetInfo) GetProjectsOk() (*[]ProjectInfo, bool)` GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProjects -`func (o *WorkspaceInfo) SetProjects(v []ProjectInfo)` +`func (o *TargetInfo) SetProjects(v []ProjectInfo)` SetProjects sets Projects field to given value. ### GetProviderMetadata -`func (o *WorkspaceInfo) GetProviderMetadata() string` +`func (o *TargetInfo) GetProviderMetadata() string` GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. ### GetProviderMetadataOk -`func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool)` +`func (o *TargetInfo) GetProviderMetadataOk() (*string, bool)` GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderMetadata -`func (o *WorkspaceInfo) SetProviderMetadata(v string)` +`func (o *TargetInfo) SetProviderMetadata(v string)` SetProviderMetadata sets ProviderMetadata field to given value. ### HasProviderMetadata -`func (o *WorkspaceInfo) HasProviderMetadata() bool` +`func (o *TargetInfo) HasProviderMetadata() bool` HasProviderMetadata returns a boolean if a field has been set. diff --git a/pkg/apiclient/model_apikey_api_key_type.go b/pkg/apiclient/model_apikey_api_key_type.go index d75dfb81ff..42d2995f7e 100644 --- a/pkg/apiclient/model_apikey_api_key_type.go +++ b/pkg/apiclient/model_apikey_api_key_type.go @@ -20,16 +20,16 @@ type ApikeyApiKeyType string // List of apikey.ApiKeyType const ( - ApiKeyTypeClient ApikeyApiKeyType = "client" - ApiKeyTypeProject ApikeyApiKeyType = "project" - ApiKeyTypeWorkspace ApikeyApiKeyType = "workspace" + ApiKeyTypeClient ApikeyApiKeyType = "client" + ApiKeyTypeProject ApikeyApiKeyType = "project" + ApiKeyTypeTarget ApikeyApiKeyType = "target" ) // All allowed values of ApikeyApiKeyType enum var AllowedApikeyApiKeyTypeEnumValues = []ApikeyApiKeyType{ "client", "project", - "workspace", + "target", } func (v *ApikeyApiKeyType) UnmarshalJSON(src []byte) error { diff --git a/pkg/apiclient/model_create_workspace_dto.go b/pkg/apiclient/model_create_target_dto.go similarity index 61% rename from pkg/apiclient/model_create_workspace_dto.go rename to pkg/apiclient/model_create_target_dto.go index 53262a10cd..94122bc805 100644 --- a/pkg/apiclient/model_create_workspace_dto.go +++ b/pkg/apiclient/model_create_target_dto.go @@ -16,25 +16,25 @@ import ( "fmt" ) -// checks if the CreateWorkspaceDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateWorkspaceDTO{} +// checks if the CreateTargetDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateTargetDTO{} -// CreateWorkspaceDTO struct for CreateWorkspaceDTO -type CreateWorkspaceDTO struct { +// CreateTargetDTO struct for CreateTargetDTO +type CreateTargetDTO struct { Id string `json:"id"` Name string `json:"name"` Projects []CreateProjectDTO `json:"projects"` TargetConfig string `json:"targetConfig"` } -type _CreateWorkspaceDTO CreateWorkspaceDTO +type _CreateTargetDTO CreateTargetDTO -// NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object +// NewCreateTargetDTO instantiates a new CreateTargetDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, targetConfig string) *CreateWorkspaceDTO { - this := CreateWorkspaceDTO{} +func NewCreateTargetDTO(id string, name string, projects []CreateProjectDTO, targetConfig string) *CreateTargetDTO { + this := CreateTargetDTO{} this.Id = id this.Name = name this.Projects = projects @@ -42,16 +42,16 @@ func NewCreateWorkspaceDTO(id string, name string, projects []CreateProjectDTO, return &this } -// NewCreateWorkspaceDTOWithDefaults instantiates a new CreateWorkspaceDTO object +// NewCreateTargetDTOWithDefaults instantiates a new CreateTargetDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateWorkspaceDTOWithDefaults() *CreateWorkspaceDTO { - this := CreateWorkspaceDTO{} +func NewCreateTargetDTOWithDefaults() *CreateTargetDTO { + this := CreateTargetDTO{} return &this } // GetId returns the Id field value -func (o *CreateWorkspaceDTO) GetId() string { +func (o *CreateTargetDTO) GetId() string { if o == nil { var ret string return ret @@ -62,7 +62,7 @@ func (o *CreateWorkspaceDTO) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceDTO) GetIdOk() (*string, bool) { +func (o *CreateTargetDTO) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -70,12 +70,12 @@ func (o *CreateWorkspaceDTO) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *CreateWorkspaceDTO) SetId(v string) { +func (o *CreateTargetDTO) SetId(v string) { o.Id = v } // GetName returns the Name field value -func (o *CreateWorkspaceDTO) GetName() string { +func (o *CreateTargetDTO) GetName() string { if o == nil { var ret string return ret @@ -86,7 +86,7 @@ func (o *CreateWorkspaceDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceDTO) GetNameOk() (*string, bool) { +func (o *CreateTargetDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -94,12 +94,12 @@ func (o *CreateWorkspaceDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *CreateWorkspaceDTO) SetName(v string) { +func (o *CreateTargetDTO) SetName(v string) { o.Name = v } // GetProjects returns the Projects field value -func (o *CreateWorkspaceDTO) GetProjects() []CreateProjectDTO { +func (o *CreateTargetDTO) GetProjects() []CreateProjectDTO { if o == nil { var ret []CreateProjectDTO return ret @@ -110,7 +110,7 @@ func (o *CreateWorkspaceDTO) GetProjects() []CreateProjectDTO { // GetProjectsOk returns a tuple with the Projects field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceDTO) GetProjectsOk() ([]CreateProjectDTO, bool) { +func (o *CreateTargetDTO) GetProjectsOk() ([]CreateProjectDTO, bool) { if o == nil { return nil, false } @@ -118,12 +118,12 @@ func (o *CreateWorkspaceDTO) GetProjectsOk() ([]CreateProjectDTO, bool) { } // SetProjects sets field value -func (o *CreateWorkspaceDTO) SetProjects(v []CreateProjectDTO) { +func (o *CreateTargetDTO) SetProjects(v []CreateProjectDTO) { o.Projects = v } // GetTargetConfig returns the TargetConfig field value -func (o *CreateWorkspaceDTO) GetTargetConfig() string { +func (o *CreateTargetDTO) GetTargetConfig() string { if o == nil { var ret string return ret @@ -134,7 +134,7 @@ func (o *CreateWorkspaceDTO) GetTargetConfig() string { // GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceDTO) GetTargetConfigOk() (*string, bool) { +func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } @@ -142,11 +142,11 @@ func (o *CreateWorkspaceDTO) GetTargetConfigOk() (*string, bool) { } // SetTargetConfig sets field value -func (o *CreateWorkspaceDTO) SetTargetConfig(v string) { +func (o *CreateTargetDTO) SetTargetConfig(v string) { o.TargetConfig = v } -func (o CreateWorkspaceDTO) MarshalJSON() ([]byte, error) { +func (o CreateTargetDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -154,7 +154,7 @@ func (o CreateWorkspaceDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateWorkspaceDTO) ToMap() (map[string]interface{}, error) { +func (o CreateTargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name @@ -163,7 +163,7 @@ func (o CreateWorkspaceDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *CreateWorkspaceDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateTargetDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -188,53 +188,53 @@ func (o *CreateWorkspaceDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateWorkspaceDTO := _CreateWorkspaceDTO{} + varCreateTargetDTO := _CreateTargetDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateWorkspaceDTO) + err = decoder.Decode(&varCreateTargetDTO) if err != nil { return err } - *o = CreateWorkspaceDTO(varCreateWorkspaceDTO) + *o = CreateTargetDTO(varCreateTargetDTO) return err } -type NullableCreateWorkspaceDTO struct { - value *CreateWorkspaceDTO +type NullableCreateTargetDTO struct { + value *CreateTargetDTO isSet bool } -func (v NullableCreateWorkspaceDTO) Get() *CreateWorkspaceDTO { +func (v NullableCreateTargetDTO) Get() *CreateTargetDTO { return v.value } -func (v *NullableCreateWorkspaceDTO) Set(val *CreateWorkspaceDTO) { +func (v *NullableCreateTargetDTO) Set(val *CreateTargetDTO) { v.value = val v.isSet = true } -func (v NullableCreateWorkspaceDTO) IsSet() bool { +func (v NullableCreateTargetDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateWorkspaceDTO) Unset() { +func (v *NullableCreateTargetDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateWorkspaceDTO(val *CreateWorkspaceDTO) *NullableCreateWorkspaceDTO { - return &NullableCreateWorkspaceDTO{value: val, isSet: true} +func NewNullableCreateTargetDTO(val *CreateTargetDTO) *NullableCreateTargetDTO { + return &NullableCreateTargetDTO{value: val, isSet: true} } -func (v NullableCreateWorkspaceDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateTargetDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateWorkspaceDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateTargetDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_project.go b/pkg/apiclient/model_project.go index a9ba9cb754..d8676bd1a0 100644 --- a/pkg/apiclient/model_project.go +++ b/pkg/apiclient/model_project.go @@ -29,8 +29,8 @@ type Project struct { Repository GitRepository `json:"repository"` State *ProjectState `json:"state,omitempty"` TargetConfig string `json:"targetConfig"` + TargetId string `json:"targetId"` User string `json:"user"` - WorkspaceId string `json:"workspaceId"` } type _Project Project @@ -39,15 +39,15 @@ type _Project Project // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, user string, workspaceId string) *Project { +func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string) *Project { this := Project{} this.EnvVars = envVars this.Image = image this.Name = name this.Repository = repository this.TargetConfig = targetConfig + this.TargetId = targetId this.User = user - this.WorkspaceId = workspaceId return &this } @@ -275,52 +275,52 @@ func (o *Project) SetTargetConfig(v string) { o.TargetConfig = v } -// GetUser returns the User field value -func (o *Project) GetUser() string { +// GetTargetId returns the TargetId field value +func (o *Project) GetTargetId() string { if o == nil { var ret string return ret } - return o.User + return o.TargetId } -// GetUserOk returns a tuple with the User field value +// GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *Project) GetUserOk() (*string, bool) { +func (o *Project) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.User, true + return &o.TargetId, true } -// SetUser sets field value -func (o *Project) SetUser(v string) { - o.User = v +// SetTargetId sets field value +func (o *Project) SetTargetId(v string) { + o.TargetId = v } -// GetWorkspaceId returns the WorkspaceId field value -func (o *Project) GetWorkspaceId() string { +// GetUser returns the User field value +func (o *Project) GetUser() string { if o == nil { var ret string return ret } - return o.WorkspaceId + return o.User } -// GetWorkspaceIdOk returns a tuple with the WorkspaceId field value +// GetUserOk returns a tuple with the User field value // and a boolean to check if the value has been set. -func (o *Project) GetWorkspaceIdOk() (*string, bool) { +func (o *Project) GetUserOk() (*string, bool) { if o == nil { return nil, false } - return &o.WorkspaceId, true + return &o.User, true } -// SetWorkspaceId sets field value -func (o *Project) SetWorkspaceId(v string) { - o.WorkspaceId = v +// SetUser sets field value +func (o *Project) SetUser(v string) { + o.User = v } func (o Project) MarshalJSON() ([]byte, error) { @@ -347,8 +347,8 @@ func (o Project) ToMap() (map[string]interface{}, error) { toSerialize["state"] = o.State } toSerialize["targetConfig"] = o.TargetConfig + toSerialize["targetId"] = o.TargetId toSerialize["user"] = o.User - toSerialize["workspaceId"] = o.WorkspaceId return toSerialize, nil } @@ -362,8 +362,8 @@ func (o *Project) UnmarshalJSON(data []byte) (err error) { "name", "repository", "targetConfig", + "targetId", "user", - "workspaceId", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_project_info.go b/pkg/apiclient/model_project_info.go index 15d0072ba8..3bdf2a543e 100644 --- a/pkg/apiclient/model_project_info.go +++ b/pkg/apiclient/model_project_info.go @@ -25,7 +25,7 @@ type ProjectInfo struct { IsRunning bool `json:"isRunning"` Name string `json:"name"` ProviderMetadata *string `json:"providerMetadata,omitempty"` - WorkspaceId string `json:"workspaceId"` + TargetId string `json:"targetId"` } type _ProjectInfo ProjectInfo @@ -34,12 +34,12 @@ type _ProjectInfo ProjectInfo // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProjectInfo(created string, isRunning bool, name string, workspaceId string) *ProjectInfo { +func NewProjectInfo(created string, isRunning bool, name string, targetId string) *ProjectInfo { this := ProjectInfo{} this.Created = created this.IsRunning = isRunning this.Name = name - this.WorkspaceId = workspaceId + this.TargetId = targetId return &this } @@ -155,28 +155,28 @@ func (o *ProjectInfo) SetProviderMetadata(v string) { o.ProviderMetadata = &v } -// GetWorkspaceId returns the WorkspaceId field value -func (o *ProjectInfo) GetWorkspaceId() string { +// GetTargetId returns the TargetId field value +func (o *ProjectInfo) GetTargetId() string { if o == nil { var ret string return ret } - return o.WorkspaceId + return o.TargetId } -// GetWorkspaceIdOk returns a tuple with the WorkspaceId field value +// GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *ProjectInfo) GetWorkspaceIdOk() (*string, bool) { +func (o *ProjectInfo) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.WorkspaceId, true + return &o.TargetId, true } -// SetWorkspaceId sets field value -func (o *ProjectInfo) SetWorkspaceId(v string) { - o.WorkspaceId = v +// SetTargetId sets field value +func (o *ProjectInfo) SetTargetId(v string) { + o.TargetId = v } func (o ProjectInfo) MarshalJSON() ([]byte, error) { @@ -195,7 +195,7 @@ func (o ProjectInfo) ToMap() (map[string]interface{}, error) { if !IsNil(o.ProviderMetadata) { toSerialize["providerMetadata"] = o.ProviderMetadata } - toSerialize["workspaceId"] = o.WorkspaceId + toSerialize["targetId"] = o.TargetId return toSerialize, nil } @@ -207,7 +207,7 @@ func (o *ProjectInfo) UnmarshalJSON(data []byte) (err error) { "created", "isRunning", "name", - "workspaceId", + "targetId", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_target.go similarity index 66% rename from pkg/apiclient/model_workspace.go rename to pkg/apiclient/model_target.go index f2d187db3d..c74ac69ed8 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_target.go @@ -16,25 +16,25 @@ import ( "fmt" ) -// checks if the Workspace type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &Workspace{} +// checks if the Target type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Target{} -// Workspace struct for Workspace -type Workspace struct { +// Target struct for Target +type Target struct { Id string `json:"id"` Name string `json:"name"` Projects []Project `json:"projects"` TargetConfig string `json:"targetConfig"` } -type _Workspace Workspace +type _Target Target -// NewWorkspace instantiates a new Workspace object +// NewTarget instantiates a new Target object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspace(id string, name string, projects []Project, targetConfig string) *Workspace { - this := Workspace{} +func NewTarget(id string, name string, projects []Project, targetConfig string) *Target { + this := Target{} this.Id = id this.Name = name this.Projects = projects @@ -42,16 +42,16 @@ func NewWorkspace(id string, name string, projects []Project, targetConfig strin return &this } -// NewWorkspaceWithDefaults instantiates a new Workspace object +// NewTargetWithDefaults instantiates a new Target object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceWithDefaults() *Workspace { - this := Workspace{} +func NewTargetWithDefaults() *Target { + this := Target{} return &this } // GetId returns the Id field value -func (o *Workspace) GetId() string { +func (o *Target) GetId() string { if o == nil { var ret string return ret @@ -62,7 +62,7 @@ func (o *Workspace) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *Workspace) GetIdOk() (*string, bool) { +func (o *Target) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -70,12 +70,12 @@ func (o *Workspace) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *Workspace) SetId(v string) { +func (o *Target) SetId(v string) { o.Id = v } // GetName returns the Name field value -func (o *Workspace) GetName() string { +func (o *Target) GetName() string { if o == nil { var ret string return ret @@ -86,7 +86,7 @@ func (o *Workspace) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *Workspace) GetNameOk() (*string, bool) { +func (o *Target) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -94,12 +94,12 @@ func (o *Workspace) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *Workspace) SetName(v string) { +func (o *Target) SetName(v string) { o.Name = v } // GetProjects returns the Projects field value -func (o *Workspace) GetProjects() []Project { +func (o *Target) GetProjects() []Project { if o == nil { var ret []Project return ret @@ -110,7 +110,7 @@ func (o *Workspace) GetProjects() []Project { // GetProjectsOk returns a tuple with the Projects field value // and a boolean to check if the value has been set. -func (o *Workspace) GetProjectsOk() ([]Project, bool) { +func (o *Target) GetProjectsOk() ([]Project, bool) { if o == nil { return nil, false } @@ -118,12 +118,12 @@ func (o *Workspace) GetProjectsOk() ([]Project, bool) { } // SetProjects sets field value -func (o *Workspace) SetProjects(v []Project) { +func (o *Target) SetProjects(v []Project) { o.Projects = v } // GetTargetConfig returns the TargetConfig field value -func (o *Workspace) GetTargetConfig() string { +func (o *Target) GetTargetConfig() string { if o == nil { var ret string return ret @@ -134,7 +134,7 @@ func (o *Workspace) GetTargetConfig() string { // GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *Workspace) GetTargetConfigOk() (*string, bool) { +func (o *Target) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } @@ -142,11 +142,11 @@ func (o *Workspace) GetTargetConfigOk() (*string, bool) { } // SetTargetConfig sets field value -func (o *Workspace) SetTargetConfig(v string) { +func (o *Target) SetTargetConfig(v string) { o.TargetConfig = v } -func (o Workspace) MarshalJSON() ([]byte, error) { +func (o Target) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -154,7 +154,7 @@ func (o Workspace) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o Workspace) ToMap() (map[string]interface{}, error) { +func (o Target) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name @@ -163,7 +163,7 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *Workspace) UnmarshalJSON(data []byte) (err error) { +func (o *Target) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -188,53 +188,53 @@ func (o *Workspace) UnmarshalJSON(data []byte) (err error) { } } - varWorkspace := _Workspace{} + varTarget := _Target{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspace) + err = decoder.Decode(&varTarget) if err != nil { return err } - *o = Workspace(varWorkspace) + *o = Target(varTarget) return err } -type NullableWorkspace struct { - value *Workspace +type NullableTarget struct { + value *Target isSet bool } -func (v NullableWorkspace) Get() *Workspace { +func (v NullableTarget) Get() *Target { return v.value } -func (v *NullableWorkspace) Set(val *Workspace) { +func (v *NullableTarget) Set(val *Target) { v.value = val v.isSet = true } -func (v NullableWorkspace) IsSet() bool { +func (v NullableTarget) IsSet() bool { return v.isSet } -func (v *NullableWorkspace) Unset() { +func (v *NullableTarget) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspace(val *Workspace) *NullableWorkspace { - return &NullableWorkspace{value: val, isSet: true} +func NewNullableTarget(val *Target) *NullableTarget { + return &NullableTarget{value: val, isSet: true} } -func (v NullableWorkspace) MarshalJSON() ([]byte, error) { +func (v NullableTarget) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspace) UnmarshalJSON(src []byte) error { +func (v *NullableTarget) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_target_dto.go similarity index 61% rename from pkg/apiclient/model_workspace_dto.go rename to pkg/apiclient/model_target_dto.go index ccd4c0219c..7be1814fa4 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -16,26 +16,26 @@ import ( "fmt" ) -// checks if the WorkspaceDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &WorkspaceDTO{} - -// WorkspaceDTO struct for WorkspaceDTO -type WorkspaceDTO struct { - Id string `json:"id"` - Info *WorkspaceInfo `json:"info,omitempty"` - Name string `json:"name"` - Projects []Project `json:"projects"` - TargetConfig string `json:"targetConfig"` +// checks if the TargetDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TargetDTO{} + +// TargetDTO struct for TargetDTO +type TargetDTO struct { + Id string `json:"id"` + Info *TargetInfo `json:"info,omitempty"` + Name string `json:"name"` + Projects []Project `json:"projects"` + TargetConfig string `json:"targetConfig"` } -type _WorkspaceDTO WorkspaceDTO +type _TargetDTO TargetDTO -// NewWorkspaceDTO instantiates a new WorkspaceDTO object +// NewTargetDTO instantiates a new TargetDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceDTO(id string, name string, projects []Project, targetConfig string) *WorkspaceDTO { - this := WorkspaceDTO{} +func NewTargetDTO(id string, name string, projects []Project, targetConfig string) *TargetDTO { + this := TargetDTO{} this.Id = id this.Name = name this.Projects = projects @@ -43,16 +43,16 @@ func NewWorkspaceDTO(id string, name string, projects []Project, targetConfig st return &this } -// NewWorkspaceDTOWithDefaults instantiates a new WorkspaceDTO object +// NewTargetDTOWithDefaults instantiates a new TargetDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceDTOWithDefaults() *WorkspaceDTO { - this := WorkspaceDTO{} +func NewTargetDTOWithDefaults() *TargetDTO { + this := TargetDTO{} return &this } // GetId returns the Id field value -func (o *WorkspaceDTO) GetId() string { +func (o *TargetDTO) GetId() string { if o == nil { var ret string return ret @@ -63,7 +63,7 @@ func (o *WorkspaceDTO) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetIdOk() (*string, bool) { +func (o *TargetDTO) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -71,14 +71,14 @@ func (o *WorkspaceDTO) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *WorkspaceDTO) SetId(v string) { +func (o *TargetDTO) SetId(v string) { o.Id = v } // GetInfo returns the Info field value if set, zero value otherwise. -func (o *WorkspaceDTO) GetInfo() WorkspaceInfo { +func (o *TargetDTO) GetInfo() TargetInfo { if o == nil || IsNil(o.Info) { - var ret WorkspaceInfo + var ret TargetInfo return ret } return *o.Info @@ -86,7 +86,7 @@ func (o *WorkspaceDTO) GetInfo() WorkspaceInfo { // GetInfoOk returns a tuple with the Info field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool) { +func (o *TargetDTO) GetInfoOk() (*TargetInfo, bool) { if o == nil || IsNil(o.Info) { return nil, false } @@ -94,7 +94,7 @@ func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool) { } // HasInfo returns a boolean if a field has been set. -func (o *WorkspaceDTO) HasInfo() bool { +func (o *TargetDTO) HasInfo() bool { if o != nil && !IsNil(o.Info) { return true } @@ -102,13 +102,13 @@ func (o *WorkspaceDTO) HasInfo() bool { return false } -// SetInfo gets a reference to the given WorkspaceInfo and assigns it to the Info field. -func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo) { +// SetInfo gets a reference to the given TargetInfo and assigns it to the Info field. +func (o *TargetDTO) SetInfo(v TargetInfo) { o.Info = &v } // GetName returns the Name field value -func (o *WorkspaceDTO) GetName() string { +func (o *TargetDTO) GetName() string { if o == nil { var ret string return ret @@ -119,7 +119,7 @@ func (o *WorkspaceDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetNameOk() (*string, bool) { +func (o *TargetDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -127,12 +127,12 @@ func (o *WorkspaceDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *WorkspaceDTO) SetName(v string) { +func (o *TargetDTO) SetName(v string) { o.Name = v } // GetProjects returns the Projects field value -func (o *WorkspaceDTO) GetProjects() []Project { +func (o *TargetDTO) GetProjects() []Project { if o == nil { var ret []Project return ret @@ -143,7 +143,7 @@ func (o *WorkspaceDTO) GetProjects() []Project { // GetProjectsOk returns a tuple with the Projects field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetProjectsOk() ([]Project, bool) { +func (o *TargetDTO) GetProjectsOk() ([]Project, bool) { if o == nil { return nil, false } @@ -151,12 +151,12 @@ func (o *WorkspaceDTO) GetProjectsOk() ([]Project, bool) { } // SetProjects sets field value -func (o *WorkspaceDTO) SetProjects(v []Project) { +func (o *TargetDTO) SetProjects(v []Project) { o.Projects = v } // GetTargetConfig returns the TargetConfig field value -func (o *WorkspaceDTO) GetTargetConfig() string { +func (o *TargetDTO) GetTargetConfig() string { if o == nil { var ret string return ret @@ -167,7 +167,7 @@ func (o *WorkspaceDTO) GetTargetConfig() string { // GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetTargetConfigOk() (*string, bool) { +func (o *TargetDTO) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } @@ -175,11 +175,11 @@ func (o *WorkspaceDTO) GetTargetConfigOk() (*string, bool) { } // SetTargetConfig sets field value -func (o *WorkspaceDTO) SetTargetConfig(v string) { +func (o *TargetDTO) SetTargetConfig(v string) { o.TargetConfig = v } -func (o WorkspaceDTO) MarshalJSON() ([]byte, error) { +func (o TargetDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -187,7 +187,7 @@ func (o WorkspaceDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { +func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id if !IsNil(o.Info) { @@ -199,7 +199,7 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { +func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -224,53 +224,53 @@ func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { } } - varWorkspaceDTO := _WorkspaceDTO{} + varTargetDTO := _TargetDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspaceDTO) + err = decoder.Decode(&varTargetDTO) if err != nil { return err } - *o = WorkspaceDTO(varWorkspaceDTO) + *o = TargetDTO(varTargetDTO) return err } -type NullableWorkspaceDTO struct { - value *WorkspaceDTO +type NullableTargetDTO struct { + value *TargetDTO isSet bool } -func (v NullableWorkspaceDTO) Get() *WorkspaceDTO { +func (v NullableTargetDTO) Get() *TargetDTO { return v.value } -func (v *NullableWorkspaceDTO) Set(val *WorkspaceDTO) { +func (v *NullableTargetDTO) Set(val *TargetDTO) { v.value = val v.isSet = true } -func (v NullableWorkspaceDTO) IsSet() bool { +func (v NullableTargetDTO) IsSet() bool { return v.isSet } -func (v *NullableWorkspaceDTO) Unset() { +func (v *NullableTargetDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspaceDTO(val *WorkspaceDTO) *NullableWorkspaceDTO { - return &NullableWorkspaceDTO{value: val, isSet: true} +func NewNullableTargetDTO(val *TargetDTO) *NullableTargetDTO { + return &NullableTargetDTO{value: val, isSet: true} } -func (v NullableWorkspaceDTO) MarshalJSON() ([]byte, error) { +func (v NullableTargetDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspaceDTO) UnmarshalJSON(src []byte) error { +func (v *NullableTargetDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_workspace_info.go b/pkg/apiclient/model_target_info.go similarity index 65% rename from pkg/apiclient/model_workspace_info.go rename to pkg/apiclient/model_target_info.go index 7c7b22a6a3..6efac92903 100644 --- a/pkg/apiclient/model_workspace_info.go +++ b/pkg/apiclient/model_target_info.go @@ -16,39 +16,39 @@ import ( "fmt" ) -// checks if the WorkspaceInfo type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &WorkspaceInfo{} +// checks if the TargetInfo type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TargetInfo{} -// WorkspaceInfo struct for WorkspaceInfo -type WorkspaceInfo struct { +// TargetInfo struct for TargetInfo +type TargetInfo struct { Name string `json:"name"` Projects []ProjectInfo `json:"projects"` ProviderMetadata *string `json:"providerMetadata,omitempty"` } -type _WorkspaceInfo WorkspaceInfo +type _TargetInfo TargetInfo -// NewWorkspaceInfo instantiates a new WorkspaceInfo object +// NewTargetInfo instantiates a new TargetInfo object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceInfo(name string, projects []ProjectInfo) *WorkspaceInfo { - this := WorkspaceInfo{} +func NewTargetInfo(name string, projects []ProjectInfo) *TargetInfo { + this := TargetInfo{} this.Name = name this.Projects = projects return &this } -// NewWorkspaceInfoWithDefaults instantiates a new WorkspaceInfo object +// NewTargetInfoWithDefaults instantiates a new TargetInfo object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceInfoWithDefaults() *WorkspaceInfo { - this := WorkspaceInfo{} +func NewTargetInfoWithDefaults() *TargetInfo { + this := TargetInfo{} return &this } // GetName returns the Name field value -func (o *WorkspaceInfo) GetName() string { +func (o *TargetInfo) GetName() string { if o == nil { var ret string return ret @@ -59,7 +59,7 @@ func (o *WorkspaceInfo) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetNameOk() (*string, bool) { +func (o *TargetInfo) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -67,12 +67,12 @@ func (o *WorkspaceInfo) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *WorkspaceInfo) SetName(v string) { +func (o *TargetInfo) SetName(v string) { o.Name = v } // GetProjects returns the Projects field value -func (o *WorkspaceInfo) GetProjects() []ProjectInfo { +func (o *TargetInfo) GetProjects() []ProjectInfo { if o == nil { var ret []ProjectInfo return ret @@ -83,7 +83,7 @@ func (o *WorkspaceInfo) GetProjects() []ProjectInfo { // GetProjectsOk returns a tuple with the Projects field value // and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetProjectsOk() ([]ProjectInfo, bool) { +func (o *TargetInfo) GetProjectsOk() ([]ProjectInfo, bool) { if o == nil { return nil, false } @@ -91,12 +91,12 @@ func (o *WorkspaceInfo) GetProjectsOk() ([]ProjectInfo, bool) { } // SetProjects sets field value -func (o *WorkspaceInfo) SetProjects(v []ProjectInfo) { +func (o *TargetInfo) SetProjects(v []ProjectInfo) { o.Projects = v } // GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. -func (o *WorkspaceInfo) GetProviderMetadata() string { +func (o *TargetInfo) GetProviderMetadata() string { if o == nil || IsNil(o.ProviderMetadata) { var ret string return ret @@ -106,7 +106,7 @@ func (o *WorkspaceInfo) GetProviderMetadata() string { // GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool) { +func (o *TargetInfo) GetProviderMetadataOk() (*string, bool) { if o == nil || IsNil(o.ProviderMetadata) { return nil, false } @@ -114,7 +114,7 @@ func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool) { } // HasProviderMetadata returns a boolean if a field has been set. -func (o *WorkspaceInfo) HasProviderMetadata() bool { +func (o *TargetInfo) HasProviderMetadata() bool { if o != nil && !IsNil(o.ProviderMetadata) { return true } @@ -123,11 +123,11 @@ func (o *WorkspaceInfo) HasProviderMetadata() bool { } // SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. -func (o *WorkspaceInfo) SetProviderMetadata(v string) { +func (o *TargetInfo) SetProviderMetadata(v string) { o.ProviderMetadata = &v } -func (o WorkspaceInfo) MarshalJSON() ([]byte, error) { +func (o TargetInfo) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -135,7 +135,7 @@ func (o WorkspaceInfo) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o WorkspaceInfo) ToMap() (map[string]interface{}, error) { +func (o TargetInfo) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["name"] = o.Name toSerialize["projects"] = o.Projects @@ -145,7 +145,7 @@ func (o WorkspaceInfo) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *WorkspaceInfo) UnmarshalJSON(data []byte) (err error) { +func (o *TargetInfo) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -168,53 +168,53 @@ func (o *WorkspaceInfo) UnmarshalJSON(data []byte) (err error) { } } - varWorkspaceInfo := _WorkspaceInfo{} + varTargetInfo := _TargetInfo{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspaceInfo) + err = decoder.Decode(&varTargetInfo) if err != nil { return err } - *o = WorkspaceInfo(varWorkspaceInfo) + *o = TargetInfo(varTargetInfo) return err } -type NullableWorkspaceInfo struct { - value *WorkspaceInfo +type NullableTargetInfo struct { + value *TargetInfo isSet bool } -func (v NullableWorkspaceInfo) Get() *WorkspaceInfo { +func (v NullableTargetInfo) Get() *TargetInfo { return v.value } -func (v *NullableWorkspaceInfo) Set(val *WorkspaceInfo) { +func (v *NullableTargetInfo) Set(val *TargetInfo) { v.value = val v.isSet = true } -func (v NullableWorkspaceInfo) IsSet() bool { +func (v NullableTargetInfo) IsSet() bool { return v.isSet } -func (v *NullableWorkspaceInfo) Unset() { +func (v *NullableTargetInfo) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspaceInfo(val *WorkspaceInfo) *NullableWorkspaceInfo { - return &NullableWorkspaceInfo{value: val, isSet: true} +func NewNullableTargetInfo(val *TargetInfo) *NullableTargetInfo { + return &NullableTargetInfo{value: val, isSet: true} } -func (v NullableWorkspaceInfo) MarshalJSON() ([]byte, error) { +func (v NullableTargetInfo) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspaceInfo) UnmarshalJSON(src []byte) error { +func (v *NullableTargetInfo) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apikey/apikey.go b/pkg/apikey/apikey.go index 2900bca156..0b917a4b84 100644 --- a/pkg/apikey/apikey.go +++ b/pkg/apikey/apikey.go @@ -6,9 +6,9 @@ package apikey type ApiKeyType string const ( - ApiKeyTypeClient ApiKeyType = "client" - ApiKeyTypeProject ApiKeyType = "project" - ApiKeyTypeWorkspace ApiKeyType = "workspace" + ApiKeyTypeClient ApiKeyType = "client" + ApiKeyTypeProject ApiKeyType = "project" + ApiKeyTypeTarget ApiKeyType = "target" ) type ApiKey struct { diff --git a/pkg/build/build.go b/pkg/build/build.go index a21d34a2d0..d745be27f0 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -9,8 +9,8 @@ import ( "time" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/containerconfig" ) type BuildState string diff --git a/pkg/build/builder_test.go b/pkg/build/builder_test.go index 8ca66b4d07..e574398425 100644 --- a/pkg/build/builder_test.go +++ b/pkg/build/builder_test.go @@ -8,7 +8,7 @@ import ( t_build "github.com/daytonaio/daytona/internal/testing/build" git_mocks "github.com/daytonaio/daytona/internal/testing/git/mocks" - builder_mocks "github.com/daytonaio/daytona/internal/testing/server/workspaces/mocks" + builder_mocks "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/pkg/build" "github.com/stretchr/testify/suite" ) diff --git a/pkg/build/detect/detect.go b/pkg/build/detect/detect.go index 81e47ade94..ba5b8d3ea0 100644 --- a/pkg/build/detect/detect.go +++ b/pkg/build/detect/detect.go @@ -9,7 +9,7 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type BuilderType string diff --git a/pkg/build/runner_test.go b/pkg/build/runner_test.go index 47454ddbd2..d6e3c8af97 100644 --- a/pkg/build/runner_test.go +++ b/pkg/build/runner_test.go @@ -9,7 +9,7 @@ import ( t_build "github.com/daytonaio/daytona/internal/testing/build" git_mocks "github.com/daytonaio/daytona/internal/testing/git/mocks" logger_mocks "github.com/daytonaio/daytona/internal/testing/logger/mocks" - "github.com/daytonaio/daytona/internal/testing/server/workspaces/mocks" + "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" t_gitprovider "github.com/daytonaio/daytona/pkg/build/mocks" diff --git a/pkg/build/store.go b/pkg/build/store.go index 04fbf9b07f..446293b87f 100644 --- a/pkg/build/store.go +++ b/pkg/build/store.go @@ -6,7 +6,7 @@ package build import ( "errors" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type Store interface { diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index d45061ecc0..24371d2426 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -18,7 +18,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -82,9 +82,9 @@ var AgentCmd = &cobra.Command{ DefaultProjectDir: os.Getenv("HOME"), } - tailscaleHostname := project.GetProjectHostname(c.WorkspaceId, c.ProjectName) + tailscaleHostname := project.GetProjectHostname(c.TargetId, c.ProjectName) if hostModeFlag { - tailscaleHostname = c.WorkspaceId + tailscaleHostname = c.TargetId } toolBoxServer := &toolbox.Server{ diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go new file mode 100644 index 0000000000..344b7d4376 --- /dev/null +++ b/pkg/cmd/agentmode/agent_mode.go @@ -0,0 +1,71 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package agentmode + +import ( + "os" + "time" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + cmd "github.com/daytonaio/daytona/pkg/cmd" + . "github.com/daytonaio/daytona/pkg/cmd/agent" + + "github.com/spf13/cobra" +) + +var targetId = "" +var projectName = "" + +var agentModeRootCmd = &cobra.Command{ + Use: "daytona", + Short: "Daytona is a Dev Environment Manager", + Long: "Daytona is a Dev Environment Manager", + DisableAutoGenTag: true, + SilenceUsage: true, + SilenceErrors: true, + RunE: func(cmd *cobra.Command, args []string) error { + return cmd.Help() + }, +} + +func Execute() error { + cmd.SetupRootCommand(agentModeRootCmd) + agentModeRootCmd.AddGroup(&cobra.Group{ID: util.TARGET_GROUP, Title: "Project & Target"}) + agentModeRootCmd.AddCommand(gitCredCmd) + agentModeRootCmd.AddCommand(AgentCmd) + agentModeRootCmd.AddCommand(startCmd) + agentModeRootCmd.AddCommand(stopCmd) + agentModeRootCmd.AddCommand(restartCmd) + agentModeRootCmd.AddCommand(infoCmd) + agentModeRootCmd.AddCommand(portForwardCmd) + agentModeRootCmd.AddCommand(exposeCmd) + + clientId := config.GetClientId() + telemetryEnabled := config.TelemetryEnabled() + startTime := time.Now() + + telemetryService, command, flags, isComplete, err := cmd.PreRun(agentModeRootCmd, os.Args[1:], telemetryEnabled, clientId, startTime) + if err != nil { + return err + } + + err = agentModeRootCmd.Execute() + + endTime := time.Now() + if !isComplete { + cmd.PostRun(command, err, telemetryService, clientId, startTime, endTime, flags) + } + + return err +} + +func init() { + if targetIdEnv := os.Getenv("DAYTONA_TARGET_ID"); targetIdEnv != "" { + targetId = targetIdEnv + } + if projectNameEnv := os.Getenv("DAYTONA_PROJECT_NAME"); projectNameEnv != "" { + projectName = projectNameEnv + } +} diff --git a/pkg/cmd/workspacemode/expose.go b/pkg/cmd/agentmode/expose.go similarity index 94% rename from pkg/cmd/workspacemode/expose.go rename to pkg/cmd/agentmode/expose.go index ef95e27242..5d81c34738 100644 --- a/pkg/cmd/workspacemode/expose.go +++ b/pkg/cmd/agentmode/expose.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "fmt" @@ -19,7 +19,7 @@ var exposeCmd = &cobra.Command{ Use: "expose [PORT]", Short: "Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project", Args: cobra.ExactArgs(1), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { port, err := strconv.Atoi(args[0]) if err != nil { diff --git a/pkg/cmd/workspacemode/forward.go b/pkg/cmd/agentmode/forward.go similarity index 80% rename from pkg/cmd/workspacemode/forward.go rename to pkg/cmd/agentmode/forward.go index 3bfc645953..11979e8da3 100644 --- a/pkg/cmd/workspacemode/forward.go +++ b/pkg/cmd/agentmode/forward.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "strconv" @@ -16,7 +16,7 @@ var portForwardCmd = &cobra.Command{ Use: "forward [PORT]", Short: "Forward a port publicly via an URL", Args: cobra.ExactArgs(1), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { port, err := strconv.Atoi(args[0]) if err != nil { @@ -25,7 +25,7 @@ var portForwardCmd = &cobra.Command{ errChan := make(chan error) go func() { - errChan <- defaultPortForwardCmd.ForwardPublicPort(workspaceId, projectName, uint16(port), uint16(port)) + errChan <- defaultPortForwardCmd.ForwardPublicPort(targetId, projectName, uint16(port), uint16(port)) }() for { diff --git a/pkg/cmd/workspacemode/git_cred.go b/pkg/cmd/agentmode/git_cred.go similarity index 92% rename from pkg/cmd/workspacemode/git_cred.go rename to pkg/cmd/agentmode/git_cred.go index 572d9659f8..c5d6013382 100644 --- a/pkg/cmd/workspacemode/git_cred.go +++ b/pkg/cmd/agentmode/git_cred.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "bufio" @@ -37,14 +37,14 @@ var gitCredCmd = &cobra.Command{ return err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } var gitProviderConfigId *string - for _, project := range workspace.Projects { + for _, project := range target.Projects { if project.Name == projectName { gitProviderConfigId = project.GitProviderConfigId break diff --git a/pkg/cmd/workspacemode/info.go b/pkg/cmd/agentmode/info.go similarity index 69% rename from pkg/cmd/workspacemode/info.go rename to pkg/cmd/agentmode/info.go index 10137d2a50..b1752aed25 100644 --- a/pkg/cmd/workspacemode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -1,14 +1,14 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - "github.com/daytonaio/daytona/pkg/views/workspace/info" + "github.com/daytonaio/daytona/pkg/views/target/info" "github.com/spf13/cobra" ) @@ -17,26 +17,26 @@ var infoCmd = &cobra.Command{ Short: "Show project info", Aliases: []string{"view", "inspect"}, Args: cobra.ExactArgs(0), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var workspace *apiclient.WorkspaceDTO + var target *apiclient.TargetDTO - workspace, err := apiclient_util.GetWorkspace(workspaceId, true) + target, err := apiclient_util.GetTarget(targetId, true) if err != nil { return err } - if workspace == nil { + if target == nil { return nil } if format.FormatFlag != "" { - formattedData := format.NewFormatter(workspace) + formattedData := format.NewFormatter(target) formattedData.Print() return nil } - info.Render(workspace, "", false) + info.Render(target, "", false) return nil }, } diff --git a/pkg/cmd/workspacemode/restart.go b/pkg/cmd/agentmode/restart.go similarity index 59% rename from pkg/cmd/workspacemode/restart.go rename to pkg/cmd/agentmode/restart.go index 466c6d47b4..25b364fee9 100644 --- a/pkg/cmd/workspacemode/restart.go +++ b/pkg/cmd/agentmode/restart.go @@ -1,14 +1,14 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "fmt" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient" - workspace_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace" + target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) @@ -17,22 +17,22 @@ var restartCmd = &cobra.Command{ Use: "restart", Short: "Restart the project", Args: cobra.NoArgs, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { apiClient, err := apiclient.GetApiClient(nil) if err != nil { return err } - err = workspace_cmd.RestartWorkspace(apiClient, workspaceId, projectName) + err = target_cmd.RestartTarget(apiClient, targetId, projectName) if err != nil { return err } if projectName != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' successfully restarted", projectName, workspaceId)) + views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully restarted", projectName, targetId)) } else { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully restarted", workspaceId)) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) } return nil }, diff --git a/pkg/cmd/workspacemode/start.go b/pkg/cmd/agentmode/start.go similarity index 76% rename from pkg/cmd/workspacemode/start.go rename to pkg/cmd/agentmode/start.go index 2473068e82..b74a96d152 100644 --- a/pkg/cmd/workspacemode/start.go +++ b/pkg/cmd/agentmode/start.go @@ -1,12 +1,12 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient" - workspace_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace" + target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) @@ -15,14 +15,14 @@ var startCmd = &cobra.Command{ Use: "start", Short: "Start the project", Args: cobra.NoArgs, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { apiClient, err := apiclient.GetApiClient(nil) if err != nil { return err } - err = workspace_cmd.StartWorkspace(apiClient, workspaceId, projectName) + err = target_cmd.StartTarget(apiClient, targetId, projectName) if err != nil { return err } diff --git a/pkg/cmd/workspacemode/stop.go b/pkg/cmd/agentmode/stop.go similarity index 60% rename from pkg/cmd/workspacemode/stop.go rename to pkg/cmd/agentmode/stop.go index f11e885ece..a6efb39b1f 100644 --- a/pkg/cmd/workspacemode/stop.go +++ b/pkg/cmd/agentmode/stop.go @@ -1,14 +1,14 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspacemode +package agentmode import ( "fmt" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient" - workspace_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace" + target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) @@ -17,22 +17,22 @@ var stopCmd = &cobra.Command{ Use: "stop", Short: "Stop the project", Args: cobra.NoArgs, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { apiClient, err := apiclient.GetApiClient(nil) if err != nil { return err } - err = workspace_cmd.StopWorkspace(apiClient, workspaceId, projectName) + err = target_cmd.StopTarget(apiClient, targetId, projectName) if err != nil { return err } if projectName != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' successfully stopped", projectName, workspaceId)) + views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully stopped", projectName, targetId)) } else { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully stopped", workspaceId)) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) } return nil }, diff --git a/pkg/cmd/build/build.go b/pkg/cmd/build/build.go index 877da28a89..d8b128b0eb 100644 --- a/pkg/cmd/build/build.go +++ b/pkg/cmd/build/build.go @@ -12,7 +12,7 @@ var BuildCmd = &cobra.Command{ Use: "build", Aliases: []string{"builds"}, Short: "Manage builds", - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, } func init() { diff --git a/pkg/cmd/build/delete.go b/pkg/cmd/build/delete.go index e9400d1577..f9426d8ae6 100644 --- a/pkg/cmd/build/delete.go +++ b/pkg/cmd/build/delete.go @@ -9,8 +9,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/info.go b/pkg/cmd/build/info.go index 7af105a0be..8bbe78687e 100644 --- a/pkg/cmd/build/info.go +++ b/pkg/cmd/build/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/build/info" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index 143b9162b8..d4e23ba16f 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index d4422f1232..d0e9dae270 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -11,9 +11,9 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/daytonaio/daytona/pkg/views/target/selection" "github.com/spf13/cobra" ) @@ -45,7 +45,7 @@ var buildRunCmd = &cobra.Command{ return errors.New("The chosen project config does not have a build configuration") } - chosenBranch, err := workspace_util.GetBranchFromProjectConfig(projectConfig, apiClient, 0) + chosenBranch, err := target_util.GetBranchFromProjectConfig(projectConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 1d3ef80341..6388f58df7 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -26,9 +26,9 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/projectconfig" . "github.com/daytonaio/daytona/pkg/cmd/provider" . "github.com/daytonaio/daytona/pkg/cmd/server" + . "github.com/daytonaio/daytona/pkg/cmd/target" . "github.com/daytonaio/daytona/pkg/cmd/targetconfig" . "github.com/daytonaio/daytona/pkg/cmd/telemetry" - . "github.com/daytonaio/daytona/pkg/cmd/workspace" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/telemetry" @@ -49,7 +49,7 @@ var rootCmd = &cobra.Command{ } func Execute() error { - rootCmd.AddGroup(&cobra.Group{ID: WORKSPACE_GROUP, Title: "Workspaces & Projects"}) + rootCmd.AddGroup(&cobra.Group{ID: TARGET_GROUP, Title: "Targets & Projects"}) rootCmd.AddGroup(&cobra.Group{ID: SERVER_GROUP, Title: "Server"}) rootCmd.AddGroup(&cobra.Group{ID: PROFILE_GROUP, Title: "Profile"}) @@ -211,7 +211,7 @@ func GetCmdTelemetryData(cmd *cobra.Command, flags []string) map[string]interfac } source := telemetry.CLI_SOURCE - if internal.WorkspaceMode() { + if internal.AgentMode() { source = telemetry.CLI_PROJECT_SOURCE } diff --git a/pkg/cmd/gitprovider/delete.go b/pkg/cmd/gitprovider/delete.go index af357b0db3..433566896c 100644 --- a/pkg/cmd/gitprovider/delete.go +++ b/pkg/cmd/gitprovider/delete.go @@ -11,8 +11,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/gitprovider/update.go b/pkg/cmd/gitprovider/update.go index 15da83e337..fd985318d8 100644 --- a/pkg/cmd/gitprovider/update.go +++ b/pkg/cmd/gitprovider/update.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/logs.go b/pkg/cmd/logs.go index b68113277c..d021e39380 100644 --- a/pkg/cmd/logs.go +++ b/pkg/cmd/logs.go @@ -12,18 +12,18 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/daytonaio/daytona/pkg/views/target/selection" "github.com/spf13/cobra" ) var followFlag bool -var workspaceFlag bool +var targetFlag bool var logsCmd = &cobra.Command{ - Use: "logs [WORKSPACE] [PROJECT_NAME]", - Short: "View logs for a workspace/project", + Use: "logs [TARGET] [PROJECT_NAME]", + Short: "View logs for a target/project", Args: cobra.RangeArgs(0, 2), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, Aliases: []string{"lg", "log"}, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -37,42 +37,42 @@ var logsCmd = &cobra.Command{ return err } - var workspace *apiclient.WorkspaceDTO + var target *apiclient.TargetDTO apiClient, err := apiclient_util.GetApiClient(&activeProfile) if err != nil { return err } var ( - showWorkspaceLogs = true - projectNames []string + showTargetLogs = true + projectNames []string ) if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views.RenderInfoMessage("The workspace list is empty. Start off by running 'daytona create'.") + if len(targetList) == 0 { + views.RenderInfoMessage("The target list is empty. Start off by running 'daytona create'.") return nil } - workspace = selection.GetWorkspaceFromPrompt(workspaceList, "Get Logs For") + target = selection.GetTargetFromPrompt(targetList, "Get Logs For") } else { - workspace, err = apiclient_util.GetWorkspace(args[0], false) + target, err = apiclient_util.GetTarget(args[0], false) if err != nil { return err } } - if workspace == nil { - return errors.New("workspace not found") - } else if len(workspace.Projects) == 0 { - return errors.New("no projects found in workspace") + if target == nil { + return errors.New("target not found") + } else if len(target.Projects) == 0 { + return errors.New("no projects found in target") } if len(args) == 2 { - projects := util.ArrayMap(workspace.Projects, func(p apiclient.Project) string { + projects := util.ArrayMap(target.Projects, func(p apiclient.Project) string { return p.Name }) var found bool @@ -83,21 +83,21 @@ var logsCmd = &cobra.Command{ } } if !found { - return errors.New("project not found in workspace") + return errors.New("project not found in target") } projectNames = append(projectNames, args[1]) - if workspaceFlag { - showWorkspaceLogs = true + if targetFlag { + showTargetLogs = true } else { - showWorkspaceLogs = false + showTargetLogs = false } - } else if !workspaceFlag { - projectNames = util.ArrayMap(workspace.Projects, func(p apiclient.Project) string { + } else if !targetFlag { + projectNames = util.ArrayMap(target.Projects, func(p apiclient.Project) string { return p.Name }) } - apiclient_util.ReadWorkspaceLogs(ctx, activeProfile, workspace.Id, projectNames, followFlag, showWorkspaceLogs, nil) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, followFlag, showTargetLogs, nil) return nil }, @@ -105,5 +105,5 @@ var logsCmd = &cobra.Command{ func init() { logsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") - logsCmd.Flags().BoolVarP(&workspaceFlag, "workspace", "w", false, "View workspace logs") + logsCmd.Flags().BoolVarP(&targetFlag, "target", "w", false, "View target logs") } diff --git a/pkg/cmd/ports/forward.go b/pkg/cmd/ports/forward.go index f911e9a791..95df6c0b3e 100644 --- a/pkg/cmd/ports/forward.go +++ b/pkg/cmd/ports/forward.go @@ -24,13 +24,13 @@ import ( ) var publicPreview bool -var workspaceId string +var targetId string var projectName string var PortForwardCmd = &cobra.Command{ - Use: "forward [PORT] [WORKSPACE] [PROJECT]", + Use: "forward [PORT] [TARGET] [PROJECT]", Short: "Forward a port from a project to your local machine", - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, Args: cobra.RangeArgs(2, 3), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() @@ -46,22 +46,22 @@ var PortForwardCmd = &cobra.Command{ if err != nil { return err } - workspace, err := apiclient.GetWorkspace(args[1], true) + target, err := apiclient.GetTarget(args[1], true) if err != nil { return err } - workspaceId = workspace.Id + targetId = target.Id if len(args) == 3 { projectName = args[2] } else { - projectName, err = apiclient.GetFirstWorkspaceProjectName(workspaceId, projectName, nil) + projectName, err = apiclient.GetFirstProjectName(targetId, projectName, nil) if err != nil { return err } } - hostPort, errChan := tailscale.ForwardPort(workspaceId, projectName, uint16(port), activeProfile) + hostPort, errChan := tailscale.ForwardPort(targetId, projectName, uint16(port), activeProfile) if hostPort == nil { if err = <-errChan; err != nil { @@ -76,7 +76,7 @@ var PortForwardCmd = &cobra.Command{ if publicPreview { go func() { - errChan <- ForwardPublicPort(workspaceId, projectName, *hostPort, uint16(port)) + errChan <- ForwardPublicPort(targetId, projectName, *hostPort, uint16(port)) }() } @@ -93,7 +93,7 @@ func init() { PortForwardCmd.Flags().BoolVar(&publicPreview, "public", false, "Should be port be available publicly via an URL") } -func ForwardPublicPort(workspaceId, projectName string, hostPort, targetPort uint16) error { +func ForwardPublicPort(targetId, projectName string, hostPort, targetPort uint16) error { views.RenderInfoMessage("Forwarding port to a public URL...") apiClient, err := apiclient.GetApiClient(nil) @@ -107,7 +107,7 @@ func ForwardPublicPort(workspaceId, projectName string, hostPort, targetPort uin } h := fnv.New64() - h.Write([]byte(fmt.Sprintf("%s-%s-%s", workspaceId, projectName, serverConfig.Id))) + h.Write([]byte(fmt.Sprintf("%s-%s-%s", targetId, projectName, serverConfig.Id))) subDomain := fmt.Sprintf("%d-%s", targetPort, base64.RawURLEncoding.EncodeToString([]byte(fmt.Sprint(h.Sum64())))) diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/add.go index 5a1bfeb080..2f609ecc9a 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/add.go @@ -14,10 +14,10 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" "github.com/daytonaio/daytona/pkg/cmd/projectconfig" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/daytonaio/daytona/pkg/views/target/selection" "github.com/spf13/cobra" ) @@ -75,7 +75,7 @@ var prebuildAddCmd = &cobra.Command{ return errors.New("The chosen project config does not have a build configuration") } - chosenBranch, err := workspace_util.GetBranchFromProjectConfig(projectConfig, apiClient, 0) + chosenBranch, err := target_util.GetBranchFromProjectConfig(projectConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index 1c900b577d..b17c4856a5 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -10,8 +10,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index ffaad2a3fb..228bc413bb 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/prebuild/info" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/prebuild.go b/pkg/cmd/prebuild/prebuild.go index 63e2d11421..1cf24600bb 100644 --- a/pkg/cmd/prebuild/prebuild.go +++ b/pkg/cmd/prebuild/prebuild.go @@ -12,7 +12,7 @@ var PrebuildCmd = &cobra.Command{ Use: "prebuild", Aliases: []string{"pb", "prebuilds"}, Short: "Manage prebuilds", - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, } func init() { diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index 047e0de620..0c21a5b3ba 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/build" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/profiledata/env/env.go b/pkg/cmd/profiledata/env/env.go index d22ea3d209..045e17796a 100644 --- a/pkg/cmd/profiledata/env/env.go +++ b/pkg/cmd/profiledata/env/env.go @@ -10,7 +10,7 @@ import ( var EnvCmd = &cobra.Command{ Use: "env", - Short: "Manage profile environment variables that are added to all workspaces", + Short: "Manage profile environment variables that are added to all targets and projects", GroupID: util.PROFILE_GROUP, } diff --git a/pkg/cmd/projectconfig/add.go b/pkg/cmd/projectconfig/add.go index ce1d3d003d..904ea442c1 100644 --- a/pkg/cmd/projectconfig/add.go +++ b/pkg/cmd/projectconfig/add.go @@ -12,11 +12,11 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/create" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" "github.com/spf13/cobra" ) @@ -66,7 +66,7 @@ var projectConfigAddCmd = &cobra.Command{ } func RunProjectConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.ProjectConfig, error) { - if workspace_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) { + if target_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) { return nil, errors.New("please provide the repository URL in order to set up custom project config details through the CLI") } @@ -88,7 +88,7 @@ func RunProjectConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apic DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - createDtos, err = workspace_util.GetProjectsCreationDataFromPrompt(workspace_util.ProjectsDataPromptConfig{ + createDtos, err = target_util.GetProjectsCreationDataFromPrompt(target_util.ProjectsDataPromptConfig{ UserGitProviders: gitProviders, Manual: *projectConfigurationFlags.Manual, MultiProject: false, @@ -120,7 +120,7 @@ func RunProjectConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apic initialSuggestion := createDtos[0].Name - chosenName := workspace_util.GetSuggestedName(initialSuggestion, existingProjectConfigNames) + chosenName := target_util.GetSuggestedName(initialSuggestion, existingProjectConfigNames) submissionFormConfig := create.SubmissionFormConfig{ ChosenName: &chosenName, @@ -208,12 +208,12 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con return nil, apiclient_util.HandleErrorResponse(res, err) } - projectConfigurationFlags.GitProviderConfig, err = workspace_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, projectConfigurationFlags.GitProviderConfig) + projectConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, projectConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } - project, err := workspace_util.GetCreateProjectDtoFromFlags(projectConfigurationFlags) + project, err := target_util.GetCreateProjectDtoFromFlags(projectConfigurationFlags) if err != nil { return nil, err } @@ -222,8 +222,8 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con if nameFlag != "" { name = nameFlag } else { - projectName := workspace_util.GetProjectNameFromRepo(repoUrl) - name = workspace_util.GetSuggestedName(projectName, existingProjectConfigNames) + projectName := target_util.GetProjectNameFromRepo(repoUrl) + name = target_util.GetSuggestedName(projectName, existingProjectConfigNames) } if project.GitProviderConfigId == nil || *project.GitProviderConfigId == "" { @@ -277,7 +277,7 @@ func GetExistingProjectConfigNames(apiClient *apiclient.APIClient) ([]string, er var nameFlag string -var projectConfigurationFlags = workspace_util.ProjectConfigurationFlags{ +var projectConfigurationFlags = target_util.ProjectConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -290,5 +290,5 @@ var projectConfigurationFlags = workspace_util.ProjectConfigurationFlags{ func init() { projectConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the project config name") - workspace_util.AddProjectConfigurationFlags(projectConfigAddCmd, projectConfigurationFlags, false) + target_util.AddProjectConfigurationFlags(projectConfigAddCmd, projectConfigurationFlags, false) } diff --git a/pkg/cmd/projectconfig/delete.go b/pkg/cmd/projectconfig/delete.go index 3944047917..6f26239e0f 100644 --- a/pkg/cmd/projectconfig/delete.go +++ b/pkg/cmd/projectconfig/delete.go @@ -11,8 +11,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/projectconfig/info.go b/pkg/cmd/projectconfig/info.go index 482e4eb955..c4254c0b3c 100644 --- a/pkg/cmd/projectconfig/info.go +++ b/pkg/cmd/projectconfig/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/projectconfig/info" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/projectconfig/projectconfig.go b/pkg/cmd/projectconfig/projectconfig.go index d5ccdce6f7..4037c2fca1 100644 --- a/pkg/cmd/projectconfig/projectconfig.go +++ b/pkg/cmd/projectconfig/projectconfig.go @@ -12,7 +12,7 @@ var ProjectConfigCmd = &cobra.Command{ Use: "project-config", Short: "Manage project configs", Aliases: []string{"pc"}, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, } func init() { diff --git a/pkg/cmd/projectconfig/setdefault.go b/pkg/cmd/projectconfig/setdefault.go index 242f374e03..61cc31e311 100644 --- a/pkg/cmd/projectconfig/setdefault.go +++ b/pkg/cmd/projectconfig/setdefault.go @@ -9,8 +9,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/projectconfig/update.go b/pkg/cmd/projectconfig/update.go index ff86465609..729465df27 100644 --- a/pkg/cmd/projectconfig/update.go +++ b/pkg/cmd/projectconfig/update.go @@ -11,9 +11,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/create" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 5c7f082d0c..0fb30e3986 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -29,7 +29,7 @@ var forceFlag bool var purgeCmd = &cobra.Command{ Use: "purge", Short: "Purges all Daytona data from the current device", - Long: "Purges all Daytona data from the current device - including all workspaces, configuration files, and SSH files. This command is irreversible.", + Long: "Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var confirmCheck bool @@ -241,5 +241,5 @@ var purgeCmd = &cobra.Command{ func init() { purgeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Execute purge without prompt") - purgeCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete all workspaces by force") + purgeCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete all targets by force") } diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 156f27ec3c..30c91f1fff 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -36,7 +36,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/projectconfig" "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -192,7 +192,7 @@ var ServeCmd = &cobra.Command{ } func GetInstance(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (*server.Server, error) { - wsLogsDir, err := server.GetWorkspaceLogsDir(configDir) + targetLogsDir, err := server.GetTargetLogsDir(configDir) if err != nil { return nil, err } @@ -200,7 +200,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - loggerFactory := logs.NewLoggerFactory(&wsLogsDir, &buildLogsDir) + loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) dbPath, err := getDbPath() if err != nil { @@ -233,7 +233,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - workspaceStore, err := db.NewWorkspaceStore(dbConnection) + targetStore, err := db.NewTargetStore(dbConnection) if err != nil { return nil, err } @@ -323,7 +323,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{ - LogsDir: wsLogsDir, + LogsDir: targetLogsDir, ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), DaytonaDownloadUrl: getDaytonaScriptUrl(c), ServerUrl: headscaleUrl, @@ -342,8 +342,8 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ProviderManager: providerManager, }) - workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ - WorkspaceStore: workspaceStore, + targetService := targets.NewTargetService(targets.TargetServiceConfig{ + TargetStore: targetStore, TargetConfigStore: targetConfigStore, ApiKeyService: apiKeyService, GitProviderService: gitProviderService, @@ -375,7 +375,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ProjectConfigService: projectConfigService, LocalContainerRegistry: localContainerRegistry, ApiKeyService: apiKeyService, - WorkspaceService: workspaceService, + TargetService: targetService, GitProviderService: gitProviderService, ProviderManager: providerManager, ProfileDataService: profileDataService, diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/target/code.go similarity index 51% rename from pkg/cmd/workspace/code.go rename to pkg/cmd/target/code.go index 74e0fb4df3..910ca5271a 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/target/code.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -15,23 +15,24 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/ide" - "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/telemetry" ide_views "github.com/daytonaio/daytona/pkg/views/ide" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var CodeCmd = &cobra.Command{ - Use: "code [WORKSPACE] [PROJECT]", - Short: "Open a workspace in your preferred IDE", + Use: "code [TARGET] [PROJECT]", + Short: "Open a target in your preferred IDE", Args: cobra.RangeArgs(0, 2), Aliases: []string{"open"}, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { @@ -39,11 +40,11 @@ var CodeCmd = &cobra.Command{ } ctx := context.Background() - var workspaceId string + var targetId string var projectName string var providerConfigId *string var ideId string - var workspace *apiclient.WorkspaceDTO + var target *apiclient.TargetDTO activeProfile, err := c.GetActiveProfile() if err != nil { @@ -58,35 +59,35 @@ var CodeCmd = &cobra.Command{ } if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Verbose(true).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) return nil } - workspace = selection.GetWorkspaceFromPrompt(workspaceList, "Open") - if workspace == nil { + target = selection.GetTargetFromPrompt(targetList, "Open") + if target == nil { return nil } - workspaceId = workspace.Id + targetId = target.Id } else { - workspace, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]), true) + target, err = apiclient_util.GetTarget(url.PathEscape(args[0]), true) if err != nil { - if strings.Contains(err.Error(), workspaces.ErrWorkspaceNotFound.Error()) { + if strings.Contains(err.Error(), targets.ErrTargetNotFound.Error()) { log.Debug(err) - return errors.New("workspace not found. You can see all workspace names by running the command `daytona list`") + return errors.New("target not found. You can see all target names by running the command `daytona list`") } return err } - workspaceId = workspace.Id + targetId = target.Id } if len(args) == 0 || len(args) == 1 { - selectedProject, err := selectWorkspaceProject(workspaceId, &activeProfile) + selectedProject, err := selectTargetProject(targetId, &activeProfile) if err != nil { return err } @@ -100,7 +101,7 @@ var CodeCmd = &cobra.Command{ if len(args) == 2 { projectName = args[1] - for _, project := range workspace.Projects { + for _, project := range target.Projects { if project.Name == projectName { providerConfigId = project.GitProviderConfigId break @@ -112,8 +113,8 @@ var CodeCmd = &cobra.Command{ ideId = ideFlag } - if !workspace_util.IsProjectRunning(workspace, projectName) { - wsRunningStatus, err := AutoStartWorkspace(workspace.Name, projectName) + if !target_util.IsProjectRunning(target, projectName) { + wsRunningStatus, err := AutoStartTarget(target.Name, projectName) if err != nil { return err } @@ -124,7 +125,7 @@ var CodeCmd = &cobra.Command{ providerMetadata := "" if ideId != "ssh" { - providerMetadata, err = workspace_util.GetProjectProviderMetadata(workspace, projectName) + providerMetadata, err = target_util.GetProjectProviderMetadata(target, projectName) if err != nil { return err } @@ -137,19 +138,19 @@ var CodeCmd = &cobra.Command{ yesFlag, _ := cmd.Flags().GetBool("yes") ideList := config.GetIdeList() - ide_views.RenderIdeOpeningMessage(workspace.Name, projectName, ideId, ideList) - return openIDE(ideId, activeProfile, workspaceId, projectName, providerMetadata, yesFlag, gpgKey) + ide_views.RenderIdeOpeningMessage(target.Name, projectName, ideId, ideList) + return openIDE(ideId, activeProfile, targetId, projectName, providerMetadata, yesFlag, gpgKey) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { return getProjectNameCompletions(cmd, args, toComplete) } - return getWorkspaceNameCompletions() + return getTargetNameCompletions() }, } -func selectWorkspaceProject(workspaceId string, profile *config.Profile) (*apiclient.Project, error) { +func selectTargetProject(targetId string, profile *config.Profile) (*apiclient.Project, error) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(profile) @@ -157,56 +158,56 @@ func selectWorkspaceProject(workspaceId string, profile *config.Profile) (*apicl return nil, err } - wsInfo, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - if len(wsInfo.Projects) > 1 { - selectedProject := selection.GetProjectFromPrompt(wsInfo.Projects, "Open") + if len(targetInfo.Projects) > 1 { + selectedProject := selection.GetProjectFromPrompt(targetInfo.Projects, "Open") if selectedProject == nil { return nil, nil } return selectedProject, nil - } else if len(wsInfo.Projects) == 1 { - return &wsInfo.Projects[0], nil + } else if len(targetInfo.Projects) == 1 { + return &targetInfo.Projects[0], nil } - return nil, errors.New("no projects found in workspace") + return nil, errors.New("no projects found in target") } -func openIDE(ideId string, activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, yesFlag bool, gpgKey string) error { +func openIDE(ideId string, activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, yesFlag bool, gpgKey string) error { telemetry.AdditionalData["ide"] = ideId switch ideId { case "vscode": - return ide.OpenVSCode(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVSCode(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "code-insiders": - return ide.OpenVSCodeInsiders(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVSCodeInsiders(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "ssh": - return ide.OpenTerminalSsh(activeProfile, workspaceId, projectName, gpgKey, nil) + return ide.OpenTerminalSsh(activeProfile, targetId, projectName, gpgKey, nil) case "browser": - return ide.OpenBrowserIDE(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenBrowserIDE(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "codium": - return ide.OpenVScodium(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVScodium(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "codium-insiders": - return ide.OpenVScodiumInsiders(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVScodiumInsiders(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "cursor": - return ide.OpenCursor(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenCursor(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "jupyter": - return ide.OpenJupyterIDE(activeProfile, workspaceId, projectName, projectProviderMetadata, yesFlag, gpgKey) + return ide.OpenJupyterIDE(activeProfile, targetId, projectName, projectProviderMetadata, yesFlag, gpgKey) case "fleet": - return ide.OpenFleet(activeProfile, workspaceId, projectName, gpgKey) + return ide.OpenFleet(activeProfile, targetId, projectName, gpgKey) case "positron": - return ide.OpenPositron(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenPositron(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) case "zed": - return ide.OpenZed(activeProfile, workspaceId, projectName, gpgKey) + return ide.OpenZed(activeProfile, targetId, projectName, gpgKey) case "windsurf": - return ide.OpenWindsurf(activeProfile, workspaceId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenWindsurf(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) default: _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] if ok { - return ide.OpenJetbrainsIDE(activeProfile, ideId, workspaceId, projectName, gpgKey) + return ide.OpenJetbrainsIDE(activeProfile, ideId, targetId, projectName, gpgKey) } } @@ -228,9 +229,9 @@ func init() { } -func AutoStartWorkspace(workspaceId string, projectName string) (bool, error) { +func AutoStartTarget(targetId string, projectName string) (bool, error) { if !yesFlag { - if !ide_views.RunStartWorkspaceForm(workspaceId) { + if !ide_views.RunStartTargetForm(targetId) { return false, nil } } @@ -240,7 +241,7 @@ func AutoStartWorkspace(workspaceId string, projectName string) (bool, error) { return false, err } - err = StartWorkspace(apiClient, workspaceId, projectName) + err = StartTarget(apiClient, targetId, projectName) if err != nil { return false, err } diff --git a/pkg/cmd/workspace/create.go b/pkg/cmd/target/create.go similarity index 78% rename from pkg/cmd/workspace/create.go rename to pkg/cmd/target/create.go index 635c8e0b98..0dc9784cf9 100644 --- a/pkg/cmd/workspace/create.go +++ b/pkg/cmd/target/create.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -18,17 +18,17 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/daytonaio/daytona/pkg/views" logs_view "github.com/daytonaio/daytona/pkg/views/logs" + "github.com/daytonaio/daytona/pkg/views/target/create" + "github.com/daytonaio/daytona/pkg/views/target/info" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/info" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" - "github.com/daytonaio/daytona/pkg/workspace/project" "github.com/docker/docker/pkg/stringid" log "github.com/sirupsen/logrus" "tailscale.com/tsnet" @@ -40,13 +40,13 @@ import ( var CreateCmd = &cobra.Command{ Use: "create [REPOSITORY_URL | PROJECT_CONFIG_NAME]...", - Short: "Create a workspace", - GroupID: util.WORKSPACE_GROUP, + Short: "Create a target", + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var projects []apiclient.CreateProjectDTO - var workspaceName string - var existingWorkspaceNames []string + var targetName string + var existingTargetNames []string var existingProjectConfigNames []string promptUsingTUI := len(args) == 0 @@ -71,19 +71,19 @@ var CreateCmd = &cobra.Command{ } if nameFlag != "" { - workspaceName = nameFlag + targetName = nameFlag } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - for _, workspaceInfo := range workspaceList { - existingWorkspaceNames = append(existingWorkspaceNames, workspaceInfo.Name) + for _, targetInfo := range targetList { + existingTargetNames = append(existingTargetNames, targetInfo.Name) } if promptUsingTUI { - err = processPrompting(ctx, apiClient, &workspaceName, &projects, existingWorkspaceNames) + err = processPrompting(ctx, apiClient, &targetName, &projects, existingTargetNames) if err != nil { if common.IsCtrlCAbort(err) { return nil @@ -99,13 +99,13 @@ var CreateCmd = &cobra.Command{ initialSuggestion := projects[0].Name - if workspaceName == "" { - workspaceName = workspace_util.GetSuggestedName(initialSuggestion, existingWorkspaceNames) + if targetName == "" { + targetName = target_util.GetSuggestedName(initialSuggestion, existingTargetNames) } } - if workspaceName == "" || len(projects) == 0 { - return errors.New("workspace name and repository urls are required") + if targetName == "" || len(projects) == 0 { + return errors.New("target name and repository urls are required") } projectNames := []string{} @@ -133,7 +133,7 @@ var CreateCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - targetConfig, err := workspace_util.GetTargetConfig(workspace_util.GetTargetConfigParams{ + targetConfig, err := target_util.GetTargetConfig(target_util.GetTargetConfigParams{ Ctx: ctx, ApiClient: apiClient, TargetConfigs: targetConfigs, @@ -171,11 +171,11 @@ var CreateCmd = &cobra.Command{ id = stringid.TruncateID(id) logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadWorkspaceLogs(logsContext, activeProfile, id, projectNames, true, true, nil) + go apiclient_util.ReadTargetLogs(logsContext, activeProfile, id, projectNames, true, true, nil) - createdWorkspace, res, err := apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(apiclient.CreateWorkspaceDTO{ + createdTarget, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(apiclient.CreateTargetDTO{ Id: id, - Name: workspaceName, + Name: targetName, TargetConfig: targetConfig.Name, Projects: projects, }).Execute() @@ -188,7 +188,7 @@ var CreateCmd = &cobra.Command{ log.Warn(err) } - err = waitForDial(createdWorkspace, &activeProfile, tsConn, gpgKey) + err = waitForDial(createdTarget, &activeProfile, tsConn, gpgKey) if err != nil { stopLogs() return err @@ -199,7 +199,7 @@ var CreateCmd = &cobra.Command{ // Make sure terminal cursor is reset fmt.Print("\033[?25h") - wsInfo, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceName).Verbose(true).Execute() + targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetName).Verbose(true).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -219,22 +219,22 @@ var CreateCmd = &cobra.Command{ } fmt.Println() - info.Render(wsInfo, chosenIde.Name, false) + info.Render(targetInfo, chosenIde.Name, false) if noIdeFlag { views.RenderCreationInfoMessage("Run 'daytona code' when you're ready to start developing") return nil } - views.RenderCreationInfoMessage(fmt.Sprintf("Opening the workspace in %s ...", chosenIde.Name)) + views.RenderCreationInfoMessage(fmt.Sprintf("Opening the target in %s ...", chosenIde.Name)) - projectName := wsInfo.Projects[0].Name - providerMetadata, err := workspace_util.GetProjectProviderMetadata(wsInfo, projectName) + projectName := targetInfo.Projects[0].Name + providerMetadata, err := target_util.GetProjectProviderMetadata(targetInfo, projectName) if err != nil { return err } - return openIDE(chosenIdeId, activeProfile, createdWorkspace.Id, wsInfo.Projects[0].Name, providerMetadata, yesFlag, gpgKey) + return openIDE(chosenIdeId, activeProfile, createdTarget.Id, targetInfo.Projects[0].Name, providerMetadata, yesFlag, gpgKey) }, } @@ -244,7 +244,7 @@ var noIdeFlag bool var blankFlag bool var multiProjectFlag bool -var projectConfigurationFlags = workspace_util.ProjectConfigurationFlags{ +var projectConfigurationFlags = target_util.ProjectConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -263,20 +263,20 @@ func init() { } ideListStr := strings.Join(ids, ", ") - CreateCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace name") + CreateCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the target name") CreateCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) CreateCmd.Flags().StringVarP(&targetConfigNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank project without using existing configurations") - CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the workspace in the IDE after workspace creation") - CreateCmd.Flags().BoolVar(&multiProjectFlag, "multi-project", false, "Workspace with multiple projects/repos") + CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the target in the IDE after target creation") + CreateCmd.Flags().BoolVar(&multiProjectFlag, "multi-project", false, "Target with multiple projects/repos") CreateCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") CreateCmd.Flags().StringSliceVar(projectConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the projects") - workspace_util.AddProjectConfigurationFlags(CreateCmd, projectConfigurationFlags, true) + target_util.AddProjectConfigurationFlags(CreateCmd, projectConfigurationFlags, true) } -func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, workspaceName *string, projects *[]apiclient.CreateProjectDTO, workspaceNames []string) error { - if workspace_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) || (projectConfigurationFlags.Branches != nil && len(*projectConfigurationFlags.Branches) > 0) { +func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targetName *string, projects *[]apiclient.CreateProjectDTO, targetNames []string) error { + if target_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) || (projectConfigurationFlags.Branches != nil && len(*projectConfigurationFlags.Branches) > 0) { return errors.New("please provide the repository URL in order to set up custom project details through the CLI") } @@ -302,7 +302,7 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, works DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - *projects, err = workspace_util.GetProjectsCreationDataFromPrompt(workspace_util.ProjectsDataPromptConfig{ + *projects, err = target_util.GetProjectsCreationDataFromPrompt(target_util.ProjectsDataPromptConfig{ UserGitProviders: gitProviders, ProjectConfigs: projectConfigs, Manual: *projectConfigurationFlags.Manual, @@ -318,16 +318,16 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, works initialSuggestion := (*projects)[0].Name - suggestedName := workspace_util.GetSuggestedName(initialSuggestion, workspaceNames) + suggestedName := target_util.GetSuggestedName(initialSuggestion, targetNames) dedupProjectNames(projects) submissionFormConfig := create.SubmissionFormConfig{ - ChosenName: workspaceName, + ChosenName: targetName, SuggestedName: suggestedName, - ExistingNames: workspaceNames, + ExistingNames: targetNames, ProjectList: projects, - NameLabel: "Workspace", + NameLabel: "Target", Defaults: projectDefaults, } @@ -345,7 +345,7 @@ func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apic return nil, fmt.Errorf("no repository URLs provided") } - if len(repoUrls) > 1 && workspace_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) { + if len(repoUrls) > 1 && target_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) { return nil, fmt.Errorf("can't set custom project configuration properties for multiple projects") } @@ -385,7 +385,7 @@ func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apic return nil, fmt.Errorf("failed to parse the URL or fetch the project config for '%s'", repoUrl) } - existingProjectConfigName, err := workspace_util.AddProjectFromConfig(projectConfig, apiClient, projects, branch) + existingProjectConfigName, err := target_util.AddProjectFromConfig(projectConfig, apiClient, projects, branch) if err != nil { return nil, err } @@ -408,7 +408,7 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API projectConfig, res, err := apiClient.ProjectConfigAPI.GetDefaultProjectConfig(ctx, encodedURLParam).Execute() if err == nil { projectConfig.GitProviderConfigId = projectConfigurationFlags.GitProviderConfig - return workspace_util.AddProjectFromConfig(projectConfig, apiClient, projects, branch) + return target_util.AddProjectFromConfig(projectConfig, apiClient, projects, branch) } if res.StatusCode != http.StatusNotFound { @@ -424,12 +424,12 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API return nil, apiclient_util.HandleErrorResponse(res, err) } - projectName, err := workspace_util.GetSanitizedProjectName(repo.Name) + projectName, err := target_util.GetSanitizedProjectName(repo.Name) if err != nil { return nil, err } - projectConfigurationFlags.GitProviderConfig, err = workspace_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, projectConfigurationFlags.GitProviderConfig) + projectConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, projectConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } @@ -454,7 +454,7 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API } } - project, err := workspace_util.GetCreateProjectDtoFromFlags(projectConfigurationFlags) + project, err := target_util.GetCreateProjectDtoFromFlags(projectConfigurationFlags) if err != nil { return nil, err } @@ -469,14 +469,14 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API return nil, nil } -func waitForDial(workspace *apiclient.Workspace, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { - if workspace.TargetConfig == "local" && (activeProfile != nil && activeProfile.Id == "default") { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspace.Id, workspace.Projects[0].Name, gpgKey) +func waitForDial(target *apiclient.Target, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { + if target.TargetConfig == "local" && (activeProfile != nil && activeProfile.Id == "default") { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, target.Id, target.Projects[0].Name, gpgKey) if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspace.Id, workspace.Projects[0].Name) + projectHostname := config.GetProjectHostname(activeProfile.Id, target.Id, target.Projects[0].Name) for { sshCommand := exec.Command("ssh", projectHostname, "daytona", "version") @@ -499,7 +499,7 @@ func waitForDial(workspace *apiclient.Workspace, activeProfile *config.Profile, go func() { for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(workspace.Id, workspace.Projects[0].Name), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(target.Id, target.Projects[0].Name), ssh_config.SSH_PORT)) if err == nil { connectChan <- dialConn.Close() return diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/target/delete.go similarity index 53% rename from pkg/cmd/workspace/delete.go rename to pkg/cmd/target/delete.go index 75b0761321..553535482b 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/target/delete.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -14,8 +14,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -24,15 +24,15 @@ var yesFlag bool var forceFlag bool var DeleteCmd = &cobra.Command{ - Use: "delete [WORKSPACE]", - Short: "Delete a workspace", - GroupID: util.WORKSPACE_GROUP, + Use: "delete [TARGET]", + Short: "Delete a target", + GroupID: util.TARGET_GROUP, Aliases: []string{"remove", "rm"}, RunE: func(cmd *cobra.Command, args []string) error { if allFlag { if yesFlag { - fmt.Println("Deleting all workspaces.") - err := DeleteAllWorkspaces(forceFlag) + fmt.Println("Deleting all targets.") + err := DeleteAllTargets(forceFlag) if err != nil { return err } @@ -40,8 +40,8 @@ var DeleteCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title("Delete all workspaces?"). - Description("Are you sure you want to delete all workspaces?"). + Title("Delete all targets?"). + Description("Are you sure you want to delete all targets?"). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -52,7 +52,7 @@ var DeleteCmd = &cobra.Command{ } if yesFlag { - err := DeleteAllWorkspaces(forceFlag) + err := DeleteAllTargets(forceFlag) if err != nil { return err } @@ -65,41 +65,41 @@ var DeleteCmd = &cobra.Command{ ctx := context.Background() - var workspaceDeleteList = []*apiclient.WorkspaceDTO{} - var workspaceDeleteListNames = []string{} + var targetDeleteList = []*apiclient.TargetDTO{} + var targetDeleteListNames = []string{} apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(false) + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(false) return nil } - workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, "Delete") - for _, workspace := range workspaceDeleteList { - workspaceDeleteListNames = append(workspaceDeleteListNames, workspace.Name) + targetDeleteList = selection.GetTargetsFromPrompt(targetList, "Delete") + for _, target := range targetDeleteList { + targetDeleteListNames = append(targetDeleteListNames, target.Name) } } else { for _, arg := range args { - workspace, err := apiclient_util.GetWorkspace(arg, false) + target, err := apiclient_util.GetTarget(arg, false) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue } - workspaceDeleteList = append(workspaceDeleteList, workspace) - workspaceDeleteListNames = append(workspaceDeleteListNames, workspace.Name) + targetDeleteList = append(targetDeleteList, target) + targetDeleteListNames = append(targetDeleteListNames, target.Name) } } - if len(workspaceDeleteList) == 0 { + if len(targetDeleteList) == 0 { return nil } @@ -107,8 +107,8 @@ var DeleteCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title(fmt.Sprintf("Delete workspace(s): [%s]?", strings.Join(workspaceDeleteListNames, ", "))). - Description(fmt.Sprintf("Are you sure you want to delete the workspace(s): [%s]?", strings.Join(workspaceDeleteListNames, ", "))). + Title(fmt.Sprintf("Delete target(s): [%s]?", strings.Join(targetDeleteListNames, ", "))). + Description(fmt.Sprintf("Are you sure you want to delete the target(s): [%s]?", strings.Join(targetDeleteListNames, ", "))). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -122,54 +122,54 @@ var DeleteCmd = &cobra.Command{ if !yesFlag { fmt.Println("Operation canceled.") } else { - for _, workspace := range workspaceDeleteList { - err := RemoveWorkspace(ctx, apiClient, workspace, forceFlag) + for _, target := range targetDeleteList { + err := RemoveTarget(ctx, apiClient, target, forceFlag) if err != nil { - log.Error(fmt.Sprintf("[ %s ] : %v", workspace.Name, err)) + log.Error(fmt.Sprintf("[ %s ] : %v", target.Name, err)) } - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully deleted", workspace.Name)) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully deleted", target.Name)) } } return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getWorkspaceNameCompletions() + return getTargetNameCompletions() }, } func init() { - DeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspaces") + DeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all targets") DeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") - DeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a workspace by force") + DeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a target by force") } -func DeleteAllWorkspaces(force bool) error { +func DeleteAllTargets(force bool) error { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - for _, workspace := range workspaceList { - err := RemoveWorkspace(ctx, apiClient, &workspace, force) + for _, target := range targetList { + err := RemoveTarget(ctx, apiClient, &target, force) if err != nil { - log.Errorf("Failed to delete workspace %s: %v", workspace.Name, err) + log.Errorf("Failed to delete target %s: %v", target.Name, err) continue } - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' successfully deleted", workspace.Name)) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully deleted", target.Name)) } return nil } -func RemoveWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspace *apiclient.WorkspaceDTO, force bool) error { - message := fmt.Sprintf("Deleting workspace %s", workspace.Name) +func RemoveTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO, force bool) error { + message := fmt.Sprintf("Deleting target %s", target.Name) err := views_util.WithInlineSpinner(message, func() error { - res, err := apiClient.WorkspaceAPI.RemoveWorkspace(ctx, workspace.Id).Force(force).Execute() + res, err := apiClient.TargetAPI.RemoveTarget(ctx, target.Id).Force(force).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -183,11 +183,9 @@ func RemoveWorkspace(ctx context.Context, apiClient *apiclient.APIClient, worksp return err } - for _, project := range workspace.Projects { - err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspace.Id, project.Name) - if err != nil { - return err - } + err = config.RemoveTargetSshEntries(activeProfile.Id, target.Id) + if err != nil { + return err } return nil }) diff --git a/pkg/cmd/workspace/info.go b/pkg/cmd/target/info.go similarity index 63% rename from pkg/cmd/workspace/info.go rename to pkg/cmd/target/info.go index 16611c1df4..da68e06ce8 100644 --- a/pkg/cmd/workspace/info.go +++ b/pkg/cmd/target/info.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -10,18 +10,18 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/views/target/info" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/info" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) var InfoCmd = &cobra.Command{ - Use: "info [WORKSPACE]", - Short: "Show workspace info", + Use: "info [TARGET]", + Short: "Show target info", Aliases: []string{"view", "inspect"}, Args: cobra.RangeArgs(0, 1), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -30,16 +30,16 @@ var InfoCmd = &cobra.Command{ return err } - var workspace *apiclient.WorkspaceDTO + var target *apiclient.TargetDTO if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Verbose(true).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) return nil } @@ -47,33 +47,33 @@ var InfoCmd = &cobra.Command{ format.UnblockStdOut() } - workspace = selection.GetWorkspaceFromPrompt(workspaceList, "View") + target = selection.GetTargetFromPrompt(targetList, "View") if format.FormatFlag != "" { format.BlockStdOut() } } else { - workspace, err = apiclient_util.GetWorkspace(args[0], true) + target, err = apiclient_util.GetTarget(args[0], true) if err != nil { return err } } - if workspace == nil { + if target == nil { return nil } if format.FormatFlag != "" { - formattedData := format.NewFormatter(workspace) + formattedData := format.NewFormatter(target) formattedData.Print() return nil } - info.Render(workspace, "", false) + info.Render(target, "", false) return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getWorkspaceNameCompletions() + return getTargetNameCompletions() }, } diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/target/list.go similarity index 78% rename from pkg/cmd/workspace/list.go rename to pkg/cmd/target/list.go index d37d62e8c7..1abf11ccf8 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/target/list.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - list_view "github.com/daytonaio/daytona/pkg/views/workspace/list" + list_view "github.com/daytonaio/daytona/pkg/views/target/list" "github.com/spf13/cobra" ) @@ -19,10 +19,10 @@ var verbose bool var ListCmd = &cobra.Command{ Use: "list", - Short: "List workspaces", + Short: "List targets", Args: cobra.ExactArgs(0), Aliases: []string{"ls"}, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var specifyGitProviders bool @@ -32,7 +32,7 @@ var ListCmd = &cobra.Command{ return err } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(verbose).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Verbose(verbose).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) @@ -48,7 +48,7 @@ var ListCmd = &cobra.Command{ } if format.FormatFlag != "" { - formattedData := format.NewFormatter(workspaceList) + formattedData := format.NewFormatter(targetList) formattedData.Print() return nil } @@ -63,7 +63,7 @@ var ListCmd = &cobra.Command{ return err } - list_view.ListWorkspaces(workspaceList, specifyGitProviders, verbose, activeProfile.Name) + list_view.ListTargets(targetList, specifyGitProviders, verbose, activeProfile.Name) return nil }, diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/target/restart.go similarity index 52% rename from pkg/cmd/workspace/restart.go rename to pkg/cmd/target/restart.go index 200f979c3a..38dcad80fe 100644 --- a/pkg/cmd/workspace/restart.go +++ b/pkg/cmd/target/restart.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -11,20 +11,20 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) var restartProjectFlag string var RestartCmd = &cobra.Command{ - Use: "restart [WORKSPACE]", - Short: "Restart a workspace", + Use: "restart [TARGET]", + Short: "Restart a target", Args: cobra.RangeArgs(0, 1), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var workspaceId string + var targetId string ctx := context.Background() @@ -42,49 +42,49 @@ var RestartCmd = &cobra.Command{ return nil } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) return nil } - workspace := selection.GetWorkspaceFromPrompt(workspaceList, "Restart") - if workspace == nil { + target := selection.GetTargetFromPrompt(targetList, "Restart") + if target == nil { return nil } - workspaceId = workspace.Name + targetId = target.Name } else { - workspaceId = args[0] + targetId = args[0] } - err = RestartWorkspace(apiClient, workspaceId, restartProjectFlag) + err = RestartTarget(apiClient, targetId, restartProjectFlag) if err != nil { return err } if restartProjectFlag != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' successfully restarted", restartProjectFlag, workspaceId)) + views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully restarted", restartProjectFlag, targetId)) } else { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully restarted", workspaceId)) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) } return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllWorkspacesByState(WORKSPACE_STATUS_RUNNING) + return getAllTargetsByState(TARGET_STATE_RUNNING) }, } func init() { - RestartCmd.Flags().StringVarP(&restartProjectFlag, "project", "p", "", "Restart a single project in the workspace (project name)") + RestartCmd.Flags().StringVarP(&restartProjectFlag, "project", "p", "", "Restart a single project in the target (project name)") } -func RestartWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName string) error { - err := StopWorkspace(apiClient, workspaceId, projectName) +func RestartTarget(apiClient *apiclient.APIClient, targetId, projectName string) error { + err := StopTarget(apiClient, targetId, projectName) if err != nil { return err } - return StartWorkspace(apiClient, workspaceId, projectName) + return StartTarget(apiClient, targetId, projectName) } diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/target/ssh-proxy.go similarity index 82% rename from pkg/cmd/workspace/ssh-proxy.go rename to pkg/cmd/target/ssh-proxy.go index adedd911ef..fc80fbe0f1 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/target/ssh-proxy.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -16,7 +16,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" @@ -26,7 +26,7 @@ import ( ) var SshProxyCmd = &cobra.Command{ - Use: "ssh-proxy [PROFILE_ID] [WORKSPACE_ID] [PROJECT]", + Use: "ssh-proxy [PROFILE_ID] [TARGET_ID] [PROJECT]", Args: cobra.RangeArgs(2, 3), Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { @@ -36,7 +36,7 @@ var SshProxyCmd = &cobra.Command{ } profileId := args[0] - workspaceId := args[1] + targetId := args[1] projectName := "" profile, err := c.GetProfile(profileId) @@ -47,23 +47,23 @@ var SshProxyCmd = &cobra.Command{ if len(args) == 3 { projectName = args[2] } else { - projectName, err = apiclient.GetFirstWorkspaceProjectName(workspaceId, projectName, &profile) + projectName, err = apiclient.GetFirstProjectName(targetId, projectName, &profile) if err != nil { return err } } - workspace, err := apiclient.GetWorkspace(workspaceId, true) + target, err := apiclient.GetTarget(targetId, true) if err != nil { return err } - if workspace.TargetConfig == "local" && profile.Id == "default" { - // If the workspace is local, we directly access the ssh port through the container - project := workspace.Projects[0] + if target.TargetConfig == "local" && profile.Id == "default" { + // If the target is local, we directly access the ssh port through the container + project := target.Projects[0] if project.Name != projectName { - for _, p := range workspace.Projects { + for _, p := range target.Projects { if p.Name == projectName { project = p break @@ -139,7 +139,7 @@ var SshProxyCmd = &cobra.Command{ errChan := make(chan error) - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(workspaceId, projectName), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(targetId, projectName), ssh_config.SSH_PORT)) if err != nil { return err } diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/target/ssh.go similarity index 78% rename from pkg/cmd/workspace/ssh.go rename to pkg/cmd/target/ssh.go index c4322b0454..2a1f40bb15 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/target/ssh.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -16,11 +16,11 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -31,10 +31,10 @@ var ( ) var SshCmd = &cobra.Command{ - Use: "ssh [WORKSPACE] [PROJECT] [CMD...]", + Use: "ssh [TARGET] [PROJECT] [CMD...]", Short: "SSH into a project using the terminal", Args: cobra.ArbitraryArgs, - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { @@ -47,7 +47,7 @@ var SshCmd = &cobra.Command{ } ctx := context.Background() - var workspace *apiclient.WorkspaceDTO + var target *apiclient.TargetDTO var projectName string var providerConfigId *string @@ -57,29 +57,29 @@ var SshCmd = &cobra.Command{ } if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) return nil } - workspace = selection.GetWorkspaceFromPrompt(workspaceList, "SSH Into") - if workspace == nil { + target = selection.GetTargetFromPrompt(targetList, "SSH Into") + if target == nil { return nil } } else { - workspace, err = apiclient_util.GetWorkspace(args[0], true) + target, err = apiclient_util.GetTarget(args[0], true) if err != nil { return err } } if len(args) == 0 || len(args) == 1 { - selectedProject, err := selectWorkspaceProject(workspace.Id, &activeProfile) + selectedProject, err := selectTargetProject(target.Id, &activeProfile) if err != nil { return err } @@ -92,7 +92,7 @@ var SshCmd = &cobra.Command{ if len(args) >= 2 { projectName = args[1] - for _, project := range workspace.Projects { + for _, project := range target.Projects { if project.Name == projectName { providerConfigId = project.GitProviderConfigId break @@ -101,19 +101,19 @@ var SshCmd = &cobra.Command{ } if edit { - err := editSSHConfig(activeProfile, workspace, projectName) + err := editSSHConfig(activeProfile, target, projectName) if err != nil { return err } return nil } - if !workspace_util.IsProjectRunning(workspace, projectName) { - wsRunningStatus, err := AutoStartWorkspace(workspace.Name, projectName) + if !target_util.IsProjectRunning(target, projectName) { + tgRunningStatus, err := AutoStartTarget(target.Name, projectName) if err != nil { return err } - if !wsRunningStatus { + if !tgRunningStatus { return nil } } @@ -128,7 +128,7 @@ var SshCmd = &cobra.Command{ log.Warn(err) } - return ide.OpenTerminalSsh(activeProfile, workspace.Id, projectName, gpgKey, sshOptions, sshArgs...) + return ide.OpenTerminalSsh(activeProfile, target.Id, projectName, gpgKey, sshOptions, sshArgs...) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) >= 2 { @@ -138,7 +138,7 @@ var SshCmd = &cobra.Command{ return getProjectNameCompletions(cmd, args, toComplete) } - return getWorkspaceNameCompletions() + return getTargetNameCompletions() }, } @@ -148,7 +148,7 @@ func init() { SshCmd.Flags().StringArrayVarP(&sshOptions, "option", "o", []string{}, "Specify SSH options in KEY=VALUE format.") } -func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceDTO, projectName string) error { +func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, projectName string) error { sshDir := filepath.Join(config.SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") sshConfig, err := config.ReadSshConfig(configPath) @@ -156,7 +156,7 @@ func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceD return err } - hostLine := fmt.Sprintf("Host %s", config.GetProjectHostname(activeProfile.Id, workspace.Id, projectName)) + hostLine := fmt.Sprintf("Host %s", config.GetProjectHostname(activeProfile.Id, target.Id, projectName)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(sshConfig) if matchedEntry == "" { @@ -213,7 +213,7 @@ func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceD } if modifiedContent == "" { - err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspace.Id, projectName) + err = config.RemoveTargetSshEntries(activeProfile.Id, target.Id) if err != nil { return err } @@ -237,7 +237,7 @@ func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceD modifiedContent += "\n" } - err = config.UpdateWorkspaceSshEntry(activeProfile.Id, workspace.Id, projectName, modifiedContent) + err = config.UpdateWorkspaceSshEntry(activeProfile.Id, target.Id, projectName, modifiedContent) if err != nil { return err } diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/target/start.go similarity index 55% rename from pkg/cmd/workspace/start.go rename to pkg/cmd/target/start.go index c3e8052974..57ba8c343b 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/target/start.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "context" @@ -12,20 +12,21 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/views" ide_views "github.com/daytonaio/daytona/pkg/views/ide" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -type WorkspaceState string +type TargetState string const ( - WORKSPACE_STATUS_RUNNING WorkspaceState = "Running" - WORKSPACE_STATUS_STOPPED WorkspaceState = "Unavailable" + TARGET_STATE_RUNNING TargetState = "Running" + TARGET_STATE_STOPPED TargetState = "Unavailable" ) var startProjectFlag string @@ -33,12 +34,12 @@ var allFlag bool var codeFlag bool var StartCmd = &cobra.Command{ - Use: "start [WORKSPACE]", - Short: "Start a workspace", + Use: "start [TARGET]", + Short: "Start a target", Args: cobra.RangeArgs(0, 1), - GroupID: util.WORKSPACE_GROUP, + GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var selectedWorkspacesNames []string + var selectedTargetsNames []string var activeProfile config.Profile var ideId string var ideList []config.Ide @@ -53,34 +54,33 @@ var StartCmd = &cobra.Command{ } if allFlag { - return startAllWorkspaces() + return startAllTargets() } if len(args) == 0 { if startProjectFlag != "" { return cmd.Help() } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) return nil } - - selectedWorkspaces := selection.GetWorkspacesFromPrompt(workspaceList, "Start") - for _, workspaces := range selectedWorkspaces { - selectedWorkspacesNames = append(selectedWorkspacesNames, workspaces.Name) + selectedTargets := selection.GetTargetsFromPrompt(targetList, "Start") + for _, targets := range selectedTargets { + selectedTargetsNames = append(selectedTargetsNames, targets.Name) } } else { - selectedWorkspacesNames = append(selectedWorkspacesNames, args[0]) + selectedTargetsNames = append(selectedTargetsNames, args[0]) } - if len(selectedWorkspacesNames) == 1 { - workspaceName := selectedWorkspacesNames[0] - var workspaceId string + if len(selectedTargetsNames) == 1 { + targetName := selectedTargetsNames[0] + var targetId string if codeFlag { c, err := config.GetConfig() if err != nil { @@ -95,16 +95,16 @@ var StartCmd = &cobra.Command{ ideList = config.GetIdeList() ideId = c.DefaultIdeId - wsInfo, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceName).Execute() + targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - workspaceId = wsInfo.Id + targetId = targetInfo.Id if startProjectFlag == "" { - startProjectFlag = wsInfo.Projects[0].Name - providerConfigId = wsInfo.Projects[0].GitProviderConfigId + startProjectFlag = targetInfo.Projects[0].Name + providerConfigId = targetInfo.Projects[0].GitProviderConfigId } else { - for _, project := range wsInfo.Projects { + for _, project := range targetInfo.Projects { if project.Name == startProjectFlag { providerConfigId = project.GitProviderConfigId break @@ -113,14 +113,14 @@ var StartCmd = &cobra.Command{ } if ideId != "ssh" { - projectProviderMetadata, err = workspace_util.GetProjectProviderMetadata(wsInfo, wsInfo.Projects[0].Name) + projectProviderMetadata, err = target_util.GetProjectProviderMetadata(targetInfo, targetInfo.Projects[0].Name) if err != nil { return err } } } - err = StartWorkspace(apiClient, workspaceName, startProjectFlag) + err = StartTarget(apiClient, targetName, startProjectFlag) if err != nil { return err } @@ -130,39 +130,39 @@ var StartCmd = &cobra.Command{ } if startProjectFlag == "" { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' started successfully", workspaceName)) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' started successfully", targetName)) } else { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' started successfully", startProjectFlag, workspaceName)) + views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' started successfully", startProjectFlag, targetName)) if codeFlag { - ide_views.RenderIdeOpeningMessage(workspaceName, startProjectFlag, ideId, ideList) - err = openIDE(ideId, activeProfile, workspaceId, startProjectFlag, projectProviderMetadata, yesFlag, gpgKey) + ide_views.RenderIdeOpeningMessage(targetName, startProjectFlag, ideId, ideList) + err = openIDE(ideId, activeProfile, targetId, startProjectFlag, projectProviderMetadata, yesFlag, gpgKey) if err != nil { return err } } } } else { - for _, workspace := range selectedWorkspacesNames { - err := StartWorkspace(apiClient, workspace, "") + for _, target := range selectedTargetsNames { + err := StartTarget(apiClient, target, "") if err != nil { - log.Errorf("Failed to start workspace %s: %v\n\n", workspace, err) + log.Errorf("Failed to start target %s: %v\n\n", target, err) continue } - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", workspace)) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' started successfully", target)) } } return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllWorkspacesByState(WORKSPACE_STATUS_STOPPED) + return getAllTargetsByState(TARGET_STATE_STOPPED) }, } func init() { - StartCmd.PersistentFlags().StringVarP(&startProjectFlag, "project", "p", "", "Start a single project in the workspace (project name)") - StartCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Start all workspaces") - StartCmd.PersistentFlags().BoolVarP(&codeFlag, "code", "c", false, "Open the workspace in the IDE after workspace start") + StartCmd.PersistentFlags().StringVarP(&startProjectFlag, "project", "p", "", "Start a single project in the target (project name)") + StartCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Start all targets") + StartCmd.PersistentFlags().BoolVarP(&codeFlag, "code", "c", false, "Open the target in the IDE after target start") StartCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") err := StartCmd.RegisterFlagCompletionFunc("project", getProjectNameCompletions) @@ -171,26 +171,26 @@ func init() { } } -func startAllWorkspaces() error { +func startAllTargets() error { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - for _, workspace := range workspaceList { - err := StartWorkspace(apiClient, workspace.Name, "") + for _, target := range targetList { + err := StartTarget(apiClient, target.Name, "") if err != nil { - log.Errorf("Failed to start workspace %s: %v\n\n", workspace.Name, err) + log.Errorf("Failed to start target %s: %v\n\n", target.Name, err) continue } - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", workspace.Name)) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' started successfully", target.Name)) } return nil } @@ -202,63 +202,63 @@ func getProjectNameCompletions(cmd *cobra.Command, args []string, toComplete str return nil, cobra.ShellCompDirectiveDefault } - workspaceId := args[0] - workspace, _, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + targetId := args[0] + target, _, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() if err != nil { return nil, cobra.ShellCompDirectiveDefault } var choices []string - for _, project := range workspace.Projects { + for _, project := range target.Projects { choices = append(choices, project.Name) } return choices, cobra.ShellCompDirectiveDefault } -func getWorkspaceNameCompletions() ([]string, cobra.ShellCompDirective) { +func getTargetNameCompletions() ([]string, cobra.ShellCompDirective) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return nil, cobra.ShellCompDirectiveNoFileComp } - workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, _, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return nil, cobra.ShellCompDirectiveNoFileComp } var choices []string - for _, v := range workspaceList { + for _, v := range targetList { choices = append(choices, v.Name) } return choices, cobra.ShellCompDirectiveNoFileComp } -func getAllWorkspacesByState(state WorkspaceState) ([]string, cobra.ShellCompDirective) { +func getAllTargetsByState(state TargetState) ([]string, cobra.ShellCompDirective) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return nil, cobra.ShellCompDirectiveNoFileComp } - workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, _, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return nil, cobra.ShellCompDirectiveNoFileComp } var choices []string - for _, workspace := range workspaceList { - for _, project := range workspace.Projects { + for _, target := range targetList { + for _, project := range target.Projects { if project.State == nil { continue } - if state == WORKSPACE_STATUS_RUNNING && project.State.Uptime != 0 { - choices = append(choices, workspace.Name) + if state == TARGET_STATE_RUNNING && project.State.Uptime != 0 { + choices = append(choices, target.Name) break } - if state == WORKSPACE_STATUS_STOPPED && project.State.Uptime == 0 { - choices = append(choices, workspace.Name) + if state == TARGET_STATE_STOPPED && project.State.Uptime == 0 { + choices = append(choices, target.Name) break } } @@ -267,7 +267,7 @@ func getAllWorkspacesByState(state WorkspaceState) ([]string, cobra.ShellCompDir return choices, cobra.ShellCompDirectiveNoFileComp } -func StartWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName string) error { +func StartTarget(apiClient *apiclient.APIClient, targetId, projectName string) error { ctx := context.Background() var projectNames []string timeFormat := time.Now().Format("2006-01-02 15:04:05") @@ -286,23 +286,23 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName str return err } - workspace, err := apiclient_util.GetWorkspace(workspaceId, false) + target, err := apiclient_util.GetTarget(targetId, false) if err != nil { return err } if projectName != "" { projectNames = append(projectNames, projectName) } else { - projectNames = util.ArrayMap(workspace.Projects, func(p apiclient.Project) string { + projectNames = util.ArrayMap(target.Projects, func(p apiclient.Project) string { return p.Name }) } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadWorkspaceLogs(logsContext, activeProfile, workspace.Id, projectNames, true, true, &from) + go apiclient_util.ReadTargetLogs(logsContext, activeProfile, target.Id, projectNames, true, true, &from) if projectName == "" { - res, err := apiClient.WorkspaceAPI.StartWorkspace(ctx, workspaceId).Execute() + res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) @@ -311,7 +311,7 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName str stopLogs() return nil } else { - res, err := apiClient.WorkspaceAPI.StartProject(ctx, workspaceId, projectName).Execute() + res, err := apiClient.TargetAPI.StartProject(ctx, targetId, projectName).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go new file mode 100644 index 0000000000..f13a6be34c --- /dev/null +++ b/pkg/cmd/target/stop.go @@ -0,0 +1,188 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + "time" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var stopProjectFlag string + +var StopCmd = &cobra.Command{ + Use: "stop [TARGET]", + Short: "Stop a target", + GroupID: util.TARGET_GROUP, + Args: cobra.RangeArgs(0, 1), + RunE: func(cmd *cobra.Command, args []string) error { + timeFormat := time.Now().Format("2006-01-02 15:04:05") + from, err := time.Parse("2006-01-02 15:04:05", timeFormat) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + if allFlag { + return stopAllTargets(activeProfile, from) + } + + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if len(args) == 0 { + if stopProjectFlag != "" { + return cmd.Help() + } + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) + return nil + } + + selectedTargets := selection.GetTargetsFromPrompt(targetList, "Stop") + + for _, target := range selectedTargets { + err := StopTarget(apiClient, target.Name, "") + if err != nil { + log.Errorf("Failed to stop target %s: %v\n\n", target.Name, err) + continue + } + + projectNames := util.ArrayMap(target.Projects, func(p apiclient.Project) string { + return p.Name + }) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, false, true, &from) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) + } + } else { + targetId := args[0] + var projectNames []string + + err = StopTarget(apiClient, targetId, stopProjectFlag) + if err != nil { + return err + } + + target, err := apiclient_util.GetTarget(targetId, false) + if err != nil { + return err + } + + if startProjectFlag != "" { + projectNames = append(projectNames, stopProjectFlag) + } else { + projectNames = util.ArrayMap(target.Projects, func(p apiclient.Project) string { + return p.Name + }) + } + + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, false, true, &from) + + if stopProjectFlag != "" { + views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully stopped", stopProjectFlag, targetId)) + } else { + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) + } + } + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getAllTargetsByState(TARGET_STATE_RUNNING) + }, +} + +func init() { + StopCmd.Flags().StringVarP(&stopProjectFlag, "project", "p", "", "Stop a single project in the target (project name)") + StopCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Stop all targets") +} + +func stopAllTargets(activeProfile config.Profile, from time.Time) error { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + for _, target := range targetList { + err := StopTarget(apiClient, target.Name, "") + if err != nil { + log.Errorf("Failed to stop target %s: %v\n\n", target.Name, err) + continue + } + + projectNames := util.ArrayMap(target.Projects, func(p apiclient.Project) string { + return p.Name + }) + + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, false, true, &from) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) + } + return nil +} + +func StopTarget(apiClient *apiclient.APIClient, targetId, projectName string) error { + ctx := context.Background() + var message string + var stopFunc func() error + + if projectName == "" { + message = fmt.Sprintf("Target '%s' is stopping", targetId) + stopFunc = func() error { + res, err := apiClient.TargetAPI.StopTarget(ctx, targetId).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + return nil + } + } else { + message = fmt.Sprintf("Project '%s' from target '%s' is stopping", projectName, targetId) + stopFunc = func() error { + res, err := apiClient.TargetAPI.StopProject(ctx, targetId, projectName).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + return nil + } + } + + err := views_util.WithInlineSpinner(message, stopFunc) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/cmd/workspace/util/add_from_config.go b/pkg/cmd/target/util/add_from_config.go similarity index 100% rename from pkg/cmd/workspace/util/add_from_config.go rename to pkg/cmd/target/util/add_from_config.go diff --git a/pkg/cmd/workspace/util/branch_wizard.go b/pkg/cmd/target/util/branch_wizard.go similarity index 99% rename from pkg/cmd/workspace/util/branch_wizard.go rename to pkg/cmd/target/util/branch_wizard.go index 4c0a26c958..39c7c3303b 100644 --- a/pkg/cmd/workspace/util/branch_wizard.go +++ b/pkg/cmd/target/util/branch_wizard.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) type BranchWizardConfig struct { diff --git a/pkg/cmd/workspace/util/creation_data.go b/pkg/cmd/target/util/creation_data.go similarity index 98% rename from pkg/cmd/workspace/util/creation_data.go rename to pkg/cmd/target/util/creation_data.go index ac1edeb3a6..e269a2e9a0 100644 --- a/pkg/cmd/workspace/util/creation_data.go +++ b/pkg/cmd/target/util/creation_data.go @@ -17,9 +17,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views/target/create" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) type ProjectsDataPromptConfig struct { diff --git a/pkg/cmd/workspace/util/get_target_config.go b/pkg/cmd/target/util/get_target_config.go similarity index 100% rename from pkg/cmd/workspace/util/get_target_config.go rename to pkg/cmd/target/util/get_target_config.go diff --git a/pkg/cmd/workspace/util/repository_wizard.go b/pkg/cmd/target/util/repository_wizard.go similarity index 98% rename from pkg/cmd/workspace/util/repository_wizard.go rename to pkg/cmd/target/util/repository_wizard.go index d957a88b68..bc0987e420 100644 --- a/pkg/cmd/workspace/util/repository_wizard.go +++ b/pkg/cmd/target/util/repository_wizard.go @@ -13,9 +13,9 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" + "github.com/daytonaio/daytona/pkg/views/target/create" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" ) diff --git a/pkg/cmd/workspace/util/workspace.go b/pkg/cmd/target/util/target.go similarity index 90% rename from pkg/cmd/workspace/util/workspace.go rename to pkg/cmd/target/util/target.go index a6092cc172..94de8f6fb2 100644 --- a/pkg/cmd/workspace/util/workspace.go +++ b/pkg/cmd/target/util/target.go @@ -51,8 +51,8 @@ func CheckAnyProjectConfigurationFlagSet(flags ProjectConfigurationFlags) bool { return *flags.GitProviderConfig != "" || *flags.CustomImage != "" || *flags.CustomImageUser != "" || *flags.DevcontainerPath != "" || *flags.Builder != "" || len(*flags.EnvVars) > 0 } -func IsProjectRunning(workspace *apiclient.WorkspaceDTO, projectName string) bool { - for _, project := range workspace.GetProjects() { +func IsProjectRunning(target *apiclient.TargetDTO, projectName string) bool { + for _, project := range target.GetProjects() { if project.GetName() == projectName { return project.GetState().Uptime != 0 } @@ -60,9 +60,9 @@ func IsProjectRunning(workspace *apiclient.WorkspaceDTO, projectName string) boo return false } -func GetProjectProviderMetadata(workspace *apiclient.WorkspaceDTO, projectName string) (string, error) { - if workspace.Info != nil { - for _, project := range workspace.Info.Projects { +func GetProjectProviderMetadata(target *apiclient.TargetDTO, projectName string) (string, error) { + if target.Info != nil { + for _, project := range target.Info.Projects { if project.Name == projectName { if project.ProviderMetadata == nil { return "", errors.New("project provider metadata is missing") diff --git a/pkg/cmd/targetconfig/remove.go b/pkg/cmd/targetconfig/remove.go index 8ea6852423..4cf7907cad 100644 --- a/pkg/cmd/targetconfig/remove.go +++ b/pkg/cmd/targetconfig/remove.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace" + target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/targetconfig" @@ -73,33 +73,33 @@ var removeCmd = &cobra.Command{ } if yesFlag { - fmt.Println("Deleting all workspaces.") - err := RemoveTargetConfigWorkspaces(ctx, apiClient, selectedConfigName) + fmt.Println("Deleting all targets.") + err := RemoveTargetConfigTargets(ctx, apiClient, selectedConfigName) if err != nil { return err } } else { - var configWorkspaceCount int + var configTargetCount int - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - for _, workspace := range workspaceList { - if workspace.TargetConfig == selectedConfigName { - configWorkspaceCount++ + for _, target := range targetList { + if target.TargetConfig == selectedConfigName { + configTargetCount++ } } - if configWorkspaceCount > 0 { - title := fmt.Sprintf("Delete %d workspaces within %s?", configWorkspaceCount, selectedConfigName) - description := "You might not be able to easily remove these workspaces later." + if configTargetCount > 0 { + title := fmt.Sprintf("Delete %d targets within %s?", configTargetCount, selectedConfigName) + description := "You might not be able to easily remove these targets later." - if configWorkspaceCount == 1 { - title = fmt.Sprintf("Delete %d workspace within %s?", configWorkspaceCount, selectedConfigName) - description = "You might not be able to easily remove this workspace later." + if configTargetCount == 1 { + title = fmt.Sprintf("Delete 1 target within %s?", selectedConfigName) + description = "You might not be able to easily remove this target later." } form := huh.NewForm( @@ -117,12 +117,12 @@ var removeCmd = &cobra.Command{ } if yesFlag { - err := RemoveTargetConfigWorkspaces(ctx, apiClient, selectedConfigName) + err := RemoveTargetConfigTargets(ctx, apiClient, selectedConfigName) if err != nil { return err } } else { - fmt.Println("Proceeding with target config removal without deleting workspaces.") + fmt.Println("Proceeding with target config removal without deleting targets.") } } } @@ -138,26 +138,26 @@ var removeCmd = &cobra.Command{ } func init() { - removeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all workspaces without prompt") + removeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all targets without prompt") } -func RemoveTargetConfigWorkspaces(ctx context.Context, client *apiclient.APIClient, targetConfig string) error { - workspaceList, res, err := client.WorkspaceAPI.ListWorkspaces(ctx).Execute() +func RemoveTargetConfigTargets(ctx context.Context, client *apiclient.APIClient, targetConfig string) error { + targetList, res, err := client.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - for _, workspace := range workspaceList { - if workspace.TargetConfig != targetConfig { + for _, target := range targetList { + if target.TargetConfig != targetConfig { continue } - err := workspace_cmd.RemoveWorkspace(ctx, client, &workspace, false) + err := target_cmd.RemoveTarget(ctx, client, &target, false) if err != nil { - log.Errorf("Failed to delete workspace %s: %v", workspace.Name, err) + log.Errorf("Failed to delete target %s: %v", target.Name, err) continue } - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' successfully deleted", workspace.Name)) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully deleted", target.Name)) } return nil diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go deleted file mode 100644 index 1c88412f31..0000000000 --- a/pkg/cmd/workspace/stop.go +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspace - -import ( - "context" - "fmt" - "time" - - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var stopProjectFlag string - -var StopCmd = &cobra.Command{ - Use: "stop [WORKSPACE]", - Short: "Stop a workspace", - GroupID: util.WORKSPACE_GROUP, - Args: cobra.RangeArgs(0, 1), - RunE: func(cmd *cobra.Command, args []string) error { - timeFormat := time.Now().Format("2006-01-02 15:04:05") - from, err := time.Parse("2006-01-02 15:04:05", timeFormat) - if err != nil { - return err - } - - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - if allFlag { - return stopAllWorkspaces(activeProfile, from) - } - - ctx := context.Background() - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - if len(args) == 0 { - if stopProjectFlag != "" { - return cmd.Help() - } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) - return nil - } - - selectedWorkspaces := selection.GetWorkspacesFromPrompt(workspaceList, "Stop") - - for _, workspace := range selectedWorkspaces { - err := StopWorkspace(apiClient, workspace.Name, "") - if err != nil { - log.Errorf("Failed to stop workspace %s: %v\n\n", workspace.Name, err) - continue - } - - projectNames := util.ArrayMap(workspace.Projects, func(p apiclient.Project) string { - return p.Name - }) - apiclient_util.ReadWorkspaceLogs(ctx, activeProfile, workspace.Id, projectNames, false, true, &from) - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' successfully stopped", workspace.Name)) - } - } else { - workspaceId := args[0] - var projectNames []string - - err = StopWorkspace(apiClient, workspaceId, stopProjectFlag) - if err != nil { - return err - } - - workspace, err := apiclient_util.GetWorkspace(workspaceId, false) - if err != nil { - return err - } - - if startProjectFlag != "" { - projectNames = append(projectNames, stopProjectFlag) - } else { - projectNames = util.ArrayMap(workspace.Projects, func(p apiclient.Project) string { - return p.Name - }) - } - - apiclient_util.ReadWorkspaceLogs(ctx, activeProfile, workspace.Id, projectNames, false, true, &from) - - if stopProjectFlag != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' successfully stopped", stopProjectFlag, workspaceId)) - } else { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully stopped", workspaceId)) - } - } - return nil - }, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllWorkspacesByState(WORKSPACE_STATUS_RUNNING) - }, -} - -func init() { - StopCmd.Flags().StringVarP(&stopProjectFlag, "project", "p", "", "Stop a single project in the workspace (project name)") - StopCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Stop all workspaces") -} - -func stopAllWorkspaces(activeProfile config.Profile, from time.Time) error { - ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - for _, workspace := range workspaceList { - err := StopWorkspace(apiClient, workspace.Name, "") - if err != nil { - log.Errorf("Failed to stop workspace %s: %v\n\n", workspace.Name, err) - continue - } - - projectNames := util.ArrayMap(workspace.Projects, func(p apiclient.Project) string { - return p.Name - }) - - apiclient_util.ReadWorkspaceLogs(ctx, activeProfile, workspace.Id, projectNames, false, true, &from) - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' successfully stopped", workspace.Name)) - } - return nil -} - -func StopWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName string) error { - ctx := context.Background() - var message string - var stopFunc func() error - - if projectName == "" { - message = fmt.Sprintf("Workspace '%s' is stopping", workspaceId) - stopFunc = func() error { - res, err := apiClient.WorkspaceAPI.StopWorkspace(ctx, workspaceId).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - return nil - } - } else { - message = fmt.Sprintf("Project '%s' from workspace '%s' is stopping", projectName, workspaceId) - stopFunc = func() error { - res, err := apiClient.WorkspaceAPI.StopProject(ctx, workspaceId, projectName).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - return nil - } - } - - err := views_util.WithInlineSpinner(message, stopFunc) - if err != nil { - return err - } - - return nil -} diff --git a/pkg/cmd/workspacemode/workspace_mode.go b/pkg/cmd/workspacemode/workspace_mode.go deleted file mode 100644 index aa06f70a57..0000000000 --- a/pkg/cmd/workspacemode/workspace_mode.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspacemode - -import ( - "os" - "time" - - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" - cmd "github.com/daytonaio/daytona/pkg/cmd" - . "github.com/daytonaio/daytona/pkg/cmd/agent" - - "github.com/spf13/cobra" -) - -var workspaceId = "" -var projectName = "" - -var workspaceModeRootCmd = &cobra.Command{ - Use: "daytona", - Short: "Use the Daytona CLI to manage your workspace", - Long: "Use the Daytona CLI to manage your workspace", - DisableAutoGenTag: true, - SilenceUsage: true, - SilenceErrors: true, - RunE: func(cmd *cobra.Command, args []string) error { - return cmd.Help() - }, -} - -func Execute() error { - cmd.SetupRootCommand(workspaceModeRootCmd) - workspaceModeRootCmd.AddGroup(&cobra.Group{ID: util.WORKSPACE_GROUP, Title: "Project & Workspace"}) - workspaceModeRootCmd.AddCommand(gitCredCmd) - workspaceModeRootCmd.AddCommand(AgentCmd) - workspaceModeRootCmd.AddCommand(startCmd) - workspaceModeRootCmd.AddCommand(stopCmd) - workspaceModeRootCmd.AddCommand(restartCmd) - workspaceModeRootCmd.AddCommand(infoCmd) - workspaceModeRootCmd.AddCommand(portForwardCmd) - workspaceModeRootCmd.AddCommand(exposeCmd) - - clientId := config.GetClientId() - telemetryEnabled := config.TelemetryEnabled() - startTime := time.Now() - - telemetryService, command, flags, isComplete, err := cmd.PreRun(workspaceModeRootCmd, os.Args[1:], telemetryEnabled, clientId, startTime) - if err != nil { - return err - } - - err = workspaceModeRootCmd.Execute() - - endTime := time.Now() - if !isComplete { - cmd.PostRun(command, err, telemetryService, clientId, startTime, endTime, flags) - } - - return err -} - -func init() { - if workspaceIdEnv := os.Getenv("DAYTONA_WS_ID"); workspaceIdEnv != "" { - workspaceId = workspaceIdEnv - } - if projectNameEnv := os.Getenv("DAYTONA_WS_PROJECT_NAME"); projectNameEnv != "" { - projectName = projectNameEnv - } -} diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index e92aeec95f..d132073ea4 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" "gorm.io/gorm" ) diff --git a/pkg/db/dto/build.go b/pkg/db/dto/build.go index 6da3818196..b1a08e29e3 100644 --- a/pkg/db/dto/build.go +++ b/pkg/db/dto/build.go @@ -7,7 +7,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/workspace/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/project/containerconfig" ) type BuildDTO struct { diff --git a/pkg/db/dto/project.go b/pkg/db/dto/project.go index 543f3925a0..d6c05a27dc 100644 --- a/pkg/db/dto/project.go +++ b/pkg/db/dto/project.go @@ -5,8 +5,8 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type RepositoryDTO struct { @@ -57,7 +57,7 @@ type ProjectDTO struct { User string `json:"user"` Build *ProjectBuildDTO `json:"build,omitempty" gorm:"serializer:json"` Repository RepositoryDTO `json:"repository" gorm:"serializer:json"` - WorkspaceId string `json:"workspaceId"` + TargetId string `json:"targetId"` TargetConfig string `json:"targetConfig"` ApiKey string `json:"apiKey"` State *ProjectStateDTO `json:"state,omitempty" gorm:"serializer:json"` @@ -71,7 +71,7 @@ func ToProjectDTO(project *project.Project) ProjectDTO { User: project.User, Build: ToProjectBuildDTO(project.BuildConfig), Repository: ToRepositoryDTO(project.Repository), - WorkspaceId: project.WorkspaceId, + TargetId: project.TargetId, TargetConfig: project.TargetConfig, State: ToProjectStateDTO(project.State), ApiKey: project.ApiKey, @@ -163,7 +163,7 @@ func ToProject(projectDTO ProjectDTO) *project.Project { User: projectDTO.User, BuildConfig: ToProjectBuild(projectDTO.Build), Repository: ToRepository(projectDTO.Repository), - WorkspaceId: projectDTO.WorkspaceId, + TargetId: projectDTO.TargetId, TargetConfig: projectDTO.TargetConfig, State: ToProjectState(projectDTO.State), ApiKey: projectDTO.ApiKey, diff --git a/pkg/db/dto/project_config.go b/pkg/db/dto/project_config.go index a0a5f9c92a..2051570521 100644 --- a/pkg/db/dto/project_config.go +++ b/pkg/db/dto/project_config.go @@ -4,7 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" ) type ProjectConfigDTO struct { diff --git a/pkg/db/dto/target.go b/pkg/db/dto/target.go new file mode 100644 index 0000000000..7918c954d5 --- /dev/null +++ b/pkg/db/dto/target.go @@ -0,0 +1,58 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/target" +) + +type TargetDTO struct { + Id string `gorm:"primaryKey"` + Name string `json:"name" gorm:"unique"` + TargetConfig string `json:"config"` + ApiKey string `json:"apiKey"` + Projects []ProjectDTO `gorm:"serializer:json"` +} + +func (w TargetDTO) GetProject(name string) (*ProjectDTO, error) { + for _, project := range w.Projects { + if project.Name == name { + return &project, nil + } + } + + return nil, errors.New("project not found") +} + +func ToTargetDTO(target *target.Target) TargetDTO { + targetDTO := TargetDTO{ + Id: target.Id, + Name: target.Name, + TargetConfig: target.TargetConfig, + ApiKey: target.ApiKey, + } + + for _, project := range target.Projects { + targetDTO.Projects = append(targetDTO.Projects, ToProjectDTO(project)) + } + + return targetDTO +} + +func ToTarget(targetDTO TargetDTO) *target.Target { + target := target.Target{ + Id: targetDTO.Id, + Name: targetDTO.Name, + TargetConfig: targetDTO.TargetConfig, + ApiKey: targetDTO.ApiKey, + } + + for _, projectDTO := range targetDTO.Projects { + target.Projects = append(target.Projects, ToProject(projectDTO)) + } + + return &target +} diff --git a/pkg/db/dto/workspace.go b/pkg/db/dto/workspace.go deleted file mode 100644 index 4f800c5bc5..0000000000 --- a/pkg/db/dto/workspace.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "errors" - - "github.com/daytonaio/daytona/pkg/workspace" -) - -type WorkspaceDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name" gorm:"unique"` - TargetConfig string `json:"config"` - ApiKey string `json:"apiKey"` - Projects []ProjectDTO `gorm:"serializer:json"` -} - -func (w WorkspaceDTO) GetProject(name string) (*ProjectDTO, error) { - for _, project := range w.Projects { - if project.Name == name { - return &project, nil - } - } - - return nil, errors.New("project not found") -} - -func ToWorkspaceDTO(workspace *workspace.Workspace) WorkspaceDTO { - workspaceDTO := WorkspaceDTO{ - Id: workspace.Id, - Name: workspace.Name, - TargetConfig: workspace.TargetConfig, - ApiKey: workspace.ApiKey, - } - - for _, project := range workspace.Projects { - workspaceDTO.Projects = append(workspaceDTO.Projects, ToProjectDTO(project)) - } - - return workspaceDTO -} - -func ToWorkspace(workspaceDTO WorkspaceDTO) *workspace.Workspace { - workspace := workspace.Workspace{ - Id: workspaceDTO.Id, - Name: workspaceDTO.Name, - TargetConfig: workspaceDTO.TargetConfig, - ApiKey: workspaceDTO.ApiKey, - } - - for _, projectDTO := range workspaceDTO.Projects { - workspace.Projects = append(workspace.Projects, ToProject(projectDTO)) - } - - return &workspace -} diff --git a/pkg/db/project_config_store.go b/pkg/db/project_config_store.go index 40a6295f3f..df9ce01e87 100644 --- a/pkg/db/project_config_store.go +++ b/pkg/db/project_config_store.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" ) type ProjectConfigStore struct { diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go new file mode 100644 index 0000000000..bf55b32453 --- /dev/null +++ b/pkg/db/target_store.go @@ -0,0 +1,73 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + + . "github.com/daytonaio/daytona/pkg/db/dto" + "github.com/daytonaio/daytona/pkg/target" +) + +type TargetStore struct { + db *gorm.DB +} + +func NewTargetStore(db *gorm.DB) (*TargetStore, error) { + err := db.AutoMigrate(&TargetDTO{}) + if err != nil { + return nil, err + } + + return &TargetStore{db: db}, nil +} + +func (store *TargetStore) List() ([]*target.Target, error) { + targetDTOs := []TargetDTO{} + tx := store.db.Find(&targetDTOs) + if tx.Error != nil { + return nil, tx.Error + } + + targets := []*target.Target{} + for _, targetDTO := range targetDTOs { + targets = append(targets, ToTarget(targetDTO)) + } + + return targets, nil +} + +func (w *TargetStore) Find(idOrName string) (*target.Target, error) { + targetDTO := TargetDTO{} + tx := w.db.Where("id = ? OR name = ?", idOrName, idOrName).First(&targetDTO) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, target.ErrTargetNotFound + } + return nil, tx.Error + } + + return ToTarget(targetDTO), nil +} + +func (w *TargetStore) Save(target *target.Target) error { + tx := w.db.Save(ToTargetDTO(target)) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (w *TargetStore) Delete(t *target.Target) error { + tx := w.db.Delete(ToTargetDTO(t)) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return target.ErrTargetNotFound + } + + return nil +} diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go deleted file mode 100644 index 6800df94c2..0000000000 --- a/pkg/db/workspace_store.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "gorm.io/gorm" - - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/workspace" -) - -type WorkspaceStore struct { - db *gorm.DB -} - -func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { - err := db.AutoMigrate(&WorkspaceDTO{}) - if err != nil { - return nil, err - } - - return &WorkspaceStore{db: db}, nil -} - -func (w *WorkspaceStore) List() ([]*workspace.Workspace, error) { - workspaceDTOs := []WorkspaceDTO{} - tx := w.db.Find(&workspaceDTOs) - if tx.Error != nil { - return nil, tx.Error - } - - workspaces := []*workspace.Workspace{} - for _, workspaceDTO := range workspaceDTOs { - workspaces = append(workspaces, ToWorkspace(workspaceDTO)) - } - - return workspaces, nil -} - -func (w *WorkspaceStore) Find(idOrName string) (*workspace.Workspace, error) { - workspaceDTO := WorkspaceDTO{} - tx := w.db.Where("id = ? OR name = ?", idOrName, idOrName).First(&workspaceDTO) - if tx.Error != nil { - if IsRecordNotFound(tx.Error) { - return nil, workspace.ErrWorkspaceNotFound - } - return nil, tx.Error - } - - return ToWorkspace(workspaceDTO), nil -} - -func (w *WorkspaceStore) Save(workspace *workspace.Workspace) error { - tx := w.db.Save(ToWorkspaceDTO(workspace)) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (w *WorkspaceStore) Delete(ws *workspace.Workspace) error { - tx := w.db.Delete(ToWorkspaceDTO(ws)) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return workspace.ErrWorkspaceNotFound - } - - return nil -} diff --git a/pkg/docker/README.md b/pkg/docker/README.md index a83692b38a..c8ebdbf555 100644 --- a/pkg/docker/README.md +++ b/pkg/docker/README.md @@ -1,13 +1,14 @@ ## Package Purpose -The purpose of the `docker` package is to provide a single library that providers can use to easily create workspaces and projects. -Most providers will import the package and call commands from the `DockerClient` in order to create workspaces and projects on provided targets. +The purpose of the `docker` package is to provide a single library that providers can use to easily create targets and projects. +Most providers will import the package and call commands from the `DockerClient` in order to create targets and projects on provided targets. ## Usage To use the Daytona `DockerClient`, the consumer of the library must provide a Docker API client from `github.com/docker/docker/client`. Example: + ```golang import ( "github.com/docker/docker/client" @@ -31,12 +32,14 @@ func GetDockerClient() (docker.IDockerClient, error) { To test changes made in this library, other than writing tests, we recommend using the library locally with the [Docker provider](https://github.com/daytonaio/daytona-provider-docker). The procedure would be as follows: + 1. Clone the [Docker provider](https://github.com/daytonaio/daytona-provider-docker) 1. Open the `go.mod` file. 1. Add `replace github.com/daytonaio/daytona => ` 1. Run `go mod tidy` 1. Build the Docker provider and store it to your local provider directory. - - `go build -o /docker-provider/docker-provider main.go` - - If you're developing Daytona in a devcontainer, ` = ~/.config/daytona/providers` + +- `go build -o /docker-provider/docker-provider main.go` +- If you're developing Daytona in a devcontainer, ` = ~/.config/daytona/providers` **Note**: Any change to the `docker` library will require that providers update the version of `github.com/daytonaio/daytona` after the next release and post a release of their own. diff --git a/pkg/docker/client.go b/pkg/docker/client.go index 4ff5e988de..ea9d8eda11 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" @@ -32,16 +32,16 @@ type CreateProjectOptions struct { type IDockerClient interface { CreateProject(opts *CreateProjectOptions) error - CreateWorkspace(workspace *workspace.Workspace, workspaceDir string, logWriter io.Writer, sshClient *ssh.Client) error + CreateTarget(target *target.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error DestroyProject(project *project.Project, projectDir string, sshClient *ssh.Client) error - DestroyWorkspace(workspace *workspace.Workspace, workspaceDir string, sshClient *ssh.Client) error + DestroyTarget(target *target.Target, targetDir string, sshClient *ssh.Client) error StartProject(opts *CreateProjectOptions, daytonaDownloadUrl string) error StopProject(project *project.Project, logWriter io.Writer) error GetProjectInfo(project *project.Project) (*project.ProjectInfo, error) - GetWorkspaceInfo(ws *workspace.Workspace) (*workspace.WorkspaceInfo, error) + GetTargetInfo(ws *target.Target) (*target.TargetInfo, error) GetProjectContainerName(project *project.Project) string GetProjectVolumeName(project *project.Project) string @@ -71,18 +71,18 @@ type DockerClient struct { func (d *DockerClient) GetProjectContainerName(project *project.Project) string { containers, err := d.apiClient.ContainerList(context.Background(), container.ListOptions{ - Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.workspace.id=%s", project.WorkspaceId)), filters.Arg("label", fmt.Sprintf("daytona.project.name=%s", project.Name))), + Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.target.id=%s", project.TargetId)), filters.Arg("label", fmt.Sprintf("daytona.project.name=%s", project.Name))), All: true, }) if err != nil || len(containers) == 0 { - return project.WorkspaceId + "-" + project.Name + return project.TargetId + "-" + project.Name } return containers[0].ID } func (d *DockerClient) GetProjectVolumeName(project *project.Project) string { - return project.WorkspaceId + "-" + project.Name + return project.TargetId + "-" + project.Name } func (d *DockerClient) getComposeContainers(c types.ContainerJSON) (string, []types.Container, error) { diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index c886146155..24021cc1c0 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -9,9 +9,9 @@ import ( "github.com/daytonaio/daytona/internal/testing/docker/mocks" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" "github.com/stretchr/testify/suite" ) @@ -24,12 +24,12 @@ var project1 = &project.Project{ }, Image: "test-image:tag", User: "test-user", - WorkspaceId: "123", + TargetId: "123", TargetConfig: "local", BuildConfig: &buildconfig.BuildConfig{}, } -var workspace1 = &workspace.Workspace{ +var target1 = &target.Target{ Id: "123", Name: "test", TargetConfig: "local", diff --git a/pkg/docker/create.go b/pkg/docker/create.go index 26fd13c0e4..35ce258b93 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -17,19 +17,19 @@ import ( "github.com/daytonaio/daytona/pkg/build/detect" "github.com/daytonaio/daytona/pkg/git" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/go-git/go-git/v5/plumbing/transport/http" log "github.com/sirupsen/logrus" ) -func (d *DockerClient) CreateWorkspace(workspace *workspace.Workspace, workspaceDir string, logWriter io.Writer, sshClient *ssh.Client) error { +func (d *DockerClient) CreateTarget(target *target.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error { var err error if sshClient == nil { - err = os.MkdirAll(workspaceDir, 0755) + err = os.MkdirAll(targetDir, 0755) } else { - err = sshClient.Exec(fmt.Sprintf("mkdir -p %s", workspaceDir), nil) + err = sshClient.Exec(fmt.Sprintf("mkdir -p %s", targetDir), nil) } return err @@ -95,7 +95,7 @@ func (d *DockerClient) cloneProjectRepository(opts *CreateProjectOptions) error } gitService := git.Service{ - ProjectDir: fmt.Sprintf("/workdir/%s-%s", opts.Project.WorkspaceId, opts.Project.Name), + ProjectDir: fmt.Sprintf("/workdir/%s-%s", opts.Project.TargetId, opts.Project.Name), } cloneCmd := gitService.CloneRepositoryCmd(opts.Project.Repository, auth) @@ -115,7 +115,7 @@ func (d *DockerClient) cloneProjectRepository(opts *CreateProjectOptions) error Target: "/workdir", }, }, - }, nil, nil, fmt.Sprintf("git-clone-%s-%s", opts.Project.WorkspaceId, opts.Project.Name)) + }, nil, nil, fmt.Sprintf("git-clone-%s-%s", opts.Project.TargetId, opts.Project.Name)) if err != nil { return err } @@ -212,7 +212,7 @@ func (d *DockerClient) toCreateDevcontainerOptions(opts *CreateProjectOptions, p BuilderContainerRegistry: opts.BuilderContainerRegistry, EnvVars: opts.Project.EnvVars, IdLabels: map[string]string{ - "daytona.workspace.id": opts.Project.WorkspaceId, + "daytona.target.id": opts.Project.TargetId, "daytona.project.name": opts.Project.Name, }, Prebuild: prebuild, diff --git a/pkg/docker/create_devcontainer.go b/pkg/docker/create_devcontainer.go index 6053aa8e30..06e361aca0 100644 --- a/pkg/docker/create_devcontainer.go +++ b/pkg/docker/create_devcontainer.go @@ -21,7 +21,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/mount" diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index 42a21012be..17e660ff43 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -10,7 +10,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/docker/go-connections/nat" @@ -48,7 +48,7 @@ func (d *DockerClient) initProjectContainer(opts *CreateProjectOptions, mountPro var availablePort *uint16 var portBindings map[nat.Port][]nat.PortBinding - if opts.Project.Target == "local" { + if opts.Project.TargetConfig == "local" { p, err := ports.GetAvailableEphemeralPort() if err != nil { log.Error(err) @@ -114,9 +114,9 @@ func GetContainerCreateConfig(project *project.Project, toolboxApiHostPort *uint } labels := map[string]string{ - "daytona.workspace.id": project.WorkspaceId, - "daytona.workspace.project.name": project.Name, - "daytona.workspace.project.repository.url": project.Repository.Url, + "daytona.target.id": project.TargetId, + "daytona.project.name": project.Name, + "daytona.project.repository.url": project.Repository.Url, } if toolboxApiHostPort != nil { diff --git a/pkg/docker/create_test.go b/pkg/docker/create_test.go index 5e1e210de7..f215d0294b 100644 --- a/pkg/docker/create_test.go +++ b/pkg/docker/create_test.go @@ -23,13 +23,13 @@ import ( "github.com/stretchr/testify/require" ) -func (s *DockerClientTestSuite) TestCreateWorkspace() { - workspaceDir := s.T().TempDir() +func (s *DockerClientTestSuite) TestCreateTarget() { + targetDir := s.T().TempDir() - err := s.dockerClient.CreateWorkspace(workspace1, workspaceDir, nil, nil) + err := s.dockerClient.CreateTarget(target1, targetDir, nil, nil) require.Nil(s.T(), err) - _, err = os.Stat(workspaceDir) + _, err = os.Stat(targetDir) require.Nil(s.T(), err) } @@ -80,7 +80,7 @@ func (s *DockerClientTestSuite) TestCreateProject() { Target: "/workdir", }, }, - }, networkingConfig, platform, fmt.Sprintf("git-clone-%s-%s", project1.WorkspaceId, project1.Name), + }, networkingConfig, platform, fmt.Sprintf("git-clone-%s-%s", project1.TargetId, project1.Name), ).Return(container.CreateResponse{ID: "123"}, nil) s.mockClient.On("ContainerCreate", mock.Anything, docker.GetContainerCreateConfig(project1, nil), &container.HostConfig{ diff --git a/pkg/docker/destroy.go b/pkg/docker/destroy.go index 59e1de6011..cdb1a8b71c 100644 --- a/pkg/docker/destroy.go +++ b/pkg/docker/destroy.go @@ -9,17 +9,17 @@ import ( "os" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) -func (d *DockerClient) DestroyWorkspace(workspace *workspace.Workspace, workspaceDir string, sshClient *ssh.Client) error { +func (d *DockerClient) DestroyTarget(target *target.Target, targetDir string, sshClient *ssh.Client) error { if sshClient == nil { - return os.RemoveAll(workspaceDir) + return os.RemoveAll(targetDir) } else { - return sshClient.Exec(fmt.Sprintf("rm -rf %s", workspaceDir), nil) + return sshClient.Exec(fmt.Sprintf("rm -rf %s", targetDir), nil) } } diff --git a/pkg/docker/destroy_test.go b/pkg/docker/destroy_test.go index 11e6cc3d93..e18f1d58db 100644 --- a/pkg/docker/destroy_test.go +++ b/pkg/docker/destroy_test.go @@ -12,13 +12,13 @@ import ( "github.com/stretchr/testify/require" ) -func (s *DockerClientTestSuite) TestDestroyWorkspace() { - workspaceDir := s.T().TempDir() +func (s *DockerClientTestSuite) TestDestroyTarget() { + targetDir := s.T().TempDir() - err := s.dockerClient.DestroyWorkspace(workspace1, workspaceDir, nil) + err := s.dockerClient.DestroyTarget(target1, targetDir, nil) require.Nil(s.T(), err) - _, err = os.Stat(workspaceDir) + _, err = os.Stat(targetDir) require.True(s.T(), os.IsNotExist(err)) } diff --git a/pkg/docker/info.go b/pkg/docker/info.go index f6355bbb29..a54cf4762b 100644 --- a/pkg/docker/info.go +++ b/pkg/docker/info.go @@ -8,32 +8,32 @@ import ( "encoding/json" "fmt" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) const ContainerNotFoundMetadata = "{\"state\": \"container not found\"}" -const WorkspaceMetadataFormat = "{\"networkId\": \"%s\"}" +const TargetMetadataFormat = "{\"networkId\": \"%s\"}" -func (d *DockerClient) GetWorkspaceInfo(ws *workspace.Workspace) (*workspace.WorkspaceInfo, error) { - workspaceInfo := &workspace.WorkspaceInfo{ - Name: ws.Name, - ProviderMetadata: fmt.Sprintf(WorkspaceMetadataFormat, ws.Id), +func (d *DockerClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, error) { + targetInfo := &target.TargetInfo{ + Name: t.Name, + ProviderMetadata: fmt.Sprintf(TargetMetadataFormat, t.Id), } projectInfos := []*project.ProjectInfo{} - for _, project := range ws.Projects { + for _, project := range t.Projects { projectInfo, err := d.GetProjectInfo(project) if err != nil { return nil, err } projectInfos = append(projectInfos, projectInfo) } - workspaceInfo.Projects = projectInfos + targetInfo.Projects = projectInfos - return workspaceInfo, nil + return targetInfo, nil } func (d *DockerClient) GetProjectInfo(p *project.Project) (*project.ProjectInfo, error) { diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go index 781c8e3025..3d64acd570 100644 --- a/pkg/docker/info_test.go +++ b/pkg/docker/info_test.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/mock" @@ -44,15 +44,15 @@ func (s *DockerClientTestSuite) TestGetProjectInfo() { require.Equal(s.T(), projectInfo.ProviderMetadata, metadata) } -func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { - workspaceWithoutProjects := &workspace.Workspace{ +func (s *DockerClientTestSuite) TestGetTargetInfo() { + targetWithoutProjects := &target.Target{ Id: "123", Name: "test", TargetConfig: "local", } - wsInfo, err := s.dockerClient.GetWorkspaceInfo(workspaceWithoutProjects) + targetInfo, err := s.dockerClient.GetTargetInfo(targetWithoutProjects) require.Nil(s.T(), err) - require.Equal(s.T(), wsInfo.Name, workspaceWithoutProjects.Name) - require.Equal(s.T(), wsInfo.ProviderMetadata, fmt.Sprintf(docker.WorkspaceMetadataFormat, workspaceWithoutProjects.Id)) + require.Equal(s.T(), targetInfo.Name, targetWithoutProjects.Name) + require.Equal(s.T(), targetInfo.ProviderMetadata, fmt.Sprintf(docker.TargetMetadataFormat, targetWithoutProjects.Id)) } diff --git a/pkg/docker/start.go b/pkg/docker/start.go index d10d993ab5..15e1209bf4 100644 --- a/pkg/docker/start.go +++ b/pkg/docker/start.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/detect" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types/container" ) diff --git a/pkg/docker/start_devcontainer.go b/pkg/docker/start_devcontainer.go index b1ae1a2e39..5faa263271 100644 --- a/pkg/docker/start_devcontainer.go +++ b/pkg/docker/start_devcontainer.go @@ -39,7 +39,7 @@ func (d *DockerClient) runDevcontainerUserCommands(opts *CreateProjectOptions) e "--workspace-folder=" + paths.ProjectTarget, "--config=" + paths.TargetConfigFilePath, "--override-config=" + path.Join(paths.OverridesTarget, "devcontainer.json"), - "--id-label=daytona.workspace.id=" + opts.Project.WorkspaceId, + "--id-label=daytona.target.id=" + opts.Project.TargetId, "--id-label=daytona.project.name=" + opts.Project.Name, } diff --git a/pkg/docker/stop.go b/pkg/docker/stop.go index 631f44f278..3efc0a3f54 100644 --- a/pkg/docker/stop.go +++ b/pkg/docker/stop.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" ) diff --git a/pkg/git/service.go b/pkg/git/service.go index 38fb5bf4e5..a95ab78769 100644 --- a/pkg/git/service.go +++ b/pkg/git/service.go @@ -9,7 +9,7 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/transport/http" ) diff --git a/pkg/ide/browser.go b/pkg/ide/browser.go index 1ad9c99382..3296df4b49 100644 --- a/pkg/ide/browser.go +++ b/pkg/ide/browser.go @@ -23,15 +23,15 @@ import ( const startVSCodeServerCommand = "$HOME/vscode-server/bin/openvscode-server --start-server --port=63000 --host=0.0.0.0 --without-connection-token --disable-workspace-trust --default-folder=" -func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgKey string) error { +func OpenBrowserIDE(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgKey string) error { // Download and start IDE - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, projectName, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) if err != nil { return err } views.RenderInfoMessageBold("Downloading OpenVSCode Server...") - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) installServerCommand := exec.Command("ssh", projectHostname, "curl -fsSL https://download.daytona.io/daytona/get-openvscode-server.sh | sh") installServerCommand.Stdout = io.Writer(&util.DebugLogWriter{}) @@ -42,7 +42,7 @@ func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, projectNam return err } - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } @@ -61,7 +61,7 @@ func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, projectNam }() // Forward IDE port - browserPort, errChan := tailscale.ForwardPort(workspaceId, projectName, 63000, activeProfile) + browserPort, errChan := tailscale.ForwardPort(targetId, projectName, 63000, activeProfile) if browserPort == nil { if err := <-errChan; err != nil { return err diff --git a/pkg/ide/cursor.go b/pkg/ide/cursor.go index 00e63fbc58..9a0ec5e469 100644 --- a/pkg/ide/cursor.go +++ b/pkg/ide/cursor.go @@ -14,15 +14,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenCursor(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenCursor(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { path, err := GetCursorBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgkey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) if err != nil { return err } diff --git a/pkg/ide/fleet.go b/pkg/ide/fleet.go index 4f39157d1f..854332eb11 100644 --- a/pkg/ide/fleet.go +++ b/pkg/ide/fleet.go @@ -13,13 +13,13 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenFleet(activeProfile config.Profile, workspaceId string, projectName string, gpgKey string) error { +func OpenFleet(activeProfile config.Profile, targetId string, projectName string, gpgKey string) error { if err := CheckFleetInstallation(); err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } diff --git a/pkg/ide/jetbrains.go b/pkg/ide/jetbrains.go index 4ddc570765..f6e1b324e6 100644 --- a/pkg/ide/jetbrains.go +++ b/pkg/ide/jetbrains.go @@ -23,25 +23,25 @@ import ( "github.com/pkg/browser" ) -func OpenJetbrainsIDE(activeProfile config.Profile, ide, workspaceId, projectName string, gpgKey string) error { +func OpenJetbrainsIDE(activeProfile config.Profile, ide, targetId, projectName string, gpgKey string) error { err := IsJetBrainsGatewayInstalled() if err != nil { return err } - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) jbIde, ok := jetbrains.GetIdes()[jetbrains.Id(ide)] if !ok { return errors.New("IDE not found") } - home, err := util.GetHomeDir(activeProfile, workspaceId, projectName, gpgKey) + home, err := util.GetHomeDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } diff --git a/pkg/ide/jupyter.go b/pkg/ide/jupyter.go index c60ade2f17..27ba89b261 100644 --- a/pkg/ide/jupyter.go +++ b/pkg/ide/jupyter.go @@ -25,15 +25,15 @@ import ( const startJupyterCommand = "notebook --no-browser --port=8888 --ip=0.0.0.0 --NotebookApp.token='' --NotebookApp.password=''" -// OpenJupyterIDE manages the installation and startup of a Jupyter IDE on a remote workspace. -func OpenJupyterIDE(activeProfile config.Profile, workspaceId, projectName, projectProviderMetadata string, yesFlag bool, gpgKey string) error { +// OpenJupyterIDE manages the installation and startup of a Jupyter IDE on a remote target. +func OpenJupyterIDE(activeProfile config.Profile, targetId, projectName, projectProviderMetadata string, yesFlag bool, gpgKey string) error { // Ensure SSH config entry is added - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, projectName, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) // Check and install Python if necessary if err := ensurePythonInstalled(projectHostname, yesFlag); err != nil { @@ -51,7 +51,7 @@ func OpenJupyterIDE(activeProfile config.Profile, workspaceId, projectName, proj } // Start Jupyter Notebook server - if err := startJupyterServer(projectHostname, activeProfile, workspaceId, projectName, gpgKey); err != nil { + if err := startJupyterServer(projectHostname, activeProfile, targetId, projectName, gpgKey); err != nil { return err } @@ -215,9 +215,9 @@ func ensureJupyterInstalled(hostname string) error { return runRemoteCommand(hostname, installCmd) } -// startJupyterServer starts the Jupyter Notebook server on the remote workspace. -func startJupyterServer(hostname string, activeProfile config.Profile, workspaceId, projectName string, gpgKey string) error { - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) +// startJupyterServer starts the Jupyter Notebook server on the remote target. +func startJupyterServer(hostname string, activeProfile config.Profile, targetId, projectName string, gpgKey string) error { + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } @@ -235,7 +235,7 @@ func startJupyterServer(hostname string, activeProfile config.Profile, workspace }() // Forward the IDE port - browserPort, errChan := tailscale.ForwardPort(workspaceId, projectName, 8888, activeProfile) + browserPort, errChan := tailscale.ForwardPort(targetId, projectName, 8888, activeProfile) if browserPort == nil { if err := <-errChan; err != nil { return err diff --git a/pkg/ide/positron.go b/pkg/ide/positron.go index d26f4c5cfc..f54ae3543a 100644 --- a/pkg/ide/positron.go +++ b/pkg/ide/positron.go @@ -15,15 +15,15 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenPositron(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenPositron(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { path, err := GetPositronBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgkey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) if err != nil { return err } diff --git a/pkg/ide/terminal.go b/pkg/ide/terminal.go index 3acbaa19ff..ee286d05bd 100644 --- a/pkg/ide/terminal.go +++ b/pkg/ide/terminal.go @@ -12,8 +12,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func OpenTerminalSsh(activeProfile config.Profile, workspaceId string, projectName string, gpgKey string, sshOptions []string, args ...string) error { - if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, projectName, gpgKey); err != nil { +func OpenTerminalSsh(activeProfile config.Profile, targetId string, projectName string, gpgKey string, sshOptions []string, args ...string) error { + if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey); err != nil { return err } @@ -23,7 +23,7 @@ func OpenTerminalSsh(activeProfile config.Profile, workspaceId string, projectNa return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) cmdArgs := buildCommandArgs(projectHostname, parsedOptions, args...) sshCommand := exec.Command("ssh", cmdArgs...) diff --git a/pkg/ide/vscode-insiders.go b/pkg/ide/vscode-insiders.go index e204f3be1b..3f63cb8b7f 100644 --- a/pkg/ide/vscode-insiders.go +++ b/pkg/ide/vscode-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVSCodeInsiders(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgKey string) error { +func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgKey string) error { path, err := GetVSCodeInsidersBinaryPath() if err != nil { return err @@ -23,9 +23,9 @@ func OpenVSCodeInsiders(activeProfile config.Profile, workspaceId string, projec return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } diff --git a/pkg/ide/vscode.go b/pkg/ide/vscode.go index 35fe0370f8..f37248adbd 100644 --- a/pkg/ide/vscode.go +++ b/pkg/ide/vscode.go @@ -19,16 +19,16 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenVSCode(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgKey string) error { +func OpenVSCode(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgKey string) error { CheckAndAlertVSCodeInstalled() err := installRemoteSSHExtension("code") if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } diff --git a/pkg/ide/vscodium-insiders.go b/pkg/ide/vscodium-insiders.go index 214e72cdcc..7db918e98e 100644 --- a/pkg/ide/vscodium-insiders.go +++ b/pkg/ide/vscodium-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVScodiumInsiders(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { path, err := GetCodiumInsidersBinaryPath() if err != nil { return err @@ -23,9 +23,9 @@ func OpenVScodiumInsiders(activeProfile config.Profile, workspaceId string, proj if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgkey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) if err != nil { return err } diff --git a/pkg/ide/vscodium.go b/pkg/ide/vscodium.go index b572da0f7a..4d9bf68a94 100644 --- a/pkg/ide/vscodium.go +++ b/pkg/ide/vscodium.go @@ -16,7 +16,7 @@ import ( const requiredExtension = "jeanp413.open-remote-ssh" -func OpenVScodium(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenVScodium(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { path, err := GetCodiumBinaryPath() if err != nil { return err @@ -26,9 +26,9 @@ func OpenVScodium(activeProfile config.Profile, workspaceId string, projectName if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgkey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) if err != nil { return err } diff --git a/pkg/ide/windsurf.go b/pkg/ide/windsurf.go index 7b511667a8..7984007d5c 100644 --- a/pkg/ide/windsurf.go +++ b/pkg/ide/windsurf.go @@ -13,15 +13,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenWindsurf(activeProfile config.Profile, workspaceId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenWindsurf(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { path, err := GetWindsurfBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgkey) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) if err != nil { return err } diff --git a/pkg/ide/zed.go b/pkg/ide/zed.go index 6ef41598bd..1bc939a965 100644 --- a/pkg/ide/zed.go +++ b/pkg/ide/zed.go @@ -14,14 +14,14 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenZed(activeProfile config.Profile, workspaceId, projectName, gpgKey string) error { +func OpenZed(activeProfile config.Profile, targetId, projectName, gpgKey string) error { path, err := GetZedBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, workspaceId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, workspaceId, projectName, gpgKey) + projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) if err != nil { return err } diff --git a/pkg/logs/logger.go b/pkg/logs/logger.go index 8fa7c28333..3c88daa5d6 100644 --- a/pkg/logs/logger.go +++ b/pkg/logs/logger.go @@ -24,7 +24,7 @@ const ( type LogEntry struct { Source string `json:"source"` - WorkspaceId *string `json:"workspaceId,omitempty"` + TargetId *string `json:"targetId,omitempty"` ProjectName *string `json:"projectName,omitempty"` BuildId *string `json:"buildId,omitempty"` Msg string `json:"msg"` @@ -33,24 +33,24 @@ type LogEntry struct { } type LoggerFactory interface { - CreateWorkspaceLogger(workspaceId string, source LogSource) Logger - CreateProjectLogger(workspaceId, projectName string, source LogSource) Logger + CreateTargetLogger(targetId string, source LogSource) Logger + CreateProjectLogger(targetId, projectName string, source LogSource) Logger CreateBuildLogger(buildId string, source LogSource) Logger - CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) - CreateProjectLogReader(workspaceId, projectName string) (io.Reader, error) + CreateTargetLogReader(targetId string) (io.Reader, error) + CreateProjectLogReader(targetId, projectName string) (io.Reader, error) CreateBuildLogReader(buildId string) (io.Reader, error) } type loggerFactoryImpl struct { - wsLogsDir string - buildLogsDir string + targetLogsDir string + buildLogsDir string } -func NewLoggerFactory(wsLogsDir *string, buildLogsDir *string) LoggerFactory { +func NewLoggerFactory(targetLogsDir *string, buildLogsDir *string) LoggerFactory { loggerFactoryImpl := &loggerFactoryImpl{} - if wsLogsDir != nil { - loggerFactoryImpl.wsLogsDir = *wsLogsDir + if targetLogsDir != nil { + loggerFactoryImpl.targetLogsDir = *targetLogsDir } if buildLogsDir != nil { diff --git a/pkg/logs/project.go b/pkg/logs/project.go index 23d9f50e04..0e05bc6176 100644 --- a/pkg/logs/project.go +++ b/pkg/logs/project.go @@ -15,7 +15,7 @@ import ( type projectLogger struct { logsDir string - workspaceId string + targetId string projectName string logFile *os.File logger *logrus.Logger @@ -24,7 +24,7 @@ type projectLogger struct { func (pl *projectLogger) Write(p []byte) (n int, err error) { if pl.logFile == nil { - filePath := filepath.Join(pl.logsDir, pl.workspaceId, pl.projectName, "log") + filePath := filepath.Join(pl.logsDir, pl.targetId, pl.projectName, "log") err = os.MkdirAll(filepath.Dir(filePath), 0755) if err != nil { return len(p), err @@ -41,7 +41,7 @@ func (pl *projectLogger) Write(p []byte) (n int, err error) { var entry LogEntry entry.Msg = string(p) entry.Source = string(pl.source) - entry.WorkspaceId = &pl.workspaceId + entry.TargetId = &pl.targetId entry.ProjectName = &pl.projectName entry.Time = time.Now().Format(time.RFC3339) @@ -70,7 +70,7 @@ func (pl *projectLogger) Close() error { } func (pl *projectLogger) Cleanup() error { - projectLogsDir := filepath.Join(pl.logsDir, pl.workspaceId, pl.projectName) + projectLogsDir := filepath.Join(pl.logsDir, pl.targetId, pl.projectName) _, err := os.Stat(projectLogsDir) if os.IsNotExist(err) { @@ -82,19 +82,19 @@ func (pl *projectLogger) Cleanup() error { return os.RemoveAll(projectLogsDir) } -func (l *loggerFactoryImpl) CreateProjectLogger(workspaceId, projectName string, source LogSource) Logger { +func (l *loggerFactoryImpl) CreateProjectLogger(targetId, projectName string, source LogSource) Logger { logger := logrus.New() return &projectLogger{ - workspaceId: workspaceId, - logsDir: l.wsLogsDir, + targetId: targetId, + logsDir: l.targetLogsDir, projectName: projectName, logger: logger, source: source, } } -func (l *loggerFactoryImpl) CreateProjectLogReader(workspaceId, projectName string) (io.Reader, error) { - filePath := filepath.Join(l.wsLogsDir, workspaceId, projectName, "log") +func (l *loggerFactoryImpl) CreateProjectLogReader(targetId, projectName string) (io.Reader, error) { + filePath := filepath.Join(l.targetLogsDir, targetId, projectName, "log") return os.Open(filePath) } diff --git a/pkg/logs/workspace.go b/pkg/logs/target.go similarity index 54% rename from pkg/logs/workspace.go rename to pkg/logs/target.go index 277055bbee..c5a0d3f392 100644 --- a/pkg/logs/workspace.go +++ b/pkg/logs/target.go @@ -13,17 +13,17 @@ import ( "github.com/sirupsen/logrus" ) -type workspaceLogger struct { - logsDir string - workspaceId string - logFile *os.File - logger *logrus.Logger - source LogSource +type targetLogger struct { + logsDir string + targetId string + logFile *os.File + logger *logrus.Logger + source LogSource } -func (w *workspaceLogger) Write(p []byte) (n int, err error) { +func (w *targetLogger) Write(p []byte) (n int, err error) { if w.logFile == nil { - filePath := filepath.Join(w.logsDir, w.workspaceId, "log") + filePath := filepath.Join(w.logsDir, w.targetId, "log") err = os.MkdirAll(filepath.Dir(filePath), 0755) if err != nil { return len(p), err @@ -39,7 +39,7 @@ func (w *workspaceLogger) Write(p []byte) (n int, err error) { var entry LogEntry entry.Msg = string(p) entry.Source = string(w.source) - entry.WorkspaceId = &w.workspaceId + entry.TargetId = &w.targetId entry.Time = time.Now().Format(time.RFC3339) b, err := json.Marshal(entry) @@ -57,7 +57,7 @@ func (w *workspaceLogger) Write(p []byte) (n int, err error) { return len(p), nil } -func (w *workspaceLogger) Close() error { +func (w *targetLogger) Close() error { if w.logFile != nil { err := w.logFile.Close() w.logFile = nil @@ -66,31 +66,31 @@ func (w *workspaceLogger) Close() error { return nil } -func (w *workspaceLogger) Cleanup() error { - workspaceLogsDir := filepath.Join(w.logsDir, w.workspaceId) +func (w *targetLogger) Cleanup() error { + targetLogsDir := filepath.Join(w.logsDir, w.targetId) - _, err := os.Stat(workspaceLogsDir) + _, err := os.Stat(targetLogsDir) if os.IsNotExist(err) { return nil } else if err != nil { return err } - return os.RemoveAll(workspaceLogsDir) + return os.RemoveAll(targetLogsDir) } -func (l *loggerFactoryImpl) CreateWorkspaceLogger(workspaceId string, source LogSource) Logger { +func (l *loggerFactoryImpl) CreateTargetLogger(targetId string, source LogSource) Logger { logger := logrus.New() - return &workspaceLogger{ - workspaceId: workspaceId, - logsDir: l.wsLogsDir, - logger: logger, - source: source, + return &targetLogger{ + targetId: targetId, + logsDir: l.targetLogsDir, + logger: logger, + source: source, } } -func (l *loggerFactoryImpl) CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) { - filePath := filepath.Join(l.wsLogsDir, workspaceId, "log") +func (l *loggerFactoryImpl) CreateTargetLogReader(targetId string) (io.Reader, error) { + filePath := filepath.Join(l.targetLogsDir, targetId, "log") return os.Open(filePath) } diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 8b2557a304..af658bfd3e 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -7,8 +7,8 @@ import ( "net/rpc" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/hashicorp/go-plugin" ) @@ -20,11 +20,11 @@ type Provider interface { GetTargetConfigManifest() (*TargetConfigManifest, error) GetPresetTargetConfigs() (*[]TargetConfig, error) - CreateWorkspace(*WorkspaceRequest) (*util.Empty, error) - StartWorkspace(*WorkspaceRequest) (*util.Empty, error) - StopWorkspace(*WorkspaceRequest) (*util.Empty, error) - DestroyWorkspace(*WorkspaceRequest) (*util.Empty, error) - GetWorkspaceInfo(*WorkspaceRequest) (*workspace.WorkspaceInfo, error) + CreateTarget(*TargetRequest) (*util.Empty, error) + StartTarget(*TargetRequest) (*util.Empty, error) + StopTarget(*TargetRequest) (*util.Empty, error) + DestroyTarget(*TargetRequest) (*util.Empty, error) + GetTargetInfo(*TargetRequest) (*target.TargetInfo, error) CreateProject(*ProjectRequest) (*util.Empty, error) StartProject(*ProjectRequest) (*util.Empty, error) diff --git a/pkg/provider/rpc_client.go b/pkg/provider/rpc_client.go index e9f619db44..db6281fa8e 100644 --- a/pkg/provider/rpc_client.go +++ b/pkg/provider/rpc_client.go @@ -7,8 +7,8 @@ import ( "net/rpc" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) type ProviderRPCClient struct { @@ -45,29 +45,29 @@ func (m *ProviderRPCClient) GetPresetTargetConfigs() (*[]TargetConfig, error) { return &resp, err } -func (m *ProviderRPCClient) CreateWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.CreateWorkspace", workspaceReq, new(util.Empty)) +func (m *ProviderRPCClient) CreateTarget(targetReq *TargetRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.CreateTarget", targetReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) StartWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.StartWorkspace", workspaceReq, new(util.Empty)) +func (m *ProviderRPCClient) StartTarget(targetReq *TargetRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.StartTarget", targetReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) StopWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.StopWorkspace", workspaceReq, new(util.Empty)) +func (m *ProviderRPCClient) StopTarget(targetReq *TargetRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.StopTarget", targetReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) DestroyWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.DestroyWorkspace", workspaceReq, new(util.Empty)) +func (m *ProviderRPCClient) DestroyTarget(targetReq *TargetRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.DestroyTarget", targetReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) GetWorkspaceInfo(workspaceReq *WorkspaceRequest) (*workspace.WorkspaceInfo, error) { - var response workspace.WorkspaceInfo - err := m.client.Call("Plugin.GetWorkspaceInfo", workspaceReq, &response) +func (m *ProviderRPCClient) GetTargetInfo(targetReq *TargetRequest) (*target.TargetInfo, error) { + var response target.TargetInfo + err := m.client.Call("Plugin.GetTargetInfo", targetReq, &response) return &response, err } diff --git a/pkg/provider/rpc_server.go b/pkg/provider/rpc_server.go index 7b3dc624f1..691411dec6 100644 --- a/pkg/provider/rpc_server.go +++ b/pkg/provider/rpc_server.go @@ -5,8 +5,8 @@ package provider import ( "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) type ProviderRPCServer struct { @@ -57,28 +57,28 @@ func (m *ProviderRPCServer) GetPresetTargetConfigs(arg interface{}, resp *[]Targ return nil } -func (m *ProviderRPCServer) CreateWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { - _, err := m.Impl.CreateWorkspace(arg) +func (m *ProviderRPCServer) CreateTarget(arg *TargetRequest, resp *util.Empty) error { + _, err := m.Impl.CreateTarget(arg) return err } -func (m *ProviderRPCServer) StartWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { - _, err := m.Impl.StartWorkspace(arg) +func (m *ProviderRPCServer) StartTarget(arg *TargetRequest, resp *util.Empty) error { + _, err := m.Impl.StartTarget(arg) return err } -func (m *ProviderRPCServer) StopWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { - _, err := m.Impl.StopWorkspace(arg) +func (m *ProviderRPCServer) StopTarget(arg *TargetRequest, resp *util.Empty) error { + _, err := m.Impl.StopTarget(arg) return err } -func (m *ProviderRPCServer) DestroyWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { - _, err := m.Impl.DestroyWorkspace(arg) +func (m *ProviderRPCServer) DestroyTarget(arg *TargetRequest, resp *util.Empty) error { + _, err := m.Impl.DestroyTarget(arg) return err } -func (m *ProviderRPCServer) GetWorkspaceInfo(arg *WorkspaceRequest, resp *workspace.WorkspaceInfo) error { - info, err := m.Impl.GetWorkspaceInfo(arg) +func (m *ProviderRPCServer) GetTargetInfo(arg *TargetRequest, resp *target.TargetInfo) error { + info, err := m.Impl.GetTargetInfo(arg) if err != nil { return err } diff --git a/pkg/provider/types.go b/pkg/provider/types.go index 2f8d6c91ae..9447244fc0 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -6,8 +6,8 @@ package provider import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) type ProviderInfo struct { @@ -31,9 +31,9 @@ type InitializeProviderRequest struct { ApiPort uint32 } -type WorkspaceRequest struct { +type TargetRequest struct { TargetConfigOptions string - Workspace *workspace.Workspace + Target *target.Target } type ProjectRequest struct { diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index b70ca674b7..6a4d55ea56 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -5,18 +5,18 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" ) -func (p *Provisioner) CreateWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { +func (p *Provisioner) CreateTarget(target *target.Target, targetConfig *provider.TargetConfig) error { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ + _, err = (*targetProvider).CreateTarget(&provider.TargetRequest{ TargetConfigOptions: targetConfig.Options, - Workspace: workspace, + Target: target, }) return err diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index 4c49d20284..2e989e0122 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -5,19 +5,19 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) -func (p *Provisioner) DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { +func (p *Provisioner) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).DestroyWorkspace(&provider.WorkspaceRequest{ + _, err = (*targetProvider).DestroyTarget(&provider.TargetRequest{ TargetConfigOptions: targetConfig.Options, - Workspace: workspace, + Target: target, }) return err diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go index 25d1ba2a7e..717a6a3f45 100644 --- a/pkg/provisioner/info.go +++ b/pkg/provisioner/info.go @@ -7,16 +7,16 @@ import ( "context" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" ) type InfoResult struct { - Info *workspace.WorkspaceInfo + Info *target.TargetInfo Err error } -// Gets the workspace info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, ws *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { +// Gets the target info from the provider - the context is used to cancel the request if it takes too long +func (p *Provisioner) GetTargetInfo(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) { ch := make(chan InfoResult, 1) go func() { @@ -26,9 +26,9 @@ func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, ws *workspace.Worksp return } - info, err := (*targetProvider).GetWorkspaceInfo(&provider.WorkspaceRequest{ + info, err := (*targetProvider).GetTargetInfo(&provider.TargetRequest{ TargetConfigOptions: targetConfig.Options, - Workspace: ws, + Target: target, }) ch <- InfoResult{info, err} diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index 83b2b19d5a..3a21ee2e9a 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) type ProjectParams struct { @@ -24,15 +24,16 @@ type ProjectParams struct { } type IProvisioner interface { + CreateTarget(target *target.Target, targetConfig *provider.TargetConfig) error + StartTarget(target *target.Target, targetConfig *provider.TargetConfig) error + StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error + GetTargetInfo(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) + DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error + CreateProject(params ProjectParams) error - CreateWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error DestroyProject(project *project.Project, targetConfig *provider.TargetConfig) error - DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error - GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) StartProject(params ProjectParams) error - StartWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error StopProject(project *project.Project, targetConfig *provider.TargetConfig) error - StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error } type ProvisionerConfig struct { diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index 79fe3e6b8a..f71a1f6e59 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -5,18 +5,18 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" ) -func (p *Provisioner) StartWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { +func (p *Provisioner) StartTarget(target *target.Target, targetConfig *provider.TargetConfig) error { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ + _, err = (*targetProvider).StartTarget(&provider.TargetRequest{ TargetConfigOptions: targetConfig.Options, - Workspace: workspace, + Target: target, }) return err diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index b8b29316cd..efda1d5ee6 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -5,19 +5,19 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" ) -func (p *Provisioner) StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error { +func (p *Provisioner) StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).StopWorkspace(&provider.WorkspaceRequest{ + _, err = (*targetProvider).StopTarget(&provider.TargetRequest{ TargetConfigOptions: targetConfig.Options, - Workspace: workspace, + Target: target, }) return err diff --git a/pkg/server/apikeys/service.go b/pkg/server/apikeys/service.go index 42bb25ebb2..272dec8d60 100644 --- a/pkg/server/apikeys/service.go +++ b/pkg/server/apikeys/service.go @@ -8,7 +8,7 @@ import "github.com/daytonaio/daytona/pkg/apikey" type IApiKeyService interface { Generate(keyType apikey.ApiKeyType, name string) (string, error) IsProjectApiKey(apiKey string) bool - IsWorkspaceApiKey(apiKey string) bool + IsTargetApiKey(apiKey string) bool IsValidApiKey(apiKey string) bool ListClientKeys() ([]*apikey.ApiKey, error) Revoke(name string) error diff --git a/pkg/server/apikeys/validate.go b/pkg/server/apikeys/validate.go index 89454bc8ec..a065a91db5 100644 --- a/pkg/server/apikeys/validate.go +++ b/pkg/server/apikeys/validate.go @@ -30,7 +30,7 @@ func (s *ApiKeyService) IsProjectApiKey(apiKey string) bool { return true } -func (s *ApiKeyService) IsWorkspaceApiKey(apiKey string) bool { +func (s *ApiKeyService) IsTargetApiKey(apiKey string) bool { keyHash := apikeys.HashKey(apiKey) key, err := s.apiKeyStore.Find(keyHash) @@ -38,7 +38,7 @@ func (s *ApiKeyService) IsWorkspaceApiKey(apiKey string) bool { return false } - if key.Type != apikey.ApiKeyTypeWorkspace { + if key.Type != apikey.ApiKeyTypeTarget { return false } diff --git a/pkg/server/apikeys/validate_test.go b/pkg/server/apikeys/validate_test.go index 003090cdce..996c93ce7a 100644 --- a/pkg/server/apikeys/validate_test.go +++ b/pkg/server/apikeys/validate_test.go @@ -50,19 +50,19 @@ func (s *ApiKeyServiceTestSuite) TestIsProjectApiKey_False() { require.False(res) } -func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_True() { - keyName := "workspaceKey" +func (s *ApiKeyServiceTestSuite) TestIsIsTargetApiKey_True() { + keyName := "targetKey" require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, keyName) require.Nil(err) - res := s.apiKeyService.IsWorkspaceApiKey(apiKey) + res := s.apiKeyService.IsTargetApiKey(apiKey) require.True(res) } -func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_False() { +func (s *ApiKeyServiceTestSuite) TestIsTargetApiKey_False() { keyName := "clientKey" require := s.Require() @@ -70,6 +70,6 @@ func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_False() { apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) require.Nil(err) - res := s.apiKeyService.IsWorkspaceApiKey(apiKey) + res := s.apiKeyService.IsTargetApiKey(apiKey) require.False(res) } diff --git a/pkg/server/builds/dto/builds.go b/pkg/server/builds/dto/builds.go index 82c9c7311b..03cb9df14b 100644 --- a/pkg/server/builds/dto/builds.go +++ b/pkg/server/builds/dto/builds.go @@ -5,7 +5,7 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type BuildCreationData struct { diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index 1681ec6386..f7582bd423 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/project/containerconfig" "github.com/docker/docker/pkg/stringid" ) diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 4124b85613..ed4804dad2 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/containerconfig" "github.com/stretchr/testify/suite" ) diff --git a/pkg/server/config.go b/pkg/server/config.go index c72227d1b8..b35e07af4f 100644 --- a/pkg/server/config.go +++ b/pkg/server/config.go @@ -114,7 +114,7 @@ func GetConfigDir() (string, error) { return filepath.Join(configDir, "server"), nil } -func GetWorkspaceLogsDir(configDir string) (string, error) { +func GetTargetLogsDir(configDir string) (string, error) { return filepath.Join(configDir, "logs"), nil } diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index 3f7b9c0a51..d4baf22866 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -3,7 +3,7 @@ package gitproviders -import "github.com/daytonaio/daytona/pkg/workspace/project/config" +import "github.com/daytonaio/daytona/pkg/target/project/config" func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { gitProvider, err := s.configStore.Find(gitProviderId) diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index 8a48c13c0b..3fbc109d02 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" ) type IGitProviderService interface { diff --git a/pkg/server/projectconfig/dto/projectconfig.go b/pkg/server/projectconfig/dto/projectconfig.go index 9ff6ab4082..15f036a2e9 100644 --- a/pkg/server/projectconfig/dto/projectconfig.go +++ b/pkg/server/projectconfig/dto/projectconfig.go @@ -4,7 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type CreateProjectConfigDTO struct { diff --git a/pkg/server/projectconfig/prebuild.go b/pkg/server/projectconfig/prebuild.go index 5c28533bdf..f154fba0d4 100644 --- a/pkg/server/projectconfig/prebuild.go +++ b/pkg/server/projectconfig/prebuild.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" - "github.com/daytonaio/daytona/pkg/workspace/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/project/config" + "github.com/daytonaio/daytona/pkg/target/project/containerconfig" log "github.com/sirupsen/logrus" ) diff --git a/pkg/server/projectconfig/prebuild_test.go b/pkg/server/projectconfig/prebuild_test.go index d780a30186..b498abc332 100644 --- a/pkg/server/projectconfig/prebuild_test.go +++ b/pkg/server/projectconfig/prebuild_test.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" ) var prebuild1 *config.PrebuildConfig = &config.PrebuildConfig{ diff --git a/pkg/server/projectconfig/service.go b/pkg/server/projectconfig/service.go index 89e1f7dadd..56d4e0f55e 100644 --- a/pkg/server/projectconfig/service.go +++ b/pkg/server/projectconfig/service.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" ) type IProjectConfigService interface { diff --git a/pkg/server/projectconfig/service_test.go b/pkg/server/projectconfig/service_test.go index b1733cd274..2e2985c102 100644 --- a/pkg/server/projectconfig/service_test.go +++ b/pkg/server/projectconfig/service_test.go @@ -8,10 +8,10 @@ import ( git_provider_mock "github.com/daytonaio/daytona/internal/testing/gitprovider/mocks" projectconfig_internal "github.com/daytonaio/daytona/internal/testing/server/projectconfig" - "github.com/daytonaio/daytona/internal/testing/server/workspaces/mocks" + "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/server/projectconfig" - "github.com/daytonaio/daytona/pkg/workspace/project/config" + "github.com/daytonaio/daytona/pkg/target/project/config" "github.com/stretchr/testify/suite" ) diff --git a/pkg/server/purge.go b/pkg/server/purge.go index cd292f368f..f2a74fb8c9 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -28,7 +28,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { } } - fmt.Println("Deleting all workspaces...") + fmt.Println("Deleting all targets...") err := server.Start() if err != nil { @@ -36,7 +36,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { return []error{err} } - workspaces, err := s.WorkspaceService.ListWorkspaces(ctx, false) + targets, err := s.TargetService.ListTargets(ctx, false) if err != nil { s.trackPurgeError(ctx, force, err) if !force { @@ -45,21 +45,21 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { } if err == nil { - for _, workspace := range workspaces { - err := s.WorkspaceService.RemoveWorkspace(ctx, workspace.Id) + for _, target := range targets { + err := s.TargetService.RemoveTarget(ctx, target.Id) if err != nil { s.trackPurgeError(ctx, force, err) if !force { return []error{err} } else { - fmt.Printf("Failed to delete %s: %v\n", workspace.Name, err) + fmt.Printf("Failed to delete %s: %v\n", target.Name, err) } } else { - fmt.Printf("Workspace %s deleted\n", workspace.Name) + fmt.Printf("Target %s deleted\n", target.Name) } } } else { - fmt.Printf("Failed to list workspaces: %v\n", err) + fmt.Printf("Failed to list targets: %v\n", err) } fmt.Println("Purging providers...") diff --git a/pkg/server/server.go b/pkg/server/server.go index a3eb04481f..ec652e5c7c 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -15,7 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/projectconfig" "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/hashicorp/go-plugin" @@ -31,7 +31,7 @@ type ServerInstanceConfig struct { BuildService builds.IBuildService ProjectConfigService projectconfig.IProjectConfigService LocalContainerRegistry ILocalContainerRegistry - WorkspaceService workspaces.IWorkspaceService + TargetService targets.ITargetService ApiKeyService apikeys.IApiKeyService GitProviderService gitproviders.IGitProviderService ProviderManager manager.IProviderManager @@ -60,7 +60,7 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { BuildService: serverConfig.BuildService, ProjectConfigService: serverConfig.ProjectConfigService, LocalContainerRegistry: serverConfig.LocalContainerRegistry, - WorkspaceService: serverConfig.WorkspaceService, + TargetService: serverConfig.TargetService, ApiKeyService: serverConfig.ApiKeyService, GitProviderService: serverConfig.GitProviderService, ProviderManager: serverConfig.ProviderManager, @@ -82,7 +82,7 @@ type Server struct { BuildService builds.IBuildService ProjectConfigService projectconfig.IProjectConfigService LocalContainerRegistry ILocalContainerRegistry - WorkspaceService workspaces.IWorkspaceService + TargetService targets.ITargetService ApiKeyService apikeys.IApiKeyService GitProviderService gitproviders.IGitProviderService ProviderManager manager.IProviderManager diff --git a/pkg/server/workspaces/create.go b/pkg/server/targets/create.go similarity index 70% rename from pkg/server/workspaces/create.go rename to pkg/server/targets/create.go index 2ccd6fd4c2..b53512136e 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/targets/create.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package targets import ( "context" @@ -19,16 +19,16 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" log "github.com/sirupsen/logrus" ) -func isValidWorkspaceName(name string) bool { +func isValidTargetName(name string) bool { // The repository name can only contain ASCII letters, digits, and the characters ., -, and _. var validName = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) @@ -45,30 +45,30 @@ func isValidWorkspaceName(name string) bool { return true } -func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*workspace.Workspace, error) { - _, err := s.workspaceStore.Find(req.Name) +func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*target.Target, error) { + _, err := s.targetStore.Find(req.Name) if err == nil { - return nil, ErrWorkspaceAlreadyExists + return nil, ErrTargetAlreadyExists } - // Repo name is taken as the name for workspace by default - if !isValidWorkspaceName(req.Name) { - return nil, ErrInvalidWorkspaceName + // Repo name is taken as the name for target by default + if !isValidTargetName(req.Name) { + return nil, ErrInvalidTargetName } - w := &workspace.Workspace{ + target := &target.Target{ Id: req.Id, Name: req.Name, TargetConfig: req.TargetConfig, } - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, w.Id) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, target.Id) if err != nil { return nil, err } - w.ApiKey = apiKey + target.ApiKey = apiKey - w.Projects = []*project.Project{} + target.Projects = []*project.Project{} for _, projectDto := range req.Projects { p := conversion.CreateDtoToProject(projectDto) @@ -117,50 +117,50 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo p.User = s.defaultProjectUser } - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeProject, fmt.Sprintf("%s/%s", w.Id, p.Name)) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeProject, fmt.Sprintf("%s/%s", target.Id, p.Name)) if err != nil { return nil, err } - p.WorkspaceId = w.Id + p.TargetId = target.Id p.ApiKey = apiKey - p.TargetConfig = w.TargetConfig - w.Projects = append(w.Projects, p) + p.TargetConfig = target.TargetConfig + target.Projects = append(target.Projects, p) } - err = s.workspaceStore.Save(w) + err = s.targetStore.Save(target) if err != nil { return nil, err } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) if err != nil { - return w, err + return target, err } - w, err = s.createWorkspace(ctx, w, targetConfig) + target, err = s.createTarget(ctx, target, targetConfig) if !telemetry.TelemetryEnabled(ctx) { - return w, err + return target, err } clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w, targetConfig) - event := telemetry.ServerEventWorkspaceCreated + telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) + event := telemetry.ServerEventTargetCreated if err != nil { telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceCreateError + event = telemetry.ServerEventTargetCreateError } telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) if telemetryError != nil { log.Trace(err) } - return w, err + return target, err } -func (s *WorkspaceService) createProject(p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { +func (s *TargetService) createProject(p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { logWriter.Write([]byte(fmt.Sprintf("Creating project %s\n", p.Name))) cr, err := s.containerRegistryService.FindByImageName(p.Image) @@ -199,26 +199,26 @@ func (s *WorkspaceService) createProject(p *project.Project, targetConfig *provi return nil } -func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.Workspace, error) { - wsLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, logs.LogSourceServer) - defer wsLogger.Close() +func (s *TargetService) createTarget(ctx context.Context, t *target.Target, targetConfig *provider.TargetConfig) (*target.Target, error) { + targetLogger := s.loggerFactory.CreateTargetLogger(t.Id, logs.LogSourceServer) + defer targetLogger.Close() - wsLogger.Write([]byte(fmt.Sprintf("Creating workspace %s (%s)\n", ws.Name, ws.Id))) + targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", t.Name, t.Id))) - ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ + t.EnvVars = target.GetTargetEnvVars(t, target.TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err := s.provisioner.CreateWorkspace(ws, targetConfig) + err := s.provisioner.CreateTarget(t, targetConfig) if err != nil { return nil, err } - for i, p := range ws.Projects { - projectLogger := s.loggerFactory.CreateProjectLogger(ws.Id, p.Name, logs.LogSourceServer) + for i, p := range t.Projects { + projectLogger := s.loggerFactory.CreateProjectLogger(t.Id, p.Name, logs.LogSourceServer) defer projectLogger.Close() projectWithEnv := *p @@ -237,8 +237,8 @@ func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Wo p = &projectWithEnv - ws.Projects[i] = p - err = s.workspaceStore.Save(ws) + t.Projects[i] = p + err = s.targetStore.Save(t) if err != nil { return nil, err } @@ -249,17 +249,17 @@ func (s *WorkspaceService) createWorkspace(ctx context.Context, ws *workspace.Wo } } - wsLogger.Write([]byte("Workspace creation complete. Pending start...\n")) + targetLogger.Write([]byte("Target creation complete. Pending start...\n")) - err = s.startWorkspace(ctx, ws, targetConfig, wsLogger) + err = s.startTarget(ctx, t, targetConfig, targetLogger) if err != nil { return nil, err } - return ws, nil + return t, nil } -func (s *WorkspaceService) getCachedBuildForProject(p *project.Project) (*buildconfig.CachedBuild, error) { +func (s *TargetService) getCachedBuildForProject(p *project.Project) (*buildconfig.CachedBuild, error) { validStates := &[]build.BuildState{ build.BuildState(build.BuildStatePublished), } diff --git a/pkg/server/workspaces/dto/workspace.go b/pkg/server/targets/dto/target.go similarity index 79% rename from pkg/server/workspaces/dto/workspace.go rename to pkg/server/targets/dto/target.go index b6c02c857d..f8b256681b 100644 --- a/pkg/server/workspaces/dto/workspace.go +++ b/pkg/server/targets/dto/target.go @@ -5,27 +5,27 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) -type WorkspaceDTO struct { - workspace.Workspace - Info *workspace.WorkspaceInfo `json:"info" validate:"optional"` -} // @name WorkspaceDTO +type TargetDTO struct { + target.Target + Info *target.TargetInfo `json:"info" validate:"optional"` +} // @name TargetDTO type ProjectDTO struct { project.Project Info *project.ProjectInfo `json:"info" validate:"optional"` } // @name ProjectDTO -type CreateWorkspaceDTO struct { +type CreateTargetDTO struct { Id string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` TargetConfig string `json:"targetConfig" validate:"required"` Projects []CreateProjectDTO `json:"projects" validate:"required,gt=0,dive"` -} // @name CreateWorkspaceDTO +} // @name CreateTargetDTO type CreateProjectDTO struct { Name string `json:"name" validate:"required"` diff --git a/pkg/server/targets/error.go b/pkg/server/targets/error.go new file mode 100644 index 0000000000..cdc6318016 --- /dev/null +++ b/pkg/server/targets/error.go @@ -0,0 +1,17 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "errors" +) + +var ( + ErrTargetAlreadyExists = errors.New("target already exists") + ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") + ErrTargetNotFound = errors.New("target not found") + ErrProjectNotFound = errors.New("project not found") + ErrInvalidProjectName = errors.New("project name is not valid. Only [a-zA-Z0-9-_.] are allowed") + ErrInvalidProjectConfig = errors.New("project config is invalid") +) diff --git a/pkg/server/workspaces/get.go b/pkg/server/targets/get.go similarity index 51% rename from pkg/server/workspaces/get.go rename to pkg/server/targets/get.go index b21d83979b..499d4dff4e 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/targets/get.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package targets import ( "context" @@ -11,25 +11,25 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/server/targets/dto" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) { - ws, err := s.workspaceStore.Find(workspaceId) +func (s *TargetService) GetTarget(ctx context.Context, targetId string, verbose bool) (*dto.TargetDTO, error) { + tg, err := s.targetStore.Find(targetId) if err != nil { - return nil, ErrWorkspaceNotFound + return nil, ErrTargetNotFound } - response := dto.WorkspaceDTO{ - Workspace: *ws, + response := dto.TargetDTO{ + Target: *tg, } if !verbose { return &response, nil } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &ws.TargetConfig}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &tg.TargetConfig}) if err != nil { return nil, err } @@ -40,23 +40,23 @@ func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, resultCh := make(chan provisioner.InfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws, targetConfig) - resultCh <- provisioner.InfoResult{Info: workspaceInfo, Err: err} + targetInfo, err := s.provisioner.GetTargetInfo(ctx, tg, targetConfig) + resultCh <- provisioner.InfoResult{Info: targetInfo, Err: err} }() select { case res := <-resultCh: if res.Err != nil { - log.Error(fmt.Errorf("failed to get workspace info for %s: %v", ws.Name, res.Err)) + log.Error(fmt.Errorf("failed to get target info for %s: %v", tg.Name, res.Err)) return nil, res.Err } response.Info = res.Info case <-ctx.Done(): if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting workspace info for %s", ws.Name)) + log.Warn(fmt.Sprintf("timeout getting target info for %s", tg.Name)) } else { - log.Warn(fmt.Sprintf("cancelled getting workspace info for %s", ws.Name)) + log.Warn(fmt.Sprintf("cancelled getting target info for %s", tg.Name)) } } diff --git a/pkg/server/workspaces/list.go b/pkg/server/targets/list.go similarity index 52% rename from pkg/server/workspaces/list.go rename to pkg/server/targets/list.go index 589bfa9a21..1f79c324b2 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/targets/list.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package targets import ( "context" @@ -12,21 +12,21 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/server/targets/dto" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) { - workspaces, err := s.workspaceStore.List() +func (s *TargetService) ListTargets(ctx context.Context, verbose bool) ([]dto.TargetDTO, error) { + targets, err := s.targetStore.List() if err != nil { return nil, err } var wg sync.WaitGroup - response := []dto.WorkspaceDTO{} + response := []dto.TargetDTO{} - for i, w := range workspaces { - response = append(response, dto.WorkspaceDTO{Workspace: *w}) + for i, t := range targets { + response = append(response, dto.TargetDTO{Target: *t}) if !verbose { continue } @@ -35,9 +35,9 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] go func(i int) { defer wg.Done() - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &t.TargetConfig}) if err != nil { - log.Error(fmt.Errorf("failed to get target config for %s", w.TargetConfig)) + log.Error(fmt.Errorf("failed to get target config for %s", t.TargetConfig)) return } @@ -47,23 +47,23 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] resultCh := make(chan provisioner.InfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, w, targetConfig) - resultCh <- provisioner.InfoResult{Info: workspaceInfo, Err: err} + targetInfo, err := s.provisioner.GetTargetInfo(ctx, t, targetConfig) + resultCh <- provisioner.InfoResult{Info: targetInfo, Err: err} }() select { case res := <-resultCh: if res.Err != nil { - log.Error(fmt.Errorf("failed to get workspace info for %s: %v", w.Name, res.Err)) + log.Error(fmt.Errorf("failed to get target info for %s: %v", t.Name, res.Err)) return } response[i].Info = res.Info case <-ctx.Done(): if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting workspace info for %s", w.Name)) + log.Warn(fmt.Sprintf("timeout getting target info for %s", t.Name)) } else { - log.Warn(fmt.Sprintf("cancelled getting workspace info for %s", w.Name)) + log.Warn(fmt.Sprintf("cancelled getting target info for %s", t.Name)) } } }(i) diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go new file mode 100644 index 0000000000..25608bc1c4 --- /dev/null +++ b/pkg/server/targets/remove.go @@ -0,0 +1,153 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" +) + +func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { + target, err := s.targetStore.Find(targetId) + if err != nil { + return ErrTargetNotFound + } + + log.Infof("Destroying target %s", target.Id) + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return err + } + + for _, project := range target.Projects { + // todo: go routines + err := s.provisioner.DestroyProject(project, targetConfig) + if err != nil { + return err + } + } + + err = s.provisioner.DestroyTarget(target, targetConfig) + if err != nil { + return err + } + + // Should not fail the whole operation if the API key cannot be revoked + err = s.apiKeyService.Revoke(target.Id) + if err != nil { + log.Error(err) + } + + for _, project := range target.Projects { + err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, project.Name)) + if err != nil { + // Should not fail the whole operation if the API key cannot be revoked + log.Error(err) + } + projectLogger := s.loggerFactory.CreateProjectLogger(target.Id, project.Name, logs.LogSourceServer) + err = projectLogger.Cleanup() + if err != nil { + // Should not fail the whole operation if the project logger cannot be cleaned up + log.Error(err) + } + } + + logger := s.loggerFactory.CreateTargetLogger(target.Id, logs.LogSourceServer) + err = logger.Cleanup() + if err != nil { + // Should not fail the whole operation if the target logger cannot be cleaned up + log.Error(err) + } + + err = s.targetStore.Delete(target) + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) + event := telemetry.ServerEventTargetDestroyed + if err != nil { + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventTargetDestroyError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} + +// ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. +func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { + target, err := s.targetStore.Find(targetId) + if err != nil { + return ErrTargetNotFound + } + + log.Infof("Destroying target %s", target.Id) + + targetConfig, _ := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + + for _, project := range target.Projects { + // todo: go routines + err := s.provisioner.DestroyProject(project, targetConfig) + if err != nil { + log.Error(err) + } + } + + err = s.provisioner.DestroyTarget(target, targetConfig) + if err != nil { + log.Error(err) + } + + err = s.apiKeyService.Revoke(target.Id) + if err != nil { + log.Error(err) + } + + for _, project := range target.Projects { + err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, project.Name)) + if err != nil { + log.Error(err) + } + + projectLogger := s.loggerFactory.CreateProjectLogger(target.Id, project.Name, logs.LogSourceServer) + err = projectLogger.Cleanup() + if err != nil { + log.Error(err) + } + } + + err = s.targetStore.Delete(target) + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) + event := telemetry.ServerEventTargetDestroyed + if err != nil { + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventTargetDestroyError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/server/workspaces/service.go b/pkg/server/targets/service.go similarity index 59% rename from pkg/server/workspaces/service.go rename to pkg/server/targets/service.go index 508ead25d5..55fbc50011 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/targets/service.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package targets import ( "context" @@ -16,33 +16,34 @@ import ( "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/projectconfig" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" ) -type IWorkspaceService interface { - CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*workspace.Workspace, error) - GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) - GetWorkspaceLogReader(workspaceId string) (io.Reader, error) - GetProjectLogReader(workspaceId, projectName string) (io.Reader, error) - ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) - RemoveWorkspace(ctx context.Context, workspaceId string) error - ForceRemoveWorkspace(ctx context.Context, workspaceId string) error - SetProjectState(workspaceId string, projectName string, state *project.ProjectState) (*workspace.Workspace, error) - StartProject(ctx context.Context, workspaceId string, projectName string) error - StartWorkspace(ctx context.Context, workspaceId string) error - StopProject(ctx context.Context, workspaceId string, projectName string) error - StopWorkspace(ctx context.Context, workspaceId string) error +type ITargetService interface { + CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*target.Target, error) + GetTarget(ctx context.Context, targetId string, verbose bool) (*dto.TargetDTO, error) + GetTargetLogReader(targetId string) (io.Reader, error) + ListTargets(ctx context.Context, verbose bool) ([]dto.TargetDTO, error) + StartTarget(ctx context.Context, targetId string) error + StopTarget(ctx context.Context, targetId string) error + RemoveTarget(ctx context.Context, targetId string) error + ForceRemoveTarget(ctx context.Context, targetId string) error + + GetProjectLogReader(targetId, projectName string) (io.Reader, error) + SetProjectState(targetId string, projectName string, state *project.ProjectState) (*target.Target, error) + StartProject(ctx context.Context, targetId string, projectName string) error + StopProject(ctx context.Context, targetId string, projectName string) error } type targetConfigStore interface { Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) } -type WorkspaceServiceConfig struct { - WorkspaceStore workspace.Store +type TargetServiceConfig struct { + TargetStore target.Store TargetConfigStore targetConfigStore ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService @@ -60,9 +61,9 @@ type WorkspaceServiceConfig struct { TelemetryService telemetry.TelemetryService } -func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { - return &WorkspaceService{ - workspaceStore: config.WorkspaceStore, +func NewTargetService(config TargetServiceConfig) ITargetService { + return &TargetService{ + targetStore: config.TargetStore, targetConfigStore: config.TargetConfigStore, containerRegistryService: config.ContainerRegistryService, buildService: config.BuildService, @@ -81,8 +82,8 @@ func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { } } -type WorkspaceService struct { - workspaceStore workspace.Store +type TargetService struct { + targetStore target.Store targetConfigStore targetConfigStore containerRegistryService containerregistries.IContainerRegistryService buildService builds.IBuildService @@ -100,26 +101,26 @@ type WorkspaceService struct { telemetryService telemetry.TelemetryService } -func (s *WorkspaceService) SetProjectState(workspaceId, projectName string, state *project.ProjectState) (*workspace.Workspace, error) { - ws, err := s.workspaceStore.Find(workspaceId) +func (s *TargetService) SetProjectState(targetId, projectName string, state *project.ProjectState) (*target.Target, error) { + tg, err := s.targetStore.Find(targetId) if err != nil { return nil, err } - for _, project := range ws.Projects { + for _, project := range tg.Projects { if project.Name == projectName { project.State = state - return ws, s.workspaceStore.Save(ws) + return tg, s.targetStore.Save(tg) } } return nil, errors.New("project not found") } -func (s *WorkspaceService) GetWorkspaceLogReader(workspaceId string) (io.Reader, error) { - return s.loggerFactory.CreateWorkspaceLogReader(workspaceId) +func (s *TargetService) GetTargetLogReader(targetId string) (io.Reader, error) { + return s.loggerFactory.CreateTargetLogReader(targetId) } -func (s *WorkspaceService) GetProjectLogReader(workspaceId, projectName string) (io.Reader, error) { - return s.loggerFactory.CreateProjectLogReader(workspaceId, projectName) +func (s *TargetService) GetProjectLogReader(targetId, projectName string) (io.Reader, error) { + return s.loggerFactory.CreateProjectLogReader(targetId, projectName) } diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/targets/service_test.go similarity index 51% rename from pkg/server/workspaces/service_test.go rename to pkg/server/targets/service_test.go index b65149a7ac..2fb20ed65e 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/targets/service_test.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces_test +package targets_test import ( "context" @@ -10,8 +10,8 @@ import ( "time" t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" - t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" - "github.com/daytonaio/daytona/internal/testing/server/workspaces/mocks" + t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" + "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/containerregistry" @@ -19,11 +19,11 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -55,7 +55,7 @@ var gitProviderConfig = gitprovider.GitProviderConfig{ BaseApiUrl: &baseApiUrl, } -var createWorkspaceDto = dto.CreateWorkspaceDTO{ +var createTargetDTO = dto.CreateTargetDTO{ Name: "test", Id: "test", TargetConfig: targetConfig.Name, @@ -78,25 +78,25 @@ var createWorkspaceDto = dto.CreateWorkspaceDTO{ }, } -var workspaceInfo = workspace.WorkspaceInfo{ - Name: createWorkspaceDto.Name, +var targetInfo = target.TargetInfo{ + Name: createTargetDTO.Name, ProviderMetadata: "provider-metadata-test", Projects: []*project.ProjectInfo{ { - Name: createWorkspaceDto.Projects[0].Name, + Name: createTargetDTO.Projects[0].Name, Created: "1 min ago", IsRunning: true, ProviderMetadata: "provider-metadata-test", - WorkspaceId: createWorkspaceDto.Id, + TargetId: createTargetDTO.Id, }, }, } -func TestWorkspaceService(t *testing.T) { +func TestTargetService(t *testing.T) { ctx := context.Background() ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test") - workspaceStore := t_workspaces.NewInMemoryWorkspaceStore() + targetStore := t_targets.NewInMemoryTargetStore() containerRegistryService := mocks.NewMockContainerRegistryService() @@ -110,11 +110,11 @@ func TestWorkspaceService(t *testing.T) { gitProviderService := mocks.NewMockGitProviderService() mockProvisioner := mocks.NewMockProvisioner() - wsLogsDir := t.TempDir() + tgLogsDir := t.TempDir() buildLogsDir := t.TempDir() - service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ - WorkspaceStore: workspaceStore, + service := targets.NewTargetService(targets.TargetServiceConfig{ + TargetStore: targetStore, TargetConfigStore: targetConfigStore, ServerApiUrl: serverApiUrl, ServerUrl: serverUrl, @@ -123,38 +123,37 @@ func TestWorkspaceService(t *testing.T) { ProjectConfigService: projectConfigService, DefaultProjectImage: defaultProjectImage, DefaultProjectUser: defaultProjectUser, - BuilderImage: defaultProjectImage, ApiKeyService: apiKeyService, + BuilderImage: defaultProjectImage, Provisioner: mockProvisioner, - LoggerFactory: logs.NewLoggerFactory(&wsLogsDir, &buildLogsDir), + LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), GitProviderService: gitProviderService, }) - t.Run("CreateWorkspace", func(t *testing.T) { + t.Run("CreateTarget", func(t *testing.T) { var containerRegistry *containerregistry.ContainerRegistry containerRegistryService.On("FindByImageName", defaultProjectImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) - mockProvisioner.On("CreateWorkspace", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("CreateTarget", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) - apiKeyService.On("Generate", apikey.ApiKeyTypeWorkspace, createWorkspaceDto.Id).Return(createWorkspaceDto.Id, nil) - gitProviderService.On("GetLastCommitSha", createWorkspaceDto.Projects[0].Source.Repository).Return("123", nil) + apiKeyService.On("Generate", apikey.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) + gitProviderService.On("GetLastCommitSha", createTargetDTO.Projects[0].Source.Repository).Return("123", nil) - for _, project := range createWorkspaceDto.Projects { - apiKeyService.On("Generate", apikey.ApiKeyTypeProject, fmt.Sprintf("%s/%s", createWorkspaceDto.Id, project.Name)).Return(project.Name, nil) + for _, project := range createTargetDTO.Projects { + apiKeyService.On("Generate", apikey.ApiKeyTypeProject, fmt.Sprintf("%s/%s", createTargetDTO.Id, project.Name)).Return(project.Name, nil) } - proj := &project.Project{ - Name: createWorkspaceDto.Projects[0].Name, - Image: *createWorkspaceDto.Projects[0].Image, - User: *createWorkspaceDto.Projects[0].User, - BuildConfig: createWorkspaceDto.Projects[0].BuildConfig, - Repository: createWorkspaceDto.Projects[0].Source.Repository, - ApiKey: createWorkspaceDto.Projects[0].Name, - GitProviderConfigId: createWorkspaceDto.Projects[0].GitProviderConfigId, - WorkspaceId: createWorkspaceDto.Id, - TargetConfig: createWorkspaceDto.TargetConfig, + Name: createTargetDTO.Projects[0].Name, + Image: *createTargetDTO.Projects[0].Image, + User: *createTargetDTO.Projects[0].User, + BuildConfig: createTargetDTO.Projects[0].BuildConfig, + Repository: createTargetDTO.Projects[0].Source.Repository, + ApiKey: createTargetDTO.Projects[0].Name, + GitProviderConfigId: createTargetDTO.Projects[0].GitProviderConfigId, + TargetId: createTargetDTO.Id, + TargetConfig: createTargetDTO.TargetConfig, } proj.EnvVars = project.GetProjectEnvVars(proj, project.ProjectEnvVarParams{ @@ -183,146 +182,146 @@ func TestWorkspaceService(t *testing.T) { gitProviderService.On("GetConfig", "github").Return(&gitProviderConfig, nil) - workspace, err := service.CreateWorkspace(ctx, createWorkspaceDto) + target, err := service.CreateTarget(ctx, createTargetDTO) require.Nil(t, err) - require.NotNil(t, workspace) + require.NotNil(t, target) - workspaceEquals(t, createWorkspaceDto, workspace, defaultProjectImage) + targetEquals(t, createTargetDTO, target, defaultProjectImage) }) - t.Run("CreateWorkspace fails when workspace already exists", func(t *testing.T) { - _, err := service.CreateWorkspace(ctx, createWorkspaceDto) + t.Run("CreateTarget fails when target already exists", func(t *testing.T) { + _, err := service.CreateTarget(ctx, createTargetDTO) require.NotNil(t, err) - require.Equal(t, workspaces.ErrWorkspaceAlreadyExists, err) + require.Equal(t, targets.ErrTargetAlreadyExists, err) }) - t.Run("CreateWorkspace fails name validation", func(t *testing.T) { - invalidWorkspaceRequest := createWorkspaceDto - invalidWorkspaceRequest.Name = "invalid name" + t.Run("CreateTarget fails name validation", func(t *testing.T) { + invalidTargetRequest := createTargetDTO + invalidTargetRequest.Name = "invalid name" - _, err := service.CreateWorkspace(ctx, invalidWorkspaceRequest) + _, err := service.CreateTarget(ctx, invalidTargetRequest) require.NotNil(t, err) - require.Equal(t, workspaces.ErrInvalidWorkspaceName, err) + require.Equal(t, targets.ErrInvalidTargetName, err) }) - t.Run("GetWorkspace", func(t *testing.T) { - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &targetConfig).Return(&workspaceInfo, nil) + t.Run("GetTarget", func(t *testing.T) { + mockProvisioner.On("GetTargetInfo", mock.Anything, mock.Anything, &targetConfig).Return(&targetInfo, nil) - workspace, err := service.GetWorkspace(ctx, createWorkspaceDto.Id, true) + target, err := service.GetTarget(ctx, createTargetDTO.Id, true) require.Nil(t, err) - require.NotNil(t, workspace) + require.NotNil(t, target) - workspaceDtoEquals(t, createWorkspaceDto, *workspace, workspaceInfo, defaultProjectImage, true) + targetDtoEquals(t, createTargetDTO, *target, targetInfo, defaultProjectImage, true) }) - t.Run("GetWorkspace fails when workspace not found", func(t *testing.T) { - _, err := service.GetWorkspace(ctx, "invalid-id", true) + t.Run("GetTarget fails when target not found", func(t *testing.T) { + _, err := service.GetTarget(ctx, "invalid-id", true) require.NotNil(t, err) - require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + require.Equal(t, targets.ErrTargetNotFound, err) }) - t.Run("ListWorkspaces", func(t *testing.T) { + t.Run("ListTargets", func(t *testing.T) { verbose := false - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &targetConfig).Return(&workspaceInfo, nil) + mockProvisioner.On("GetTargetInfo", mock.Anything, mock.Anything, &targetConfig).Return(&targetInfo, nil) - workspaces, err := service.ListWorkspaces(ctx, verbose) + targets, err := service.ListTargets(ctx, verbose) require.Nil(t, err) - require.Len(t, workspaces, 1) + require.Len(t, targets, 1) - workspace := workspaces[0] + target := targets[0] - workspaceDtoEquals(t, createWorkspaceDto, workspace, workspaceInfo, defaultProjectImage, verbose) + targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultProjectImage, verbose) }) - t.Run("ListWorkspaces - verbose", func(t *testing.T) { + t.Run("ListTargets - verbose", func(t *testing.T) { verbose := true - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, mock.Anything, &targetConfig).Return(&workspaceInfo, nil) + mockProvisioner.On("GetTargetInfo", mock.Anything, mock.Anything, &targetConfig).Return(&targetInfo, nil) - workspaces, err := service.ListWorkspaces(ctx, verbose) + targets, err := service.ListTargets(ctx, verbose) require.Nil(t, err) - require.Len(t, workspaces, 1) + require.Len(t, targets, 1) - workspace := workspaces[0] + target := targets[0] - workspaceDtoEquals(t, createWorkspaceDto, workspace, workspaceInfo, defaultProjectImage, verbose) + targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultProjectImage, verbose) }) - t.Run("StartWorkspace", func(t *testing.T) { - mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + t.Run("StartTarget", func(t *testing.T) { + mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("StartProject", mock.Anything, &targetConfig).Return(nil) - err := service.StartWorkspace(ctx, createWorkspaceDto.Id) + err := service.StartTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) t.Run("StartProject", func(t *testing.T) { - mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("StartProject", mock.Anything, &targetConfig).Return(nil) - err := service.StartProject(ctx, createWorkspaceDto.Id, createWorkspaceDto.Projects[0].Name) + err := service.StartProject(ctx, createTargetDTO.Id, createTargetDTO.Projects[0].Name) require.Nil(t, err) }) - t.Run("StopWorkspace", func(t *testing.T) { - mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) + t.Run("StopTarget", func(t *testing.T) { + mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("StopProject", mock.Anything, &targetConfig).Return(nil) - err := service.StopWorkspace(ctx, createWorkspaceDto.Id) + err := service.StopTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) t.Run("StopProject", func(t *testing.T) { - mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("StopProject", mock.Anything, &targetConfig).Return(nil) - err := service.StopProject(ctx, createWorkspaceDto.Id, createWorkspaceDto.Projects[0].Name) + err := service.StopProject(ctx, createTargetDTO.Id, createTargetDTO.Projects[0].Name) require.Nil(t, err) }) - t.Run("RemoveWorkspace", func(t *testing.T) { - mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + t.Run("RemoveTarget", func(t *testing.T) { + mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("DestroyProject", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) - err := service.RemoveWorkspace(ctx, createWorkspaceDto.Id) + err := service.RemoveTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDto.Id, true) - require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + _, err = service.GetTarget(ctx, createTargetDTO.Id, true) + require.Equal(t, targets.ErrTargetNotFound, err) }) - t.Run("ForceRemoveWorkspace", func(t *testing.T) { - err := workspaceStore.Save(&workspace.Workspace{Id: createWorkspaceDto.Id, TargetConfig: targetConfig.Name}) + t.Run("ForceRemoveTarget", func(t *testing.T) { + err := targetStore.Save(&target.Target{Id: createTargetDTO.Id, TargetConfig: targetConfig.Name}) require.Nil(t, err) - mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("DestroyProject", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) - err = service.ForceRemoveWorkspace(ctx, createWorkspaceDto.Id) + err = service.ForceRemoveTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDto.Id, true) - require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + _, err = service.GetTarget(ctx, createTargetDTO.Id, true) + require.Equal(t, targets.ErrTargetNotFound, err) }) t.Run("SetProjectState", func(t *testing.T) { - ws, err := service.CreateWorkspace(ctx, createWorkspaceDto) + tg, err := service.CreateTarget(ctx, createTargetDTO) require.Nil(t, err) - projectName := ws.Projects[0].Name + projectName := tg.Projects[0].Name updatedAt := time.Now().Format(time.RFC1123) - res, err := service.SetProjectState(ws.Id, projectName, &project.ProjectState{ + res, err := service.SetProjectState(tg.Id, projectName, &project.ProjectState{ UpdatedAt: updatedAt, Uptime: 10, GitStatus: &project.GitStatus{ @@ -342,14 +341,14 @@ func TestWorkspaceService(t *testing.T) { }) } -func workspaceEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace *workspace.Workspace, projectImage string) { +func targetEquals(t *testing.T, req dto.CreateTargetDTO, target *target.Target, projectImage string) { t.Helper() - require.Equal(t, req.Id, workspace.Id) - require.Equal(t, req.Name, workspace.Name) - require.Equal(t, req.TargetConfig, workspace.TargetConfig) + require.Equal(t, req.Id, target.Id) + require.Equal(t, req.Name, target.Name) + require.Equal(t, req.TargetConfig, target.TargetConfig) - for i, project := range workspace.Projects { + for i, project := range target.Projects { require.Equal(t, req.Projects[i].Name, project.Name) require.Equal(t, req.Projects[i].Source.Repository.Id, project.Repository.Id) require.Equal(t, req.Projects[i].Source.Repository.Url, project.Repository.Url) @@ -360,21 +359,21 @@ func workspaceEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace *worksp } } -func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto.WorkspaceDTO, workspaceInfo workspace.WorkspaceInfo, projectImage string, verbose bool) { +func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, projectImage string, verbose bool) { t.Helper() - require.Equal(t, req.Id, workspace.Id) - require.Equal(t, req.Name, workspace.Name) - require.Equal(t, req.TargetConfig, workspace.TargetConfig) + require.Equal(t, req.Id, target.Id) + require.Equal(t, req.Name, target.Name) + require.Equal(t, req.TargetConfig, target.TargetConfig) if verbose { - require.Equal(t, workspace.Info.Name, workspaceInfo.Name) - require.Equal(t, workspace.Info.ProviderMetadata, workspaceInfo.ProviderMetadata) + require.Equal(t, target.Info.Name, targetInfo.Name) + require.Equal(t, target.Info.ProviderMetadata, targetInfo.ProviderMetadata) } else { - require.Nil(t, workspace.Info) + require.Nil(t, target.Info) } - for i, project := range workspace.Projects { + for i, project := range target.Projects { require.Equal(t, req.Projects[i].Name, project.Name) require.Equal(t, req.Projects[i].Source.Repository.Id, project.Repository.Id) require.Equal(t, req.Projects[i].Source.Repository.Url, project.Repository.Url) @@ -384,10 +383,10 @@ func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto. require.Equal(t, project.Image, projectImage) if verbose { - require.Equal(t, workspace.Info.Projects[i].Name, workspaceInfo.Projects[i].Name) - require.Equal(t, workspace.Info.Projects[i].Created, workspaceInfo.Projects[i].Created) - require.Equal(t, workspace.Info.Projects[i].IsRunning, workspaceInfo.Projects[i].IsRunning) - require.Equal(t, workspace.Info.Projects[i].ProviderMetadata, workspaceInfo.Projects[i].ProviderMetadata) + require.Equal(t, target.Info.Projects[i].Name, targetInfo.Projects[i].Name) + require.Equal(t, target.Info.Projects[i].Created, targetInfo.Projects[i].Created) + require.Equal(t, target.Info.Projects[i].IsRunning, targetInfo.Projects[i].IsRunning) + require.Equal(t, target.Info.Projects[i].ProviderMetadata, targetInfo.Projects[i].ProviderMetadata) } } } diff --git a/pkg/server/workspaces/start.go b/pkg/server/targets/start.go similarity index 66% rename from pkg/server/workspaces/start.go rename to pkg/server/targets/start.go index 5695e8573f..6b78ebe897 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/targets/start.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package targets import ( "context" @@ -13,18 +13,18 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/project" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/project" log "github.com/sirupsen/logrus" "github.com/daytonaio/daytona/internal/util" ) -func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { - w, err := s.workspaceStore.Find(workspaceId) +func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { + w, err := s.targetStore.Find(targetId) if err != nil { - return ErrWorkspaceNotFound + return ErrTargetNotFound } targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) @@ -32,12 +32,12 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin return err } - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(w.Id, logs.LogSourceServer) - defer workspaceLogger.Close() + targetLogger := s.loggerFactory.CreateTargetLogger(w.Id, logs.LogSourceServer) + defer targetLogger.Close() - wsLogWriter := io.MultiWriter(&util.InfoLogWriter{}, workspaceLogger) + tgLogWriter := io.MultiWriter(&util.InfoLogWriter{}, targetLogger) - err = s.startWorkspace(ctx, w, targetConfig, wsLogWriter) + err = s.startTarget(ctx, w, targetConfig, tgLogWriter) if !telemetry.TelemetryEnabled(ctx) { return err @@ -45,11 +45,11 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w, targetConfig) - event := telemetry.ServerEventWorkspaceStarted + telemetryProps := telemetry.NewTargetEventProps(ctx, w, targetConfig) + event := telemetry.ServerEventTargetStarted if err != nil { telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceStartError + event = telemetry.ServerEventTargetStartError } telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) if telemetryError != nil { @@ -59,10 +59,10 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin return err } -func (s *WorkspaceService) StartProject(ctx context.Context, workspaceId, projectName string) error { - w, err := s.workspaceStore.Find(workspaceId) +func (s *TargetService) StartProject(ctx context.Context, targetId, projectName string) error { + w, err := s.targetStore.Find(targetId) if err != nil { - return ErrWorkspaceNotFound + return ErrTargetNotFound } project, err := w.GetProject(projectName) @@ -81,23 +81,23 @@ func (s *WorkspaceService) StartProject(ctx context.Context, workspaceId, projec return s.startProject(ctx, project, targetConfig, projectLogger) } -func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Workspace, targetConfig *provider.TargetConfig, wsLogWriter io.Writer) error { - wsLogWriter.Write([]byte("Starting workspace\n")) +func (s *TargetService) startTarget(ctx context.Context, t *target.Target, targetConfig *provider.TargetConfig, targetLogger io.Writer) error { + targetLogger.Write([]byte("Starting target\n")) - ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ + t.EnvVars = target.GetTargetEnvVars(t, target.TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err := s.provisioner.StartWorkspace(ws, targetConfig) + err := s.provisioner.StartTarget(t, targetConfig) if err != nil { return err } - for _, project := range ws.Projects { - projectLogger := s.loggerFactory.CreateProjectLogger(ws.Id, project.Name, logs.LogSourceServer) + for _, project := range t.Projects { + projectLogger := s.loggerFactory.CreateProjectLogger(t.Id, project.Name, logs.LogSourceServer) defer projectLogger.Close() err = s.startProject(ctx, project, targetConfig, projectLogger) @@ -106,12 +106,12 @@ func (s *WorkspaceService) startWorkspace(ctx context.Context, ws *workspace.Wor } } - wsLogWriter.Write([]byte(fmt.Sprintf("Workspace %s started\n", ws.Name))) + targetLogger.Write([]byte(fmt.Sprintf("Target %s started\n", t.Name))) return nil } -func (s *WorkspaceService) startProject(ctx context.Context, p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { +func (s *TargetService) startProject(ctx context.Context, p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { logWriter.Write([]byte(fmt.Sprintf("Starting project %s\n", p.Name))) projectToStart := *p diff --git a/pkg/server/workspaces/stop.go b/pkg/server/targets/stop.go similarity index 64% rename from pkg/server/workspaces/stop.go rename to pkg/server/targets/stop.go index 2c521ac4e8..00e0eb3b0d 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/targets/stop.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package targets import ( "context" @@ -12,18 +12,18 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { - workspace, err := s.workspaceStore.Find(workspaceId) +func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { + target, err := s.targetStore.Find(targetId) if err != nil { - return ErrWorkspaceNotFound + return ErrTargetNotFound } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &workspace.TargetConfig}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) if err != nil { return err } - for _, project := range workspace.Projects { + for _, project := range target.Projects { // todo: go routines err := s.provisioner.StopProject(project, targetConfig) if err != nil { @@ -35,9 +35,9 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string } } - err = s.provisioner.StopWorkspace(workspace, targetConfig) + err = s.provisioner.StopTarget(target, targetConfig) if err == nil { - err = s.workspaceStore.Save(workspace) + err = s.targetStore.Save(target) } if !telemetry.TelemetryEnabled(ctx) { @@ -46,11 +46,11 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, targetConfig) - event := telemetry.ServerEventWorkspaceStopped + telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) + event := telemetry.ServerEventTargetStopped if err != nil { telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceStopError + event = telemetry.ServerEventTargetStopError } telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) if telemetryError != nil { @@ -60,10 +60,10 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string return err } -func (s *WorkspaceService) StopProject(ctx context.Context, workspaceId, projectName string) error { - w, err := s.workspaceStore.Find(workspaceId) +func (s *TargetService) StopProject(ctx context.Context, targetId, projectName string) error { + w, err := s.targetStore.Find(targetId) if err != nil { - return ErrWorkspaceNotFound + return ErrTargetNotFound } project, err := w.GetProject(projectName) @@ -86,5 +86,5 @@ func (s *WorkspaceService) StopProject(ctx context.Context, workspaceId, project project.State.UpdatedAt = time.Now().Format(time.RFC1123) } - return s.workspaceStore.Save(w) + return s.targetStore.Save(w) } diff --git a/pkg/server/workspaces/error.go b/pkg/server/workspaces/error.go deleted file mode 100644 index 55fee21339..0000000000 --- a/pkg/server/workspaces/error.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaces - -import ( - "errors" -) - -var ( - ErrWorkspaceAlreadyExists = errors.New("workspace already exists") - ErrInvalidWorkspaceName = errors.New("name is not a valid alphanumeric string") - ErrWorkspaceNotFound = errors.New("workspace not found") - ErrProjectNotFound = errors.New("project not found") - ErrInvalidProjectName = errors.New("project name is not valid. Only [a-zA-Z0-9-_.] are allowed") - ErrInvalidProjectConfig = errors.New("project config is invalid") -) - -func IsWorkspaceAlreadyExists(err error) bool { - return err.Error() == ErrWorkspaceAlreadyExists.Error() -} - -func IsWorkspaceNotFound(err error) bool { - return err.Error() == ErrWorkspaceNotFound.Error() -} - -func IsProjectNotFound(err error) bool { - return err.Error() == ErrProjectNotFound.Error() -} - -func IsInvalidWorkspaceName(err error) bool { - return err.Error() == ErrInvalidWorkspaceName.Error() -} diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go deleted file mode 100644 index f635e95c54..0000000000 --- a/pkg/server/workspaces/remove.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaces - -import ( - "context" - "fmt" - - "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/telemetry" - log "github.com/sirupsen/logrus" -) - -func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId string) error { - workspace, err := s.workspaceStore.Find(workspaceId) - if err != nil { - return ErrWorkspaceNotFound - } - - log.Infof("Destroying workspace %s", workspace.Id) - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &workspace.TargetConfig}) - if err != nil { - return err - } - - for _, project := range workspace.Projects { - // todo: go routines - err := s.provisioner.DestroyProject(project, targetConfig) - if err != nil { - return err - } - } - - err = s.provisioner.DestroyWorkspace(workspace, targetConfig) - if err != nil { - return err - } - - // Should not fail the whole operation if the API key cannot be revoked - err = s.apiKeyService.Revoke(workspace.Id) - if err != nil { - log.Error(err) - } - - for _, project := range workspace.Projects { - err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", workspace.Id, project.Name)) - if err != nil { - // Should not fail the whole operation if the API key cannot be revoked - log.Error(err) - } - projectLogger := s.loggerFactory.CreateProjectLogger(workspace.Id, project.Name, logs.LogSourceServer) - err = projectLogger.Cleanup() - if err != nil { - // Should not fail the whole operation if the project logger cannot be cleaned up - log.Error(err) - } - } - - logger := s.loggerFactory.CreateWorkspaceLogger(workspace.Id, logs.LogSourceServer) - err = logger.Cleanup() - if err != nil { - // Should not fail the whole operation if the workspace logger cannot be cleaned up - log.Error(err) - } - - err = s.workspaceStore.Delete(workspace) - - if !telemetry.TelemetryEnabled(ctx) { - return err - } - - clientId := telemetry.ClientId(ctx) - - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, targetConfig) - event := telemetry.ServerEventWorkspaceDestroyed - if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceDestroyError - } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) - if telemetryError != nil { - log.Trace(telemetryError) - } - - return err -} - -// ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. -func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { - workspace, err := s.workspaceStore.Find(workspaceId) - if err != nil { - return ErrWorkspaceNotFound - } - - log.Infof("Destroying workspace %s", workspace.Id) - - targetConfig, _ := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &workspace.TargetConfig}) - - for _, project := range workspace.Projects { - // todo: go routines - err := s.provisioner.DestroyProject(project, targetConfig) - if err != nil { - log.Error(err) - } - } - - err = s.provisioner.DestroyWorkspace(workspace, targetConfig) - if err != nil { - log.Error(err) - } - - err = s.apiKeyService.Revoke(workspace.Id) - if err != nil { - log.Error(err) - } - - for _, project := range workspace.Projects { - err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", workspace.Id, project.Name)) - if err != nil { - log.Error(err) - } - - projectLogger := s.loggerFactory.CreateProjectLogger(workspace.Id, project.Name, logs.LogSourceServer) - err = projectLogger.Cleanup() - if err != nil { - log.Error(err) - } - } - - err = s.workspaceStore.Delete(workspace) - - if !telemetry.TelemetryEnabled(ctx) { - return err - } - - clientId := telemetry.ClientId(ctx) - - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, workspace, targetConfig) - event := telemetry.ServerEventWorkspaceDestroyed - if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceDestroyError - } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) - if telemetryError != nil { - log.Trace(telemetryError) - } - - return err -} diff --git a/pkg/workspace/project/buildconfig/config.go b/pkg/target/project/buildconfig/config.go similarity index 100% rename from pkg/workspace/project/buildconfig/config.go rename to pkg/target/project/buildconfig/config.go diff --git a/pkg/workspace/project/config/config.go b/pkg/target/project/config/config.go similarity index 97% rename from pkg/workspace/project/config/config.go rename to pkg/target/project/config/config.go index 86f6d9ed97..9b4ac10863 100644 --- a/pkg/workspace/project/config/config.go +++ b/pkg/target/project/config/config.go @@ -6,7 +6,7 @@ package config import ( "errors" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type ProjectConfig struct { diff --git a/pkg/workspace/project/config/prebuild.go b/pkg/target/project/config/prebuild.go similarity index 100% rename from pkg/workspace/project/config/prebuild.go rename to pkg/target/project/config/prebuild.go diff --git a/pkg/workspace/project/config/store.go b/pkg/target/project/config/store.go similarity index 100% rename from pkg/workspace/project/config/store.go rename to pkg/target/project/config/store.go diff --git a/pkg/workspace/project/containerconfig/config.go b/pkg/target/project/containerconfig/config.go similarity index 100% rename from pkg/workspace/project/containerconfig/config.go rename to pkg/target/project/containerconfig/config.go diff --git a/pkg/workspace/project/project.go b/pkg/target/project/project.go similarity index 89% rename from pkg/workspace/project/project.go rename to pkg/target/project/project.go index 1eaebec910..403bbf47d9 100644 --- a/pkg/workspace/project/project.go +++ b/pkg/target/project/project.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/project/buildconfig" ) type Project struct { @@ -18,7 +18,7 @@ type Project struct { BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` Repository *gitprovider.GitRepository `json:"repository" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` - WorkspaceId string `json:"workspaceId" validate:"required"` + TargetId string `json:"targetId" validate:"required"` ApiKey string `json:"-"` TargetConfig string `json:"targetConfig" validate:"required"` State *ProjectState `json:"state,omitempty" validate:"optional"` @@ -30,7 +30,7 @@ type ProjectInfo struct { Created string `json:"created" validate:"required"` IsRunning bool `json:"isRunning" validate:"required"` ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` - WorkspaceId string `json:"workspaceId" validate:"required"` + TargetId string `json:"targetId" validate:"required"` } // @name ProjectInfo type ProjectState struct { @@ -77,8 +77,8 @@ type ProjectEnvVarParams struct { func GetProjectEnvVars(project *Project, params ProjectEnvVarParams, telemetryEnabled bool) map[string]string { envVars := map[string]string{ - "DAYTONA_WS_ID": project.WorkspaceId, - "DAYTONA_WS_PROJECT_NAME": project.Name, + "DAYTONA_TARGET_ID": project.TargetId, + "DAYTONA_PROJECT_NAME": project.Name, "DAYTONA_WS_PROJECT_REPOSITORY_URL": project.Repository.Url, "DAYTONA_SERVER_API_KEY": project.ApiKey, "DAYTONA_SERVER_VERSION": params.ServerVersion, @@ -96,14 +96,14 @@ func GetProjectEnvVars(project *Project, params ProjectEnvVarParams, telemetryEn return envVars } -func GetProjectHostname(workspaceId string, projectName string) string { +func GetProjectHostname(targetId string, projectName string) string { // Replace special chars with hyphen to form valid hostname // String resulting in consecutive hyphens is also valid projectName = strings.ReplaceAll(projectName, "_", "-") projectName = strings.ReplaceAll(projectName, "*", "-") projectName = strings.ReplaceAll(projectName, ".", "-") - hostname := fmt.Sprintf("%s-%s", workspaceId, projectName) + hostname := fmt.Sprintf("%s-%s", targetId, projectName) if len(hostname) > 63 { return hostname[:63] diff --git a/pkg/target/store.go b/pkg/target/store.go new file mode 100644 index 0000000000..5b0e61e859 --- /dev/null +++ b/pkg/target/store.go @@ -0,0 +1,21 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import "errors" + +type Store interface { + List() ([]*Target, error) + Find(idOrName string) (*Target, error) + Save(target *Target) error + Delete(target *Target) error +} + +var ( + ErrTargetNotFound = errors.New("target not found") +) + +func IsTargetNotFound(err error) bool { + return err.Error() == ErrTargetNotFound.Error() +} diff --git a/pkg/workspace/workspace.go b/pkg/target/target.go similarity index 71% rename from pkg/workspace/workspace.go rename to pkg/target/target.go index 38f1f421ea..b179e7273a 100644 --- a/pkg/workspace/workspace.go +++ b/pkg/target/target.go @@ -1,31 +1,31 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package target import ( "errors" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/project" ) -type Workspace struct { +type Target struct { Id string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` Projects []*project.Project `json:"projects" validate:"required"` TargetConfig string `json:"targetConfig" validate:"required"` ApiKey string `json:"-"` EnvVars map[string]string `json:"-"` -} // @name Workspace +} // @name Target -type WorkspaceInfo struct { +type TargetInfo struct { Name string `json:"name" validate:"required"` Projects []*project.ProjectInfo `json:"projects" validate:"required"` ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` -} // @name WorkspaceInfo +} // @name TargetInfo -func (w *Workspace) GetProject(projectName string) (*project.Project, error) { - for _, project := range w.Projects { +func (t *Target) GetProject(projectName string) (*project.Project, error) { + for _, project := range t.Projects { if project.Name == projectName { return project, nil } @@ -33,17 +33,17 @@ func (w *Workspace) GetProject(projectName string) (*project.Project, error) { return nil, errors.New("project not found") } -type WorkspaceEnvVarParams struct { +type TargetEnvVarParams struct { ApiUrl string ServerUrl string ServerVersion string ClientId string } -func GetWorkspaceEnvVars(workspace *Workspace, params WorkspaceEnvVarParams, telemetryEnabled bool) map[string]string { +func GetTargetEnvVars(target *Target, params TargetEnvVarParams, telemetryEnabled bool) map[string]string { envVars := map[string]string{ - "DAYTONA_WS_ID": workspace.Id, - "DAYTONA_SERVER_API_KEY": workspace.ApiKey, + "DAYTONA_TARGET_ID": target.Id, + "DAYTONA_SERVER_API_KEY": target.ApiKey, "DAYTONA_SERVER_VERSION": params.ServerVersion, "DAYTONA_SERVER_URL": params.ServerUrl, "DAYTONA_SERVER_API_URL": params.ApiUrl, diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index 5614dfbf9e..4727a75d5a 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -10,7 +10,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/target" ) type ServerEvent string @@ -22,18 +22,18 @@ const ( ServerEventPurgeCompleted ServerEvent = "server_purge_completed" ServerEventPurgeError ServerEvent = "server_purge_error" - // Workspace events - ServerEventWorkspaceCreated ServerEvent = "server_workspace_created" - ServerEventWorkspaceDestroyed ServerEvent = "server_workspace_destroyed" - ServerEventWorkspaceStarted ServerEvent = "server_workspace_started" - ServerEventWorkspaceStopped ServerEvent = "server_workspace_stopped" - ServerEventWorkspaceCreateError ServerEvent = "server_workspace_created_error" - ServerEventWorkspaceDestroyError ServerEvent = "server_workspace_destroyed_error" - ServerEventWorkspaceStartError ServerEvent = "server_workspace_started_error" - ServerEventWorkspaceStopError ServerEvent = "server_workspace_stopped_error" + // Target events + ServerEventTargetCreated ServerEvent = "server_target_created" + ServerEventTargetDestroyed ServerEvent = "server_target_destroyed" + ServerEventTargetStarted ServerEvent = "server_target_started" + ServerEventTargetStopped ServerEvent = "server_target_stopped" + ServerEventTargetCreateError ServerEvent = "server_target_created_error" + ServerEventTargetDestroyError ServerEvent = "server_target_destroyed_error" + ServerEventTargetStartError ServerEvent = "server_target_started_error" + ServerEventTargetStopError ServerEvent = "server_target_stopped_error" ) -func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) map[string]interface{} { +func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) map[string]interface{} { props := map[string]interface{}{} sessionId := SessionId(ctx) @@ -42,14 +42,14 @@ func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace, props["session_id"] = sessionId props["server_id"] = serverId - if workspace != nil { - props["workspace_id"] = workspace.Id - props["workspace_n_projects"] = len(workspace.Projects) + if target != nil { + props["target_id"] = target.Id + props["target_n_projects"] = len(target.Projects) publicRepos := []string{} publicImages := []string{} builders := map[string]int{} - for _, project := range workspace.Projects { + for _, project := range target.Projects { if isImagePublic(project.Image) { publicImages = append(publicImages, project.Image) } @@ -65,9 +65,9 @@ func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace, } } - props["workspace_public_repos"] = publicRepos - props["workspace_public_images"] = publicImages - props["workspace_builders"] = builders + props["target_public_repos"] = publicRepos + props["target_public_images"] = publicImages + props["target_builders"] = builders } if targetConfig != nil { diff --git a/pkg/views/ide/code.go b/pkg/views/ide/code.go index f3a2a42643..b4d7278b1d 100644 --- a/pkg/views/ide/code.go +++ b/pkg/views/ide/code.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func RenderIdeOpeningMessage(workspaceId, projectName, ideId string, ideList []config.Ide) { +func RenderIdeOpeningMessage(target, projectName, ideId string, ideList []config.Ide) { ideName := "" for _, ide := range ideList { if ide.Id == ideId { @@ -18,5 +18,5 @@ func RenderIdeOpeningMessage(workspaceId, projectName, ideId string, ideList []c break } } - views.RenderInfoMessage(fmt.Sprintf("Opening the project '%s' from workspace '%s' in %s", projectName, workspaceId, ideName)) + views.RenderInfoMessage(fmt.Sprintf("Opening the project '%s' from target '%s' in %s", projectName, target, ideName)) } diff --git a/pkg/views/ide/start_workspace.go b/pkg/views/ide/start_target.go similarity index 75% rename from pkg/views/ide/start_workspace.go rename to pkg/views/ide/start_target.go index 92d56004f7..140e5800ec 100644 --- a/pkg/views/ide/start_workspace.go +++ b/pkg/views/ide/start_target.go @@ -11,13 +11,13 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func RunStartWorkspaceForm(workspaceName string) bool { +func RunStartTargetForm(targetName string) bool { confirmCheck := true form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title(fmt.Sprintf("The workspace %s is stopped, would you like to start it?", workspaceName)). + Title(fmt.Sprintf("The target %s is stopped, would you like to start it?", targetName)). Value(&confirmCheck), ), ).WithTheme(views.GetCustomTheme()) diff --git a/pkg/views/logs/display.go b/pkg/views/logs/display.go index 13f6c43bb1..10b11e1e8c 100644 --- a/pkg/views/logs/display.go +++ b/pkg/views/logs/display.go @@ -14,10 +14,10 @@ import ( var FIRST_PROJECT_INDEX = 0 var STATIC_INDEX = -1 -var WORKSPACE_PREFIX = "WORKSPACE" +var TARGET_PREFIX = "TARGET" var PROVIDER_PREFIX = "PROVIDER" -var longestPrefixLength = len(WORKSPACE_PREFIX) +var longestPrefixLength = len(TARGET_PREFIX) var maxPrefixLength = 20 var prefixDelimiter = " | " var prefixPadding = " " @@ -46,7 +46,7 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { if logEntry.Source == string(logs.LogSourceProvider) { prefixText = PROVIDER_PREFIX } else { - prefixText = WORKSPACE_PREFIX + prefixText = TARGET_PREFIX } } diff --git a/pkg/views/workspace/create/configuration.go b/pkg/views/target/create/configuration.go similarity index 99% rename from pkg/views/workspace/create/configuration.go rename to pkg/views/target/create/configuration.go index 946b213020..6e8cb1b8f2 100644 --- a/pkg/views/workspace/create/configuration.go +++ b/pkg/views/target/create/configuration.go @@ -15,8 +15,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) const ( diff --git a/pkg/views/workspace/create/summary.go b/pkg/views/target/create/summary.go similarity index 100% rename from pkg/views/workspace/create/summary.go rename to pkg/views/target/create/summary.go diff --git a/pkg/views/workspace/create/view.go b/pkg/views/target/create/view.go similarity index 100% rename from pkg/views/workspace/create/view.go rename to pkg/views/target/create/view.go diff --git a/pkg/views/workspace/info/view.go b/pkg/views/target/info/view.go similarity index 91% rename from pkg/views/workspace/info/view.go rename to pkg/views/target/info/view.go index 7ac3a243a4..68c8905604 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/target/info/view.go @@ -23,7 +23,7 @@ var propertyValueStyle = lipgloss.NewStyle(). Foreground(views.Light). Bold(true) -func Render(workspace *apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { +func Render(target *apiclient.TargetDTO, ide string, forceUnstyled bool) { var isCreationView bool var output string nameLabel := "Name" @@ -33,22 +33,22 @@ func Render(workspace *apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { } if isCreationView { - nameLabel = "Workspace" + nameLabel = "Target" } output += "\n" - output += getInfoLine(nameLabel, workspace.Name) + "\n" + output += getInfoLine(nameLabel, target.Name) + "\n" - output += getInfoLine("ID", workspace.Id) + "\n" + output += getInfoLine("ID", target.Id) + "\n" if isCreationView { output += getInfoLine("Editor", ide) + "\n" } - if len(workspace.Projects) == 1 { - output += getSingleProjectOutput(&workspace.Projects[0], isCreationView) + if len(target.Projects) == 1 { + output += getSingleProjectOutput(&target.Projects[0], isCreationView) } else { - output += getProjectsOutputs(workspace.Projects, isCreationView) + output += getProjectsOutputs(target.Projects, isCreationView) } terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) @@ -62,7 +62,7 @@ func Render(workspace *apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { } if !isCreationView { - output = views.GetStyledMainTitle("Workspace Info") + "\n" + output + output = views.GetStyledMainTitle("Target Info") + "\n" + output } renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth), isCreationView) diff --git a/pkg/views/workspace/list/view.go b/pkg/views/target/list/view.go similarity index 51% rename from pkg/views/workspace/list/view.go rename to pkg/views/target/list/view.go index 52d7283864..c29f1d31f2 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/target/list/view.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + info_view "github.com/daytonaio/daytona/pkg/views/target/info" views_util "github.com/daytonaio/daytona/pkg/views/util" - info_view "github.com/daytonaio/daytona/pkg/views/workspace/info" ) type RowData struct { @@ -24,31 +24,31 @@ type RowData struct { Branch string } -func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { - if len(workspaceList) == 0 { - views_util.NotifyEmptyWorkspaceList(true) +func ListTargets(targetList []apiclient.TargetDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) return } - SortWorkspaces(&workspaceList, verbose) + SortTargets(&targetList, verbose) - headers := []string{"Workspace", "Repository", "Target Config", "Status", "Created", "Branch"} + headers := []string{"Target", "Repository", "Target Config", "Status", "Created", "Branch"} data := [][]string{} - for _, workspace := range workspaceList { + for _, target := range targetList { var rowData *RowData var row []string - if len(workspace.Projects) == 1 { - rowData = getWorkspaceTableRowData(workspace, specifyGitProviders) + if len(target.Projects) == 1 { + rowData = getTargetTableRowData(target, specifyGitProviders) row = getRowFromRowData(*rowData, false) data = append(data, row) } else { - row = getRowFromRowData(RowData{Name: workspace.Name}, true) + row = getRowFromRowData(RowData{Name: target.Name}, true) data = append(data, row) - for _, project := range workspace.Projects { - rowData = getProjectTableRowData(workspace, project, specifyGitProviders) + for _, project := range target.Projects { + rowData = getProjectTableRowData(target, project, specifyGitProviders) if rowData == nil { continue } @@ -74,17 +74,17 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders footer := lipgloss.NewStyle().Foreground(views.LightGray).Render(views.GetListFooter(activeProfileName, &views.Padding{})) table := views_util.GetTableView(data, headers, &footer, func() { - renderUnstyledList(workspaceList) + renderUnstyledList(targetList) }) fmt.Println(table) } -func renderUnstyledList(workspaceList []apiclient.WorkspaceDTO) { - for _, workspace := range workspaceList { - info_view.Render(&workspace, "", true) +func renderUnstyledList(targetList []apiclient.TargetDTO) { + for _, target := range targetList { + info_view.Render(&target, "", true) - if workspace.Id != workspaceList[len(workspaceList)-1].Id { + if target.Id != targetList[len(targetList)-1].Id { fmt.Printf("\n%s\n\n", views.SeparatorString) } @@ -119,53 +119,53 @@ func getRowFromRowData(rowData RowData, isMultiProjectAccordion bool) []string { return row } -func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { +func SortTargets(targetList *[]apiclient.TargetDTO, verbose bool) { if verbose { - sort.Slice(*workspaceList, func(i, j int) bool { - ws1 := (*workspaceList)[i] - ws2 := (*workspaceList)[j] - if ws1.Info == nil || ws2.Info == nil || ws1.Info.Projects == nil || ws2.Info.Projects == nil { + sort.Slice(*targetList, func(i, j int) bool { + t1 := (*targetList)[i] + t2 := (*targetList)[j] + if t1.Info == nil || t2.Info == nil || t1.Info.Projects == nil || t2.Info.Projects == nil { return true } - if len(ws1.Info.Projects) == 0 || len(ws2.Info.Projects) == 0 { + if len(t1.Info.Projects) == 0 || len(t2.Info.Projects) == 0 { return true } - return ws1.Info.Projects[0].Created > ws2.Info.Projects[0].Created + return t1.Info.Projects[0].Created > t2.Info.Projects[0].Created }) return } - sort.Slice(*workspaceList, func(i, j int) bool { - ws1 := (*workspaceList)[i] - ws2 := (*workspaceList)[j] - if len(ws1.Projects) == 0 || len(ws2.Projects) == 0 || ws1.Projects[0].State == nil || ws2.Projects[0].State == nil { + sort.Slice(*targetList, func(i, j int) bool { + t1 := (*targetList)[i] + t2 := (*targetList)[j] + if len(t1.Projects) == 0 || len(t2.Projects) == 0 || t1.Projects[0].State == nil || t2.Projects[0].State == nil { return true } - return ws1.Projects[0].State.Uptime < ws2.Projects[0].State.Uptime + return t1.Projects[0].State.Uptime < t2.Projects[0].State.Uptime }) } -func getWorkspaceTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) *RowData { +func getTargetTableRowData(target apiclient.TargetDTO, specifyGitProviders bool) *RowData { rowData := RowData{"", "", "", "", "", ""} - rowData.Name = workspace.Name + views_util.AdditionalPropertyPadding - if len(workspace.Projects) > 0 { - rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Projects[0].Repository.Url, specifyGitProviders) - rowData.Branch = workspace.Projects[0].Repository.Branch + rowData.Name = target.Name + views_util.AdditionalPropertyPadding + if len(target.Projects) > 0 { + rowData.Repository = util.GetRepositorySlugFromUrl(target.Projects[0].Repository.Url, specifyGitProviders) + rowData.Branch = target.Projects[0].Repository.Branch } - rowData.TargetConfig = workspace.TargetConfig + views_util.AdditionalPropertyPadding + rowData.TargetConfig = target.TargetConfig + views_util.AdditionalPropertyPadding - if workspace.Info != nil && workspace.Info.Projects != nil && len(workspace.Info.Projects) > 0 { - rowData.Created = util.FormatTimestamp(workspace.Info.Projects[0].Created) + if target.Info != nil && target.Info.Projects != nil && len(target.Info.Projects) > 0 { + rowData.Created = util.FormatTimestamp(target.Info.Projects[0].Created) } - if len(workspace.Projects) > 0 && workspace.Projects[0].State != nil && workspace.Projects[0].State.Uptime > 0 { - rowData.Status = util.FormatUptime(workspace.Projects[0].State.Uptime) + if len(target.Projects) > 0 && target.Projects[0].State != nil && target.Projects[0].State.Uptime > 0 { + rowData.Status = util.FormatUptime(target.Projects[0].State.Uptime) } return &rowData } -func getProjectTableRowData(workspaceDTO apiclient.WorkspaceDTO, project apiclient.Project, specifyGitProviders bool) *RowData { +func getProjectTableRowData(targetDTO apiclient.TargetDTO, project apiclient.Project, specifyGitProviders bool) *RowData { rowData := RowData{"", "", "", "", "", ""} rowData.Name = " └ " + project.Name @@ -178,11 +178,11 @@ func getProjectTableRowData(workspaceDTO apiclient.WorkspaceDTO, project apiclie rowData.Status = util.FormatUptime(project.State.Uptime) } - if workspaceDTO.Info == nil || workspaceDTO.Info.Projects == nil { + if targetDTO.Info == nil || targetDTO.Info.Projects == nil { return &rowData } - for _, projectInfo := range workspaceDTO.Info.Projects { + for _, projectInfo := range targetDTO.Info.Projects { if projectInfo.Name == project.Name { rowData.Created = util.FormatTimestamp(projectInfo.Created) break diff --git a/pkg/views/workspace/selection/branch.go b/pkg/views/target/selection/branch.go similarity index 96% rename from pkg/views/workspace/selection/branch.go rename to pkg/views/target/selection/branch.go index 9186f08fb6..6f9a471a66 100644 --- a/pkg/views/workspace/selection/branch.go +++ b/pkg/views/target/selection/branch.go @@ -17,7 +17,6 @@ import ( func selectBranchPrompt(branches []apiclient.GitBranch, projectOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { items := []list.Item{} - // Populate items with titles and descriptions from workspaces. for _, branch := range branches { newItem := item[string]{id: branch.Name, title: branch.Name, choiceProperty: branch.Name} if branch.Sha != "" { diff --git a/pkg/views/workspace/selection/build.go b/pkg/views/target/selection/build.go similarity index 100% rename from pkg/views/workspace/selection/build.go rename to pkg/views/target/selection/build.go diff --git a/pkg/views/workspace/selection/checkout.go b/pkg/views/target/selection/checkout.go similarity index 100% rename from pkg/views/workspace/selection/checkout.go rename to pkg/views/target/selection/checkout.go diff --git a/pkg/views/workspace/selection/common.go b/pkg/views/target/selection/common.go similarity index 100% rename from pkg/views/workspace/selection/common.go rename to pkg/views/target/selection/common.go diff --git a/pkg/views/workspace/selection/gitprovider.go b/pkg/views/target/selection/gitprovider.go similarity index 96% rename from pkg/views/workspace/selection/gitprovider.go rename to pkg/views/target/selection/gitprovider.go index 1000f7c420..a2aa54c0b8 100644 --- a/pkg/views/workspace/selection/gitprovider.go +++ b/pkg/views/target/selection/gitprovider.go @@ -20,7 +20,6 @@ var titleStyle = lipgloss.NewStyle() func selectGitProviderPrompt(gitProviders []gitprovider_view.GitProviderView, projectOrder int, choiceChan chan<- string, samplesEnabled bool) { items := []list.Item{} - // Populate items with titles and descriptions from workspaces. for _, provider := range gitProviders { newItem := item[string]{id: provider.Id, title: fmt.Sprintf("%s (%s)", provider.Name, provider.Alias), choiceProperty: provider.Id} items = append(items, newItem) diff --git a/pkg/views/workspace/selection/gitproviderconfig.go b/pkg/views/target/selection/gitproviderconfig.go similarity index 100% rename from pkg/views/workspace/selection/gitproviderconfig.go rename to pkg/views/target/selection/gitproviderconfig.go diff --git a/pkg/views/workspace/selection/namespace.go b/pkg/views/target/selection/namespace.go similarity index 96% rename from pkg/views/workspace/selection/namespace.go rename to pkg/views/target/selection/namespace.go index 19b4144601..7678de8216 100644 --- a/pkg/views/workspace/selection/namespace.go +++ b/pkg/views/target/selection/namespace.go @@ -17,7 +17,6 @@ func selectNamespacePrompt(namespaces []apiclient.GitNamespace, projectOrder int items := []list.Item{} var desc string - // Populate items with titles and descriptions from workspaces. for _, namespace := range namespaces { if namespace.Id == "" { desc = "personal" diff --git a/pkg/views/workspace/selection/prebuild.go b/pkg/views/target/selection/prebuild.go similarity index 100% rename from pkg/views/workspace/selection/prebuild.go rename to pkg/views/target/selection/prebuild.go diff --git a/pkg/views/workspace/selection/project.go b/pkg/views/target/selection/project.go similarity index 100% rename from pkg/views/workspace/selection/project.go rename to pkg/views/target/selection/project.go diff --git a/pkg/views/workspace/selection/projectconfig.go b/pkg/views/target/selection/projectconfig.go similarity index 100% rename from pkg/views/workspace/selection/projectconfig.go rename to pkg/views/target/selection/projectconfig.go diff --git a/pkg/views/workspace/selection/projectrequest.go b/pkg/views/target/selection/projectrequest.go similarity index 100% rename from pkg/views/workspace/selection/projectrequest.go rename to pkg/views/target/selection/projectrequest.go diff --git a/pkg/views/workspace/selection/pullrequest.go b/pkg/views/target/selection/pullrequest.go similarity index 97% rename from pkg/views/workspace/selection/pullrequest.go rename to pkg/views/target/selection/pullrequest.go index b81c4a5b7b..c0c4332123 100644 --- a/pkg/views/workspace/selection/pullrequest.go +++ b/pkg/views/target/selection/pullrequest.go @@ -17,7 +17,6 @@ import ( func selectPullRequestPrompt(pullRequests []apiclient.GitPullRequest, projectOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { items := []list.Item{} - // Populate items with titles and descriptions from workspaces. for _, pr := range pullRequests { newItem := item[string]{ id: pr.Name, diff --git a/pkg/views/workspace/selection/repository.go b/pkg/views/target/selection/repository.go similarity index 97% rename from pkg/views/workspace/selection/repository.go rename to pkg/views/target/selection/repository.go index d5f5fe92d3..5557a08013 100644 --- a/pkg/views/workspace/selection/repository.go +++ b/pkg/views/target/selection/repository.go @@ -17,7 +17,6 @@ import ( func selectRepositoryPrompt(repositories []apiclient.GitRepository, projectOrder int, choiceChan chan<- string, navChan chan<- string, selectedRepos map[string]int, selectionListOptions views.SelectionListOptions) { items := []list.Item{} - // Populate items with titles and descriptions from workspaces. for _, repository := range repositories { newItem := item[string]{ id: repository.Url, diff --git a/pkg/views/workspace/selection/sample.go b/pkg/views/target/selection/sample.go similarity index 94% rename from pkg/views/workspace/selection/sample.go rename to pkg/views/target/selection/sample.go index 708f06d351..5ac672188a 100644 --- a/pkg/views/workspace/selection/sample.go +++ b/pkg/views/target/selection/sample.go @@ -17,7 +17,6 @@ import ( func selectSamplePrompt(samples []apiclient.Sample, choiceChan chan<- *apiclient.Sample) { items := []list.Item{} - // Populate items with titles and descriptions from workspaces. for _, sample := range samples { newItem := item[apiclient.Sample]{id: sample.Name, title: sample.Name, desc: sample.GitUrl, choiceProperty: sample} items = append(items, newItem) diff --git a/pkg/views/target/selection/target.go b/pkg/views/target/selection/target.go new file mode 100644 index 0000000000..c45bda76ce --- /dev/null +++ b/pkg/views/target/selection/target.go @@ -0,0 +1,147 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package selection + +import ( + "fmt" + "os" + "strings" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + list_view "github.com/daytonaio/daytona/pkg/views/target/list" +) + +func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, action string) []list.Item { + + // Initialize an empty list of items. + items := []list.Item{} + + // Populate items with titles and descriptions from targets. + for _, target := range targets { + var projectsInfo []string + + if len(target.Projects) == 0 { + continue + } + + if len(target.Projects) == 1 { + projectsInfo = append(projectsInfo, util.GetRepositorySlugFromUrl(target.Projects[0].Repository.Url, true)) + } else { + for _, project := range target.Projects { + projectsInfo = append(projectsInfo, project.Name) + } + } + + // Get the time if available + uptime := "" + createdTime := "" + if target.Info != nil && target.Info.Projects != nil && len(target.Info.Projects) > 0 { + createdTime = util.FormatTimestamp(target.Info.Projects[0].Created) + } + if len(target.Projects) > 0 && target.Projects[0].State != nil { + if target.Projects[0].State.Uptime == 0 { + uptime = "STOPPED" + } else { + uptime = fmt.Sprintf("up %s", util.FormatUptime(target.Projects[0].State.Uptime)) + } + } + + newItem := item[apiclient.TargetDTO]{ + title: target.Name, + id: target.Id, + desc: strings.Join(projectsInfo, ", "), + createdTime: createdTime, + uptime: uptime, + targetConfig: target.TargetConfig, + choiceProperty: target, + } + + if isMultipleSelect { + newItem.isMultipleSelect = true + newItem.action = action + } + + items = append(items, newItem) + } + + return items +} + +func getTargetProgramEssentials(modelTitle string, actionVerb string, targets []apiclient.TargetDTO, footerText string, isMultipleSelect bool) tea.Model { + + items := generateTargetList(targets, isMultipleSelect, actionVerb) + + d := ItemDelegate[apiclient.TargetDTO]{} + + l := list.New(items, d, 0, 0) + + l.Styles.FilterPrompt = lipgloss.NewStyle().Foreground(views.Green) + l.Styles.FilterCursor = lipgloss.NewStyle().Foreground(views.Green) + + l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) + l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) + + m := model[apiclient.TargetDTO]{list: l} + + m.list.Title = views.GetStyledMainTitle(modelTitle + actionVerb) + m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) + m.footer = footerText + + p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() + + if err != nil { + fmt.Println("Error running program:", err) + os.Exit(1) + } + + return p +} + +func selectTargetPrompt(targets []apiclient.TargetDTO, actionVerb string, choiceChan chan<- *apiclient.TargetDTO) { + list_view.SortTargets(&targets, true) + + p := getTargetProgramEssentials("Select a Target To ", actionVerb, targets, "", false) + if m, ok := p.(model[apiclient.TargetDTO]); ok && m.choice != nil { + choiceChan <- m.choice + } else { + choiceChan <- nil + } +} + +func GetTargetFromPrompt(targets []apiclient.TargetDTO, actionVerb string) *apiclient.TargetDTO { + choiceChan := make(chan *apiclient.TargetDTO) + + go selectTargetPrompt(targets, actionVerb, choiceChan) + + return <-choiceChan +} + +func selectTargetsFromPrompt(targets []apiclient.TargetDTO, actionVerb string, choiceChan chan<- []*apiclient.TargetDTO) { + list_view.SortTargets(&targets, true) + + footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark target.\nPress 'enter' to %s the current/marked targets.", actionVerb)) + p := getTargetProgramEssentials("Select Targets To ", actionVerb, targets, footerText, true) + + m, ok := p.(model[apiclient.TargetDTO]) + if ok && m.choices != nil { + choiceChan <- m.choices + } else if ok && m.choice != nil { + choiceChan <- []*apiclient.TargetDTO{m.choice} + } else { + choiceChan <- nil + } +} + +func GetTargetsFromPrompt(targets []apiclient.TargetDTO, actionVerb string) []*apiclient.TargetDTO { + choiceChan := make(chan []*apiclient.TargetDTO) + + go selectTargetsFromPrompt(targets, actionVerb, choiceChan) + + return <-choiceChan +} diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/target/selection/view.go similarity index 92% rename from pkg/views/workspace/selection/view.go rename to pkg/views/target/selection/view.go index 35b2d000ef..23b6464407 100644 --- a/pkg/views/workspace/selection/view.go +++ b/pkg/views/target/selection/view.go @@ -84,15 +84,15 @@ func (m model[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd) { if ok { m.choice = &i.choiceProperty } - workspaceList := m.list.Items() + targetList := m.list.Items() var choices []*T - for _, workspace := range workspaceList { - if workspace.(item[T]).isMarked { - workspaceItem, ok := workspace.(item[T]) + for _, target := range targetList { + if target.(item[T]).isMarked { + targetItem, ok := target.(item[T]) if !ok { continue } - choices = append(choices, &workspaceItem.choiceProperty) + choices = append(choices, &targetItem.choiceProperty) } } @@ -213,14 +213,14 @@ func (d ItemDelegate[T]) Update(msg tea.Msg, m *list.Model) tea.Cmd { i.title = strings.TrimPrefix(i.title, statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action))) i.isMarked = false m.SetItem(m.Index(), i) - return m.NewStatusMessage(statusMessageGreenStyle("Removed workspace from list: ") + statusMessageGreenStyle(i.title)) + return m.NewStatusMessage(statusMessageGreenStyle("Removed target from list: ") + statusMessageGreenStyle(i.title)) } title = i.title i.title = statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action)) + statusMessageGreenStyle(i.title) i.isMarked = true m.SetItem(m.Index(), i) - return m.NewStatusMessage(statusMessageDangerStyle("Added workspace to list: ") + statusMessageGreenStyle(title)) + return m.NewStatusMessage(statusMessageDangerStyle("Added target to list: ") + statusMessageGreenStyle(title)) } } return nil diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index a94807686e..e7affff1ff 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -33,10 +33,10 @@ func NotifyEmptyProjectConfigList(tip bool) { } } -func NotifyEmptyWorkspaceList(tip bool) { - views.RenderInfoMessageBold("No workspaces found") +func NotifyEmptyTargetList(tip bool) { + views.RenderInfoMessageBold("No targets found") if tip { - views.RenderTip("Use 'daytona create' to create a workspace") + views.RenderTip("Use 'daytona create' to create a target") } } diff --git a/pkg/views/util/table.go b/pkg/views/util/table.go index 4a54e15278..62196d1156 100644 --- a/pkg/views/util/table.go +++ b/pkg/views/util/table.go @@ -16,7 +16,7 @@ import ( var AdditionalPropertyPadding = " " -// Left border, BaseTableStyle padding left, additional padding for workspace name and target config, BaseTableStyle padding right, BaseCellStyle padding right, right border +// Left border, BaseTableStyle padding left, additional padding for target name and target config, BaseTableStyle padding right, BaseCellStyle padding right, right border var RowWhiteSpace = 1 + 4 + len(AdditionalPropertyPadding)*2 + 4 + 4 + 1 var ArbitrarySpace = 10 diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go deleted file mode 100644 index f82a95b072..0000000000 --- a/pkg/views/workspace/selection/workspace.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package selection - -import ( - "fmt" - "os" - "strings" - - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - list_view "github.com/daytonaio/daytona/pkg/views/workspace/list" -) - -func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect bool, action string) []list.Item { - - // Initialize an empty list of items. - items := []list.Item{} - - // Populate items with titles and descriptions from workspaces. - for _, workspace := range workspaces { - var projectsInfo []string - - if len(workspace.Projects) == 0 { - continue - } - - if len(workspace.Projects) == 1 { - projectsInfo = append(projectsInfo, util.GetRepositorySlugFromUrl(workspace.Projects[0].Repository.Url, true)) - } else { - for _, project := range workspace.Projects { - projectsInfo = append(projectsInfo, project.Name) - } - } - - // Get the time if available - uptime := "" - createdTime := "" - if workspace.Info != nil && workspace.Info.Projects != nil && len(workspace.Info.Projects) > 0 { - createdTime = util.FormatTimestamp(workspace.Info.Projects[0].Created) - } - if len(workspace.Projects) > 0 && workspace.Projects[0].State != nil { - if workspace.Projects[0].State.Uptime == 0 { - uptime = "STOPPED" - } else { - uptime = fmt.Sprintf("up %s", util.FormatUptime(workspace.Projects[0].State.Uptime)) - } - } - - newItem := item[apiclient.WorkspaceDTO]{ - title: workspace.Name, - id: workspace.Id, - desc: strings.Join(projectsInfo, ", "), - createdTime: createdTime, - uptime: uptime, - targetConfig: workspace.TargetConfig, - choiceProperty: workspace, - } - - if isMultipleSelect { - newItem.isMultipleSelect = true - newItem.action = action - } - - items = append(items, newItem) - } - - return items -} - -func getWorkspaceProgramEssentials(modelTitle string, actionVerb string, workspaces []apiclient.WorkspaceDTO, footerText string, isMultipleSelect bool) tea.Model { - - items := generateWorkspaceList(workspaces, isMultipleSelect, actionVerb) - - d := ItemDelegate[apiclient.WorkspaceDTO]{} - - l := list.New(items, d, 0, 0) - - l.Styles.FilterPrompt = lipgloss.NewStyle().Foreground(views.Green) - l.Styles.FilterCursor = lipgloss.NewStyle().Foreground(views.Green) - - l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) - l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) - - m := model[apiclient.WorkspaceDTO]{list: l} - - m.list.Title = views.GetStyledMainTitle(modelTitle + actionVerb) - m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) - m.footer = footerText - - p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() - - if err != nil { - fmt.Println("Error running program:", err) - os.Exit(1) - } - - return p -} - -func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- *apiclient.WorkspaceDTO) { - list_view.SortWorkspaces(&workspaces, true) - - p := getWorkspaceProgramEssentials("Select a Workspace To ", actionVerb, workspaces, "", false) - if m, ok := p.(model[apiclient.WorkspaceDTO]); ok && m.choice != nil { - choiceChan <- m.choice - } else { - choiceChan <- nil - } -} - -func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) *apiclient.WorkspaceDTO { - choiceChan := make(chan *apiclient.WorkspaceDTO) - - go selectWorkspacePrompt(workspaces, actionVerb, choiceChan) - - return <-choiceChan -} - -func selectWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- []*apiclient.WorkspaceDTO) { - list_view.SortWorkspaces(&workspaces, true) - - footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark workspace.\nPress 'enter' to %s the current/marked workspaces.", actionVerb)) - p := getWorkspaceProgramEssentials("Select Workspaces To ", actionVerb, workspaces, footerText, true) - - m, ok := p.(model[apiclient.WorkspaceDTO]) - if ok && m.choices != nil { - choiceChan <- m.choices - } else if ok && m.choice != nil { - choiceChan <- []*apiclient.WorkspaceDTO{m.choice} - } else { - choiceChan <- nil - } -} - -func GetWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) []*apiclient.WorkspaceDTO { - choiceChan := make(chan []*apiclient.WorkspaceDTO) - - go selectWorkspacesFromPrompt(workspaces, actionVerb, choiceChan) - - return <-choiceChan -} diff --git a/pkg/workspace/store.go b/pkg/workspace/store.go deleted file mode 100644 index eeec232fa7..0000000000 --- a/pkg/workspace/store.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspace - -import "errors" - -type Store interface { - List() ([]*Workspace, error) - Find(idOrName string) (*Workspace, error) - Save(workspace *Workspace) error - Delete(workspace *Workspace) error -} - -var ( - ErrWorkspaceNotFound = errors.New("workspace not found") -) - -func IsWorkspaceNotFound(err error) bool { - return err.Error() == ErrWorkspaceNotFound.Error() -} From b53cfeee3855a177bfa3a32aa4009200788f60e0 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Mon, 28 Oct 2024 11:45:20 +0100 Subject: [PATCH 03/76] refactor: rename project to workspace (#1299) BREAKING CHANGE: - renamed all occurrences of project to workspace - renamed all relevant functions, methods and commands - changed the provider interface to use Workspace instead of Project Signed-off-by: Ivan Dagelic --- .vscode/launch.json | 2 +- README.md | 2 +- cmd/daytona/config/ssh_file.go | 58 +- docs/agent_mode/daytona.md | 34 - docs/agent_mode/daytona_agent.md | 25 - docs/agent_mode/daytona_agent_logs.md | 24 - docs/agent_mode/daytona_autocomplete.md | 18 - docs/agent_mode/daytona_docs.md | 18 - docs/agent_mode/daytona_expose.md | 18 - docs/agent_mode/daytona_forward.md | 18 - docs/agent_mode/daytona_info.md | 24 - docs/agent_mode/daytona_list.md | 25 - docs/agent_mode/daytona_logs.md | 25 - docs/agent_mode/daytona_restart.md | 18 - docs/agent_mode/daytona_start.md | 18 - docs/agent_mode/daytona_stop.md | 18 - docs/agent_mode/daytona_version.md | 18 - docs/daytona.md | 55 - docs/daytona_api-key.md | 17 - docs/daytona_api-key_generate.md | 18 - docs/daytona_api-key_list.md | 24 - docs/daytona_api-key_revoke.md | 24 - docs/daytona_autocomplete.md | 18 - docs/daytona_build.md | 19 - docs/daytona_build_delete.md | 26 - docs/daytona_build_info.md | 24 - docs/daytona_build_list.md | 24 - docs/daytona_build_logs.md | 24 - docs/daytona_build_run.md | 18 - docs/daytona_code.md | 25 - docs/daytona_config.md | 25 - docs/daytona_container-registry.md | 17 - docs/daytona_container-registry_delete.md | 18 - docs/daytona_container-registry_list.md | 24 - docs/daytona_container-registry_set.md | 26 - docs/daytona_create.md | 38 - docs/daytona_delete.md | 26 - docs/daytona_docs.md | 18 - docs/daytona_env.md | 16 - docs/daytona_env_list.md | 24 - docs/daytona_env_set.md | 18 - docs/daytona_forward.md | 24 - docs/daytona_git-providers.md | 18 - docs/daytona_git-providers_add.md | 29 - docs/daytona_git-providers_delete.md | 25 - docs/daytona_git-providers_list.md | 24 - docs/daytona_git-providers_update.md | 18 - docs/daytona_ide.md | 18 - docs/daytona_info.md | 24 - docs/daytona_list.md | 25 - docs/daytona_logs.md | 25 - docs/daytona_prebuild.md | 19 - docs/daytona_prebuild_add.md | 28 - docs/daytona_prebuild_delete.md | 24 - docs/daytona_prebuild_info.md | 24 - docs/daytona_prebuild_list.md | 24 - docs/daytona_prebuild_update.md | 28 - docs/daytona_profile.md | 19 - docs/daytona_profile_add.md | 26 - docs/daytona_profile_delete.md | 18 - docs/daytona_profile_edit.md | 26 - docs/daytona_profile_list.md | 24 - docs/daytona_project-config.md | 22 - docs/daytona_project-config_add.md | 31 - docs/daytona_project-config_delete.md | 26 - docs/daytona_project-config_info.md | 24 - docs/daytona_project-config_list.md | 24 - docs/daytona_project-config_set-default.md | 18 - docs/daytona_project-config_update.md | 18 - docs/daytona_provider.md | 18 - docs/daytona_provider_install.md | 24 - docs/daytona_provider_list.md | 24 - docs/daytona_provider_uninstall.md | 18 - docs/daytona_provider_update.md | 24 - docs/daytona_purge.md | 29 - docs/daytona_restart.md | 24 - docs/daytona_serve.md | 18 - docs/daytona_server.md | 30 - docs/daytona_server_config.md | 24 - docs/daytona_server_configure.md | 18 - docs/daytona_server_logs.md | 27 - docs/daytona_server_logs_list.md | 18 - docs/daytona_server_restart.md | 18 - docs/daytona_server_start.md | 18 - docs/daytona_server_stop.md | 18 - docs/daytona_ssh.md | 26 - docs/daytona_start.md | 27 - docs/daytona_stop.md | 25 - docs/daytona_target-config.md | 18 - docs/daytona_target-config_list.md | 24 - docs/daytona_target-config_remove.md | 24 - docs/daytona_target-config_set-default.md | 18 - docs/daytona_target-config_set.md | 18 - docs/daytona_telemetry.md | 16 - docs/daytona_telemetry_disable.md | 18 - docs/daytona_telemetry_enable.md | 18 - docs/daytona_use.md | 18 - docs/daytona_version.md | 18 - docs/daytona_whoami.md | 24 - .../.devcontainer/devcontainer.json | 2 +- hack/docs/agent_mode/daytona.yaml | 25 - hack/docs/agent_mode/daytona_agent.yaml | 14 - hack/docs/agent_mode/daytona_agent_logs.yaml | 14 - .../docs/agent_mode/daytona_autocomplete.yaml | 9 - hack/docs/agent_mode/daytona_docs.yaml | 9 - hack/docs/agent_mode/daytona_expose.yaml | 10 - hack/docs/agent_mode/daytona_forward.yaml | 9 - hack/docs/agent_mode/daytona_info.yaml | 13 - hack/docs/agent_mode/daytona_list.yaml | 17 - hack/docs/agent_mode/daytona_logs.yaml | 18 - hack/docs/agent_mode/daytona_restart.yaml | 9 - hack/docs/agent_mode/daytona_start.yaml | 9 - hack/docs/agent_mode/daytona_stop.yaml | 9 - hack/docs/agent_mode/daytona_version.yaml | 9 - hack/docs/daytona.yaml | 46 - hack/docs/daytona_api-key.yaml | 11 - hack/docs/daytona_api-key_generate.yaml | 9 - hack/docs/daytona_api-key_list.yaml | 13 - hack/docs/daytona_api-key_revoke.yaml | 14 - hack/docs/daytona_autocomplete.yaml | 9 - hack/docs/daytona_build.yaml | 13 - hack/docs/daytona_build_delete.yaml | 20 - hack/docs/daytona_build_info.yaml | 13 - hack/docs/daytona_build_list.yaml | 13 - hack/docs/daytona_build_logs.yaml | 14 - hack/docs/daytona_build_run.yaml | 9 - hack/docs/daytona_code.yaml | 18 - hack/docs/daytona_config.yaml | 17 - hack/docs/daytona_container-registry.yaml | 11 - .../daytona_container-registry_delete.yaml | 9 - .../docs/daytona_container-registry_list.yaml | 13 - hack/docs/daytona_container-registry_set.yaml | 19 - hack/docs/daytona_create.yaml | 56 - hack/docs/daytona_delete.yaml | 22 - hack/docs/daytona_docs.yaml | 9 - hack/docs/daytona_env.yaml | 11 - hack/docs/daytona_env_list.yaml | 13 - hack/docs/daytona_env_set.yaml | 9 - hack/docs/daytona_forward.yaml | 13 - hack/docs/daytona_git-providers.yaml | 12 - hack/docs/daytona_git-providers_add.yaml | 28 - hack/docs/daytona_git-providers_delete.yaml | 18 - hack/docs/daytona_git-providers_list.yaml | 13 - hack/docs/daytona_git-providers_update.yaml | 9 - hack/docs/daytona_ide.yaml | 9 - hack/docs/daytona_info.yaml | 13 - hack/docs/daytona_list.yaml | 17 - hack/docs/daytona_logs.yaml | 18 - hack/docs/daytona_prebuild.yaml | 13 - hack/docs/daytona_prebuild_add.yaml | 30 - hack/docs/daytona_prebuild_delete.yaml | 14 - hack/docs/daytona_prebuild_info.yaml | 13 - hack/docs/daytona_prebuild_list.yaml | 13 - hack/docs/daytona_prebuild_update.yaml | 30 - hack/docs/daytona_profile.yaml | 13 - hack/docs/daytona_profile_add.yaml | 19 - hack/docs/daytona_profile_delete.yaml | 9 - hack/docs/daytona_profile_edit.yaml | 19 - hack/docs/daytona_profile_list.yaml | 13 - hack/docs/daytona_project-config.yaml | 16 - hack/docs/daytona_project-config_add.yaml | 32 - hack/docs/daytona_project-config_delete.yaml | 22 - hack/docs/daytona_project-config_info.yaml | 13 - hack/docs/daytona_project-config_list.yaml | 13 - .../daytona_project-config_set-default.yaml | 9 - hack/docs/daytona_project-config_update.yaml | 9 - hack/docs/daytona_provider.yaml | 12 - hack/docs/daytona_provider_install.yaml | 14 - hack/docs/daytona_provider_list.yaml | 13 - hack/docs/daytona_provider_uninstall.yaml | 9 - hack/docs/daytona_provider_update.yaml | 14 - hack/docs/daytona_purge.yaml | 20 - hack/docs/daytona_restart.yaml | 13 - hack/docs/daytona_serve.yaml | 9 - hack/docs/daytona_server.yaml | 20 - hack/docs/daytona_server_config.yaml | 13 - hack/docs/daytona_server_configure.yaml | 9 - hack/docs/daytona_server_logs.yaml | 21 - hack/docs/daytona_server_logs_list.yaml | 9 - hack/docs/daytona_server_restart.yaml | 9 - hack/docs/daytona_server_start.yaml | 9 - hack/docs/daytona_server_stop.yaml | 9 - hack/docs/daytona_ssh.yaml | 22 - hack/docs/daytona_start.yaml | 25 - hack/docs/daytona_stop.yaml | 17 - hack/docs/daytona_target-config.yaml | 12 - hack/docs/daytona_target-config_list.yaml | 13 - hack/docs/daytona_target-config_remove.yaml | 14 - .../daytona_target-config_set-default.yaml | 9 - hack/docs/daytona_target-config_set.yaml | 9 - hack/docs/daytona_telemetry.yaml | 10 - hack/docs/daytona_telemetry_disable.yaml | 9 - hack/docs/daytona_telemetry_enable.yaml | 9 - hack/docs/daytona_use.yaml | 9 - hack/docs/daytona_version.yaml | 9 - hack/docs/daytona_whoami.yaml | 13 - .../.devcontainer/devcontainer.json | 0 .../Dockerfile | 0 .../docker/postinstall.sh | 0 internal/cmd/tailscale/forward.go | 6 +- internal/testing/docker/mocks/client.go | 32 +- internal/testing/git/mocks/gitservice.go | 6 +- internal/testing/logger/mocks/logger.go | 8 +- .../testing/server/projectconfig/store.go | 94 - .../server/targets/mocks/api_key_service.go | 2 +- .../testing/server/targets/mocks/builder.go | 12 +- .../targets/mocks/project_config_service.go | 81 - .../server/targets/mocks/provisioner.go | 14 +- ...{project_config.go => workspace_config.go} | 6 +- .../targets/mocks/workspace_config_service.go | 81 + .../testing/server/workspaceconfig/store.go | 94 + internal/util/apiclient/api_client.go | 20 +- internal/util/apiclient/conversion/project.go | 207 --- .../util/apiclient/conversion/workspace.go | 207 +++ .../util/apiclient/websocket_log_reader.go | 16 +- internal/util/path.go | 24 +- pkg/agent/agent.go | 38 +- pkg/agent/agent_test.go | 26 +- pkg/agent/config/config.go | 24 +- pkg/agent/ssh/server.go | 16 +- pkg/agent/toolbox/git/add.go | 2 +- pkg/agent/toolbox/git/clone_repository.go | 2 +- pkg/agent/toolbox/git/commit.go | 2 +- pkg/agent/toolbox/git/create_branch.go | 2 +- pkg/agent/toolbox/git/history.go | 2 +- pkg/agent/toolbox/git/list_branches.go | 2 +- pkg/agent/toolbox/git/pull.go | 2 +- pkg/agent/toolbox/git/push.go | 2 +- pkg/agent/toolbox/git/status.go | 2 +- pkg/agent/toolbox/process/execute.go | 4 +- pkg/agent/toolbox/process/session/session.go | 4 +- pkg/agent/toolbox/toolbox.go | 22 +- pkg/api/controllers/binary/get_daytona.go | 2 +- pkg/api/controllers/build/build.go | 20 +- pkg/api/controllers/build/dto/dto.go | 8 +- pkg/api/controllers/log/websocket.go | 12 +- .../projectconfig/project_config.go | 218 --- pkg/api/controllers/target/dto/dto.go | 12 +- pkg/api/controllers/target/project.go | 53 - pkg/api/controllers/target/start.go | 20 +- pkg/api/controllers/target/stop.go | 20 +- pkg/api/controllers/target/workspace.go | 53 + .../controllers/workspace/toolbox/toolbox.go | 42 +- .../prebuild/prebuild.go | 42 +- .../prebuild/process_git_event.go | 4 +- .../workspaceconfig/workspace_config.go | 218 +++ pkg/api/docs/docs.go | 1548 ++++++++--------- pkg/api/docs/swagger.json | 1548 ++++++++--------- pkg/api/docs/swagger.yaml | 1130 ++++++------ pkg/api/middlewares/auth.go | 4 +- pkg/api/middlewares/telemetry.go | 6 +- .../middlewares/{project.go => workspace.go} | 4 +- pkg/api/server.go | 50 +- pkg/apiclient/README.md | 50 +- pkg/apiclient/api/openapi.yaml | 1398 +++++++-------- pkg/apiclient/api_prebuild.go | 36 +- pkg/apiclient/api_target.go | 174 +- ...ject_config.go => api_workspace_config.go} | 178 +- pkg/apiclient/api_workspace_toolbox.go | 74 +- pkg/apiclient/client.go | 6 +- pkg/apiclient/docs/ApiKey.md | 2 +- pkg/apiclient/docs/ApikeyApiKeyType.md | 2 +- pkg/apiclient/docs/BuildAPI.md | 2 +- pkg/apiclient/docs/CreateBuildDTO.md | 22 +- pkg/apiclient/docs/CreateTargetDTO.md | 40 +- ...nfigDTO.md => CreateWorkspaceConfigDTO.md} | 64 +- ...ateProjectDTO.md => CreateWorkspaceDTO.md} | 66 +- ...urceDTO.md => CreateWorkspaceSourceDTO.md} | 20 +- pkg/apiclient/docs/PrebuildAPI.md | 36 +- pkg/apiclient/docs/PrebuildDTO.md | 44 +- pkg/apiclient/docs/ServerAPI.md | 2 +- pkg/apiclient/docs/ServerConfig.md | 42 +- ...etProjectState.md => SetWorkspaceState.md} | 28 +- pkg/apiclient/docs/Target.md | 40 +- pkg/apiclient/docs/TargetAPI.md | 88 +- pkg/apiclient/docs/TargetDTO.md | 40 +- pkg/apiclient/docs/TargetInfo.md | 44 +- .../docs/{Project.md => Workspace.md} | 82 +- .../{ProjectConfig.md => WorkspaceConfig.md} | 74 +- ...jectConfigAPI.md => WorkspaceConfigAPI.md} | 108 +- ...DirResponse.md => WorkspaceDirResponse.md} | 22 +- .../docs/{ProjectInfo.md => WorkspaceInfo.md} | 46 +- .../{ProjectState.md => WorkspaceState.md} | 34 +- pkg/apiclient/docs/WorkspaceToolboxAPI.md | 54 +- pkg/apiclient/model_api_key.go | 2 +- pkg/apiclient/model_apikey_api_key_type.go | 8 +- pkg/apiclient/model_create_build_dto.go | 34 +- pkg/apiclient/model_create_target_dto.go | 56 +- ...o => model_create_workspace_config_dto.go} | 104 +- ...t_dto.go => model_create_workspace_dto.go} | 120 +- ...o => model_create_workspace_source_dto.go} | 60 +- pkg/apiclient/model_prebuild_dto.go | 68 +- pkg/apiclient/model_server_config.go | 54 +- ..._state.go => model_set_workspace_state.go} | 68 +- pkg/apiclient/model_target.go | 56 +- pkg/apiclient/model_target_dto.go | 50 +- pkg/apiclient/model_target_info.go | 62 +- .../{model_project.go => model_workspace.go} | 126 +- ...ct_config.go => model_workspace_config.go} | 114 +- ...nse.go => model_workspace_dir_response.go} | 52 +- ...roject_info.go => model_workspace_info.go} | 86 +- ...ject_state.go => model_workspace_state.go} | 74 +- pkg/apikey/apikey.go | 8 +- pkg/build/build.go | 4 +- pkg/build/builder.go | 8 +- pkg/build/detect/detect.go | 16 +- pkg/build/devcontainer.go | 22 +- pkg/build/factory.go | 26 +- pkg/build/runner.go | 28 +- pkg/build/runner_test.go | 12 +- pkg/build/store.go | 2 +- pkg/cmd/agent/agent.go | 28 +- pkg/cmd/agentmode/agent_mode.go | 8 +- pkg/cmd/agentmode/expose.go | 2 +- pkg/cmd/agentmode/forward.go | 2 +- pkg/cmd/agentmode/git_cred.go | 6 +- pkg/cmd/agentmode/info.go | 2 +- pkg/cmd/agentmode/restart.go | 8 +- pkg/cmd/agentmode/start.go | 6 +- pkg/cmd/agentmode/stop.go | 8 +- pkg/cmd/build/run.go | 34 +- pkg/cmd/cmd.go | 8 +- pkg/cmd/logs.go | 28 +- pkg/cmd/ports/forward.go | 18 +- pkg/cmd/prebuild/add.go | 48 +- pkg/cmd/prebuild/delete.go | 14 +- pkg/cmd/prebuild/info.go | 6 +- pkg/cmd/prebuild/update.go | 32 +- pkg/cmd/profiledata/env/env.go | 2 +- pkg/cmd/projectconfig/add.go | 294 ---- pkg/cmd/projectconfig/delete.go | 116 -- pkg/cmd/projectconfig/projectconfig.go | 27 - pkg/cmd/server/serve.go | 28 +- pkg/cmd/target/code.go | 80 +- pkg/cmd/target/create.go | 184 +- pkg/cmd/target/restart.go | 18 +- pkg/cmd/target/ssh-proxy.go | 24 +- pkg/cmd/target/ssh.go | 47 +- pkg/cmd/target/start.go | 66 +- pkg/cmd/target/stop.go | 44 +- pkg/cmd/target/util/add_from_config.go | 26 +- pkg/cmd/target/util/branch_wizard.go | 8 +- pkg/cmd/target/util/creation_data.go | 142 +- pkg/cmd/target/util/repository_wizard.go | 16 +- pkg/cmd/target/util/target.go | 42 +- pkg/cmd/workspaceconfig/add.go | 293 ++++ pkg/cmd/workspaceconfig/delete.go | 116 ++ .../export.go | 64 +- .../import.go | 82 +- .../info.go | 28 +- .../list.go | 16 +- .../setdefault.go | 26 +- .../update.go | 60 +- pkg/cmd/workspaceconfig/workspaceconfig.go | 27 + pkg/common/get_daytona_script.go | 2 +- pkg/db/build_store.go | 2 +- pkg/db/dto/build.go | 8 +- pkg/db/dto/project_config.go | 86 - pkg/db/dto/target.go | 28 +- pkg/db/dto/{project.go => workspace.go} | 116 +- pkg/db/dto/workspace_config.go | 86 + pkg/db/project_config_store.go | 94 - pkg/db/workspace_config_store.go | 94 + pkg/docker/README.md | 4 +- pkg/docker/client.go | 38 +- pkg/docker/client_test.go | 10 +- pkg/docker/container_logs_test.go | 2 +- pkg/docker/create.go | 44 +- pkg/docker/create_devcontainer.go | 62 +- pkg/docker/create_image.go | 48 +- pkg/docker/create_test.go | 26 +- pkg/docker/destroy.go | 14 +- pkg/docker/destroy_test.go | 12 +- pkg/docker/exec_test.go | 6 +- pkg/docker/info.go | 32 +- pkg/docker/info_test.go | 22 +- pkg/docker/start.go | 24 +- pkg/docker/start_devcontainer.go | 14 +- pkg/docker/start_image.go | 6 +- pkg/docker/start_test.go | 10 +- pkg/docker/stop.go | 10 +- pkg/docker/stop_test.go | 6 +- pkg/git/add.go | 2 +- pkg/git/branch.go | 4 +- pkg/git/clone.go | 8 +- pkg/git/commit.go | 2 +- pkg/git/config.go | 2 +- pkg/git/log.go | 2 +- pkg/git/pull.go | 2 +- pkg/git/push.go | 2 +- pkg/git/service.go | 26 +- pkg/git/service_test.go | 2 +- pkg/git/status.go | 16 +- pkg/ide/browser.go | 20 +- pkg/ide/cursor.go | 12 +- pkg/ide/fleet.go | 8 +- pkg/ide/jetbrains.go | 26 +- pkg/ide/jupyter.go | 24 +- pkg/ide/positron.go | 12 +- pkg/ide/terminal.go | 12 +- pkg/ide/vscode-insiders.go | 12 +- pkg/ide/vscode.go | 32 +- pkg/ide/vscodium-insiders.go | 13 +- pkg/ide/vscodium.go | 13 +- pkg/ide/windsurf.go | 12 +- pkg/ide/zed.go | 8 +- pkg/logs/logger.go | 18 +- pkg/logs/{project.go => workspace.go} | 48 +- pkg/provider/provider.go | 12 +- pkg/provider/rpc_client.go | 24 +- pkg/provider/rpc_server.go | 22 +- pkg/provider/types.go | 6 +- ...rt_script.go => workspace_start_script.go} | 2 +- pkg/provisioner/create.go | 6 +- pkg/provisioner/destroy.go | 8 +- pkg/provisioner/provisioner.go | 14 +- pkg/provisioner/start.go | 6 +- pkg/provisioner/stop.go | 8 +- pkg/server/apikeys/apikeys_test.go | 4 +- pkg/server/apikeys/service.go | 2 +- pkg/server/apikeys/service_test.go | 6 +- pkg/server/apikeys/validate.go | 4 +- pkg/server/apikeys/validate_test.go | 14 +- pkg/server/builds/dto/builds.go | 2 +- pkg/server/builds/service.go | 2 +- pkg/server/builds/service_test.go | 4 +- pkg/server/defaults.go | 8 +- pkg/server/gitproviders/remove.go | 12 +- pkg/server/gitproviders/service.go | 20 +- pkg/server/projectconfig/service.go | 134 -- pkg/server/projectconfig/service_test.go | 195 --- pkg/server/server.go | 8 +- pkg/server/targets/create.go | 100 +- pkg/server/targets/dto/target.go | 30 +- pkg/server/targets/error.go | 12 +- pkg/server/targets/remove.go | 26 +- pkg/server/targets/service.go | 44 +- pkg/server/targets/service_test.go | 153 +- pkg/server/targets/start.go | 42 +- pkg/server/targets/stop.go | 24 +- pkg/server/types.go | 4 +- .../dto/workspaceconfig.go} | 18 +- .../prebuild.go | 136 +- .../prebuild_test.go | 66 +- pkg/server/workspaceconfig/service.go | 133 ++ pkg/server/workspaceconfig/service_test.go | 195 +++ pkg/target/project/config/store.go | 42 - pkg/target/target.go | 30 +- .../buildconfig/config.go | 0 .../{project => workspace}/config/config.go | 28 +- .../{project => workspace}/config/prebuild.go | 0 pkg/target/workspace/config/store.go | 42 + .../containerconfig/config.go | 0 .../project.go => workspace/workspace.go} | 48 +- pkg/telemetry/constants.go | 6 +- pkg/telemetry/server_events.go | 16 +- pkg/views/build/info/view.go | 14 +- pkg/views/ide/code.go | 4 +- pkg/views/logs/display.go | 14 +- pkg/views/prebuild/add/add.go | 12 +- pkg/views/prebuild/info/view.go | 2 +- pkg/views/prebuild/list/view.go | 22 +- pkg/views/projectconfig/list/view.go | 91 - pkg/views/server/config.go | 4 +- pkg/views/server/configure.go | 8 +- pkg/views/target/create/configuration.go | 113 +- pkg/views/target/create/summary.go | 106 +- pkg/views/target/create/view.go | 12 +- pkg/views/target/info/view.go | 46 +- pkg/views/target/list/view.go | 56 +- pkg/views/target/selection/branch.go | 10 +- pkg/views/target/selection/checkout.go | 10 +- pkg/views/target/selection/gitprovider.go | 10 +- pkg/views/target/selection/namespace.go | 10 +- pkg/views/target/selection/prebuild.go | 2 +- pkg/views/target/selection/projectconfig.go | 93 - pkg/views/target/selection/pullrequest.go | 10 +- pkg/views/target/selection/repository.go | 10 +- pkg/views/target/selection/target.go | 24 +- .../selection/{project.go => workspace.go} | 24 +- pkg/views/target/selection/workspaceconfig.go | 93 + ...{projectrequest.go => workspacerequest.go} | 76 +- pkg/views/util/build_choice.go | 14 +- pkg/views/util/empty_list.go | 6 +- .../info/view.go | 48 +- pkg/views/workspaceconfig/list/view.go | 91 + 486 files changed, 8253 insertions(+), 11816 deletions(-) delete mode 100644 docs/agent_mode/daytona.md delete mode 100644 docs/agent_mode/daytona_agent.md delete mode 100644 docs/agent_mode/daytona_agent_logs.md delete mode 100644 docs/agent_mode/daytona_autocomplete.md delete mode 100644 docs/agent_mode/daytona_docs.md delete mode 100644 docs/agent_mode/daytona_expose.md delete mode 100644 docs/agent_mode/daytona_forward.md delete mode 100644 docs/agent_mode/daytona_info.md delete mode 100644 docs/agent_mode/daytona_list.md delete mode 100644 docs/agent_mode/daytona_logs.md delete mode 100644 docs/agent_mode/daytona_restart.md delete mode 100644 docs/agent_mode/daytona_start.md delete mode 100644 docs/agent_mode/daytona_stop.md delete mode 100644 docs/agent_mode/daytona_version.md delete mode 100644 docs/daytona.md delete mode 100644 docs/daytona_api-key.md delete mode 100644 docs/daytona_api-key_generate.md delete mode 100644 docs/daytona_api-key_list.md delete mode 100644 docs/daytona_api-key_revoke.md delete mode 100644 docs/daytona_autocomplete.md delete mode 100644 docs/daytona_build.md delete mode 100644 docs/daytona_build_delete.md delete mode 100644 docs/daytona_build_info.md delete mode 100644 docs/daytona_build_list.md delete mode 100644 docs/daytona_build_logs.md delete mode 100644 docs/daytona_build_run.md delete mode 100644 docs/daytona_code.md delete mode 100644 docs/daytona_config.md delete mode 100644 docs/daytona_container-registry.md delete mode 100644 docs/daytona_container-registry_delete.md delete mode 100644 docs/daytona_container-registry_list.md delete mode 100644 docs/daytona_container-registry_set.md delete mode 100644 docs/daytona_create.md delete mode 100644 docs/daytona_delete.md delete mode 100644 docs/daytona_docs.md delete mode 100644 docs/daytona_env.md delete mode 100644 docs/daytona_env_list.md delete mode 100644 docs/daytona_env_set.md delete mode 100644 docs/daytona_forward.md delete mode 100644 docs/daytona_git-providers.md delete mode 100644 docs/daytona_git-providers_add.md delete mode 100644 docs/daytona_git-providers_delete.md delete mode 100644 docs/daytona_git-providers_list.md delete mode 100644 docs/daytona_git-providers_update.md delete mode 100644 docs/daytona_ide.md delete mode 100644 docs/daytona_info.md delete mode 100644 docs/daytona_list.md delete mode 100644 docs/daytona_logs.md delete mode 100644 docs/daytona_prebuild.md delete mode 100644 docs/daytona_prebuild_add.md delete mode 100644 docs/daytona_prebuild_delete.md delete mode 100644 docs/daytona_prebuild_info.md delete mode 100644 docs/daytona_prebuild_list.md delete mode 100644 docs/daytona_prebuild_update.md delete mode 100644 docs/daytona_profile.md delete mode 100644 docs/daytona_profile_add.md delete mode 100644 docs/daytona_profile_delete.md delete mode 100644 docs/daytona_profile_edit.md delete mode 100644 docs/daytona_profile_list.md delete mode 100644 docs/daytona_project-config.md delete mode 100644 docs/daytona_project-config_add.md delete mode 100644 docs/daytona_project-config_delete.md delete mode 100644 docs/daytona_project-config_info.md delete mode 100644 docs/daytona_project-config_list.md delete mode 100644 docs/daytona_project-config_set-default.md delete mode 100644 docs/daytona_project-config_update.md delete mode 100644 docs/daytona_provider.md delete mode 100644 docs/daytona_provider_install.md delete mode 100644 docs/daytona_provider_list.md delete mode 100644 docs/daytona_provider_uninstall.md delete mode 100644 docs/daytona_provider_update.md delete mode 100644 docs/daytona_purge.md delete mode 100644 docs/daytona_restart.md delete mode 100644 docs/daytona_serve.md delete mode 100644 docs/daytona_server.md delete mode 100644 docs/daytona_server_config.md delete mode 100644 docs/daytona_server_configure.md delete mode 100644 docs/daytona_server_logs.md delete mode 100644 docs/daytona_server_logs_list.md delete mode 100644 docs/daytona_server_restart.md delete mode 100644 docs/daytona_server_start.md delete mode 100644 docs/daytona_server_stop.md delete mode 100644 docs/daytona_ssh.md delete mode 100644 docs/daytona_start.md delete mode 100644 docs/daytona_stop.md delete mode 100644 docs/daytona_target-config.md delete mode 100644 docs/daytona_target-config_list.md delete mode 100644 docs/daytona_target-config_remove.md delete mode 100644 docs/daytona_target-config_set-default.md delete mode 100644 docs/daytona_target-config_set.md delete mode 100644 docs/daytona_telemetry.md delete mode 100644 docs/daytona_telemetry_disable.md delete mode 100644 docs/daytona_telemetry_enable.md delete mode 100644 docs/daytona_use.md delete mode 100644 docs/daytona_version.md delete mode 100644 docs/daytona_whoami.md delete mode 100644 hack/docs/agent_mode/daytona.yaml delete mode 100644 hack/docs/agent_mode/daytona_agent.yaml delete mode 100644 hack/docs/agent_mode/daytona_agent_logs.yaml delete mode 100644 hack/docs/agent_mode/daytona_autocomplete.yaml delete mode 100644 hack/docs/agent_mode/daytona_docs.yaml delete mode 100644 hack/docs/agent_mode/daytona_expose.yaml delete mode 100644 hack/docs/agent_mode/daytona_forward.yaml delete mode 100644 hack/docs/agent_mode/daytona_info.yaml delete mode 100644 hack/docs/agent_mode/daytona_list.yaml delete mode 100644 hack/docs/agent_mode/daytona_logs.yaml delete mode 100644 hack/docs/agent_mode/daytona_restart.yaml delete mode 100644 hack/docs/agent_mode/daytona_start.yaml delete mode 100644 hack/docs/agent_mode/daytona_stop.yaml delete mode 100644 hack/docs/agent_mode/daytona_version.yaml delete mode 100644 hack/docs/daytona.yaml delete mode 100644 hack/docs/daytona_api-key.yaml delete mode 100644 hack/docs/daytona_api-key_generate.yaml delete mode 100644 hack/docs/daytona_api-key_list.yaml delete mode 100644 hack/docs/daytona_api-key_revoke.yaml delete mode 100644 hack/docs/daytona_autocomplete.yaml delete mode 100644 hack/docs/daytona_build.yaml delete mode 100644 hack/docs/daytona_build_delete.yaml delete mode 100644 hack/docs/daytona_build_info.yaml delete mode 100644 hack/docs/daytona_build_list.yaml delete mode 100644 hack/docs/daytona_build_logs.yaml delete mode 100644 hack/docs/daytona_build_run.yaml delete mode 100644 hack/docs/daytona_code.yaml delete mode 100644 hack/docs/daytona_config.yaml delete mode 100644 hack/docs/daytona_container-registry.yaml delete mode 100644 hack/docs/daytona_container-registry_delete.yaml delete mode 100644 hack/docs/daytona_container-registry_list.yaml delete mode 100644 hack/docs/daytona_container-registry_set.yaml delete mode 100644 hack/docs/daytona_create.yaml delete mode 100644 hack/docs/daytona_delete.yaml delete mode 100644 hack/docs/daytona_docs.yaml delete mode 100644 hack/docs/daytona_env.yaml delete mode 100644 hack/docs/daytona_env_list.yaml delete mode 100644 hack/docs/daytona_env_set.yaml delete mode 100644 hack/docs/daytona_forward.yaml delete mode 100644 hack/docs/daytona_git-providers.yaml delete mode 100644 hack/docs/daytona_git-providers_add.yaml delete mode 100644 hack/docs/daytona_git-providers_delete.yaml delete mode 100644 hack/docs/daytona_git-providers_list.yaml delete mode 100644 hack/docs/daytona_git-providers_update.yaml delete mode 100644 hack/docs/daytona_ide.yaml delete mode 100644 hack/docs/daytona_info.yaml delete mode 100644 hack/docs/daytona_list.yaml delete mode 100644 hack/docs/daytona_logs.yaml delete mode 100644 hack/docs/daytona_prebuild.yaml delete mode 100644 hack/docs/daytona_prebuild_add.yaml delete mode 100644 hack/docs/daytona_prebuild_delete.yaml delete mode 100644 hack/docs/daytona_prebuild_info.yaml delete mode 100644 hack/docs/daytona_prebuild_list.yaml delete mode 100644 hack/docs/daytona_prebuild_update.yaml delete mode 100644 hack/docs/daytona_profile.yaml delete mode 100644 hack/docs/daytona_profile_add.yaml delete mode 100644 hack/docs/daytona_profile_delete.yaml delete mode 100644 hack/docs/daytona_profile_edit.yaml delete mode 100644 hack/docs/daytona_profile_list.yaml delete mode 100644 hack/docs/daytona_project-config.yaml delete mode 100644 hack/docs/daytona_project-config_add.yaml delete mode 100644 hack/docs/daytona_project-config_delete.yaml delete mode 100644 hack/docs/daytona_project-config_info.yaml delete mode 100644 hack/docs/daytona_project-config_list.yaml delete mode 100644 hack/docs/daytona_project-config_set-default.yaml delete mode 100644 hack/docs/daytona_project-config_update.yaml delete mode 100644 hack/docs/daytona_provider.yaml delete mode 100644 hack/docs/daytona_provider_install.yaml delete mode 100644 hack/docs/daytona_provider_list.yaml delete mode 100644 hack/docs/daytona_provider_uninstall.yaml delete mode 100644 hack/docs/daytona_provider_update.yaml delete mode 100644 hack/docs/daytona_purge.yaml delete mode 100644 hack/docs/daytona_restart.yaml delete mode 100644 hack/docs/daytona_serve.yaml delete mode 100644 hack/docs/daytona_server.yaml delete mode 100644 hack/docs/daytona_server_config.yaml delete mode 100644 hack/docs/daytona_server_configure.yaml delete mode 100644 hack/docs/daytona_server_logs.yaml delete mode 100644 hack/docs/daytona_server_logs_list.yaml delete mode 100644 hack/docs/daytona_server_restart.yaml delete mode 100644 hack/docs/daytona_server_start.yaml delete mode 100644 hack/docs/daytona_server_stop.yaml delete mode 100644 hack/docs/daytona_ssh.yaml delete mode 100644 hack/docs/daytona_start.yaml delete mode 100644 hack/docs/daytona_stop.yaml delete mode 100644 hack/docs/daytona_target-config.yaml delete mode 100644 hack/docs/daytona_target-config_list.yaml delete mode 100644 hack/docs/daytona_target-config_remove.yaml delete mode 100644 hack/docs/daytona_target-config_set-default.yaml delete mode 100644 hack/docs/daytona_target-config_set.yaml delete mode 100644 hack/docs/daytona_telemetry.yaml delete mode 100644 hack/docs/daytona_telemetry_disable.yaml delete mode 100644 hack/docs/daytona_telemetry_enable.yaml delete mode 100644 hack/docs/daytona_use.yaml delete mode 100644 hack/docs/daytona_version.yaml delete mode 100644 hack/docs/daytona_whoami.yaml rename hack/{project_image => workspace_image}/.devcontainer/devcontainer.json (100%) rename hack/{project_image => workspace_image}/Dockerfile (100%) rename hack/{project_image => workspace_image}/docker/postinstall.sh (100%) delete mode 100644 internal/testing/server/projectconfig/store.go delete mode 100644 internal/testing/server/targets/mocks/project_config_service.go rename internal/testing/server/targets/mocks/{project_config.go => workspace_config.go} (65%) create mode 100644 internal/testing/server/targets/mocks/workspace_config_service.go create mode 100644 internal/testing/server/workspaceconfig/store.go delete mode 100644 internal/util/apiclient/conversion/project.go create mode 100644 internal/util/apiclient/conversion/workspace.go delete mode 100644 pkg/api/controllers/projectconfig/project_config.go delete mode 100644 pkg/api/controllers/target/project.go create mode 100644 pkg/api/controllers/target/workspace.go rename pkg/api/controllers/{projectconfig => workspaceconfig}/prebuild/prebuild.go (72%) rename pkg/api/controllers/{projectconfig => workspaceconfig}/prebuild/process_git_event.go (89%) create mode 100644 pkg/api/controllers/workspaceconfig/workspace_config.go rename pkg/api/middlewares/{project.go => workspace.go} (80%) rename pkg/apiclient/{api_project_config.go => api_workspace_config.go} (75%) rename pkg/apiclient/docs/{CreateProjectConfigDTO.md => CreateWorkspaceConfigDTO.md} (63%) rename pkg/apiclient/docs/{CreateProjectDTO.md => CreateWorkspaceDTO.md} (64%) rename pkg/apiclient/docs/{CreateProjectSourceDTO.md => CreateWorkspaceSourceDTO.md} (62%) rename pkg/apiclient/docs/{SetProjectState.md => SetWorkspaceState.md} (66%) rename pkg/apiclient/docs/{Project.md => Workspace.md} (68%) rename pkg/apiclient/docs/{ProjectConfig.md => WorkspaceConfig.md} (67%) rename pkg/apiclient/docs/{ProjectConfigAPI.md => WorkspaceConfigAPI.md} (60%) rename pkg/apiclient/docs/{ProjectDirResponse.md => WorkspaceDirResponse.md} (64%) rename pkg/apiclient/docs/{ProjectInfo.md => WorkspaceInfo.md} (68%) rename pkg/apiclient/docs/{ProjectState.md => WorkspaceState.md} (68%) rename pkg/apiclient/{model_create_project_config_dto.go => model_create_workspace_config_dto.go} (65%) rename pkg/apiclient/{model_create_project_dto.go => model_create_workspace_dto.go} (62%) rename pkg/apiclient/{model_create_project_source_dto.go => model_create_workspace_source_dto.go} (53%) rename pkg/apiclient/{model_set_project_state.go => model_set_workspace_state.go} (61%) rename pkg/apiclient/{model_project.go => model_workspace.go} (70%) rename pkg/apiclient/{model_project_config.go => model_workspace_config.go} (69%) rename pkg/apiclient/{model_project_dir_response.go => model_workspace_dir_response.go} (52%) rename pkg/apiclient/{model_project_info.go => model_workspace_info.go} (67%) rename pkg/apiclient/{model_project_state.go => model_workspace_state.go} (64%) delete mode 100644 pkg/cmd/projectconfig/add.go delete mode 100644 pkg/cmd/projectconfig/delete.go delete mode 100644 pkg/cmd/projectconfig/projectconfig.go create mode 100644 pkg/cmd/workspaceconfig/add.go create mode 100644 pkg/cmd/workspaceconfig/delete.go rename pkg/cmd/{projectconfig => workspaceconfig}/export.go (52%) rename pkg/cmd/{projectconfig => workspaceconfig}/import.go (61%) rename pkg/cmd/{projectconfig => workspaceconfig}/info.go (62%) rename pkg/cmd/{projectconfig => workspaceconfig}/list.go (68%) rename pkg/cmd/{projectconfig => workspaceconfig}/setdefault.go (53%) rename pkg/cmd/{projectconfig => workspaceconfig}/update.go (55%) create mode 100644 pkg/cmd/workspaceconfig/workspaceconfig.go delete mode 100644 pkg/db/dto/project_config.go rename pkg/db/dto/{project.go => workspace.go} (55%) create mode 100644 pkg/db/dto/workspace_config.go delete mode 100644 pkg/db/project_config_store.go create mode 100644 pkg/db/workspace_config_store.go rename pkg/logs/{project.go => workspace.go} (51%) rename pkg/provider/util/{project_start_script.go => workspace_start_script.go} (96%) delete mode 100644 pkg/server/projectconfig/service.go delete mode 100644 pkg/server/projectconfig/service_test.go rename pkg/server/{projectconfig/dto/projectconfig.go => workspaceconfig/dto/workspaceconfig.go} (67%) rename pkg/server/{projectconfig => workspaceconfig}/prebuild.go (67%) rename pkg/server/{projectconfig => workspaceconfig}/prebuild_test.go (72%) create mode 100644 pkg/server/workspaceconfig/service.go create mode 100644 pkg/server/workspaceconfig/service_test.go delete mode 100644 pkg/target/project/config/store.go rename pkg/target/{project => workspace}/buildconfig/config.go (100%) rename pkg/target/{project => workspace}/config/config.go (69%) rename pkg/target/{project => workspace}/config/prebuild.go (100%) create mode 100644 pkg/target/workspace/config/store.go rename pkg/target/{project => workspace}/containerconfig/config.go (100%) rename pkg/target/{project/project.go => workspace/workspace.go} (72%) delete mode 100644 pkg/views/projectconfig/list/view.go delete mode 100644 pkg/views/target/selection/projectconfig.go rename pkg/views/target/selection/{project.go => workspace.go} (63%) create mode 100644 pkg/views/target/selection/workspaceconfig.go rename pkg/views/target/selection/{projectrequest.go => workspacerequest.go} (55%) rename pkg/views/{projectconfig => workspaceconfig}/info/view.go (63%) create mode 100644 pkg/views/workspaceconfig/list/view.go diff --git a/.vscode/launch.json b/.vscode/launch.json index 2c09a89c3c..286e4cbb39 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "console": "integratedTerminal", "env": { "DAYTONA_TARGET_ID": "TARGET_ID", - "DAYTONA_PROJECT_NAME": "PROJECT_NAME", + "DAYTONA_WORKSPACE_NAME": "WORKSPACE_NAME", "DAYTONA_SERVER_URL": "http://localhost:3986", "DAYTONA_SERVER_API_KEY": "1234567890", }, diff --git a/README.md b/README.md index 46327dea04..1f5b6ac1a0 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Set up a development environment on any infrastructure, with a single command. - **Prebuilds System**: Drastically improve environment setup times (Contributions welcome here!). - **IDE Support** : Seamlessly supports [VS Code](https://github.com/microsoft/vscode) & [JetBrains](https://www.jetbrains.com/remote-development/gateway/) locally, ready to use without configuration. Includes a built-in Web IDE for added convenience. - **Git Provider Integration**: GitHub, GitLab, Bitbucket, Bitbucket Server, Gitea, Gitness, Azure DevOps, AWS CodeCommit, Gogs & Gitee can be connected, allowing easy repo branch or PR pull and commit back from the targets. -- **Multiple Project Targets**: Support for multiple project repositories in the same target, making it easy to develop using a micro-service architecture. +- **Multiple Workspace Targets**: Support for multiple workspace repositories in the same target, making it easy to develop using a micro-service architecture. - **Reverse Proxy Integration**: Enable collaboration and streamline feedback loops by leveraging reverse proxy functionality. Access preview ports and the Web IDE seamlessly, even behind firewalls. - **Extensibility**: Enable extensibility with plugin or provider development. Moreover, in any dynamic language, not just Go (Contributions welcome here!). - **Security**: Automatically creates a VPN connection between the client machine and the development environment, ensuring a fully secure connection. diff --git a/cmd/daytona/config/ssh_file.go b/cmd/daytona/config/ssh_file.go index ab3b9bdc1c..57f1a5c990 100644 --- a/cmd/daytona/config/ssh_file.go +++ b/cmd/daytona/config/ssh_file.go @@ -114,21 +114,21 @@ func UnlinkSshFiles() error { // Add ssh entry -func generateSshConfigEntry(profileId, targetId, projectName, knownHostsPath string, gpgForward bool) (string, error) { +func generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsPath string, gpgForward bool) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } tab := "\t" - projectHostname := GetProjectHostname(profileId, targetId, projectName) + workspaceHostname := GetWorkspaceHostname(profileId, targetId, workspaceName) config := fmt.Sprintf("Host %s\n"+ tab+"User daytona\n"+ tab+"StrictHostKeyChecking no\n"+ tab+"UserKnownHostsFile %s\n"+ tab+"ProxyCommand \"%s\" ssh-proxy %s %s %s\n"+ - tab+"ForwardAgent yes\n", projectHostname, knownHostsPath, daytonaPath, profileId, targetId, projectName) + tab+"ForwardAgent yes\n", workspaceHostname, knownHostsPath, daytonaPath, profileId, targetId, workspaceName) if gpgForward { localSocket, err := getLocalGPGSocket() @@ -137,7 +137,7 @@ func generateSshConfigEntry(profileId, targetId, projectName, knownHostsPath str return config, nil } - remoteSocket, err := getRemoteGPGSocket(projectHostname) + remoteSocket, err := getRemoteGPGSocket(workspaceHostname) if err != nil { log.Trace(err) return config, nil @@ -153,7 +153,7 @@ func generateSshConfigEntry(profileId, targetId, projectName, knownHostsPath str return config, nil } -func EnsureSshConfigEntryAdded(profileId, targetName, projectName string, gpgKey string) error { +func EnsureSshConfigEntryAdded(profileId, targetName, workspaceName string, gpgKey string) error { err := ensureSshFilesLinked() if err != nil { return err @@ -171,10 +171,10 @@ func EnsureSshConfigEntryAdded(profileId, targetName, projectName string, gpgKey } var configGenerated bool - regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, targetName, projectName)) - regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, targetName, projectName)) + regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, targetName, workspaceName)) + regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, targetName, workspaceName)) if !regexWithoutGPG.MatchString(existingContent) { - newContent, err := appendSshConfigEntry(configPath, profileId, targetName, projectName, knownHostsFile, false, existingContent) + newContent, err := appendSshConfigEntry(configPath, profileId, targetName, workspaceName, knownHostsFile, false, existingContent) if err != nil { return err } @@ -183,13 +183,13 @@ func EnsureSshConfigEntryAdded(profileId, targetName, projectName string, gpgKey } if gpgKey != "" && !regexWithGPG.MatchString(existingContent) { - _, err := appendSshConfigEntry(configPath, profileId, targetName, projectName, knownHostsFile, true, existingContent) + _, err := appendSshConfigEntry(configPath, profileId, targetName, workspaceName, knownHostsFile, true, existingContent) if err != nil { return err } - projectHostname := GetProjectHostname(profileId, targetName, projectName) - err = ExportGPGKey(gpgKey, projectHostname) + workspaceHostname := GetWorkspaceHostname(profileId, targetName, workspaceName) + err = ExportGPGKey(gpgKey, workspaceHostname) if err != nil { return err } @@ -198,11 +198,11 @@ func EnsureSshConfigEntryAdded(profileId, targetName, projectName string, gpgKey } if !configGenerated { - updatedContent, err := regenerateProxyCommand(existingContent, profileId, targetName, projectName) + updatedContent, err := regenerateProxyCommand(existingContent, profileId, targetName, workspaceName) if err != nil { return err } - err = UpdateWorkspaceSshEntry(profileId, targetName, projectName, updatedContent) + err = UpdateWorkspaceSshEntry(profileId, targetName, workspaceName, updatedContent) if err != nil { return err } @@ -211,21 +211,21 @@ func EnsureSshConfigEntryAdded(profileId, targetName, projectName string, gpgKey return nil } -func regenerateProxyCommand(existingContent, profileId, workspaceId, projectName string) (string, error) { +func regenerateProxyCommand(existingContent, profileId, targetId, workspaceName string) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } - hostLine := fmt.Sprintf("Host %s", GetProjectHostname(profileId, workspaceId, projectName)) + hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, targetId, workspaceName)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(existingContent) if matchedEntry == "" { - return "", fmt.Errorf("no SSH entry found for project %s", projectName) + return "", fmt.Errorf("no SSH entry found for workspace %s", workspaceName) } re := regexp.MustCompile(`(?m)^\s*ProxyCommand\s+.*$`) - updatedContent := re.ReplaceAllString(matchedEntry, fmt.Sprintf("\tProxyCommand \"%s\" ssh-proxy %s %s %s", daytonaPath, profileId, workspaceId, projectName)) + updatedContent := re.ReplaceAllString(matchedEntry, fmt.Sprintf("\tProxyCommand \"%s\" ssh-proxy %s %s %s", daytonaPath, profileId, targetId, workspaceName)) return updatedContent, nil } @@ -237,8 +237,8 @@ func getKnownHostsFile() string { return "/dev/null" } -func appendSshConfigEntry(configPath, profileId, targetId, projectName, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { - data, err := generateSshConfigEntry(profileId, targetId, projectName, knownHostsFile, gpgForward) +func appendSshConfigEntry(configPath, profileId, targetId, workspaceName, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { + data, err := generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsFile, gpgForward) if err != nil { return "", err } @@ -249,7 +249,7 @@ func appendSshConfigEntry(configPath, profileId, targetId, projectName, knownHos } // We want to remove the config entry gpg counterpart - configCounterpart, err := generateSshConfigEntry(profileId, targetId, projectName, knownHostsFile, !gpgForward) + configCounterpart, err := generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsFile, !gpgForward) if err != nil { return "", err } @@ -282,8 +282,8 @@ func getLocalGPGSocket() (string, error) { return strings.TrimSpace(string(output)), nil } -func getRemoteGPGSocket(projectHostname string) (string, error) { - cmd := exec.Command("ssh", projectHostname, "gpgconf --list-dir agent-socket") +func getRemoteGPGSocket(workspaceHostname string) (string, error) { + cmd := exec.Command("ssh", workspaceHostname, "gpgconf --list-dir agent-socket") output, err := cmd.Output() if err != nil { return "", fmt.Errorf("failed to get remote GPG socket: %v", err) @@ -291,7 +291,7 @@ func getRemoteGPGSocket(projectHostname string) (string, error) { return strings.TrimSpace(string(output)), nil } -func ExportGPGKey(keyID, projectHostname string) error { +func ExportGPGKey(keyID, workspaceHostname string) error { exportCmd := exec.Command("gpg", "--export", keyID) var output bytes.Buffer exportCmd.Stdout = &output @@ -300,7 +300,7 @@ func ExportGPGKey(keyID, projectHostname string) error { return err } - importCmd := exec.Command("ssh", projectHostname, "gpg --import") + importCmd := exec.Command("ssh", workspaceHostname, "gpg --import") importCmd.Stdin = &output return importCmd.Run() @@ -352,7 +352,7 @@ func RemoveTargetSshEntries(profileId, targetId string) error { return writeSshConfig(configPath, newContent) } -func UpdateWorkspaceSshEntry(profileId, targetId, projectName, updatedContent string) error { +func UpdateWorkspaceSshEntry(profileId, targetId, workspaceName, updatedContent string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -361,11 +361,11 @@ func UpdateWorkspaceSshEntry(profileId, targetId, projectName, updatedContent st return err } - hostLine := fmt.Sprintf("Host %s", GetProjectHostname(profileId, targetId, projectName)) + hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, targetId, workspaceName)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) oldContent := regex.FindString(existingContent) if oldContent == "" { - return fmt.Errorf("no SSH entry found for project %s", projectName) + return fmt.Errorf("no SSH entry found for workspace %s", workspaceName) } existingContent = strings.ReplaceAll(existingContent, oldContent, updatedContent) @@ -377,8 +377,8 @@ func UpdateWorkspaceSshEntry(profileId, targetId, projectName, updatedContent st return nil } -func GetProjectHostname(profileId, targetId, projectName string) string { - return fmt.Sprintf("%s-%s-%s", profileId, targetId, projectName) +func GetWorkspaceHostname(profileId, targetId, workspaceName string) string { + return fmt.Sprintf("%s-%s-%s", profileId, targetId, workspaceName) } func init() { diff --git a/docs/agent_mode/daytona.md b/docs/agent_mode/daytona.md deleted file mode 100644 index d27930f6ef..0000000000 --- a/docs/agent_mode/daytona.md +++ /dev/null @@ -1,34 +0,0 @@ -## daytona - -Daytona is a Dev Environment Manager - -### Synopsis - -Daytona is a Dev Environment Manager - -``` -daytona [flags] -``` - -### Options - -``` - --help help for daytona - -v, --version Display the version of Daytona -``` - -### SEE ALSO - -* [daytona agent](daytona_agent.md) - Start the agent process -* [daytona autocomplete](daytona_autocomplete.md) - Adds a completion script for your shell environment -* [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. -* [daytona expose](daytona_expose.md) - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project -* [daytona forward](daytona_forward.md) - Forward a port publicly via an URL -* [daytona info](daytona_info.md) - Show project info -* [daytona list](daytona_list.md) - List targets -* [daytona logs](daytona_logs.md) - View logs for a target/project -* [daytona restart](daytona_restart.md) - Restart the project -* [daytona start](daytona_start.md) - Start the project -* [daytona stop](daytona_stop.md) - Stop the project -* [daytona version](daytona_version.md) - Print the version number - diff --git a/docs/agent_mode/daytona_agent.md b/docs/agent_mode/daytona_agent.md deleted file mode 100644 index 7c19d6cdae..0000000000 --- a/docs/agent_mode/daytona_agent.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona agent - -Start the agent process - -``` -daytona agent [flags] -``` - -### Options - -``` - --host Run the agent in host mode -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona agent logs](daytona_agent_logs.md) - Output Daytona Agent logs - diff --git a/docs/agent_mode/daytona_agent_logs.md b/docs/agent_mode/daytona_agent_logs.md deleted file mode 100644 index b0947b016c..0000000000 --- a/docs/agent_mode/daytona_agent_logs.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona agent logs - -Output Daytona Agent logs - -``` -daytona agent logs [flags] -``` - -### Options - -``` - -f, --follow Follow logs -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona agent](daytona_agent.md) - Start the agent process - diff --git a/docs/agent_mode/daytona_autocomplete.md b/docs/agent_mode/daytona_autocomplete.md deleted file mode 100644 index 2a2d749125..0000000000 --- a/docs/agent_mode/daytona_autocomplete.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona autocomplete - -Adds a completion script for your shell environment - -``` -daytona autocomplete [bash|zsh|fish|powershell] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_docs.md b/docs/agent_mode/daytona_docs.md deleted file mode 100644 index 612505ce71..0000000000 --- a/docs/agent_mode/daytona_docs.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona docs - -Opens the Daytona documentation in your default browser. - -``` -daytona docs [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_expose.md b/docs/agent_mode/daytona_expose.md deleted file mode 100644 index 7281642f6f..0000000000 --- a/docs/agent_mode/daytona_expose.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona expose - -Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project - -``` -daytona expose [PORT] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_forward.md b/docs/agent_mode/daytona_forward.md deleted file mode 100644 index 926b4ae0d3..0000000000 --- a/docs/agent_mode/daytona_forward.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona forward - -Forward a port publicly via an URL - -``` -daytona forward [PORT] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_info.md b/docs/agent_mode/daytona_info.md deleted file mode 100644 index b91c6f9401..0000000000 --- a/docs/agent_mode/daytona_info.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona info - -Show project info - -``` -daytona info [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_list.md b/docs/agent_mode/daytona_list.md deleted file mode 100644 index 9bf836328a..0000000000 --- a/docs/agent_mode/daytona_list.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona list - -List targets - -``` -daytona list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) - -v, --verbose Show verbose output -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_logs.md b/docs/agent_mode/daytona_logs.md deleted file mode 100644 index 219a5a2701..0000000000 --- a/docs/agent_mode/daytona_logs.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona logs - -View logs for a target/project - -``` -daytona logs [TARGET] [PROJECT_NAME] [flags] -``` - -### Options - -``` - -f, --follow Follow logs - -w, --target View target logs -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_restart.md b/docs/agent_mode/daytona_restart.md deleted file mode 100644 index f1795f7416..0000000000 --- a/docs/agent_mode/daytona_restart.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona restart - -Restart the project - -``` -daytona restart [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_start.md b/docs/agent_mode/daytona_start.md deleted file mode 100644 index b100222779..0000000000 --- a/docs/agent_mode/daytona_start.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona start - -Start the project - -``` -daytona start [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_stop.md b/docs/agent_mode/daytona_stop.md deleted file mode 100644 index ea71d28747..0000000000 --- a/docs/agent_mode/daytona_stop.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona stop - -Stop the project - -``` -daytona stop [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_version.md b/docs/agent_mode/daytona_version.md deleted file mode 100644 index 2f0f9fb6a6..0000000000 --- a/docs/agent_mode/daytona_version.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona version - -Print the version number - -``` -daytona version [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona.md b/docs/daytona.md deleted file mode 100644 index 9769e1d3bd..0000000000 --- a/docs/daytona.md +++ /dev/null @@ -1,55 +0,0 @@ -## daytona - -Daytona is a Dev Environment Manager - -### Synopsis - -Daytona is a Dev Environment Manager - -``` -daytona [flags] -``` - -### Options - -``` - --help help for daytona - -v, --version Display the version of Daytona -``` - -### SEE ALSO - -* [daytona api-key](daytona_api-key.md) - Api Key commands -* [daytona autocomplete](daytona_autocomplete.md) - Adds a completion script for your shell environment -* [daytona build](daytona_build.md) - Manage builds -* [daytona code](daytona_code.md) - Open a target in your preferred IDE -* [daytona config](daytona_config.md) - Output Daytona configuration -* [daytona container-registry](daytona_container-registry.md) - Manage container registries -* [daytona create](daytona_create.md) - Create a target -* [daytona delete](daytona_delete.md) - Delete a target -* [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and projects -* [daytona forward](daytona_forward.md) - Forward a port from a project to your local machine -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers -* [daytona ide](daytona_ide.md) - Choose the default IDE -* [daytona info](daytona_info.md) - Show target info -* [daytona list](daytona_list.md) - List targets -* [daytona logs](daytona_logs.md) - View logs for a target/project -* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds -* [daytona profile](daytona_profile.md) - Manage profiles -* [daytona project-config](daytona_project-config.md) - Manage project configs -* [daytona provider](daytona_provider.md) - Manage providers -* [daytona purge](daytona_purge.md) - Purges all Daytona data from the current device -* [daytona restart](daytona_restart.md) - Restart a target -* [daytona serve](daytona_serve.md) - Run the server process in the current terminal session -* [daytona server](daytona_server.md) - Start the server process in daemon mode -* [daytona ssh](daytona_ssh.md) - SSH into a project using the terminal -* [daytona start](daytona_start.md) - Start a target -* [daytona stop](daytona_stop.md) - Stop a target -* [daytona target-config](daytona_target-config.md) - Manage target configs -* [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection -* [daytona update](daytona_update.md) - Update Daytona CLI -* [daytona use](daytona_use.md) - Use profile [PROFILE_NAME] -* [daytona version](daytona_version.md) - Print the version number -* [daytona whoami](daytona_whoami.md) - Display information about the active user - diff --git a/docs/daytona_api-key.md b/docs/daytona_api-key.md deleted file mode 100644 index 11ac2ece14..0000000000 --- a/docs/daytona_api-key.md +++ /dev/null @@ -1,17 +0,0 @@ -## daytona api-key - -Api Key commands - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona api-key generate](daytona_api-key_generate.md) - Generate a new API key -* [daytona api-key list](daytona_api-key_list.md) - List API keys -* [daytona api-key revoke](daytona_api-key_revoke.md) - Revoke an API key - diff --git a/docs/daytona_api-key_generate.md b/docs/daytona_api-key_generate.md deleted file mode 100644 index 66d7b563d4..0000000000 --- a/docs/daytona_api-key_generate.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona api-key generate - -Generate a new API key - -``` -daytona api-key generate [NAME] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona api-key](daytona_api-key.md) - Api Key commands - diff --git a/docs/daytona_api-key_list.md b/docs/daytona_api-key_list.md deleted file mode 100644 index f83d10fa1d..0000000000 --- a/docs/daytona_api-key_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona api-key list - -List API keys - -``` -daytona api-key list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona api-key](daytona_api-key.md) - Api Key commands - diff --git a/docs/daytona_api-key_revoke.md b/docs/daytona_api-key_revoke.md deleted file mode 100644 index 90366c5c1b..0000000000 --- a/docs/daytona_api-key_revoke.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona api-key revoke - -Revoke an API key - -``` -daytona api-key revoke [NAME] [flags] -``` - -### Options - -``` - -y, --yes Skip confirmation prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona api-key](daytona_api-key.md) - Api Key commands - diff --git a/docs/daytona_autocomplete.md b/docs/daytona_autocomplete.md deleted file mode 100644 index 2a2d749125..0000000000 --- a/docs/daytona_autocomplete.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona autocomplete - -Adds a completion script for your shell environment - -``` -daytona autocomplete [bash|zsh|fish|powershell] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_build.md b/docs/daytona_build.md deleted file mode 100644 index 25069c66b3..0000000000 --- a/docs/daytona_build.md +++ /dev/null @@ -1,19 +0,0 @@ -## daytona build - -Manage builds - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona build delete](daytona_build_delete.md) - Delete a build -* [daytona build info](daytona_build_info.md) - Show build info -* [daytona build list](daytona_build_list.md) - List all builds -* [daytona build logs](daytona_build_logs.md) - View logs for build -* [daytona build run](daytona_build_run.md) - Run a build from a project config - diff --git a/docs/daytona_build_delete.md b/docs/daytona_build_delete.md deleted file mode 100644 index 7e8710a650..0000000000 --- a/docs/daytona_build_delete.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona build delete - -Delete a build - -``` -daytona build delete [BUILD] [flags] -``` - -### Options - -``` - -a, --all Delete ALL builds - -f, --force Force delete build - --prebuild-id string Delete ALL builds from prebuild -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona build](daytona_build.md) - Manage builds - diff --git a/docs/daytona_build_info.md b/docs/daytona_build_info.md deleted file mode 100644 index 4f287ead34..0000000000 --- a/docs/daytona_build_info.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona build info - -Show build info - -``` -daytona build info [BUILD] [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona build](daytona_build.md) - Manage builds - diff --git a/docs/daytona_build_list.md b/docs/daytona_build_list.md deleted file mode 100644 index 8f338d5618..0000000000 --- a/docs/daytona_build_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona build list - -List all builds - -``` -daytona build list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona build](daytona_build.md) - Manage builds - diff --git a/docs/daytona_build_logs.md b/docs/daytona_build_logs.md deleted file mode 100644 index 3ac0187e57..0000000000 --- a/docs/daytona_build_logs.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona build logs - -View logs for build - -``` -daytona build logs [flags] -``` - -### Options - -``` - -f, --follow Follow logs -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona build](daytona_build.md) - Manage builds - diff --git a/docs/daytona_build_run.md b/docs/daytona_build_run.md deleted file mode 100644 index 61ba79e017..0000000000 --- a/docs/daytona_build_run.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona build run - -Run a build from a project config - -``` -daytona build run [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona build](daytona_build.md) - Manage builds - diff --git a/docs/daytona_code.md b/docs/daytona_code.md deleted file mode 100644 index 6b59d791cf..0000000000 --- a/docs/daytona_code.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona code - -Open a target in your preferred IDE - -``` -daytona code [TARGET] [PROJECT] [flags] -``` - -### Options - -``` - -i, --ide string Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) - -y, --yes Automatically confirm any prompts -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_config.md b/docs/daytona_config.md deleted file mode 100644 index 1adb37b7f0..0000000000 --- a/docs/daytona_config.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona config - -Output Daytona configuration - -``` -daytona config [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) - -k, --show-api-keys Show API keys -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_container-registry.md b/docs/daytona_container-registry.md deleted file mode 100644 index f101ccfbd7..0000000000 --- a/docs/daytona_container-registry.md +++ /dev/null @@ -1,17 +0,0 @@ -## daytona container-registry - -Manage container registries - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona container-registry delete](daytona_container-registry_delete.md) - Delete a container registry -* [daytona container-registry list](daytona_container-registry_list.md) - Lists container registries -* [daytona container-registry set](daytona_container-registry_set.md) - Set container registry - diff --git a/docs/daytona_container-registry_delete.md b/docs/daytona_container-registry_delete.md deleted file mode 100644 index bbf017d9f9..0000000000 --- a/docs/daytona_container-registry_delete.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona container-registry delete - -Delete a container registry - -``` -daytona container-registry delete [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona container-registry](daytona_container-registry.md) - Manage container registries - diff --git a/docs/daytona_container-registry_list.md b/docs/daytona_container-registry_list.md deleted file mode 100644 index ca07652b86..0000000000 --- a/docs/daytona_container-registry_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona container-registry list - -Lists container registries - -``` -daytona container-registry list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona container-registry](daytona_container-registry.md) - Manage container registries - diff --git a/docs/daytona_container-registry_set.md b/docs/daytona_container-registry_set.md deleted file mode 100644 index dd3ed61d0c..0000000000 --- a/docs/daytona_container-registry_set.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona container-registry set - -Set container registry - -``` -daytona container-registry set [flags] -``` - -### Options - -``` - -p, --password string Password - -s, --server string Server - -u, --username string Username -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona container-registry](daytona_container-registry.md) - Manage container registries - diff --git a/docs/daytona_create.md b/docs/daytona_create.md deleted file mode 100644 index ada0f9ee66..0000000000 --- a/docs/daytona_create.md +++ /dev/null @@ -1,38 +0,0 @@ -## daytona create - -Create a target - -``` -daytona create [REPOSITORY_URL | PROJECT_CONFIG_NAME]... [flags] -``` - -### Options - -``` - --blank Create a blank project without using existing configurations - --branch strings Specify the Git branches to use in the projects - --builder BuildChoice Specify the builder (currently auto/devcontainer/none) - --custom-image string Create the project with the custom image passed as the flag value; Requires setting --custom-image-user flag as well - --custom-image-user string Create the project with the custom image user passed as the flag value; Requires setting --custom-image flag as well - --devcontainer-path string Automatically assign the devcontainer builder with the path passed as the flag value - --env stringArray Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') - --git-provider-config string Specify the Git provider configuration ID or alias - -i, --ide string Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) - --manual Manually enter the Git repository - --multi-project Target with multiple projects/repos - --name string Specify the target name - -n, --no-ide Do not open the target in the IDE after target creation - -t, --target string Specify the target (e.g. 'local') - -y, --yes Automatically confirm any prompts -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_delete.md b/docs/daytona_delete.md deleted file mode 100644 index 2339118824..0000000000 --- a/docs/daytona_delete.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona delete - -Delete a target - -``` -daytona delete [TARGET] [flags] -``` - -### Options - -``` - -a, --all Delete all targets - -f, --force Delete a target by force - -y, --yes Confirm deletion without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_docs.md b/docs/daytona_docs.md deleted file mode 100644 index 612505ce71..0000000000 --- a/docs/daytona_docs.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona docs - -Opens the Daytona documentation in your default browser. - -``` -daytona docs [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_env.md b/docs/daytona_env.md deleted file mode 100644 index eaa09464d1..0000000000 --- a/docs/daytona_env.md +++ /dev/null @@ -1,16 +0,0 @@ -## daytona env - -Manage profile environment variables that are added to all targets and projects - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona env list](daytona_env_list.md) - List profile environment variables -* [daytona env set](daytona_env_set.md) - Set profile environment variables - diff --git a/docs/daytona_env_list.md b/docs/daytona_env_list.md deleted file mode 100644 index abb49fff04..0000000000 --- a/docs/daytona_env_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona env list - -List profile environment variables - -``` -daytona env list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and projects - diff --git a/docs/daytona_env_set.md b/docs/daytona_env_set.md deleted file mode 100644 index 24697cc2c9..0000000000 --- a/docs/daytona_env_set.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona env set - -Set profile environment variables - -``` -daytona env set [KEY=VALUE]... [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and projects - diff --git a/docs/daytona_forward.md b/docs/daytona_forward.md deleted file mode 100644 index f7a6d4f299..0000000000 --- a/docs/daytona_forward.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona forward - -Forward a port from a project to your local machine - -``` -daytona forward [PORT] [TARGET] [PROJECT] [flags] -``` - -### Options - -``` - --public Should be port be available publicly via an URL -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_git-providers.md b/docs/daytona_git-providers.md deleted file mode 100644 index 702fdac3a3..0000000000 --- a/docs/daytona_git-providers.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona git-providers - -Manage Git providers - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona git-providers add](daytona_git-providers_add.md) - Register a Git provider -* [daytona git-providers delete](daytona_git-providers_delete.md) - Unregister a Git provider -* [daytona git-providers list](daytona_git-providers_list.md) - Lists your registered Git providers -* [daytona git-providers update](daytona_git-providers_update.md) - Update a Git provider - diff --git a/docs/daytona_git-providers_add.md b/docs/daytona_git-providers_add.md deleted file mode 100644 index 88deff5d95..0000000000 --- a/docs/daytona_git-providers_add.md +++ /dev/null @@ -1,29 +0,0 @@ -## daytona git-providers add - -Register a Git provider - -``` -daytona git-providers add [GIT_PROVIDER_ID] [flags] -``` - -### Options - -``` - -a, --alias string Alias - -b, --base-api-url string Base API Url - -k, --signing-key string Signing Key - -s, --signing-method string Signing Method (ssh, gpg) - -t, --token string Personal Access Token - -u, --username string Username -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_git-providers_delete.md b/docs/daytona_git-providers_delete.md deleted file mode 100644 index ab7a22aa23..0000000000 --- a/docs/daytona_git-providers_delete.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona git-providers delete - -Unregister a Git provider - -``` -daytona git-providers delete [flags] -``` - -### Options - -``` - -a, --all Remove all Git providers - -y, --yes Confirm deletion without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_git-providers_list.md b/docs/daytona_git-providers_list.md deleted file mode 100644 index a99673badb..0000000000 --- a/docs/daytona_git-providers_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona git-providers list - -Lists your registered Git providers - -``` -daytona git-providers list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_git-providers_update.md b/docs/daytona_git-providers_update.md deleted file mode 100644 index 164f00de24..0000000000 --- a/docs/daytona_git-providers_update.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona git-providers update - -Update a Git provider - -``` -daytona git-providers update [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_ide.md b/docs/daytona_ide.md deleted file mode 100644 index 3674d95883..0000000000 --- a/docs/daytona_ide.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona ide - -Choose the default IDE - -``` -daytona ide [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_info.md b/docs/daytona_info.md deleted file mode 100644 index 8ae541bb98..0000000000 --- a/docs/daytona_info.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona info - -Show target info - -``` -daytona info [TARGET] [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_list.md b/docs/daytona_list.md deleted file mode 100644 index 9bf836328a..0000000000 --- a/docs/daytona_list.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona list - -List targets - -``` -daytona list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) - -v, --verbose Show verbose output -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_logs.md b/docs/daytona_logs.md deleted file mode 100644 index 219a5a2701..0000000000 --- a/docs/daytona_logs.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona logs - -View logs for a target/project - -``` -daytona logs [TARGET] [PROJECT_NAME] [flags] -``` - -### Options - -``` - -f, --follow Follow logs - -w, --target View target logs -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_prebuild.md b/docs/daytona_prebuild.md deleted file mode 100644 index 8fbe49c684..0000000000 --- a/docs/daytona_prebuild.md +++ /dev/null @@ -1,19 +0,0 @@ -## daytona prebuild - -Manage prebuilds - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona prebuild add](daytona_prebuild_add.md) - Add a prebuild configuration -* [daytona prebuild delete](daytona_prebuild_delete.md) - Delete a prebuild configuration -* [daytona prebuild info](daytona_prebuild_info.md) - Show prebuild configuration info -* [daytona prebuild list](daytona_prebuild_list.md) - List prebuild configurations -* [daytona prebuild update](daytona_prebuild_update.md) - Update a prebuild configuration - diff --git a/docs/daytona_prebuild_add.md b/docs/daytona_prebuild_add.md deleted file mode 100644 index bfdcb38aa5..0000000000 --- a/docs/daytona_prebuild_add.md +++ /dev/null @@ -1,28 +0,0 @@ -## daytona prebuild add - -Add a prebuild configuration - -``` -daytona prebuild add [PROJECT_CONFIG] [flags] -``` - -### Options - -``` - -b, --branch string Git branch for the prebuild - -c, --commit-interval int Commit interval for running a prebuild - leave blank to ignore push events - -r, --retention int Maximum number of resulting builds stored at a time - --run Run the prebuild once after adding it - -t, --trigger-files strings Full paths of files whose changes should explicitly trigger a prebuild -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds - diff --git a/docs/daytona_prebuild_delete.md b/docs/daytona_prebuild_delete.md deleted file mode 100644 index 3b887b4158..0000000000 --- a/docs/daytona_prebuild_delete.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona prebuild delete - -Delete a prebuild configuration - -``` -daytona prebuild delete [PROJECT_CONFIG] [PREBUILD] [flags] -``` - -### Options - -``` - -f, --force Force delete prebuild -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds - diff --git a/docs/daytona_prebuild_info.md b/docs/daytona_prebuild_info.md deleted file mode 100644 index 70eea63dd1..0000000000 --- a/docs/daytona_prebuild_info.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona prebuild info - -Show prebuild configuration info - -``` -daytona prebuild info [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds - diff --git a/docs/daytona_prebuild_list.md b/docs/daytona_prebuild_list.md deleted file mode 100644 index a00151506a..0000000000 --- a/docs/daytona_prebuild_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona prebuild list - -List prebuild configurations - -``` -daytona prebuild list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds - diff --git a/docs/daytona_prebuild_update.md b/docs/daytona_prebuild_update.md deleted file mode 100644 index ae85a83a36..0000000000 --- a/docs/daytona_prebuild_update.md +++ /dev/null @@ -1,28 +0,0 @@ -## daytona prebuild update - -Update a prebuild configuration - -``` -daytona prebuild update [PROJECT_CONFIG] [PREBUILD_ID] [flags] -``` - -### Options - -``` - -b, --branch string Git branch for the prebuild - -c, --commit-interval int Commit interval for running a prebuild - leave blank to ignore push events - -r, --retention int Maximum number of resulting builds stored at a time - --run Run the prebuild once after updating it - -t, --trigger-files strings Full paths of files whose changes should explicitly trigger a prebuild -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds - diff --git a/docs/daytona_profile.md b/docs/daytona_profile.md deleted file mode 100644 index 2226adeae0..0000000000 --- a/docs/daytona_profile.md +++ /dev/null @@ -1,19 +0,0 @@ -## daytona profile - -Manage profiles - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona profile add](daytona_profile_add.md) - Add profile -* [daytona profile delete](daytona_profile_delete.md) - Delete profile [PROFILE_NAME] -* [daytona profile edit](daytona_profile_edit.md) - Edit profile [PROFILE_NAME] -* [daytona profile list](daytona_profile_list.md) - List profiles -* [daytona profile use](daytona_profile_use.md) - Use profile [PROFILE_NAME] - diff --git a/docs/daytona_profile_add.md b/docs/daytona_profile_add.md deleted file mode 100644 index 12ea0fa96d..0000000000 --- a/docs/daytona_profile_add.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona profile add - -Add profile - -``` -daytona profile add [flags] -``` - -### Options - -``` - -k, --api-key string API Key - -a, --api-url string API URL - -n, --name string Profile name -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona profile](daytona_profile.md) - Manage profiles - diff --git a/docs/daytona_profile_delete.md b/docs/daytona_profile_delete.md deleted file mode 100644 index d8ed86d359..0000000000 --- a/docs/daytona_profile_delete.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona profile delete - -Delete profile [PROFILE_NAME] - -``` -daytona profile delete [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona profile](daytona_profile.md) - Manage profiles - diff --git a/docs/daytona_profile_edit.md b/docs/daytona_profile_edit.md deleted file mode 100644 index 79be7454f4..0000000000 --- a/docs/daytona_profile_edit.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona profile edit - -Edit profile [PROFILE_NAME] - -``` -daytona profile edit [flags] -``` - -### Options - -``` - -k, --api-key string API Key - -a, --api-url string API URL - -n, --name string Profile name -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona profile](daytona_profile.md) - Manage profiles - diff --git a/docs/daytona_profile_list.md b/docs/daytona_profile_list.md deleted file mode 100644 index 348bec7028..0000000000 --- a/docs/daytona_profile_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona profile list - -List profiles - -``` -daytona profile list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona profile](daytona_profile.md) - Manage profiles - diff --git a/docs/daytona_project-config.md b/docs/daytona_project-config.md deleted file mode 100644 index 59f335322b..0000000000 --- a/docs/daytona_project-config.md +++ /dev/null @@ -1,22 +0,0 @@ -## daytona project-config - -Manage project configs - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona project-config add](daytona_project-config_add.md) - Add a project config -* [daytona project-config delete](daytona_project-config_delete.md) - Delete a project config -* [daytona project-config export](daytona_project-config_export.md) - Export a project config -* [daytona project-config import](daytona_project-config_import.md) - Import project config from JSON -* [daytona project-config info](daytona_project-config_info.md) - Show project config info -* [daytona project-config list](daytona_project-config_list.md) - Lists project configs -* [daytona project-config set-default](daytona_project-config_set-default.md) - Set project config info -* [daytona project-config update](daytona_project-config_update.md) - Update a project config - diff --git a/docs/daytona_project-config_add.md b/docs/daytona_project-config_add.md deleted file mode 100644 index 3204ef80ce..0000000000 --- a/docs/daytona_project-config_add.md +++ /dev/null @@ -1,31 +0,0 @@ -## daytona project-config add - -Add a project config - -``` -daytona project-config add [flags] -``` - -### Options - -``` - --builder BuildChoice Specify the builder (currently auto/devcontainer/none) - --custom-image string Create the project with the custom image passed as the flag value; Requires setting --custom-image-user flag as well - --custom-image-user string Create the project with the custom image user passed as the flag value; Requires setting --custom-image flag as well - --devcontainer-path string Automatically assign the devcontainer builder with the path passed as the flag value - --env stringArray Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') - --git-provider-config string Specify the Git provider configuration ID or alias - --manual Manually enter the Git repository - --name string Specify the project config name -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_project-config_delete.md b/docs/daytona_project-config_delete.md deleted file mode 100644 index e235a32c80..0000000000 --- a/docs/daytona_project-config_delete.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona project-config delete - -Delete a project config - -``` -daytona project-config delete [flags] -``` - -### Options - -``` - -a, --all Delete all project configs - -f, --force Force delete prebuild - -y, --yes Confirm deletion without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_project-config_info.md b/docs/daytona_project-config_info.md deleted file mode 100644 index 4fca73851f..0000000000 --- a/docs/daytona_project-config_info.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona project-config info - -Show project config info - -``` -daytona project-config info [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_project-config_list.md b/docs/daytona_project-config_list.md deleted file mode 100644 index 10078c2302..0000000000 --- a/docs/daytona_project-config_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona project-config list - -Lists project configs - -``` -daytona project-config list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_project-config_set-default.md b/docs/daytona_project-config_set-default.md deleted file mode 100644 index a2561d03d0..0000000000 --- a/docs/daytona_project-config_set-default.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona project-config set-default - -Set project config info - -``` -daytona project-config set-default [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_project-config_update.md b/docs/daytona_project-config_update.md deleted file mode 100644 index c78a16cb1c..0000000000 --- a/docs/daytona_project-config_update.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona project-config update - -Update a project config - -``` -daytona project-config update [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_provider.md b/docs/daytona_provider.md deleted file mode 100644 index b509313b07..0000000000 --- a/docs/daytona_provider.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona provider - -Manage providers - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona provider install](daytona_provider_install.md) - Install provider -* [daytona provider list](daytona_provider_list.md) - List installed providers -* [daytona provider uninstall](daytona_provider_uninstall.md) - Uninstall provider -* [daytona provider update](daytona_provider_update.md) - Update provider - diff --git a/docs/daytona_provider_install.md b/docs/daytona_provider_install.md deleted file mode 100644 index 71c36d175d..0000000000 --- a/docs/daytona_provider_install.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona provider install - -Install provider - -``` -daytona provider install [flags] -``` - -### Options - -``` - -y, --yes Automatically confirm any prompts -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona provider](daytona_provider.md) - Manage providers - diff --git a/docs/daytona_provider_list.md b/docs/daytona_provider_list.md deleted file mode 100644 index d78d0f4f65..0000000000 --- a/docs/daytona_provider_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona provider list - -List installed providers - -``` -daytona provider list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona provider](daytona_provider.md) - Manage providers - diff --git a/docs/daytona_provider_uninstall.md b/docs/daytona_provider_uninstall.md deleted file mode 100644 index 04fdf4e149..0000000000 --- a/docs/daytona_provider_uninstall.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona provider uninstall - -Uninstall provider - -``` -daytona provider uninstall [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona provider](daytona_provider.md) - Manage providers - diff --git a/docs/daytona_provider_update.md b/docs/daytona_provider_update.md deleted file mode 100644 index 9e41020273..0000000000 --- a/docs/daytona_provider_update.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona provider update - -Update provider - -``` -daytona provider update [flags] -``` - -### Options - -``` - -a, --all Update all providers -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona provider](daytona_provider.md) - Manage providers - diff --git a/docs/daytona_purge.md b/docs/daytona_purge.md deleted file mode 100644 index b34cf5c858..0000000000 --- a/docs/daytona_purge.md +++ /dev/null @@ -1,29 +0,0 @@ -## daytona purge - -Purges all Daytona data from the current device - -### Synopsis - -Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. - -``` -daytona purge [flags] -``` - -### Options - -``` - -f, --force Delete all targets by force - -y, --yes Execute purge without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_restart.md b/docs/daytona_restart.md deleted file mode 100644 index b42a1d574e..0000000000 --- a/docs/daytona_restart.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona restart - -Restart a target - -``` -daytona restart [TARGET] [flags] -``` - -### Options - -``` - -p, --project string Restart a single project in the target (project name) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_serve.md b/docs/daytona_serve.md deleted file mode 100644 index f19d30acae..0000000000 --- a/docs/daytona_serve.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona serve - -Run the server process in the current terminal session - -``` -daytona serve [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_server.md b/docs/daytona_server.md deleted file mode 100644 index bffb71a5e9..0000000000 --- a/docs/daytona_server.md +++ /dev/null @@ -1,30 +0,0 @@ -## daytona server - -Start the server process in daemon mode - -``` -daytona server [flags] -``` - -### Options - -``` - -y, --yes Skip the confirmation prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona server config](daytona_server_config.md) - Output local Daytona Server config -* [daytona server configure](daytona_server_configure.md) - Configure Daytona Server -* [daytona server logs](daytona_server_logs.md) - Output Daytona Server logs -* [daytona server restart](daytona_server_restart.md) - Restarts the Daytona Server daemon -* [daytona server start](daytona_server_start.md) - Start the Daytona Server daemon -* [daytona server stop](daytona_server_stop.md) - Stops the Daytona Server daemon - diff --git a/docs/daytona_server_config.md b/docs/daytona_server_config.md deleted file mode 100644 index ff2eb80a78..0000000000 --- a/docs/daytona_server_config.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona server config - -Output local Daytona Server config - -``` -daytona server config [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server](daytona_server.md) - Start the server process in daemon mode - diff --git a/docs/daytona_server_configure.md b/docs/daytona_server_configure.md deleted file mode 100644 index 4c9bbbcde4..0000000000 --- a/docs/daytona_server_configure.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona server configure - -Configure Daytona Server - -``` -daytona server configure [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server](daytona_server.md) - Start the server process in daemon mode - diff --git a/docs/daytona_server_logs.md b/docs/daytona_server_logs.md deleted file mode 100644 index 94447c34f5..0000000000 --- a/docs/daytona_server_logs.md +++ /dev/null @@ -1,27 +0,0 @@ -## daytona server logs - -Output Daytona Server logs - -``` -daytona server logs [flags] -``` - -### Options - -``` - --file string Read specific log file - -f, --follow Follow logs - -l, --local Read local server log files -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server](daytona_server.md) - Start the server process in daemon mode -* [daytona server logs list](daytona_server_logs_list.md) - Lists Daytona Server Log Files - diff --git a/docs/daytona_server_logs_list.md b/docs/daytona_server_logs_list.md deleted file mode 100644 index 377d96d9f6..0000000000 --- a/docs/daytona_server_logs_list.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona server logs list - -Lists Daytona Server Log Files - -``` -daytona server logs list [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server logs](daytona_server_logs.md) - Output Daytona Server logs - diff --git a/docs/daytona_server_restart.md b/docs/daytona_server_restart.md deleted file mode 100644 index 1857fb1402..0000000000 --- a/docs/daytona_server_restart.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona server restart - -Restarts the Daytona Server daemon - -``` -daytona server restart [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server](daytona_server.md) - Start the server process in daemon mode - diff --git a/docs/daytona_server_start.md b/docs/daytona_server_start.md deleted file mode 100644 index 95bb3859f9..0000000000 --- a/docs/daytona_server_start.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona server start - -Start the Daytona Server daemon - -``` -daytona server start [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server](daytona_server.md) - Start the server process in daemon mode - diff --git a/docs/daytona_server_stop.md b/docs/daytona_server_stop.md deleted file mode 100644 index 1852546025..0000000000 --- a/docs/daytona_server_stop.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona server stop - -Stops the Daytona Server daemon - -``` -daytona server stop [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona server](daytona_server.md) - Start the server process in daemon mode - diff --git a/docs/daytona_ssh.md b/docs/daytona_ssh.md deleted file mode 100644 index c455b5e7d5..0000000000 --- a/docs/daytona_ssh.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona ssh - -SSH into a project using the terminal - -``` -daytona ssh [TARGET] [PROJECT] [CMD...] [flags] -``` - -### Options - -``` - -e, --edit Edit the project's SSH config - -o, --option stringArray Specify SSH options in KEY=VALUE format. - -y, --yes Automatically confirm any prompts -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_start.md b/docs/daytona_start.md deleted file mode 100644 index 7667c9abaf..0000000000 --- a/docs/daytona_start.md +++ /dev/null @@ -1,27 +0,0 @@ -## daytona start - -Start a target - -``` -daytona start [TARGET] [flags] -``` - -### Options - -``` - -a, --all Start all targets - -c, --code Open the target in the IDE after target start - -p, --project string Start a single project in the target (project name) - -y, --yes Automatically confirm any prompts -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_stop.md b/docs/daytona_stop.md deleted file mode 100644 index 387bdb4653..0000000000 --- a/docs/daytona_stop.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona stop - -Stop a target - -``` -daytona stop [TARGET] [flags] -``` - -### Options - -``` - -a, --all Stop all targets - -p, --project string Stop a single project in the target (project name) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_target-config.md b/docs/daytona_target-config.md deleted file mode 100644 index 3effd3ca45..0000000000 --- a/docs/daytona_target-config.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona target-config - -Manage target configs - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona target-config list](daytona_target-config_list.md) - List target configs -* [daytona target-config remove](daytona_target-config_remove.md) - Remove target config -* [daytona target-config set](daytona_target-config_set.md) - Set target config -* [daytona target-config set-default](daytona_target-config_set-default.md) - Set default target config - diff --git a/docs/daytona_target-config_list.md b/docs/daytona_target-config_list.md deleted file mode 100644 index b14c9641fd..0000000000 --- a/docs/daytona_target-config_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona target-config list - -List target configs - -``` -daytona target-config list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target-config](daytona_target-config.md) - Manage target configs - diff --git a/docs/daytona_target-config_remove.md b/docs/daytona_target-config_remove.md deleted file mode 100644 index aebe62cfb7..0000000000 --- a/docs/daytona_target-config_remove.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona target-config remove - -Remove target config - -``` -daytona target-config remove [CONFIG_NAME] [flags] -``` - -### Options - -``` - -y, --yes Confirm deletion of all targets without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target-config](daytona_target-config.md) - Manage target configs - diff --git a/docs/daytona_target-config_set-default.md b/docs/daytona_target-config_set-default.md deleted file mode 100644 index 60aa9b6f7c..0000000000 --- a/docs/daytona_target-config_set-default.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona target-config set-default - -Set default target config - -``` -daytona target-config set-default [CONFIG_NAME] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target-config](daytona_target-config.md) - Manage target configs - diff --git a/docs/daytona_target-config_set.md b/docs/daytona_target-config_set.md deleted file mode 100644 index fb453a3699..0000000000 --- a/docs/daytona_target-config_set.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona target-config set - -Set target config - -``` -daytona target-config set [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target-config](daytona_target-config.md) - Manage target configs - diff --git a/docs/daytona_telemetry.md b/docs/daytona_telemetry.md deleted file mode 100644 index 68d4c9726a..0000000000 --- a/docs/daytona_telemetry.md +++ /dev/null @@ -1,16 +0,0 @@ -## daytona telemetry - -Manage telemetry collection - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona telemetry disable](daytona_telemetry_disable.md) - Disable telemetry collection -* [daytona telemetry enable](daytona_telemetry_enable.md) - Enable telemetry collection - diff --git a/docs/daytona_telemetry_disable.md b/docs/daytona_telemetry_disable.md deleted file mode 100644 index f062a90208..0000000000 --- a/docs/daytona_telemetry_disable.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona telemetry disable - -Disable telemetry collection - -``` -daytona telemetry disable [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection - diff --git a/docs/daytona_telemetry_enable.md b/docs/daytona_telemetry_enable.md deleted file mode 100644 index 2e8c71acd6..0000000000 --- a/docs/daytona_telemetry_enable.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona telemetry enable - -Enable telemetry collection - -``` -daytona telemetry enable [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection - diff --git a/docs/daytona_use.md b/docs/daytona_use.md deleted file mode 100644 index b1921191ca..0000000000 --- a/docs/daytona_use.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona use - -Use profile [PROFILE_NAME] - -``` -daytona use [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_version.md b/docs/daytona_version.md deleted file mode 100644 index 2f0f9fb6a6..0000000000 --- a/docs/daytona_version.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona version - -Print the version number - -``` -daytona version [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/daytona_whoami.md b/docs/daytona_whoami.md deleted file mode 100644 index b7c5683b89..0000000000 --- a/docs/daytona_whoami.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona whoami - -Display information about the active user - -``` -daytona whoami [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/hack/builder_image/.devcontainer/devcontainer.json b/hack/builder_image/.devcontainer/devcontainer.json index 97d388e526..257d94f52a 100644 --- a/hack/builder_image/.devcontainer/devcontainer.json +++ b/hack/builder_image/.devcontainer/devcontainer.json @@ -1,5 +1,5 @@ { - "name": "Daytona Project Image Builder", + "name": "Daytona Workspace Image Builder", "image": "ubuntu:22.04", "features": { "ghcr.io/devcontainers/features/common-utils:1": { diff --git a/hack/docs/agent_mode/daytona.yaml b/hack/docs/agent_mode/daytona.yaml deleted file mode 100644 index a1d9e10e33..0000000000 --- a/hack/docs/agent_mode/daytona.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: daytona -synopsis: Daytona is a Dev Environment Manager -description: Daytona is a Dev Environment Manager -usage: daytona [flags] -options: - - name: help - default_value: "false" - usage: help for daytona - - name: version - shorthand: v - default_value: "false" - usage: Display the version of Daytona -see_also: - - daytona agent - Start the agent process - - daytona autocomplete - Adds a completion script for your shell environment - - daytona docs - Opens the Daytona documentation in your default browser. - - daytona expose - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project - - daytona forward - Forward a port publicly via an URL - - daytona info - Show project info - - daytona list - List targets - - daytona logs - View logs for a target/project - - daytona restart - Restart the project - - daytona start - Start the project - - daytona stop - Stop the project - - daytona version - Print the version number diff --git a/hack/docs/agent_mode/daytona_agent.yaml b/hack/docs/agent_mode/daytona_agent.yaml deleted file mode 100644 index 5034cc17be..0000000000 --- a/hack/docs/agent_mode/daytona_agent.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona agent -synopsis: Start the agent process -usage: daytona agent [flags] -options: - - name: host - default_value: "false" - usage: Run the agent in host mode -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona agent logs - Output Daytona Agent logs diff --git a/hack/docs/agent_mode/daytona_agent_logs.yaml b/hack/docs/agent_mode/daytona_agent_logs.yaml deleted file mode 100644 index 7ff3b8e0a3..0000000000 --- a/hack/docs/agent_mode/daytona_agent_logs.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona agent logs -synopsis: Output Daytona Agent logs -usage: daytona agent logs [flags] -options: - - name: follow - shorthand: f - default_value: "false" - usage: Follow logs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona agent - Start the agent process diff --git a/hack/docs/agent_mode/daytona_autocomplete.yaml b/hack/docs/agent_mode/daytona_autocomplete.yaml deleted file mode 100644 index 3d7cd97846..0000000000 --- a/hack/docs/agent_mode/daytona_autocomplete.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona autocomplete -synopsis: Adds a completion script for your shell environment -usage: daytona autocomplete [bash|zsh|fish|powershell] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_docs.yaml b/hack/docs/agent_mode/daytona_docs.yaml deleted file mode 100644 index 2eb2502768..0000000000 --- a/hack/docs/agent_mode/daytona_docs.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona docs -synopsis: Opens the Daytona documentation in your default browser. -usage: daytona docs [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_expose.yaml b/hack/docs/agent_mode/daytona_expose.yaml deleted file mode 100644 index dafc5ce601..0000000000 --- a/hack/docs/agent_mode/daytona_expose.yaml +++ /dev/null @@ -1,10 +0,0 @@ -name: daytona expose -synopsis: | - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project -usage: daytona expose [PORT] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_forward.yaml b/hack/docs/agent_mode/daytona_forward.yaml deleted file mode 100644 index a6b70eea12..0000000000 --- a/hack/docs/agent_mode/daytona_forward.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona forward -synopsis: Forward a port publicly via an URL -usage: daytona forward [PORT] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_info.yaml b/hack/docs/agent_mode/daytona_info.yaml deleted file mode 100644 index 401c578dbc..0000000000 --- a/hack/docs/agent_mode/daytona_info.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona info -synopsis: Show project info -usage: daytona info [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_list.yaml b/hack/docs/agent_mode/daytona_list.yaml deleted file mode 100644 index 08be0d7c58..0000000000 --- a/hack/docs/agent_mode/daytona_list.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: daytona list -synopsis: List targets -usage: daytona list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) - - name: verbose - shorthand: v - default_value: "false" - usage: Show verbose output -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_logs.yaml b/hack/docs/agent_mode/daytona_logs.yaml deleted file mode 100644 index d045665711..0000000000 --- a/hack/docs/agent_mode/daytona_logs.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: daytona logs -synopsis: View logs for a target/project -usage: daytona logs [TARGET] [PROJECT_NAME] [flags] -options: - - name: follow - shorthand: f - default_value: "false" - usage: Follow logs - - name: target - shorthand: w - default_value: "false" - usage: View target logs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_restart.yaml b/hack/docs/agent_mode/daytona_restart.yaml deleted file mode 100644 index 0acef2905d..0000000000 --- a/hack/docs/agent_mode/daytona_restart.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona restart -synopsis: Restart the project -usage: daytona restart [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_start.yaml b/hack/docs/agent_mode/daytona_start.yaml deleted file mode 100644 index 4dbd1585ca..0000000000 --- a/hack/docs/agent_mode/daytona_start.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona start -synopsis: Start the project -usage: daytona start [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_stop.yaml b/hack/docs/agent_mode/daytona_stop.yaml deleted file mode 100644 index bdcaa8361e..0000000000 --- a/hack/docs/agent_mode/daytona_stop.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona stop -synopsis: Stop the project -usage: daytona stop [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_version.yaml b/hack/docs/agent_mode/daytona_version.yaml deleted file mode 100644 index 02035a7170..0000000000 --- a/hack/docs/agent_mode/daytona_version.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona version -synopsis: Print the version number -usage: daytona version [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml deleted file mode 100644 index 7d100277f0..0000000000 --- a/hack/docs/daytona.yaml +++ /dev/null @@ -1,46 +0,0 @@ -name: daytona -synopsis: Daytona is a Dev Environment Manager -description: Daytona is a Dev Environment Manager -usage: daytona [flags] -options: - - name: help - default_value: "false" - usage: help for daytona - - name: version - shorthand: v - default_value: "false" - usage: Display the version of Daytona -see_also: - - daytona api-key - Api Key commands - - daytona autocomplete - Adds a completion script for your shell environment - - daytona build - Manage builds - - daytona code - Open a target in your preferred IDE - - daytona config - Output Daytona configuration - - daytona container-registry - Manage container registries - - daytona create - Create a target - - daytona delete - Delete a target - - daytona docs - Opens the Daytona documentation in your default browser. - - daytona env - Manage profile environment variables that are added to all targets and projects - - daytona forward - Forward a port from a project to your local machine - - daytona git-providers - Manage Git providers - - daytona ide - Choose the default IDE - - daytona info - Show target info - - daytona list - List targets - - daytona logs - View logs for a target/project - - daytona prebuild - Manage prebuilds - - daytona profile - Manage profiles - - daytona project-config - Manage project configs - - daytona provider - Manage providers - - daytona purge - Purges all Daytona data from the current device - - daytona restart - Restart a target - - daytona serve - Run the server process in the current terminal session - - daytona server - Start the server process in daemon mode - - daytona ssh - SSH into a project using the terminal - - daytona start - Start a target - - daytona stop - Stop a target - - daytona target-config - Manage target configs - - daytona telemetry - Manage telemetry collection - - daytona update - Update Daytona CLI - - daytona use - Use profile [PROFILE_NAME] - - daytona version - Print the version number - - daytona whoami - Display information about the active user diff --git a/hack/docs/daytona_api-key.yaml b/hack/docs/daytona_api-key.yaml deleted file mode 100644 index a886de682c..0000000000 --- a/hack/docs/daytona_api-key.yaml +++ /dev/null @@ -1,11 +0,0 @@ -name: daytona api-key -synopsis: Api Key commands -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona api-key generate - Generate a new API key - - daytona api-key list - List API keys - - daytona api-key revoke - Revoke an API key diff --git a/hack/docs/daytona_api-key_generate.yaml b/hack/docs/daytona_api-key_generate.yaml deleted file mode 100644 index 988087f62b..0000000000 --- a/hack/docs/daytona_api-key_generate.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona api-key generate -synopsis: Generate a new API key -usage: daytona api-key generate [NAME] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona api-key - Api Key commands diff --git a/hack/docs/daytona_api-key_list.yaml b/hack/docs/daytona_api-key_list.yaml deleted file mode 100644 index d46b49b95d..0000000000 --- a/hack/docs/daytona_api-key_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona api-key list -synopsis: List API keys -usage: daytona api-key list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona api-key - Api Key commands diff --git a/hack/docs/daytona_api-key_revoke.yaml b/hack/docs/daytona_api-key_revoke.yaml deleted file mode 100644 index 2009ac9ee1..0000000000 --- a/hack/docs/daytona_api-key_revoke.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona api-key revoke -synopsis: Revoke an API key -usage: daytona api-key revoke [NAME] [flags] -options: - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Skip confirmation prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona api-key - Api Key commands diff --git a/hack/docs/daytona_autocomplete.yaml b/hack/docs/daytona_autocomplete.yaml deleted file mode 100644 index 3d7cd97846..0000000000 --- a/hack/docs/daytona_autocomplete.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona autocomplete -synopsis: Adds a completion script for your shell environment -usage: daytona autocomplete [bash|zsh|fish|powershell] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_build.yaml b/hack/docs/daytona_build.yaml deleted file mode 100644 index 555d40057f..0000000000 --- a/hack/docs/daytona_build.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona build -synopsis: Manage builds -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona build delete - Delete a build - - daytona build info - Show build info - - daytona build list - List all builds - - daytona build logs - View logs for build - - daytona build run - Run a build from a project config diff --git a/hack/docs/daytona_build_delete.yaml b/hack/docs/daytona_build_delete.yaml deleted file mode 100644 index 36b845e633..0000000000 --- a/hack/docs/daytona_build_delete.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: daytona build delete -synopsis: Delete a build -usage: daytona build delete [BUILD] [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Delete ALL builds - - name: force - shorthand: f - default_value: "false" - usage: Force delete build - - name: prebuild-id - usage: Delete ALL builds from prebuild -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona build - Manage builds diff --git a/hack/docs/daytona_build_info.yaml b/hack/docs/daytona_build_info.yaml deleted file mode 100644 index 1deaf0f3b9..0000000000 --- a/hack/docs/daytona_build_info.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona build info -synopsis: Show build info -usage: daytona build info [BUILD] [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona build - Manage builds diff --git a/hack/docs/daytona_build_list.yaml b/hack/docs/daytona_build_list.yaml deleted file mode 100644 index 35c86da275..0000000000 --- a/hack/docs/daytona_build_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona build list -synopsis: List all builds -usage: daytona build list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona build - Manage builds diff --git a/hack/docs/daytona_build_logs.yaml b/hack/docs/daytona_build_logs.yaml deleted file mode 100644 index 653c6e435c..0000000000 --- a/hack/docs/daytona_build_logs.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona build logs -synopsis: View logs for build -usage: daytona build logs [flags] -options: - - name: follow - shorthand: f - default_value: "false" - usage: Follow logs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona build - Manage builds diff --git a/hack/docs/daytona_build_run.yaml b/hack/docs/daytona_build_run.yaml deleted file mode 100644 index a0d2f7a6b0..0000000000 --- a/hack/docs/daytona_build_run.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona build run -synopsis: Run a build from a project config -usage: daytona build run [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona build - Manage builds diff --git a/hack/docs/daytona_code.yaml b/hack/docs/daytona_code.yaml deleted file mode 100644 index 264fc64e7d..0000000000 --- a/hack/docs/daytona_code.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: daytona code -synopsis: Open a target in your preferred IDE -usage: daytona code [TARGET] [PROJECT] [flags] -options: - - name: ide - shorthand: i - usage: | - Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Automatically confirm any prompts -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_config.yaml b/hack/docs/daytona_config.yaml deleted file mode 100644 index 9bf7563015..0000000000 --- a/hack/docs/daytona_config.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: daytona config -synopsis: Output Daytona configuration -usage: daytona config [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) - - name: show-api-keys - shorthand: k - default_value: "false" - usage: Show API keys -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_container-registry.yaml b/hack/docs/daytona_container-registry.yaml deleted file mode 100644 index 8157d18d0d..0000000000 --- a/hack/docs/daytona_container-registry.yaml +++ /dev/null @@ -1,11 +0,0 @@ -name: daytona container-registry -synopsis: Manage container registries -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona container-registry delete - Delete a container registry - - daytona container-registry list - Lists container registries - - daytona container-registry set - Set container registry diff --git a/hack/docs/daytona_container-registry_delete.yaml b/hack/docs/daytona_container-registry_delete.yaml deleted file mode 100644 index 8200c586fd..0000000000 --- a/hack/docs/daytona_container-registry_delete.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona container-registry delete -synopsis: Delete a container registry -usage: daytona container-registry delete [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_container-registry_list.yaml b/hack/docs/daytona_container-registry_list.yaml deleted file mode 100644 index be84cb144c..0000000000 --- a/hack/docs/daytona_container-registry_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona container-registry list -synopsis: Lists container registries -usage: daytona container-registry list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_container-registry_set.yaml b/hack/docs/daytona_container-registry_set.yaml deleted file mode 100644 index b4ca3426b9..0000000000 --- a/hack/docs/daytona_container-registry_set.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: daytona container-registry set -synopsis: Set container registry -usage: daytona container-registry set [flags] -options: - - name: password - shorthand: p - usage: Password - - name: server - shorthand: s - usage: Server - - name: username - shorthand: u - usage: Username -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_create.yaml b/hack/docs/daytona_create.yaml deleted file mode 100644 index 8e48bddded..0000000000 --- a/hack/docs/daytona_create.yaml +++ /dev/null @@ -1,56 +0,0 @@ -name: daytona create -synopsis: Create a target -usage: daytona create [REPOSITORY_URL | PROJECT_CONFIG_NAME]... [flags] -options: - - name: blank - default_value: "false" - usage: Create a blank project without using existing configurations - - name: branch - default_value: '[]' - usage: Specify the Git branches to use in the projects - - name: builder - usage: Specify the builder (currently auto/devcontainer/none) - - name: custom-image - usage: | - Create the project with the custom image passed as the flag value; Requires setting --custom-image-user flag as well - - name: custom-image-user - usage: | - Create the project with the custom image user passed as the flag value; Requires setting --custom-image flag as well - - name: devcontainer-path - usage: | - Automatically assign the devcontainer builder with the path passed as the flag value - - name: env - default_value: '[]' - usage: | - Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') - - name: git-provider-config - usage: Specify the Git provider configuration ID or alias - - name: ide - shorthand: i - usage: | - Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) - - name: manual - default_value: "false" - usage: Manually enter the Git repository - - name: multi-project - default_value: "false" - usage: Target with multiple projects/repos - - name: name - usage: Specify the target name - - name: no-ide - shorthand: "n" - default_value: "false" - usage: Do not open the target in the IDE after target creation - - name: target - shorthand: t - usage: Specify the target (e.g. 'local') - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Automatically confirm any prompts -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_delete.yaml b/hack/docs/daytona_delete.yaml deleted file mode 100644 index 2b800708da..0000000000 --- a/hack/docs/daytona_delete.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: daytona delete -synopsis: Delete a target -usage: daytona delete [TARGET] [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Delete all targets - - name: force - shorthand: f - default_value: "false" - usage: Delete a target by force - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Confirm deletion without prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_docs.yaml b/hack/docs/daytona_docs.yaml deleted file mode 100644 index 2eb2502768..0000000000 --- a/hack/docs/daytona_docs.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona docs -synopsis: Opens the Daytona documentation in your default browser. -usage: daytona docs [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_env.yaml b/hack/docs/daytona_env.yaml deleted file mode 100644 index bffc8dabb3..0000000000 --- a/hack/docs/daytona_env.yaml +++ /dev/null @@ -1,11 +0,0 @@ -name: daytona env -synopsis: | - Manage profile environment variables that are added to all targets and projects -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona env list - List profile environment variables - - daytona env set - Set profile environment variables diff --git a/hack/docs/daytona_env_list.yaml b/hack/docs/daytona_env_list.yaml deleted file mode 100644 index d74f46a61a..0000000000 --- a/hack/docs/daytona_env_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona env list -synopsis: List profile environment variables -usage: daytona env list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona env - Manage profile environment variables that are added to all targets and projects diff --git a/hack/docs/daytona_env_set.yaml b/hack/docs/daytona_env_set.yaml deleted file mode 100644 index e082b96d6d..0000000000 --- a/hack/docs/daytona_env_set.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona env set -synopsis: Set profile environment variables -usage: daytona env set [KEY=VALUE]... [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona env - Manage profile environment variables that are added to all targets and projects diff --git a/hack/docs/daytona_forward.yaml b/hack/docs/daytona_forward.yaml deleted file mode 100644 index 7b95869f20..0000000000 --- a/hack/docs/daytona_forward.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona forward -synopsis: Forward a port from a project to your local machine -usage: daytona forward [PORT] [TARGET] [PROJECT] [flags] -options: - - name: public - default_value: "false" - usage: Should be port be available publicly via an URL -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_git-providers.yaml b/hack/docs/daytona_git-providers.yaml deleted file mode 100644 index 0d80b38486..0000000000 --- a/hack/docs/daytona_git-providers.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: daytona git-providers -synopsis: Manage Git providers -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona git-providers add - Register a Git provider - - daytona git-providers delete - Unregister a Git provider - - daytona git-providers list - Lists your registered Git providers - - daytona git-providers update - Update a Git provider diff --git a/hack/docs/daytona_git-providers_add.yaml b/hack/docs/daytona_git-providers_add.yaml deleted file mode 100644 index 30b5b7f50c..0000000000 --- a/hack/docs/daytona_git-providers_add.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: daytona git-providers add -synopsis: Register a Git provider -usage: daytona git-providers add [GIT_PROVIDER_ID] [flags] -options: - - name: alias - shorthand: a - usage: Alias - - name: base-api-url - shorthand: b - usage: Base API Url - - name: signing-key - shorthand: k - usage: Signing Key - - name: signing-method - shorthand: s - usage: Signing Method (ssh, gpg) - - name: token - shorthand: t - usage: Personal Access Token - - name: username - shorthand: u - usage: Username -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_git-providers_delete.yaml b/hack/docs/daytona_git-providers_delete.yaml deleted file mode 100644 index 95d0109933..0000000000 --- a/hack/docs/daytona_git-providers_delete.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: daytona git-providers delete -synopsis: Unregister a Git provider -usage: daytona git-providers delete [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Remove all Git providers - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Confirm deletion without prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_git-providers_list.yaml b/hack/docs/daytona_git-providers_list.yaml deleted file mode 100644 index 002423af47..0000000000 --- a/hack/docs/daytona_git-providers_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona git-providers list -synopsis: Lists your registered Git providers -usage: daytona git-providers list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_git-providers_update.yaml b/hack/docs/daytona_git-providers_update.yaml deleted file mode 100644 index 3782e8afda..0000000000 --- a/hack/docs/daytona_git-providers_update.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona git-providers update -synopsis: Update a Git provider -usage: daytona git-providers update [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_ide.yaml b/hack/docs/daytona_ide.yaml deleted file mode 100644 index 6ee01c616d..0000000000 --- a/hack/docs/daytona_ide.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona ide -synopsis: Choose the default IDE -usage: daytona ide [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_info.yaml b/hack/docs/daytona_info.yaml deleted file mode 100644 index 6c96f1013e..0000000000 --- a/hack/docs/daytona_info.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona info -synopsis: Show target info -usage: daytona info [TARGET] [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_list.yaml b/hack/docs/daytona_list.yaml deleted file mode 100644 index 08be0d7c58..0000000000 --- a/hack/docs/daytona_list.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: daytona list -synopsis: List targets -usage: daytona list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) - - name: verbose - shorthand: v - default_value: "false" - usage: Show verbose output -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_logs.yaml b/hack/docs/daytona_logs.yaml deleted file mode 100644 index d045665711..0000000000 --- a/hack/docs/daytona_logs.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: daytona logs -synopsis: View logs for a target/project -usage: daytona logs [TARGET] [PROJECT_NAME] [flags] -options: - - name: follow - shorthand: f - default_value: "false" - usage: Follow logs - - name: target - shorthand: w - default_value: "false" - usage: View target logs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_prebuild.yaml b/hack/docs/daytona_prebuild.yaml deleted file mode 100644 index d667986aa0..0000000000 --- a/hack/docs/daytona_prebuild.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona prebuild -synopsis: Manage prebuilds -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona prebuild add - Add a prebuild configuration - - daytona prebuild delete - Delete a prebuild configuration - - daytona prebuild info - Show prebuild configuration info - - daytona prebuild list - List prebuild configurations - - daytona prebuild update - Update a prebuild configuration diff --git a/hack/docs/daytona_prebuild_add.yaml b/hack/docs/daytona_prebuild_add.yaml deleted file mode 100644 index c448c05dd4..0000000000 --- a/hack/docs/daytona_prebuild_add.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: daytona prebuild add -synopsis: Add a prebuild configuration -usage: daytona prebuild add [PROJECT_CONFIG] [flags] -options: - - name: branch - shorthand: b - usage: Git branch for the prebuild - - name: commit-interval - shorthand: c - default_value: "0" - usage: | - Commit interval for running a prebuild - leave blank to ignore push events - - name: retention - shorthand: r - default_value: "0" - usage: Maximum number of resulting builds stored at a time - - name: run - default_value: "false" - usage: Run the prebuild once after adding it - - name: trigger-files - shorthand: t - default_value: '[]' - usage: | - Full paths of files whose changes should explicitly trigger a prebuild -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_delete.yaml b/hack/docs/daytona_prebuild_delete.yaml deleted file mode 100644 index 0deb02f7cb..0000000000 --- a/hack/docs/daytona_prebuild_delete.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona prebuild delete -synopsis: Delete a prebuild configuration -usage: daytona prebuild delete [PROJECT_CONFIG] [PREBUILD] [flags] -options: - - name: force - shorthand: f - default_value: "false" - usage: Force delete prebuild -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_info.yaml b/hack/docs/daytona_prebuild_info.yaml deleted file mode 100644 index 82a7246c6e..0000000000 --- a/hack/docs/daytona_prebuild_info.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona prebuild info -synopsis: Show prebuild configuration info -usage: daytona prebuild info [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_list.yaml b/hack/docs/daytona_prebuild_list.yaml deleted file mode 100644 index d70deff793..0000000000 --- a/hack/docs/daytona_prebuild_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona prebuild list -synopsis: List prebuild configurations -usage: daytona prebuild list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_update.yaml b/hack/docs/daytona_prebuild_update.yaml deleted file mode 100644 index 4454b4b2f5..0000000000 --- a/hack/docs/daytona_prebuild_update.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: daytona prebuild update -synopsis: Update a prebuild configuration -usage: daytona prebuild update [PROJECT_CONFIG] [PREBUILD_ID] [flags] -options: - - name: branch - shorthand: b - usage: Git branch for the prebuild - - name: commit-interval - shorthand: c - default_value: "0" - usage: | - Commit interval for running a prebuild - leave blank to ignore push events - - name: retention - shorthand: r - default_value: "0" - usage: Maximum number of resulting builds stored at a time - - name: run - default_value: "false" - usage: Run the prebuild once after updating it - - name: trigger-files - shorthand: t - default_value: '[]' - usage: | - Full paths of files whose changes should explicitly trigger a prebuild -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_profile.yaml b/hack/docs/daytona_profile.yaml deleted file mode 100644 index a9cc38d245..0000000000 --- a/hack/docs/daytona_profile.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona profile -synopsis: Manage profiles -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona profile add - Add profile - - daytona profile delete - Delete profile [PROFILE_NAME] - - daytona profile edit - Edit profile [PROFILE_NAME] - - daytona profile list - List profiles - - daytona use - Use profile [PROFILE_NAME] diff --git a/hack/docs/daytona_profile_add.yaml b/hack/docs/daytona_profile_add.yaml deleted file mode 100644 index c2c08730a2..0000000000 --- a/hack/docs/daytona_profile_add.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: daytona profile add -synopsis: Add profile -usage: daytona profile add [flags] -options: - - name: api-key - shorthand: k - usage: API Key - - name: api-url - shorthand: a - usage: API URL - - name: name - shorthand: "n" - usage: Profile name -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona profile - Manage profiles diff --git a/hack/docs/daytona_profile_delete.yaml b/hack/docs/daytona_profile_delete.yaml deleted file mode 100644 index 95628ac7c8..0000000000 --- a/hack/docs/daytona_profile_delete.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona profile delete -synopsis: Delete profile [PROFILE_NAME] -usage: daytona profile delete [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona profile - Manage profiles diff --git a/hack/docs/daytona_profile_edit.yaml b/hack/docs/daytona_profile_edit.yaml deleted file mode 100644 index a2c71353d6..0000000000 --- a/hack/docs/daytona_profile_edit.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: daytona profile edit -synopsis: Edit profile [PROFILE_NAME] -usage: daytona profile edit [flags] -options: - - name: api-key - shorthand: k - usage: API Key - - name: api-url - shorthand: a - usage: API URL - - name: name - shorthand: "n" - usage: Profile name -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona profile - Manage profiles diff --git a/hack/docs/daytona_profile_list.yaml b/hack/docs/daytona_profile_list.yaml deleted file mode 100644 index e483577021..0000000000 --- a/hack/docs/daytona_profile_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona profile list -synopsis: List profiles -usage: daytona profile list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona profile - Manage profiles diff --git a/hack/docs/daytona_project-config.yaml b/hack/docs/daytona_project-config.yaml deleted file mode 100644 index bd3a0c9c0f..0000000000 --- a/hack/docs/daytona_project-config.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: daytona project-config -synopsis: Manage project configs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona project-config add - Add a project config - - daytona project-config delete - Delete a project config - - daytona project-config export - Export a project config - - daytona project-config import - Import project config from JSON - - daytona project-config info - Show project config info - - daytona project-config list - Lists project configs - - daytona project-config set-default - Set project config info - - daytona project-config update - Update a project config diff --git a/hack/docs/daytona_project-config_add.yaml b/hack/docs/daytona_project-config_add.yaml deleted file mode 100644 index 3e4316f049..0000000000 --- a/hack/docs/daytona_project-config_add.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: daytona project-config add -synopsis: Add a project config -usage: daytona project-config add [flags] -options: - - name: builder - usage: Specify the builder (currently auto/devcontainer/none) - - name: custom-image - usage: | - Create the project with the custom image passed as the flag value; Requires setting --custom-image-user flag as well - - name: custom-image-user - usage: | - Create the project with the custom image user passed as the flag value; Requires setting --custom-image flag as well - - name: devcontainer-path - usage: | - Automatically assign the devcontainer builder with the path passed as the flag value - - name: env - default_value: '[]' - usage: | - Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') - - name: git-provider-config - usage: Specify the Git provider configuration ID or alias - - name: manual - default_value: "false" - usage: Manually enter the Git repository - - name: name - usage: Specify the project config name -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_project-config_delete.yaml b/hack/docs/daytona_project-config_delete.yaml deleted file mode 100644 index d8399e8b2b..0000000000 --- a/hack/docs/daytona_project-config_delete.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: daytona project-config delete -synopsis: Delete a project config -usage: daytona project-config delete [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Delete all project configs - - name: force - shorthand: f - default_value: "false" - usage: Force delete prebuild - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Confirm deletion without prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_project-config_info.yaml b/hack/docs/daytona_project-config_info.yaml deleted file mode 100644 index c06cbd1981..0000000000 --- a/hack/docs/daytona_project-config_info.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona project-config info -synopsis: Show project config info -usage: daytona project-config info [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_project-config_list.yaml b/hack/docs/daytona_project-config_list.yaml deleted file mode 100644 index 7deac6e153..0000000000 --- a/hack/docs/daytona_project-config_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona project-config list -synopsis: Lists project configs -usage: daytona project-config list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_project-config_set-default.yaml b/hack/docs/daytona_project-config_set-default.yaml deleted file mode 100644 index bbbf42c4c6..0000000000 --- a/hack/docs/daytona_project-config_set-default.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona project-config set-default -synopsis: Set project config info -usage: daytona project-config set-default [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_project-config_update.yaml b/hack/docs/daytona_project-config_update.yaml deleted file mode 100644 index 2de5a2aa47..0000000000 --- a/hack/docs/daytona_project-config_update.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona project-config update -synopsis: Update a project config -usage: daytona project-config update [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_provider.yaml b/hack/docs/daytona_provider.yaml deleted file mode 100644 index 168c2228ed..0000000000 --- a/hack/docs/daytona_provider.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: daytona provider -synopsis: Manage providers -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona provider install - Install provider - - daytona provider list - List installed providers - - daytona provider uninstall - Uninstall provider - - daytona provider update - Update provider diff --git a/hack/docs/daytona_provider_install.yaml b/hack/docs/daytona_provider_install.yaml deleted file mode 100644 index 29886e0613..0000000000 --- a/hack/docs/daytona_provider_install.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona provider install -synopsis: Install provider -usage: daytona provider install [flags] -options: - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Automatically confirm any prompts -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona provider - Manage providers diff --git a/hack/docs/daytona_provider_list.yaml b/hack/docs/daytona_provider_list.yaml deleted file mode 100644 index 9ffae1cfce..0000000000 --- a/hack/docs/daytona_provider_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona provider list -synopsis: List installed providers -usage: daytona provider list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona provider - Manage providers diff --git a/hack/docs/daytona_provider_uninstall.yaml b/hack/docs/daytona_provider_uninstall.yaml deleted file mode 100644 index eb84417597..0000000000 --- a/hack/docs/daytona_provider_uninstall.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona provider uninstall -synopsis: Uninstall provider -usage: daytona provider uninstall [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona provider - Manage providers diff --git a/hack/docs/daytona_provider_update.yaml b/hack/docs/daytona_provider_update.yaml deleted file mode 100644 index cf042fcfb9..0000000000 --- a/hack/docs/daytona_provider_update.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona provider update -synopsis: Update provider -usage: daytona provider update [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Update all providers -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona provider - Manage providers diff --git a/hack/docs/daytona_purge.yaml b/hack/docs/daytona_purge.yaml deleted file mode 100644 index 7d28219871..0000000000 --- a/hack/docs/daytona_purge.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: daytona purge -synopsis: Purges all Daytona data from the current device -description: | - Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. -usage: daytona purge [flags] -options: - - name: force - shorthand: f - default_value: "false" - usage: Delete all targets by force - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Execute purge without prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_restart.yaml b/hack/docs/daytona_restart.yaml deleted file mode 100644 index ba3d9d6253..0000000000 --- a/hack/docs/daytona_restart.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona restart -synopsis: Restart a target -usage: daytona restart [TARGET] [flags] -options: - - name: project - shorthand: p - usage: Restart a single project in the target (project name) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_serve.yaml b/hack/docs/daytona_serve.yaml deleted file mode 100644 index ed180bb7a8..0000000000 --- a/hack/docs/daytona_serve.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona serve -synopsis: Run the server process in the current terminal session -usage: daytona serve [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_server.yaml b/hack/docs/daytona_server.yaml deleted file mode 100644 index 6f19f3150f..0000000000 --- a/hack/docs/daytona_server.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: daytona server -synopsis: Start the server process in daemon mode -usage: daytona server [flags] -options: - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Skip the confirmation prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona server config - Output local Daytona Server config - - daytona server configure - Configure Daytona Server - - daytona server logs - Output Daytona Server logs - - daytona server restart - Restarts the Daytona Server daemon - - daytona server start - Start the Daytona Server daemon - - daytona server stop - Stops the Daytona Server daemon diff --git a/hack/docs/daytona_server_config.yaml b/hack/docs/daytona_server_config.yaml deleted file mode 100644 index 1fb4da88d6..0000000000 --- a/hack/docs/daytona_server_config.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona server config -synopsis: Output local Daytona Server config -usage: daytona server config [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_configure.yaml b/hack/docs/daytona_server_configure.yaml deleted file mode 100644 index 877dc2399c..0000000000 --- a/hack/docs/daytona_server_configure.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona server configure -synopsis: Configure Daytona Server -usage: daytona server configure [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_logs.yaml b/hack/docs/daytona_server_logs.yaml deleted file mode 100644 index eee2c53036..0000000000 --- a/hack/docs/daytona_server_logs.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: daytona server logs -synopsis: Output Daytona Server logs -usage: daytona server logs [flags] -options: - - name: file - usage: Read specific log file - - name: follow - shorthand: f - default_value: "false" - usage: Follow logs - - name: local - shorthand: l - default_value: "false" - usage: Read local server log files -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server - Start the server process in daemon mode - - daytona server logs list - Lists Daytona Server Log Files diff --git a/hack/docs/daytona_server_logs_list.yaml b/hack/docs/daytona_server_logs_list.yaml deleted file mode 100644 index cc9ff0349c..0000000000 --- a/hack/docs/daytona_server_logs_list.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona server logs list -synopsis: Lists Daytona Server Log Files -usage: daytona server logs list [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server logs - Output Daytona Server logs diff --git a/hack/docs/daytona_server_restart.yaml b/hack/docs/daytona_server_restart.yaml deleted file mode 100644 index 1b6ab08abe..0000000000 --- a/hack/docs/daytona_server_restart.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona server restart -synopsis: Restarts the Daytona Server daemon -usage: daytona server restart [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_start.yaml b/hack/docs/daytona_server_start.yaml deleted file mode 100644 index 16b6a1410e..0000000000 --- a/hack/docs/daytona_server_start.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona server start -synopsis: Start the Daytona Server daemon -usage: daytona server start [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_stop.yaml b/hack/docs/daytona_server_stop.yaml deleted file mode 100644 index 1d1b0005fd..0000000000 --- a/hack/docs/daytona_server_stop.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona server stop -synopsis: Stops the Daytona Server daemon -usage: daytona server stop [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_ssh.yaml b/hack/docs/daytona_ssh.yaml deleted file mode 100644 index 242b06d421..0000000000 --- a/hack/docs/daytona_ssh.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: daytona ssh -synopsis: SSH into a project using the terminal -usage: daytona ssh [TARGET] [PROJECT] [CMD...] [flags] -options: - - name: edit - shorthand: e - default_value: "false" - usage: Edit the project's SSH config - - name: option - shorthand: o - default_value: '[]' - usage: Specify SSH options in KEY=VALUE format. - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Automatically confirm any prompts -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_start.yaml b/hack/docs/daytona_start.yaml deleted file mode 100644 index b51ca5e180..0000000000 --- a/hack/docs/daytona_start.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: daytona start -synopsis: Start a target -usage: daytona start [TARGET] [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Start all targets - - name: code - shorthand: c - default_value: "false" - usage: Open the target in the IDE after target start - - name: project - shorthand: p - usage: Start a single project in the target (project name) - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Automatically confirm any prompts -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_stop.yaml b/hack/docs/daytona_stop.yaml deleted file mode 100644 index 7235fb8771..0000000000 --- a/hack/docs/daytona_stop.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: daytona stop -synopsis: Stop a target -usage: daytona stop [TARGET] [flags] -options: - - name: all - shorthand: a - default_value: "false" - usage: Stop all targets - - name: project - shorthand: p - usage: Stop a single project in the target (project name) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_target-config.yaml b/hack/docs/daytona_target-config.yaml deleted file mode 100644 index 60577252ee..0000000000 --- a/hack/docs/daytona_target-config.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: daytona target-config -synopsis: Manage target configs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona target-config list - List target configs - - daytona target-config remove - Remove target config - - daytona target-config set - Set target config - - daytona target-config set-default - Set default target config diff --git a/hack/docs/daytona_target-config_list.yaml b/hack/docs/daytona_target-config_list.yaml deleted file mode 100644 index a96c7f7908..0000000000 --- a/hack/docs/daytona_target-config_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona target-config list -synopsis: List target configs -usage: daytona target-config list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_remove.yaml b/hack/docs/daytona_target-config_remove.yaml deleted file mode 100644 index 8ee216a64d..0000000000 --- a/hack/docs/daytona_target-config_remove.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona target-config remove -synopsis: Remove target config -usage: daytona target-config remove [CONFIG_NAME] [flags] -options: - - name: "yes" - shorthand: "y" - default_value: "false" - usage: Confirm deletion of all targets without prompt -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_set-default.yaml b/hack/docs/daytona_target-config_set-default.yaml deleted file mode 100644 index dc6fe9e01e..0000000000 --- a/hack/docs/daytona_target-config_set-default.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona target-config set-default -synopsis: Set default target config -usage: daytona target-config set-default [CONFIG_NAME] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_set.yaml b/hack/docs/daytona_target-config_set.yaml deleted file mode 100644 index 21c4fa5447..0000000000 --- a/hack/docs/daytona_target-config_set.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona target-config set -synopsis: Set target config -usage: daytona target-config set [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_telemetry.yaml b/hack/docs/daytona_telemetry.yaml deleted file mode 100644 index 996ac41725..0000000000 --- a/hack/docs/daytona_telemetry.yaml +++ /dev/null @@ -1,10 +0,0 @@ -name: daytona telemetry -synopsis: Manage telemetry collection -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona telemetry disable - Disable telemetry collection - - daytona telemetry enable - Enable telemetry collection diff --git a/hack/docs/daytona_telemetry_disable.yaml b/hack/docs/daytona_telemetry_disable.yaml deleted file mode 100644 index 38039dca01..0000000000 --- a/hack/docs/daytona_telemetry_disable.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona telemetry disable -synopsis: Disable telemetry collection -usage: daytona telemetry disable [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona telemetry - Manage telemetry collection diff --git a/hack/docs/daytona_telemetry_enable.yaml b/hack/docs/daytona_telemetry_enable.yaml deleted file mode 100644 index a32bc5050e..0000000000 --- a/hack/docs/daytona_telemetry_enable.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona telemetry enable -synopsis: Enable telemetry collection -usage: daytona telemetry enable [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona telemetry - Manage telemetry collection diff --git a/hack/docs/daytona_use.yaml b/hack/docs/daytona_use.yaml deleted file mode 100644 index 171159b88a..0000000000 --- a/hack/docs/daytona_use.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona use -synopsis: Use profile [PROFILE_NAME] -usage: daytona use [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_version.yaml b/hack/docs/daytona_version.yaml deleted file mode 100644 index 02035a7170..0000000000 --- a/hack/docs/daytona_version.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona version -synopsis: Print the version number -usage: daytona version [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_whoami.yaml b/hack/docs/daytona_whoami.yaml deleted file mode 100644 index ff8fd58784..0000000000 --- a/hack/docs/daytona_whoami.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona whoami -synopsis: Display information about the active user -usage: daytona whoami [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/project_image/.devcontainer/devcontainer.json b/hack/workspace_image/.devcontainer/devcontainer.json similarity index 100% rename from hack/project_image/.devcontainer/devcontainer.json rename to hack/workspace_image/.devcontainer/devcontainer.json diff --git a/hack/project_image/Dockerfile b/hack/workspace_image/Dockerfile similarity index 100% rename from hack/project_image/Dockerfile rename to hack/workspace_image/Dockerfile diff --git a/hack/project_image/docker/postinstall.sh b/hack/workspace_image/docker/postinstall.sh similarity index 100% rename from hack/project_image/docker/postinstall.sh rename to hack/workspace_image/docker/postinstall.sh diff --git a/internal/cmd/tailscale/forward.go b/internal/cmd/tailscale/forward.go index 4562966db4..9918374333 100644 --- a/internal/cmd/tailscale/forward.go +++ b/internal/cmd/tailscale/forward.go @@ -11,11 +11,11 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "tailscale.com/tsnet" ) -func ForwardPort(targetId, projectName string, targetPort uint16, profile config.Profile) (*uint16, chan error) { +func ForwardPort(targetId, workspaceName string, targetPort uint16, profile config.Profile) (*uint16, chan error) { hostPort := targetPort errChan := make(chan error) var err error @@ -47,7 +47,7 @@ func ForwardPort(targetId, projectName string, targetPort uint16, profile config return } - targetUrl := fmt.Sprintf("%s:%d", project.GetProjectHostname(targetId, projectName), targetPort) + targetUrl := fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(targetId, workspaceName), targetPort) go handlePortConnection(conn, tsConn, targetUrl, errChan) } diff --git a/internal/testing/docker/mocks/client.go b/internal/testing/docker/mocks/client.go index 69c34bc4fe..86a6241fde 100644 --- a/internal/testing/docker/mocks/client.go +++ b/internal/testing/docker/mocks/client.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/mock" ) @@ -25,8 +25,8 @@ func NewMockClient() *MockClient { return &MockClient{} } -func (c *MockClient) CreateProject(p *project.Project, serverDownloadUrl string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error { - args := c.Called(p, serverDownloadUrl, cr, logWriter) +func (c *MockClient) CreateWorkspace(w *workspace.Workspace, serverDownloadUrl string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error { + args := c.Called(w, serverDownloadUrl, cr, logWriter) return args.Error(0) } @@ -35,8 +35,8 @@ func (c *MockClient) CreateTarget(target *target.Target, logWriter io.Writer) er return args.Error(0) } -func (c *MockClient) DestroyProject(p *project.Project) error { - args := c.Called(p) +func (c *MockClient) DestroyWorkspace(w *workspace.Workspace) error { + args := c.Called(w) return args.Error(0) } @@ -45,28 +45,28 @@ func (c *MockClient) DestroyTarget(target *target.Target) error { return args.Error(0) } -func (c *MockClient) StartProject(p *project.Project) error { - args := c.Called(p) +func (c *MockClient) StartWorkspace(w *workspace.Workspace) error { + args := c.Called(w) return args.Error(0) } -func (c *MockClient) StopProject(p *project.Project) error { - args := c.Called(p) +func (c *MockClient) StopWorkspace(w *workspace.Workspace) error { + args := c.Called(w) return args.Error(0) } -func (c *MockClient) GetProjectInfo(p *project.Project) (*project.ProjectInfo, error) { - args := c.Called(p) - return args.Get(0).(*project.ProjectInfo), args.Error(1) +func (c *MockClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.WorkspaceInfo, error) { + args := c.Called(w) + return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) } -func (c *MockClient) GetTargetInfo(ws *target.Target) (*target.TargetInfo, error) { - args := c.Called(ws) +func (c *MockClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, error) { + args := c.Called(t) return args.Get(0).(*target.TargetInfo), args.Error(1) } -func (c *MockClient) GetProjectContainerName(p *project.Project) string { - args := c.Called(p) +func (c *MockClient) GetWorkspaceContainerName(w *workspace.Workspace) string { + args := c.Called(w) return args.String(0) } diff --git a/internal/testing/git/mocks/gitservice.go b/internal/testing/git/mocks/gitservice.go index 02d67e19b9..74cba6abc6 100644 --- a/internal/testing/git/mocks/gitservice.go +++ b/internal/testing/git/mocks/gitservice.go @@ -7,7 +7,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/mock" ) @@ -36,9 +36,9 @@ func (m *MockGitService) SetGitConfig(userData *gitprovider.GitUser, providerCon return args.Error(0) } -func (m *MockGitService) GetGitStatus() (*project.GitStatus, error) { +func (m *MockGitService) GetGitStatus() (*workspace.GitStatus, error) { args := m.Called() - return args.Get(0).(*project.GitStatus), args.Error(1) + return args.Get(0).(*workspace.GitStatus), args.Error(1) } func NewMockGitService() *MockGitService { diff --git a/internal/testing/logger/mocks/logger.go b/internal/testing/logger/mocks/logger.go index ab65d90929..a61ba56ff3 100644 --- a/internal/testing/logger/mocks/logger.go +++ b/internal/testing/logger/mocks/logger.go @@ -24,11 +24,11 @@ func (f *MockLoggerFactory) CreateTargetLogger(targetId string, source logs.LogS return &mockLogger{} } -func (f *MockLoggerFactory) CreateProjectLogger(targetId, projectName string, source logs.LogSource) logs.Logger { +func (f *MockLoggerFactory) CreateWorkspaceLogger(targetId, workspaceName string, source logs.LogSource) logs.Logger { return &mockLogger{} } -func (f *MockLoggerFactory) CreateBuildLogger(projectName, hash string, source logs.LogSource) logs.Logger { +func (f *MockLoggerFactory) CreateBuildLogger(workspaceName, hash string, source logs.LogSource) logs.Logger { return &mockLogger{} } @@ -36,11 +36,11 @@ func (f *MockLoggerFactory) CreateTargetLogReader(targetId string) (io.Reader, e return nil, nil } -func (f *MockLoggerFactory) CreateProjectLogReader(targetId, projectName string) (io.Reader, error) { +func (f *MockLoggerFactory) CreateWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) { return nil, nil } -func (f *MockLoggerFactory) CreateBuildLogReader(projectName, hash string) (io.Reader, error) { +func (f *MockLoggerFactory) CreateBuildLogReader(workspaceName, hash string) (io.Reader, error) { return nil, nil } diff --git a/internal/testing/server/projectconfig/store.go b/internal/testing/server/projectconfig/store.go deleted file mode 100644 index ec7d983648..0000000000 --- a/internal/testing/server/projectconfig/store.go +++ /dev/null @@ -1,94 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig - -import ( - "fmt" - - "github.com/daytonaio/daytona/pkg/target/project/config" -) - -type InMemoryProjectConfigStore struct { - projectConfigs map[string]*config.ProjectConfig -} - -func NewInMemoryProjectConfigStore() config.Store { - return &InMemoryProjectConfigStore{ - projectConfigs: make(map[string]*config.ProjectConfig), - } -} - -func (s *InMemoryProjectConfigStore) List(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) { - return s.processFilters(filter) -} - -func (s *InMemoryProjectConfigStore) Find(filter *config.ProjectConfigFilter) (*config.ProjectConfig, error) { - projectConfigs, err := s.processFilters(filter) - if err != nil { - return nil, err - } - if len(projectConfigs) == 0 { - return nil, config.ErrProjectConfigNotFound - } - - return projectConfigs[0], nil -} - -func (s *InMemoryProjectConfigStore) Save(projectConfig *config.ProjectConfig) error { - s.projectConfigs[projectConfig.Name] = projectConfig - return nil -} - -func (s *InMemoryProjectConfigStore) Delete(projectConfig *config.ProjectConfig) error { - delete(s.projectConfigs, projectConfig.Name) - return nil -} - -func (s *InMemoryProjectConfigStore) processFilters(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) { - var result []*config.ProjectConfig - filteredProjectConfigs := make(map[string]*config.ProjectConfig) - for k, v := range s.projectConfigs { - filteredProjectConfigs[k] = v - } - - if filter != nil { - if filter.Name != nil { - projectConfig, ok := s.projectConfigs[*filter.Name] - if ok { - return []*config.ProjectConfig{projectConfig}, nil - } else { - return []*config.ProjectConfig{}, fmt.Errorf("project config with name %s not found", *filter.Name) - } - } - if filter.Url != nil { - for _, projectConfig := range filteredProjectConfigs { - if projectConfig.RepositoryUrl != *filter.Url { - delete(filteredProjectConfigs, projectConfig.Name) - } - } - } - if filter.Default != nil { - for _, projectConfig := range filteredProjectConfigs { - if projectConfig.IsDefault != *filter.Default { - delete(filteredProjectConfigs, projectConfig.Name) - } - } - } - if filter.GitProviderConfigId != nil { - for _, projectConfig := range filteredProjectConfigs { - if projectConfig.GitProviderConfigId != nil && *projectConfig.GitProviderConfigId != *filter.GitProviderConfigId { - delete(filteredProjectConfigs, projectConfig.Name) - } - } - } - } - - for _, projectConfig := range filteredProjectConfigs { - result = append(result, projectConfig) - } - - return result, nil -} diff --git a/internal/testing/server/targets/mocks/api_key_service.go b/internal/testing/server/targets/mocks/api_key_service.go index 779d44d9e5..340d53d02e 100644 --- a/internal/testing/server/targets/mocks/api_key_service.go +++ b/internal/testing/server/targets/mocks/api_key_service.go @@ -23,7 +23,7 @@ func (s *mockApiKeyService) Generate(keyType apikey.ApiKeyType, name string) (st return args.String(0), args.Error(1) } -func (s *mockApiKeyService) IsProjectApiKey(apiKey string) bool { +func (s *mockApiKeyService) IsWorkspaceApiKey(apiKey string) bool { args := s.Called(apiKey) return args.Bool(0) } diff --git a/internal/testing/server/targets/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go index 39648faeb6..130d2028d4 100644 --- a/internal/testing/server/targets/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" - "github.com/daytonaio/daytona/pkg/target/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" "github.com/stretchr/testify/mock" ) @@ -24,10 +24,10 @@ var MockBuild = &build.Build{ User: "test", }, BuildConfig: &buildconfig.BuildConfig{ - Devcontainer: MockProjectConfig.BuildConfig.Devcontainer, + Devcontainer: MockWorkspaceConfig.BuildConfig.Devcontainer, }, Repository: &gitprovider.GitRepository{ - Url: MockProjectConfig.RepositoryUrl, + Url: MockWorkspaceConfig.RepositoryUrl, }, EnvVars: map[string]string{}, } @@ -36,8 +36,8 @@ type MockBuilderFactory struct { mock.Mock } -func (f *MockBuilderFactory) Create(build build.Build, projectDir string) (build.IBuilder, error) { - args := f.Called(build, projectDir) +func (f *MockBuilderFactory) Create(build build.Build, workspaceDir string) (build.IBuilder, error) { + args := f.Called(build, workspaceDir) return args.Get(0).(*MockBuilder), args.Error(1) } diff --git a/internal/testing/server/targets/mocks/project_config_service.go b/internal/testing/server/targets/mocks/project_config_service.go deleted file mode 100644 index 90ba2fc330..0000000000 --- a/internal/testing/server/targets/mocks/project_config_service.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package mocks - -import ( - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" - "github.com/stretchr/testify/mock" -) - -type mockProjectConfigService struct { - mock.Mock -} - -func NewMockProjectConfigService() *mockProjectConfigService { - return &mockProjectConfigService{} -} - -func (m *mockProjectConfigService) Delete(name string, force bool) []error { - args := m.Called(name, force) - return args.Get(0).([]error) -} - -func (m *mockProjectConfigService) Find(filter *config.ProjectConfigFilter) (*config.ProjectConfig, error) { - args := m.Called(filter) - return args.Get(0).(*config.ProjectConfig), args.Error(1) -} - -func (m *mockProjectConfigService) List(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) { - args := m.Called(filter) - return args.Get(0).([]*config.ProjectConfig), args.Error(1) -} - -func (m *mockProjectConfigService) SetDefault(name string) error { - args := m.Called(name) - return args.Error(0) -} - -func (m *mockProjectConfigService) Save(pc *config.ProjectConfig) error { - args := m.Called(pc) - return args.Error(0) -} - -func (m *mockProjectConfigService) SetPrebuild(projectConfigName string, createProjectDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { - args := m.Called(projectConfigName, createProjectDto) - return args.Get(0).(*dto.PrebuildDTO), args.Error(1) -} - -func (m *mockProjectConfigService) FindPrebuild(projectConfigFilter *config.ProjectConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) { - args := m.Called(projectConfigFilter, prebuildFilter) - return args.Get(0).(*dto.PrebuildDTO), args.Error(1) -} - -func (m *mockProjectConfigService) ListPrebuilds(projectConfigFilter *config.ProjectConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) { - args := m.Called(projectConfigFilter, prebuildFilter) - return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) -} - -func (m *mockProjectConfigService) DeletePrebuild(projectConfigName string, id string, force bool) []error { - args := m.Called(projectConfigName, id, force) - return args.Get(0).([]error) -} - -func (m *mockProjectConfigService) StartRetentionPoller() error { - args := m.Called() - return args.Error(0) -} - -func (m *mockProjectConfigService) EnforceRetentionPolicy() error { - args := m.Called() - return args.Error(0) -} - -func (m *mockProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { - args := m.Called(data) - return args.Error(0) -} diff --git a/internal/testing/server/targets/mocks/provisioner.go b/internal/testing/server/targets/mocks/provisioner.go index 1febda9885..cdae7d0e53 100644 --- a/internal/testing/server/targets/mocks/provisioner.go +++ b/internal/testing/server/targets/mocks/provisioner.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/stretchr/testify/mock" ) @@ -23,7 +23,7 @@ func NewMockProvisioner() *mockProvisioner { return &mockProvisioner{} } -func (p *mockProvisioner) CreateProject(params provisioner.ProjectParams) error { +func (p *mockProvisioner) CreateWorkspace(params provisioner.WorkspaceParams) error { args := p.Called(params) return args.Error(0) } @@ -33,8 +33,8 @@ func (p *mockProvisioner) CreateTarget(target *target.Target, targetConfig *prov return args.Error(0) } -func (p *mockProvisioner) DestroyProject(proj *project.Project, targetConfig *provider.TargetConfig) error { - args := p.Called(proj, targetConfig) +func (p *mockProvisioner) DestroyWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { + args := p.Called(ws, targetConfig) return args.Error(0) } @@ -48,7 +48,7 @@ func (p *mockProvisioner) GetTargetInfo(ctx context.Context, w *target.Target, t return args.Get(0).(*target.TargetInfo), args.Error(1) } -func (p *mockProvisioner) StartProject(params provisioner.ProjectParams) error { +func (p *mockProvisioner) StartWorkspace(params provisioner.WorkspaceParams) error { args := p.Called(params) return args.Error(0) } @@ -58,8 +58,8 @@ func (p *mockProvisioner) StartTarget(target *target.Target, targetConfig *provi return args.Error(0) } -func (p *mockProvisioner) StopProject(proj *project.Project, targetConfig *provider.TargetConfig) error { - args := p.Called(proj, targetConfig) +func (p *mockProvisioner) StopWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { + args := p.Called(ws, targetConfig) return args.Error(0) } diff --git a/internal/testing/server/targets/mocks/project_config.go b/internal/testing/server/targets/mocks/workspace_config.go similarity index 65% rename from internal/testing/server/targets/mocks/project_config.go rename to internal/testing/server/targets/mocks/workspace_config.go index 2c29bd2555..2a527b6712 100644 --- a/internal/testing/server/targets/mocks/project_config.go +++ b/internal/testing/server/targets/mocks/workspace_config.go @@ -6,11 +6,11 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" - "github.com/daytonaio/daytona/pkg/target/project/config" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/config" ) -var MockProjectConfig = config.ProjectConfig{ +var MockWorkspaceConfig = config.WorkspaceConfig{ BuildConfig: &buildconfig.BuildConfig{ Devcontainer: &buildconfig.DevcontainerConfig{ FilePath: ".devcontainer/devcontainer.json", diff --git a/internal/testing/server/targets/mocks/workspace_config_service.go b/internal/testing/server/targets/mocks/workspace_config_service.go new file mode 100644 index 0000000000..60767d4d9c --- /dev/null +++ b/internal/testing/server/targets/mocks/workspace_config_service.go @@ -0,0 +1,81 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package mocks + +import ( + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/stretchr/testify/mock" +) + +type mockWorkspaceConfigService struct { + mock.Mock +} + +func NewMockWorkspaceConfigService() *mockWorkspaceConfigService { + return &mockWorkspaceConfigService{} +} + +func (m *mockWorkspaceConfigService) Delete(name string, force bool) []error { + args := m.Called(name, force) + return args.Get(0).([]error) +} + +func (m *mockWorkspaceConfigService) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { + args := m.Called(filter) + return args.Get(0).(*config.WorkspaceConfig), args.Error(1) +} + +func (m *mockWorkspaceConfigService) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { + args := m.Called(filter) + return args.Get(0).([]*config.WorkspaceConfig), args.Error(1) +} + +func (m *mockWorkspaceConfigService) SetDefault(name string) error { + args := m.Called(name) + return args.Error(0) +} + +func (m *mockWorkspaceConfigService) Save(wc *config.WorkspaceConfig) error { + args := m.Called(wc) + return args.Error(0) +} + +func (m *mockWorkspaceConfigService) SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { + args := m.Called(workspaceConfigName, createPrebuildDto) + return args.Get(0).(*dto.PrebuildDTO), args.Error(1) +} + +func (m *mockWorkspaceConfigService) FindPrebuild(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) { + args := m.Called(workspaceConfigFilter, prebuildFilter) + return args.Get(0).(*dto.PrebuildDTO), args.Error(1) +} + +func (m *mockWorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) { + args := m.Called(workspaceConfigFilter, prebuildFilter) + return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) +} + +func (m *mockWorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id string, force bool) []error { + args := m.Called(workspaceConfigName, id, force) + return args.Get(0).([]error) +} + +func (m *mockWorkspaceConfigService) StartRetentionPoller() error { + args := m.Called() + return args.Error(0) +} + +func (m *mockWorkspaceConfigService) EnforceRetentionPolicy() error { + args := m.Called() + return args.Error(0) +} + +func (m *mockWorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { + args := m.Called(data) + return args.Error(0) +} diff --git a/internal/testing/server/workspaceconfig/store.go b/internal/testing/server/workspaceconfig/store.go new file mode 100644 index 0000000000..164aeda53a --- /dev/null +++ b/internal/testing/server/workspaceconfig/store.go @@ -0,0 +1,94 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig + +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/target/workspace/config" +) + +type InMemoryWorkspaceConfigStore struct { + workspaceConfigs map[string]*config.WorkspaceConfig +} + +func NewInMemoryWorkspaceConfigStore() config.Store { + return &InMemoryWorkspaceConfigStore{ + workspaceConfigs: make(map[string]*config.WorkspaceConfig), + } +} + +func (s *InMemoryWorkspaceConfigStore) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { + return s.processFilters(filter) +} + +func (s *InMemoryWorkspaceConfigStore) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { + workspaceConfigs, err := s.processFilters(filter) + if err != nil { + return nil, err + } + if len(workspaceConfigs) == 0 { + return nil, config.ErrWorkspaceConfigNotFound + } + + return workspaceConfigs[0], nil +} + +func (s *InMemoryWorkspaceConfigStore) Save(workspaceConfig *config.WorkspaceConfig) error { + s.workspaceConfigs[workspaceConfig.Name] = workspaceConfig + return nil +} + +func (s *InMemoryWorkspaceConfigStore) Delete(workspaceConfig *config.WorkspaceConfig) error { + delete(s.workspaceConfigs, workspaceConfig.Name) + return nil +} + +func (s *InMemoryWorkspaceConfigStore) processFilters(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { + var result []*config.WorkspaceConfig + filteredWorkspaceConfigs := make(map[string]*config.WorkspaceConfig) + for k, v := range s.workspaceConfigs { + filteredWorkspaceConfigs[k] = v + } + + if filter != nil { + if filter.Name != nil { + workspaceConfig, ok := s.workspaceConfigs[*filter.Name] + if ok { + return []*config.WorkspaceConfig{workspaceConfig}, nil + } else { + return []*config.WorkspaceConfig{}, fmt.Errorf("workspace config with name %s not found", *filter.Name) + } + } + if filter.Url != nil { + for _, workspaceConfig := range filteredWorkspaceConfigs { + if workspaceConfig.RepositoryUrl != *filter.Url { + delete(filteredWorkspaceConfigs, workspaceConfig.Name) + } + } + } + if filter.Default != nil { + for _, workspaceConfig := range filteredWorkspaceConfigs { + if workspaceConfig.IsDefault != *filter.Default { + delete(filteredWorkspaceConfigs, workspaceConfig.Name) + } + } + } + if filter.GitProviderConfigId != nil { + for _, workspaceConfig := range filteredWorkspaceConfigs { + if workspaceConfig.GitProviderConfigId != nil && *workspaceConfig.GitProviderConfigId != *filter.GitProviderConfigId { + delete(filteredWorkspaceConfigs, workspaceConfig.Name) + } + } + } + } + + for _, workspaceConfig := range filteredWorkspaceConfigs { + result = append(result, workspaceConfig) + } + + return result, nil +} diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index 7310a98ea3..a471475e7b 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -62,7 +62,7 @@ func GetApiClient(profile *config.Profile) (*apiclient.APIClient, error) { clientConfig.AddDefaultHeader(telemetry.SESSION_ID_HEADER, internal.SESSION_ID) clientConfig.AddDefaultHeader(telemetry.CLIENT_ID_HEADER, config.GetClientId()) if internal.AgentMode() { - clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_PROJECT_SOURCE)) + clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_WORKSPACE_SOURCE)) } else { clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_SOURCE)) } @@ -131,7 +131,7 @@ func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, error return target, nil } -func GetFirstProjectName(targetId string, projectName string, profile *config.Profile) (string, error) { +func GetFirstWorkspaceName(targetId string, workspaceName string, profile *config.Profile) (string, error) { ctx := context.Background() apiClient, err := GetApiClient(profile) @@ -144,19 +144,19 @@ func GetFirstProjectName(targetId string, projectName string, profile *config.Pr return "", HandleErrorResponse(res, err) } - if projectName == "" { - if len(targetInfo.Projects) == 0 { - return "", errors.New("no projects found in target") + if workspaceName == "" { + if len(targetInfo.Workspaces) == 0 { + return "", errors.New("no workspaces found in target") } - return targetInfo.Projects[0].Name, nil + return targetInfo.Workspaces[0].Name, nil } - for _, project := range targetInfo.Projects { - if project.Name == projectName { - return project.Name, nil + for _, workspace := range targetInfo.Workspaces { + if workspace.Name == workspaceName { + return workspace.Name, nil } } - return "", errors.New("project not found in target") + return "", errors.New("workspace not found in target") } diff --git a/internal/util/apiclient/conversion/project.go b/internal/util/apiclient/conversion/project.go deleted file mode 100644 index 916f6472d0..0000000000 --- a/internal/util/apiclient/conversion/project.go +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package conversion - -import ( - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/gitprovider" - pc_dto "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - project_dto "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target/project" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" - "github.com/daytonaio/daytona/pkg/target/project/config" -) - -func ToProject(projectDTO *apiclient.Project) *project.Project { - if projectDTO == nil { - return nil - } - - repository := &gitprovider.GitRepository{ - Id: projectDTO.Repository.Id, - Name: projectDTO.Repository.Name, - Branch: projectDTO.Repository.Branch, - Owner: projectDTO.Repository.Owner, - Path: projectDTO.Repository.Path, - Sha: projectDTO.Repository.Sha, - Source: projectDTO.Repository.Source, - Url: projectDTO.Repository.Url, - } - - var projectState *project.ProjectState - if projectDTO.State != nil { - uptime := projectDTO.State.Uptime - projectState = &project.ProjectState{ - UpdatedAt: projectDTO.State.UpdatedAt, - Uptime: uint64(uptime), - GitStatus: ToGitStatus(projectDTO.State.GitStatus), - } - } - - var projectBuild *buildconfig.BuildConfig - if projectDTO.BuildConfig != nil { - projectBuild = &buildconfig.BuildConfig{} - if projectDTO.BuildConfig.Devcontainer != nil { - projectBuild.Devcontainer = &buildconfig.DevcontainerConfig{ - FilePath: projectDTO.BuildConfig.Devcontainer.FilePath, - } - } - } - - project := &project.Project{ - Name: projectDTO.Name, - Image: projectDTO.Image, - User: projectDTO.User, - BuildConfig: projectBuild, - Repository: repository, - TargetConfig: projectDTO.TargetConfig, - TargetId: projectDTO.TargetId, - State: projectState, - GitProviderConfigId: projectDTO.GitProviderConfigId, - } - - if projectDTO.Repository.PrNumber != nil { - prNumber := uint32(*projectDTO.Repository.PrNumber) - project.Repository.PrNumber = &prNumber - } - - return project -} - -func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *project.GitStatus { - if gitStatusDTO == nil { - return nil - } - - files := []*project.FileStatus{} - for _, fileDTO := range gitStatusDTO.FileStatus { - staging := project.Status(string(fileDTO.Staging)) - worktree := project.Status(string(fileDTO.Worktree)) - file := &project.FileStatus{ - Name: fileDTO.Name, - Extra: fileDTO.Extra, - Staging: staging, - Worktree: worktree, - } - files = append(files, file) - } - - var ahead, behind int - if gitStatusDTO.Ahead != nil { - ahead = int(*gitStatusDTO.Ahead) - } - if gitStatusDTO.Behind != nil { - behind = int(*gitStatusDTO.Behind) - } - - var branchPublished bool - if gitStatusDTO.BranchPublished != nil { - branchPublished = *gitStatusDTO.BranchPublished - } - - return &project.GitStatus{ - CurrentBranch: gitStatusDTO.CurrentBranch, - Files: files, - BranchPublished: branchPublished, - Ahead: ahead, - Behind: behind, - } -} - -func ToGitStatusDTO(gitStatus *project.GitStatus) *apiclient.GitStatus { - if gitStatus == nil { - return nil - } - - fileStatusDTO := []apiclient.FileStatus{} - for _, file := range gitStatus.Files { - staging := apiclient.Status(string(file.Staging)) - worktree := apiclient.Status(string(file.Worktree)) - fileDTO := apiclient.FileStatus{ - Name: file.Name, - Extra: file.Extra, - Staging: staging, - Worktree: worktree, - } - fileStatusDTO = append(fileStatusDTO, fileDTO) - } - - var ahead, behind *int32 - if gitStatus.Ahead != 0 { - value := int32(gitStatus.Ahead) - ahead = &value - } - if gitStatus.Behind != 0 { - value := int32(gitStatus.Behind) - behind = &value - } - var branchPublished *bool - if gitStatus.BranchPublished { - value := true - branchPublished = &value - } - - return &apiclient.GitStatus{ - CurrentBranch: gitStatus.CurrentBranch, - FileStatus: fileStatusDTO, - BranchPublished: branchPublished, - Ahead: ahead, - Behind: behind, - } -} - -func ToProjectConfig(createProjectConfigDto pc_dto.CreateProjectConfigDTO) *config.ProjectConfig { - result := &config.ProjectConfig{ - Name: createProjectConfigDto.Name, - BuildConfig: createProjectConfigDto.BuildConfig, - EnvVars: createProjectConfigDto.EnvVars, - GitProviderConfigId: createProjectConfigDto.GitProviderConfigId, - } - - result.RepositoryUrl = createProjectConfigDto.RepositoryUrl - - if createProjectConfigDto.Image != nil { - result.Image = *createProjectConfigDto.Image - } - - if createProjectConfigDto.User != nil { - result.User = *createProjectConfigDto.User - } - - return result -} - -func CreateDtoToProject(createProjectDto project_dto.CreateProjectDTO) *project.Project { - p := &project.Project{ - Name: createProjectDto.Name, - BuildConfig: createProjectDto.BuildConfig, - Repository: createProjectDto.Source.Repository, - EnvVars: createProjectDto.EnvVars, - GitProviderConfigId: createProjectDto.GitProviderConfigId, - } - - if createProjectDto.Image != nil { - p.Image = *createProjectDto.Image - } - - if createProjectDto.User != nil { - p.User = *createProjectDto.User - } - - return p -} - -func CreateConfigDtoToProject(createProjectConfigDto pc_dto.CreateProjectConfigDTO) *project.Project { - return &project.Project{ - Name: createProjectConfigDto.Name, - Image: *createProjectConfigDto.Image, - User: *createProjectConfigDto.User, - BuildConfig: createProjectConfigDto.BuildConfig, - GitProviderConfigId: createProjectConfigDto.GitProviderConfigId, - Repository: &gitprovider.GitRepository{ - Url: createProjectConfigDto.RepositoryUrl, - }, - EnvVars: createProjectConfigDto.EnvVars, - } -} diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go new file mode 100644 index 0000000000..b47072f0fa --- /dev/null +++ b/internal/util/apiclient/conversion/workspace.go @@ -0,0 +1,207 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package conversion + +import ( + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/gitprovider" + workspace_dto "github.com/daytonaio/daytona/pkg/server/targets/dto" + wc_dto "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/config" +) + +func ToWorkspace(workspaceDTO *apiclient.Workspace) *workspace.Workspace { + if workspaceDTO == nil { + return nil + } + + repository := &gitprovider.GitRepository{ + Id: workspaceDTO.Repository.Id, + Name: workspaceDTO.Repository.Name, + Branch: workspaceDTO.Repository.Branch, + Owner: workspaceDTO.Repository.Owner, + Path: workspaceDTO.Repository.Path, + Sha: workspaceDTO.Repository.Sha, + Source: workspaceDTO.Repository.Source, + Url: workspaceDTO.Repository.Url, + } + + var workspaceState *workspace.WorkspaceState + if workspaceDTO.State != nil { + uptime := workspaceDTO.State.Uptime + workspaceState = &workspace.WorkspaceState{ + UpdatedAt: workspaceDTO.State.UpdatedAt, + Uptime: uint64(uptime), + GitStatus: ToGitStatus(workspaceDTO.State.GitStatus), + } + } + + var workspaceBuild *buildconfig.BuildConfig + if workspaceDTO.BuildConfig != nil { + workspaceBuild = &buildconfig.BuildConfig{} + if workspaceDTO.BuildConfig.Devcontainer != nil { + workspaceBuild.Devcontainer = &buildconfig.DevcontainerConfig{ + FilePath: workspaceDTO.BuildConfig.Devcontainer.FilePath, + } + } + } + + workspace := &workspace.Workspace{ + Name: workspaceDTO.Name, + Image: workspaceDTO.Image, + User: workspaceDTO.User, + BuildConfig: workspaceBuild, + Repository: repository, + TargetConfig: workspaceDTO.TargetConfig, + TargetId: workspaceDTO.TargetId, + State: workspaceState, + GitProviderConfigId: workspaceDTO.GitProviderConfigId, + } + + if workspaceDTO.Repository.PrNumber != nil { + prNumber := uint32(*workspaceDTO.Repository.PrNumber) + workspace.Repository.PrNumber = &prNumber + } + + return workspace +} + +func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *workspace.GitStatus { + if gitStatusDTO == nil { + return nil + } + + files := []*workspace.FileStatus{} + for _, fileDTO := range gitStatusDTO.FileStatus { + staging := workspace.Status(string(fileDTO.Staging)) + worktree := workspace.Status(string(fileDTO.Worktree)) + file := &workspace.FileStatus{ + Name: fileDTO.Name, + Extra: fileDTO.Extra, + Staging: staging, + Worktree: worktree, + } + files = append(files, file) + } + + var ahead, behind int + if gitStatusDTO.Ahead != nil { + ahead = int(*gitStatusDTO.Ahead) + } + if gitStatusDTO.Behind != nil { + behind = int(*gitStatusDTO.Behind) + } + + var branchPublished bool + if gitStatusDTO.BranchPublished != nil { + branchPublished = *gitStatusDTO.BranchPublished + } + + return &workspace.GitStatus{ + CurrentBranch: gitStatusDTO.CurrentBranch, + Files: files, + BranchPublished: branchPublished, + Ahead: ahead, + Behind: behind, + } +} + +func ToGitStatusDTO(gitStatus *workspace.GitStatus) *apiclient.GitStatus { + if gitStatus == nil { + return nil + } + + fileStatusDTO := []apiclient.FileStatus{} + for _, file := range gitStatus.Files { + staging := apiclient.Status(string(file.Staging)) + worktree := apiclient.Status(string(file.Worktree)) + fileDTO := apiclient.FileStatus{ + Name: file.Name, + Extra: file.Extra, + Staging: staging, + Worktree: worktree, + } + fileStatusDTO = append(fileStatusDTO, fileDTO) + } + + var ahead, behind *int32 + if gitStatus.Ahead != 0 { + value := int32(gitStatus.Ahead) + ahead = &value + } + if gitStatus.Behind != 0 { + value := int32(gitStatus.Behind) + behind = &value + } + var branchPublished *bool + if gitStatus.BranchPublished { + value := true + branchPublished = &value + } + + return &apiclient.GitStatus{ + CurrentBranch: gitStatus.CurrentBranch, + FileStatus: fileStatusDTO, + BranchPublished: branchPublished, + Ahead: ahead, + Behind: behind, + } +} + +func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) *config.WorkspaceConfig { + result := &config.WorkspaceConfig{ + Name: createWorkspaceConfigDto.Name, + BuildConfig: createWorkspaceConfigDto.BuildConfig, + EnvVars: createWorkspaceConfigDto.EnvVars, + GitProviderConfigId: createWorkspaceConfigDto.GitProviderConfigId, + } + + result.RepositoryUrl = createWorkspaceConfigDto.RepositoryUrl + + if createWorkspaceConfigDto.Image != nil { + result.Image = *createWorkspaceConfigDto.Image + } + + if createWorkspaceConfigDto.User != nil { + result.User = *createWorkspaceConfigDto.User + } + + return result +} + +func CreateDtoToWorkspace(createWorkspaceDto workspace_dto.CreateWorkspaceDTO) *workspace.Workspace { + w := &workspace.Workspace{ + Name: createWorkspaceDto.Name, + BuildConfig: createWorkspaceDto.BuildConfig, + Repository: createWorkspaceDto.Source.Repository, + EnvVars: createWorkspaceDto.EnvVars, + GitProviderConfigId: createWorkspaceDto.GitProviderConfigId, + } + + if createWorkspaceDto.Image != nil { + w.Image = *createWorkspaceDto.Image + } + + if createWorkspaceDto.User != nil { + w.User = *createWorkspaceDto.User + } + + return w +} + +func CreateConfigDtoToWorkspace(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) *workspace.Workspace { + return &workspace.Workspace{ + Name: createWorkspaceConfigDto.Name, + Image: *createWorkspaceConfigDto.Image, + User: *createWorkspaceConfigDto.User, + BuildConfig: createWorkspaceConfigDto.BuildConfig, + GitProviderConfigId: createWorkspaceConfigDto.GitProviderConfigId, + Repository: &gitprovider.GitRepository{ + Url: createWorkspaceConfigDto.RepositoryUrl, + }, + EnvVars: createWorkspaceConfigDto.EnvVars, + } +} diff --git a/internal/util/apiclient/websocket_log_reader.go b/internal/util/apiclient/websocket_log_reader.go index aeebf0c004..14b4ee2e8c 100644 --- a/internal/util/apiclient/websocket_log_reader.go +++ b/internal/util/apiclient/websocket_log_reader.go @@ -18,7 +18,7 @@ import ( var targetLogsStarted bool -func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId string, projectNames []string, follow, showTargetLogs bool, from *time.Time) { +func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId string, workspaceNames []string, follow, showTargetLogs bool, from *time.Time) { var wg sync.WaitGroup query := "" if follow { @@ -28,21 +28,21 @@ func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId if !showTargetLogs { targetLogsStarted = true } - logs_view.CalculateLongestPrefixLength(projectNames) + logs_view.CalculateLongestPrefixLength(workspaceNames) - for index, projectName := range projectNames { + for index, workspaceName := range workspaceNames { wg.Add(1) - go func(projectName string, from *time.Time) { + go func(workspaceName string, from *time.Time) { defer wg.Done() for { - // Make sure target logs started before showing any project logs + // Make sure target logs started before showing any workspace logs if !targetLogsStarted { time.Sleep(250 * time.Millisecond) continue } - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s/%s", targetId, projectName), &activeProfile, &query) + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s/%s", targetId, workspaceName), &activeProfile, &query) // We want to retry getting the logs if it fails if err != nil { log.Trace(HandleErrorResponse(res, err)) @@ -54,7 +54,7 @@ func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId ws.Close() break } - }(projectName, from) + }(workspaceName, from) } if showTargetLogs { @@ -88,7 +88,7 @@ func ReadBuildLogs(ctx context.Context, activeProfile config.Profile, buildId st continue } - readJSONLog(ctx, ws, logs_view.FIRST_PROJECT_INDEX, nil) + readJSONLog(ctx, ws, logs_view.FIRST_WORKSPACE_INDEX, nil) ws.Close() break } diff --git a/internal/util/path.go b/internal/util/path.go index 2df3482292..62b51be06b 100644 --- a/internal/util/path.go +++ b/internal/util/path.go @@ -11,15 +11,15 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func GetHomeDir(activeProfile config.Profile, targetId string, projectName string, gpgKey string) (string, error) { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) +func GetHomeDir(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string) (string, error) { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) if err != nil { return "", err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - homeDir, err := exec.Command("ssh", projectHostname, "echo", "$HOME").Output() + homeDir, err := exec.Command("ssh", workspaceHostname, "echo", "$HOME").Output() if err != nil { return "", err } @@ -27,27 +27,27 @@ func GetHomeDir(activeProfile config.Profile, targetId string, projectName strin return strings.TrimRight(string(homeDir), "\n"), nil } -func GetProjectDir(activeProfile config.Profile, targetId string, projectName string, gpgKey string) (string, error) { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) +func GetWorkspaceDir(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string) (string, error) { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) if err != nil { return "", err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - daytonaProjectDir, err := exec.Command("ssh", projectHostname, "echo", "$DAYTONA_PROJECT_DIR").Output() + daytonaWorkspaceDir, err := exec.Command("ssh", workspaceHostname, "echo", "$DAYTONA_WORKSPACE_DIR").Output() if err != nil { return "", err } - if strings.TrimRight(string(daytonaProjectDir), "\n") != "" { - return strings.TrimRight(string(daytonaProjectDir), "\n"), nil + if strings.TrimRight(string(daytonaWorkspaceDir), "\n") != "" { + return strings.TrimRight(string(daytonaWorkspaceDir), "\n"), nil } - homeDir, err := GetHomeDir(activeProfile, targetId, projectName, gpgKey) + homeDir, err := GetHomeDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return "", err } - return path.Join(homeDir, projectName), nil + return path.Join(homeDir, workspaceName), nil } diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 1be2c55a9b..bb89156166 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -19,7 +19,7 @@ import ( agent_config "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/go-git/go-git/v5/plumbing/transport/http" log "github.com/sirupsen/logrus" ) @@ -33,8 +33,8 @@ func (a *Agent) Start() error { a.startTime = time.Now() - if a.Config.Mode == agent_config.ModeProject { - err := a.startProjectMode() + if a.Config.Mode == agent_config.ModeWorkspace { + err := a.startWorkspaceMode() if err != nil { return err } @@ -65,20 +65,20 @@ func (a *Agent) Start() error { return <-errChan } -func (a *Agent) startProjectMode() error { +func (a *Agent) startWorkspaceMode() error { err := a.ensureDefaultProfile() if err != nil { return err } if a.Config.SkipClone == "" { - project, err := a.getProject() + workspace, err := a.getWorkspace() if err != nil { return err } // Ignoring error because we don't want to fail if the git provider is not found - gitProvider, _ := a.getGitProvider(project.Repository.Url) + gitProvider, _ := a.getGitProvider(workspace.Repository.Url) var auth *http.BasicAuth if gitProvider != nil { @@ -94,10 +94,10 @@ func (a *Agent) startProjectMode() error { if exists { log.Info("Repository already exists. Skipping clone...") } else { - if stat, err := os.Stat(a.Config.ProjectDir); err == nil { + if stat, err := os.Stat(a.Config.WorkspaceDir); err == nil { ownerUid := stat.Sys().(*syscall.Stat_t).Uid if ownerUid != uint32(os.Getuid()) { - chownCmd := exec.Command("sudo", "chown", "-R", fmt.Sprintf("%s:%s", project.User, project.User), a.Config.ProjectDir) + chownCmd := exec.Command("sudo", "chown", "-R", fmt.Sprintf("%s:%s", workspace.User, workspace.User), a.Config.WorkspaceDir) err = chownCmd.Run() if err != nil { log.Error(err) @@ -106,7 +106,7 @@ func (a *Agent) startProjectMode() error { } log.Info("Cloning repository...") - err = a.Git.CloneRepository(project.Repository, auth) + err = a.Git.CloneRepository(workspace.Repository, auth) if err != nil { log.Error(fmt.Sprintf("failed to clone repository: %s", err)) } else { @@ -145,9 +145,9 @@ func (a *Agent) startProjectMode() error { go func() { for { - err := a.updateProjectState() + err := a.updateWorkspaceState() if err != nil { - log.Error(fmt.Sprintf("failed to update project state: %s", err)) + log.Error(fmt.Sprintf("failed to update workspace state: %s", err)) } time.Sleep(2 * time.Second) @@ -157,7 +157,7 @@ func (a *Agent) startProjectMode() error { return nil } -func (a *Agent) getProject() (*project.Project, error) { +func (a *Agent) getWorkspace() (*workspace.Workspace, error) { ctx := context.Background() apiClient, err := apiclient_util.GetAgentApiClient(a.Config.Server.ApiUrl, a.Config.Server.ApiKey, a.Config.ClientId, a.TelemetryEnabled) @@ -170,13 +170,13 @@ func (a *Agent) getProject() (*project.Project, error) { return nil, apiclient_util.HandleErrorResponse(res, err) } - for _, project := range target.Projects { - if project.Name == a.Config.ProjectName { - return conversion.ToProject(&project), nil + for _, workspace := range target.Workspaces { + if workspace.Name == a.Config.WorkspaceName { + return conversion.ToWorkspace(&workspace), nil } } - return nil, errors.New("project not found") + return nil, errors.New("workspace not found") } func (a *Agent) getGitProvider(repoUrl string) (*apiclient.GitProvider, error) { @@ -248,13 +248,13 @@ func (a *Agent) uptime() int32 { return max(int32(time.Since(a.startTime).Seconds()), 1) } -func (a *Agent) updateProjectState() error { +func (a *Agent) updateWorkspaceState() error { apiClient, err := apiclient_util.GetAgentApiClient(a.Config.Server.ApiUrl, a.Config.Server.ApiKey, a.Config.ClientId, a.TelemetryEnabled) if err != nil { return err } - var gitStatus *project.GitStatus + var gitStatus *workspace.GitStatus if a.Config.SkipClone == "" { var err error gitStatus, err = a.Git.GetGitStatus() @@ -264,7 +264,7 @@ func (a *Agent) updateProjectState() error { } uptime := a.uptime() - res, err := apiClient.TargetAPI.SetProjectState(context.Background(), a.Config.TargetId, a.Config.ProjectName).SetState(apiclient.SetProjectState{ + res, err := apiClient.TargetAPI.SetWorkspaceState(context.Background(), a.Config.TargetId, a.Config.WorkspaceName).SetState(apiclient.SetWorkspaceState{ Uptime: uptime, GitStatus: conversion.ToGitStatusDTO(gitStatus), }).Execute() diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 5a1760975d..6f67b3746c 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -17,10 +17,10 @@ import ( "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) -var project1 = &project.Project{ +var workspace1 = &workspace.Workspace{ Name: "test", Repository: &gitprovider.GitRepository{ Id: "123", @@ -29,7 +29,7 @@ var project1 = &project.Project{ }, TargetId: "123", TargetConfig: "local", - State: &project.ProjectState{ + State: &workspace.WorkspaceState{ UpdatedAt: "123", Uptime: 148, GitStatus: gitStatus1, @@ -40,28 +40,28 @@ var target1 = &target.Target{ Id: "123", Name: "test", TargetConfig: "local", - Projects: []*project.Project{ - project1, + Workspaces: []*workspace.Workspace{ + workspace1, }, } -var gitStatus1 = &project.GitStatus{ +var gitStatus1 = &workspace.GitStatus{ CurrentBranch: "main", - Files: []*project.FileStatus{{ + Files: []*workspace.FileStatus{{ Name: "File1", Extra: "", - Staging: project.Modified, - Worktree: project.Modified, + Staging: workspace.Modified, + Worktree: workspace.Modified, }}, } var mockConfig = &config.Config{ - TargetId: target1.Id, - ProjectName: project1.Name, + TargetId: target1.Id, + WorkspaceName: workspace1.Name, Server: config.DaytonaServerConfig{ ApiKey: "test-api-key", }, - Mode: config.ModeProject, + Mode: config.ModeWorkspace, } func TestAgent(t *testing.T) { @@ -82,7 +82,7 @@ func TestAgent(t *testing.T) { mockTailscaleServer := mocks.NewMockTailscaleServer() mockToolboxServer := mocks.NewMockToolboxServer() - mockConfig.ProjectDir = t.TempDir() + mockConfig.WorkspaceDir = t.TempDir() // Create a new Agent instance a := &agent.Agent{ diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index 613b35d249..17bed4bfb2 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -21,13 +21,13 @@ type DaytonaServerConfig struct { } type Config struct { - ProjectDir string - ClientId string `envconfig:"DAYTONA_CLIENT_ID" validate:"required"` - ProjectName string `envconfig:"DAYTONA_PROJECT_NAME"` - TargetId string `envconfig:"DAYTONA_TARGET_ID" validate:"required"` - LogFilePath *string `envconfig:"DAYTONA_AGENT_LOG_FILE_PATH"` - Server DaytonaServerConfig - Mode Mode + WorkspaceDir string + ClientId string `envconfig:"DAYTONA_CLIENT_ID" validate:"required"` + WorkspaceName string `envconfig:"DAYTONA_WORKSPACE_NAME"` + TargetId string `envconfig:"DAYTONA_TARGET_ID" validate:"required"` + LogFilePath *string `envconfig:"DAYTONA_AGENT_LOG_FILE_PATH"` + Server DaytonaServerConfig + Mode Mode SkipClone string `envconfig:"DAYTONA_SKIP_CLONE"` } @@ -35,8 +35,8 @@ type Config struct { type Mode string const ( - ModeHost Mode = "host" - ModeProject Mode = "project" + ModeHost Mode = "host" + ModeWorkspace Mode = "workspace" ) var config *Config @@ -65,9 +65,9 @@ func GetConfig(mode Mode) (*Config, error) { return nil, err } - if config.Mode == ModeProject { - if config.ProjectName == "" { - return nil, errors.New("DAYTONA_PROJECT_NAME is required in project mode") + if config.Mode == ModeWorkspace { + if config.WorkspaceName == "" { + return nil, errors.New("DAYTONA_WORKSPACE_NAME is required in workspace mode") } } diff --git a/pkg/agent/ssh/server.go b/pkg/agent/ssh/server.go index d4d8d4d438..9d464ae4d1 100644 --- a/pkg/agent/ssh/server.go +++ b/pkg/agent/ssh/server.go @@ -22,8 +22,8 @@ import ( ) type Server struct { - ProjectDir string - DefaultProjectDir string + WorkspaceDir string + DefaultWorkspaceDir string } func (s *Server) Start() error { @@ -84,10 +84,10 @@ func (s *Server) handlePty(session ssh.Session, ptyReq ssh.Pty, winCh <-chan ssh shell := common.GetShell() cmd := exec.Command(shell) - cmd.Dir = s.ProjectDir + cmd.Dir = s.WorkspaceDir - if _, err := os.Stat(s.ProjectDir); os.IsNotExist(err) { - cmd.Dir = s.DefaultProjectDir + if _, err := os.Stat(s.WorkspaceDir); os.IsNotExist(err) { + cmd.Dir = s.DefaultWorkspaceDir } if ssh.AgentRequested(session) { @@ -143,9 +143,9 @@ func (s *Server) handleNonPty(session ssh.Session) { cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", "SSH_AUTH_SOCK", l.Addr().String())) } - cmd.Dir = s.ProjectDir - if _, err := os.Stat(s.ProjectDir); os.IsNotExist(err) { - cmd.Dir = s.DefaultProjectDir + cmd.Dir = s.WorkspaceDir + if _, err := os.Stat(s.WorkspaceDir); os.IsNotExist(err) { + cmd.Dir = s.DefaultWorkspaceDir } cmd.Stdout = session diff --git a/pkg/agent/toolbox/git/add.go b/pkg/agent/toolbox/git/add.go index 3ab6eb8134..b70053049d 100644 --- a/pkg/agent/toolbox/git/add.go +++ b/pkg/agent/toolbox/git/add.go @@ -16,7 +16,7 @@ func AddFiles(c *gin.Context) { } gitService := git.Service{ - ProjectDir: req.Path, + WorkspaceDir: req.Path, } if err := gitService.Add(req.Files); err != nil { diff --git a/pkg/agent/toolbox/git/clone_repository.go b/pkg/agent/toolbox/git/clone_repository.go index fd5bec42e8..f357d52692 100644 --- a/pkg/agent/toolbox/git/clone_repository.go +++ b/pkg/agent/toolbox/git/clone_repository.go @@ -33,7 +33,7 @@ func CloneRepository(c *gin.Context) { } gitService := git.Service{ - ProjectDir: req.Path, + WorkspaceDir: req.Path, } var auth *http.BasicAuth diff --git a/pkg/agent/toolbox/git/commit.go b/pkg/agent/toolbox/git/commit.go index d03bbbe236..0fd13fd739 100644 --- a/pkg/agent/toolbox/git/commit.go +++ b/pkg/agent/toolbox/git/commit.go @@ -20,7 +20,7 @@ func CommitChanges(c *gin.Context) { } gitService := git.Service{ - ProjectDir: req.Path, + WorkspaceDir: req.Path, } commitSha, err := gitService.Commit(req.Message, &go_git.CommitOptions{ diff --git a/pkg/agent/toolbox/git/create_branch.go b/pkg/agent/toolbox/git/create_branch.go index 5c9d05d97d..ce4d93181e 100644 --- a/pkg/agent/toolbox/git/create_branch.go +++ b/pkg/agent/toolbox/git/create_branch.go @@ -16,7 +16,7 @@ func CreateBranch(c *gin.Context) { } gitService := git.Service{ - ProjectDir: req.Path, + WorkspaceDir: req.Path, } if err := gitService.CreateBranch(req.Name); err != nil { diff --git a/pkg/agent/toolbox/git/history.go b/pkg/agent/toolbox/git/history.go index 1894efe83b..32d4614787 100644 --- a/pkg/agent/toolbox/git/history.go +++ b/pkg/agent/toolbox/git/history.go @@ -18,7 +18,7 @@ func GetCommitHistory(c *gin.Context) { } gitService := git.Service{ - ProjectDir: path, + WorkspaceDir: path, } log, err := gitService.Log() diff --git a/pkg/agent/toolbox/git/list_branches.go b/pkg/agent/toolbox/git/list_branches.go index 18553ebab6..78a48fcdf7 100644 --- a/pkg/agent/toolbox/git/list_branches.go +++ b/pkg/agent/toolbox/git/list_branches.go @@ -18,7 +18,7 @@ func ListBranches(c *gin.Context) { } gitService := git.Service{ - ProjectDir: path, + WorkspaceDir: path, } branchList, err := gitService.ListBranches() diff --git a/pkg/agent/toolbox/git/pull.go b/pkg/agent/toolbox/git/pull.go index ba7727f361..5493acaf7d 100644 --- a/pkg/agent/toolbox/git/pull.go +++ b/pkg/agent/toolbox/git/pull.go @@ -26,7 +26,7 @@ func PullChanges(c *gin.Context) { } gitService := git.Service{ - ProjectDir: req.Path, + WorkspaceDir: req.Path, } err := gitService.Pull(auth) diff --git a/pkg/agent/toolbox/git/push.go b/pkg/agent/toolbox/git/push.go index 94c2459c5f..4217103da5 100644 --- a/pkg/agent/toolbox/git/push.go +++ b/pkg/agent/toolbox/git/push.go @@ -26,7 +26,7 @@ func PushChanges(c *gin.Context) { } gitService := git.Service{ - ProjectDir: req.Path, + WorkspaceDir: req.Path, } err := gitService.Push(auth) diff --git a/pkg/agent/toolbox/git/status.go b/pkg/agent/toolbox/git/status.go index 5e78ffa8ed..2b48cf955a 100644 --- a/pkg/agent/toolbox/git/status.go +++ b/pkg/agent/toolbox/git/status.go @@ -18,7 +18,7 @@ func GetStatus(c *gin.Context) { } gitService := git.Service{ - ProjectDir: path, + WorkspaceDir: path, } status, err := gitService.GetGitStatus() diff --git a/pkg/agent/toolbox/process/execute.go b/pkg/agent/toolbox/process/execute.go index cef4ef3fc5..b34bf1ebca 100644 --- a/pkg/agent/toolbox/process/execute.go +++ b/pkg/agent/toolbox/process/execute.go @@ -14,7 +14,7 @@ import ( "github.com/gin-gonic/gin" ) -func ExecuteCommand(projectDir string) func(c *gin.Context) { +func ExecuteCommand(workspaceDir string) func(c *gin.Context) { return func(c *gin.Context) { var request ExecuteRequest if err := c.ShouldBindJSON(&request); err != nil { @@ -29,7 +29,7 @@ func ExecuteCommand(projectDir string) func(c *gin.Context) { } cmd := exec.Command(cmdParts[0], cmdParts[1:]...) - cmd.Dir = projectDir + cmd.Dir = workspaceDir // set maximum execution time timeout := 10 * time.Second diff --git a/pkg/agent/toolbox/process/session/session.go b/pkg/agent/toolbox/process/session/session.go index 968d348fce..585cec1efc 100644 --- a/pkg/agent/toolbox/process/session/session.go +++ b/pkg/agent/toolbox/process/session/session.go @@ -18,11 +18,11 @@ import ( var sessions = map[string]*session{} -func CreateSession(projectDir, configDir string) func(c *gin.Context) { +func CreateSession(workspaceDir, configDir string) func(c *gin.Context) { return func(c *gin.Context) { cmd := exec.Command(common.GetShell()) cmd.Env = os.Environ() - cmd.Dir = projectDir + cmd.Dir = workspaceDir var request CreateSessionRequest if err := c.ShouldBindJSON(&request); err != nil { diff --git a/pkg/agent/toolbox/toolbox.go b/pkg/agent/toolbox/toolbox.go index d02211edac..cfb720b791 100644 --- a/pkg/agent/toolbox/toolbox.go +++ b/pkg/agent/toolbox/toolbox.go @@ -21,20 +21,20 @@ import ( ) type Server struct { - ProjectDir string - ConfigDir string + ConfigDir string + WorkspaceDir string } -type ProjectDirResponse struct { +type WorkspaceDirResponse struct { Dir string `json:"dir"` -} // @name ProjectDirResponse +} // @name WorkspaceDirResponse -func (s *Server) GetProjectDir(ctx *gin.Context) { - projectDir := ProjectDirResponse{ - Dir: s.ProjectDir, +func (s *Server) GetWorkspaceDir(ctx *gin.Context) { + workspaceDir := WorkspaceDirResponse{ + Dir: s.WorkspaceDir, } - ctx.JSON(200, projectDir) + ctx.JSON(200, workspaceDir) } func (s *Server) Start() error { @@ -43,7 +43,7 @@ func (s *Server) Start() error { r.Use(middlewares.LoggingMiddleware()) binding.Validator = new(api.DefaultValidator) - r.GET("/project-dir", s.GetProjectDir) + r.GET("/workspace-dir", s.GetWorkspaceDir) fsController := r.Group("/files") { @@ -67,12 +67,12 @@ func (s *Server) Start() error { processController := r.Group("/process") { - processController.POST("/execute", process.ExecuteCommand(s.ProjectDir)) + processController.POST("/execute", process.ExecuteCommand(s.WorkspaceDir)) sessionController := processController.Group("/session") { sessionController.GET("", session.ListSessions) - sessionController.POST("", session.CreateSession(s.ProjectDir, s.ConfigDir)) + sessionController.POST("", session.CreateSession(s.WorkspaceDir, s.ConfigDir)) sessionController.POST("/:sessionId/exec", session.SessionExecuteCommand(s.ConfigDir)) sessionController.DELETE("/:sessionId", session.DeleteSession(s.ConfigDir)) sessionController.GET("/:sessionId/command/:commandId/logs", session.GetSessionCommandLogs(s.ConfigDir)) diff --git a/pkg/api/controllers/binary/get_daytona.go b/pkg/api/controllers/binary/get_daytona.go index 3d7aff1fe9..1759862742 100644 --- a/pkg/api/controllers/binary/get_daytona.go +++ b/pkg/api/controllers/binary/get_daytona.go @@ -12,7 +12,7 @@ import ( "github.com/gin-gonic/gin" ) -// Used in projects to download the Daytona binary +// Used in workspaces to download the Daytona binary func GetDaytonaScript(ctx *gin.Context) { scheme := "http" if ctx.Request.TLS != nil || ctx.GetHeader("X-Forwarded-Proto") == "https" { diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index ebd32cc888..a2cbc435e2 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server" builds_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" + "github.com/daytonaio/daytona/pkg/target/workspace/config" "github.com/gin-gonic/gin" ) @@ -39,22 +39,22 @@ func CreateBuild(ctx *gin.Context) { s := server.GetInstance(nil) - projectConfig, err := s.ProjectConfigService.Find(&config.ProjectConfigFilter{ - Name: &createBuildDto.ProjectConfigName, + workspaceConfig, err := s.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + Name: &createBuildDto.WorkspaceConfigName, }) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get project config: %s", err.Error())) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace config: %s", err.Error())) return } - gitProvider, _, err := s.GitProviderService.GetGitProviderForUrl(projectConfig.RepositoryUrl) + gitProvider, _, err := s.GitProviderService.GetGitProviderForUrl(workspaceConfig.RepositoryUrl) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get git provider for url: %s", err.Error())) return } repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, Branch: &createBuildDto.Branch, }) if err != nil { @@ -63,9 +63,9 @@ func CreateBuild(ctx *gin.Context) { } newBuildDto := builds_dto.BuildCreationData{ - Image: projectConfig.Image, - User: projectConfig.User, - BuildConfig: projectConfig.BuildConfig, + Image: workspaceConfig.Image, + User: workspaceConfig.User, + BuildConfig: workspaceConfig.BuildConfig, Repository: repo, EnvVars: createBuildDto.EnvVars, } @@ -242,7 +242,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { server := server.GetInstance(nil) // Fail if prebuild does not exist - _, err = server.ProjectConfigService.FindPrebuild(nil, &config.PrebuildFilter{ + _, err = server.WorkspaceConfigService.FindPrebuild(nil, &config.PrebuildFilter{ Id: &prebuildId, }) if err != nil { diff --git a/pkg/api/controllers/build/dto/dto.go b/pkg/api/controllers/build/dto/dto.go index f97ef23c04..9f9a26554b 100644 --- a/pkg/api/controllers/build/dto/dto.go +++ b/pkg/api/controllers/build/dto/dto.go @@ -4,8 +4,8 @@ package dto type CreateBuildDTO struct { - ProjectConfigName string `json:"projectConfigName" validate:"required"` - Branch string `json:"branch" validate:"required"` - PrebuildId *string `json:"prebuildId" validate:"optional"` - EnvVars map[string]string `json:"envVars" validate:"required"` + WorkspaceConfigName string `json:"workspaceConfigName" validate:"required"` + Branch string `json:"branch" validate:"required"` + PrebuildId *string `json:"prebuildId" validate:"optional"` + EnvVars map[string]string `json:"envVars" validate:"required"` } // @name CreateBuildDTO diff --git a/pkg/api/controllers/log/websocket.go b/pkg/api/controllers/log/websocket.go index 12447ba208..1ab58f1473 100644 --- a/pkg/api/controllers/log/websocket.go +++ b/pkg/api/controllers/log/websocket.go @@ -170,9 +170,9 @@ func ReadTargetLog(ginCtx *gin.Context) { ReadLog(ginCtx, wsLogReader, util.ReadJSONLog, writeJSONToWs) } -func ReadProjectLog(ginCtx *gin.Context) { +func ReadWorkspaceLog(ginCtx *gin.Context) { targetId := ginCtx.Param("targetId") - projectName := ginCtx.Param("projectName") + workspaceName := ginCtx.Param("workspaceName") retryQuery := ginCtx.DefaultQuery("retry", "true") retry := retryQuery == "true" @@ -180,22 +180,22 @@ func ReadProjectLog(ginCtx *gin.Context) { if retry { for { - projectLogReader, err := server.TargetService.GetProjectLogReader(targetId, projectName) + workspaceLogReader, err := server.TargetService.GetWorkspaceLogReader(targetId, workspaceName) if err == nil { - ReadLog(ginCtx, projectLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ginCtx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) } } - projectLogReader, err := server.TargetService.GetProjectLogReader(targetId, projectName) + workspaceLogReader, err := server.TargetService.GetWorkspaceLogReader(targetId, workspaceName) if err != nil { ginCtx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ginCtx, projectLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ginCtx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) } func ReadBuildLog(ginCtx *gin.Context) { diff --git a/pkg/api/controllers/projectconfig/project_config.go b/pkg/api/controllers/projectconfig/project_config.go deleted file mode 100644 index 30689f4e5f..0000000000 --- a/pkg/api/controllers/projectconfig/project_config.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strconv" - - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" - "github.com/gin-gonic/gin" - log "github.com/sirupsen/logrus" -) - -// GetProjectConfig godoc -// -// @Tags project-config -// @Summary Get project config data -// @Description Get project config data -// @Accept json -// @Param configName path string true "Config name" -// @Success 200 {object} ProjectConfig -// @Router /project-config/{configName} [get] -// -// @id GetProjectConfig -func GetProjectConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - - server := server.GetInstance(nil) - - projectConfig, err := server.ProjectConfigService.Find(&config.ProjectConfigFilter{ - Name: &configName, - }) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get project config: %s", err.Error())) - return - } - - ctx.JSON(200, projectConfig) -} - -// GetDefaultProjectConfig godoc -// -// @Tags project-config -// @Summary Get project configs by git url -// @Description Get project configs by git url -// @Produce json -// @Param gitUrl path string true "Git URL" -// @Success 200 {object} ProjectConfig -// @Router /project-config/default/{gitUrl} [get] -// -// @id GetDefaultProjectConfig -func GetDefaultProjectConfig(ctx *gin.Context) { - gitUrl := ctx.Param("gitUrl") - - decodedURLParam, err := url.QueryUnescape(gitUrl) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode query param: %s", err.Error())) - return - } - - server := server.GetInstance(nil) - - projectConfigs, err := server.ProjectConfigService.Find(&config.ProjectConfigFilter{ - Url: &decodedURLParam, - Default: util.Pointer(true), - }) - if err != nil { - statusCode := http.StatusInternalServerError - if config.IsProjectConfigNotFound(err) { - statusCode = http.StatusNotFound - ctx.AbortWithStatus(statusCode) - log.Debugf("Project config not added for git url: %s", decodedURLParam) - return - } - ctx.AbortWithError(statusCode, fmt.Errorf("failed to find project config by git url: %s", err.Error())) - return - } - - ctx.JSON(200, projectConfigs) -} - -// ListProjectConfigs godoc -// -// @Tags project-config -// @Summary List project configs -// @Description List project configs -// @Produce json -// @Success 200 {array} ProjectConfig -// @Router /project-config [get] -// -// @id ListProjectConfigs -func ListProjectConfigs(ctx *gin.Context) { - server := server.GetInstance(nil) - - projectConfigs, err := server.ProjectConfigService.List(nil) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list project configs: %s", err.Error())) - return - } - - ctx.JSON(200, projectConfigs) -} - -// SetProjectConfig godoc -// -// @Tags project-config -// @Summary Set project config data -// @Description Set project config data -// @Accept json -// @Param projectConfig body CreateProjectConfigDTO true "Project config" -// @Success 201 -// @Router /project-config [put] -// -// @id SetProjectConfig -func SetProjectConfig(ctx *gin.Context) { - var req dto.CreateProjectConfigDTO - err := ctx.BindJSON(&req) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) - return - } - - s := server.GetInstance(nil) - - projectConfig := conversion.ToProjectConfig(req) - - err = s.ProjectConfigService.Save(projectConfig) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save project config: %s", err.Error())) - return - } - - ctx.Status(201) -} - -// SetDefaultProjectConfig godoc -// -// @Tags project-config -// @Summary Set project config to default -// @Description Set project config to default -// @Param configName path string true "Config name" -// @Success 200 -// @Router /project-config/{configName}/set-default [patch] -// -// @id SetDefaultProjectConfig -func SetDefaultProjectConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - - server := server.GetInstance(nil) - - err := server.ProjectConfigService.SetDefault(configName) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set project config to default: %s", err.Error())) - return - } - - ctx.Status(200) -} - -// DeleteProjectConfig godoc -// -// @Tags project-config -// @Summary Delete project config data -// @Description Delete project config data -// @Param configName path string true "Config name" -// @Param force query bool false "Force" -// @Success 204 -// @Router /project-config/{configName} [delete] -// -// @id DeleteProjectConfig -func DeleteProjectConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - forceQuery := ctx.Query("force") - - var err error - var force bool - - if forceQuery != "" { - force, err = strconv.ParseBool(forceQuery) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) - return - } - } - - server := server.GetInstance(nil) - - projectConfig, err := server.ProjectConfigService.Find(&config.ProjectConfigFilter{ - Name: &configName, - }) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find project config: %s", err.Error())) - return - } - - errs := server.ProjectConfigService.Delete(projectConfig.Name, force) - if len(errs) > 0 { - if config.IsProjectConfigNotFound(errs[0]) { - ctx.AbortWithError(http.StatusNotFound, errors.New("project config not found")) - return - } - for _, err := range errs { - _ = ctx.Error(err) - } - ctx.AbortWithStatus(http.StatusInternalServerError) - return - } - - ctx.Status(204) -} diff --git a/pkg/api/controllers/target/dto/dto.go b/pkg/api/controllers/target/dto/dto.go index 2b821b7572..487635ac46 100644 --- a/pkg/api/controllers/target/dto/dto.go +++ b/pkg/api/controllers/target/dto/dto.go @@ -3,11 +3,9 @@ package dto -import ( - "github.com/daytonaio/daytona/pkg/target/project" -) +import "github.com/daytonaio/daytona/pkg/target/workspace" -type SetProjectState struct { - Uptime uint64 `json:"uptime" validate:"required"` - GitStatus *project.GitStatus `json:"gitStatus,omitempty" validate:"optional"` -} // @name SetProjectState +type SetWorkspaceState struct { + Uptime uint64 `json:"uptime" validate:"required"` + GitStatus *workspace.GitStatus `json:"gitStatus,omitempty" validate:"optional"` +} // @name SetWorkspaceState diff --git a/pkg/api/controllers/target/project.go b/pkg/api/controllers/target/project.go deleted file mode 100644 index 2f17205df5..0000000000 --- a/pkg/api/controllers/target/project.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "fmt" - "net/http" - "time" - - "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/target/project" - "github.com/gin-gonic/gin" -) - -// SetProjectState godoc -// -// @Tags target -// @Summary Set project state -// @Description Set project state -// @Param targetId path string true "Target ID or Name" -// @Param projectId path string true "Project ID" -// @Param setState body SetProjectState true "Set State" -// @Success 200 -// @Router /target/{targetId}/{projectId}/state [post] -// -// @id SetProjectState -func SetProjectState(ctx *gin.Context) { - targetId := ctx.Param("targetId") - projectId := ctx.Param("projectId") - - var setProjectStateDTO dto.SetProjectState - err := ctx.BindJSON(&setProjectStateDTO) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - - _, err = server.TargetService.SetProjectState(targetId, projectId, &project.ProjectState{ - Uptime: setProjectStateDTO.Uptime, - UpdatedAt: time.Now().Format(time.RFC1123), - GitStatus: setProjectStateDTO.GitStatus, - }) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop target %s: %w", targetId, err)) - return - } - - ctx.Status(200) -} diff --git a/pkg/api/controllers/target/start.go b/pkg/api/controllers/target/start.go index a0bea25bc9..d38ae9d782 100644 --- a/pkg/api/controllers/target/start.go +++ b/pkg/api/controllers/target/start.go @@ -35,26 +35,26 @@ func StartTarget(ctx *gin.Context) { ctx.Status(200) } -// StartProject godoc +// StartWorkspace godoc // // @Tags target -// @Summary Start project -// @Description Start project +// @Summary Start workspace +// @Description Start workspace // @Param targetId path string true "Target ID or Name" -// @Param projectId path string true "Project ID" +// @Param workspaceId path string true "Workspace ID" // @Success 200 -// @Router /target/{targetId}/{projectId}/start [post] +// @Router /target/{targetId}/{workspaceId}/start [post] // -// @id StartProject -func StartProject(ctx *gin.Context) { +// @id StartWorkspace +func StartWorkspace(ctx *gin.Context) { targetId := ctx.Param("targetId") - projectId := ctx.Param("projectId") + workspaceId := ctx.Param("workspaceId") server := server.GetInstance(nil) - err := server.TargetService.StartProject(ctx.Request.Context(), targetId, projectId) + err := server.TargetService.StartWorkspace(ctx.Request.Context(), targetId, workspaceId) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start project %s: %w", projectId, err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start workspace %s: %w", workspaceId, err)) return } diff --git a/pkg/api/controllers/target/stop.go b/pkg/api/controllers/target/stop.go index b16a72344c..be8a694384 100644 --- a/pkg/api/controllers/target/stop.go +++ b/pkg/api/controllers/target/stop.go @@ -35,26 +35,26 @@ func StopTarget(ctx *gin.Context) { ctx.Status(200) } -// StopProject godoc +// StopWorkspace godoc // // @Tags target -// @Summary Stop project -// @Description Stop project +// @Summary Stop workspace +// @Description Stop workspace // @Param targetId path string true "Target ID or Name" -// @Param projectId path string true "Project ID" +// @Param workspaceId path string true "Workspace ID" // @Success 200 -// @Router /target/{targetId}/{projectId}/stop [post] +// @Router /target/{targetId}/{workspaceId}/stop [post] // -// @id StopProject -func StopProject(ctx *gin.Context) { +// @id StopWorkspace +func StopWorkspace(ctx *gin.Context) { targetId := ctx.Param("targetId") - projectId := ctx.Param("projectId") + workspaceId := ctx.Param("workspaceId") server := server.GetInstance(nil) - err := server.TargetService.StopProject(ctx.Request.Context(), targetId, projectId) + err := server.TargetService.StopWorkspace(ctx.Request.Context(), targetId, workspaceId) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop project %s: %w", projectId, err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %w", workspaceId, err)) return } diff --git a/pkg/api/controllers/target/workspace.go b/pkg/api/controllers/target/workspace.go new file mode 100644 index 0000000000..002817f6ce --- /dev/null +++ b/pkg/api/controllers/target/workspace.go @@ -0,0 +1,53 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "fmt" + "net/http" + "time" + + "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/gin-gonic/gin" +) + +// SetWorkspaceState godoc +// +// @Tags target +// @Summary Set workspace state +// @Description Set workspace state +// @Param targetId path string true "Target ID or Name" +// @Param workspaceId path string true "Workspace ID" +// @Param setState body SetWorkspaceState true "Set State" +// @Success 200 +// @Router /target/{targetId}/{workspaceId}/state [post] +// +// @id SetWorkspaceState +func SetWorkspaceState(ctx *gin.Context) { + targetId := ctx.Param("targetId") + workspaceId := ctx.Param("workspaceId") + + var setWorkspaceStateDTO dto.SetWorkspaceState + err := ctx.BindJSON(&setWorkspaceStateDTO) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + _, err = server.TargetService.SetWorkspaceState(targetId, workspaceId, &workspace.WorkspaceState{ + Uptime: setWorkspaceStateDTO.Uptime, + UpdatedAt: time.Now().Format(time.RFC1123), + GitStatus: setWorkspaceStateDTO.GitStatus, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop target %s: %w", targetId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index 54acf1ff34..cd057f21ca 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -16,25 +16,25 @@ import ( "github.com/daytonaio/daytona/pkg/agent/toolbox/config" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) -// GetProjectDir godoc +// GetWorkspaceDir godoc // // @Tags workspace toolbox -// @Summary Get project dir -// @Description Get project directory +// @Summary Get workspace dir +// @Description Get workspace directory // @Produce json // @Param workspaceId path string true "Workspace ID or Name" // @Param projectId path string true "Project ID" -// @Success 200 {object} ProjectDirResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/project-dir [get] +// @Success 200 {object} WorkspaceDirResponse +// @Router /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir [get] // -// @id GetProjectDir -func GetProjectDir(ctx *gin.Context) { +// @id GetWorkspaceDir +func GetWorkspaceDir(ctx *gin.Context) { forwardRequestToToolbox(ctx) } @@ -45,14 +45,14 @@ var upgrader = websocket.Upgrader{ } func forwardRequestToToolbox(ctx *gin.Context) { + targetId := ctx.Param("targetId") workspaceId := ctx.Param("workspaceId") - projectId := ctx.Param("projectId") server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, true) + tg, err := server.TargetService.GetTarget(ctx.Request.Context(), targetId, true) if err != nil { - if workspaces.IsWorkspaceNotFound(err) { + if errors.Is(err, targets.ErrTargetNotFound) { ctx.AbortWithError(http.StatusNotFound, err) return } @@ -60,26 +60,26 @@ func forwardRequestToToolbox(ctx *gin.Context) { return } - var projectInfo *project.ProjectInfo + var workspaceInfo *workspace.WorkspaceInfo found := false - for _, p := range w.Info.Projects { - if p.Name == projectId { - projectInfo = p + for _, w := range tg.Info.Workspaces { + if w.Name == workspaceId { + workspaceInfo = w found = true break } } if !found { - ctx.AbortWithError(http.StatusNotFound, errors.New("project not found")) + ctx.AbortWithError(http.StatusNotFound, errors.New("workspace not found")) return } var client *http.Client var websocketDialer *websocket.Dialer - projectHostname := project.GetProjectHostname(w.Id, projectId) - route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/%s/toolbox/", workspaceId, projectId), "", 1) + projectHostname := workspace.GetWorkspaceHostname(tg.Id, workspaceId) + route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/%s/toolbox/", targetId, workspaceId), "", 1) query := ctx.Request.URL.Query().Encode() scheme := "http" @@ -95,9 +95,9 @@ func forwardRequestToToolbox(ctx *gin.Context) { }, } - if w.Target == "local" { + if tg.TargetConfig == "local" { var metadata map[string]interface{} - err := json.Unmarshal([]byte(projectInfo.ProviderMetadata), &metadata) + err := json.Unmarshal([]byte(workspaceInfo.ProviderMetadata), &metadata) if err == nil { if toolboxPortString, ok := metadata["daytona.toolbox.api.hostPort"]; ok { toolboxPort, err := strconv.ParseUint(toolboxPortString.(string), 10, 16) diff --git a/pkg/api/controllers/projectconfig/prebuild/prebuild.go b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go similarity index 72% rename from pkg/api/controllers/projectconfig/prebuild/prebuild.go rename to pkg/api/controllers/workspaceconfig/prebuild/prebuild.go index c9437e2948..df287daaef 100644 --- a/pkg/api/controllers/projectconfig/prebuild/prebuild.go +++ b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go @@ -10,8 +10,8 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" "github.com/gin-gonic/gin" ) @@ -21,10 +21,10 @@ import ( // @Summary Get prebuild // @Description Get prebuild // @Accept json -// @Param configName path string true "Project config name" +// @Param configName path string true "Workspace config name" // @Param prebuildId path string true "Prebuild ID" // @Success 200 {object} PrebuildDTO -// @Router /project-config/{configName}/prebuild/{prebuildId} [get] +// @Router /workspace-config/{configName}/prebuild/{prebuildId} [get] // // @id GetPrebuild func GetPrebuild(ctx *gin.Context) { @@ -32,7 +32,7 @@ func GetPrebuild(ctx *gin.Context) { prebuildId := ctx.Param("prebuildId") server := server.GetInstance(nil) - res, err := server.ProjectConfigService.FindPrebuild(&config.ProjectConfigFilter{ + res, err := server.WorkspaceConfigService.FindPrebuild(&config.WorkspaceConfigFilter{ Name: &configName, }, &config.PrebuildFilter{ Id: &prebuildId, @@ -58,7 +58,7 @@ func GetPrebuild(ctx *gin.Context) { // @Param configName path string true "Config name" // @Param prebuild body CreatePrebuildDTO true "Prebuild" // @Success 201 {string} prebuildId -// @Router /project-config/{configName}/prebuild [put] +// @Router /workspace-config/{configName}/prebuild [put] // // @id SetPrebuild func SetPrebuild(ctx *gin.Context) { @@ -72,7 +72,7 @@ func SetPrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - prebuild, err := server.ProjectConfigService.SetPrebuild(configName, dto) + prebuild, err := server.WorkspaceConfigService.SetPrebuild(configName, dto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set prebuild: %s", err.Error())) return @@ -88,12 +88,12 @@ func SetPrebuild(ctx *gin.Context) { // @Description List prebuilds // @Accept json // @Success 200 {array} PrebuildDTO -// @Router /project-config/prebuild [get] +// @Router /workspace-config/prebuild [get] // // @id ListPrebuilds func ListPrebuilds(ctx *gin.Context) { server := server.GetInstance(nil) - res, err := server.ProjectConfigService.ListPrebuilds(nil, nil) + res, err := server.WorkspaceConfigService.ListPrebuilds(nil, nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get prebuilds: %s", err.Error())) return @@ -102,30 +102,30 @@ func ListPrebuilds(ctx *gin.Context) { ctx.JSON(200, res) } -// ListPrebuildsForProjectConfig godoc +// ListPrebuildsForWorkspaceConfig godoc // @Tags prebuild -// @Summary List prebuilds for project config -// @Description List prebuilds for project config +// @Summary List prebuilds for workspace config +// @Description List prebuilds for workspace config // @Accept json // @Param configName path string true "Config name" // @Success 200 {array} PrebuildDTO -// @Router /project-config/{configName}/prebuild [get] +// @Router /workspace-config/{configName}/prebuild [get] // -// @id ListPrebuildsForProjectConfig -func ListPrebuildsForProjectConfig(ctx *gin.Context) { +// @id ListPrebuildsForWorkspaceConfig +func ListPrebuildsForWorkspaceConfig(ctx *gin.Context) { configName := ctx.Param("configName") - var projectConfigFilter *config.ProjectConfigFilter + var workspaceConfigFilter *config.WorkspaceConfigFilter if configName != "" { - projectConfigFilter = &config.ProjectConfigFilter{ + workspaceConfigFilter = &config.WorkspaceConfigFilter{ Name: &configName, } } server := server.GetInstance(nil) - res, err := server.ProjectConfigService.ListPrebuilds(projectConfigFilter, nil) + res, err := server.WorkspaceConfigService.ListPrebuilds(workspaceConfigFilter, nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get prebuilds: %s", err.Error())) return @@ -140,11 +140,11 @@ func ListPrebuildsForProjectConfig(ctx *gin.Context) { // @Summary Delete prebuild // @Description Delete prebuild // @Accept json -// @Param configName path string true "Project config name" +// @Param configName path string true "Workspace config name" // @Param prebuildId path string true "Prebuild ID" // @Param force query bool false "Force" // @Success 204 -// @Router /project-config/{configName}/prebuild/{prebuildId} [delete] +// @Router /workspace-config/{configName}/prebuild/{prebuildId} [delete] // // @id DeletePrebuild func DeletePrebuild(ctx *gin.Context) { @@ -164,7 +164,7 @@ func DeletePrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - errs := server.ProjectConfigService.DeletePrebuild(configName, prebuildId, force) + errs := server.WorkspaceConfigService.DeletePrebuild(configName, prebuildId, force) if len(errs) > 0 { if config.IsPrebuildNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) diff --git a/pkg/api/controllers/projectconfig/prebuild/process_git_event.go b/pkg/api/controllers/workspaceconfig/prebuild/process_git_event.go similarity index 89% rename from pkg/api/controllers/projectconfig/prebuild/process_git_event.go rename to pkg/api/controllers/workspaceconfig/prebuild/process_git_event.go index 1d1abeae65..b8259f8649 100644 --- a/pkg/api/controllers/projectconfig/prebuild/process_git_event.go +++ b/pkg/api/controllers/workspaceconfig/prebuild/process_git_event.go @@ -19,7 +19,7 @@ import ( // @Description ProcessGitEvent // @Param body body interface{} true "Webhook event" // @Success 200 -// @Router /project-config/prebuild/process-git-event [post] +// @Router /workspace-config/prebuild/process-git-event [post] // // @id ProcessGitEvent func ProcessGitEvent(ctx *gin.Context) { @@ -41,7 +41,7 @@ func ProcessGitEvent(ctx *gin.Context) { return } - err = server.ProjectConfigService.ProcessGitEvent(*gitEventData) + err = server.WorkspaceConfigService.ProcessGitEvent(*gitEventData) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to process git event: %s", err.Error())) return diff --git a/pkg/api/controllers/workspaceconfig/workspace_config.go b/pkg/api/controllers/workspaceconfig/workspace_config.go new file mode 100644 index 0000000000..afe7cd20e2 --- /dev/null +++ b/pkg/api/controllers/workspaceconfig/workspace_config.go @@ -0,0 +1,218 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" +) + +// GetWorkspaceConfig godoc +// +// @Tags workspace-config +// @Summary Get workspace config data +// @Description Get workspace config data +// @Accept json +// @Param configName path string true "Config name" +// @Success 200 {object} WorkspaceConfig +// @Router /workspace-config/{configName} [get] +// +// @id GetWorkspaceConfig +func GetWorkspaceConfig(ctx *gin.Context) { + configName := ctx.Param("configName") + + server := server.GetInstance(nil) + + workspaceConfig, err := server.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + Name: &configName, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace config: %s", err.Error())) + return + } + + ctx.JSON(200, workspaceConfig) +} + +// GetDefaultWorkspaceConfig godoc +// +// @Tags workspace-config +// @Summary Get workspace configs by git url +// @Description Get workspace configs by git url +// @Produce json +// @Param gitUrl path string true "Git URL" +// @Success 200 {object} WorkspaceConfig +// @Router /workspace-config/default/{gitUrl} [get] +// +// @id GetDefaultWorkspaceConfig +func GetDefaultWorkspaceConfig(ctx *gin.Context) { + gitUrl := ctx.Param("gitUrl") + + decodedURLParam, err := url.QueryUnescape(gitUrl) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode query param: %s", err.Error())) + return + } + + server := server.GetInstance(nil) + + workspaceConfigs, err := server.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + Url: &decodedURLParam, + Default: util.Pointer(true), + }) + if err != nil { + statusCode := http.StatusInternalServerError + if config.IsWorkspaceConfigNotFound(err) { + statusCode = http.StatusNotFound + ctx.AbortWithStatus(statusCode) + log.Debugf("Workspace config not added for git url: %s", decodedURLParam) + return + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to find workspace config by git url: %s", err.Error())) + return + } + + ctx.JSON(200, workspaceConfigs) +} + +// ListWorkspaceConfigs godoc +// +// @Tags workspace-config +// @Summary List workspace configs +// @Description List workspace configs +// @Produce json +// @Success 200 {array} WorkspaceConfig +// @Router /workspace-config [get] +// +// @id ListWorkspaceConfigs +func ListWorkspaceConfigs(ctx *gin.Context) { + server := server.GetInstance(nil) + + workspaceConfigs, err := server.WorkspaceConfigService.List(nil) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspace configs: %s", err.Error())) + return + } + + ctx.JSON(200, workspaceConfigs) +} + +// SetWorkspaceConfig godoc +// +// @Tags workspace-config +// @Summary Set workspace config data +// @Description Set workspace config data +// @Accept json +// @Param workspaceConfig body CreateWorkspaceConfigDTO true "Workspace config" +// @Success 201 +// @Router /workspace-config [put] +// +// @id SetWorkspaceConfig +func SetWorkspaceConfig(ctx *gin.Context) { + var req dto.CreateWorkspaceConfigDTO + err := ctx.BindJSON(&req) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) + return + } + + s := server.GetInstance(nil) + + workspaceConfig := conversion.ToWorkspaceConfig(req) + + err = s.WorkspaceConfigService.Save(workspaceConfig) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save workspace config: %s", err.Error())) + return + } + + ctx.Status(201) +} + +// SetDefaultWorkspaceConfig godoc +// +// @Tags workspace-config +// @Summary Set workspace config to default +// @Description Set workspace config to default +// @Param configName path string true "Config name" +// @Success 200 +// @Router /workspace-config/{configName}/set-default [patch] +// +// @id SetDefaultWorkspaceConfig +func SetDefaultWorkspaceConfig(ctx *gin.Context) { + configName := ctx.Param("configName") + + server := server.GetInstance(nil) + + err := server.WorkspaceConfigService.SetDefault(configName) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set workspace config to default: %s", err.Error())) + return + } + + ctx.Status(200) +} + +// DeleteWorkspaceConfig godoc +// +// @Tags workspace-config +// @Summary Delete workspace config data +// @Description Delete workspace config data +// @Param configName path string true "Config name" +// @Param force query bool false "Force" +// @Success 204 +// @Router /workspace-config/{configName} [delete] +// +// @id DeleteWorkspaceConfig +func DeleteWorkspaceConfig(ctx *gin.Context) { + configName := ctx.Param("configName") + forceQuery := ctx.Query("force") + + var err error + var force bool + + if forceQuery != "" { + force, err = strconv.ParseBool(forceQuery) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) + return + } + } + + server := server.GetInstance(nil) + + workspaceConfig, err := server.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + Name: &configName, + }) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find workspace config: %s", err.Error())) + return + } + + errs := server.WorkspaceConfigService.Delete(workspaceConfig.Name, force) + if len(errs) > 0 { + if config.IsWorkspaceConfigNotFound(errs[0]) { + ctx.AbortWithError(http.StatusNotFound, errors.New("workspace config not found")) + return + } + for _, err := range errs { + _ = ctx.Error(err) + } + ctx.AbortWithStatus(http.StatusInternalServerError) + return + } + + ctx.Status(204) +} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index ed4fb11678..cfaefaecd2 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -921,73 +921,72 @@ const docTemplate = `{ } } }, - "/project-config": { + "/provider": { "get": { - "description": "List project configs", + "description": "List providers", "produces": [ "application/json" ], "tags": [ - "project-config" + "provider" ], - "summary": "List project configs", - "operationId": "ListProjectConfigs", + "summary": "List providers", + "operationId": "ListProviders", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/ProjectConfig" + "$ref": "#/definitions/Provider" } } } } - }, - "put": { - "description": "Set project config data", + } + }, + "/provider/install": { + "post": { + "description": "Install a provider", "consumes": [ "application/json" ], "tags": [ - "project-config" + "provider" ], - "summary": "Set project config data", - "operationId": "SetProjectConfig", + "summary": "Install a provider", + "operationId": "InstallProvider", "parameters": [ { - "description": "Project config", - "name": "projectConfig", + "description": "Provider to install", + "name": "provider", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateProjectConfigDTO" + "$ref": "#/definitions/InstallProviderRequest" } } ], "responses": { - "201": { - "description": "Created" + "200": { + "description": "OK" } } } }, - "/project-config/default/{gitUrl}": { + "/provider/{provider}/target-config-manifest": { "get": { - "description": "Get project configs by git url", - "produces": [ - "application/json" - ], + "description": "Get provider target config manifest", "tags": [ - "project-config" + "provider" ], - "summary": "Get project configs by git url", - "operationId": "GetDefaultProjectConfig", + "summary": "Get provider target config manifest", + "operationId": "GetTargetConfigManifest", "parameters": [ { "type": "string", - "description": "Git URL", - "name": "gitUrl", + "description": "Provider name", + "name": "provider", "in": "path", "required": true } @@ -996,138 +995,179 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProjectConfig" + "$ref": "#/definitions/TargetConfigManifest" } } } } }, - "/project-config/prebuild": { - "get": { - "description": "List prebuilds", + "/provider/{provider}/uninstall": { + "post": { + "description": "Uninstall a provider", "consumes": [ "application/json" ], "tags": [ - "prebuild" + "provider" ], - "summary": "List prebuilds", - "operationId": "ListPrebuilds", + "summary": "Uninstall a provider", + "operationId": "UninstallProvider", + "parameters": [ + { + "type": "string", + "description": "Provider to uninstall", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sample": { + "get": { + "description": "List samples", + "produces": [ + "application/json" + ], + "tags": [ + "sample" + ], + "summary": "List samples", + "operationId": "ListSamples", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/PrebuildDTO" + "$ref": "#/definitions/Sample" } } } } } }, - "/project-config/prebuild/process-git-event": { + "/server/config": { + "get": { + "description": "Get the server configuration", + "produces": [ + "application/json" + ], + "tags": [ + "server" + ], + "summary": "Get the server configuration", + "operationId": "GetConfig", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/ServerConfig" + } + } + } + }, "post": { - "description": "ProcessGitEvent", + "description": "Set the server configuration", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], "tags": [ - "prebuild" + "server" ], - "summary": "ProcessGitEvent", - "operationId": "ProcessGitEvent", + "summary": "Set the server configuration", + "operationId": "SetConfig", "parameters": [ { - "description": "Webhook event", - "name": "body", + "description": "Server configuration", + "name": "config", "in": "body", "required": true, "schema": { - "type": "object" + "$ref": "#/definitions/ServerConfig" } } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/ServerConfig" + } } } } }, - "/project-config/{configName}": { + "/server/logs": { "get": { - "description": "Get project config data", - "consumes": [ + "description": "List server log files", + "produces": [ "application/json" ], "tags": [ - "project-config" - ], - "summary": "Get project config data", - "operationId": "GetProjectConfig", - "parameters": [ - { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true - } + "server" ], + "summary": "List server log files", + "operationId": "GetServerLogFiles", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProjectConfig" + "type": "array", + "items": { + "type": "string" + } } } } - }, - "delete": { - "description": "Delete project config data", - "tags": [ - "project-config" + } + }, + "/server/network-key": { + "post": { + "description": "Generate a new authentication key", + "produces": [ + "application/json" ], - "summary": "Delete project config data", - "operationId": "DeleteProjectConfig", - "parameters": [ - { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Force", - "name": "force", - "in": "query" - } + "tags": [ + "server" ], + "summary": "Generate a new authentication key", + "operationId": "GenerateNetworkKey", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/NetworkKey" + } } } } }, - "/project-config/{configName}/prebuild": { + "/target": { "get": { - "description": "List prebuilds for project config", - "consumes": [ + "description": "List targets", + "produces": [ "application/json" ], "tags": [ - "prebuild" + "target" ], - "summary": "List prebuilds for project config", - "operationId": "ListPrebuildsForProjectConfig", + "summary": "List targets", + "operationId": "ListTargets", "parameters": [ { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" } ], "responses": { @@ -1136,116 +1176,106 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/PrebuildDTO" + "$ref": "#/definitions/TargetDTO" } } } } }, - "put": { - "description": "Set prebuild", - "consumes": [ + "post": { + "description": "Create a target", + "produces": [ "application/json" ], "tags": [ - "prebuild" + "target" ], - "summary": "Set prebuild", - "operationId": "SetPrebuild", + "summary": "Create a target", + "operationId": "CreateTarget", "parameters": [ { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true - }, - { - "description": "Prebuild", - "name": "prebuild", + "description": "Create target", + "name": "target", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreatePrebuildDTO" + "$ref": "#/definitions/CreateTargetDTO" } } ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "schema": { - "type": "string" + "$ref": "#/definitions/Target" } } } } }, - "/project-config/{configName}/prebuild/{prebuildId}": { + "/target-config": { "get": { - "description": "Get prebuild", - "consumes": [ + "description": "List target configs", + "produces": [ "application/json" ], "tags": [ - "prebuild" - ], - "summary": "Get prebuild", - "operationId": "GetPrebuild", - "parameters": [ - { - "type": "string", - "description": "Project config name", - "name": "configName", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Prebuild ID", - "name": "prebuildId", - "in": "path", - "required": true - } + "target-config" ], + "summary": "List target configs", + "operationId": "ListTargetConfigs", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/PrebuildDTO" - } - } - } + "type": "array", + "items": { + "$ref": "#/definitions/TargetConfig" + } + } + } + } }, - "delete": { - "description": "Delete prebuild", - "consumes": [ - "application/json" + "put": { + "description": "Set a target config", + "tags": [ + "target-config" ], + "summary": "Set a target config", + "operationId": "SetTargetConfig", + "parameters": [ + { + "description": "Target config to set", + "name": "targetConfig", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateTargetConfigDTO" + } + } + ], + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/target-config/{configName}": { + "delete": { + "description": "Remove a target config", "tags": [ - "prebuild" + "target-config" ], - "summary": "Delete prebuild", - "operationId": "DeletePrebuild", + "summary": "Remove a target config", + "operationId": "RemoveTargetConfig", "parameters": [ { "type": "string", - "description": "Project config name", + "description": "Target Config name", "name": "configName", "in": "path", "required": true - }, - { - "type": "string", - "description": "Prebuild ID", - "name": "prebuildId", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Force", - "name": "force", - "in": "query" } ], "responses": { @@ -1255,18 +1285,18 @@ const docTemplate = `{ } } }, - "/project-config/{configName}/set-default": { + "/target-config/{configName}/set-default": { "patch": { - "description": "Set project config to default", + "description": "Set target config to default", "tags": [ - "project-config" + "target-config" ], - "summary": "Set project config to default", - "operationId": "SetDefaultProjectConfig", + "summary": "Set target config to default", + "operationId": "SetDefaultTargetConfig", "parameters": [ { "type": "string", - "description": "Config name", + "description": "Target config name", "name": "configName", "in": "path", "required": true @@ -1279,50 +1309,61 @@ const docTemplate = `{ } } }, - "/provider": { + "/target/{targetId}": { "get": { - "description": "List providers", + "description": "Get target info", "produces": [ "application/json" ], "tags": [ - "provider" + "target" + ], + "summary": "Get target info", + "operationId": "GetTarget", + "parameters": [ + { + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" + } ], - "summary": "List providers", - "operationId": "ListProviders", "responses": { "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Provider" - } + "$ref": "#/definitions/TargetDTO" } } } - } - }, - "/provider/install": { - "post": { - "description": "Install a provider", - "consumes": [ - "application/json" - ], + }, + "delete": { + "description": "Remove target", "tags": [ - "provider" + "target" ], - "summary": "Install a provider", - "operationId": "InstallProvider", + "summary": "Remove target", + "operationId": "RemoveTarget", "parameters": [ { - "description": "Provider to install", - "name": "provider", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/InstallProviderRequest" - } + "type": "string", + "description": "Target ID", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" } ], "responses": { @@ -1332,49 +1373,43 @@ const docTemplate = `{ } } }, - "/provider/{provider}/target-config-manifest": { - "get": { - "description": "Get provider target config manifest", + "/target/{targetId}/start": { + "post": { + "description": "Start target", "tags": [ - "provider" + "target" ], - "summary": "Get provider target config manifest", - "operationId": "GetTargetConfigManifest", + "summary": "Start target", + "operationId": "StartTarget", "parameters": [ { "type": "string", - "description": "Provider name", - "name": "provider", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/TargetConfigManifest" - } + "description": "OK" } } } }, - "/provider/{provider}/uninstall": { + "/target/{targetId}/stop": { "post": { - "description": "Uninstall a provider", - "consumes": [ - "application/json" - ], + "description": "Stop target", "tags": [ - "provider" + "target" ], - "summary": "Uninstall a provider", - "operationId": "UninstallProvider", + "summary": "Stop target", + "operationId": "StopTarget", "parameters": [ { "type": "string", - "description": "Provider to uninstall", - "name": "provider", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } @@ -1386,229 +1421,149 @@ const docTemplate = `{ } } }, - "/sample": { - "get": { - "description": "List samples", - "produces": [ - "application/json" - ], - "tags": [ - "sample" - ], - "summary": "List samples", - "operationId": "ListSamples", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Sample" - } - } - } - } - } - }, - "/server/config": { - "get": { - "description": "Get the server configuration", - "produces": [ - "application/json" - ], - "tags": [ - "server" - ], - "summary": "Get the server configuration", - "operationId": "GetConfig", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ServerConfig" - } - } - } - }, + "/target/{targetId}/{workspaceId}/start": { "post": { - "description": "Set the server configuration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], + "description": "Start workspace", "tags": [ - "server" + "target" ], - "summary": "Set the server configuration", - "operationId": "SetConfig", + "summary": "Start workspace", + "operationId": "StartWorkspace", "parameters": [ { - "description": "Server configuration", - "name": "config", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/ServerConfig" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ServerConfig" - } + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true } - } - } - }, - "/server/logs": { - "get": { - "description": "List server log files", - "produces": [ - "application/json" ], - "tags": [ - "server" - ], - "summary": "List server log files", - "operationId": "GetServerLogFiles", "responses": { "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } + "description": "OK" } } } }, - "/server/network-key": { + "/target/{targetId}/{workspaceId}/state": { "post": { - "description": "Generate a new authentication key", - "produces": [ - "application/json" - ], - "tags": [ - "server" - ], - "summary": "Generate a new authentication key", - "operationId": "GenerateNetworkKey", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/NetworkKey" - } - } - } - } - }, - "/target": { - "get": { - "description": "List targets", - "produces": [ - "application/json" - ], + "description": "Set workspace state", "tags": [ "target" ], - "summary": "List targets", - "operationId": "ListTargets", + "summary": "Set workspace state", + "operationId": "SetWorkspaceState", "parameters": [ { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "description": "Set State", + "name": "setState", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetWorkspaceState" + } } ], "responses": { "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/TargetDTO" - } - } + "description": "OK" } } - }, + } + }, + "/target/{targetId}/{workspaceId}/stop": { "post": { - "description": "Create a target", - "produces": [ - "application/json" - ], + "description": "Stop workspace", "tags": [ "target" ], - "summary": "Create a target", - "operationId": "CreateTarget", + "summary": "Stop workspace", + "operationId": "StopWorkspace", "parameters": [ { - "description": "Create target", - "name": "target", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/CreateTargetDTO" - } + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/Target" - } + "description": "OK" } } } }, - "/target-config": { + "/workspace-config": { "get": { - "description": "List target configs", + "description": "List workspace configs", "produces": [ "application/json" ], "tags": [ - "target-config" + "workspace-config" ], - "summary": "List target configs", - "operationId": "ListTargetConfigs", + "summary": "List workspace configs", + "operationId": "ListWorkspaceConfigs", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/TargetConfig" + "$ref": "#/definitions/WorkspaceConfig" } } } } }, "put": { - "description": "Set a target config", + "description": "Set workspace config data", + "consumes": [ + "application/json" + ], "tags": [ - "target-config" + "workspace-config" ], - "summary": "Set a target config", - "operationId": "SetTargetConfig", + "summary": "Set workspace config data", + "operationId": "SetWorkspaceConfig", "parameters": [ { - "description": "Target config to set", - "name": "targetConfig", + "description": "Workspace config", + "name": "workspaceConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateTargetConfigDTO" + "$ref": "#/definitions/CreateWorkspaceConfigDTO" } } ], @@ -1619,45 +1574,77 @@ const docTemplate = `{ } } }, - "/target-config/{configName}": { - "delete": { - "description": "Remove a target config", + "/workspace-config/default/{gitUrl}": { + "get": { + "description": "Get workspace configs by git url", + "produces": [ + "application/json" + ], "tags": [ - "target-config" + "workspace-config" ], - "summary": "Remove a target config", - "operationId": "RemoveTargetConfig", + "summary": "Get workspace configs by git url", + "operationId": "GetDefaultWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target Config name", - "name": "configName", + "description": "Git URL", + "name": "gitUrl", "in": "path", "required": true } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceConfig" + } } } } }, - "/target-config/{configName}/set-default": { - "patch": { - "description": "Set target config to default", + "/workspace-config/prebuild": { + "get": { + "description": "List prebuilds", + "consumes": [ + "application/json" + ], "tags": [ - "target-config" + "prebuild" ], - "summary": "Set target config to default", - "operationId": "SetDefaultTargetConfig", + "summary": "List prebuilds", + "operationId": "ListPrebuilds", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildDTO" + } + } + } + } + } + }, + "/workspace-config/prebuild/process-git-event": { + "post": { + "description": "ProcessGitEvent", + "tags": [ + "prebuild" + ], + "summary": "ProcessGitEvent", + "operationId": "ProcessGitEvent", "parameters": [ { - "type": "string", - "description": "Target config name", - "name": "configName", - "in": "path", - "required": true + "description": "Webhook event", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } } ], "responses": { @@ -1667,53 +1654,47 @@ const docTemplate = `{ } } }, - "/target/{targetId}": { + "/workspace-config/{configName}": { "get": { - "description": "Get target info", - "produces": [ + "description": "Get workspace config data", + "consumes": [ "application/json" ], "tags": [ - "target" + "workspace-config" ], - "summary": "Get target info", - "operationId": "GetTarget", + "summary": "Get workspace config data", + "operationId": "GetWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true - }, - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/TargetDTO" + "$ref": "#/definitions/WorkspaceConfig" } } } }, "delete": { - "description": "Remove target", + "description": "Delete workspace config data", "tags": [ - "target" + "workspace-config" ], - "summary": "Remove target", - "operationId": "RemoveTarget", + "summary": "Delete workspace config data", + "operationId": "DeleteWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true }, @@ -1725,151 +1706,170 @@ const docTemplate = `{ } ], "responses": { - "200": { - "description": "OK" + "204": { + "description": "No Content" } } } }, - "/target/{targetId}/start": { - "post": { - "description": "Start target", + "/workspace-config/{configName}/prebuild": { + "get": { + "description": "List prebuilds for workspace config", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Start target", - "operationId": "StartTarget", + "summary": "List prebuilds for workspace config", + "operationId": "ListPrebuildsForWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildDTO" + } + } } } - } - }, - "/target/{targetId}/stop": { - "post": { - "description": "Stop target", + }, + "put": { + "description": "Set prebuild", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Stop target", - "operationId": "StopTarget", + "summary": "Set prebuild", + "operationId": "SetPrebuild", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true + }, + { + "description": "Prebuild", + "name": "prebuild", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreatePrebuildDTO" + } } ], "responses": { - "200": { - "description": "OK" + "201": { + "description": "Created", + "schema": { + "type": "string" + } } } } }, - "/target/{targetId}/{projectId}/start": { - "post": { - "description": "Start project", + "/workspace-config/{configName}/prebuild/{prebuildId}": { + "get": { + "description": "Get prebuild", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Start project", - "operationId": "StartProject", + "summary": "Get prebuild", + "operationId": "GetPrebuild", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Workspace config name", + "name": "configName", "in": "path", "required": true }, { "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Prebuild ID", + "name": "prebuildId", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/PrebuildDTO" + } } } - } - }, - "/target/{targetId}/{projectId}/state": { - "post": { - "description": "Set project state", + }, + "delete": { + "description": "Delete prebuild", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Set project state", - "operationId": "SetProjectState", + "summary": "Delete prebuild", + "operationId": "DeletePrebuild", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Workspace config name", + "name": "configName", "in": "path", "required": true }, { "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Prebuild ID", + "name": "prebuildId", "in": "path", - "required": true - }, - { - "description": "Set State", - "name": "setState", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/SetProjectState" - } + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" } ], "responses": { - "200": { - "description": "OK" + "204": { + "description": "No Content" } } } }, - "/target/{targetId}/{projectId}/stop": { - "post": { - "description": "Stop project", + "/workspace-config/{configName}/set-default": { + "patch": { + "description": "Set workspace config to default", "tags": [ - "target" + "workspace-config" ], - "summary": "Stop project", - "operationId": "StopProject", + "summary": "Set workspace config to default", + "operationId": "SetDefaultWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Config name", + "name": "configName", "in": "path", "required": true } @@ -3414,17 +3414,17 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/project-dir": { + "/workspace/{workspaceId}/{projectId}/toolbox/workspace-dir": { "get": { - "description": "Get project directory", + "description": "Get workspace directory", "produces": [ "application/json" ], "tags": [ "workspace toolbox" ], - "summary": "Get project dir", - "operationId": "GetProjectDir", + "summary": "Get workspace dir", + "operationId": "GetWorkspaceDir", "parameters": [ { "type": "string", @@ -3445,7 +3445,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProjectDirResponse" + "$ref": "#/definitions/WorkspaceDirResponse" } } } @@ -3465,7 +3465,7 @@ const docTemplate = `{ "type": "string" }, "name": { - "description": "Project or client name", + "description": "Workspace or client name", "type": "string" }, "type": { @@ -3677,7 +3677,7 @@ const docTemplate = `{ "required": [ "branch", "envVars", - "projectConfigName" + "workspaceConfigName" ], "properties": { "branch": { @@ -3692,7 +3692,7 @@ const docTemplate = `{ "prebuildId": { "type": "string" }, - "projectConfigName": { + "workspaceConfigName": { "type": "string" } } @@ -3723,7 +3723,63 @@ const docTemplate = `{ } } }, - "CreateProjectConfigDTO": { + "CreateSessionRequest": { + "type": "object", + "required": [ + "sessionId" + ], + "properties": { + "sessionId": { + "type": "string" + } + } + }, + "CreateTargetConfigDTO": { + "type": "object", + "required": [ + "name", + "options", + "providerInfo" + ], + "properties": { + "name": { + "type": "string" + }, + "options": { + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/provider.ProviderInfo" + } + } + }, + "CreateTargetDTO": { + "type": "object", + "required": [ + "id", + "name", + "targetConfig", + "workspaces" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "targetConfig": { + "type": "string" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/CreateWorkspaceDTO" + } + } + } + }, + "CreateWorkspaceConfigDTO": { "type": "object", "required": [ "envVars", @@ -3757,7 +3813,7 @@ const docTemplate = `{ } } }, - "CreateProjectDTO": { + "CreateWorkspaceDTO": { "type": "object", "required": [ "envVars", @@ -3784,14 +3840,14 @@ const docTemplate = `{ "type": "string" }, "source": { - "$ref": "#/definitions/CreateProjectSourceDTO" + "$ref": "#/definitions/CreateWorkspaceSourceDTO" }, "user": { "type": "string" } } }, - "CreateProjectSourceDTO": { + "CreateWorkspaceSourceDTO": { "type": "object", "required": [ "repository" @@ -3802,62 +3858,6 @@ const docTemplate = `{ } } }, - "CreateSessionRequest": { - "type": "object", - "required": [ - "sessionId" - ], - "properties": { - "sessionId": { - "type": "string" - } - } - }, - "CreateTargetConfigDTO": { - "type": "object", - "required": [ - "name", - "options", - "providerInfo" - ], - "properties": { - "name": { - "type": "string" - }, - "options": { - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" - } - } - }, - "CreateTargetDTO": { - "type": "object", - "required": [ - "id", - "name", - "projects", - "targetConfig" - ], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "projects": { - "type": "array", - "items": { - "$ref": "#/definitions/CreateProjectDTO" - } - }, - "targetConfig": { - "type": "string" - } - } - }, "DevcontainerConfig": { "type": "object", "required": [ @@ -4566,237 +4566,92 @@ const docTemplate = `{ }, "Position": { "type": "object", - "required": [ - "character", - "line" - ], - "properties": { - "character": { - "type": "integer" - }, - "line": { - "type": "integer" - } - } - }, - "PrebuildConfig": { - "type": "object", - "required": [ - "branch", - "commitInterval", - "id", - "retention", - "triggerFiles" - ], - "properties": { - "branch": { - "type": "string" - }, - "commitInterval": { - "type": "integer" - }, - "id": { - "type": "string" - }, - "retention": { - "type": "integer" - }, - "triggerFiles": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "PrebuildDTO": { - "type": "object", - "required": [ - "branch", - "id", - "projectConfigName", - "retention" - ], - "properties": { - "branch": { - "type": "string" - }, - "commitInterval": { - "type": "integer" - }, - "id": { - "type": "string" - }, - "projectConfigName": { - "type": "string" - }, - "retention": { - "type": "integer" - }, - "triggerFiles": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "ProfileData": { - "type": "object", - "required": [ - "envVars" - ], - "properties": { - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - } - }, - "Project": { - "type": "object", - "required": [ - "envVars", - "image", - "name", - "repository", - "targetConfig", - "targetId", - "user" - ], - "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { - "type": "string" - }, - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "repository": { - "$ref": "#/definitions/GitRepository" - }, - "state": { - "$ref": "#/definitions/ProjectState" - }, - "targetConfig": { - "type": "string" - }, - "targetId": { - "type": "string" + "required": [ + "character", + "line" + ], + "properties": { + "character": { + "type": "integer" }, - "user": { - "type": "string" + "line": { + "type": "integer" } } }, - "ProjectConfig": { + "PrebuildConfig": { "type": "object", "required": [ - "default", - "envVars", - "image", - "name", - "repositoryUrl", - "user" + "branch", + "commitInterval", + "id", + "retention", + "triggerFiles" ], "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "default": { - "type": "boolean" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { + "branch": { "type": "string" }, - "image": { - "type": "string" + "commitInterval": { + "type": "integer" }, - "name": { + "id": { "type": "string" }, - "prebuilds": { + "retention": { + "type": "integer" + }, + "triggerFiles": { "type": "array", "items": { - "$ref": "#/definitions/PrebuildConfig" + "type": "string" } - }, - "repositoryUrl": { - "type": "string" - }, - "user": { - "type": "string" } } }, - "ProjectDirResponse": { - "type": "object", - "properties": { - "dir": { - "type": "string" - } - } - }, - "ProjectInfo": { + "PrebuildDTO": { "type": "object", "required": [ - "created", - "isRunning", - "name", - "targetId" + "branch", + "id", + "retention", + "workspaceConfigName" ], "properties": { - "created": { + "branch": { "type": "string" }, - "isRunning": { - "type": "boolean" + "commitInterval": { + "type": "integer" }, - "name": { + "id": { "type": "string" }, - "providerMetadata": { - "type": "string" + "retention": { + "type": "integer" }, - "targetId": { + "triggerFiles": { + "type": "array", + "items": { + "type": "string" + } + }, + "workspaceConfigName": { "type": "string" } } }, - "ProjectState": { + "ProfileData": { "type": "object", "required": [ - "updatedAt", - "uptime" + "envVars" ], "properties": { - "gitStatus": { - "$ref": "#/definitions/GitStatus" - }, - "updatedAt": { - "type": "string" - }, - "uptime": { - "type": "integer" + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } } } }, @@ -4905,8 +4760,8 @@ const docTemplate = `{ "binariesPath", "builderImage", "builderRegistryServer", - "defaultProjectImage", - "defaultProjectUser", + "defaultWorkspaceImage", + "defaultWorkspaceUser", "headscalePort", "id", "localBuilderRegistryImage", @@ -4932,10 +4787,10 @@ const docTemplate = `{ "builderRegistryServer": { "type": "string" }, - "defaultProjectImage": { + "defaultWorkspaceImage": { "type": "string" }, - "defaultProjectUser": { + "defaultWorkspaceUser": { "type": "string" }, "frps": { @@ -5049,7 +4904,7 @@ const docTemplate = `{ } } }, - "SetProjectState": { + "SetWorkspaceState": { "type": "object", "required": [ "uptime" @@ -5102,8 +4957,8 @@ const docTemplate = `{ "required": [ "id", "name", - "projects", - "targetConfig" + "targetConfig", + "workspaces" ], "properties": { "id": { @@ -5112,14 +4967,14 @@ const docTemplate = `{ "name": { "type": "string" }, - "projects": { + "targetConfig": { + "type": "string" + }, + "workspaces": { "type": "array", "items": { - "$ref": "#/definitions/Project" + "$ref": "#/definitions/Workspace" } - }, - "targetConfig": { - "type": "string" } } }, @@ -5195,8 +5050,8 @@ const docTemplate = `{ "required": [ "id", "name", - "projects", - "targetConfig" + "targetConfig", + "workspaces" ], "properties": { "id": { @@ -5208,35 +5063,180 @@ const docTemplate = `{ "name": { "type": "string" }, - "projects": { + "targetConfig": { + "type": "string" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/Workspace" + } + } + } + }, + "TargetInfo": { + "type": "object", + "required": [ + "name", + "workspaces" + ], + "properties": { + "name": { + "type": "string" + }, + "providerMetadata": { + "type": "string" + }, + "workspaces": { "type": "array", "items": { - "$ref": "#/definitions/Project" + "$ref": "#/definitions/WorkspaceInfo" + } + } + } + }, + "Workspace": { + "type": "object", + "required": [ + "envVars", + "image", + "name", + "repository", + "targetConfig", + "targetId", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" } }, + "gitProviderConfigId": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repository": { + "$ref": "#/definitions/GitRepository" + }, + "state": { + "$ref": "#/definitions/WorkspaceState" + }, "targetConfig": { "type": "string" + }, + "targetId": { + "type": "string" + }, + "user": { + "type": "string" } } }, - "TargetInfo": { + "WorkspaceConfig": { "type": "object", "required": [ + "default", + "envVars", + "image", "name", - "projects" + "repositoryUrl", + "user" ], "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "default": { + "type": "boolean" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "image": { + "type": "string" + }, "name": { "type": "string" }, - "projects": { + "prebuilds": { "type": "array", "items": { - "$ref": "#/definitions/ProjectInfo" + "$ref": "#/definitions/PrebuildConfig" } }, + "repositoryUrl": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, + "WorkspaceDirResponse": { + "type": "object", + "properties": { + "dir": { + "type": "string" + } + } + }, + "WorkspaceInfo": { + "type": "object", + "required": [ + "created", + "isRunning", + "name", + "targetId" + ], + "properties": { + "created": { + "type": "string" + }, + "isRunning": { + "type": "boolean" + }, + "name": { + "type": "string" + }, "providerMetadata": { "type": "string" + }, + "targetId": { + "type": "string" + } + } + }, + "WorkspaceState": { + "type": "object", + "required": [ + "updatedAt", + "uptime" + ], + "properties": { + "gitStatus": { + "$ref": "#/definitions/GitStatus" + }, + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" } } }, @@ -5244,12 +5244,12 @@ const docTemplate = `{ "type": "string", "enum": [ "client", - "project", + "workspace", "target" ], "x-enum-varnames": [ "ApiKeyTypeClient", - "ApiKeyTypeProject", + "ApiKeyTypeWorkspace", "ApiKeyTypeTarget" ] }, diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 506c4daaf6..c0bb7a5529 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -918,73 +918,72 @@ } } }, - "/project-config": { + "/provider": { "get": { - "description": "List project configs", + "description": "List providers", "produces": [ "application/json" ], "tags": [ - "project-config" + "provider" ], - "summary": "List project configs", - "operationId": "ListProjectConfigs", + "summary": "List providers", + "operationId": "ListProviders", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/ProjectConfig" + "$ref": "#/definitions/Provider" } } } } - }, - "put": { - "description": "Set project config data", + } + }, + "/provider/install": { + "post": { + "description": "Install a provider", "consumes": [ "application/json" ], "tags": [ - "project-config" + "provider" ], - "summary": "Set project config data", - "operationId": "SetProjectConfig", + "summary": "Install a provider", + "operationId": "InstallProvider", "parameters": [ { - "description": "Project config", - "name": "projectConfig", + "description": "Provider to install", + "name": "provider", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateProjectConfigDTO" + "$ref": "#/definitions/InstallProviderRequest" } } ], "responses": { - "201": { - "description": "Created" + "200": { + "description": "OK" } } } }, - "/project-config/default/{gitUrl}": { + "/provider/{provider}/target-config-manifest": { "get": { - "description": "Get project configs by git url", - "produces": [ - "application/json" - ], + "description": "Get provider target config manifest", "tags": [ - "project-config" + "provider" ], - "summary": "Get project configs by git url", - "operationId": "GetDefaultProjectConfig", + "summary": "Get provider target config manifest", + "operationId": "GetTargetConfigManifest", "parameters": [ { "type": "string", - "description": "Git URL", - "name": "gitUrl", + "description": "Provider name", + "name": "provider", "in": "path", "required": true } @@ -993,138 +992,179 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProjectConfig" + "$ref": "#/definitions/TargetConfigManifest" } } } } }, - "/project-config/prebuild": { - "get": { - "description": "List prebuilds", + "/provider/{provider}/uninstall": { + "post": { + "description": "Uninstall a provider", "consumes": [ "application/json" ], "tags": [ - "prebuild" + "provider" ], - "summary": "List prebuilds", - "operationId": "ListPrebuilds", + "summary": "Uninstall a provider", + "operationId": "UninstallProvider", + "parameters": [ + { + "type": "string", + "description": "Provider to uninstall", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sample": { + "get": { + "description": "List samples", + "produces": [ + "application/json" + ], + "tags": [ + "sample" + ], + "summary": "List samples", + "operationId": "ListSamples", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/PrebuildDTO" + "$ref": "#/definitions/Sample" } } } } } }, - "/project-config/prebuild/process-git-event": { + "/server/config": { + "get": { + "description": "Get the server configuration", + "produces": [ + "application/json" + ], + "tags": [ + "server" + ], + "summary": "Get the server configuration", + "operationId": "GetConfig", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/ServerConfig" + } + } + } + }, "post": { - "description": "ProcessGitEvent", + "description": "Set the server configuration", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], "tags": [ - "prebuild" + "server" ], - "summary": "ProcessGitEvent", - "operationId": "ProcessGitEvent", + "summary": "Set the server configuration", + "operationId": "SetConfig", "parameters": [ { - "description": "Webhook event", - "name": "body", + "description": "Server configuration", + "name": "config", "in": "body", "required": true, "schema": { - "type": "object" + "$ref": "#/definitions/ServerConfig" } } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/ServerConfig" + } } } } }, - "/project-config/{configName}": { + "/server/logs": { "get": { - "description": "Get project config data", - "consumes": [ + "description": "List server log files", + "produces": [ "application/json" ], "tags": [ - "project-config" - ], - "summary": "Get project config data", - "operationId": "GetProjectConfig", - "parameters": [ - { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true - } + "server" ], + "summary": "List server log files", + "operationId": "GetServerLogFiles", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProjectConfig" + "type": "array", + "items": { + "type": "string" + } } } } - }, - "delete": { - "description": "Delete project config data", - "tags": [ - "project-config" + } + }, + "/server/network-key": { + "post": { + "description": "Generate a new authentication key", + "produces": [ + "application/json" ], - "summary": "Delete project config data", - "operationId": "DeleteProjectConfig", - "parameters": [ - { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Force", - "name": "force", - "in": "query" - } + "tags": [ + "server" ], + "summary": "Generate a new authentication key", + "operationId": "GenerateNetworkKey", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/NetworkKey" + } } } } }, - "/project-config/{configName}/prebuild": { + "/target": { "get": { - "description": "List prebuilds for project config", - "consumes": [ + "description": "List targets", + "produces": [ "application/json" ], "tags": [ - "prebuild" + "target" ], - "summary": "List prebuilds for project config", - "operationId": "ListPrebuildsForProjectConfig", + "summary": "List targets", + "operationId": "ListTargets", "parameters": [ { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" } ], "responses": { @@ -1133,116 +1173,106 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/PrebuildDTO" + "$ref": "#/definitions/TargetDTO" } } } } }, - "put": { - "description": "Set prebuild", - "consumes": [ + "post": { + "description": "Create a target", + "produces": [ "application/json" ], "tags": [ - "prebuild" + "target" ], - "summary": "Set prebuild", - "operationId": "SetPrebuild", + "summary": "Create a target", + "operationId": "CreateTarget", "parameters": [ { - "type": "string", - "description": "Config name", - "name": "configName", - "in": "path", - "required": true - }, - { - "description": "Prebuild", - "name": "prebuild", + "description": "Create target", + "name": "target", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreatePrebuildDTO" + "$ref": "#/definitions/CreateTargetDTO" } } ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "schema": { - "type": "string" + "$ref": "#/definitions/Target" } } } } }, - "/project-config/{configName}/prebuild/{prebuildId}": { + "/target-config": { "get": { - "description": "Get prebuild", - "consumes": [ + "description": "List target configs", + "produces": [ "application/json" ], "tags": [ - "prebuild" - ], - "summary": "Get prebuild", - "operationId": "GetPrebuild", - "parameters": [ - { - "type": "string", - "description": "Project config name", - "name": "configName", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Prebuild ID", - "name": "prebuildId", - "in": "path", - "required": true - } + "target-config" ], + "summary": "List target configs", + "operationId": "ListTargetConfigs", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/PrebuildDTO" - } - } - } + "type": "array", + "items": { + "$ref": "#/definitions/TargetConfig" + } + } + } + } }, - "delete": { - "description": "Delete prebuild", - "consumes": [ - "application/json" + "put": { + "description": "Set a target config", + "tags": [ + "target-config" ], + "summary": "Set a target config", + "operationId": "SetTargetConfig", + "parameters": [ + { + "description": "Target config to set", + "name": "targetConfig", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateTargetConfigDTO" + } + } + ], + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/target-config/{configName}": { + "delete": { + "description": "Remove a target config", "tags": [ - "prebuild" + "target-config" ], - "summary": "Delete prebuild", - "operationId": "DeletePrebuild", + "summary": "Remove a target config", + "operationId": "RemoveTargetConfig", "parameters": [ { "type": "string", - "description": "Project config name", + "description": "Target Config name", "name": "configName", "in": "path", "required": true - }, - { - "type": "string", - "description": "Prebuild ID", - "name": "prebuildId", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Force", - "name": "force", - "in": "query" } ], "responses": { @@ -1252,18 +1282,18 @@ } } }, - "/project-config/{configName}/set-default": { + "/target-config/{configName}/set-default": { "patch": { - "description": "Set project config to default", + "description": "Set target config to default", "tags": [ - "project-config" + "target-config" ], - "summary": "Set project config to default", - "operationId": "SetDefaultProjectConfig", + "summary": "Set target config to default", + "operationId": "SetDefaultTargetConfig", "parameters": [ { "type": "string", - "description": "Config name", + "description": "Target config name", "name": "configName", "in": "path", "required": true @@ -1276,50 +1306,61 @@ } } }, - "/provider": { + "/target/{targetId}": { "get": { - "description": "List providers", + "description": "Get target info", "produces": [ "application/json" ], "tags": [ - "provider" + "target" + ], + "summary": "Get target info", + "operationId": "GetTarget", + "parameters": [ + { + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" + } ], - "summary": "List providers", - "operationId": "ListProviders", "responses": { "200": { "description": "OK", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Provider" - } + "$ref": "#/definitions/TargetDTO" } } } - } - }, - "/provider/install": { - "post": { - "description": "Install a provider", - "consumes": [ - "application/json" - ], + }, + "delete": { + "description": "Remove target", "tags": [ - "provider" + "target" ], - "summary": "Install a provider", - "operationId": "InstallProvider", + "summary": "Remove target", + "operationId": "RemoveTarget", "parameters": [ { - "description": "Provider to install", - "name": "provider", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/InstallProviderRequest" - } + "type": "string", + "description": "Target ID", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" } ], "responses": { @@ -1329,49 +1370,43 @@ } } }, - "/provider/{provider}/target-config-manifest": { - "get": { - "description": "Get provider target config manifest", + "/target/{targetId}/start": { + "post": { + "description": "Start target", "tags": [ - "provider" + "target" ], - "summary": "Get provider target config manifest", - "operationId": "GetTargetConfigManifest", + "summary": "Start target", + "operationId": "StartTarget", "parameters": [ { "type": "string", - "description": "Provider name", - "name": "provider", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/TargetConfigManifest" - } + "description": "OK" } } } }, - "/provider/{provider}/uninstall": { + "/target/{targetId}/stop": { "post": { - "description": "Uninstall a provider", - "consumes": [ - "application/json" - ], + "description": "Stop target", "tags": [ - "provider" + "target" ], - "summary": "Uninstall a provider", - "operationId": "UninstallProvider", + "summary": "Stop target", + "operationId": "StopTarget", "parameters": [ { "type": "string", - "description": "Provider to uninstall", - "name": "provider", + "description": "Target ID or Name", + "name": "targetId", "in": "path", "required": true } @@ -1383,229 +1418,149 @@ } } }, - "/sample": { - "get": { - "description": "List samples", - "produces": [ - "application/json" - ], - "tags": [ - "sample" - ], - "summary": "List samples", - "operationId": "ListSamples", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/Sample" - } - } - } - } - } - }, - "/server/config": { - "get": { - "description": "Get the server configuration", - "produces": [ - "application/json" - ], - "tags": [ - "server" - ], - "summary": "Get the server configuration", - "operationId": "GetConfig", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ServerConfig" - } - } - } - }, + "/target/{targetId}/{workspaceId}/start": { "post": { - "description": "Set the server configuration", - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], + "description": "Start workspace", "tags": [ - "server" + "target" ], - "summary": "Set the server configuration", - "operationId": "SetConfig", + "summary": "Start workspace", + "operationId": "StartWorkspace", "parameters": [ { - "description": "Server configuration", - "name": "config", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/ServerConfig" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ServerConfig" - } + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true } - } - } - }, - "/server/logs": { - "get": { - "description": "List server log files", - "produces": [ - "application/json" ], - "tags": [ - "server" - ], - "summary": "List server log files", - "operationId": "GetServerLogFiles", "responses": { "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "type": "string" - } - } + "description": "OK" } } } }, - "/server/network-key": { + "/target/{targetId}/{workspaceId}/state": { "post": { - "description": "Generate a new authentication key", - "produces": [ - "application/json" - ], - "tags": [ - "server" - ], - "summary": "Generate a new authentication key", - "operationId": "GenerateNetworkKey", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/NetworkKey" - } - } - } - } - }, - "/target": { - "get": { - "description": "List targets", - "produces": [ - "application/json" - ], + "description": "Set workspace state", "tags": [ "target" ], - "summary": "List targets", - "operationId": "ListTargets", + "summary": "Set workspace state", + "operationId": "SetWorkspaceState", "parameters": [ { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "description": "Set State", + "name": "setState", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetWorkspaceState" + } } ], "responses": { "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/TargetDTO" - } - } + "description": "OK" } } - }, + } + }, + "/target/{targetId}/{workspaceId}/stop": { "post": { - "description": "Create a target", - "produces": [ - "application/json" - ], + "description": "Stop workspace", "tags": [ "target" ], - "summary": "Create a target", - "operationId": "CreateTarget", + "summary": "Stop workspace", + "operationId": "StopWorkspace", "parameters": [ { - "description": "Create target", - "name": "target", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/CreateTargetDTO" - } + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true } ], "responses": { "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/Target" - } + "description": "OK" } } } }, - "/target-config": { + "/workspace-config": { "get": { - "description": "List target configs", + "description": "List workspace configs", "produces": [ "application/json" ], "tags": [ - "target-config" + "workspace-config" ], - "summary": "List target configs", - "operationId": "ListTargetConfigs", + "summary": "List workspace configs", + "operationId": "ListWorkspaceConfigs", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/TargetConfig" + "$ref": "#/definitions/WorkspaceConfig" } } } } }, "put": { - "description": "Set a target config", + "description": "Set workspace config data", + "consumes": [ + "application/json" + ], "tags": [ - "target-config" + "workspace-config" ], - "summary": "Set a target config", - "operationId": "SetTargetConfig", + "summary": "Set workspace config data", + "operationId": "SetWorkspaceConfig", "parameters": [ { - "description": "Target config to set", - "name": "targetConfig", + "description": "Workspace config", + "name": "workspaceConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateTargetConfigDTO" + "$ref": "#/definitions/CreateWorkspaceConfigDTO" } } ], @@ -1616,45 +1571,77 @@ } } }, - "/target-config/{configName}": { - "delete": { - "description": "Remove a target config", + "/workspace-config/default/{gitUrl}": { + "get": { + "description": "Get workspace configs by git url", + "produces": [ + "application/json" + ], "tags": [ - "target-config" + "workspace-config" ], - "summary": "Remove a target config", - "operationId": "RemoveTargetConfig", + "summary": "Get workspace configs by git url", + "operationId": "GetDefaultWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target Config name", - "name": "configName", + "description": "Git URL", + "name": "gitUrl", "in": "path", "required": true } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceConfig" + } } } } }, - "/target-config/{configName}/set-default": { - "patch": { - "description": "Set target config to default", + "/workspace-config/prebuild": { + "get": { + "description": "List prebuilds", + "consumes": [ + "application/json" + ], "tags": [ - "target-config" + "prebuild" ], - "summary": "Set target config to default", - "operationId": "SetDefaultTargetConfig", + "summary": "List prebuilds", + "operationId": "ListPrebuilds", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildDTO" + } + } + } + } + } + }, + "/workspace-config/prebuild/process-git-event": { + "post": { + "description": "ProcessGitEvent", + "tags": [ + "prebuild" + ], + "summary": "ProcessGitEvent", + "operationId": "ProcessGitEvent", "parameters": [ { - "type": "string", - "description": "Target config name", - "name": "configName", - "in": "path", - "required": true + "description": "Webhook event", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object" + } } ], "responses": { @@ -1664,53 +1651,47 @@ } } }, - "/target/{targetId}": { + "/workspace-config/{configName}": { "get": { - "description": "Get target info", - "produces": [ + "description": "Get workspace config data", + "consumes": [ "application/json" ], "tags": [ - "target" + "workspace-config" ], - "summary": "Get target info", - "operationId": "GetTarget", + "summary": "Get workspace config data", + "operationId": "GetWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true - }, - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/TargetDTO" + "$ref": "#/definitions/WorkspaceConfig" } } } }, "delete": { - "description": "Remove target", + "description": "Delete workspace config data", "tags": [ - "target" + "workspace-config" ], - "summary": "Remove target", - "operationId": "RemoveTarget", + "summary": "Delete workspace config data", + "operationId": "DeleteWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true }, @@ -1722,151 +1703,170 @@ } ], "responses": { - "200": { - "description": "OK" + "204": { + "description": "No Content" } } } }, - "/target/{targetId}/start": { - "post": { - "description": "Start target", + "/workspace-config/{configName}/prebuild": { + "get": { + "description": "List prebuilds for workspace config", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Start target", - "operationId": "StartTarget", + "summary": "List prebuilds for workspace config", + "operationId": "ListPrebuildsForWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildDTO" + } + } } } - } - }, - "/target/{targetId}/stop": { - "post": { - "description": "Stop target", + }, + "put": { + "description": "Set prebuild", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Stop target", - "operationId": "StopTarget", + "summary": "Set prebuild", + "operationId": "SetPrebuild", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Config name", + "name": "configName", "in": "path", "required": true + }, + { + "description": "Prebuild", + "name": "prebuild", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreatePrebuildDTO" + } } ], "responses": { - "200": { - "description": "OK" + "201": { + "description": "Created", + "schema": { + "type": "string" + } } } } }, - "/target/{targetId}/{projectId}/start": { - "post": { - "description": "Start project", + "/workspace-config/{configName}/prebuild/{prebuildId}": { + "get": { + "description": "Get prebuild", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Start project", - "operationId": "StartProject", + "summary": "Get prebuild", + "operationId": "GetPrebuild", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Workspace config name", + "name": "configName", "in": "path", "required": true }, { "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Prebuild ID", + "name": "prebuildId", "in": "path", "required": true } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/PrebuildDTO" + } } } - } - }, - "/target/{targetId}/{projectId}/state": { - "post": { - "description": "Set project state", + }, + "delete": { + "description": "Delete prebuild", + "consumes": [ + "application/json" + ], "tags": [ - "target" + "prebuild" ], - "summary": "Set project state", - "operationId": "SetProjectState", + "summary": "Delete prebuild", + "operationId": "DeletePrebuild", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", + "description": "Workspace config name", + "name": "configName", "in": "path", "required": true }, { "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Prebuild ID", + "name": "prebuildId", "in": "path", - "required": true - }, - { - "description": "Set State", - "name": "setState", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/SetProjectState" - } + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" } ], "responses": { - "200": { - "description": "OK" + "204": { + "description": "No Content" } } } }, - "/target/{targetId}/{projectId}/stop": { - "post": { - "description": "Stop project", + "/workspace-config/{configName}/set-default": { + "patch": { + "description": "Set workspace config to default", "tags": [ - "target" + "workspace-config" ], - "summary": "Stop project", - "operationId": "StopProject", + "summary": "Set workspace config to default", + "operationId": "SetDefaultWorkspaceConfig", "parameters": [ { "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Config name", + "name": "configName", "in": "path", "required": true } @@ -3411,17 +3411,17 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/project-dir": { + "/workspace/{workspaceId}/{projectId}/toolbox/workspace-dir": { "get": { - "description": "Get project directory", + "description": "Get workspace directory", "produces": [ "application/json" ], "tags": [ "workspace toolbox" ], - "summary": "Get project dir", - "operationId": "GetProjectDir", + "summary": "Get workspace dir", + "operationId": "GetWorkspaceDir", "parameters": [ { "type": "string", @@ -3442,7 +3442,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/ProjectDirResponse" + "$ref": "#/definitions/WorkspaceDirResponse" } } } @@ -3462,7 +3462,7 @@ "type": "string" }, "name": { - "description": "Project or client name", + "description": "Workspace or client name", "type": "string" }, "type": { @@ -3674,7 +3674,7 @@ "required": [ "branch", "envVars", - "projectConfigName" + "workspaceConfigName" ], "properties": { "branch": { @@ -3689,7 +3689,7 @@ "prebuildId": { "type": "string" }, - "projectConfigName": { + "workspaceConfigName": { "type": "string" } } @@ -3720,7 +3720,63 @@ } } }, - "CreateProjectConfigDTO": { + "CreateSessionRequest": { + "type": "object", + "required": [ + "sessionId" + ], + "properties": { + "sessionId": { + "type": "string" + } + } + }, + "CreateTargetConfigDTO": { + "type": "object", + "required": [ + "name", + "options", + "providerInfo" + ], + "properties": { + "name": { + "type": "string" + }, + "options": { + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/provider.ProviderInfo" + } + } + }, + "CreateTargetDTO": { + "type": "object", + "required": [ + "id", + "name", + "targetConfig", + "workspaces" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "targetConfig": { + "type": "string" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/CreateWorkspaceDTO" + } + } + } + }, + "CreateWorkspaceConfigDTO": { "type": "object", "required": [ "envVars", @@ -3754,7 +3810,7 @@ } } }, - "CreateProjectDTO": { + "CreateWorkspaceDTO": { "type": "object", "required": [ "envVars", @@ -3781,14 +3837,14 @@ "type": "string" }, "source": { - "$ref": "#/definitions/CreateProjectSourceDTO" + "$ref": "#/definitions/CreateWorkspaceSourceDTO" }, "user": { "type": "string" } } }, - "CreateProjectSourceDTO": { + "CreateWorkspaceSourceDTO": { "type": "object", "required": [ "repository" @@ -3799,62 +3855,6 @@ } } }, - "CreateSessionRequest": { - "type": "object", - "required": [ - "sessionId" - ], - "properties": { - "sessionId": { - "type": "string" - } - } - }, - "CreateTargetConfigDTO": { - "type": "object", - "required": [ - "name", - "options", - "providerInfo" - ], - "properties": { - "name": { - "type": "string" - }, - "options": { - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" - } - } - }, - "CreateTargetDTO": { - "type": "object", - "required": [ - "id", - "name", - "projects", - "targetConfig" - ], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "projects": { - "type": "array", - "items": { - "$ref": "#/definitions/CreateProjectDTO" - } - }, - "targetConfig": { - "type": "string" - } - } - }, "DevcontainerConfig": { "type": "object", "required": [ @@ -4563,237 +4563,92 @@ }, "Position": { "type": "object", - "required": [ - "character", - "line" - ], - "properties": { - "character": { - "type": "integer" - }, - "line": { - "type": "integer" - } - } - }, - "PrebuildConfig": { - "type": "object", - "required": [ - "branch", - "commitInterval", - "id", - "retention", - "triggerFiles" - ], - "properties": { - "branch": { - "type": "string" - }, - "commitInterval": { - "type": "integer" - }, - "id": { - "type": "string" - }, - "retention": { - "type": "integer" - }, - "triggerFiles": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "PrebuildDTO": { - "type": "object", - "required": [ - "branch", - "id", - "projectConfigName", - "retention" - ], - "properties": { - "branch": { - "type": "string" - }, - "commitInterval": { - "type": "integer" - }, - "id": { - "type": "string" - }, - "projectConfigName": { - "type": "string" - }, - "retention": { - "type": "integer" - }, - "triggerFiles": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "ProfileData": { - "type": "object", - "required": [ - "envVars" - ], - "properties": { - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - } - }, - "Project": { - "type": "object", - "required": [ - "envVars", - "image", - "name", - "repository", - "targetConfig", - "targetId", - "user" - ], - "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { - "type": "string" - }, - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "repository": { - "$ref": "#/definitions/GitRepository" - }, - "state": { - "$ref": "#/definitions/ProjectState" - }, - "targetConfig": { - "type": "string" - }, - "targetId": { - "type": "string" + "required": [ + "character", + "line" + ], + "properties": { + "character": { + "type": "integer" }, - "user": { - "type": "string" + "line": { + "type": "integer" } } }, - "ProjectConfig": { + "PrebuildConfig": { "type": "object", "required": [ - "default", - "envVars", - "image", - "name", - "repositoryUrl", - "user" + "branch", + "commitInterval", + "id", + "retention", + "triggerFiles" ], "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "default": { - "type": "boolean" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { + "branch": { "type": "string" }, - "image": { - "type": "string" + "commitInterval": { + "type": "integer" }, - "name": { + "id": { "type": "string" }, - "prebuilds": { + "retention": { + "type": "integer" + }, + "triggerFiles": { "type": "array", "items": { - "$ref": "#/definitions/PrebuildConfig" + "type": "string" } - }, - "repositoryUrl": { - "type": "string" - }, - "user": { - "type": "string" } } }, - "ProjectDirResponse": { - "type": "object", - "properties": { - "dir": { - "type": "string" - } - } - }, - "ProjectInfo": { + "PrebuildDTO": { "type": "object", "required": [ - "created", - "isRunning", - "name", - "targetId" + "branch", + "id", + "retention", + "workspaceConfigName" ], "properties": { - "created": { + "branch": { "type": "string" }, - "isRunning": { - "type": "boolean" + "commitInterval": { + "type": "integer" }, - "name": { + "id": { "type": "string" }, - "providerMetadata": { - "type": "string" + "retention": { + "type": "integer" }, - "targetId": { + "triggerFiles": { + "type": "array", + "items": { + "type": "string" + } + }, + "workspaceConfigName": { "type": "string" } } }, - "ProjectState": { + "ProfileData": { "type": "object", "required": [ - "updatedAt", - "uptime" + "envVars" ], "properties": { - "gitStatus": { - "$ref": "#/definitions/GitStatus" - }, - "updatedAt": { - "type": "string" - }, - "uptime": { - "type": "integer" + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } } } }, @@ -4902,8 +4757,8 @@ "binariesPath", "builderImage", "builderRegistryServer", - "defaultProjectImage", - "defaultProjectUser", + "defaultWorkspaceImage", + "defaultWorkspaceUser", "headscalePort", "id", "localBuilderRegistryImage", @@ -4929,10 +4784,10 @@ "builderRegistryServer": { "type": "string" }, - "defaultProjectImage": { + "defaultWorkspaceImage": { "type": "string" }, - "defaultProjectUser": { + "defaultWorkspaceUser": { "type": "string" }, "frps": { @@ -5046,7 +4901,7 @@ } } }, - "SetProjectState": { + "SetWorkspaceState": { "type": "object", "required": [ "uptime" @@ -5099,8 +4954,8 @@ "required": [ "id", "name", - "projects", - "targetConfig" + "targetConfig", + "workspaces" ], "properties": { "id": { @@ -5109,14 +4964,14 @@ "name": { "type": "string" }, - "projects": { + "targetConfig": { + "type": "string" + }, + "workspaces": { "type": "array", "items": { - "$ref": "#/definitions/Project" + "$ref": "#/definitions/Workspace" } - }, - "targetConfig": { - "type": "string" } } }, @@ -5192,8 +5047,8 @@ "required": [ "id", "name", - "projects", - "targetConfig" + "targetConfig", + "workspaces" ], "properties": { "id": { @@ -5205,35 +5060,180 @@ "name": { "type": "string" }, - "projects": { + "targetConfig": { + "type": "string" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/Workspace" + } + } + } + }, + "TargetInfo": { + "type": "object", + "required": [ + "name", + "workspaces" + ], + "properties": { + "name": { + "type": "string" + }, + "providerMetadata": { + "type": "string" + }, + "workspaces": { "type": "array", "items": { - "$ref": "#/definitions/Project" + "$ref": "#/definitions/WorkspaceInfo" + } + } + } + }, + "Workspace": { + "type": "object", + "required": [ + "envVars", + "image", + "name", + "repository", + "targetConfig", + "targetId", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" } }, + "gitProviderConfigId": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repository": { + "$ref": "#/definitions/GitRepository" + }, + "state": { + "$ref": "#/definitions/WorkspaceState" + }, "targetConfig": { "type": "string" + }, + "targetId": { + "type": "string" + }, + "user": { + "type": "string" } } }, - "TargetInfo": { + "WorkspaceConfig": { "type": "object", "required": [ + "default", + "envVars", + "image", "name", - "projects" + "repositoryUrl", + "user" ], "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "default": { + "type": "boolean" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "image": { + "type": "string" + }, "name": { "type": "string" }, - "projects": { + "prebuilds": { "type": "array", "items": { - "$ref": "#/definitions/ProjectInfo" + "$ref": "#/definitions/PrebuildConfig" } }, + "repositoryUrl": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, + "WorkspaceDirResponse": { + "type": "object", + "properties": { + "dir": { + "type": "string" + } + } + }, + "WorkspaceInfo": { + "type": "object", + "required": [ + "created", + "isRunning", + "name", + "targetId" + ], + "properties": { + "created": { + "type": "string" + }, + "isRunning": { + "type": "boolean" + }, + "name": { + "type": "string" + }, "providerMetadata": { "type": "string" + }, + "targetId": { + "type": "string" + } + } + }, + "WorkspaceState": { + "type": "object", + "required": [ + "updatedAt", + "uptime" + ], + "properties": { + "gitStatus": { + "$ref": "#/definitions/GitStatus" + }, + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" } } }, @@ -5241,12 +5241,12 @@ "type": "string", "enum": [ "client", - "project", + "workspace", "target" ], "x-enum-varnames": [ "ApiKeyTypeClient", - "ApiKeyTypeProject", + "ApiKeyTypeWorkspace", "ApiKeyTypeTarget" ] }, diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 51f2701f9f..f94c15bbcc 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -5,7 +5,7 @@ definitions: keyHash: type: string name: - description: Project or client name + description: Workspace or client name type: string type: $ref: '#/definitions/apikey.ApiKeyType' @@ -159,12 +159,12 @@ definitions: type: object prebuildId: type: string - projectConfigName: + workspaceConfigName: type: string required: - branch - envVars - - projectConfigName + - workspaceConfigName type: object CreatePrebuildDTO: properties: @@ -183,7 +183,45 @@ definitions: required: - retention type: object - CreateProjectConfigDTO: + CreateSessionRequest: + properties: + sessionId: + type: string + required: + - sessionId + type: object + CreateTargetConfigDTO: + properties: + name: + type: string + options: + type: string + providerInfo: + $ref: '#/definitions/provider.ProviderInfo' + required: + - name + - options + - providerInfo + type: object + CreateTargetDTO: + properties: + id: + type: string + name: + type: string + targetConfig: + type: string + workspaces: + items: + $ref: '#/definitions/CreateWorkspaceDTO' + type: array + required: + - id + - name + - targetConfig + - workspaces + type: object + CreateWorkspaceConfigDTO: properties: buildConfig: $ref: '#/definitions/BuildConfig' @@ -206,7 +244,7 @@ definitions: - name - repositoryUrl type: object - CreateProjectDTO: + CreateWorkspaceDTO: properties: buildConfig: $ref: '#/definitions/BuildConfig' @@ -221,7 +259,7 @@ definitions: name: type: string source: - $ref: '#/definitions/CreateProjectSourceDTO' + $ref: '#/definitions/CreateWorkspaceSourceDTO' user: type: string required: @@ -229,51 +267,13 @@ definitions: - name - source type: object - CreateProjectSourceDTO: + CreateWorkspaceSourceDTO: properties: repository: $ref: '#/definitions/GitRepository' required: - repository type: object - CreateSessionRequest: - properties: - sessionId: - type: string - required: - - sessionId - type: object - CreateTargetConfigDTO: - properties: - name: - type: string - options: - type: string - providerInfo: - $ref: '#/definitions/provider.ProviderInfo' - required: - - name - - options - - providerInfo - type: object - CreateTargetDTO: - properties: - id: - type: string - name: - type: string - projects: - items: - $ref: '#/definitions/CreateProjectDTO' - type: array - targetConfig: - type: string - required: - - id - - name - - projects - - targetConfig - type: object DevcontainerConfig: properties: filePath: @@ -794,19 +794,19 @@ definitions: type: integer id: type: string - projectConfigName: - type: string retention: type: integer triggerFiles: items: type: string type: array + workspaceConfigName: + type: string required: - branch - id - - projectConfigName - retention + - workspaceConfigName type: object ProfileData: properties: @@ -817,106 +817,6 @@ definitions: required: - envVars type: object - Project: - properties: - buildConfig: - $ref: '#/definitions/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - repository: - $ref: '#/definitions/GitRepository' - state: - $ref: '#/definitions/ProjectState' - targetConfig: - type: string - targetId: - type: string - user: - type: string - required: - - envVars - - image - - name - - repository - - targetConfig - - targetId - - user - type: object - ProjectConfig: - properties: - buildConfig: - $ref: '#/definitions/BuildConfig' - default: - type: boolean - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - prebuilds: - items: - $ref: '#/definitions/PrebuildConfig' - type: array - repositoryUrl: - type: string - user: - type: string - required: - - default - - envVars - - image - - name - - repositoryUrl - - user - type: object - ProjectDirResponse: - properties: - dir: - type: string - type: object - ProjectInfo: - properties: - created: - type: string - isRunning: - type: boolean - name: - type: string - providerMetadata: - type: string - targetId: - type: string - required: - - created - - isRunning - - name - - targetId - type: object - ProjectState: - properties: - gitStatus: - $ref: '#/definitions/GitStatus' - updatedAt: - type: string - uptime: - type: integer - required: - - updatedAt - - uptime - type: object Provider: properties: label: @@ -994,9 +894,9 @@ definitions: type: string builderRegistryServer: type: string - defaultProjectImage: + defaultWorkspaceImage: type: string - defaultProjectUser: + defaultWorkspaceUser: type: string frps: $ref: '#/definitions/FRPSConfig' @@ -1023,8 +923,8 @@ definitions: - binariesPath - builderImage - builderRegistryServer - - defaultProjectImage - - defaultProjectUser + - defaultWorkspaceImage + - defaultWorkspaceUser - headscalePort - id - localBuilderRegistryImage @@ -1086,7 +986,7 @@ definitions: - providerId - token type: object - SetProjectState: + SetWorkspaceState: properties: gitStatus: $ref: '#/definitions/GitStatus' @@ -1129,17 +1029,17 @@ definitions: type: string name: type: string - projects: - items: - $ref: '#/definitions/Project' - type: array targetConfig: type: string + workspaces: + items: + $ref: '#/definitions/Workspace' + type: array required: - id - name - - projects - targetConfig + - workspaces type: object TargetConfig: properties: @@ -1202,97 +1102,197 @@ definitions: $ref: '#/definitions/TargetInfo' name: type: string - projects: - items: - $ref: '#/definitions/Project' - type: array targetConfig: type: string + workspaces: + items: + $ref: '#/definitions/Workspace' + type: array required: - id - name - - projects - targetConfig + - workspaces type: object TargetInfo: properties: name: type: string - projects: - items: - $ref: '#/definitions/ProjectInfo' - type: array providerMetadata: type: string + workspaces: + items: + $ref: '#/definitions/WorkspaceInfo' + type: array required: - name - - projects + - workspaces type: object - apikey.ApiKeyType: - enum: - - client - - project - - target - type: string - x-enum-varnames: - - ApiKeyTypeClient - - ApiKeyTypeProject - - ApiKeyTypeTarget - build.BuildState: - enum: - - pending-run - - running - - error - - success - - published - - pending-delete - - pending-forced-delete - - deleting - type: string - x-enum-varnames: - - BuildStatePendingRun - - BuildStateRunning - - BuildStateError - - BuildStateSuccess - - BuildStatePublished - - BuildStatePendingDelete - - BuildStatePendingForcedDelete - - BuildStateDeleting - provider.ProviderInfo: + Workspace: properties: - label: + buildConfig: + $ref: '#/definitions/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: type: string name: type: string - version: + repository: + $ref: '#/definitions/GitRepository' + state: + $ref: '#/definitions/WorkspaceState' + targetConfig: + type: string + targetId: + type: string + user: type: string required: + - envVars + - image - name - - version + - repository + - targetConfig + - targetId + - user type: object - provider.TargetConfigPropertyType: - enum: - - string - - option - - boolean - - int - - float - - file-path - type: string - x-enum-varnames: - - TargetConfigPropertyTypeString - - TargetConfigPropertyTypeOption - - TargetConfigPropertyTypeBoolean - - TargetConfigPropertyTypeInt - - TargetConfigPropertyTypeFloat - - TargetConfigPropertyTypeFilePath -host: localhost:3986 -info: - contact: {} - description: Daytona Server API - title: Daytona Server API - version: v0.0.0-dev -paths: + WorkspaceConfig: + properties: + buildConfig: + $ref: '#/definitions/BuildConfig' + default: + type: boolean + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + prebuilds: + items: + $ref: '#/definitions/PrebuildConfig' + type: array + repositoryUrl: + type: string + user: + type: string + required: + - default + - envVars + - image + - name + - repositoryUrl + - user + type: object + WorkspaceDirResponse: + properties: + dir: + type: string + type: object + WorkspaceInfo: + properties: + created: + type: string + isRunning: + type: boolean + name: + type: string + providerMetadata: + type: string + targetId: + type: string + required: + - created + - isRunning + - name + - targetId + type: object + WorkspaceState: + properties: + gitStatus: + $ref: '#/definitions/GitStatus' + updatedAt: + type: string + uptime: + type: integer + required: + - updatedAt + - uptime + type: object + apikey.ApiKeyType: + enum: + - client + - workspace + - target + type: string + x-enum-varnames: + - ApiKeyTypeClient + - ApiKeyTypeWorkspace + - ApiKeyTypeTarget + build.BuildState: + enum: + - pending-run + - running + - error + - success + - published + - pending-delete + - pending-forced-delete + - deleting + type: string + x-enum-varnames: + - BuildStatePendingRun + - BuildStateRunning + - BuildStateError + - BuildStateSuccess + - BuildStatePublished + - BuildStatePendingDelete + - BuildStatePendingForcedDelete + - BuildStateDeleting + provider.ProviderInfo: + properties: + label: + type: string + name: + type: string + version: + type: string + required: + - name + - version + type: object + provider.TargetConfigPropertyType: + enum: + - string + - option + - boolean + - int + - float + - file-path + type: string + x-enum-varnames: + - TargetConfigPropertyTypeString + - TargetConfigPropertyTypeOption + - TargetConfigPropertyTypeBoolean + - TargetConfigPropertyTypeInt + - TargetConfigPropertyTypeFloat + - TargetConfigPropertyTypeFilePath +host: localhost:3986 +info: + contact: {} + description: Daytona Server API + title: Daytona Server API + version: v0.0.0-dev +paths: /apikey: get: description: List API keys @@ -1900,10 +1900,10 @@ paths: summary: Set profile data tags: - profile - /project-config: + /provider: get: - description: List project configs - operationId: ListProjectConfigs + description: List providers + operationId: ListProviders produces: - application/json responses: @@ -1911,356 +1911,116 @@ paths: description: OK schema: items: - $ref: '#/definitions/ProjectConfig' + $ref: '#/definitions/Provider' type: array - summary: List project configs - tags: - - project-config - put: - consumes: - - application/json - description: Set project config data - operationId: SetProjectConfig - parameters: - - description: Project config - in: body - name: projectConfig - required: true - schema: - $ref: '#/definitions/CreateProjectConfigDTO' - responses: - "201": - description: Created - summary: Set project config data + summary: List providers tags: - - project-config - /project-config/{configName}: - delete: - description: Delete project config data - operationId: DeleteProjectConfig + - provider + /provider/{provider}/target-config-manifest: + get: + description: Get provider target config manifest + operationId: GetTargetConfigManifest parameters: - - description: Config name + - description: Provider name in: path - name: configName + name: provider required: true type: string - - description: Force - in: query - name: force - type: boolean responses: - "204": - description: No Content - summary: Delete project config data + "200": + description: OK + schema: + $ref: '#/definitions/TargetConfigManifest' + summary: Get provider target config manifest tags: - - project-config - get: + - provider + /provider/{provider}/uninstall: + post: consumes: - application/json - description: Get project config data - operationId: GetProjectConfig + description: Uninstall a provider + operationId: UninstallProvider parameters: - - description: Config name + - description: Provider to uninstall in: path - name: configName + name: provider required: true type: string responses: "200": description: OK - schema: - $ref: '#/definitions/ProjectConfig' - summary: Get project config data + summary: Uninstall a provider tags: - - project-config - /project-config/{configName}/prebuild: - get: + - provider + /provider/install: + post: consumes: - application/json - description: List prebuilds for project config - operationId: ListPrebuildsForProjectConfig + description: Install a provider + operationId: InstallProvider parameters: - - description: Config name - in: path - name: configName + - description: Provider to install + in: body + name: provider required: true - type: string + schema: + $ref: '#/definitions/InstallProviderRequest' + responses: + "200": + description: OK + summary: Install a provider + tags: + - provider + /sample: + get: + description: List samples + operationId: ListSamples + produces: + - application/json responses: "200": description: OK schema: items: - $ref: '#/definitions/PrebuildDTO' + $ref: '#/definitions/Sample' type: array - summary: List prebuilds for project config + summary: List samples tags: - - prebuild - put: + - sample + /server/config: + get: + description: Get the server configuration + operationId: GetConfig + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/ServerConfig' + summary: Get the server configuration + tags: + - server + post: consumes: - application/json - description: Set prebuild - operationId: SetPrebuild + description: Set the server configuration + operationId: SetConfig parameters: - - description: Config name - in: path - name: configName - required: true - type: string - - description: Prebuild + - description: Server configuration in: body - name: prebuild + name: config required: true schema: - $ref: '#/definitions/CreatePrebuildDTO' + $ref: '#/definitions/ServerConfig' + produces: + - application/json responses: - "201": - description: Created + "200": + description: OK schema: - type: string - summary: Set prebuild - tags: - - prebuild - /project-config/{configName}/prebuild/{prebuildId}: - delete: - consumes: - - application/json - description: Delete prebuild - operationId: DeletePrebuild - parameters: - - description: Project config name - in: path - name: configName - required: true - type: string - - description: Prebuild ID - in: path - name: prebuildId - required: true - type: string - - description: Force - in: query - name: force - type: boolean - responses: - "204": - description: No Content - summary: Delete prebuild - tags: - - prebuild - get: - consumes: - - application/json - description: Get prebuild - operationId: GetPrebuild - parameters: - - description: Project config name - in: path - name: configName - required: true - type: string - - description: Prebuild ID - in: path - name: prebuildId - required: true - type: string - responses: - "200": - description: OK - schema: - $ref: '#/definitions/PrebuildDTO' - summary: Get prebuild - tags: - - prebuild - /project-config/{configName}/set-default: - patch: - description: Set project config to default - operationId: SetDefaultProjectConfig - parameters: - - description: Config name - in: path - name: configName - required: true - type: string - responses: - "200": - description: OK - summary: Set project config to default - tags: - - project-config - /project-config/default/{gitUrl}: - get: - description: Get project configs by git url - operationId: GetDefaultProjectConfig - parameters: - - description: Git URL - in: path - name: gitUrl - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/ProjectConfig' - summary: Get project configs by git url - tags: - - project-config - /project-config/prebuild: - get: - consumes: - - application/json - description: List prebuilds - operationId: ListPrebuilds - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/PrebuildDTO' - type: array - summary: List prebuilds - tags: - - prebuild - /project-config/prebuild/process-git-event: - post: - description: ProcessGitEvent - operationId: ProcessGitEvent - parameters: - - description: Webhook event - in: body - name: body - required: true - schema: - type: object - responses: - "200": - description: OK - summary: ProcessGitEvent - tags: - - prebuild - /provider: - get: - description: List providers - operationId: ListProviders - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/Provider' - type: array - summary: List providers - tags: - - provider - /provider/{provider}/target-config-manifest: - get: - description: Get provider target config manifest - operationId: GetTargetConfigManifest - parameters: - - description: Provider name - in: path - name: provider - required: true - type: string - responses: - "200": - description: OK - schema: - $ref: '#/definitions/TargetConfigManifest' - summary: Get provider target config manifest - tags: - - provider - /provider/{provider}/uninstall: - post: - consumes: - - application/json - description: Uninstall a provider - operationId: UninstallProvider - parameters: - - description: Provider to uninstall - in: path - name: provider - required: true - type: string - responses: - "200": - description: OK - summary: Uninstall a provider - tags: - - provider - /provider/install: - post: - consumes: - - application/json - description: Install a provider - operationId: InstallProvider - parameters: - - description: Provider to install - in: body - name: provider - required: true - schema: - $ref: '#/definitions/InstallProviderRequest' - responses: - "200": - description: OK - summary: Install a provider - tags: - - provider - /sample: - get: - description: List samples - operationId: ListSamples - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/Sample' - type: array - summary: List samples - tags: - - sample - /server/config: - get: - description: Get the server configuration - operationId: GetConfig - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/ServerConfig' - summary: Get the server configuration - tags: - - server - post: - consumes: - - application/json - description: Set the server configuration - operationId: SetConfig - parameters: - - description: Server configuration - in: body - name: config - required: true - schema: - $ref: '#/definitions/ServerConfig' - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/ServerConfig' - summary: Set the server configuration + $ref: '#/definitions/ServerConfig' + summary: Set the server configuration tags: - server /server/logs: @@ -2441,40 +2201,40 @@ paths: summary: Get target info tags: - target - /target/{targetId}/{projectId}/start: + /target/{targetId}/{workspaceId}/start: post: - description: Start project - operationId: StartProject + description: Start workspace + operationId: StartWorkspace parameters: - description: Target ID or Name in: path name: targetId required: true type: string - - description: Project ID + - description: Workspace ID in: path - name: projectId + name: workspaceId required: true type: string responses: "200": description: OK - summary: Start project + summary: Start workspace tags: - target - /target/{targetId}/{projectId}/state: + /target/{targetId}/{workspaceId}/state: post: - description: Set project state - operationId: SetProjectState + description: Set workspace state + operationId: SetWorkspaceState parameters: - description: Target ID or Name in: path name: targetId required: true type: string - - description: Project ID + - description: Workspace ID in: path - name: projectId + name: workspaceId required: true type: string - description: Set State @@ -2482,32 +2242,32 @@ paths: name: setState required: true schema: - $ref: '#/definitions/SetProjectState' + $ref: '#/definitions/SetWorkspaceState' responses: "200": description: OK - summary: Set project state + summary: Set workspace state tags: - target - /target/{targetId}/{projectId}/stop: + /target/{targetId}/{workspaceId}/stop: post: - description: Stop project - operationId: StopProject + description: Stop workspace + operationId: StopWorkspace parameters: - description: Target ID or Name in: path name: targetId required: true type: string - - description: Project ID + - description: Workspace ID in: path - name: projectId + name: workspaceId required: true type: string responses: "200": description: OK - summary: Stop project + summary: Stop workspace tags: - target /target/{targetId}/start: @@ -2542,6 +2302,246 @@ paths: summary: Stop target tags: - target + /workspace-config: + get: + description: List workspace configs + operationId: ListWorkspaceConfigs + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/WorkspaceConfig' + type: array + summary: List workspace configs + tags: + - workspace-config + put: + consumes: + - application/json + description: Set workspace config data + operationId: SetWorkspaceConfig + parameters: + - description: Workspace config + in: body + name: workspaceConfig + required: true + schema: + $ref: '#/definitions/CreateWorkspaceConfigDTO' + responses: + "201": + description: Created + summary: Set workspace config data + tags: + - workspace-config + /workspace-config/{configName}: + delete: + description: Delete workspace config data + operationId: DeleteWorkspaceConfig + parameters: + - description: Config name + in: path + name: configName + required: true + type: string + - description: Force + in: query + name: force + type: boolean + responses: + "204": + description: No Content + summary: Delete workspace config data + tags: + - workspace-config + get: + consumes: + - application/json + description: Get workspace config data + operationId: GetWorkspaceConfig + parameters: + - description: Config name + in: path + name: configName + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/WorkspaceConfig' + summary: Get workspace config data + tags: + - workspace-config + /workspace-config/{configName}/prebuild: + get: + consumes: + - application/json + description: List prebuilds for workspace config + operationId: ListPrebuildsForWorkspaceConfig + parameters: + - description: Config name + in: path + name: configName + required: true + type: string + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/PrebuildDTO' + type: array + summary: List prebuilds for workspace config + tags: + - prebuild + put: + consumes: + - application/json + description: Set prebuild + operationId: SetPrebuild + parameters: + - description: Config name + in: path + name: configName + required: true + type: string + - description: Prebuild + in: body + name: prebuild + required: true + schema: + $ref: '#/definitions/CreatePrebuildDTO' + responses: + "201": + description: Created + schema: + type: string + summary: Set prebuild + tags: + - prebuild + /workspace-config/{configName}/prebuild/{prebuildId}: + delete: + consumes: + - application/json + description: Delete prebuild + operationId: DeletePrebuild + parameters: + - description: Workspace config name + in: path + name: configName + required: true + type: string + - description: Prebuild ID + in: path + name: prebuildId + required: true + type: string + - description: Force + in: query + name: force + type: boolean + responses: + "204": + description: No Content + summary: Delete prebuild + tags: + - prebuild + get: + consumes: + - application/json + description: Get prebuild + operationId: GetPrebuild + parameters: + - description: Workspace config name + in: path + name: configName + required: true + type: string + - description: Prebuild ID + in: path + name: prebuildId + required: true + type: string + responses: + "200": + description: OK + schema: + $ref: '#/definitions/PrebuildDTO' + summary: Get prebuild + tags: + - prebuild + /workspace-config/{configName}/set-default: + patch: + description: Set workspace config to default + operationId: SetDefaultWorkspaceConfig + parameters: + - description: Config name + in: path + name: configName + required: true + type: string + responses: + "200": + description: OK + summary: Set workspace config to default + tags: + - workspace-config + /workspace-config/default/{gitUrl}: + get: + description: Get workspace configs by git url + operationId: GetDefaultWorkspaceConfig + parameters: + - description: Git URL + in: path + name: gitUrl + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/WorkspaceConfig' + summary: Get workspace configs by git url + tags: + - workspace-config + /workspace-config/prebuild: + get: + consumes: + - application/json + description: List prebuilds + operationId: ListPrebuilds + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/PrebuildDTO' + type: array + summary: List prebuilds + tags: + - prebuild + /workspace-config/prebuild/process-git-event: + post: + description: ProcessGitEvent + operationId: ProcessGitEvent + parameters: + - description: Webhook event + in: body + name: body + required: true + schema: + type: object + responses: + "200": + description: OK + summary: ProcessGitEvent + tags: + - prebuild /workspace/{workspaceId}/{projectId}/toolbox/files: delete: description: Delete file inside workspace project @@ -3591,10 +3591,10 @@ paths: summary: Execute command in session tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/project-dir: + /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir: get: - description: Get project directory - operationId: GetProjectDir + description: Get workspace directory + operationId: GetWorkspaceDir parameters: - description: Workspace ID or Name in: path @@ -3612,8 +3612,8 @@ paths: "200": description: OK schema: - $ref: '#/definitions/ProjectDirResponse' - summary: Get project dir + $ref: '#/definitions/WorkspaceDirResponse' + summary: Get workspace dir tags: - workspace toolbox schemes: diff --git a/pkg/api/middlewares/auth.go b/pkg/api/middlewares/auth.go index ff47bd21bf..80b3e09aa8 100644 --- a/pkg/api/middlewares/auth.go +++ b/pkg/api/middlewares/auth.go @@ -37,8 +37,8 @@ func AuthMiddleware() gin.HandlerFunc { if server.ApiKeyService.IsTargetApiKey(token) { apiKeyType = apikey.ApiKeyTypeTarget - } else if server.ApiKeyService.IsProjectApiKey(token) { - apiKeyType = apikey.ApiKeyTypeProject + } else if server.ApiKeyService.IsWorkspaceApiKey(token) { + apiKeyType = apikey.ApiKeyTypeWorkspace } ctx.Set("apiKeyType", apiKeyType) diff --git a/pkg/api/middlewares/telemetry.go b/pkg/api/middlewares/telemetry.go index 9facdd364d..c3edd209fe 100644 --- a/pkg/api/middlewares/telemetry.go +++ b/pkg/api/middlewares/telemetry.go @@ -17,9 +17,9 @@ import ( ) var ignorePaths = map[string]bool{ - "/health": true, - "/target/:targetId/:projectId/state": true, - "/server/network-key": true, + "/health": true, + "/target/:targetId/:workspaceId/state": true, + "/server/network-key": true, } func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.HandlerFunc { diff --git a/pkg/api/middlewares/project.go b/pkg/api/middlewares/workspace.go similarity index 80% rename from pkg/api/middlewares/project.go rename to pkg/api/middlewares/workspace.go index 1a347c4299..0dc167eb98 100644 --- a/pkg/api/middlewares/project.go +++ b/pkg/api/middlewares/workspace.go @@ -10,7 +10,7 @@ import ( "github.com/gin-gonic/gin" ) -func ProjectAuthMiddleware() gin.HandlerFunc { +func WorkspaceAuthMiddleware() gin.HandlerFunc { return func(ctx *gin.Context) { bearerToken := ctx.GetHeader("Authorization") if bearerToken == "" { @@ -26,7 +26,7 @@ func ProjectAuthMiddleware() gin.HandlerFunc { server := server.GetInstance(nil) - if !server.ApiKeyService.IsProjectApiKey(token) && !server.ApiKeyService.IsTargetApiKey(token) { + if !server.ApiKeyService.IsWorkspaceApiKey(token) && !server.ApiKeyService.IsTargetApiKey(token) { ctx.AbortWithError(401, errors.New("unauthorized")) } diff --git a/pkg/api/server.go b/pkg/api/server.go index 9ab5a8c58c..896b575f77 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -40,14 +40,14 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/health" log_controller "github.com/daytonaio/daytona/pkg/api/controllers/log" "github.com/daytonaio/daytona/pkg/api/controllers/profiledata" - "github.com/daytonaio/daytona/pkg/api/controllers/projectconfig" - "github.com/daytonaio/daytona/pkg/api/controllers/projectconfig/prebuild" "github.com/daytonaio/daytona/pkg/api/controllers/provider" "github.com/daytonaio/daytona/pkg/api/controllers/sample" "github.com/daytonaio/daytona/pkg/api/controllers/server" "github.com/daytonaio/daytona/pkg/api/controllers/target" "github.com/daytonaio/daytona/pkg/api/controllers/targetconfig" "github.com/daytonaio/daytona/pkg/api/controllers/workspace/toolbox" + "github.com/daytonaio/daytona/pkg/api/controllers/workspaceconfig" + "github.com/daytonaio/daytona/pkg/api/controllers/workspaceconfig/prebuild" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" @@ -144,7 +144,7 @@ func (a *ApiServer) Start() error { { toolboxController := targetController.Group("/:targetId/:projectId/toolbox") { - toolboxController.GET("/project-dir", toolbox.GetProjectDir) + toolboxController.GET("/workspace-dir", toolbox.GetWorkspaceDir) processController := toolboxController.Group("/process") { @@ -210,34 +210,34 @@ func (a *ApiServer) Start() error { targetController.POST("/:targetId/start", target.StartTarget) targetController.POST("/:targetId/stop", target.StopTarget) targetController.DELETE("/:targetId", target.RemoveTarget) - targetController.POST("/:targetId/:projectId/start", target.StartProject) - targetController.POST("/:targetId/:projectId/stop", target.StopProject) + targetController.POST("/:targetId/:workspaceId/start", target.StartWorkspace) + targetController.POST("/:targetId/:workspaceId/stop", target.StopWorkspace) } - projectConfigController := protected.Group("/project-config") + workspaceConfigController := protected.Group("/workspace-config") { - // Defining the prebuild routes first to avoid conflicts with the project config routes + // Defining the prebuild routes first to avoid conflicts with the workspace config routes prebuildRoutePath := "/prebuild" - projectConfigPrebuildsGroup := projectConfigController.Group(prebuildRoutePath) + workspaceConfigPrebuildsGroup := workspaceConfigController.Group(prebuildRoutePath) { - projectConfigPrebuildsGroup.GET("", prebuild.ListPrebuilds) + workspaceConfigPrebuildsGroup.GET("", prebuild.ListPrebuilds) } - projectConfigNameGroup := projectConfigController.Group(":configName") + workspaceConfigNameGroup := workspaceConfigController.Group(":configName") { - projectConfigNameGroup.PUT(prebuildRoutePath, prebuild.SetPrebuild) - projectConfigNameGroup.GET(prebuildRoutePath, prebuild.ListPrebuildsForProjectConfig) - projectConfigNameGroup.GET(prebuildRoutePath+"/:prebuildId", prebuild.GetPrebuild) - projectConfigNameGroup.DELETE(prebuildRoutePath+"/:prebuildId", prebuild.DeletePrebuild) - - projectConfigNameGroup.GET("", projectconfig.GetProjectConfig) - projectConfigNameGroup.PATCH("/set-default", projectconfig.SetDefaultProjectConfig) - projectConfigNameGroup.DELETE("", projectconfig.DeleteProjectConfig) + workspaceConfigNameGroup.PUT(prebuildRoutePath, prebuild.SetPrebuild) + workspaceConfigNameGroup.GET(prebuildRoutePath, prebuild.ListPrebuildsForWorkspaceConfig) + workspaceConfigNameGroup.GET(prebuildRoutePath+"/:prebuildId", prebuild.GetPrebuild) + workspaceConfigNameGroup.DELETE(prebuildRoutePath+"/:prebuildId", prebuild.DeletePrebuild) + + workspaceConfigNameGroup.GET("", workspaceconfig.GetWorkspaceConfig) + workspaceConfigNameGroup.PATCH("/set-default", workspaceconfig.SetDefaultWorkspaceConfig) + workspaceConfigNameGroup.DELETE("", workspaceconfig.DeleteWorkspaceConfig) } - projectConfigController.GET("", projectconfig.ListProjectConfigs) - projectConfigController.PUT("", projectconfig.SetProjectConfig) - projectConfigController.GET("/default/:gitUrl", projectconfig.GetDefaultProjectConfig) + workspaceConfigController.GET("", workspaceconfig.ListWorkspaceConfigs) + workspaceConfigController.PUT("", workspaceconfig.SetWorkspaceConfig) + workspaceConfigController.GET("/default/:gitUrl", workspaceconfig.GetDefaultWorkspaceConfig) } public.POST(constants.WEBHOOK_EVENT_ROUTE, prebuild.ProcessGitEvent) @@ -280,7 +280,7 @@ func (a *ApiServer) Start() error { { logController.GET("/server", log_controller.ReadServerLog) logController.GET("/target/:targetId", log_controller.ReadTargetLog) - logController.GET("/target/:targetId/:projectName", log_controller.ReadProjectLog) + logController.GET("/target/:targetId/:workspaceName", log_controller.ReadWorkspaceLog) logController.GET("/build/:buildId", log_controller.ReadBuildLog) } @@ -320,10 +320,10 @@ func (a *ApiServer) Start() error { samplesController.GET("", sample.ListSamples) } - projectGroup := protected.Group("/") - projectGroup.Use(middlewares.ProjectAuthMiddleware()) + workspaceGroup := protected.Group("/") + workspaceGroup.Use(middlewares.WorkspaceAuthMiddleware()) { - projectGroup.POST(targetController.BasePath()+"/:targetId/:projectId/state", target.SetProjectState) + workspaceGroup.POST(targetController.BasePath()+"/:targetId/:workspaceId/state", target.SetWorkspaceState) } a.httpServer = &http.Server{ diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 210b5054f6..766882dbd4 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -104,21 +104,15 @@ Class | Method | HTTP request | Description *GitProviderAPI* | [**ListGitProvidersForUrl**](docs/GitProviderAPI.md#listgitprovidersforurl) | **Get** /gitprovider/for-url/{url} | List Git providers for url *GitProviderAPI* | [**RemoveGitProvider**](docs/GitProviderAPI.md#removegitprovider) | **Delete** /gitprovider/{gitProviderId} | Remove Git provider *GitProviderAPI* | [**SetGitProvider**](docs/GitProviderAPI.md#setgitprovider) | **Put** /gitprovider | Set Git provider -*PrebuildAPI* | [**DeletePrebuild**](docs/PrebuildAPI.md#deleteprebuild) | **Delete** /project-config/{configName}/prebuild/{prebuildId} | Delete prebuild -*PrebuildAPI* | [**GetPrebuild**](docs/PrebuildAPI.md#getprebuild) | **Get** /project-config/{configName}/prebuild/{prebuildId} | Get prebuild -*PrebuildAPI* | [**ListPrebuilds**](docs/PrebuildAPI.md#listprebuilds) | **Get** /project-config/prebuild | List prebuilds -*PrebuildAPI* | [**ListPrebuildsForProjectConfig**](docs/PrebuildAPI.md#listprebuildsforprojectconfig) | **Get** /project-config/{configName}/prebuild | List prebuilds for project config -*PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /project-config/prebuild/process-git-event | ProcessGitEvent -*PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /project-config/{configName}/prebuild | Set prebuild +*PrebuildAPI* | [**DeletePrebuild**](docs/PrebuildAPI.md#deleteprebuild) | **Delete** /workspace-config/{configName}/prebuild/{prebuildId} | Delete prebuild +*PrebuildAPI* | [**GetPrebuild**](docs/PrebuildAPI.md#getprebuild) | **Get** /workspace-config/{configName}/prebuild/{prebuildId} | Get prebuild +*PrebuildAPI* | [**ListPrebuilds**](docs/PrebuildAPI.md#listprebuilds) | **Get** /workspace-config/prebuild | List prebuilds +*PrebuildAPI* | [**ListPrebuildsForWorkspaceConfig**](docs/PrebuildAPI.md#listprebuildsforworkspaceconfig) | **Get** /workspace-config/{configName}/prebuild | List prebuilds for workspace config +*PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /workspace-config/prebuild/process-git-event | ProcessGitEvent +*PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /workspace-config/{configName}/prebuild | Set prebuild *ProfileAPI* | [**DeleteProfileData**](docs/ProfileAPI.md#deleteprofiledata) | **Delete** /profile | Delete profile data *ProfileAPI* | [**GetProfileData**](docs/ProfileAPI.md#getprofiledata) | **Get** /profile | Get profile data *ProfileAPI* | [**SetProfileData**](docs/ProfileAPI.md#setprofiledata) | **Put** /profile | Set profile data -*ProjectConfigAPI* | [**DeleteProjectConfig**](docs/ProjectConfigAPI.md#deleteprojectconfig) | **Delete** /project-config/{configName} | Delete project config data -*ProjectConfigAPI* | [**GetDefaultProjectConfig**](docs/ProjectConfigAPI.md#getdefaultprojectconfig) | **Get** /project-config/default/{gitUrl} | Get project configs by git url -*ProjectConfigAPI* | [**GetProjectConfig**](docs/ProjectConfigAPI.md#getprojectconfig) | **Get** /project-config/{configName} | Get project config data -*ProjectConfigAPI* | [**ListProjectConfigs**](docs/ProjectConfigAPI.md#listprojectconfigs) | **Get** /project-config | List project configs -*ProjectConfigAPI* | [**SetDefaultProjectConfig**](docs/ProjectConfigAPI.md#setdefaultprojectconfig) | **Patch** /project-config/{configName}/set-default | Set project config to default -*ProjectConfigAPI* | [**SetProjectConfig**](docs/ProjectConfigAPI.md#setprojectconfig) | **Put** /project-config | Set project config data *ProviderAPI* | [**GetTargetConfigManifest**](docs/ProviderAPI.md#gettargetconfigmanifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest *ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /provider/install | Install a provider *ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /provider | List providers @@ -132,15 +126,21 @@ Class | Method | HTTP request | Description *TargetAPI* | [**GetTarget**](docs/TargetAPI.md#gettarget) | **Get** /target/{targetId} | Get target info *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets *TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target -*TargetAPI* | [**SetProjectState**](docs/TargetAPI.md#setprojectstate) | **Post** /target/{targetId}/{projectId}/state | Set project state -*TargetAPI* | [**StartProject**](docs/TargetAPI.md#startproject) | **Post** /target/{targetId}/{projectId}/start | Start project +*TargetAPI* | [**SetWorkspaceState**](docs/TargetAPI.md#setworkspacestate) | **Post** /target/{targetId}/{workspaceId}/state | Set workspace state *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target -*TargetAPI* | [**StopProject**](docs/TargetAPI.md#stopproject) | **Post** /target/{targetId}/{projectId}/stop | Stop project +*TargetAPI* | [**StartWorkspace**](docs/TargetAPI.md#startworkspace) | **Post** /target/{targetId}/{workspaceId}/start | Start workspace *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target +*TargetAPI* | [**StopWorkspace**](docs/TargetAPI.md#stopworkspace) | **Post** /target/{targetId}/{workspaceId}/stop | Stop workspace *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs *TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configName} | Remove a target config *TargetConfigAPI* | [**SetDefaultTargetConfig**](docs/TargetConfigAPI.md#setdefaulttargetconfig) | **Patch** /target-config/{configName}/set-default | Set target config to default *TargetConfigAPI* | [**SetTargetConfig**](docs/TargetConfigAPI.md#settargetconfig) | **Put** /target-config | Set a target config +*WorkspaceConfigAPI* | [**DeleteWorkspaceConfig**](docs/WorkspaceConfigAPI.md#deleteworkspaceconfig) | **Delete** /workspace-config/{configName} | Delete workspace config data +*WorkspaceConfigAPI* | [**GetDefaultWorkspaceConfig**](docs/WorkspaceConfigAPI.md#getdefaultworkspaceconfig) | **Get** /workspace-config/default/{gitUrl} | Get workspace configs by git url +*WorkspaceConfigAPI* | [**GetWorkspaceConfig**](docs/WorkspaceConfigAPI.md#getworkspaceconfig) | **Get** /workspace-config/{configName} | Get workspace config data +*WorkspaceConfigAPI* | [**ListWorkspaceConfigs**](docs/WorkspaceConfigAPI.md#listworkspaceconfigs) | **Get** /workspace-config | List workspace configs +*WorkspaceConfigAPI* | [**SetDefaultWorkspaceConfig**](docs/WorkspaceConfigAPI.md#setdefaultworkspaceconfig) | **Patch** /workspace-config/{configName}/set-default | Set workspace config to default +*WorkspaceConfigAPI* | [**SetWorkspaceConfig**](docs/WorkspaceConfigAPI.md#setworkspaceconfig) | **Put** /workspace-config | Set workspace config data *WorkspaceToolboxAPI* | [**CreateSession**](docs/WorkspaceToolboxAPI.md#createsession) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/session | Create exec session *WorkspaceToolboxAPI* | [**DeleteSession**](docs/WorkspaceToolboxAPI.md#deletesession) | **Delete** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId} | Delete session *WorkspaceToolboxAPI* | [**FsCreateFolder**](docs/WorkspaceToolboxAPI.md#fscreatefolder) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/folder | Create folder @@ -154,8 +154,8 @@ Class | Method | HTTP request | Description *WorkspaceToolboxAPI* | [**FsSearchFiles**](docs/WorkspaceToolboxAPI.md#fssearchfiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/search | Search for files *WorkspaceToolboxAPI* | [**FsSetFilePermissions**](docs/WorkspaceToolboxAPI.md#fssetfilepermissions) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/permissions | Set file owner/group/permissions *WorkspaceToolboxAPI* | [**FsUploadFile**](docs/WorkspaceToolboxAPI.md#fsuploadfile) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/upload | Upload file -*WorkspaceToolboxAPI* | [**GetProjectDir**](docs/WorkspaceToolboxAPI.md#getprojectdir) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/project-dir | Get project dir *WorkspaceToolboxAPI* | [**GetSessionCommandLogs**](docs/WorkspaceToolboxAPI.md#getsessioncommandlogs) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs | Get session command logs +*WorkspaceToolboxAPI* | [**GetWorkspaceDir**](docs/WorkspaceToolboxAPI.md#getworkspacedir) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir | Get workspace dir *WorkspaceToolboxAPI* | [**GitAddFiles**](docs/WorkspaceToolboxAPI.md#gitaddfiles) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/add | Add files *WorkspaceToolboxAPI* | [**GitBranchList**](docs/WorkspaceToolboxAPI.md#gitbranchlist) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/branches | Get branch list *WorkspaceToolboxAPI* | [**GitCloneRepository**](docs/WorkspaceToolboxAPI.md#gitclonerepository) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/clone | Clone git repository @@ -194,12 +194,12 @@ Class | Method | HTTP request | Description - [ContainerRegistry](docs/ContainerRegistry.md) - [CreateBuildDTO](docs/CreateBuildDTO.md) - [CreatePrebuildDTO](docs/CreatePrebuildDTO.md) - - [CreateProjectConfigDTO](docs/CreateProjectConfigDTO.md) - - [CreateProjectDTO](docs/CreateProjectDTO.md) - - [CreateProjectSourceDTO](docs/CreateProjectSourceDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) - [CreateTargetConfigDTO](docs/CreateTargetConfigDTO.md) - [CreateTargetDTO](docs/CreateTargetDTO.md) + - [CreateWorkspaceConfigDTO](docs/CreateWorkspaceConfigDTO.md) + - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) + - [CreateWorkspaceSourceDTO](docs/CreateWorkspaceSourceDTO.md) - [DevcontainerConfig](docs/DevcontainerConfig.md) - [ExecuteRequest](docs/ExecuteRequest.md) - [ExecuteResponse](docs/ExecuteResponse.md) @@ -237,11 +237,6 @@ Class | Method | HTTP request | Description - [PrebuildConfig](docs/PrebuildConfig.md) - [PrebuildDTO](docs/PrebuildDTO.md) - [ProfileData](docs/ProfileData.md) - - [Project](docs/Project.md) - - [ProjectConfig](docs/ProjectConfig.md) - - [ProjectDirResponse](docs/ProjectDirResponse.md) - - [ProjectInfo](docs/ProjectInfo.md) - - [ProjectState](docs/ProjectState.md) - [Provider](docs/Provider.md) - [ProviderProviderInfo](docs/ProviderProviderInfo.md) - [ProviderTargetConfigPropertyType](docs/ProviderTargetConfigPropertyType.md) @@ -255,7 +250,7 @@ Class | Method | HTTP request | Description - [SessionExecuteRequest](docs/SessionExecuteRequest.md) - [SessionExecuteResponse](docs/SessionExecuteResponse.md) - [SetGitProviderConfig](docs/SetGitProviderConfig.md) - - [SetProjectState](docs/SetProjectState.md) + - [SetWorkspaceState](docs/SetWorkspaceState.md) - [SigningMethod](docs/SigningMethod.md) - [Status](docs/Status.md) - [Target](docs/Target.md) @@ -263,6 +258,11 @@ Class | Method | HTTP request | Description - [TargetConfigProperty](docs/TargetConfigProperty.md) - [TargetDTO](docs/TargetDTO.md) - [TargetInfo](docs/TargetInfo.md) + - [Workspace](docs/Workspace.md) + - [WorkspaceConfig](docs/WorkspaceConfig.md) + - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) + - [WorkspaceInfo](docs/WorkspaceInfo.md) + - [WorkspaceState](docs/WorkspaceState.md) ## Documentation For Authorization diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 15f9fb1d26..5df465f00c 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -660,263 +660,6 @@ paths: tags: - profile x-codegen-request-body-name: profileData - /project-config: - get: - description: List project configs - operationId: ListProjectConfigs - responses: - "200": - content: - application/json: - schema: - items: - $ref: '#/components/schemas/ProjectConfig' - type: array - description: OK - summary: List project configs - tags: - - project-config - put: - description: Set project config data - operationId: SetProjectConfig - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreateProjectConfigDTO' - description: Project config - required: true - responses: - "201": - content: {} - description: Created - summary: Set project config data - tags: - - project-config - x-codegen-request-body-name: projectConfig - /project-config/default/{gitUrl}: - get: - description: Get project configs by git url - operationId: GetDefaultProjectConfig - parameters: - - description: Git URL - in: path - name: gitUrl - required: true - schema: - type: string - responses: - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/ProjectConfig' - description: OK - summary: Get project configs by git url - tags: - - project-config - /project-config/prebuild: - get: - description: List prebuilds - operationId: ListPrebuilds - responses: - "200": - content: - '*/*': - schema: - items: - $ref: '#/components/schemas/PrebuildDTO' - type: array - description: OK - summary: List prebuilds - tags: - - prebuild - /project-config/prebuild/process-git-event: - post: - description: ProcessGitEvent - operationId: ProcessGitEvent - requestBody: - content: - '*/*': - schema: - type: object - description: Webhook event - required: true - responses: - "200": - content: {} - description: OK - summary: ProcessGitEvent - tags: - - prebuild - x-codegen-request-body-name: body - /project-config/{configName}: - delete: - description: Delete project config data - operationId: DeleteProjectConfig - parameters: - - description: Config name - in: path - name: configName - required: true - schema: - type: string - - description: Force - in: query - name: force - schema: - type: boolean - responses: - "204": - content: {} - description: No Content - summary: Delete project config data - tags: - - project-config - get: - description: Get project config data - operationId: GetProjectConfig - parameters: - - description: Config name - in: path - name: configName - required: true - schema: - type: string - responses: - "200": - content: - '*/*': - schema: - $ref: '#/components/schemas/ProjectConfig' - description: OK - summary: Get project config data - tags: - - project-config - /project-config/{configName}/prebuild: - get: - description: List prebuilds for project config - operationId: ListPrebuildsForProjectConfig - parameters: - - description: Config name - in: path - name: configName - required: true - schema: - type: string - responses: - "200": - content: - '*/*': - schema: - items: - $ref: '#/components/schemas/PrebuildDTO' - type: array - description: OK - summary: List prebuilds for project config - tags: - - prebuild - put: - description: Set prebuild - operationId: SetPrebuild - parameters: - - description: Config name - in: path - name: configName - required: true - schema: - type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/CreatePrebuildDTO' - description: Prebuild - required: true - responses: - "201": - content: - '*/*': - schema: - type: string - description: Created - summary: Set prebuild - tags: - - prebuild - x-codegen-request-body-name: prebuild - /project-config/{configName}/prebuild/{prebuildId}: - delete: - description: Delete prebuild - operationId: DeletePrebuild - parameters: - - description: Project config name - in: path - name: configName - required: true - schema: - type: string - - description: Prebuild ID - in: path - name: prebuildId - required: true - schema: - type: string - - description: Force - in: query - name: force - schema: - type: boolean - responses: - "204": - content: {} - description: No Content - summary: Delete prebuild - tags: - - prebuild - get: - description: Get prebuild - operationId: GetPrebuild - parameters: - - description: Project config name - in: path - name: configName - required: true - schema: - type: string - - description: Prebuild ID - in: path - name: prebuildId - required: true - schema: - type: string - responses: - "200": - content: - '*/*': - schema: - $ref: '#/components/schemas/PrebuildDTO' - description: OK - summary: Get prebuild - tags: - - prebuild - /project-config/{configName}/set-default: - patch: - description: Set project config to default - operationId: SetDefaultProjectConfig - parameters: - - description: Config name - in: path - name: configName - required: true - schema: - type: string - responses: - "200": - content: {} - description: OK - summary: Set project config to default - tags: - - project-config /provider: get: description: List providers @@ -1222,123 +965,380 @@ paths: in: query name: verbose schema: - type: boolean + type: boolean + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/TargetDTO' + description: OK + summary: Get target info + tags: + - target + /target/{targetId}/start: + post: + description: Start target + operationId: StartTarget + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Start target + tags: + - target + /target/{targetId}/stop: + post: + description: Stop target + operationId: StopTarget + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Stop target + tags: + - target + /target/{targetId}/{workspaceId}/start: + post: + description: Start workspace + operationId: StartWorkspace + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + schema: + type: string + - description: Workspace ID + in: path + name: workspaceId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Start workspace + tags: + - target + /target/{targetId}/{workspaceId}/state: + post: + description: Set workspace state + operationId: SetWorkspaceState + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + schema: + type: string + - description: Workspace ID + in: path + name: workspaceId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/SetWorkspaceState' + description: Set State + required: true + responses: + "200": + content: {} + description: OK + summary: Set workspace state + tags: + - target + x-codegen-request-body-name: setState + /target/{targetId}/{workspaceId}/stop: + post: + description: Stop workspace + operationId: StopWorkspace + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + schema: + type: string + - description: Workspace ID + in: path + name: workspaceId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Stop workspace + tags: + - target + /workspace-config: + get: + description: List workspace configs + operationId: ListWorkspaceConfigs + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/WorkspaceConfig' + type: array + description: OK + summary: List workspace configs + tags: + - workspace-config + put: + description: Set workspace config data + operationId: SetWorkspaceConfig + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkspaceConfigDTO' + description: Workspace config + required: true + responses: + "201": + content: {} + description: Created + summary: Set workspace config data + tags: + - workspace-config + x-codegen-request-body-name: workspaceConfig + /workspace-config/default/{gitUrl}: + get: + description: Get workspace configs by git url + operationId: GetDefaultWorkspaceConfig + parameters: + - description: Git URL + in: path + name: gitUrl + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceConfig' + description: OK + summary: Get workspace configs by git url + tags: + - workspace-config + /workspace-config/prebuild: + get: + description: List prebuilds + operationId: ListPrebuilds + responses: + "200": + content: + '*/*': + schema: + items: + $ref: '#/components/schemas/PrebuildDTO' + type: array + description: OK + summary: List prebuilds + tags: + - prebuild + /workspace-config/prebuild/process-git-event: + post: + description: ProcessGitEvent + operationId: ProcessGitEvent + requestBody: + content: + '*/*': + schema: + type: object + description: Webhook event + required: true + responses: + "200": + content: {} + description: OK + summary: ProcessGitEvent + tags: + - prebuild + x-codegen-request-body-name: body + /workspace-config/{configName}: + delete: + description: Delete workspace config data + operationId: DeleteWorkspaceConfig + parameters: + - description: Config name + in: path + name: configName + required: true + schema: + type: string + - description: Force + in: query + name: force + schema: + type: boolean + responses: + "204": + content: {} + description: No Content + summary: Delete workspace config data + tags: + - workspace-config + get: + description: Get workspace config data + operationId: GetWorkspaceConfig + parameters: + - description: Config name + in: path + name: configName + required: true + schema: + type: string responses: "200": content: - application/json: + '*/*': schema: - $ref: '#/components/schemas/TargetDTO' + $ref: '#/components/schemas/WorkspaceConfig' description: OK - summary: Get target info + summary: Get workspace config data tags: - - target - /target/{targetId}/start: - post: - description: Start target - operationId: StartTarget + - workspace-config + /workspace-config/{configName}/prebuild: + get: + description: List prebuilds for workspace config + operationId: ListPrebuildsForWorkspaceConfig parameters: - - description: Target ID or Name + - description: Config name in: path - name: targetId + name: configName required: true schema: type: string responses: "200": - content: {} + content: + '*/*': + schema: + items: + $ref: '#/components/schemas/PrebuildDTO' + type: array description: OK - summary: Start target + summary: List prebuilds for workspace config tags: - - target - /target/{targetId}/stop: - post: - description: Stop target - operationId: StopTarget + - prebuild + put: + description: Set prebuild + operationId: SetPrebuild parameters: - - description: Target ID or Name + - description: Config name in: path - name: targetId + name: configName required: true schema: type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePrebuildDTO' + description: Prebuild + required: true responses: - "200": - content: {} - description: OK - summary: Stop target + "201": + content: + '*/*': + schema: + type: string + description: Created + summary: Set prebuild tags: - - target - /target/{targetId}/{projectId}/start: - post: - description: Start project - operationId: StartProject + - prebuild + x-codegen-request-body-name: prebuild + /workspace-config/{configName}/prebuild/{prebuildId}: + delete: + description: Delete prebuild + operationId: DeletePrebuild parameters: - - description: Target ID or Name + - description: Workspace config name in: path - name: targetId + name: configName required: true schema: type: string - - description: Project ID + - description: Prebuild ID in: path - name: projectId + name: prebuildId required: true schema: type: string + - description: Force + in: query + name: force + schema: + type: boolean responses: - "200": + "204": content: {} - description: OK - summary: Start project + description: No Content + summary: Delete prebuild tags: - - target - /target/{targetId}/{projectId}/state: - post: - description: Set project state - operationId: SetProjectState + - prebuild + get: + description: Get prebuild + operationId: GetPrebuild parameters: - - description: Target ID or Name + - description: Workspace config name in: path - name: targetId + name: configName required: true schema: type: string - - description: Project ID + - description: Prebuild ID in: path - name: projectId + name: prebuildId required: true schema: type: string - requestBody: - content: - '*/*': - schema: - $ref: '#/components/schemas/SetProjectState' - description: Set State - required: true responses: "200": - content: {} + content: + '*/*': + schema: + $ref: '#/components/schemas/PrebuildDTO' description: OK - summary: Set project state + summary: Get prebuild tags: - - target - x-codegen-request-body-name: setState - /target/{targetId}/{projectId}/stop: - post: - description: Stop project - operationId: StopProject + - prebuild + /workspace-config/{configName}/set-default: + patch: + description: Set workspace config to default + operationId: SetDefaultWorkspaceConfig parameters: - - description: Target ID or Name - in: path - name: targetId - required: true - schema: - type: string - - description: Project ID + - description: Config name in: path - name: projectId + name: configName required: true schema: type: string @@ -1346,9 +1346,9 @@ paths: "200": content: {} description: OK - summary: Stop project + summary: Set workspace config to default tags: - - target + - workspace-config /workspace/{workspaceId}/{projectId}/toolbox/files: delete: description: Delete file inside workspace project @@ -2512,10 +2512,10 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/project-dir: + /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir: get: - description: Get project directory - operationId: GetProjectDir + description: Get workspace directory + operationId: GetWorkspaceDir parameters: - description: Workspace ID or Name in: path @@ -2534,9 +2534,9 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ProjectDirResponse' + $ref: '#/components/schemas/WorkspaceDirResponse' description: OK - summary: Get project dir + summary: Get workspace dir tags: - workspace toolbox components: @@ -2550,7 +2550,7 @@ components: keyHash: type: string name: - description: Project or client name + description: Workspace or client name type: string type: $ref: '#/components/schemas/apikey.ApiKeyType' @@ -2776,9 +2776,9 @@ components: CreateBuildDTO: example: prebuildId: prebuildId - projectConfigName: projectConfigName envVars: key: envVars + workspaceConfigName: workspaceConfigName branch: branch properties: branch: @@ -2789,12 +2789,12 @@ components: type: object prebuildId: type: string - projectConfigName: + workspaceConfigName: type: string required: - branch - envVars - - projectConfigName + - workspaceConfigName type: object CreatePrebuildDTO: example: @@ -2821,110 +2821,6 @@ components: required: - retention type: object - CreateProjectConfigDTO: - example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - envVars: - key: envVars - name: name - user: user - repositoryUrl: repositoryUrl - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - repositoryUrl: - type: string - user: - type: string - required: - - envVars - - name - - repositoryUrl - type: object - CreateProjectDTO: - example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - envVars: - key: envVars - name: name - source: - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - source: - $ref: '#/components/schemas/CreateProjectSourceDTO' - user: - type: string - required: - - envVars - - name - - source - type: object - CreateProjectSourceDTO: - example: - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - properties: - repository: - $ref: '#/components/schemas/GitRepository' - required: - - repository - type: object CreateSessionRequest: example: sessionId: sessionId @@ -2957,7 +2853,9 @@ components: CreateTargetDTO: example: targetConfig: targetConfig - projects: + name: name + id: id + workspaces: - buildConfig: cachedBuild: image: image @@ -3006,24 +2904,126 @@ components: sha: sha url: url user: user + properties: + id: + type: string + name: + type: string + targetConfig: + type: string + workspaces: + items: + $ref: '#/components/schemas/CreateWorkspaceDTO' + type: array + required: + - id + - name + - targetConfig + - workspaces + type: object + CreateWorkspaceConfigDTO: + example: + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + envVars: + key: envVars + name: name + user: user + repositoryUrl: repositoryUrl + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + repositoryUrl: + type: string + user: + type: string + required: + - envVars + - name + - repositoryUrl + type: object + CreateWorkspaceDTO: + example: + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + envVars: + key: envVars name: name - id: id + source: + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + user: user properties: - id: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: type: string name: type: string - projects: - items: - $ref: '#/components/schemas/CreateProjectDTO' - type: array - targetConfig: + source: + $ref: '#/components/schemas/CreateWorkspaceSourceDTO' + user: type: string required: - - id + - envVars - name - - projects - - targetConfig + - source + type: object + CreateWorkspaceSourceDTO: + example: + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + properties: + repository: + $ref: '#/components/schemas/GitRepository' + required: + - repository type: object DevcontainerConfig: example: @@ -3740,8 +3740,8 @@ components: type: object PrebuildDTO: example: - projectConfigName: projectConfigName commitInterval: 0 + workspaceConfigName: workspaceConfigName id: id branch: branch retention: 6 @@ -3755,229 +3755,31 @@ components: type: integer id: type: string - projectConfigName: - type: string retention: type: integer triggerFiles: - items: - type: string - type: array - required: - - branch - - id - - projectConfigName - - retention - type: object - ProfileData: - example: - envVars: - key: envVars - properties: - envVars: - additionalProperties: - type: string - type: object - required: - - envVars - type: object - Project: - example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - targetConfig: targetConfig - targetId: targetId - envVars: - key: envVars - name: name - state: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - repository: - $ref: '#/components/schemas/GitRepository' - state: - $ref: '#/components/schemas/ProjectState' - targetConfig: - type: string - targetId: - type: string - user: - type: string - required: - - envVars - - image - - name - - repository - - targetConfig - - targetId - - user - type: object - ProjectConfig: - example: - prebuilds: - - commitInterval: 0 - id: id - branch: branch - retention: 6 - triggerFiles: - - triggerFiles - - triggerFiles - - commitInterval: 0 - id: id - branch: branch - retention: 6 - triggerFiles: - - triggerFiles - - triggerFiles - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - default: true - envVars: - key: envVars - name: name - user: user - repositoryUrl: repositoryUrl - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - default: - type: boolean - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - prebuilds: - items: - $ref: '#/components/schemas/PrebuildConfig' - type: array - repositoryUrl: - type: string - user: - type: string - required: - - default - - envVars - - image - - name - - repositoryUrl - - user - type: object - ProjectDirResponse: - example: - dir: dir - properties: - dir: - type: string - type: object - ProjectInfo: - example: - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name - properties: - created: - type: string - isRunning: - type: boolean - name: - type: string - providerMetadata: - type: string - targetId: + items: + type: string + type: array + workspaceConfigName: type: string required: - - created - - isRunning - - name - - targetId + - branch + - id + - retention + - workspaceConfigName type: object - ProjectState: + ProfileData: example: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 + envVars: + key: envVars properties: - gitStatus: - $ref: '#/components/schemas/GitStatus' - updatedAt: - type: string - uptime: - type: integer + envVars: + additionalProperties: + type: string + type: object required: - - updatedAt - - uptime + - envVars type: object Provider: example: @@ -4073,9 +3875,9 @@ components: registryUrl: registryUrl localBuilderRegistryPort: 5 localBuilderRegistryImage: localBuilderRegistryImage - defaultProjectUser: defaultProjectUser builderRegistryServer: builderRegistryServer builderImage: builderImage + defaultWorkspaceImage: defaultWorkspaceImage apiPort: 0 headscalePort: 1 buildImageNamespace: buildImageNamespace @@ -4089,8 +3891,8 @@ components: maxBackups: 2 maxSize: 7 samplesIndexUrl: samplesIndexUrl - defaultProjectImage: defaultProjectImage providersDir: providersDir + defaultWorkspaceUser: defaultWorkspaceUser id: id frps: protocol: protocol @@ -4107,9 +3909,9 @@ components: type: string builderRegistryServer: type: string - defaultProjectImage: + defaultWorkspaceImage: type: string - defaultProjectUser: + defaultWorkspaceUser: type: string frps: $ref: '#/components/schemas/FRPSConfig' @@ -4136,8 +3938,8 @@ components: - binariesPath - builderImage - builderRegistryServer - - defaultProjectImage - - defaultProjectUser + - defaultWorkspaceImage + - defaultWorkspaceUser - headscalePort - id - localBuilderRegistryImage @@ -4224,7 +4026,7 @@ components: - providerId - token type: object - SetProjectState: + SetWorkspaceState: example: gitStatus: behind: 6 @@ -4280,7 +4082,9 @@ components: Target: example: targetConfig: targetConfig - projects: + name: name + id: id + workspaces: - buildConfig: cachedBuild: image: image @@ -4365,24 +4169,22 @@ components: sha: sha url: url user: user - name: name - id: id properties: id: type: string name: type: string - projects: - items: - $ref: '#/components/schemas/Project' - type: array targetConfig: type: string + workspaces: + items: + $ref: '#/components/schemas/Workspace' + type: array required: - id - name - - projects - targetConfig + - workspaces type: object TargetConfig: example: @@ -4448,7 +4250,9 @@ components: TargetDTO: example: targetConfig: targetConfig - projects: + name: name + id: id + workspaces: - buildConfig: cachedBuild: image: image @@ -4533,10 +4337,10 @@ components: sha: sha url: url user: user - name: name - id: id info: - projects: + providerMetadata: providerMetadata + name: name + workspaces: - providerMetadata: providerMetadata targetId: targetId isRunning: true @@ -4547,8 +4351,6 @@ components: isRunning: true created: created name: name - providerMetadata: providerMetadata - name: name properties: id: type: string @@ -4556,21 +4358,23 @@ components: $ref: '#/components/schemas/TargetInfo' name: type: string - projects: - items: - $ref: '#/components/schemas/Project' - type: array targetConfig: type: string + workspaces: + items: + $ref: '#/components/schemas/Workspace' + type: array required: - id - name - - projects - targetConfig + - workspaces type: object TargetInfo: example: - projects: + providerMetadata: providerMetadata + name: name + workspaces: - providerMetadata: providerMetadata targetId: targetId isRunning: true @@ -4581,30 +4385,226 @@ components: isRunning: true created: created name: name - providerMetadata: providerMetadata + properties: + name: + type: string + providerMetadata: + type: string + workspaces: + items: + $ref: '#/components/schemas/WorkspaceInfo' + type: array + required: + - name + - workspaces + type: object + Workspace: + example: + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + targetConfig: targetConfig + targetId: targetId + envVars: + key: envVars + name: name + state: + gitStatus: + behind: 6 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 0 + branchPublished: true + currentBranch: currentBranch + updatedAt: updatedAt + uptime: 1 + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + user: user + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + repository: + $ref: '#/components/schemas/GitRepository' + state: + $ref: '#/components/schemas/WorkspaceState' + targetConfig: + type: string + targetId: + type: string + user: + type: string + required: + - envVars + - image + - name + - repository + - targetConfig + - targetId + - user + type: object + WorkspaceConfig: + example: + prebuilds: + - commitInterval: 0 + id: id + branch: branch + retention: 6 + triggerFiles: + - triggerFiles + - triggerFiles + - commitInterval: 0 + id: id + branch: branch + retention: 6 + triggerFiles: + - triggerFiles + - triggerFiles + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + default: true + envVars: + key: envVars name: name + user: user + repositoryUrl: repositoryUrl properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + default: + type: boolean + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string name: type: string - projects: + prebuilds: items: - $ref: '#/components/schemas/ProjectInfo' + $ref: '#/components/schemas/PrebuildConfig' type: array + repositoryUrl: + type: string + user: + type: string + required: + - default + - envVars + - image + - name + - repositoryUrl + - user + type: object + WorkspaceDirResponse: + example: + dir: dir + properties: + dir: + type: string + type: object + WorkspaceInfo: + example: + providerMetadata: providerMetadata + targetId: targetId + isRunning: true + created: created + name: name + properties: + created: + type: string + isRunning: + type: boolean + name: + type: string providerMetadata: type: string + targetId: + type: string required: + - created + - isRunning - name - - projects + - targetId + type: object + WorkspaceState: + example: + gitStatus: + behind: 6 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 0 + branchPublished: true + currentBranch: currentBranch + updatedAt: updatedAt + uptime: 1 + properties: + gitStatus: + $ref: '#/components/schemas/GitStatus' + updatedAt: + type: string + uptime: + type: integer + required: + - updatedAt + - uptime type: object apikey.ApiKeyType: enum: - client - - project + - workspace - target type: string x-enum-varnames: - ApiKeyTypeClient - - ApiKeyTypeProject + - ApiKeyTypeWorkspace - ApiKeyTypeTarget build.BuildState: enum: diff --git a/pkg/apiclient/api_prebuild.go b/pkg/apiclient/api_prebuild.go index a6ce2bf687..7168d1b499 100644 --- a/pkg/apiclient/api_prebuild.go +++ b/pkg/apiclient/api_prebuild.go @@ -46,7 +46,7 @@ DeletePrebuild Delete prebuild Delete prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Project config name + @param configName Workspace config name @param prebuildId Prebuild ID @return ApiDeletePrebuildRequest */ @@ -72,7 +72,7 @@ func (a *PrebuildAPIService) DeletePrebuildExecute(r ApiDeletePrebuildRequest) ( return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}/prebuild/{prebuildId}" + localVarPath := localBasePath + "/workspace-config/{configName}/prebuild/{prebuildId}" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarPath = strings.Replace(localVarPath, "{"+"prebuildId"+"}", url.PathEscape(parameterValueToString(r.prebuildId, "prebuildId")), -1) @@ -159,7 +159,7 @@ GetPrebuild Get prebuild Get prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Project config name + @param configName Workspace config name @param prebuildId Prebuild ID @return ApiGetPrebuildRequest */ @@ -188,7 +188,7 @@ func (a *PrebuildAPIService) GetPrebuildExecute(r ApiGetPrebuildRequest) (*Prebu return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}/prebuild/{prebuildId}" + localVarPath := localBasePath + "/workspace-config/{configName}/prebuild/{prebuildId}" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarPath = strings.Replace(localVarPath, "{"+"prebuildId"+"}", url.PathEscape(parameterValueToString(r.prebuildId, "prebuildId")), -1) @@ -304,7 +304,7 @@ func (a *PrebuildAPIService) ListPrebuildsExecute(r ApiListPrebuildsRequest) ([] return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/prebuild" + localVarPath := localBasePath + "/workspace-config/prebuild" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -378,27 +378,27 @@ func (a *PrebuildAPIService) ListPrebuildsExecute(r ApiListPrebuildsRequest) ([] return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListPrebuildsForProjectConfigRequest struct { +type ApiListPrebuildsForWorkspaceConfigRequest struct { ctx context.Context ApiService *PrebuildAPIService configName string } -func (r ApiListPrebuildsForProjectConfigRequest) Execute() ([]PrebuildDTO, *http.Response, error) { - return r.ApiService.ListPrebuildsForProjectConfigExecute(r) +func (r ApiListPrebuildsForWorkspaceConfigRequest) Execute() ([]PrebuildDTO, *http.Response, error) { + return r.ApiService.ListPrebuildsForWorkspaceConfigExecute(r) } /* -ListPrebuildsForProjectConfig List prebuilds for project config +ListPrebuildsForWorkspaceConfig List prebuilds for workspace config -List prebuilds for project config +List prebuilds for workspace config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param configName Config name - @return ApiListPrebuildsForProjectConfigRequest + @return ApiListPrebuildsForWorkspaceConfigRequest */ -func (a *PrebuildAPIService) ListPrebuildsForProjectConfig(ctx context.Context, configName string) ApiListPrebuildsForProjectConfigRequest { - return ApiListPrebuildsForProjectConfigRequest{ +func (a *PrebuildAPIService) ListPrebuildsForWorkspaceConfig(ctx context.Context, configName string) ApiListPrebuildsForWorkspaceConfigRequest { + return ApiListPrebuildsForWorkspaceConfigRequest{ ApiService: a, ctx: ctx, configName: configName, @@ -408,7 +408,7 @@ func (a *PrebuildAPIService) ListPrebuildsForProjectConfig(ctx context.Context, // Execute executes the request // // @return []PrebuildDTO -func (a *PrebuildAPIService) ListPrebuildsForProjectConfigExecute(r ApiListPrebuildsForProjectConfigRequest) ([]PrebuildDTO, *http.Response, error) { +func (a *PrebuildAPIService) ListPrebuildsForWorkspaceConfigExecute(r ApiListPrebuildsForWorkspaceConfigRequest) ([]PrebuildDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -416,12 +416,12 @@ func (a *PrebuildAPIService) ListPrebuildsForProjectConfigExecute(r ApiListPrebu localVarReturnValue []PrebuildDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.ListPrebuildsForProjectConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.ListPrebuildsForWorkspaceConfig") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}/prebuild" + localVarPath := localBasePath + "/workspace-config/{configName}/prebuild" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) @@ -540,7 +540,7 @@ func (a *PrebuildAPIService) ProcessGitEventExecute(r ApiProcessGitEventRequest) return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/prebuild/process-git-event" + localVarPath := localBasePath + "/workspace-config/prebuild/process-git-event" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -660,7 +660,7 @@ func (a *PrebuildAPIService) SetPrebuildExecute(r ApiSetPrebuildRequest) (string return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}/prebuild" + localVarPath := localBasePath + "/workspace-config/{configName}/prebuild" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index 4472aedc6b..d91cad7d3e 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -516,59 +516,59 @@ func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http. return localVarHTTPResponse, nil } -type ApiSetProjectStateRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - projectId string - setState *SetProjectState +type ApiSetWorkspaceStateRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + workspaceId string + setState *SetWorkspaceState } // Set State -func (r ApiSetProjectStateRequest) SetState(setState SetProjectState) ApiSetProjectStateRequest { +func (r ApiSetWorkspaceStateRequest) SetState(setState SetWorkspaceState) ApiSetWorkspaceStateRequest { r.setState = &setState return r } -func (r ApiSetProjectStateRequest) Execute() (*http.Response, error) { - return r.ApiService.SetProjectStateExecute(r) +func (r ApiSetWorkspaceStateRequest) Execute() (*http.Response, error) { + return r.ApiService.SetWorkspaceStateExecute(r) } /* -SetProjectState Set project state +SetWorkspaceState Set workspace state -Set project state +Set workspace state @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @param projectId Project ID - @return ApiSetProjectStateRequest + @param workspaceId Workspace ID + @return ApiSetWorkspaceStateRequest */ -func (a *TargetAPIService) SetProjectState(ctx context.Context, targetId string, projectId string) ApiSetProjectStateRequest { - return ApiSetProjectStateRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, - projectId: projectId, +func (a *TargetAPIService) SetWorkspaceState(ctx context.Context, targetId string, workspaceId string) ApiSetWorkspaceStateRequest { + return ApiSetWorkspaceStateRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + workspaceId: workspaceId, } } // Execute executes the request -func (a *TargetAPIService) SetProjectStateExecute(r ApiSetProjectStateRequest) (*http.Response, error) { +func (a *TargetAPIService) SetWorkspaceStateExecute(r ApiSetWorkspaceStateRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetProjectState") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetWorkspaceState") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/{projectId}/state" + localVarPath := localBasePath + "/target/{targetId}/{workspaceId}/state" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -638,52 +638,48 @@ func (a *TargetAPIService) SetProjectStateExecute(r ApiSetProjectStateRequest) ( return localVarHTTPResponse, nil } -type ApiStartProjectRequest struct { +type ApiStartTargetRequest struct { ctx context.Context ApiService *TargetAPIService targetId string - projectId string } -func (r ApiStartProjectRequest) Execute() (*http.Response, error) { - return r.ApiService.StartProjectExecute(r) +func (r ApiStartTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.StartTargetExecute(r) } /* -StartProject Start project +StartTarget Start target -Start project +Start target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @param projectId Project ID - @return ApiStartProjectRequest + @return ApiStartTargetRequest */ -func (a *TargetAPIService) StartProject(ctx context.Context, targetId string, projectId string) ApiStartProjectRequest { - return ApiStartProjectRequest{ +func (a *TargetAPIService) StartTarget(ctx context.Context, targetId string) ApiStartTargetRequest { + return ApiStartTargetRequest{ ApiService: a, ctx: ctx, targetId: targetId, - projectId: projectId, } } // Execute executes the request -func (a *TargetAPIService) StartProjectExecute(r ApiStartProjectRequest) (*http.Response, error) { +func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartProject") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/{projectId}/start" + localVarPath := localBasePath + "/target/{targetId}/start" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -748,48 +744,52 @@ func (a *TargetAPIService) StartProjectExecute(r ApiStartProjectRequest) (*http. return localVarHTTPResponse, nil } -type ApiStartTargetRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string +type ApiStartWorkspaceRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + workspaceId string } -func (r ApiStartTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.StartTargetExecute(r) +func (r ApiStartWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.StartWorkspaceExecute(r) } /* -StartTarget Start target +StartWorkspace Start workspace -Start target +Start workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @return ApiStartTargetRequest + @param workspaceId Workspace ID + @return ApiStartWorkspaceRequest */ -func (a *TargetAPIService) StartTarget(ctx context.Context, targetId string) ApiStartTargetRequest { - return ApiStartTargetRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, +func (a *TargetAPIService) StartWorkspace(ctx context.Context, targetId string, workspaceId string) ApiStartWorkspaceRequest { + return ApiStartWorkspaceRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + workspaceId: workspaceId, } } // Execute executes the request -func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Response, error) { +func (a *TargetAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartWorkspace") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/start" + localVarPath := localBasePath + "/target/{targetId}/{workspaceId}/start" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -854,52 +854,48 @@ func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Re return localVarHTTPResponse, nil } -type ApiStopProjectRequest struct { +type ApiStopTargetRequest struct { ctx context.Context ApiService *TargetAPIService targetId string - projectId string } -func (r ApiStopProjectRequest) Execute() (*http.Response, error) { - return r.ApiService.StopProjectExecute(r) +func (r ApiStopTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.StopTargetExecute(r) } /* -StopProject Stop project +StopTarget Stop target -Stop project +Stop target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @param projectId Project ID - @return ApiStopProjectRequest + @return ApiStopTargetRequest */ -func (a *TargetAPIService) StopProject(ctx context.Context, targetId string, projectId string) ApiStopProjectRequest { - return ApiStopProjectRequest{ +func (a *TargetAPIService) StopTarget(ctx context.Context, targetId string) ApiStopTargetRequest { + return ApiStopTargetRequest{ ApiService: a, ctx: ctx, targetId: targetId, - projectId: projectId, } } // Execute executes the request -func (a *TargetAPIService) StopProjectExecute(r ApiStopProjectRequest) (*http.Response, error) { +func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopProject") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/{projectId}/stop" + localVarPath := localBasePath + "/target/{targetId}/stop" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -964,48 +960,52 @@ func (a *TargetAPIService) StopProjectExecute(r ApiStopProjectRequest) (*http.Re return localVarHTTPResponse, nil } -type ApiStopTargetRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string +type ApiStopWorkspaceRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + workspaceId string } -func (r ApiStopTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.StopTargetExecute(r) +func (r ApiStopWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.StopWorkspaceExecute(r) } /* -StopTarget Stop target +StopWorkspace Stop workspace -Stop target +Stop workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @return ApiStopTargetRequest + @param workspaceId Workspace ID + @return ApiStopWorkspaceRequest */ -func (a *TargetAPIService) StopTarget(ctx context.Context, targetId string) ApiStopTargetRequest { - return ApiStopTargetRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, +func (a *TargetAPIService) StopWorkspace(ctx context.Context, targetId string, workspaceId string) ApiStopWorkspaceRequest { + return ApiStopWorkspaceRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + workspaceId: workspaceId, } } // Execute executes the request -func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Response, error) { +func (a *TargetAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopWorkspace") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/stop" + localVarPath := localBasePath + "/target/{targetId}/{workspaceId}/stop" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} diff --git a/pkg/apiclient/api_project_config.go b/pkg/apiclient/api_workspace_config.go similarity index 75% rename from pkg/apiclient/api_project_config.go rename to pkg/apiclient/api_workspace_config.go index a42a381a59..6cb66b47f7 100644 --- a/pkg/apiclient/api_project_config.go +++ b/pkg/apiclient/api_workspace_config.go @@ -19,37 +19,37 @@ import ( "strings" ) -// ProjectConfigAPIService ProjectConfigAPI service -type ProjectConfigAPIService service +// WorkspaceConfigAPIService WorkspaceConfigAPI service +type WorkspaceConfigAPIService service -type ApiDeleteProjectConfigRequest struct { +type ApiDeleteWorkspaceConfigRequest struct { ctx context.Context - ApiService *ProjectConfigAPIService + ApiService *WorkspaceConfigAPIService configName string force *bool } // Force -func (r ApiDeleteProjectConfigRequest) Force(force bool) ApiDeleteProjectConfigRequest { +func (r ApiDeleteWorkspaceConfigRequest) Force(force bool) ApiDeleteWorkspaceConfigRequest { r.force = &force return r } -func (r ApiDeleteProjectConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.DeleteProjectConfigExecute(r) +func (r ApiDeleteWorkspaceConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteWorkspaceConfigExecute(r) } /* -DeleteProjectConfig Delete project config data +DeleteWorkspaceConfig Delete workspace config data -Delete project config data +Delete workspace config data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param configName Config name - @return ApiDeleteProjectConfigRequest + @return ApiDeleteWorkspaceConfigRequest */ -func (a *ProjectConfigAPIService) DeleteProjectConfig(ctx context.Context, configName string) ApiDeleteProjectConfigRequest { - return ApiDeleteProjectConfigRequest{ +func (a *WorkspaceConfigAPIService) DeleteWorkspaceConfig(ctx context.Context, configName string) ApiDeleteWorkspaceConfigRequest { + return ApiDeleteWorkspaceConfigRequest{ ApiService: a, ctx: ctx, configName: configName, @@ -57,19 +57,19 @@ func (a *ProjectConfigAPIService) DeleteProjectConfig(ctx context.Context, confi } // Execute executes the request -func (a *ProjectConfigAPIService) DeleteProjectConfigExecute(r ApiDeleteProjectConfigRequest) (*http.Response, error) { +func (a *WorkspaceConfigAPIService) DeleteWorkspaceConfigExecute(r ApiDeleteWorkspaceConfigRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodDelete localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProjectConfigAPIService.DeleteProjectConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.DeleteWorkspaceConfig") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}" + localVarPath := localBasePath + "/workspace-config/{configName}" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) @@ -138,27 +138,27 @@ func (a *ProjectConfigAPIService) DeleteProjectConfigExecute(r ApiDeleteProjectC return localVarHTTPResponse, nil } -type ApiGetDefaultProjectConfigRequest struct { +type ApiGetDefaultWorkspaceConfigRequest struct { ctx context.Context - ApiService *ProjectConfigAPIService + ApiService *WorkspaceConfigAPIService gitUrl string } -func (r ApiGetDefaultProjectConfigRequest) Execute() (*ProjectConfig, *http.Response, error) { - return r.ApiService.GetDefaultProjectConfigExecute(r) +func (r ApiGetDefaultWorkspaceConfigRequest) Execute() (*WorkspaceConfig, *http.Response, error) { + return r.ApiService.GetDefaultWorkspaceConfigExecute(r) } /* -GetDefaultProjectConfig Get project configs by git url +GetDefaultWorkspaceConfig Get workspace configs by git url -Get project configs by git url +Get workspace configs by git url @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param gitUrl Git URL - @return ApiGetDefaultProjectConfigRequest + @return ApiGetDefaultWorkspaceConfigRequest */ -func (a *ProjectConfigAPIService) GetDefaultProjectConfig(ctx context.Context, gitUrl string) ApiGetDefaultProjectConfigRequest { - return ApiGetDefaultProjectConfigRequest{ +func (a *WorkspaceConfigAPIService) GetDefaultWorkspaceConfig(ctx context.Context, gitUrl string) ApiGetDefaultWorkspaceConfigRequest { + return ApiGetDefaultWorkspaceConfigRequest{ ApiService: a, ctx: ctx, gitUrl: gitUrl, @@ -167,21 +167,21 @@ func (a *ProjectConfigAPIService) GetDefaultProjectConfig(ctx context.Context, g // Execute executes the request // -// @return ProjectConfig -func (a *ProjectConfigAPIService) GetDefaultProjectConfigExecute(r ApiGetDefaultProjectConfigRequest) (*ProjectConfig, *http.Response, error) { +// @return WorkspaceConfig +func (a *WorkspaceConfigAPIService) GetDefaultWorkspaceConfigExecute(r ApiGetDefaultWorkspaceConfigRequest) (*WorkspaceConfig, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *ProjectConfig + localVarReturnValue *WorkspaceConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProjectConfigAPIService.GetDefaultProjectConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.GetDefaultWorkspaceConfig") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/default/{gitUrl}" + localVarPath := localBasePath + "/workspace-config/default/{gitUrl}" localVarPath = strings.Replace(localVarPath, "{"+"gitUrl"+"}", url.PathEscape(parameterValueToString(r.gitUrl, "gitUrl")), -1) localVarHeaderParams := make(map[string]string) @@ -256,27 +256,27 @@ func (a *ProjectConfigAPIService) GetDefaultProjectConfigExecute(r ApiGetDefault return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetProjectConfigRequest struct { +type ApiGetWorkspaceConfigRequest struct { ctx context.Context - ApiService *ProjectConfigAPIService + ApiService *WorkspaceConfigAPIService configName string } -func (r ApiGetProjectConfigRequest) Execute() (*ProjectConfig, *http.Response, error) { - return r.ApiService.GetProjectConfigExecute(r) +func (r ApiGetWorkspaceConfigRequest) Execute() (*WorkspaceConfig, *http.Response, error) { + return r.ApiService.GetWorkspaceConfigExecute(r) } /* -GetProjectConfig Get project config data +GetWorkspaceConfig Get workspace config data -Get project config data +Get workspace config data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param configName Config name - @return ApiGetProjectConfigRequest + @return ApiGetWorkspaceConfigRequest */ -func (a *ProjectConfigAPIService) GetProjectConfig(ctx context.Context, configName string) ApiGetProjectConfigRequest { - return ApiGetProjectConfigRequest{ +func (a *WorkspaceConfigAPIService) GetWorkspaceConfig(ctx context.Context, configName string) ApiGetWorkspaceConfigRequest { + return ApiGetWorkspaceConfigRequest{ ApiService: a, ctx: ctx, configName: configName, @@ -285,21 +285,21 @@ func (a *ProjectConfigAPIService) GetProjectConfig(ctx context.Context, configNa // Execute executes the request // -// @return ProjectConfig -func (a *ProjectConfigAPIService) GetProjectConfigExecute(r ApiGetProjectConfigRequest) (*ProjectConfig, *http.Response, error) { +// @return WorkspaceConfig +func (a *WorkspaceConfigAPIService) GetWorkspaceConfigExecute(r ApiGetWorkspaceConfigRequest) (*WorkspaceConfig, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *ProjectConfig + localVarReturnValue *WorkspaceConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProjectConfigAPIService.GetProjectConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.GetWorkspaceConfig") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}" + localVarPath := localBasePath + "/workspace-config/{configName}" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) @@ -374,25 +374,25 @@ func (a *ProjectConfigAPIService) GetProjectConfigExecute(r ApiGetProjectConfigR return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListProjectConfigsRequest struct { +type ApiListWorkspaceConfigsRequest struct { ctx context.Context - ApiService *ProjectConfigAPIService + ApiService *WorkspaceConfigAPIService } -func (r ApiListProjectConfigsRequest) Execute() ([]ProjectConfig, *http.Response, error) { - return r.ApiService.ListProjectConfigsExecute(r) +func (r ApiListWorkspaceConfigsRequest) Execute() ([]WorkspaceConfig, *http.Response, error) { + return r.ApiService.ListWorkspaceConfigsExecute(r) } /* -ListProjectConfigs List project configs +ListWorkspaceConfigs List workspace configs -List project configs +List workspace configs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListProjectConfigsRequest + @return ApiListWorkspaceConfigsRequest */ -func (a *ProjectConfigAPIService) ListProjectConfigs(ctx context.Context) ApiListProjectConfigsRequest { - return ApiListProjectConfigsRequest{ +func (a *WorkspaceConfigAPIService) ListWorkspaceConfigs(ctx context.Context) ApiListWorkspaceConfigsRequest { + return ApiListWorkspaceConfigsRequest{ ApiService: a, ctx: ctx, } @@ -400,21 +400,21 @@ func (a *ProjectConfigAPIService) ListProjectConfigs(ctx context.Context) ApiLis // Execute executes the request // -// @return []ProjectConfig -func (a *ProjectConfigAPIService) ListProjectConfigsExecute(r ApiListProjectConfigsRequest) ([]ProjectConfig, *http.Response, error) { +// @return []WorkspaceConfig +func (a *WorkspaceConfigAPIService) ListWorkspaceConfigsExecute(r ApiListWorkspaceConfigsRequest) ([]WorkspaceConfig, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []ProjectConfig + localVarReturnValue []WorkspaceConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProjectConfigAPIService.ListProjectConfigs") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.ListWorkspaceConfigs") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config" + localVarPath := localBasePath + "/workspace-config" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -488,27 +488,27 @@ func (a *ProjectConfigAPIService) ListProjectConfigsExecute(r ApiListProjectConf return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetDefaultProjectConfigRequest struct { +type ApiSetDefaultWorkspaceConfigRequest struct { ctx context.Context - ApiService *ProjectConfigAPIService + ApiService *WorkspaceConfigAPIService configName string } -func (r ApiSetDefaultProjectConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.SetDefaultProjectConfigExecute(r) +func (r ApiSetDefaultWorkspaceConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.SetDefaultWorkspaceConfigExecute(r) } /* -SetDefaultProjectConfig Set project config to default +SetDefaultWorkspaceConfig Set workspace config to default -Set project config to default +Set workspace config to default @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param configName Config name - @return ApiSetDefaultProjectConfigRequest + @return ApiSetDefaultWorkspaceConfigRequest */ -func (a *ProjectConfigAPIService) SetDefaultProjectConfig(ctx context.Context, configName string) ApiSetDefaultProjectConfigRequest { - return ApiSetDefaultProjectConfigRequest{ +func (a *WorkspaceConfigAPIService) SetDefaultWorkspaceConfig(ctx context.Context, configName string) ApiSetDefaultWorkspaceConfigRequest { + return ApiSetDefaultWorkspaceConfigRequest{ ApiService: a, ctx: ctx, configName: configName, @@ -516,19 +516,19 @@ func (a *ProjectConfigAPIService) SetDefaultProjectConfig(ctx context.Context, c } // Execute executes the request -func (a *ProjectConfigAPIService) SetDefaultProjectConfigExecute(r ApiSetDefaultProjectConfigRequest) (*http.Response, error) { +func (a *WorkspaceConfigAPIService) SetDefaultWorkspaceConfigExecute(r ApiSetDefaultWorkspaceConfigRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPatch localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProjectConfigAPIService.SetDefaultProjectConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.SetDefaultWorkspaceConfig") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config/{configName}/set-default" + localVarPath := localBasePath + "/workspace-config/{configName}/set-default" localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) localVarHeaderParams := make(map[string]string) @@ -594,57 +594,57 @@ func (a *ProjectConfigAPIService) SetDefaultProjectConfigExecute(r ApiSetDefault return localVarHTTPResponse, nil } -type ApiSetProjectConfigRequest struct { - ctx context.Context - ApiService *ProjectConfigAPIService - projectConfig *CreateProjectConfigDTO +type ApiSetWorkspaceConfigRequest struct { + ctx context.Context + ApiService *WorkspaceConfigAPIService + workspaceConfig *CreateWorkspaceConfigDTO } -// Project config -func (r ApiSetProjectConfigRequest) ProjectConfig(projectConfig CreateProjectConfigDTO) ApiSetProjectConfigRequest { - r.projectConfig = &projectConfig +// Workspace config +func (r ApiSetWorkspaceConfigRequest) WorkspaceConfig(workspaceConfig CreateWorkspaceConfigDTO) ApiSetWorkspaceConfigRequest { + r.workspaceConfig = &workspaceConfig return r } -func (r ApiSetProjectConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.SetProjectConfigExecute(r) +func (r ApiSetWorkspaceConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.SetWorkspaceConfigExecute(r) } /* -SetProjectConfig Set project config data +SetWorkspaceConfig Set workspace config data -Set project config data +Set workspace config data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetProjectConfigRequest + @return ApiSetWorkspaceConfigRequest */ -func (a *ProjectConfigAPIService) SetProjectConfig(ctx context.Context) ApiSetProjectConfigRequest { - return ApiSetProjectConfigRequest{ +func (a *WorkspaceConfigAPIService) SetWorkspaceConfig(ctx context.Context) ApiSetWorkspaceConfigRequest { + return ApiSetWorkspaceConfigRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *ProjectConfigAPIService) SetProjectConfigExecute(r ApiSetProjectConfigRequest) (*http.Response, error) { +func (a *WorkspaceConfigAPIService) SetWorkspaceConfigExecute(r ApiSetWorkspaceConfigRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProjectConfigAPIService.SetProjectConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.SetWorkspaceConfig") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/project-config" + localVarPath := localBasePath + "/workspace-config" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.projectConfig == nil { - return nil, reportError("projectConfig is required and must be specified") + if r.workspaceConfig == nil { + return nil, reportError("workspaceConfig is required and must be specified") } // to determine the Content-Type header @@ -665,7 +665,7 @@ func (a *ProjectConfigAPIService) SetProjectConfigExecute(r ApiSetProjectConfigR localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.projectConfig + localVarPostBody = r.workspaceConfig if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/api_workspace_toolbox.go b/pkg/apiclient/api_workspace_toolbox.go index fa9a17ba8c..d32eca5ef3 100644 --- a/pkg/apiclient/api_workspace_toolbox.go +++ b/pkg/apiclient/api_workspace_toolbox.go @@ -1761,55 +1761,64 @@ func (a *WorkspaceToolboxAPIService) FsUploadFileExecute(r ApiFsUploadFileReques return localVarHTTPResponse, nil } -type ApiGetProjectDirRequest struct { +type ApiGetSessionCommandLogsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string projectId string + sessionId string + commandId string } -func (r ApiGetProjectDirRequest) Execute() (*ProjectDirResponse, *http.Response, error) { - return r.ApiService.GetProjectDirExecute(r) +func (r ApiGetSessionCommandLogsRequest) Execute() (string, *http.Response, error) { + return r.ApiService.GetSessionCommandLogsExecute(r) } /* -GetProjectDir Get project dir +GetSessionCommandLogs Get session command logs -Get project directory +Get logs of a command inside a session inside workspace project +Connect with websocket to get a stream of the logs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name @param projectId Project ID - @return ApiGetProjectDirRequest + @param sessionId Session ID + @param commandId Command ID + @return ApiGetSessionCommandLogsRequest */ -func (a *WorkspaceToolboxAPIService) GetProjectDir(ctx context.Context, workspaceId string, projectId string) ApiGetProjectDirRequest { - return ApiGetProjectDirRequest{ +func (a *WorkspaceToolboxAPIService) GetSessionCommandLogs(ctx context.Context, workspaceId string, projectId string, sessionId string, commandId string) ApiGetSessionCommandLogsRequest { + return ApiGetSessionCommandLogsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, projectId: projectId, + sessionId: sessionId, + commandId: commandId, } } // Execute executes the request // -// @return ProjectDirResponse -func (a *WorkspaceToolboxAPIService) GetProjectDirExecute(r ApiGetProjectDirRequest) (*ProjectDirResponse, *http.Response, error) { +// @return string +func (a *WorkspaceToolboxAPIService) GetSessionCommandLogsExecute(r ApiGetSessionCommandLogsRequest) (string, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *ProjectDirResponse + localVarReturnValue string ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceToolboxAPIService.GetProjectDir") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceToolboxAPIService.GetSessionCommandLogs") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/project-dir" + localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"sessionId"+"}", url.PathEscape(parameterValueToString(r.sessionId, "sessionId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"commandId"+"}", url.PathEscape(parameterValueToString(r.commandId, "commandId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1825,7 +1834,7 @@ func (a *WorkspaceToolboxAPIService) GetProjectDirExecute(r ApiGetProjectDirRequ } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{"*/*"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -1883,64 +1892,55 @@ func (a *WorkspaceToolboxAPIService) GetProjectDirExecute(r ApiGetProjectDirRequ return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetSessionCommandLogsRequest struct { +type ApiGetWorkspaceDirRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string projectId string - sessionId string - commandId string } -func (r ApiGetSessionCommandLogsRequest) Execute() (string, *http.Response, error) { - return r.ApiService.GetSessionCommandLogsExecute(r) +func (r ApiGetWorkspaceDirRequest) Execute() (*WorkspaceDirResponse, *http.Response, error) { + return r.ApiService.GetWorkspaceDirExecute(r) } /* -GetSessionCommandLogs Get session command logs +GetWorkspaceDir Get workspace dir -Get logs of a command inside a session inside workspace project -Connect with websocket to get a stream of the logs +Get workspace directory @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name @param projectId Project ID - @param sessionId Session ID - @param commandId Command ID - @return ApiGetSessionCommandLogsRequest + @return ApiGetWorkspaceDirRequest */ -func (a *WorkspaceToolboxAPIService) GetSessionCommandLogs(ctx context.Context, workspaceId string, projectId string, sessionId string, commandId string) ApiGetSessionCommandLogsRequest { - return ApiGetSessionCommandLogsRequest{ +func (a *WorkspaceToolboxAPIService) GetWorkspaceDir(ctx context.Context, workspaceId string, projectId string) ApiGetWorkspaceDirRequest { + return ApiGetWorkspaceDirRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, projectId: projectId, - sessionId: sessionId, - commandId: commandId, } } // Execute executes the request // -// @return string -func (a *WorkspaceToolboxAPIService) GetSessionCommandLogsExecute(r ApiGetSessionCommandLogsRequest) (string, *http.Response, error) { +// @return WorkspaceDirResponse +func (a *WorkspaceToolboxAPIService) GetWorkspaceDirExecute(r ApiGetWorkspaceDirRequest) (*WorkspaceDirResponse, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue string + localVarReturnValue *WorkspaceDirResponse ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceToolboxAPIService.GetSessionCommandLogs") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceToolboxAPIService.GetWorkspaceDir") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs" + localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/workspace-dir" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"sessionId"+"}", url.PathEscape(parameterValueToString(r.sessionId, "sessionId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"commandId"+"}", url.PathEscape(parameterValueToString(r.commandId, "commandId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1956,7 +1956,7 @@ func (a *WorkspaceToolboxAPIService) GetSessionCommandLogsExecute(r ApiGetSessio } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"*/*"} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index b709600808..c4f47e372b 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -62,8 +62,6 @@ type APIClient struct { ProfileAPI *ProfileAPIService - ProjectConfigAPI *ProjectConfigAPIService - ProviderAPI *ProviderAPIService SampleAPI *SampleAPIService @@ -74,6 +72,8 @@ type APIClient struct { TargetConfigAPI *TargetConfigAPIService + WorkspaceConfigAPI *WorkspaceConfigAPIService + WorkspaceToolboxAPI *WorkspaceToolboxAPIService } @@ -100,12 +100,12 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.GitProviderAPI = (*GitProviderAPIService)(&c.common) c.PrebuildAPI = (*PrebuildAPIService)(&c.common) c.ProfileAPI = (*ProfileAPIService)(&c.common) - c.ProjectConfigAPI = (*ProjectConfigAPIService)(&c.common) c.ProviderAPI = (*ProviderAPIService)(&c.common) c.SampleAPI = (*SampleAPIService)(&c.common) c.ServerAPI = (*ServerAPIService)(&c.common) c.TargetAPI = (*TargetAPIService)(&c.common) c.TargetConfigAPI = (*TargetConfigAPIService)(&c.common) + c.WorkspaceConfigAPI = (*WorkspaceConfigAPIService)(&c.common) c.WorkspaceToolboxAPI = (*WorkspaceToolboxAPIService)(&c.common) return c diff --git a/pkg/apiclient/docs/ApiKey.md b/pkg/apiclient/docs/ApiKey.md index 46fbd9b5dd..996156ee0a 100644 --- a/pkg/apiclient/docs/ApiKey.md +++ b/pkg/apiclient/docs/ApiKey.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **KeyHash** | **string** | | -**Name** | **string** | Project or client name | +**Name** | **string** | Workspace or client name | **Type** | [**ApikeyApiKeyType**](ApikeyApiKeyType.md) | | ## Methods diff --git a/pkg/apiclient/docs/ApikeyApiKeyType.md b/pkg/apiclient/docs/ApikeyApiKeyType.md index 57fc1a3a8f..3471cb39b8 100644 --- a/pkg/apiclient/docs/ApikeyApiKeyType.md +++ b/pkg/apiclient/docs/ApikeyApiKeyType.md @@ -5,7 +5,7 @@ * `ApiKeyTypeClient` (value: `"client"`) -* `ApiKeyTypeProject` (value: `"project"`) +* `ApiKeyTypeWorkspace` (value: `"workspace"`) * `ApiKeyTypeTarget` (value: `"target"`) diff --git a/pkg/apiclient/docs/BuildAPI.md b/pkg/apiclient/docs/BuildAPI.md index 8c001f7e96..86215d58bd 100644 --- a/pkg/apiclient/docs/BuildAPI.md +++ b/pkg/apiclient/docs/BuildAPI.md @@ -34,7 +34,7 @@ import ( ) func main() { - createBuildDto := *openapiclient.NewCreateBuildDTO("Branch_example", map[string]string{"key": "Inner_example"}, "ProjectConfigName_example") // CreateBuildDTO | Create Build DTO + createBuildDto := *openapiclient.NewCreateBuildDTO("Branch_example", map[string]string{"key": "Inner_example"}, "WorkspaceConfigName_example") // CreateBuildDTO | Create Build DTO configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/docs/CreateBuildDTO.md b/pkg/apiclient/docs/CreateBuildDTO.md index f7f23815d4..ac78a8948e 100644 --- a/pkg/apiclient/docs/CreateBuildDTO.md +++ b/pkg/apiclient/docs/CreateBuildDTO.md @@ -7,13 +7,13 @@ Name | Type | Description | Notes **Branch** | **string** | | **EnvVars** | **map[string]string** | | **PrebuildId** | Pointer to **string** | | [optional] -**ProjectConfigName** | **string** | | +**WorkspaceConfigName** | **string** | | ## Methods ### NewCreateBuildDTO -`func NewCreateBuildDTO(branch string, envVars map[string]string, projectConfigName string, ) *CreateBuildDTO` +`func NewCreateBuildDTO(branch string, envVars map[string]string, workspaceConfigName string, ) *CreateBuildDTO` NewCreateBuildDTO instantiates a new CreateBuildDTO object This constructor will assign default values to properties that have it defined, @@ -93,24 +93,24 @@ SetPrebuildId sets PrebuildId field to given value. HasPrebuildId returns a boolean if a field has been set. -### GetProjectConfigName +### GetWorkspaceConfigName -`func (o *CreateBuildDTO) GetProjectConfigName() string` +`func (o *CreateBuildDTO) GetWorkspaceConfigName() string` -GetProjectConfigName returns the ProjectConfigName field if non-nil, zero value otherwise. +GetWorkspaceConfigName returns the WorkspaceConfigName field if non-nil, zero value otherwise. -### GetProjectConfigNameOk +### GetWorkspaceConfigNameOk -`func (o *CreateBuildDTO) GetProjectConfigNameOk() (*string, bool)` +`func (o *CreateBuildDTO) GetWorkspaceConfigNameOk() (*string, bool)` -GetProjectConfigNameOk returns a tuple with the ProjectConfigName field if it's non-nil, zero value otherwise +GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProjectConfigName +### SetWorkspaceConfigName -`func (o *CreateBuildDTO) SetProjectConfigName(v string)` +`func (o *CreateBuildDTO) SetWorkspaceConfigName(v string)` -SetProjectConfigName sets ProjectConfigName field to given value. +SetWorkspaceConfigName sets WorkspaceConfigName field to given value. diff --git a/pkg/apiclient/docs/CreateTargetDTO.md b/pkg/apiclient/docs/CreateTargetDTO.md index 7b53c79eb2..1f58d676d7 100644 --- a/pkg/apiclient/docs/CreateTargetDTO.md +++ b/pkg/apiclient/docs/CreateTargetDTO.md @@ -6,14 +6,14 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Id** | **string** | | **Name** | **string** | | -**Projects** | [**[]CreateProjectDTO**](CreateProjectDTO.md) | | **TargetConfig** | **string** | | +**Workspaces** | [**[]CreateWorkspaceDTO**](CreateWorkspaceDTO.md) | | ## Methods ### NewCreateTargetDTO -`func NewCreateTargetDTO(id string, name string, projects []CreateProjectDTO, targetConfig string, ) *CreateTargetDTO` +`func NewCreateTargetDTO(id string, name string, targetConfig string, workspaces []CreateWorkspaceDTO, ) *CreateTargetDTO` NewCreateTargetDTO instantiates a new CreateTargetDTO object This constructor will assign default values to properties that have it defined, @@ -68,44 +68,44 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetProjects +### GetTargetConfig -`func (o *CreateTargetDTO) GetProjects() []CreateProjectDTO` +`func (o *CreateTargetDTO) GetTargetConfig() string` -GetProjects returns the Projects field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetProjectsOk +### GetTargetConfigOk -`func (o *CreateTargetDTO) GetProjectsOk() (*[]CreateProjectDTO, bool)` +`func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool)` -GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProjects +### SetTargetConfig -`func (o *CreateTargetDTO) SetProjects(v []CreateProjectDTO)` +`func (o *CreateTargetDTO) SetTargetConfig(v string)` -SetProjects sets Projects field to given value. +SetTargetConfig sets TargetConfig field to given value. -### GetTargetConfig +### GetWorkspaces -`func (o *CreateTargetDTO) GetTargetConfig() string` +`func (o *CreateTargetDTO) GetWorkspaces() []CreateWorkspaceDTO` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetWorkspacesOk -`func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool)` +`func (o *CreateTargetDTO) GetWorkspacesOk() (*[]CreateWorkspaceDTO, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetWorkspaces -`func (o *CreateTargetDTO) SetTargetConfig(v string)` +`func (o *CreateTargetDTO) SetWorkspaces(v []CreateWorkspaceDTO)` -SetTargetConfig sets TargetConfig field to given value. +SetWorkspaces sets Workspaces field to given value. diff --git a/pkg/apiclient/docs/CreateProjectConfigDTO.md b/pkg/apiclient/docs/CreateWorkspaceConfigDTO.md similarity index 63% rename from pkg/apiclient/docs/CreateProjectConfigDTO.md rename to pkg/apiclient/docs/CreateWorkspaceConfigDTO.md index f421b5d580..09697612e0 100644 --- a/pkg/apiclient/docs/CreateProjectConfigDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceConfigDTO.md @@ -1,4 +1,4 @@ -# CreateProjectConfigDTO +# CreateWorkspaceConfigDTO ## Properties @@ -14,180 +14,180 @@ Name | Type | Description | Notes ## Methods -### NewCreateProjectConfigDTO +### NewCreateWorkspaceConfigDTO -`func NewCreateProjectConfigDTO(envVars map[string]string, name string, repositoryUrl string, ) *CreateProjectConfigDTO` +`func NewCreateWorkspaceConfigDTO(envVars map[string]string, name string, repositoryUrl string, ) *CreateWorkspaceConfigDTO` -NewCreateProjectConfigDTO instantiates a new CreateProjectConfigDTO object +NewCreateWorkspaceConfigDTO instantiates a new CreateWorkspaceConfigDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateProjectConfigDTOWithDefaults +### NewCreateWorkspaceConfigDTOWithDefaults -`func NewCreateProjectConfigDTOWithDefaults() *CreateProjectConfigDTO` +`func NewCreateWorkspaceConfigDTOWithDefaults() *CreateWorkspaceConfigDTO` -NewCreateProjectConfigDTOWithDefaults instantiates a new CreateProjectConfigDTO object +NewCreateWorkspaceConfigDTOWithDefaults instantiates a new CreateWorkspaceConfigDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *CreateProjectConfigDTO) GetBuildConfig() BuildConfig` +`func (o *CreateWorkspaceConfigDTO) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *CreateProjectConfigDTO) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *CreateWorkspaceConfigDTO) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *CreateProjectConfigDTO) SetBuildConfig(v BuildConfig)` +`func (o *CreateWorkspaceConfigDTO) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *CreateProjectConfigDTO) HasBuildConfig() bool` +`func (o *CreateWorkspaceConfigDTO) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetEnvVars -`func (o *CreateProjectConfigDTO) GetEnvVars() map[string]string` +`func (o *CreateWorkspaceConfigDTO) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *CreateProjectConfigDTO) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *CreateWorkspaceConfigDTO) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *CreateProjectConfigDTO) SetEnvVars(v map[string]string)` +`func (o *CreateWorkspaceConfigDTO) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *CreateProjectConfigDTO) GetGitProviderConfigId() string` +`func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *CreateProjectConfigDTO) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *CreateProjectConfigDTO) SetGitProviderConfigId(v string)` +`func (o *CreateWorkspaceConfigDTO) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *CreateProjectConfigDTO) HasGitProviderConfigId() bool` +`func (o *CreateWorkspaceConfigDTO) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetImage -`func (o *CreateProjectConfigDTO) GetImage() string` +`func (o *CreateWorkspaceConfigDTO) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *CreateProjectConfigDTO) GetImageOk() (*string, bool)` +`func (o *CreateWorkspaceConfigDTO) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *CreateProjectConfigDTO) SetImage(v string)` +`func (o *CreateWorkspaceConfigDTO) SetImage(v string)` SetImage sets Image field to given value. ### HasImage -`func (o *CreateProjectConfigDTO) HasImage() bool` +`func (o *CreateWorkspaceConfigDTO) HasImage() bool` HasImage returns a boolean if a field has been set. ### GetName -`func (o *CreateProjectConfigDTO) GetName() string` +`func (o *CreateWorkspaceConfigDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *CreateProjectConfigDTO) GetNameOk() (*string, bool)` +`func (o *CreateWorkspaceConfigDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *CreateProjectConfigDTO) SetName(v string)` +`func (o *CreateWorkspaceConfigDTO) SetName(v string)` SetName sets Name field to given value. ### GetRepositoryUrl -`func (o *CreateProjectConfigDTO) GetRepositoryUrl() string` +`func (o *CreateWorkspaceConfigDTO) GetRepositoryUrl() string` GetRepositoryUrl returns the RepositoryUrl field if non-nil, zero value otherwise. ### GetRepositoryUrlOk -`func (o *CreateProjectConfigDTO) GetRepositoryUrlOk() (*string, bool)` +`func (o *CreateWorkspaceConfigDTO) GetRepositoryUrlOk() (*string, bool)` GetRepositoryUrlOk returns a tuple with the RepositoryUrl field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepositoryUrl -`func (o *CreateProjectConfigDTO) SetRepositoryUrl(v string)` +`func (o *CreateWorkspaceConfigDTO) SetRepositoryUrl(v string)` SetRepositoryUrl sets RepositoryUrl field to given value. ### GetUser -`func (o *CreateProjectConfigDTO) GetUser() string` +`func (o *CreateWorkspaceConfigDTO) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *CreateProjectConfigDTO) GetUserOk() (*string, bool)` +`func (o *CreateWorkspaceConfigDTO) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *CreateProjectConfigDTO) SetUser(v string)` +`func (o *CreateWorkspaceConfigDTO) SetUser(v string)` SetUser sets User field to given value. ### HasUser -`func (o *CreateProjectConfigDTO) HasUser() bool` +`func (o *CreateWorkspaceConfigDTO) HasUser() bool` HasUser returns a boolean if a field has been set. diff --git a/pkg/apiclient/docs/CreateProjectDTO.md b/pkg/apiclient/docs/CreateWorkspaceDTO.md similarity index 64% rename from pkg/apiclient/docs/CreateProjectDTO.md rename to pkg/apiclient/docs/CreateWorkspaceDTO.md index e084e5a9e5..f3e6a2b806 100644 --- a/pkg/apiclient/docs/CreateProjectDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceDTO.md @@ -1,4 +1,4 @@ -# CreateProjectDTO +# CreateWorkspaceDTO ## Properties @@ -9,185 +9,185 @@ Name | Type | Description | Notes **GitProviderConfigId** | Pointer to **string** | | [optional] **Image** | Pointer to **string** | | [optional] **Name** | **string** | | -**Source** | [**CreateProjectSourceDTO**](CreateProjectSourceDTO.md) | | +**Source** | [**CreateWorkspaceSourceDTO**](CreateWorkspaceSourceDTO.md) | | **User** | Pointer to **string** | | [optional] ## Methods -### NewCreateProjectDTO +### NewCreateWorkspaceDTO -`func NewCreateProjectDTO(envVars map[string]string, name string, source CreateProjectSourceDTO, ) *CreateProjectDTO` +`func NewCreateWorkspaceDTO(envVars map[string]string, name string, source CreateWorkspaceSourceDTO, ) *CreateWorkspaceDTO` -NewCreateProjectDTO instantiates a new CreateProjectDTO object +NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateProjectDTOWithDefaults +### NewCreateWorkspaceDTOWithDefaults -`func NewCreateProjectDTOWithDefaults() *CreateProjectDTO` +`func NewCreateWorkspaceDTOWithDefaults() *CreateWorkspaceDTO` -NewCreateProjectDTOWithDefaults instantiates a new CreateProjectDTO object +NewCreateWorkspaceDTOWithDefaults instantiates a new CreateWorkspaceDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *CreateProjectDTO) GetBuildConfig() BuildConfig` +`func (o *CreateWorkspaceDTO) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *CreateProjectDTO) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *CreateWorkspaceDTO) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *CreateProjectDTO) SetBuildConfig(v BuildConfig)` +`func (o *CreateWorkspaceDTO) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *CreateProjectDTO) HasBuildConfig() bool` +`func (o *CreateWorkspaceDTO) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetEnvVars -`func (o *CreateProjectDTO) GetEnvVars() map[string]string` +`func (o *CreateWorkspaceDTO) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *CreateProjectDTO) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *CreateWorkspaceDTO) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *CreateProjectDTO) SetEnvVars(v map[string]string)` +`func (o *CreateWorkspaceDTO) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *CreateProjectDTO) GetGitProviderConfigId() string` +`func (o *CreateWorkspaceDTO) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *CreateProjectDTO) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *CreateWorkspaceDTO) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *CreateProjectDTO) SetGitProviderConfigId(v string)` +`func (o *CreateWorkspaceDTO) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *CreateProjectDTO) HasGitProviderConfigId() bool` +`func (o *CreateWorkspaceDTO) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetImage -`func (o *CreateProjectDTO) GetImage() string` +`func (o *CreateWorkspaceDTO) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *CreateProjectDTO) GetImageOk() (*string, bool)` +`func (o *CreateWorkspaceDTO) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *CreateProjectDTO) SetImage(v string)` +`func (o *CreateWorkspaceDTO) SetImage(v string)` SetImage sets Image field to given value. ### HasImage -`func (o *CreateProjectDTO) HasImage() bool` +`func (o *CreateWorkspaceDTO) HasImage() bool` HasImage returns a boolean if a field has been set. ### GetName -`func (o *CreateProjectDTO) GetName() string` +`func (o *CreateWorkspaceDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *CreateProjectDTO) GetNameOk() (*string, bool)` +`func (o *CreateWorkspaceDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *CreateProjectDTO) SetName(v string)` +`func (o *CreateWorkspaceDTO) SetName(v string)` SetName sets Name field to given value. ### GetSource -`func (o *CreateProjectDTO) GetSource() CreateProjectSourceDTO` +`func (o *CreateWorkspaceDTO) GetSource() CreateWorkspaceSourceDTO` GetSource returns the Source field if non-nil, zero value otherwise. ### GetSourceOk -`func (o *CreateProjectDTO) GetSourceOk() (*CreateProjectSourceDTO, bool)` +`func (o *CreateWorkspaceDTO) GetSourceOk() (*CreateWorkspaceSourceDTO, bool)` GetSourceOk returns a tuple with the Source field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetSource -`func (o *CreateProjectDTO) SetSource(v CreateProjectSourceDTO)` +`func (o *CreateWorkspaceDTO) SetSource(v CreateWorkspaceSourceDTO)` SetSource sets Source field to given value. ### GetUser -`func (o *CreateProjectDTO) GetUser() string` +`func (o *CreateWorkspaceDTO) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *CreateProjectDTO) GetUserOk() (*string, bool)` +`func (o *CreateWorkspaceDTO) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *CreateProjectDTO) SetUser(v string)` +`func (o *CreateWorkspaceDTO) SetUser(v string)` SetUser sets User field to given value. ### HasUser -`func (o *CreateProjectDTO) HasUser() bool` +`func (o *CreateWorkspaceDTO) HasUser() bool` HasUser returns a boolean if a field has been set. diff --git a/pkg/apiclient/docs/CreateProjectSourceDTO.md b/pkg/apiclient/docs/CreateWorkspaceSourceDTO.md similarity index 62% rename from pkg/apiclient/docs/CreateProjectSourceDTO.md rename to pkg/apiclient/docs/CreateWorkspaceSourceDTO.md index 88591b19f1..3386a801f7 100644 --- a/pkg/apiclient/docs/CreateProjectSourceDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceSourceDTO.md @@ -1,4 +1,4 @@ -# CreateProjectSourceDTO +# CreateWorkspaceSourceDTO ## Properties @@ -8,39 +8,39 @@ Name | Type | Description | Notes ## Methods -### NewCreateProjectSourceDTO +### NewCreateWorkspaceSourceDTO -`func NewCreateProjectSourceDTO(repository GitRepository, ) *CreateProjectSourceDTO` +`func NewCreateWorkspaceSourceDTO(repository GitRepository, ) *CreateWorkspaceSourceDTO` -NewCreateProjectSourceDTO instantiates a new CreateProjectSourceDTO object +NewCreateWorkspaceSourceDTO instantiates a new CreateWorkspaceSourceDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateProjectSourceDTOWithDefaults +### NewCreateWorkspaceSourceDTOWithDefaults -`func NewCreateProjectSourceDTOWithDefaults() *CreateProjectSourceDTO` +`func NewCreateWorkspaceSourceDTOWithDefaults() *CreateWorkspaceSourceDTO` -NewCreateProjectSourceDTOWithDefaults instantiates a new CreateProjectSourceDTO object +NewCreateWorkspaceSourceDTOWithDefaults instantiates a new CreateWorkspaceSourceDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetRepository -`func (o *CreateProjectSourceDTO) GetRepository() GitRepository` +`func (o *CreateWorkspaceSourceDTO) GetRepository() GitRepository` GetRepository returns the Repository field if non-nil, zero value otherwise. ### GetRepositoryOk -`func (o *CreateProjectSourceDTO) GetRepositoryOk() (*GitRepository, bool)` +`func (o *CreateWorkspaceSourceDTO) GetRepositoryOk() (*GitRepository, bool)` GetRepositoryOk returns a tuple with the Repository field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepository -`func (o *CreateProjectSourceDTO) SetRepository(v GitRepository)` +`func (o *CreateWorkspaceSourceDTO) SetRepository(v GitRepository)` SetRepository sets Repository field to given value. diff --git a/pkg/apiclient/docs/PrebuildAPI.md b/pkg/apiclient/docs/PrebuildAPI.md index 5c98f91247..04eef269ce 100644 --- a/pkg/apiclient/docs/PrebuildAPI.md +++ b/pkg/apiclient/docs/PrebuildAPI.md @@ -4,12 +4,12 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**DeletePrebuild**](PrebuildAPI.md#DeletePrebuild) | **Delete** /project-config/{configName}/prebuild/{prebuildId} | Delete prebuild -[**GetPrebuild**](PrebuildAPI.md#GetPrebuild) | **Get** /project-config/{configName}/prebuild/{prebuildId} | Get prebuild -[**ListPrebuilds**](PrebuildAPI.md#ListPrebuilds) | **Get** /project-config/prebuild | List prebuilds -[**ListPrebuildsForProjectConfig**](PrebuildAPI.md#ListPrebuildsForProjectConfig) | **Get** /project-config/{configName}/prebuild | List prebuilds for project config -[**ProcessGitEvent**](PrebuildAPI.md#ProcessGitEvent) | **Post** /project-config/prebuild/process-git-event | ProcessGitEvent -[**SetPrebuild**](PrebuildAPI.md#SetPrebuild) | **Put** /project-config/{configName}/prebuild | Set prebuild +[**DeletePrebuild**](PrebuildAPI.md#DeletePrebuild) | **Delete** /workspace-config/{configName}/prebuild/{prebuildId} | Delete prebuild +[**GetPrebuild**](PrebuildAPI.md#GetPrebuild) | **Get** /workspace-config/{configName}/prebuild/{prebuildId} | Get prebuild +[**ListPrebuilds**](PrebuildAPI.md#ListPrebuilds) | **Get** /workspace-config/prebuild | List prebuilds +[**ListPrebuildsForWorkspaceConfig**](PrebuildAPI.md#ListPrebuildsForWorkspaceConfig) | **Get** /workspace-config/{configName}/prebuild | List prebuilds for workspace config +[**ProcessGitEvent**](PrebuildAPI.md#ProcessGitEvent) | **Post** /workspace-config/prebuild/process-git-event | ProcessGitEvent +[**SetPrebuild**](PrebuildAPI.md#SetPrebuild) | **Put** /workspace-config/{configName}/prebuild | Set prebuild @@ -34,7 +34,7 @@ import ( ) func main() { - configName := "configName_example" // string | Project config name + configName := "configName_example" // string | Workspace config name prebuildId := "prebuildId_example" // string | Prebuild ID force := true // bool | Force (optional) @@ -54,7 +54,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Project config name | +**configName** | **string** | Workspace config name | **prebuildId** | **string** | Prebuild ID | ### Other Parameters @@ -107,7 +107,7 @@ import ( ) func main() { - configName := "configName_example" // string | Project config name + configName := "configName_example" // string | Workspace config name prebuildId := "prebuildId_example" // string | Prebuild ID configuration := openapiclient.NewConfiguration() @@ -128,7 +128,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Project config name | +**configName** | **string** | Workspace config name | **prebuildId** | **string** | Prebuild ID | ### Other Parameters @@ -220,11 +220,11 @@ Other parameters are passed through a pointer to a apiListPrebuildsRequest struc [[Back to README]](../README.md) -## ListPrebuildsForProjectConfig +## ListPrebuildsForWorkspaceConfig -> []PrebuildDTO ListPrebuildsForProjectConfig(ctx, configName).Execute() +> []PrebuildDTO ListPrebuildsForWorkspaceConfig(ctx, configName).Execute() -List prebuilds for project config +List prebuilds for workspace config @@ -245,13 +245,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.PrebuildAPI.ListPrebuildsForProjectConfig(context.Background(), configName).Execute() + resp, r, err := apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(context.Background(), configName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.ListPrebuildsForProjectConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.ListPrebuildsForWorkspaceConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListPrebuildsForProjectConfig`: []PrebuildDTO - fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.ListPrebuildsForProjectConfig`: %v\n", resp) + // response from `ListPrebuildsForWorkspaceConfig`: []PrebuildDTO + fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.ListPrebuildsForWorkspaceConfig`: %v\n", resp) } ``` @@ -265,7 +265,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiListPrebuildsForProjectConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListPrebuildsForWorkspaceConfigRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/PrebuildDTO.md b/pkg/apiclient/docs/PrebuildDTO.md index edae1929af..649f5c2534 100644 --- a/pkg/apiclient/docs/PrebuildDTO.md +++ b/pkg/apiclient/docs/PrebuildDTO.md @@ -7,15 +7,15 @@ Name | Type | Description | Notes **Branch** | **string** | | **CommitInterval** | Pointer to **int32** | | [optional] **Id** | **string** | | -**ProjectConfigName** | **string** | | **Retention** | **int32** | | **TriggerFiles** | Pointer to **[]string** | | [optional] +**WorkspaceConfigName** | **string** | | ## Methods ### NewPrebuildDTO -`func NewPrebuildDTO(branch string, id string, projectConfigName string, retention int32, ) *PrebuildDTO` +`func NewPrebuildDTO(branch string, id string, retention int32, workspaceConfigName string, ) *PrebuildDTO` NewPrebuildDTO instantiates a new PrebuildDTO object This constructor will assign default values to properties that have it defined, @@ -95,26 +95,6 @@ and a boolean to check if the value has been set. SetId sets Id field to given value. -### GetProjectConfigName - -`func (o *PrebuildDTO) GetProjectConfigName() string` - -GetProjectConfigName returns the ProjectConfigName field if non-nil, zero value otherwise. - -### GetProjectConfigNameOk - -`func (o *PrebuildDTO) GetProjectConfigNameOk() (*string, bool)` - -GetProjectConfigNameOk returns a tuple with the ProjectConfigName field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetProjectConfigName - -`func (o *PrebuildDTO) SetProjectConfigName(v string)` - -SetProjectConfigName sets ProjectConfigName field to given value. - - ### GetRetention `func (o *PrebuildDTO) GetRetention() int32` @@ -160,6 +140,26 @@ SetTriggerFiles sets TriggerFiles field to given value. HasTriggerFiles returns a boolean if a field has been set. +### GetWorkspaceConfigName + +`func (o *PrebuildDTO) GetWorkspaceConfigName() string` + +GetWorkspaceConfigName returns the WorkspaceConfigName field if non-nil, zero value otherwise. + +### GetWorkspaceConfigNameOk + +`func (o *PrebuildDTO) GetWorkspaceConfigNameOk() (*string, bool)` + +GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetWorkspaceConfigName + +`func (o *PrebuildDTO) SetWorkspaceConfigName(v string)` + +SetWorkspaceConfigName sets WorkspaceConfigName field to given value. + + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/ServerAPI.md b/pkg/apiclient/docs/ServerAPI.md index 38b0b61ac6..8cf9dfa538 100644 --- a/pkg/apiclient/docs/ServerAPI.md +++ b/pkg/apiclient/docs/ServerAPI.md @@ -215,7 +215,7 @@ import ( ) func main() { - config := *openapiclient.NewServerConfig(int32(123), "BinariesPath_example", "BuilderImage_example", "BuilderRegistryServer_example", "DefaultProjectImage_example", "DefaultProjectUser_example", int32(123), "Id_example", "LocalBuilderRegistryImage_example", int32(123), *openapiclient.NewLogFileConfig(int32(123), int32(123), int32(123), "Path_example"), "ProvidersDir_example", "RegistryUrl_example", "ServerDownloadUrl_example") // ServerConfig | Server configuration + config := *openapiclient.NewServerConfig(int32(123), "BinariesPath_example", "BuilderImage_example", "BuilderRegistryServer_example", "DefaultWorkspaceImage_example", "DefaultWorkspaceUser_example", int32(123), "Id_example", "LocalBuilderRegistryImage_example", int32(123), *openapiclient.NewLogFileConfig(int32(123), int32(123), int32(123), "Path_example"), "ProvidersDir_example", "RegistryUrl_example", "ServerDownloadUrl_example") // ServerConfig | Server configuration configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/docs/ServerConfig.md b/pkg/apiclient/docs/ServerConfig.md index 3288de7691..e4bf2fea6b 100644 --- a/pkg/apiclient/docs/ServerConfig.md +++ b/pkg/apiclient/docs/ServerConfig.md @@ -9,8 +9,8 @@ Name | Type | Description | Notes **BuildImageNamespace** | Pointer to **string** | | [optional] **BuilderImage** | **string** | | **BuilderRegistryServer** | **string** | | -**DefaultProjectImage** | **string** | | -**DefaultProjectUser** | **string** | | +**DefaultWorkspaceImage** | **string** | | +**DefaultWorkspaceUser** | **string** | | **Frps** | Pointer to [**FRPSConfig**](FRPSConfig.md) | | [optional] **HeadscalePort** | **int32** | | **Id** | **string** | | @@ -26,7 +26,7 @@ Name | Type | Description | Notes ### NewServerConfig -`func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultProjectImage string, defaultProjectUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, providersDir string, registryUrl string, serverDownloadUrl string, ) *ServerConfig` +`func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultWorkspaceImage string, defaultWorkspaceUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, providersDir string, registryUrl string, serverDownloadUrl string, ) *ServerConfig` NewServerConfig instantiates a new ServerConfig object This constructor will assign default values to properties that have it defined, @@ -146,44 +146,44 @@ and a boolean to check if the value has been set. SetBuilderRegistryServer sets BuilderRegistryServer field to given value. -### GetDefaultProjectImage +### GetDefaultWorkspaceImage -`func (o *ServerConfig) GetDefaultProjectImage() string` +`func (o *ServerConfig) GetDefaultWorkspaceImage() string` -GetDefaultProjectImage returns the DefaultProjectImage field if non-nil, zero value otherwise. +GetDefaultWorkspaceImage returns the DefaultWorkspaceImage field if non-nil, zero value otherwise. -### GetDefaultProjectImageOk +### GetDefaultWorkspaceImageOk -`func (o *ServerConfig) GetDefaultProjectImageOk() (*string, bool)` +`func (o *ServerConfig) GetDefaultWorkspaceImageOk() (*string, bool)` -GetDefaultProjectImageOk returns a tuple with the DefaultProjectImage field if it's non-nil, zero value otherwise +GetDefaultWorkspaceImageOk returns a tuple with the DefaultWorkspaceImage field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetDefaultProjectImage +### SetDefaultWorkspaceImage -`func (o *ServerConfig) SetDefaultProjectImage(v string)` +`func (o *ServerConfig) SetDefaultWorkspaceImage(v string)` -SetDefaultProjectImage sets DefaultProjectImage field to given value. +SetDefaultWorkspaceImage sets DefaultWorkspaceImage field to given value. -### GetDefaultProjectUser +### GetDefaultWorkspaceUser -`func (o *ServerConfig) GetDefaultProjectUser() string` +`func (o *ServerConfig) GetDefaultWorkspaceUser() string` -GetDefaultProjectUser returns the DefaultProjectUser field if non-nil, zero value otherwise. +GetDefaultWorkspaceUser returns the DefaultWorkspaceUser field if non-nil, zero value otherwise. -### GetDefaultProjectUserOk +### GetDefaultWorkspaceUserOk -`func (o *ServerConfig) GetDefaultProjectUserOk() (*string, bool)` +`func (o *ServerConfig) GetDefaultWorkspaceUserOk() (*string, bool)` -GetDefaultProjectUserOk returns a tuple with the DefaultProjectUser field if it's non-nil, zero value otherwise +GetDefaultWorkspaceUserOk returns a tuple with the DefaultWorkspaceUser field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetDefaultProjectUser +### SetDefaultWorkspaceUser -`func (o *ServerConfig) SetDefaultProjectUser(v string)` +`func (o *ServerConfig) SetDefaultWorkspaceUser(v string)` -SetDefaultProjectUser sets DefaultProjectUser field to given value. +SetDefaultWorkspaceUser sets DefaultWorkspaceUser field to given value. ### GetFrps diff --git a/pkg/apiclient/docs/SetProjectState.md b/pkg/apiclient/docs/SetWorkspaceState.md similarity index 66% rename from pkg/apiclient/docs/SetProjectState.md rename to pkg/apiclient/docs/SetWorkspaceState.md index 662ed9d98f..d1592277de 100644 --- a/pkg/apiclient/docs/SetProjectState.md +++ b/pkg/apiclient/docs/SetWorkspaceState.md @@ -1,4 +1,4 @@ -# SetProjectState +# SetWorkspaceState ## Properties @@ -9,64 +9,64 @@ Name | Type | Description | Notes ## Methods -### NewSetProjectState +### NewSetWorkspaceState -`func NewSetProjectState(uptime int32, ) *SetProjectState` +`func NewSetWorkspaceState(uptime int32, ) *SetWorkspaceState` -NewSetProjectState instantiates a new SetProjectState object +NewSetWorkspaceState instantiates a new SetWorkspaceState object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewSetProjectStateWithDefaults +### NewSetWorkspaceStateWithDefaults -`func NewSetProjectStateWithDefaults() *SetProjectState` +`func NewSetWorkspaceStateWithDefaults() *SetWorkspaceState` -NewSetProjectStateWithDefaults instantiates a new SetProjectState object +NewSetWorkspaceStateWithDefaults instantiates a new SetWorkspaceState object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetGitStatus -`func (o *SetProjectState) GetGitStatus() GitStatus` +`func (o *SetWorkspaceState) GetGitStatus() GitStatus` GetGitStatus returns the GitStatus field if non-nil, zero value otherwise. ### GetGitStatusOk -`func (o *SetProjectState) GetGitStatusOk() (*GitStatus, bool)` +`func (o *SetWorkspaceState) GetGitStatusOk() (*GitStatus, bool)` GetGitStatusOk returns a tuple with the GitStatus field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitStatus -`func (o *SetProjectState) SetGitStatus(v GitStatus)` +`func (o *SetWorkspaceState) SetGitStatus(v GitStatus)` SetGitStatus sets GitStatus field to given value. ### HasGitStatus -`func (o *SetProjectState) HasGitStatus() bool` +`func (o *SetWorkspaceState) HasGitStatus() bool` HasGitStatus returns a boolean if a field has been set. ### GetUptime -`func (o *SetProjectState) GetUptime() int32` +`func (o *SetWorkspaceState) GetUptime() int32` GetUptime returns the Uptime field if non-nil, zero value otherwise. ### GetUptimeOk -`func (o *SetProjectState) GetUptimeOk() (*int32, bool)` +`func (o *SetWorkspaceState) GetUptimeOk() (*int32, bool)` GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUptime -`func (o *SetProjectState) SetUptime(v int32)` +`func (o *SetWorkspaceState) SetUptime(v int32)` SetUptime sets Uptime field to given value. diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index b73a3981f8..b26c5098bb 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -6,14 +6,14 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Id** | **string** | | **Name** | **string** | | -**Projects** | [**[]Project**](Project.md) | | **TargetConfig** | **string** | | +**Workspaces** | [**[]Workspace**](Workspace.md) | | ## Methods ### NewTarget -`func NewTarget(id string, name string, projects []Project, targetConfig string, ) *Target` +`func NewTarget(id string, name string, targetConfig string, workspaces []Workspace, ) *Target` NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, @@ -68,44 +68,44 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetProjects +### GetTargetConfig -`func (o *Target) GetProjects() []Project` +`func (o *Target) GetTargetConfig() string` -GetProjects returns the Projects field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetProjectsOk +### GetTargetConfigOk -`func (o *Target) GetProjectsOk() (*[]Project, bool)` +`func (o *Target) GetTargetConfigOk() (*string, bool)` -GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProjects +### SetTargetConfig -`func (o *Target) SetProjects(v []Project)` +`func (o *Target) SetTargetConfig(v string)` -SetProjects sets Projects field to given value. +SetTargetConfig sets TargetConfig field to given value. -### GetTargetConfig +### GetWorkspaces -`func (o *Target) GetTargetConfig() string` +`func (o *Target) GetWorkspaces() []Workspace` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetWorkspacesOk -`func (o *Target) GetTargetConfigOk() (*string, bool)` +`func (o *Target) GetWorkspacesOk() (*[]Workspace, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetWorkspaces -`func (o *Target) SetTargetConfig(v string)` +`func (o *Target) SetWorkspaces(v []Workspace)` -SetTargetConfig sets TargetConfig field to given value. +SetWorkspaces sets Workspaces field to given value. diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index 60376ebf4d..64fe33c33d 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -8,11 +8,11 @@ Method | HTTP request | Description [**GetTarget**](TargetAPI.md#GetTarget) | **Get** /target/{targetId} | Get target info [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets [**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target -[**SetProjectState**](TargetAPI.md#SetProjectState) | **Post** /target/{targetId}/{projectId}/state | Set project state -[**StartProject**](TargetAPI.md#StartProject) | **Post** /target/{targetId}/{projectId}/start | Start project +[**SetWorkspaceState**](TargetAPI.md#SetWorkspaceState) | **Post** /target/{targetId}/{workspaceId}/state | Set workspace state [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target -[**StopProject**](TargetAPI.md#StopProject) | **Post** /target/{targetId}/{projectId}/stop | Stop project +[**StartWorkspace**](TargetAPI.md#StartWorkspace) | **Post** /target/{targetId}/{workspaceId}/start | Start workspace [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target +[**StopWorkspace**](TargetAPI.md#StopWorkspace) | **Post** /target/{targetId}/{workspaceId}/stop | Stop workspace @@ -37,7 +37,7 @@ import ( ) func main() { - target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", []openapiclient.CreateProjectDTO{*openapiclient.NewCreateProjectDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateProjectSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}, "TargetConfig_example") // CreateTargetDTO | Create target + target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfig_example", []openapiclient.CreateWorkspaceDTO{*openapiclient.NewCreateWorkspaceDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateWorkspaceSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}) // CreateTargetDTO | Create target configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) @@ -290,11 +290,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetProjectState +## SetWorkspaceState -> SetProjectState(ctx, targetId, projectId).SetState(setState).Execute() +> SetWorkspaceState(ctx, targetId, workspaceId).SetState(setState).Execute() -Set project state +Set workspace state @@ -312,14 +312,14 @@ import ( func main() { targetId := "targetId_example" // string | Target ID or Name - projectId := "projectId_example" // string | Project ID - setState := *openapiclient.NewSetProjectState(int32(123)) // SetProjectState | Set State + workspaceId := "workspaceId_example" // string | Workspace ID + setState := *openapiclient.NewSetWorkspaceState(int32(123)) // SetWorkspaceState | Set State configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.SetProjectState(context.Background(), targetId, projectId).SetState(setState).Execute() + r, err := apiClient.TargetAPI.SetWorkspaceState(context.Background(), targetId, workspaceId).SetState(setState).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetProjectState``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetWorkspaceState``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -332,18 +332,18 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **targetId** | **string** | Target ID or Name | -**projectId** | **string** | Project ID | +**workspaceId** | **string** | Workspace ID | ### Other Parameters -Other parameters are passed through a pointer to a apiSetProjectStateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetWorkspaceStateRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **setState** | [**SetProjectState**](SetProjectState.md) | Set State | + **setState** | [**SetWorkspaceState**](SetWorkspaceState.md) | Set State | ### Return type @@ -363,11 +363,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StartProject +## StartTarget -> StartProject(ctx, targetId, projectId).Execute() +> StartTarget(ctx, targetId).Execute() -Start project +Start target @@ -385,13 +385,12 @@ import ( func main() { targetId := "targetId_example" // string | Target ID or Name - projectId := "projectId_example" // string | Project ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StartProject(context.Background(), targetId, projectId).Execute() + r, err := apiClient.TargetAPI.StartTarget(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartProject``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -404,18 +403,16 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **targetId** | **string** | Target ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters -Other parameters are passed through a pointer to a apiStartProjectRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStartTargetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - ### Return type (empty response body) @@ -434,11 +431,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StartTarget +## StartWorkspace -> StartTarget(ctx, targetId).Execute() +> StartWorkspace(ctx, targetId, workspaceId).Execute() -Start target +Start workspace @@ -456,12 +453,13 @@ import ( func main() { targetId := "targetId_example" // string | Target ID or Name + workspaceId := "workspaceId_example" // string | Workspace ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StartTarget(context.Background(), targetId).Execute() + r, err := apiClient.TargetAPI.StartWorkspace(context.Background(), targetId, workspaceId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -474,16 +472,18 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **targetId** | **string** | Target ID or Name | +**workspaceId** | **string** | Workspace ID | ### Other Parameters -Other parameters are passed through a pointer to a apiStartTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStartWorkspaceRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + ### Return type (empty response body) @@ -502,11 +502,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StopProject +## StopTarget -> StopProject(ctx, targetId, projectId).Execute() +> StopTarget(ctx, targetId).Execute() -Stop project +Stop target @@ -524,13 +524,12 @@ import ( func main() { targetId := "targetId_example" // string | Target ID or Name - projectId := "projectId_example" // string | Project ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StopProject(context.Background(), targetId, projectId).Execute() + r, err := apiClient.TargetAPI.StopTarget(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopProject``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -543,18 +542,16 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **targetId** | **string** | Target ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters -Other parameters are passed through a pointer to a apiStopProjectRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStopTargetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - ### Return type (empty response body) @@ -573,11 +570,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StopTarget +## StopWorkspace -> StopTarget(ctx, targetId).Execute() +> StopWorkspace(ctx, targetId, workspaceId).Execute() -Stop target +Stop workspace @@ -595,12 +592,13 @@ import ( func main() { targetId := "targetId_example" // string | Target ID or Name + workspaceId := "workspaceId_example" // string | Workspace ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StopTarget(context.Background(), targetId).Execute() + r, err := apiClient.TargetAPI.StopWorkspace(context.Background(), targetId, workspaceId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -613,16 +611,18 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **targetId** | **string** | Target ID or Name | +**workspaceId** | **string** | Workspace ID | ### Other Parameters -Other parameters are passed through a pointer to a apiStopTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStopWorkspaceRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + ### Return type (empty response body) diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index 7694b2dd6c..6a256f2f7b 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -7,14 +7,14 @@ Name | Type | Description | Notes **Id** | **string** | | **Info** | Pointer to [**TargetInfo**](TargetInfo.md) | | [optional] **Name** | **string** | | -**Projects** | [**[]Project**](Project.md) | | **TargetConfig** | **string** | | +**Workspaces** | [**[]Workspace**](Workspace.md) | | ## Methods ### NewTargetDTO -`func NewTargetDTO(id string, name string, projects []Project, targetConfig string, ) *TargetDTO` +`func NewTargetDTO(id string, name string, targetConfig string, workspaces []Workspace, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -94,44 +94,44 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetProjects +### GetTargetConfig -`func (o *TargetDTO) GetProjects() []Project` +`func (o *TargetDTO) GetTargetConfig() string` -GetProjects returns the Projects field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetProjectsOk +### GetTargetConfigOk -`func (o *TargetDTO) GetProjectsOk() (*[]Project, bool)` +`func (o *TargetDTO) GetTargetConfigOk() (*string, bool)` -GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProjects +### SetTargetConfig -`func (o *TargetDTO) SetProjects(v []Project)` +`func (o *TargetDTO) SetTargetConfig(v string)` -SetProjects sets Projects field to given value. +SetTargetConfig sets TargetConfig field to given value. -### GetTargetConfig +### GetWorkspaces -`func (o *TargetDTO) GetTargetConfig() string` +`func (o *TargetDTO) GetWorkspaces() []Workspace` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetWorkspacesOk -`func (o *TargetDTO) GetTargetConfigOk() (*string, bool)` +`func (o *TargetDTO) GetWorkspacesOk() (*[]Workspace, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetWorkspaces -`func (o *TargetDTO) SetTargetConfig(v string)` +`func (o *TargetDTO) SetWorkspaces(v []Workspace)` -SetTargetConfig sets TargetConfig field to given value. +SetWorkspaces sets Workspaces field to given value. diff --git a/pkg/apiclient/docs/TargetInfo.md b/pkg/apiclient/docs/TargetInfo.md index ffed91f68e..32363e64e4 100644 --- a/pkg/apiclient/docs/TargetInfo.md +++ b/pkg/apiclient/docs/TargetInfo.md @@ -5,14 +5,14 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Name** | **string** | | -**Projects** | [**[]ProjectInfo**](ProjectInfo.md) | | **ProviderMetadata** | Pointer to **string** | | [optional] +**Workspaces** | [**[]WorkspaceInfo**](WorkspaceInfo.md) | | ## Methods ### NewTargetInfo -`func NewTargetInfo(name string, projects []ProjectInfo, ) *TargetInfo` +`func NewTargetInfo(name string, workspaces []WorkspaceInfo, ) *TargetInfo` NewTargetInfo instantiates a new TargetInfo object This constructor will assign default values to properties that have it defined, @@ -47,26 +47,6 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetProjects - -`func (o *TargetInfo) GetProjects() []ProjectInfo` - -GetProjects returns the Projects field if non-nil, zero value otherwise. - -### GetProjectsOk - -`func (o *TargetInfo) GetProjectsOk() (*[]ProjectInfo, bool)` - -GetProjectsOk returns a tuple with the Projects field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetProjects - -`func (o *TargetInfo) SetProjects(v []ProjectInfo)` - -SetProjects sets Projects field to given value. - - ### GetProviderMetadata `func (o *TargetInfo) GetProviderMetadata() string` @@ -92,6 +72,26 @@ SetProviderMetadata sets ProviderMetadata field to given value. HasProviderMetadata returns a boolean if a field has been set. +### GetWorkspaces + +`func (o *TargetInfo) GetWorkspaces() []WorkspaceInfo` + +GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. + +### GetWorkspacesOk + +`func (o *TargetInfo) GetWorkspacesOk() (*[]WorkspaceInfo, bool)` + +GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetWorkspaces + +`func (o *TargetInfo) SetWorkspaces(v []WorkspaceInfo)` + +SetWorkspaces sets Workspaces field to given value. + + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/Project.md b/pkg/apiclient/docs/Workspace.md similarity index 68% rename from pkg/apiclient/docs/Project.md rename to pkg/apiclient/docs/Workspace.md index b4af3ca024..a7f1c89107 100644 --- a/pkg/apiclient/docs/Project.md +++ b/pkg/apiclient/docs/Workspace.md @@ -1,4 +1,4 @@ -# Project +# Workspace ## Properties @@ -10,241 +10,241 @@ Name | Type | Description | Notes **Image** | **string** | | **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | -**State** | Pointer to [**ProjectState**](ProjectState.md) | | [optional] +**State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] **TargetConfig** | **string** | | **TargetId** | **string** | | **User** | **string** | | ## Methods -### NewProject +### NewWorkspace -`func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string, ) *Project` +`func NewWorkspace(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string, ) *Workspace` -NewProject instantiates a new Project object +NewWorkspace instantiates a new Workspace object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProjectWithDefaults +### NewWorkspaceWithDefaults -`func NewProjectWithDefaults() *Project` +`func NewWorkspaceWithDefaults() *Workspace` -NewProjectWithDefaults instantiates a new Project object +NewWorkspaceWithDefaults instantiates a new Workspace object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *Project) GetBuildConfig() BuildConfig` +`func (o *Workspace) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *Project) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *Project) SetBuildConfig(v BuildConfig)` +`func (o *Workspace) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *Project) HasBuildConfig() bool` +`func (o *Workspace) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetEnvVars -`func (o *Project) GetEnvVars() map[string]string` +`func (o *Workspace) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *Project) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *Project) SetEnvVars(v map[string]string)` +`func (o *Workspace) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *Project) GetGitProviderConfigId() string` +`func (o *Workspace) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *Project) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *Project) SetGitProviderConfigId(v string)` +`func (o *Workspace) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *Project) HasGitProviderConfigId() bool` +`func (o *Workspace) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetImage -`func (o *Project) GetImage() string` +`func (o *Workspace) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *Project) GetImageOk() (*string, bool)` +`func (o *Workspace) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *Project) SetImage(v string)` +`func (o *Workspace) SetImage(v string)` SetImage sets Image field to given value. ### GetName -`func (o *Project) GetName() string` +`func (o *Workspace) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *Project) GetNameOk() (*string, bool)` +`func (o *Workspace) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *Project) SetName(v string)` +`func (o *Workspace) SetName(v string)` SetName sets Name field to given value. ### GetRepository -`func (o *Project) GetRepository() GitRepository` +`func (o *Workspace) GetRepository() GitRepository` GetRepository returns the Repository field if non-nil, zero value otherwise. ### GetRepositoryOk -`func (o *Project) GetRepositoryOk() (*GitRepository, bool)` +`func (o *Workspace) GetRepositoryOk() (*GitRepository, bool)` GetRepositoryOk returns a tuple with the Repository field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepository -`func (o *Project) SetRepository(v GitRepository)` +`func (o *Workspace) SetRepository(v GitRepository)` SetRepository sets Repository field to given value. ### GetState -`func (o *Project) GetState() ProjectState` +`func (o *Workspace) GetState() WorkspaceState` GetState returns the State field if non-nil, zero value otherwise. ### GetStateOk -`func (o *Project) GetStateOk() (*ProjectState, bool)` +`func (o *Workspace) GetStateOk() (*WorkspaceState, bool)` GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetState -`func (o *Project) SetState(v ProjectState)` +`func (o *Workspace) SetState(v WorkspaceState)` SetState sets State field to given value. ### HasState -`func (o *Project) HasState() bool` +`func (o *Workspace) HasState() bool` HasState returns a boolean if a field has been set. ### GetTargetConfig -`func (o *Project) GetTargetConfig() string` +`func (o *Workspace) GetTargetConfig() string` GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. ### GetTargetConfigOk -`func (o *Project) GetTargetConfigOk() (*string, bool)` +`func (o *Workspace) GetTargetConfigOk() (*string, bool)` GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetTargetConfig -`func (o *Project) SetTargetConfig(v string)` +`func (o *Workspace) SetTargetConfig(v string)` SetTargetConfig sets TargetConfig field to given value. ### GetTargetId -`func (o *Project) GetTargetId() string` +`func (o *Workspace) GetTargetId() string` GetTargetId returns the TargetId field if non-nil, zero value otherwise. ### GetTargetIdOk -`func (o *Project) GetTargetIdOk() (*string, bool)` +`func (o *Workspace) GetTargetIdOk() (*string, bool)` GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetTargetId -`func (o *Project) SetTargetId(v string)` +`func (o *Workspace) SetTargetId(v string)` SetTargetId sets TargetId field to given value. ### GetUser -`func (o *Project) GetUser() string` +`func (o *Workspace) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *Project) GetUserOk() (*string, bool)` +`func (o *Workspace) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *Project) SetUser(v string)` +`func (o *Workspace) SetUser(v string)` SetUser sets User field to given value. diff --git a/pkg/apiclient/docs/ProjectConfig.md b/pkg/apiclient/docs/WorkspaceConfig.md similarity index 67% rename from pkg/apiclient/docs/ProjectConfig.md rename to pkg/apiclient/docs/WorkspaceConfig.md index 4c211bd2fa..69529b4181 100644 --- a/pkg/apiclient/docs/ProjectConfig.md +++ b/pkg/apiclient/docs/WorkspaceConfig.md @@ -1,4 +1,4 @@ -# ProjectConfig +# WorkspaceConfig ## Properties @@ -16,214 +16,214 @@ Name | Type | Description | Notes ## Methods -### NewProjectConfig +### NewWorkspaceConfig -`func NewProjectConfig(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string, ) *ProjectConfig` +`func NewWorkspaceConfig(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string, ) *WorkspaceConfig` -NewProjectConfig instantiates a new ProjectConfig object +NewWorkspaceConfig instantiates a new WorkspaceConfig object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProjectConfigWithDefaults +### NewWorkspaceConfigWithDefaults -`func NewProjectConfigWithDefaults() *ProjectConfig` +`func NewWorkspaceConfigWithDefaults() *WorkspaceConfig` -NewProjectConfigWithDefaults instantiates a new ProjectConfig object +NewWorkspaceConfigWithDefaults instantiates a new WorkspaceConfig object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *ProjectConfig) GetBuildConfig() BuildConfig` +`func (o *WorkspaceConfig) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *ProjectConfig) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *WorkspaceConfig) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *ProjectConfig) SetBuildConfig(v BuildConfig)` +`func (o *WorkspaceConfig) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *ProjectConfig) HasBuildConfig() bool` +`func (o *WorkspaceConfig) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetDefault -`func (o *ProjectConfig) GetDefault() bool` +`func (o *WorkspaceConfig) GetDefault() bool` GetDefault returns the Default field if non-nil, zero value otherwise. ### GetDefaultOk -`func (o *ProjectConfig) GetDefaultOk() (*bool, bool)` +`func (o *WorkspaceConfig) GetDefaultOk() (*bool, bool)` GetDefaultOk returns a tuple with the Default field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDefault -`func (o *ProjectConfig) SetDefault(v bool)` +`func (o *WorkspaceConfig) SetDefault(v bool)` SetDefault sets Default field to given value. ### GetEnvVars -`func (o *ProjectConfig) GetEnvVars() map[string]string` +`func (o *WorkspaceConfig) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *ProjectConfig) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *WorkspaceConfig) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *ProjectConfig) SetEnvVars(v map[string]string)` +`func (o *WorkspaceConfig) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *ProjectConfig) GetGitProviderConfigId() string` +`func (o *WorkspaceConfig) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *ProjectConfig) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *WorkspaceConfig) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *ProjectConfig) SetGitProviderConfigId(v string)` +`func (o *WorkspaceConfig) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *ProjectConfig) HasGitProviderConfigId() bool` +`func (o *WorkspaceConfig) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetImage -`func (o *ProjectConfig) GetImage() string` +`func (o *WorkspaceConfig) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *ProjectConfig) GetImageOk() (*string, bool)` +`func (o *WorkspaceConfig) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *ProjectConfig) SetImage(v string)` +`func (o *WorkspaceConfig) SetImage(v string)` SetImage sets Image field to given value. ### GetName -`func (o *ProjectConfig) GetName() string` +`func (o *WorkspaceConfig) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *ProjectConfig) GetNameOk() (*string, bool)` +`func (o *WorkspaceConfig) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *ProjectConfig) SetName(v string)` +`func (o *WorkspaceConfig) SetName(v string)` SetName sets Name field to given value. ### GetPrebuilds -`func (o *ProjectConfig) GetPrebuilds() []PrebuildConfig` +`func (o *WorkspaceConfig) GetPrebuilds() []PrebuildConfig` GetPrebuilds returns the Prebuilds field if non-nil, zero value otherwise. ### GetPrebuildsOk -`func (o *ProjectConfig) GetPrebuildsOk() (*[]PrebuildConfig, bool)` +`func (o *WorkspaceConfig) GetPrebuildsOk() (*[]PrebuildConfig, bool)` GetPrebuildsOk returns a tuple with the Prebuilds field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetPrebuilds -`func (o *ProjectConfig) SetPrebuilds(v []PrebuildConfig)` +`func (o *WorkspaceConfig) SetPrebuilds(v []PrebuildConfig)` SetPrebuilds sets Prebuilds field to given value. ### HasPrebuilds -`func (o *ProjectConfig) HasPrebuilds() bool` +`func (o *WorkspaceConfig) HasPrebuilds() bool` HasPrebuilds returns a boolean if a field has been set. ### GetRepositoryUrl -`func (o *ProjectConfig) GetRepositoryUrl() string` +`func (o *WorkspaceConfig) GetRepositoryUrl() string` GetRepositoryUrl returns the RepositoryUrl field if non-nil, zero value otherwise. ### GetRepositoryUrlOk -`func (o *ProjectConfig) GetRepositoryUrlOk() (*string, bool)` +`func (o *WorkspaceConfig) GetRepositoryUrlOk() (*string, bool)` GetRepositoryUrlOk returns a tuple with the RepositoryUrl field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepositoryUrl -`func (o *ProjectConfig) SetRepositoryUrl(v string)` +`func (o *WorkspaceConfig) SetRepositoryUrl(v string)` SetRepositoryUrl sets RepositoryUrl field to given value. ### GetUser -`func (o *ProjectConfig) GetUser() string` +`func (o *WorkspaceConfig) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *ProjectConfig) GetUserOk() (*string, bool)` +`func (o *WorkspaceConfig) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *ProjectConfig) SetUser(v string)` +`func (o *WorkspaceConfig) SetUser(v string)` SetUser sets User field to given value. diff --git a/pkg/apiclient/docs/ProjectConfigAPI.md b/pkg/apiclient/docs/WorkspaceConfigAPI.md similarity index 60% rename from pkg/apiclient/docs/ProjectConfigAPI.md rename to pkg/apiclient/docs/WorkspaceConfigAPI.md index f3b095ae9b..5b55822205 100644 --- a/pkg/apiclient/docs/ProjectConfigAPI.md +++ b/pkg/apiclient/docs/WorkspaceConfigAPI.md @@ -1,23 +1,23 @@ -# \ProjectConfigAPI +# \WorkspaceConfigAPI All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**DeleteProjectConfig**](ProjectConfigAPI.md#DeleteProjectConfig) | **Delete** /project-config/{configName} | Delete project config data -[**GetDefaultProjectConfig**](ProjectConfigAPI.md#GetDefaultProjectConfig) | **Get** /project-config/default/{gitUrl} | Get project configs by git url -[**GetProjectConfig**](ProjectConfigAPI.md#GetProjectConfig) | **Get** /project-config/{configName} | Get project config data -[**ListProjectConfigs**](ProjectConfigAPI.md#ListProjectConfigs) | **Get** /project-config | List project configs -[**SetDefaultProjectConfig**](ProjectConfigAPI.md#SetDefaultProjectConfig) | **Patch** /project-config/{configName}/set-default | Set project config to default -[**SetProjectConfig**](ProjectConfigAPI.md#SetProjectConfig) | **Put** /project-config | Set project config data +[**DeleteWorkspaceConfig**](WorkspaceConfigAPI.md#DeleteWorkspaceConfig) | **Delete** /workspace-config/{configName} | Delete workspace config data +[**GetDefaultWorkspaceConfig**](WorkspaceConfigAPI.md#GetDefaultWorkspaceConfig) | **Get** /workspace-config/default/{gitUrl} | Get workspace configs by git url +[**GetWorkspaceConfig**](WorkspaceConfigAPI.md#GetWorkspaceConfig) | **Get** /workspace-config/{configName} | Get workspace config data +[**ListWorkspaceConfigs**](WorkspaceConfigAPI.md#ListWorkspaceConfigs) | **Get** /workspace-config | List workspace configs +[**SetDefaultWorkspaceConfig**](WorkspaceConfigAPI.md#SetDefaultWorkspaceConfig) | **Patch** /workspace-config/{configName}/set-default | Set workspace config to default +[**SetWorkspaceConfig**](WorkspaceConfigAPI.md#SetWorkspaceConfig) | **Put** /workspace-config | Set workspace config data -## DeleteProjectConfig +## DeleteWorkspaceConfig -> DeleteProjectConfig(ctx, configName).Force(force).Execute() +> DeleteWorkspaceConfig(ctx, configName).Force(force).Execute() -Delete project config data +Delete workspace config data @@ -39,9 +39,9 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProjectConfigAPI.DeleteProjectConfig(context.Background(), configName).Force(force).Execute() + r, err := apiClient.WorkspaceConfigAPI.DeleteWorkspaceConfig(context.Background(), configName).Force(force).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProjectConfigAPI.DeleteProjectConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.DeleteWorkspaceConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -57,7 +57,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiDeleteProjectConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteWorkspaceConfigRequest struct via the builder pattern Name | Type | Description | Notes @@ -83,11 +83,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetDefaultProjectConfig +## GetDefaultWorkspaceConfig -> ProjectConfig GetDefaultProjectConfig(ctx, gitUrl).Execute() +> WorkspaceConfig GetDefaultWorkspaceConfig(ctx, gitUrl).Execute() -Get project configs by git url +Get workspace configs by git url @@ -108,13 +108,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProjectConfigAPI.GetDefaultProjectConfig(context.Background(), gitUrl).Execute() + resp, r, err := apiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(context.Background(), gitUrl).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProjectConfigAPI.GetDefaultProjectConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.GetDefaultWorkspaceConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetDefaultProjectConfig`: ProjectConfig - fmt.Fprintf(os.Stdout, "Response from `ProjectConfigAPI.GetDefaultProjectConfig`: %v\n", resp) + // response from `GetDefaultWorkspaceConfig`: WorkspaceConfig + fmt.Fprintf(os.Stdout, "Response from `WorkspaceConfigAPI.GetDefaultWorkspaceConfig`: %v\n", resp) } ``` @@ -128,7 +128,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetDefaultProjectConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetDefaultWorkspaceConfigRequest struct via the builder pattern Name | Type | Description | Notes @@ -137,7 +137,7 @@ Name | Type | Description | Notes ### Return type -[**ProjectConfig**](ProjectConfig.md) +[**WorkspaceConfig**](WorkspaceConfig.md) ### Authorization @@ -153,11 +153,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetProjectConfig +## GetWorkspaceConfig -> ProjectConfig GetProjectConfig(ctx, configName).Execute() +> WorkspaceConfig GetWorkspaceConfig(ctx, configName).Execute() -Get project config data +Get workspace config data @@ -178,13 +178,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProjectConfigAPI.GetProjectConfig(context.Background(), configName).Execute() + resp, r, err := apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(context.Background(), configName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProjectConfigAPI.GetProjectConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.GetWorkspaceConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetProjectConfig`: ProjectConfig - fmt.Fprintf(os.Stdout, "Response from `ProjectConfigAPI.GetProjectConfig`: %v\n", resp) + // response from `GetWorkspaceConfig`: WorkspaceConfig + fmt.Fprintf(os.Stdout, "Response from `WorkspaceConfigAPI.GetWorkspaceConfig`: %v\n", resp) } ``` @@ -198,7 +198,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetProjectConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetWorkspaceConfigRequest struct via the builder pattern Name | Type | Description | Notes @@ -207,7 +207,7 @@ Name | Type | Description | Notes ### Return type -[**ProjectConfig**](ProjectConfig.md) +[**WorkspaceConfig**](WorkspaceConfig.md) ### Authorization @@ -223,11 +223,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## ListProjectConfigs +## ListWorkspaceConfigs -> []ProjectConfig ListProjectConfigs(ctx).Execute() +> []WorkspaceConfig ListWorkspaceConfigs(ctx).Execute() -List project configs +List workspace configs @@ -247,13 +247,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProjectConfigAPI.ListProjectConfigs(context.Background()).Execute() + resp, r, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProjectConfigAPI.ListProjectConfigs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.ListWorkspaceConfigs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListProjectConfigs`: []ProjectConfig - fmt.Fprintf(os.Stdout, "Response from `ProjectConfigAPI.ListProjectConfigs`: %v\n", resp) + // response from `ListWorkspaceConfigs`: []WorkspaceConfig + fmt.Fprintf(os.Stdout, "Response from `WorkspaceConfigAPI.ListWorkspaceConfigs`: %v\n", resp) } ``` @@ -263,12 +263,12 @@ This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiListProjectConfigsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListWorkspaceConfigsRequest struct via the builder pattern ### Return type -[**[]ProjectConfig**](ProjectConfig.md) +[**[]WorkspaceConfig**](WorkspaceConfig.md) ### Authorization @@ -284,11 +284,11 @@ Other parameters are passed through a pointer to a apiListProjectConfigsRequest [[Back to README]](../README.md) -## SetDefaultProjectConfig +## SetDefaultWorkspaceConfig -> SetDefaultProjectConfig(ctx, configName).Execute() +> SetDefaultWorkspaceConfig(ctx, configName).Execute() -Set project config to default +Set workspace config to default @@ -309,9 +309,9 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProjectConfigAPI.SetDefaultProjectConfig(context.Background(), configName).Execute() + r, err := apiClient.WorkspaceConfigAPI.SetDefaultWorkspaceConfig(context.Background(), configName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProjectConfigAPI.SetDefaultProjectConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.SetDefaultWorkspaceConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -327,7 +327,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiSetDefaultProjectConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetDefaultWorkspaceConfigRequest struct via the builder pattern Name | Type | Description | Notes @@ -352,11 +352,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetProjectConfig +## SetWorkspaceConfig -> SetProjectConfig(ctx).ProjectConfig(projectConfig).Execute() +> SetWorkspaceConfig(ctx).WorkspaceConfig(workspaceConfig).Execute() -Set project config data +Set workspace config data @@ -373,13 +373,13 @@ import ( ) func main() { - projectConfig := *openapiclient.NewCreateProjectConfigDTO(map[string]string{"key": "Inner_example"}, "Name_example", "RepositoryUrl_example") // CreateProjectConfigDTO | Project config + workspaceConfig := *openapiclient.NewCreateWorkspaceConfigDTO(map[string]string{"key": "Inner_example"}, "Name_example", "RepositoryUrl_example") // CreateWorkspaceConfigDTO | Workspace config configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProjectConfigAPI.SetProjectConfig(context.Background()).ProjectConfig(projectConfig).Execute() + r, err := apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(context.Background()).WorkspaceConfig(workspaceConfig).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProjectConfigAPI.SetProjectConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.SetWorkspaceConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -391,12 +391,12 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiSetProjectConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetWorkspaceConfigRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **projectConfig** | [**CreateProjectConfigDTO**](CreateProjectConfigDTO.md) | Project config | + **workspaceConfig** | [**CreateWorkspaceConfigDTO**](CreateWorkspaceConfigDTO.md) | Workspace config | ### Return type diff --git a/pkg/apiclient/docs/ProjectDirResponse.md b/pkg/apiclient/docs/WorkspaceDirResponse.md similarity index 64% rename from pkg/apiclient/docs/ProjectDirResponse.md rename to pkg/apiclient/docs/WorkspaceDirResponse.md index d2e4c0c2df..6a751c38af 100644 --- a/pkg/apiclient/docs/ProjectDirResponse.md +++ b/pkg/apiclient/docs/WorkspaceDirResponse.md @@ -1,4 +1,4 @@ -# ProjectDirResponse +# WorkspaceDirResponse ## Properties @@ -8,45 +8,45 @@ Name | Type | Description | Notes ## Methods -### NewProjectDirResponse +### NewWorkspaceDirResponse -`func NewProjectDirResponse() *ProjectDirResponse` +`func NewWorkspaceDirResponse() *WorkspaceDirResponse` -NewProjectDirResponse instantiates a new ProjectDirResponse object +NewWorkspaceDirResponse instantiates a new WorkspaceDirResponse object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProjectDirResponseWithDefaults +### NewWorkspaceDirResponseWithDefaults -`func NewProjectDirResponseWithDefaults() *ProjectDirResponse` +`func NewWorkspaceDirResponseWithDefaults() *WorkspaceDirResponse` -NewProjectDirResponseWithDefaults instantiates a new ProjectDirResponse object +NewWorkspaceDirResponseWithDefaults instantiates a new WorkspaceDirResponse object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetDir -`func (o *ProjectDirResponse) GetDir() string` +`func (o *WorkspaceDirResponse) GetDir() string` GetDir returns the Dir field if non-nil, zero value otherwise. ### GetDirOk -`func (o *ProjectDirResponse) GetDirOk() (*string, bool)` +`func (o *WorkspaceDirResponse) GetDirOk() (*string, bool)` GetDirOk returns a tuple with the Dir field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDir -`func (o *ProjectDirResponse) SetDir(v string)` +`func (o *WorkspaceDirResponse) SetDir(v string)` SetDir sets Dir field to given value. ### HasDir -`func (o *ProjectDirResponse) HasDir() bool` +`func (o *WorkspaceDirResponse) HasDir() bool` HasDir returns a boolean if a field has been set. diff --git a/pkg/apiclient/docs/ProjectInfo.md b/pkg/apiclient/docs/WorkspaceInfo.md similarity index 68% rename from pkg/apiclient/docs/ProjectInfo.md rename to pkg/apiclient/docs/WorkspaceInfo.md index 7e37997184..330770d20d 100644 --- a/pkg/apiclient/docs/ProjectInfo.md +++ b/pkg/apiclient/docs/WorkspaceInfo.md @@ -1,4 +1,4 @@ -# ProjectInfo +# WorkspaceInfo ## Properties @@ -12,124 +12,124 @@ Name | Type | Description | Notes ## Methods -### NewProjectInfo +### NewWorkspaceInfo -`func NewProjectInfo(created string, isRunning bool, name string, targetId string, ) *ProjectInfo` +`func NewWorkspaceInfo(created string, isRunning bool, name string, targetId string, ) *WorkspaceInfo` -NewProjectInfo instantiates a new ProjectInfo object +NewWorkspaceInfo instantiates a new WorkspaceInfo object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProjectInfoWithDefaults +### NewWorkspaceInfoWithDefaults -`func NewProjectInfoWithDefaults() *ProjectInfo` +`func NewWorkspaceInfoWithDefaults() *WorkspaceInfo` -NewProjectInfoWithDefaults instantiates a new ProjectInfo object +NewWorkspaceInfoWithDefaults instantiates a new WorkspaceInfo object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetCreated -`func (o *ProjectInfo) GetCreated() string` +`func (o *WorkspaceInfo) GetCreated() string` GetCreated returns the Created field if non-nil, zero value otherwise. ### GetCreatedOk -`func (o *ProjectInfo) GetCreatedOk() (*string, bool)` +`func (o *WorkspaceInfo) GetCreatedOk() (*string, bool)` GetCreatedOk returns a tuple with the Created field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetCreated -`func (o *ProjectInfo) SetCreated(v string)` +`func (o *WorkspaceInfo) SetCreated(v string)` SetCreated sets Created field to given value. ### GetIsRunning -`func (o *ProjectInfo) GetIsRunning() bool` +`func (o *WorkspaceInfo) GetIsRunning() bool` GetIsRunning returns the IsRunning field if non-nil, zero value otherwise. ### GetIsRunningOk -`func (o *ProjectInfo) GetIsRunningOk() (*bool, bool)` +`func (o *WorkspaceInfo) GetIsRunningOk() (*bool, bool)` GetIsRunningOk returns a tuple with the IsRunning field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetIsRunning -`func (o *ProjectInfo) SetIsRunning(v bool)` +`func (o *WorkspaceInfo) SetIsRunning(v bool)` SetIsRunning sets IsRunning field to given value. ### GetName -`func (o *ProjectInfo) GetName() string` +`func (o *WorkspaceInfo) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *ProjectInfo) GetNameOk() (*string, bool)` +`func (o *WorkspaceInfo) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *ProjectInfo) SetName(v string)` +`func (o *WorkspaceInfo) SetName(v string)` SetName sets Name field to given value. ### GetProviderMetadata -`func (o *ProjectInfo) GetProviderMetadata() string` +`func (o *WorkspaceInfo) GetProviderMetadata() string` GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. ### GetProviderMetadataOk -`func (o *ProjectInfo) GetProviderMetadataOk() (*string, bool)` +`func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool)` GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderMetadata -`func (o *ProjectInfo) SetProviderMetadata(v string)` +`func (o *WorkspaceInfo) SetProviderMetadata(v string)` SetProviderMetadata sets ProviderMetadata field to given value. ### HasProviderMetadata -`func (o *ProjectInfo) HasProviderMetadata() bool` +`func (o *WorkspaceInfo) HasProviderMetadata() bool` HasProviderMetadata returns a boolean if a field has been set. ### GetTargetId -`func (o *ProjectInfo) GetTargetId() string` +`func (o *WorkspaceInfo) GetTargetId() string` GetTargetId returns the TargetId field if non-nil, zero value otherwise. ### GetTargetIdOk -`func (o *ProjectInfo) GetTargetIdOk() (*string, bool)` +`func (o *WorkspaceInfo) GetTargetIdOk() (*string, bool)` GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetTargetId -`func (o *ProjectInfo) SetTargetId(v string)` +`func (o *WorkspaceInfo) SetTargetId(v string)` SetTargetId sets TargetId field to given value. diff --git a/pkg/apiclient/docs/ProjectState.md b/pkg/apiclient/docs/WorkspaceState.md similarity index 68% rename from pkg/apiclient/docs/ProjectState.md rename to pkg/apiclient/docs/WorkspaceState.md index 410b6a949b..a08e533c69 100644 --- a/pkg/apiclient/docs/ProjectState.md +++ b/pkg/apiclient/docs/WorkspaceState.md @@ -1,4 +1,4 @@ -# ProjectState +# WorkspaceState ## Properties @@ -10,84 +10,84 @@ Name | Type | Description | Notes ## Methods -### NewProjectState +### NewWorkspaceState -`func NewProjectState(updatedAt string, uptime int32, ) *ProjectState` +`func NewWorkspaceState(updatedAt string, uptime int32, ) *WorkspaceState` -NewProjectState instantiates a new ProjectState object +NewWorkspaceState instantiates a new WorkspaceState object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProjectStateWithDefaults +### NewWorkspaceStateWithDefaults -`func NewProjectStateWithDefaults() *ProjectState` +`func NewWorkspaceStateWithDefaults() *WorkspaceState` -NewProjectStateWithDefaults instantiates a new ProjectState object +NewWorkspaceStateWithDefaults instantiates a new WorkspaceState object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetGitStatus -`func (o *ProjectState) GetGitStatus() GitStatus` +`func (o *WorkspaceState) GetGitStatus() GitStatus` GetGitStatus returns the GitStatus field if non-nil, zero value otherwise. ### GetGitStatusOk -`func (o *ProjectState) GetGitStatusOk() (*GitStatus, bool)` +`func (o *WorkspaceState) GetGitStatusOk() (*GitStatus, bool)` GetGitStatusOk returns a tuple with the GitStatus field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitStatus -`func (o *ProjectState) SetGitStatus(v GitStatus)` +`func (o *WorkspaceState) SetGitStatus(v GitStatus)` SetGitStatus sets GitStatus field to given value. ### HasGitStatus -`func (o *ProjectState) HasGitStatus() bool` +`func (o *WorkspaceState) HasGitStatus() bool` HasGitStatus returns a boolean if a field has been set. ### GetUpdatedAt -`func (o *ProjectState) GetUpdatedAt() string` +`func (o *WorkspaceState) GetUpdatedAt() string` GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. ### GetUpdatedAtOk -`func (o *ProjectState) GetUpdatedAtOk() (*string, bool)` +`func (o *WorkspaceState) GetUpdatedAtOk() (*string, bool)` GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUpdatedAt -`func (o *ProjectState) SetUpdatedAt(v string)` +`func (o *WorkspaceState) SetUpdatedAt(v string)` SetUpdatedAt sets UpdatedAt field to given value. ### GetUptime -`func (o *ProjectState) GetUptime() int32` +`func (o *WorkspaceState) GetUptime() int32` GetUptime returns the Uptime field if non-nil, zero value otherwise. ### GetUptimeOk -`func (o *ProjectState) GetUptimeOk() (*int32, bool)` +`func (o *WorkspaceState) GetUptimeOk() (*int32, bool)` GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUptime -`func (o *ProjectState) SetUptime(v int32)` +`func (o *WorkspaceState) SetUptime(v int32)` SetUptime sets Uptime field to given value. diff --git a/pkg/apiclient/docs/WorkspaceToolboxAPI.md b/pkg/apiclient/docs/WorkspaceToolboxAPI.md index 68eed3396c..effaa6c5ef 100644 --- a/pkg/apiclient/docs/WorkspaceToolboxAPI.md +++ b/pkg/apiclient/docs/WorkspaceToolboxAPI.md @@ -17,8 +17,8 @@ Method | HTTP request | Description [**FsSearchFiles**](WorkspaceToolboxAPI.md#FsSearchFiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/search | Search for files [**FsSetFilePermissions**](WorkspaceToolboxAPI.md#FsSetFilePermissions) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/permissions | Set file owner/group/permissions [**FsUploadFile**](WorkspaceToolboxAPI.md#FsUploadFile) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/upload | Upload file -[**GetProjectDir**](WorkspaceToolboxAPI.md#GetProjectDir) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/project-dir | Get project dir [**GetSessionCommandLogs**](WorkspaceToolboxAPI.md#GetSessionCommandLogs) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs | Get session command logs +[**GetWorkspaceDir**](WorkspaceToolboxAPI.md#GetWorkspaceDir) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir | Get workspace dir [**GitAddFiles**](WorkspaceToolboxAPI.md#GitAddFiles) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/add | Add files [**GitBranchList**](WorkspaceToolboxAPI.md#GitBranchList) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/branches | Get branch list [**GitCloneRepository**](WorkspaceToolboxAPI.md#GitCloneRepository) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/clone | Clone git repository @@ -1019,11 +1019,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetProjectDir +## GetSessionCommandLogs -> ProjectDirResponse GetProjectDir(ctx, workspaceId, projectId).Execute() +> string GetSessionCommandLogs(ctx, workspaceId, projectId, sessionId, commandId).Execute() -Get project dir +Get session command logs @@ -1042,16 +1042,18 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name projectId := "projectId_example" // string | Project ID + sessionId := "sessionId_example" // string | Session ID + commandId := "commandId_example" // string | Command ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GetProjectDir(context.Background(), workspaceId, projectId).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GetSessionCommandLogs(context.Background(), workspaceId, projectId, sessionId, commandId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GetProjectDir``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GetSessionCommandLogs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetProjectDir`: ProjectDirResponse - fmt.Fprintf(os.Stdout, "Response from `WorkspaceToolboxAPI.GetProjectDir`: %v\n", resp) + // response from `GetSessionCommandLogs`: string + fmt.Fprintf(os.Stdout, "Response from `WorkspaceToolboxAPI.GetSessionCommandLogs`: %v\n", resp) } ``` @@ -1063,10 +1065,12 @@ Name | Type | Description | Notes **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | **projectId** | **string** | Project ID | +**sessionId** | **string** | Session ID | +**commandId** | **string** | Command ID | ### Other Parameters -Other parameters are passed through a pointer to a apiGetProjectDirRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetSessionCommandLogsRequest struct via the builder pattern Name | Type | Description | Notes @@ -1074,9 +1078,11 @@ Name | Type | Description | Notes + + ### Return type -[**ProjectDirResponse**](ProjectDirResponse.md) +**string** ### Authorization @@ -1085,18 +1091,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: */* [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## GetSessionCommandLogs +## GetWorkspaceDir -> string GetSessionCommandLogs(ctx, workspaceId, projectId, sessionId, commandId).Execute() +> WorkspaceDirResponse GetWorkspaceDir(ctx, workspaceId, projectId).Execute() -Get session command logs +Get workspace dir @@ -1115,18 +1121,16 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name projectId := "projectId_example" // string | Project ID - sessionId := "sessionId_example" // string | Session ID - commandId := "commandId_example" // string | Command ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GetSessionCommandLogs(context.Background(), workspaceId, projectId, sessionId, commandId).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GetWorkspaceDir(context.Background(), workspaceId, projectId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GetSessionCommandLogs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GetWorkspaceDir``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetSessionCommandLogs`: string - fmt.Fprintf(os.Stdout, "Response from `WorkspaceToolboxAPI.GetSessionCommandLogs`: %v\n", resp) + // response from `GetWorkspaceDir`: WorkspaceDirResponse + fmt.Fprintf(os.Stdout, "Response from `WorkspaceToolboxAPI.GetWorkspaceDir`: %v\n", resp) } ``` @@ -1138,12 +1142,10 @@ Name | Type | Description | Notes **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | **projectId** | **string** | Project ID | -**sessionId** | **string** | Session ID | -**commandId** | **string** | Command ID | ### Other Parameters -Other parameters are passed through a pointer to a apiGetSessionCommandLogsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetWorkspaceDirRequest struct via the builder pattern Name | Type | Description | Notes @@ -1151,11 +1153,9 @@ Name | Type | Description | Notes - - ### Return type -**string** +[**WorkspaceDirResponse**](WorkspaceDirResponse.md) ### Authorization @@ -1164,7 +1164,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: */* +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) diff --git a/pkg/apiclient/model_api_key.go b/pkg/apiclient/model_api_key.go index 4a891d3af3..121ae4528d 100644 --- a/pkg/apiclient/model_api_key.go +++ b/pkg/apiclient/model_api_key.go @@ -22,7 +22,7 @@ var _ MappedNullable = &ApiKey{} // ApiKey struct for ApiKey type ApiKey struct { KeyHash string `json:"keyHash"` - // Project or client name + // Workspace or client name Name string `json:"name"` Type ApikeyApiKeyType `json:"type"` } diff --git a/pkg/apiclient/model_apikey_api_key_type.go b/pkg/apiclient/model_apikey_api_key_type.go index 42d2995f7e..7228586047 100644 --- a/pkg/apiclient/model_apikey_api_key_type.go +++ b/pkg/apiclient/model_apikey_api_key_type.go @@ -20,15 +20,15 @@ type ApikeyApiKeyType string // List of apikey.ApiKeyType const ( - ApiKeyTypeClient ApikeyApiKeyType = "client" - ApiKeyTypeProject ApikeyApiKeyType = "project" - ApiKeyTypeTarget ApikeyApiKeyType = "target" + ApiKeyTypeClient ApikeyApiKeyType = "client" + ApiKeyTypeWorkspace ApikeyApiKeyType = "workspace" + ApiKeyTypeTarget ApikeyApiKeyType = "target" ) // All allowed values of ApikeyApiKeyType enum var AllowedApikeyApiKeyTypeEnumValues = []ApikeyApiKeyType{ "client", - "project", + "workspace", "target", } diff --git a/pkg/apiclient/model_create_build_dto.go b/pkg/apiclient/model_create_build_dto.go index 37e4267d4d..e855e4adc7 100644 --- a/pkg/apiclient/model_create_build_dto.go +++ b/pkg/apiclient/model_create_build_dto.go @@ -21,10 +21,10 @@ var _ MappedNullable = &CreateBuildDTO{} // CreateBuildDTO struct for CreateBuildDTO type CreateBuildDTO struct { - Branch string `json:"branch"` - EnvVars map[string]string `json:"envVars"` - PrebuildId *string `json:"prebuildId,omitempty"` - ProjectConfigName string `json:"projectConfigName"` + Branch string `json:"branch"` + EnvVars map[string]string `json:"envVars"` + PrebuildId *string `json:"prebuildId,omitempty"` + WorkspaceConfigName string `json:"workspaceConfigName"` } type _CreateBuildDTO CreateBuildDTO @@ -33,11 +33,11 @@ type _CreateBuildDTO CreateBuildDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateBuildDTO(branch string, envVars map[string]string, projectConfigName string) *CreateBuildDTO { +func NewCreateBuildDTO(branch string, envVars map[string]string, workspaceConfigName string) *CreateBuildDTO { this := CreateBuildDTO{} this.Branch = branch this.EnvVars = envVars - this.ProjectConfigName = projectConfigName + this.WorkspaceConfigName = workspaceConfigName return &this } @@ -129,28 +129,28 @@ func (o *CreateBuildDTO) SetPrebuildId(v string) { o.PrebuildId = &v } -// GetProjectConfigName returns the ProjectConfigName field value -func (o *CreateBuildDTO) GetProjectConfigName() string { +// GetWorkspaceConfigName returns the WorkspaceConfigName field value +func (o *CreateBuildDTO) GetWorkspaceConfigName() string { if o == nil { var ret string return ret } - return o.ProjectConfigName + return o.WorkspaceConfigName } -// GetProjectConfigNameOk returns a tuple with the ProjectConfigName field value +// GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field value // and a boolean to check if the value has been set. -func (o *CreateBuildDTO) GetProjectConfigNameOk() (*string, bool) { +func (o *CreateBuildDTO) GetWorkspaceConfigNameOk() (*string, bool) { if o == nil { return nil, false } - return &o.ProjectConfigName, true + return &o.WorkspaceConfigName, true } -// SetProjectConfigName sets field value -func (o *CreateBuildDTO) SetProjectConfigName(v string) { - o.ProjectConfigName = v +// SetWorkspaceConfigName sets field value +func (o *CreateBuildDTO) SetWorkspaceConfigName(v string) { + o.WorkspaceConfigName = v } func (o CreateBuildDTO) MarshalJSON() ([]byte, error) { @@ -168,7 +168,7 @@ func (o CreateBuildDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.PrebuildId) { toSerialize["prebuildId"] = o.PrebuildId } - toSerialize["projectConfigName"] = o.ProjectConfigName + toSerialize["workspaceConfigName"] = o.WorkspaceConfigName return toSerialize, nil } @@ -179,7 +179,7 @@ func (o *CreateBuildDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "branch", "envVars", - "projectConfigName", + "workspaceConfigName", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_create_target_dto.go b/pkg/apiclient/model_create_target_dto.go index 94122bc805..f9da9ea7c8 100644 --- a/pkg/apiclient/model_create_target_dto.go +++ b/pkg/apiclient/model_create_target_dto.go @@ -21,10 +21,10 @@ var _ MappedNullable = &CreateTargetDTO{} // CreateTargetDTO struct for CreateTargetDTO type CreateTargetDTO struct { - Id string `json:"id"` - Name string `json:"name"` - Projects []CreateProjectDTO `json:"projects"` - TargetConfig string `json:"targetConfig"` + Id string `json:"id"` + Name string `json:"name"` + TargetConfig string `json:"targetConfig"` + Workspaces []CreateWorkspaceDTO `json:"workspaces"` } type _CreateTargetDTO CreateTargetDTO @@ -33,12 +33,12 @@ type _CreateTargetDTO CreateTargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateTargetDTO(id string, name string, projects []CreateProjectDTO, targetConfig string) *CreateTargetDTO { +func NewCreateTargetDTO(id string, name string, targetConfig string, workspaces []CreateWorkspaceDTO) *CreateTargetDTO { this := CreateTargetDTO{} this.Id = id this.Name = name - this.Projects = projects this.TargetConfig = targetConfig + this.Workspaces = workspaces return &this } @@ -98,52 +98,52 @@ func (o *CreateTargetDTO) SetName(v string) { o.Name = v } -// GetProjects returns the Projects field value -func (o *CreateTargetDTO) GetProjects() []CreateProjectDTO { +// GetTargetConfig returns the TargetConfig field value +func (o *CreateTargetDTO) GetTargetConfig() string { if o == nil { - var ret []CreateProjectDTO + var ret string return ret } - return o.Projects + return o.TargetConfig } -// GetProjectsOk returns a tuple with the Projects field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *CreateTargetDTO) GetProjectsOk() ([]CreateProjectDTO, bool) { +func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return o.Projects, true + return &o.TargetConfig, true } -// SetProjects sets field value -func (o *CreateTargetDTO) SetProjects(v []CreateProjectDTO) { - o.Projects = v +// SetTargetConfig sets field value +func (o *CreateTargetDTO) SetTargetConfig(v string) { + o.TargetConfig = v } -// GetTargetConfig returns the TargetConfig field value -func (o *CreateTargetDTO) GetTargetConfig() string { +// GetWorkspaces returns the Workspaces field value +func (o *CreateTargetDTO) GetWorkspaces() []CreateWorkspaceDTO { if o == nil { - var ret string + var ret []CreateWorkspaceDTO return ret } - return o.TargetConfig + return o.Workspaces } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetWorkspacesOk returns a tuple with the Workspaces field value // and a boolean to check if the value has been set. -func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool) { +func (o *CreateTargetDTO) GetWorkspacesOk() ([]CreateWorkspaceDTO, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return o.Workspaces, true } -// SetTargetConfig sets field value -func (o *CreateTargetDTO) SetTargetConfig(v string) { - o.TargetConfig = v +// SetWorkspaces sets field value +func (o *CreateTargetDTO) SetWorkspaces(v []CreateWorkspaceDTO) { + o.Workspaces = v } func (o CreateTargetDTO) MarshalJSON() ([]byte, error) { @@ -158,8 +158,8 @@ func (o CreateTargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name - toSerialize["projects"] = o.Projects toSerialize["targetConfig"] = o.TargetConfig + toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -170,8 +170,8 @@ func (o *CreateTargetDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "id", "name", - "projects", "targetConfig", + "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_create_project_config_dto.go b/pkg/apiclient/model_create_workspace_config_dto.go similarity index 65% rename from pkg/apiclient/model_create_project_config_dto.go rename to pkg/apiclient/model_create_workspace_config_dto.go index 0de5ca203e..66d5daea1a 100644 --- a/pkg/apiclient/model_create_project_config_dto.go +++ b/pkg/apiclient/model_create_workspace_config_dto.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the CreateProjectConfigDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateProjectConfigDTO{} +// checks if the CreateWorkspaceConfigDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateWorkspaceConfigDTO{} -// CreateProjectConfigDTO struct for CreateProjectConfigDTO -type CreateProjectConfigDTO struct { +// CreateWorkspaceConfigDTO struct for CreateWorkspaceConfigDTO +type CreateWorkspaceConfigDTO struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` @@ -30,30 +30,30 @@ type CreateProjectConfigDTO struct { User *string `json:"user,omitempty"` } -type _CreateProjectConfigDTO CreateProjectConfigDTO +type _CreateWorkspaceConfigDTO CreateWorkspaceConfigDTO -// NewCreateProjectConfigDTO instantiates a new CreateProjectConfigDTO object +// NewCreateWorkspaceConfigDTO instantiates a new CreateWorkspaceConfigDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateProjectConfigDTO(envVars map[string]string, name string, repositoryUrl string) *CreateProjectConfigDTO { - this := CreateProjectConfigDTO{} +func NewCreateWorkspaceConfigDTO(envVars map[string]string, name string, repositoryUrl string) *CreateWorkspaceConfigDTO { + this := CreateWorkspaceConfigDTO{} this.EnvVars = envVars this.Name = name this.RepositoryUrl = repositoryUrl return &this } -// NewCreateProjectConfigDTOWithDefaults instantiates a new CreateProjectConfigDTO object +// NewCreateWorkspaceConfigDTOWithDefaults instantiates a new CreateWorkspaceConfigDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateProjectConfigDTOWithDefaults() *CreateProjectConfigDTO { - this := CreateProjectConfigDTO{} +func NewCreateWorkspaceConfigDTOWithDefaults() *CreateWorkspaceConfigDTO { + this := CreateWorkspaceConfigDTO{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *CreateProjectConfigDTO) GetBuildConfig() BuildConfig { +func (o *CreateWorkspaceConfigDTO) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -63,7 +63,7 @@ func (o *CreateProjectConfigDTO) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *CreateWorkspaceConfigDTO) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -71,7 +71,7 @@ func (o *CreateProjectConfigDTO) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *CreateProjectConfigDTO) HasBuildConfig() bool { +func (o *CreateWorkspaceConfigDTO) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -80,12 +80,12 @@ func (o *CreateProjectConfigDTO) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *CreateProjectConfigDTO) SetBuildConfig(v BuildConfig) { +func (o *CreateWorkspaceConfigDTO) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetEnvVars returns the EnvVars field value -func (o *CreateProjectConfigDTO) GetEnvVars() map[string]string { +func (o *CreateWorkspaceConfigDTO) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -96,7 +96,7 @@ func (o *CreateProjectConfigDTO) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetEnvVarsOk() (*map[string]string, bool) { +func (o *CreateWorkspaceConfigDTO) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -104,12 +104,12 @@ func (o *CreateProjectConfigDTO) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *CreateProjectConfigDTO) SetEnvVars(v map[string]string) { +func (o *CreateWorkspaceConfigDTO) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *CreateProjectConfigDTO) GetGitProviderConfigId() string { +func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -119,7 +119,7 @@ func (o *CreateProjectConfigDTO) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetGitProviderConfigIdOk() (*string, bool) { +func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -127,7 +127,7 @@ func (o *CreateProjectConfigDTO) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *CreateProjectConfigDTO) HasGitProviderConfigId() bool { +func (o *CreateWorkspaceConfigDTO) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -136,12 +136,12 @@ func (o *CreateProjectConfigDTO) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *CreateProjectConfigDTO) SetGitProviderConfigId(v string) { +func (o *CreateWorkspaceConfigDTO) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetImage returns the Image field value if set, zero value otherwise. -func (o *CreateProjectConfigDTO) GetImage() string { +func (o *CreateWorkspaceConfigDTO) GetImage() string { if o == nil || IsNil(o.Image) { var ret string return ret @@ -151,7 +151,7 @@ func (o *CreateProjectConfigDTO) GetImage() string { // GetImageOk returns a tuple with the Image field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetImageOk() (*string, bool) { +func (o *CreateWorkspaceConfigDTO) GetImageOk() (*string, bool) { if o == nil || IsNil(o.Image) { return nil, false } @@ -159,7 +159,7 @@ func (o *CreateProjectConfigDTO) GetImageOk() (*string, bool) { } // HasImage returns a boolean if a field has been set. -func (o *CreateProjectConfigDTO) HasImage() bool { +func (o *CreateWorkspaceConfigDTO) HasImage() bool { if o != nil && !IsNil(o.Image) { return true } @@ -168,12 +168,12 @@ func (o *CreateProjectConfigDTO) HasImage() bool { } // SetImage gets a reference to the given string and assigns it to the Image field. -func (o *CreateProjectConfigDTO) SetImage(v string) { +func (o *CreateWorkspaceConfigDTO) SetImage(v string) { o.Image = &v } // GetName returns the Name field value -func (o *CreateProjectConfigDTO) GetName() string { +func (o *CreateWorkspaceConfigDTO) GetName() string { if o == nil { var ret string return ret @@ -184,7 +184,7 @@ func (o *CreateProjectConfigDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetNameOk() (*string, bool) { +func (o *CreateWorkspaceConfigDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -192,12 +192,12 @@ func (o *CreateProjectConfigDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *CreateProjectConfigDTO) SetName(v string) { +func (o *CreateWorkspaceConfigDTO) SetName(v string) { o.Name = v } // GetRepositoryUrl returns the RepositoryUrl field value -func (o *CreateProjectConfigDTO) GetRepositoryUrl() string { +func (o *CreateWorkspaceConfigDTO) GetRepositoryUrl() string { if o == nil { var ret string return ret @@ -208,7 +208,7 @@ func (o *CreateProjectConfigDTO) GetRepositoryUrl() string { // GetRepositoryUrlOk returns a tuple with the RepositoryUrl field value // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetRepositoryUrlOk() (*string, bool) { +func (o *CreateWorkspaceConfigDTO) GetRepositoryUrlOk() (*string, bool) { if o == nil { return nil, false } @@ -216,12 +216,12 @@ func (o *CreateProjectConfigDTO) GetRepositoryUrlOk() (*string, bool) { } // SetRepositoryUrl sets field value -func (o *CreateProjectConfigDTO) SetRepositoryUrl(v string) { +func (o *CreateWorkspaceConfigDTO) SetRepositoryUrl(v string) { o.RepositoryUrl = v } // GetUser returns the User field value if set, zero value otherwise. -func (o *CreateProjectConfigDTO) GetUser() string { +func (o *CreateWorkspaceConfigDTO) GetUser() string { if o == nil || IsNil(o.User) { var ret string return ret @@ -231,7 +231,7 @@ func (o *CreateProjectConfigDTO) GetUser() string { // GetUserOk returns a tuple with the User field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectConfigDTO) GetUserOk() (*string, bool) { +func (o *CreateWorkspaceConfigDTO) GetUserOk() (*string, bool) { if o == nil || IsNil(o.User) { return nil, false } @@ -239,7 +239,7 @@ func (o *CreateProjectConfigDTO) GetUserOk() (*string, bool) { } // HasUser returns a boolean if a field has been set. -func (o *CreateProjectConfigDTO) HasUser() bool { +func (o *CreateWorkspaceConfigDTO) HasUser() bool { if o != nil && !IsNil(o.User) { return true } @@ -248,11 +248,11 @@ func (o *CreateProjectConfigDTO) HasUser() bool { } // SetUser gets a reference to the given string and assigns it to the User field. -func (o *CreateProjectConfigDTO) SetUser(v string) { +func (o *CreateWorkspaceConfigDTO) SetUser(v string) { o.User = &v } -func (o CreateProjectConfigDTO) MarshalJSON() ([]byte, error) { +func (o CreateWorkspaceConfigDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -260,7 +260,7 @@ func (o CreateProjectConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateProjectConfigDTO) ToMap() (map[string]interface{}, error) { +func (o CreateWorkspaceConfigDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -280,7 +280,7 @@ func (o CreateProjectConfigDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *CreateProjectConfigDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateWorkspaceConfigDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -304,53 +304,53 @@ func (o *CreateProjectConfigDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateProjectConfigDTO := _CreateProjectConfigDTO{} + varCreateWorkspaceConfigDTO := _CreateWorkspaceConfigDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateProjectConfigDTO) + err = decoder.Decode(&varCreateWorkspaceConfigDTO) if err != nil { return err } - *o = CreateProjectConfigDTO(varCreateProjectConfigDTO) + *o = CreateWorkspaceConfigDTO(varCreateWorkspaceConfigDTO) return err } -type NullableCreateProjectConfigDTO struct { - value *CreateProjectConfigDTO +type NullableCreateWorkspaceConfigDTO struct { + value *CreateWorkspaceConfigDTO isSet bool } -func (v NullableCreateProjectConfigDTO) Get() *CreateProjectConfigDTO { +func (v NullableCreateWorkspaceConfigDTO) Get() *CreateWorkspaceConfigDTO { return v.value } -func (v *NullableCreateProjectConfigDTO) Set(val *CreateProjectConfigDTO) { +func (v *NullableCreateWorkspaceConfigDTO) Set(val *CreateWorkspaceConfigDTO) { v.value = val v.isSet = true } -func (v NullableCreateProjectConfigDTO) IsSet() bool { +func (v NullableCreateWorkspaceConfigDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateProjectConfigDTO) Unset() { +func (v *NullableCreateWorkspaceConfigDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateProjectConfigDTO(val *CreateProjectConfigDTO) *NullableCreateProjectConfigDTO { - return &NullableCreateProjectConfigDTO{value: val, isSet: true} +func NewNullableCreateWorkspaceConfigDTO(val *CreateWorkspaceConfigDTO) *NullableCreateWorkspaceConfigDTO { + return &NullableCreateWorkspaceConfigDTO{value: val, isSet: true} } -func (v NullableCreateProjectConfigDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateWorkspaceConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateProjectConfigDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateWorkspaceConfigDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_create_project_dto.go b/pkg/apiclient/model_create_workspace_dto.go similarity index 62% rename from pkg/apiclient/model_create_project_dto.go rename to pkg/apiclient/model_create_workspace_dto.go index df7c43ec87..060e4ac114 100644 --- a/pkg/apiclient/model_create_project_dto.go +++ b/pkg/apiclient/model_create_workspace_dto.go @@ -16,44 +16,44 @@ import ( "fmt" ) -// checks if the CreateProjectDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateProjectDTO{} +// checks if the CreateWorkspaceDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateWorkspaceDTO{} -// CreateProjectDTO struct for CreateProjectDTO -type CreateProjectDTO struct { - BuildConfig *BuildConfig `json:"buildConfig,omitempty"` - EnvVars map[string]string `json:"envVars"` - GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` - Image *string `json:"image,omitempty"` - Name string `json:"name"` - Source CreateProjectSourceDTO `json:"source"` - User *string `json:"user,omitempty"` +// CreateWorkspaceDTO struct for CreateWorkspaceDTO +type CreateWorkspaceDTO struct { + BuildConfig *BuildConfig `json:"buildConfig,omitempty"` + EnvVars map[string]string `json:"envVars"` + GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` + Image *string `json:"image,omitempty"` + Name string `json:"name"` + Source CreateWorkspaceSourceDTO `json:"source"` + User *string `json:"user,omitempty"` } -type _CreateProjectDTO CreateProjectDTO +type _CreateWorkspaceDTO CreateWorkspaceDTO -// NewCreateProjectDTO instantiates a new CreateProjectDTO object +// NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateProjectDTO(envVars map[string]string, name string, source CreateProjectSourceDTO) *CreateProjectDTO { - this := CreateProjectDTO{} +func NewCreateWorkspaceDTO(envVars map[string]string, name string, source CreateWorkspaceSourceDTO) *CreateWorkspaceDTO { + this := CreateWorkspaceDTO{} this.EnvVars = envVars this.Name = name this.Source = source return &this } -// NewCreateProjectDTOWithDefaults instantiates a new CreateProjectDTO object +// NewCreateWorkspaceDTOWithDefaults instantiates a new CreateWorkspaceDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateProjectDTOWithDefaults() *CreateProjectDTO { - this := CreateProjectDTO{} +func NewCreateWorkspaceDTOWithDefaults() *CreateWorkspaceDTO { + this := CreateWorkspaceDTO{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *CreateProjectDTO) GetBuildConfig() BuildConfig { +func (o *CreateWorkspaceDTO) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -63,7 +63,7 @@ func (o *CreateProjectDTO) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *CreateWorkspaceDTO) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -71,7 +71,7 @@ func (o *CreateProjectDTO) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *CreateProjectDTO) HasBuildConfig() bool { +func (o *CreateWorkspaceDTO) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -80,12 +80,12 @@ func (o *CreateProjectDTO) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *CreateProjectDTO) SetBuildConfig(v BuildConfig) { +func (o *CreateWorkspaceDTO) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetEnvVars returns the EnvVars field value -func (o *CreateProjectDTO) GetEnvVars() map[string]string { +func (o *CreateWorkspaceDTO) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -96,7 +96,7 @@ func (o *CreateProjectDTO) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetEnvVarsOk() (*map[string]string, bool) { +func (o *CreateWorkspaceDTO) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -104,12 +104,12 @@ func (o *CreateProjectDTO) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *CreateProjectDTO) SetEnvVars(v map[string]string) { +func (o *CreateWorkspaceDTO) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *CreateProjectDTO) GetGitProviderConfigId() string { +func (o *CreateWorkspaceDTO) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -119,7 +119,7 @@ func (o *CreateProjectDTO) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetGitProviderConfigIdOk() (*string, bool) { +func (o *CreateWorkspaceDTO) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -127,7 +127,7 @@ func (o *CreateProjectDTO) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *CreateProjectDTO) HasGitProviderConfigId() bool { +func (o *CreateWorkspaceDTO) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -136,12 +136,12 @@ func (o *CreateProjectDTO) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *CreateProjectDTO) SetGitProviderConfigId(v string) { +func (o *CreateWorkspaceDTO) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetImage returns the Image field value if set, zero value otherwise. -func (o *CreateProjectDTO) GetImage() string { +func (o *CreateWorkspaceDTO) GetImage() string { if o == nil || IsNil(o.Image) { var ret string return ret @@ -151,7 +151,7 @@ func (o *CreateProjectDTO) GetImage() string { // GetImageOk returns a tuple with the Image field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetImageOk() (*string, bool) { +func (o *CreateWorkspaceDTO) GetImageOk() (*string, bool) { if o == nil || IsNil(o.Image) { return nil, false } @@ -159,7 +159,7 @@ func (o *CreateProjectDTO) GetImageOk() (*string, bool) { } // HasImage returns a boolean if a field has been set. -func (o *CreateProjectDTO) HasImage() bool { +func (o *CreateWorkspaceDTO) HasImage() bool { if o != nil && !IsNil(o.Image) { return true } @@ -168,12 +168,12 @@ func (o *CreateProjectDTO) HasImage() bool { } // SetImage gets a reference to the given string and assigns it to the Image field. -func (o *CreateProjectDTO) SetImage(v string) { +func (o *CreateWorkspaceDTO) SetImage(v string) { o.Image = &v } // GetName returns the Name field value -func (o *CreateProjectDTO) GetName() string { +func (o *CreateWorkspaceDTO) GetName() string { if o == nil { var ret string return ret @@ -184,7 +184,7 @@ func (o *CreateProjectDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetNameOk() (*string, bool) { +func (o *CreateWorkspaceDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -192,14 +192,14 @@ func (o *CreateProjectDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *CreateProjectDTO) SetName(v string) { +func (o *CreateWorkspaceDTO) SetName(v string) { o.Name = v } // GetSource returns the Source field value -func (o *CreateProjectDTO) GetSource() CreateProjectSourceDTO { +func (o *CreateWorkspaceDTO) GetSource() CreateWorkspaceSourceDTO { if o == nil { - var ret CreateProjectSourceDTO + var ret CreateWorkspaceSourceDTO return ret } @@ -208,7 +208,7 @@ func (o *CreateProjectDTO) GetSource() CreateProjectSourceDTO { // GetSourceOk returns a tuple with the Source field value // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetSourceOk() (*CreateProjectSourceDTO, bool) { +func (o *CreateWorkspaceDTO) GetSourceOk() (*CreateWorkspaceSourceDTO, bool) { if o == nil { return nil, false } @@ -216,12 +216,12 @@ func (o *CreateProjectDTO) GetSourceOk() (*CreateProjectSourceDTO, bool) { } // SetSource sets field value -func (o *CreateProjectDTO) SetSource(v CreateProjectSourceDTO) { +func (o *CreateWorkspaceDTO) SetSource(v CreateWorkspaceSourceDTO) { o.Source = v } // GetUser returns the User field value if set, zero value otherwise. -func (o *CreateProjectDTO) GetUser() string { +func (o *CreateWorkspaceDTO) GetUser() string { if o == nil || IsNil(o.User) { var ret string return ret @@ -231,7 +231,7 @@ func (o *CreateProjectDTO) GetUser() string { // GetUserOk returns a tuple with the User field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateProjectDTO) GetUserOk() (*string, bool) { +func (o *CreateWorkspaceDTO) GetUserOk() (*string, bool) { if o == nil || IsNil(o.User) { return nil, false } @@ -239,7 +239,7 @@ func (o *CreateProjectDTO) GetUserOk() (*string, bool) { } // HasUser returns a boolean if a field has been set. -func (o *CreateProjectDTO) HasUser() bool { +func (o *CreateWorkspaceDTO) HasUser() bool { if o != nil && !IsNil(o.User) { return true } @@ -248,11 +248,11 @@ func (o *CreateProjectDTO) HasUser() bool { } // SetUser gets a reference to the given string and assigns it to the User field. -func (o *CreateProjectDTO) SetUser(v string) { +func (o *CreateWorkspaceDTO) SetUser(v string) { o.User = &v } -func (o CreateProjectDTO) MarshalJSON() ([]byte, error) { +func (o CreateWorkspaceDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -260,7 +260,7 @@ func (o CreateProjectDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateProjectDTO) ToMap() (map[string]interface{}, error) { +func (o CreateWorkspaceDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -280,7 +280,7 @@ func (o CreateProjectDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *CreateProjectDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateWorkspaceDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -304,53 +304,53 @@ func (o *CreateProjectDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateProjectDTO := _CreateProjectDTO{} + varCreateWorkspaceDTO := _CreateWorkspaceDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateProjectDTO) + err = decoder.Decode(&varCreateWorkspaceDTO) if err != nil { return err } - *o = CreateProjectDTO(varCreateProjectDTO) + *o = CreateWorkspaceDTO(varCreateWorkspaceDTO) return err } -type NullableCreateProjectDTO struct { - value *CreateProjectDTO +type NullableCreateWorkspaceDTO struct { + value *CreateWorkspaceDTO isSet bool } -func (v NullableCreateProjectDTO) Get() *CreateProjectDTO { +func (v NullableCreateWorkspaceDTO) Get() *CreateWorkspaceDTO { return v.value } -func (v *NullableCreateProjectDTO) Set(val *CreateProjectDTO) { +func (v *NullableCreateWorkspaceDTO) Set(val *CreateWorkspaceDTO) { v.value = val v.isSet = true } -func (v NullableCreateProjectDTO) IsSet() bool { +func (v NullableCreateWorkspaceDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateProjectDTO) Unset() { +func (v *NullableCreateWorkspaceDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateProjectDTO(val *CreateProjectDTO) *NullableCreateProjectDTO { - return &NullableCreateProjectDTO{value: val, isSet: true} +func NewNullableCreateWorkspaceDTO(val *CreateWorkspaceDTO) *NullableCreateWorkspaceDTO { + return &NullableCreateWorkspaceDTO{value: val, isSet: true} } -func (v NullableCreateProjectDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateWorkspaceDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateProjectDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateWorkspaceDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_create_project_source_dto.go b/pkg/apiclient/model_create_workspace_source_dto.go similarity index 53% rename from pkg/apiclient/model_create_project_source_dto.go rename to pkg/apiclient/model_create_workspace_source_dto.go index b2c4c38bb6..00ae0684a0 100644 --- a/pkg/apiclient/model_create_project_source_dto.go +++ b/pkg/apiclient/model_create_workspace_source_dto.go @@ -16,36 +16,36 @@ import ( "fmt" ) -// checks if the CreateProjectSourceDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateProjectSourceDTO{} +// checks if the CreateWorkspaceSourceDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateWorkspaceSourceDTO{} -// CreateProjectSourceDTO struct for CreateProjectSourceDTO -type CreateProjectSourceDTO struct { +// CreateWorkspaceSourceDTO struct for CreateWorkspaceSourceDTO +type CreateWorkspaceSourceDTO struct { Repository GitRepository `json:"repository"` } -type _CreateProjectSourceDTO CreateProjectSourceDTO +type _CreateWorkspaceSourceDTO CreateWorkspaceSourceDTO -// NewCreateProjectSourceDTO instantiates a new CreateProjectSourceDTO object +// NewCreateWorkspaceSourceDTO instantiates a new CreateWorkspaceSourceDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateProjectSourceDTO(repository GitRepository) *CreateProjectSourceDTO { - this := CreateProjectSourceDTO{} +func NewCreateWorkspaceSourceDTO(repository GitRepository) *CreateWorkspaceSourceDTO { + this := CreateWorkspaceSourceDTO{} this.Repository = repository return &this } -// NewCreateProjectSourceDTOWithDefaults instantiates a new CreateProjectSourceDTO object +// NewCreateWorkspaceSourceDTOWithDefaults instantiates a new CreateWorkspaceSourceDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateProjectSourceDTOWithDefaults() *CreateProjectSourceDTO { - this := CreateProjectSourceDTO{} +func NewCreateWorkspaceSourceDTOWithDefaults() *CreateWorkspaceSourceDTO { + this := CreateWorkspaceSourceDTO{} return &this } // GetRepository returns the Repository field value -func (o *CreateProjectSourceDTO) GetRepository() GitRepository { +func (o *CreateWorkspaceSourceDTO) GetRepository() GitRepository { if o == nil { var ret GitRepository return ret @@ -56,7 +56,7 @@ func (o *CreateProjectSourceDTO) GetRepository() GitRepository { // GetRepositoryOk returns a tuple with the Repository field value // and a boolean to check if the value has been set. -func (o *CreateProjectSourceDTO) GetRepositoryOk() (*GitRepository, bool) { +func (o *CreateWorkspaceSourceDTO) GetRepositoryOk() (*GitRepository, bool) { if o == nil { return nil, false } @@ -64,11 +64,11 @@ func (o *CreateProjectSourceDTO) GetRepositoryOk() (*GitRepository, bool) { } // SetRepository sets field value -func (o *CreateProjectSourceDTO) SetRepository(v GitRepository) { +func (o *CreateWorkspaceSourceDTO) SetRepository(v GitRepository) { o.Repository = v } -func (o CreateProjectSourceDTO) MarshalJSON() ([]byte, error) { +func (o CreateWorkspaceSourceDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -76,13 +76,13 @@ func (o CreateProjectSourceDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateProjectSourceDTO) ToMap() (map[string]interface{}, error) { +func (o CreateWorkspaceSourceDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["repository"] = o.Repository return toSerialize, nil } -func (o *CreateProjectSourceDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateWorkspaceSourceDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -104,53 +104,53 @@ func (o *CreateProjectSourceDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateProjectSourceDTO := _CreateProjectSourceDTO{} + varCreateWorkspaceSourceDTO := _CreateWorkspaceSourceDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateProjectSourceDTO) + err = decoder.Decode(&varCreateWorkspaceSourceDTO) if err != nil { return err } - *o = CreateProjectSourceDTO(varCreateProjectSourceDTO) + *o = CreateWorkspaceSourceDTO(varCreateWorkspaceSourceDTO) return err } -type NullableCreateProjectSourceDTO struct { - value *CreateProjectSourceDTO +type NullableCreateWorkspaceSourceDTO struct { + value *CreateWorkspaceSourceDTO isSet bool } -func (v NullableCreateProjectSourceDTO) Get() *CreateProjectSourceDTO { +func (v NullableCreateWorkspaceSourceDTO) Get() *CreateWorkspaceSourceDTO { return v.value } -func (v *NullableCreateProjectSourceDTO) Set(val *CreateProjectSourceDTO) { +func (v *NullableCreateWorkspaceSourceDTO) Set(val *CreateWorkspaceSourceDTO) { v.value = val v.isSet = true } -func (v NullableCreateProjectSourceDTO) IsSet() bool { +func (v NullableCreateWorkspaceSourceDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateProjectSourceDTO) Unset() { +func (v *NullableCreateWorkspaceSourceDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateProjectSourceDTO(val *CreateProjectSourceDTO) *NullableCreateProjectSourceDTO { - return &NullableCreateProjectSourceDTO{value: val, isSet: true} +func NewNullableCreateWorkspaceSourceDTO(val *CreateWorkspaceSourceDTO) *NullableCreateWorkspaceSourceDTO { + return &NullableCreateWorkspaceSourceDTO{value: val, isSet: true} } -func (v NullableCreateProjectSourceDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateWorkspaceSourceDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateProjectSourceDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateWorkspaceSourceDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_prebuild_dto.go b/pkg/apiclient/model_prebuild_dto.go index 644591858c..306a955fc6 100644 --- a/pkg/apiclient/model_prebuild_dto.go +++ b/pkg/apiclient/model_prebuild_dto.go @@ -21,12 +21,12 @@ var _ MappedNullable = &PrebuildDTO{} // PrebuildDTO struct for PrebuildDTO type PrebuildDTO struct { - Branch string `json:"branch"` - CommitInterval *int32 `json:"commitInterval,omitempty"` - Id string `json:"id"` - ProjectConfigName string `json:"projectConfigName"` - Retention int32 `json:"retention"` - TriggerFiles []string `json:"triggerFiles,omitempty"` + Branch string `json:"branch"` + CommitInterval *int32 `json:"commitInterval,omitempty"` + Id string `json:"id"` + Retention int32 `json:"retention"` + TriggerFiles []string `json:"triggerFiles,omitempty"` + WorkspaceConfigName string `json:"workspaceConfigName"` } type _PrebuildDTO PrebuildDTO @@ -35,12 +35,12 @@ type _PrebuildDTO PrebuildDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewPrebuildDTO(branch string, id string, projectConfigName string, retention int32) *PrebuildDTO { +func NewPrebuildDTO(branch string, id string, retention int32, workspaceConfigName string) *PrebuildDTO { this := PrebuildDTO{} this.Branch = branch this.Id = id - this.ProjectConfigName = projectConfigName this.Retention = retention + this.WorkspaceConfigName = workspaceConfigName return &this } @@ -132,30 +132,6 @@ func (o *PrebuildDTO) SetId(v string) { o.Id = v } -// GetProjectConfigName returns the ProjectConfigName field value -func (o *PrebuildDTO) GetProjectConfigName() string { - if o == nil { - var ret string - return ret - } - - return o.ProjectConfigName -} - -// GetProjectConfigNameOk returns a tuple with the ProjectConfigName field value -// and a boolean to check if the value has been set. -func (o *PrebuildDTO) GetProjectConfigNameOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.ProjectConfigName, true -} - -// SetProjectConfigName sets field value -func (o *PrebuildDTO) SetProjectConfigName(v string) { - o.ProjectConfigName = v -} - // GetRetention returns the Retention field value func (o *PrebuildDTO) GetRetention() int32 { if o == nil { @@ -212,6 +188,30 @@ func (o *PrebuildDTO) SetTriggerFiles(v []string) { o.TriggerFiles = v } +// GetWorkspaceConfigName returns the WorkspaceConfigName field value +func (o *PrebuildDTO) GetWorkspaceConfigName() string { + if o == nil { + var ret string + return ret + } + + return o.WorkspaceConfigName +} + +// GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field value +// and a boolean to check if the value has been set. +func (o *PrebuildDTO) GetWorkspaceConfigNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.WorkspaceConfigName, true +} + +// SetWorkspaceConfigName sets field value +func (o *PrebuildDTO) SetWorkspaceConfigName(v string) { + o.WorkspaceConfigName = v +} + func (o PrebuildDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -227,11 +227,11 @@ func (o PrebuildDTO) ToMap() (map[string]interface{}, error) { toSerialize["commitInterval"] = o.CommitInterval } toSerialize["id"] = o.Id - toSerialize["projectConfigName"] = o.ProjectConfigName toSerialize["retention"] = o.Retention if !IsNil(o.TriggerFiles) { toSerialize["triggerFiles"] = o.TriggerFiles } + toSerialize["workspaceConfigName"] = o.WorkspaceConfigName return toSerialize, nil } @@ -242,8 +242,8 @@ func (o *PrebuildDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "branch", "id", - "projectConfigName", "retention", + "workspaceConfigName", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_server_config.go b/pkg/apiclient/model_server_config.go index 1e6843cd3d..bd30e9e1bc 100644 --- a/pkg/apiclient/model_server_config.go +++ b/pkg/apiclient/model_server_config.go @@ -26,8 +26,8 @@ type ServerConfig struct { BuildImageNamespace *string `json:"buildImageNamespace,omitempty"` BuilderImage string `json:"builderImage"` BuilderRegistryServer string `json:"builderRegistryServer"` - DefaultProjectImage string `json:"defaultProjectImage"` - DefaultProjectUser string `json:"defaultProjectUser"` + DefaultWorkspaceImage string `json:"defaultWorkspaceImage"` + DefaultWorkspaceUser string `json:"defaultWorkspaceUser"` Frps *FRPSConfig `json:"frps,omitempty"` HeadscalePort int32 `json:"headscalePort"` Id string `json:"id"` @@ -46,14 +46,14 @@ type _ServerConfig ServerConfig // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultProjectImage string, defaultProjectUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, providersDir string, registryUrl string, serverDownloadUrl string) *ServerConfig { +func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultWorkspaceImage string, defaultWorkspaceUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, providersDir string, registryUrl string, serverDownloadUrl string) *ServerConfig { this := ServerConfig{} this.ApiPort = apiPort this.BinariesPath = binariesPath this.BuilderImage = builderImage this.BuilderRegistryServer = builderRegistryServer - this.DefaultProjectImage = defaultProjectImage - this.DefaultProjectUser = defaultProjectUser + this.DefaultWorkspaceImage = defaultWorkspaceImage + this.DefaultWorkspaceUser = defaultWorkspaceUser this.HeadscalePort = headscalePort this.Id = id this.LocalBuilderRegistryImage = localBuilderRegistryImage @@ -201,52 +201,52 @@ func (o *ServerConfig) SetBuilderRegistryServer(v string) { o.BuilderRegistryServer = v } -// GetDefaultProjectImage returns the DefaultProjectImage field value -func (o *ServerConfig) GetDefaultProjectImage() string { +// GetDefaultWorkspaceImage returns the DefaultWorkspaceImage field value +func (o *ServerConfig) GetDefaultWorkspaceImage() string { if o == nil { var ret string return ret } - return o.DefaultProjectImage + return o.DefaultWorkspaceImage } -// GetDefaultProjectImageOk returns a tuple with the DefaultProjectImage field value +// GetDefaultWorkspaceImageOk returns a tuple with the DefaultWorkspaceImage field value // and a boolean to check if the value has been set. -func (o *ServerConfig) GetDefaultProjectImageOk() (*string, bool) { +func (o *ServerConfig) GetDefaultWorkspaceImageOk() (*string, bool) { if o == nil { return nil, false } - return &o.DefaultProjectImage, true + return &o.DefaultWorkspaceImage, true } -// SetDefaultProjectImage sets field value -func (o *ServerConfig) SetDefaultProjectImage(v string) { - o.DefaultProjectImage = v +// SetDefaultWorkspaceImage sets field value +func (o *ServerConfig) SetDefaultWorkspaceImage(v string) { + o.DefaultWorkspaceImage = v } -// GetDefaultProjectUser returns the DefaultProjectUser field value -func (o *ServerConfig) GetDefaultProjectUser() string { +// GetDefaultWorkspaceUser returns the DefaultWorkspaceUser field value +func (o *ServerConfig) GetDefaultWorkspaceUser() string { if o == nil { var ret string return ret } - return o.DefaultProjectUser + return o.DefaultWorkspaceUser } -// GetDefaultProjectUserOk returns a tuple with the DefaultProjectUser field value +// GetDefaultWorkspaceUserOk returns a tuple with the DefaultWorkspaceUser field value // and a boolean to check if the value has been set. -func (o *ServerConfig) GetDefaultProjectUserOk() (*string, bool) { +func (o *ServerConfig) GetDefaultWorkspaceUserOk() (*string, bool) { if o == nil { return nil, false } - return &o.DefaultProjectUser, true + return &o.DefaultWorkspaceUser, true } -// SetDefaultProjectUser sets field value -func (o *ServerConfig) SetDefaultProjectUser(v string) { - o.DefaultProjectUser = v +// SetDefaultWorkspaceUser sets field value +func (o *ServerConfig) SetDefaultWorkspaceUser(v string) { + o.DefaultWorkspaceUser = v } // GetFrps returns the Frps field value if set, zero value otherwise. @@ -522,8 +522,8 @@ func (o ServerConfig) ToMap() (map[string]interface{}, error) { } toSerialize["builderImage"] = o.BuilderImage toSerialize["builderRegistryServer"] = o.BuilderRegistryServer - toSerialize["defaultProjectImage"] = o.DefaultProjectImage - toSerialize["defaultProjectUser"] = o.DefaultProjectUser + toSerialize["defaultWorkspaceImage"] = o.DefaultWorkspaceImage + toSerialize["defaultWorkspaceUser"] = o.DefaultWorkspaceUser if !IsNil(o.Frps) { toSerialize["frps"] = o.Frps } @@ -550,8 +550,8 @@ func (o *ServerConfig) UnmarshalJSON(data []byte) (err error) { "binariesPath", "builderImage", "builderRegistryServer", - "defaultProjectImage", - "defaultProjectUser", + "defaultWorkspaceImage", + "defaultWorkspaceUser", "headscalePort", "id", "localBuilderRegistryImage", diff --git a/pkg/apiclient/model_set_project_state.go b/pkg/apiclient/model_set_workspace_state.go similarity index 61% rename from pkg/apiclient/model_set_project_state.go rename to pkg/apiclient/model_set_workspace_state.go index eebfd1d605..dbdebdf4c4 100644 --- a/pkg/apiclient/model_set_project_state.go +++ b/pkg/apiclient/model_set_workspace_state.go @@ -16,37 +16,37 @@ import ( "fmt" ) -// checks if the SetProjectState type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &SetProjectState{} +// checks if the SetWorkspaceState type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &SetWorkspaceState{} -// SetProjectState struct for SetProjectState -type SetProjectState struct { +// SetWorkspaceState struct for SetWorkspaceState +type SetWorkspaceState struct { GitStatus *GitStatus `json:"gitStatus,omitempty"` Uptime int32 `json:"uptime"` } -type _SetProjectState SetProjectState +type _SetWorkspaceState SetWorkspaceState -// NewSetProjectState instantiates a new SetProjectState object +// NewSetWorkspaceState instantiates a new SetWorkspaceState object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewSetProjectState(uptime int32) *SetProjectState { - this := SetProjectState{} +func NewSetWorkspaceState(uptime int32) *SetWorkspaceState { + this := SetWorkspaceState{} this.Uptime = uptime return &this } -// NewSetProjectStateWithDefaults instantiates a new SetProjectState object +// NewSetWorkspaceStateWithDefaults instantiates a new SetWorkspaceState object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewSetProjectStateWithDefaults() *SetProjectState { - this := SetProjectState{} +func NewSetWorkspaceStateWithDefaults() *SetWorkspaceState { + this := SetWorkspaceState{} return &this } // GetGitStatus returns the GitStatus field value if set, zero value otherwise. -func (o *SetProjectState) GetGitStatus() GitStatus { +func (o *SetWorkspaceState) GetGitStatus() GitStatus { if o == nil || IsNil(o.GitStatus) { var ret GitStatus return ret @@ -56,7 +56,7 @@ func (o *SetProjectState) GetGitStatus() GitStatus { // GetGitStatusOk returns a tuple with the GitStatus field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *SetProjectState) GetGitStatusOk() (*GitStatus, bool) { +func (o *SetWorkspaceState) GetGitStatusOk() (*GitStatus, bool) { if o == nil || IsNil(o.GitStatus) { return nil, false } @@ -64,7 +64,7 @@ func (o *SetProjectState) GetGitStatusOk() (*GitStatus, bool) { } // HasGitStatus returns a boolean if a field has been set. -func (o *SetProjectState) HasGitStatus() bool { +func (o *SetWorkspaceState) HasGitStatus() bool { if o != nil && !IsNil(o.GitStatus) { return true } @@ -73,12 +73,12 @@ func (o *SetProjectState) HasGitStatus() bool { } // SetGitStatus gets a reference to the given GitStatus and assigns it to the GitStatus field. -func (o *SetProjectState) SetGitStatus(v GitStatus) { +func (o *SetWorkspaceState) SetGitStatus(v GitStatus) { o.GitStatus = &v } // GetUptime returns the Uptime field value -func (o *SetProjectState) GetUptime() int32 { +func (o *SetWorkspaceState) GetUptime() int32 { if o == nil { var ret int32 return ret @@ -89,7 +89,7 @@ func (o *SetProjectState) GetUptime() int32 { // GetUptimeOk returns a tuple with the Uptime field value // and a boolean to check if the value has been set. -func (o *SetProjectState) GetUptimeOk() (*int32, bool) { +func (o *SetWorkspaceState) GetUptimeOk() (*int32, bool) { if o == nil { return nil, false } @@ -97,11 +97,11 @@ func (o *SetProjectState) GetUptimeOk() (*int32, bool) { } // SetUptime sets field value -func (o *SetProjectState) SetUptime(v int32) { +func (o *SetWorkspaceState) SetUptime(v int32) { o.Uptime = v } -func (o SetProjectState) MarshalJSON() ([]byte, error) { +func (o SetWorkspaceState) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -109,7 +109,7 @@ func (o SetProjectState) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o SetProjectState) ToMap() (map[string]interface{}, error) { +func (o SetWorkspaceState) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.GitStatus) { toSerialize["gitStatus"] = o.GitStatus @@ -118,7 +118,7 @@ func (o SetProjectState) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *SetProjectState) UnmarshalJSON(data []byte) (err error) { +func (o *SetWorkspaceState) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -140,53 +140,53 @@ func (o *SetProjectState) UnmarshalJSON(data []byte) (err error) { } } - varSetProjectState := _SetProjectState{} + varSetWorkspaceState := _SetWorkspaceState{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varSetProjectState) + err = decoder.Decode(&varSetWorkspaceState) if err != nil { return err } - *o = SetProjectState(varSetProjectState) + *o = SetWorkspaceState(varSetWorkspaceState) return err } -type NullableSetProjectState struct { - value *SetProjectState +type NullableSetWorkspaceState struct { + value *SetWorkspaceState isSet bool } -func (v NullableSetProjectState) Get() *SetProjectState { +func (v NullableSetWorkspaceState) Get() *SetWorkspaceState { return v.value } -func (v *NullableSetProjectState) Set(val *SetProjectState) { +func (v *NullableSetWorkspaceState) Set(val *SetWorkspaceState) { v.value = val v.isSet = true } -func (v NullableSetProjectState) IsSet() bool { +func (v NullableSetWorkspaceState) IsSet() bool { return v.isSet } -func (v *NullableSetProjectState) Unset() { +func (v *NullableSetWorkspaceState) Unset() { v.value = nil v.isSet = false } -func NewNullableSetProjectState(val *SetProjectState) *NullableSetProjectState { - return &NullableSetProjectState{value: val, isSet: true} +func NewNullableSetWorkspaceState(val *SetWorkspaceState) *NullableSetWorkspaceState { + return &NullableSetWorkspaceState{value: val, isSet: true} } -func (v NullableSetProjectState) MarshalJSON() ([]byte, error) { +func (v NullableSetWorkspaceState) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableSetProjectState) UnmarshalJSON(src []byte) error { +func (v *NullableSetWorkspaceState) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index c74ac69ed8..cd132eff46 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -21,10 +21,10 @@ var _ MappedNullable = &Target{} // Target struct for Target type Target struct { - Id string `json:"id"` - Name string `json:"name"` - Projects []Project `json:"projects"` - TargetConfig string `json:"targetConfig"` + Id string `json:"id"` + Name string `json:"name"` + TargetConfig string `json:"targetConfig"` + Workspaces []Workspace `json:"workspaces"` } type _Target Target @@ -33,12 +33,12 @@ type _Target Target // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTarget(id string, name string, projects []Project, targetConfig string) *Target { +func NewTarget(id string, name string, targetConfig string, workspaces []Workspace) *Target { this := Target{} this.Id = id this.Name = name - this.Projects = projects this.TargetConfig = targetConfig + this.Workspaces = workspaces return &this } @@ -98,52 +98,52 @@ func (o *Target) SetName(v string) { o.Name = v } -// GetProjects returns the Projects field value -func (o *Target) GetProjects() []Project { +// GetTargetConfig returns the TargetConfig field value +func (o *Target) GetTargetConfig() string { if o == nil { - var ret []Project + var ret string return ret } - return o.Projects + return o.TargetConfig } -// GetProjectsOk returns a tuple with the Projects field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *Target) GetProjectsOk() ([]Project, bool) { +func (o *Target) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return o.Projects, true + return &o.TargetConfig, true } -// SetProjects sets field value -func (o *Target) SetProjects(v []Project) { - o.Projects = v +// SetTargetConfig sets field value +func (o *Target) SetTargetConfig(v string) { + o.TargetConfig = v } -// GetTargetConfig returns the TargetConfig field value -func (o *Target) GetTargetConfig() string { +// GetWorkspaces returns the Workspaces field value +func (o *Target) GetWorkspaces() []Workspace { if o == nil { - var ret string + var ret []Workspace return ret } - return o.TargetConfig + return o.Workspaces } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetWorkspacesOk returns a tuple with the Workspaces field value // and a boolean to check if the value has been set. -func (o *Target) GetTargetConfigOk() (*string, bool) { +func (o *Target) GetWorkspacesOk() ([]Workspace, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return o.Workspaces, true } -// SetTargetConfig sets field value -func (o *Target) SetTargetConfig(v string) { - o.TargetConfig = v +// SetWorkspaces sets field value +func (o *Target) SetWorkspaces(v []Workspace) { + o.Workspaces = v } func (o Target) MarshalJSON() ([]byte, error) { @@ -158,8 +158,8 @@ func (o Target) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name - toSerialize["projects"] = o.Projects toSerialize["targetConfig"] = o.TargetConfig + toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -170,8 +170,8 @@ func (o *Target) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "id", "name", - "projects", "targetConfig", + "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 7be1814fa4..59cc945b5a 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -24,8 +24,8 @@ type TargetDTO struct { Id string `json:"id"` Info *TargetInfo `json:"info,omitempty"` Name string `json:"name"` - Projects []Project `json:"projects"` TargetConfig string `json:"targetConfig"` + Workspaces []Workspace `json:"workspaces"` } type _TargetDTO TargetDTO @@ -34,12 +34,12 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(id string, name string, projects []Project, targetConfig string) *TargetDTO { +func NewTargetDTO(id string, name string, targetConfig string, workspaces []Workspace) *TargetDTO { this := TargetDTO{} this.Id = id this.Name = name - this.Projects = projects this.TargetConfig = targetConfig + this.Workspaces = workspaces return &this } @@ -131,52 +131,52 @@ func (o *TargetDTO) SetName(v string) { o.Name = v } -// GetProjects returns the Projects field value -func (o *TargetDTO) GetProjects() []Project { +// GetTargetConfig returns the TargetConfig field value +func (o *TargetDTO) GetTargetConfig() string { if o == nil { - var ret []Project + var ret string return ret } - return o.Projects + return o.TargetConfig } -// GetProjectsOk returns a tuple with the Projects field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *TargetDTO) GetProjectsOk() ([]Project, bool) { +func (o *TargetDTO) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } - return o.Projects, true + return &o.TargetConfig, true } -// SetProjects sets field value -func (o *TargetDTO) SetProjects(v []Project) { - o.Projects = v +// SetTargetConfig sets field value +func (o *TargetDTO) SetTargetConfig(v string) { + o.TargetConfig = v } -// GetTargetConfig returns the TargetConfig field value -func (o *TargetDTO) GetTargetConfig() string { +// GetWorkspaces returns the Workspaces field value +func (o *TargetDTO) GetWorkspaces() []Workspace { if o == nil { - var ret string + var ret []Workspace return ret } - return o.TargetConfig + return o.Workspaces } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetWorkspacesOk returns a tuple with the Workspaces field value // and a boolean to check if the value has been set. -func (o *TargetDTO) GetTargetConfigOk() (*string, bool) { +func (o *TargetDTO) GetWorkspacesOk() ([]Workspace, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return o.Workspaces, true } -// SetTargetConfig sets field value -func (o *TargetDTO) SetTargetConfig(v string) { - o.TargetConfig = v +// SetWorkspaces sets field value +func (o *TargetDTO) SetWorkspaces(v []Workspace) { + o.Workspaces = v } func (o TargetDTO) MarshalJSON() ([]byte, error) { @@ -194,8 +194,8 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["info"] = o.Info } toSerialize["name"] = o.Name - toSerialize["projects"] = o.Projects toSerialize["targetConfig"] = o.TargetConfig + toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -206,8 +206,8 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "id", "name", - "projects", "targetConfig", + "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_info.go b/pkg/apiclient/model_target_info.go index 6efac92903..3e72c92962 100644 --- a/pkg/apiclient/model_target_info.go +++ b/pkg/apiclient/model_target_info.go @@ -21,9 +21,9 @@ var _ MappedNullable = &TargetInfo{} // TargetInfo struct for TargetInfo type TargetInfo struct { - Name string `json:"name"` - Projects []ProjectInfo `json:"projects"` - ProviderMetadata *string `json:"providerMetadata,omitempty"` + Name string `json:"name"` + ProviderMetadata *string `json:"providerMetadata,omitempty"` + Workspaces []WorkspaceInfo `json:"workspaces"` } type _TargetInfo TargetInfo @@ -32,10 +32,10 @@ type _TargetInfo TargetInfo // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetInfo(name string, projects []ProjectInfo) *TargetInfo { +func NewTargetInfo(name string, workspaces []WorkspaceInfo) *TargetInfo { this := TargetInfo{} this.Name = name - this.Projects = projects + this.Workspaces = workspaces return &this } @@ -71,30 +71,6 @@ func (o *TargetInfo) SetName(v string) { o.Name = v } -// GetProjects returns the Projects field value -func (o *TargetInfo) GetProjects() []ProjectInfo { - if o == nil { - var ret []ProjectInfo - return ret - } - - return o.Projects -} - -// GetProjectsOk returns a tuple with the Projects field value -// and a boolean to check if the value has been set. -func (o *TargetInfo) GetProjectsOk() ([]ProjectInfo, bool) { - if o == nil { - return nil, false - } - return o.Projects, true -} - -// SetProjects sets field value -func (o *TargetInfo) SetProjects(v []ProjectInfo) { - o.Projects = v -} - // GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. func (o *TargetInfo) GetProviderMetadata() string { if o == nil || IsNil(o.ProviderMetadata) { @@ -127,6 +103,30 @@ func (o *TargetInfo) SetProviderMetadata(v string) { o.ProviderMetadata = &v } +// GetWorkspaces returns the Workspaces field value +func (o *TargetInfo) GetWorkspaces() []WorkspaceInfo { + if o == nil { + var ret []WorkspaceInfo + return ret + } + + return o.Workspaces +} + +// GetWorkspacesOk returns a tuple with the Workspaces field value +// and a boolean to check if the value has been set. +func (o *TargetInfo) GetWorkspacesOk() ([]WorkspaceInfo, bool) { + if o == nil { + return nil, false + } + return o.Workspaces, true +} + +// SetWorkspaces sets field value +func (o *TargetInfo) SetWorkspaces(v []WorkspaceInfo) { + o.Workspaces = v +} + func (o TargetInfo) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -138,10 +138,10 @@ func (o TargetInfo) MarshalJSON() ([]byte, error) { func (o TargetInfo) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["name"] = o.Name - toSerialize["projects"] = o.Projects if !IsNil(o.ProviderMetadata) { toSerialize["providerMetadata"] = o.ProviderMetadata } + toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -151,7 +151,7 @@ func (o *TargetInfo) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "name", - "projects", + "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_project.go b/pkg/apiclient/model_workspace.go similarity index 70% rename from pkg/apiclient/model_project.go rename to pkg/apiclient/model_workspace.go index d8676bd1a0..d5035f12cf 100644 --- a/pkg/apiclient/model_project.go +++ b/pkg/apiclient/model_workspace.go @@ -16,31 +16,31 @@ import ( "fmt" ) -// checks if the Project type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &Project{} +// checks if the Workspace type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Workspace{} -// Project struct for Project -type Project struct { +// Workspace struct for Workspace +type Workspace struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` Image string `json:"image"` Name string `json:"name"` Repository GitRepository `json:"repository"` - State *ProjectState `json:"state,omitempty"` + State *WorkspaceState `json:"state,omitempty"` TargetConfig string `json:"targetConfig"` TargetId string `json:"targetId"` User string `json:"user"` } -type _Project Project +type _Workspace Workspace -// NewProject instantiates a new Project object +// NewWorkspace instantiates a new Workspace object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProject(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string) *Project { - this := Project{} +func NewWorkspace(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string) *Workspace { + this := Workspace{} this.EnvVars = envVars this.Image = image this.Name = name @@ -51,16 +51,16 @@ func NewProject(envVars map[string]string, image string, name string, repository return &this } -// NewProjectWithDefaults instantiates a new Project object +// NewWorkspaceWithDefaults instantiates a new Workspace object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProjectWithDefaults() *Project { - this := Project{} +func NewWorkspaceWithDefaults() *Workspace { + this := Workspace{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *Project) GetBuildConfig() BuildConfig { +func (o *Workspace) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -70,7 +70,7 @@ func (o *Project) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Project) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -78,7 +78,7 @@ func (o *Project) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *Project) HasBuildConfig() bool { +func (o *Workspace) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -87,12 +87,12 @@ func (o *Project) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *Project) SetBuildConfig(v BuildConfig) { +func (o *Workspace) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetEnvVars returns the EnvVars field value -func (o *Project) GetEnvVars() map[string]string { +func (o *Workspace) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -103,7 +103,7 @@ func (o *Project) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *Project) GetEnvVarsOk() (*map[string]string, bool) { +func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -111,12 +111,12 @@ func (o *Project) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *Project) SetEnvVars(v map[string]string) { +func (o *Workspace) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *Project) GetGitProviderConfigId() string { +func (o *Workspace) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -126,7 +126,7 @@ func (o *Project) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Project) GetGitProviderConfigIdOk() (*string, bool) { +func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -134,7 +134,7 @@ func (o *Project) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *Project) HasGitProviderConfigId() bool { +func (o *Workspace) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -143,12 +143,12 @@ func (o *Project) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *Project) SetGitProviderConfigId(v string) { +func (o *Workspace) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetImage returns the Image field value -func (o *Project) GetImage() string { +func (o *Workspace) GetImage() string { if o == nil { var ret string return ret @@ -159,7 +159,7 @@ func (o *Project) GetImage() string { // GetImageOk returns a tuple with the Image field value // and a boolean to check if the value has been set. -func (o *Project) GetImageOk() (*string, bool) { +func (o *Workspace) GetImageOk() (*string, bool) { if o == nil { return nil, false } @@ -167,12 +167,12 @@ func (o *Project) GetImageOk() (*string, bool) { } // SetImage sets field value -func (o *Project) SetImage(v string) { +func (o *Workspace) SetImage(v string) { o.Image = v } // GetName returns the Name field value -func (o *Project) GetName() string { +func (o *Workspace) GetName() string { if o == nil { var ret string return ret @@ -183,7 +183,7 @@ func (o *Project) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *Project) GetNameOk() (*string, bool) { +func (o *Workspace) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -191,12 +191,12 @@ func (o *Project) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *Project) SetName(v string) { +func (o *Workspace) SetName(v string) { o.Name = v } // GetRepository returns the Repository field value -func (o *Project) GetRepository() GitRepository { +func (o *Workspace) GetRepository() GitRepository { if o == nil { var ret GitRepository return ret @@ -207,7 +207,7 @@ func (o *Project) GetRepository() GitRepository { // GetRepositoryOk returns a tuple with the Repository field value // and a boolean to check if the value has been set. -func (o *Project) GetRepositoryOk() (*GitRepository, bool) { +func (o *Workspace) GetRepositoryOk() (*GitRepository, bool) { if o == nil { return nil, false } @@ -215,14 +215,14 @@ func (o *Project) GetRepositoryOk() (*GitRepository, bool) { } // SetRepository sets field value -func (o *Project) SetRepository(v GitRepository) { +func (o *Workspace) SetRepository(v GitRepository) { o.Repository = v } // GetState returns the State field value if set, zero value otherwise. -func (o *Project) GetState() ProjectState { +func (o *Workspace) GetState() WorkspaceState { if o == nil || IsNil(o.State) { - var ret ProjectState + var ret WorkspaceState return ret } return *o.State @@ -230,7 +230,7 @@ func (o *Project) GetState() ProjectState { // GetStateOk returns a tuple with the State field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Project) GetStateOk() (*ProjectState, bool) { +func (o *Workspace) GetStateOk() (*WorkspaceState, bool) { if o == nil || IsNil(o.State) { return nil, false } @@ -238,7 +238,7 @@ func (o *Project) GetStateOk() (*ProjectState, bool) { } // HasState returns a boolean if a field has been set. -func (o *Project) HasState() bool { +func (o *Workspace) HasState() bool { if o != nil && !IsNil(o.State) { return true } @@ -246,13 +246,13 @@ func (o *Project) HasState() bool { return false } -// SetState gets a reference to the given ProjectState and assigns it to the State field. -func (o *Project) SetState(v ProjectState) { +// SetState gets a reference to the given WorkspaceState and assigns it to the State field. +func (o *Workspace) SetState(v WorkspaceState) { o.State = &v } // GetTargetConfig returns the TargetConfig field value -func (o *Project) GetTargetConfig() string { +func (o *Workspace) GetTargetConfig() string { if o == nil { var ret string return ret @@ -263,7 +263,7 @@ func (o *Project) GetTargetConfig() string { // GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *Project) GetTargetConfigOk() (*string, bool) { +func (o *Workspace) GetTargetConfigOk() (*string, bool) { if o == nil { return nil, false } @@ -271,12 +271,12 @@ func (o *Project) GetTargetConfigOk() (*string, bool) { } // SetTargetConfig sets field value -func (o *Project) SetTargetConfig(v string) { +func (o *Workspace) SetTargetConfig(v string) { o.TargetConfig = v } // GetTargetId returns the TargetId field value -func (o *Project) GetTargetId() string { +func (o *Workspace) GetTargetId() string { if o == nil { var ret string return ret @@ -287,7 +287,7 @@ func (o *Project) GetTargetId() string { // GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *Project) GetTargetIdOk() (*string, bool) { +func (o *Workspace) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -295,12 +295,12 @@ func (o *Project) GetTargetIdOk() (*string, bool) { } // SetTargetId sets field value -func (o *Project) SetTargetId(v string) { +func (o *Workspace) SetTargetId(v string) { o.TargetId = v } // GetUser returns the User field value -func (o *Project) GetUser() string { +func (o *Workspace) GetUser() string { if o == nil { var ret string return ret @@ -311,7 +311,7 @@ func (o *Project) GetUser() string { // GetUserOk returns a tuple with the User field value // and a boolean to check if the value has been set. -func (o *Project) GetUserOk() (*string, bool) { +func (o *Workspace) GetUserOk() (*string, bool) { if o == nil { return nil, false } @@ -319,11 +319,11 @@ func (o *Project) GetUserOk() (*string, bool) { } // SetUser sets field value -func (o *Project) SetUser(v string) { +func (o *Workspace) SetUser(v string) { o.User = v } -func (o Project) MarshalJSON() ([]byte, error) { +func (o Workspace) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -331,7 +331,7 @@ func (o Project) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o Project) ToMap() (map[string]interface{}, error) { +func (o Workspace) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -352,7 +352,7 @@ func (o Project) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *Project) UnmarshalJSON(data []byte) (err error) { +func (o *Workspace) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -380,53 +380,53 @@ func (o *Project) UnmarshalJSON(data []byte) (err error) { } } - varProject := _Project{} + varWorkspace := _Workspace{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varProject) + err = decoder.Decode(&varWorkspace) if err != nil { return err } - *o = Project(varProject) + *o = Workspace(varWorkspace) return err } -type NullableProject struct { - value *Project +type NullableWorkspace struct { + value *Workspace isSet bool } -func (v NullableProject) Get() *Project { +func (v NullableWorkspace) Get() *Workspace { return v.value } -func (v *NullableProject) Set(val *Project) { +func (v *NullableWorkspace) Set(val *Workspace) { v.value = val v.isSet = true } -func (v NullableProject) IsSet() bool { +func (v NullableWorkspace) IsSet() bool { return v.isSet } -func (v *NullableProject) Unset() { +func (v *NullableWorkspace) Unset() { v.value = nil v.isSet = false } -func NewNullableProject(val *Project) *NullableProject { - return &NullableProject{value: val, isSet: true} +func NewNullableWorkspace(val *Workspace) *NullableWorkspace { + return &NullableWorkspace{value: val, isSet: true} } -func (v NullableProject) MarshalJSON() ([]byte, error) { +func (v NullableWorkspace) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProject) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspace) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_project_config.go b/pkg/apiclient/model_workspace_config.go similarity index 69% rename from pkg/apiclient/model_project_config.go rename to pkg/apiclient/model_workspace_config.go index 2e5b034213..36ad409edc 100644 --- a/pkg/apiclient/model_project_config.go +++ b/pkg/apiclient/model_workspace_config.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the ProjectConfig type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProjectConfig{} +// checks if the WorkspaceConfig type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceConfig{} -// ProjectConfig struct for ProjectConfig -type ProjectConfig struct { +// WorkspaceConfig struct for WorkspaceConfig +type WorkspaceConfig struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` Default bool `json:"default"` EnvVars map[string]string `json:"envVars"` @@ -32,14 +32,14 @@ type ProjectConfig struct { User string `json:"user"` } -type _ProjectConfig ProjectConfig +type _WorkspaceConfig WorkspaceConfig -// NewProjectConfig instantiates a new ProjectConfig object +// NewWorkspaceConfig instantiates a new WorkspaceConfig object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProjectConfig(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string) *ProjectConfig { - this := ProjectConfig{} +func NewWorkspaceConfig(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string) *WorkspaceConfig { + this := WorkspaceConfig{} this.Default = default_ this.EnvVars = envVars this.Image = image @@ -49,16 +49,16 @@ func NewProjectConfig(default_ bool, envVars map[string]string, image string, na return &this } -// NewProjectConfigWithDefaults instantiates a new ProjectConfig object +// NewWorkspaceConfigWithDefaults instantiates a new WorkspaceConfig object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProjectConfigWithDefaults() *ProjectConfig { - this := ProjectConfig{} +func NewWorkspaceConfigWithDefaults() *WorkspaceConfig { + this := WorkspaceConfig{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *ProjectConfig) GetBuildConfig() BuildConfig { +func (o *WorkspaceConfig) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -68,7 +68,7 @@ func (o *ProjectConfig) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *WorkspaceConfig) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -76,7 +76,7 @@ func (o *ProjectConfig) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *ProjectConfig) HasBuildConfig() bool { +func (o *WorkspaceConfig) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -85,12 +85,12 @@ func (o *ProjectConfig) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *ProjectConfig) SetBuildConfig(v BuildConfig) { +func (o *WorkspaceConfig) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetDefault returns the Default field value -func (o *ProjectConfig) GetDefault() bool { +func (o *WorkspaceConfig) GetDefault() bool { if o == nil { var ret bool return ret @@ -101,7 +101,7 @@ func (o *ProjectConfig) GetDefault() bool { // GetDefaultOk returns a tuple with the Default field value // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetDefaultOk() (*bool, bool) { +func (o *WorkspaceConfig) GetDefaultOk() (*bool, bool) { if o == nil { return nil, false } @@ -109,12 +109,12 @@ func (o *ProjectConfig) GetDefaultOk() (*bool, bool) { } // SetDefault sets field value -func (o *ProjectConfig) SetDefault(v bool) { +func (o *WorkspaceConfig) SetDefault(v bool) { o.Default = v } // GetEnvVars returns the EnvVars field value -func (o *ProjectConfig) GetEnvVars() map[string]string { +func (o *WorkspaceConfig) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -125,7 +125,7 @@ func (o *ProjectConfig) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetEnvVarsOk() (*map[string]string, bool) { +func (o *WorkspaceConfig) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -133,12 +133,12 @@ func (o *ProjectConfig) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *ProjectConfig) SetEnvVars(v map[string]string) { +func (o *WorkspaceConfig) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *ProjectConfig) GetGitProviderConfigId() string { +func (o *WorkspaceConfig) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -148,7 +148,7 @@ func (o *ProjectConfig) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetGitProviderConfigIdOk() (*string, bool) { +func (o *WorkspaceConfig) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -156,7 +156,7 @@ func (o *ProjectConfig) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *ProjectConfig) HasGitProviderConfigId() bool { +func (o *WorkspaceConfig) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -165,12 +165,12 @@ func (o *ProjectConfig) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *ProjectConfig) SetGitProviderConfigId(v string) { +func (o *WorkspaceConfig) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetImage returns the Image field value -func (o *ProjectConfig) GetImage() string { +func (o *WorkspaceConfig) GetImage() string { if o == nil { var ret string return ret @@ -181,7 +181,7 @@ func (o *ProjectConfig) GetImage() string { // GetImageOk returns a tuple with the Image field value // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetImageOk() (*string, bool) { +func (o *WorkspaceConfig) GetImageOk() (*string, bool) { if o == nil { return nil, false } @@ -189,12 +189,12 @@ func (o *ProjectConfig) GetImageOk() (*string, bool) { } // SetImage sets field value -func (o *ProjectConfig) SetImage(v string) { +func (o *WorkspaceConfig) SetImage(v string) { o.Image = v } // GetName returns the Name field value -func (o *ProjectConfig) GetName() string { +func (o *WorkspaceConfig) GetName() string { if o == nil { var ret string return ret @@ -205,7 +205,7 @@ func (o *ProjectConfig) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetNameOk() (*string, bool) { +func (o *WorkspaceConfig) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -213,12 +213,12 @@ func (o *ProjectConfig) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *ProjectConfig) SetName(v string) { +func (o *WorkspaceConfig) SetName(v string) { o.Name = v } // GetPrebuilds returns the Prebuilds field value if set, zero value otherwise. -func (o *ProjectConfig) GetPrebuilds() []PrebuildConfig { +func (o *WorkspaceConfig) GetPrebuilds() []PrebuildConfig { if o == nil || IsNil(o.Prebuilds) { var ret []PrebuildConfig return ret @@ -228,7 +228,7 @@ func (o *ProjectConfig) GetPrebuilds() []PrebuildConfig { // GetPrebuildsOk returns a tuple with the Prebuilds field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetPrebuildsOk() ([]PrebuildConfig, bool) { +func (o *WorkspaceConfig) GetPrebuildsOk() ([]PrebuildConfig, bool) { if o == nil || IsNil(o.Prebuilds) { return nil, false } @@ -236,7 +236,7 @@ func (o *ProjectConfig) GetPrebuildsOk() ([]PrebuildConfig, bool) { } // HasPrebuilds returns a boolean if a field has been set. -func (o *ProjectConfig) HasPrebuilds() bool { +func (o *WorkspaceConfig) HasPrebuilds() bool { if o != nil && !IsNil(o.Prebuilds) { return true } @@ -245,12 +245,12 @@ func (o *ProjectConfig) HasPrebuilds() bool { } // SetPrebuilds gets a reference to the given []PrebuildConfig and assigns it to the Prebuilds field. -func (o *ProjectConfig) SetPrebuilds(v []PrebuildConfig) { +func (o *WorkspaceConfig) SetPrebuilds(v []PrebuildConfig) { o.Prebuilds = v } // GetRepositoryUrl returns the RepositoryUrl field value -func (o *ProjectConfig) GetRepositoryUrl() string { +func (o *WorkspaceConfig) GetRepositoryUrl() string { if o == nil { var ret string return ret @@ -261,7 +261,7 @@ func (o *ProjectConfig) GetRepositoryUrl() string { // GetRepositoryUrlOk returns a tuple with the RepositoryUrl field value // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetRepositoryUrlOk() (*string, bool) { +func (o *WorkspaceConfig) GetRepositoryUrlOk() (*string, bool) { if o == nil { return nil, false } @@ -269,12 +269,12 @@ func (o *ProjectConfig) GetRepositoryUrlOk() (*string, bool) { } // SetRepositoryUrl sets field value -func (o *ProjectConfig) SetRepositoryUrl(v string) { +func (o *WorkspaceConfig) SetRepositoryUrl(v string) { o.RepositoryUrl = v } // GetUser returns the User field value -func (o *ProjectConfig) GetUser() string { +func (o *WorkspaceConfig) GetUser() string { if o == nil { var ret string return ret @@ -285,7 +285,7 @@ func (o *ProjectConfig) GetUser() string { // GetUserOk returns a tuple with the User field value // and a boolean to check if the value has been set. -func (o *ProjectConfig) GetUserOk() (*string, bool) { +func (o *WorkspaceConfig) GetUserOk() (*string, bool) { if o == nil { return nil, false } @@ -293,11 +293,11 @@ func (o *ProjectConfig) GetUserOk() (*string, bool) { } // SetUser sets field value -func (o *ProjectConfig) SetUser(v string) { +func (o *WorkspaceConfig) SetUser(v string) { o.User = v } -func (o ProjectConfig) MarshalJSON() ([]byte, error) { +func (o WorkspaceConfig) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -305,7 +305,7 @@ func (o ProjectConfig) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProjectConfig) ToMap() (map[string]interface{}, error) { +func (o WorkspaceConfig) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -325,7 +325,7 @@ func (o ProjectConfig) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *ProjectConfig) UnmarshalJSON(data []byte) (err error) { +func (o *WorkspaceConfig) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -352,53 +352,53 @@ func (o *ProjectConfig) UnmarshalJSON(data []byte) (err error) { } } - varProjectConfig := _ProjectConfig{} + varWorkspaceConfig := _WorkspaceConfig{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varProjectConfig) + err = decoder.Decode(&varWorkspaceConfig) if err != nil { return err } - *o = ProjectConfig(varProjectConfig) + *o = WorkspaceConfig(varWorkspaceConfig) return err } -type NullableProjectConfig struct { - value *ProjectConfig +type NullableWorkspaceConfig struct { + value *WorkspaceConfig isSet bool } -func (v NullableProjectConfig) Get() *ProjectConfig { +func (v NullableWorkspaceConfig) Get() *WorkspaceConfig { return v.value } -func (v *NullableProjectConfig) Set(val *ProjectConfig) { +func (v *NullableWorkspaceConfig) Set(val *WorkspaceConfig) { v.value = val v.isSet = true } -func (v NullableProjectConfig) IsSet() bool { +func (v NullableWorkspaceConfig) IsSet() bool { return v.isSet } -func (v *NullableProjectConfig) Unset() { +func (v *NullableWorkspaceConfig) Unset() { v.value = nil v.isSet = false } -func NewNullableProjectConfig(val *ProjectConfig) *NullableProjectConfig { - return &NullableProjectConfig{value: val, isSet: true} +func NewNullableWorkspaceConfig(val *WorkspaceConfig) *NullableWorkspaceConfig { + return &NullableWorkspaceConfig{value: val, isSet: true} } -func (v NullableProjectConfig) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceConfig) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProjectConfig) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceConfig) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_project_dir_response.go b/pkg/apiclient/model_workspace_dir_response.go similarity index 52% rename from pkg/apiclient/model_project_dir_response.go rename to pkg/apiclient/model_workspace_dir_response.go index 142707bf66..9ce87fb0b7 100644 --- a/pkg/apiclient/model_project_dir_response.go +++ b/pkg/apiclient/model_workspace_dir_response.go @@ -14,33 +14,33 @@ import ( "encoding/json" ) -// checks if the ProjectDirResponse type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProjectDirResponse{} +// checks if the WorkspaceDirResponse type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceDirResponse{} -// ProjectDirResponse struct for ProjectDirResponse -type ProjectDirResponse struct { +// WorkspaceDirResponse struct for WorkspaceDirResponse +type WorkspaceDirResponse struct { Dir *string `json:"dir,omitempty"` } -// NewProjectDirResponse instantiates a new ProjectDirResponse object +// NewWorkspaceDirResponse instantiates a new WorkspaceDirResponse object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProjectDirResponse() *ProjectDirResponse { - this := ProjectDirResponse{} +func NewWorkspaceDirResponse() *WorkspaceDirResponse { + this := WorkspaceDirResponse{} return &this } -// NewProjectDirResponseWithDefaults instantiates a new ProjectDirResponse object +// NewWorkspaceDirResponseWithDefaults instantiates a new WorkspaceDirResponse object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProjectDirResponseWithDefaults() *ProjectDirResponse { - this := ProjectDirResponse{} +func NewWorkspaceDirResponseWithDefaults() *WorkspaceDirResponse { + this := WorkspaceDirResponse{} return &this } // GetDir returns the Dir field value if set, zero value otherwise. -func (o *ProjectDirResponse) GetDir() string { +func (o *WorkspaceDirResponse) GetDir() string { if o == nil || IsNil(o.Dir) { var ret string return ret @@ -50,7 +50,7 @@ func (o *ProjectDirResponse) GetDir() string { // GetDirOk returns a tuple with the Dir field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProjectDirResponse) GetDirOk() (*string, bool) { +func (o *WorkspaceDirResponse) GetDirOk() (*string, bool) { if o == nil || IsNil(o.Dir) { return nil, false } @@ -58,7 +58,7 @@ func (o *ProjectDirResponse) GetDirOk() (*string, bool) { } // HasDir returns a boolean if a field has been set. -func (o *ProjectDirResponse) HasDir() bool { +func (o *WorkspaceDirResponse) HasDir() bool { if o != nil && !IsNil(o.Dir) { return true } @@ -67,11 +67,11 @@ func (o *ProjectDirResponse) HasDir() bool { } // SetDir gets a reference to the given string and assigns it to the Dir field. -func (o *ProjectDirResponse) SetDir(v string) { +func (o *WorkspaceDirResponse) SetDir(v string) { o.Dir = &v } -func (o ProjectDirResponse) MarshalJSON() ([]byte, error) { +func (o WorkspaceDirResponse) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -79,7 +79,7 @@ func (o ProjectDirResponse) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProjectDirResponse) ToMap() (map[string]interface{}, error) { +func (o WorkspaceDirResponse) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.Dir) { toSerialize["dir"] = o.Dir @@ -87,38 +87,38 @@ func (o ProjectDirResponse) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableProjectDirResponse struct { - value *ProjectDirResponse +type NullableWorkspaceDirResponse struct { + value *WorkspaceDirResponse isSet bool } -func (v NullableProjectDirResponse) Get() *ProjectDirResponse { +func (v NullableWorkspaceDirResponse) Get() *WorkspaceDirResponse { return v.value } -func (v *NullableProjectDirResponse) Set(val *ProjectDirResponse) { +func (v *NullableWorkspaceDirResponse) Set(val *WorkspaceDirResponse) { v.value = val v.isSet = true } -func (v NullableProjectDirResponse) IsSet() bool { +func (v NullableWorkspaceDirResponse) IsSet() bool { return v.isSet } -func (v *NullableProjectDirResponse) Unset() { +func (v *NullableWorkspaceDirResponse) Unset() { v.value = nil v.isSet = false } -func NewNullableProjectDirResponse(val *ProjectDirResponse) *NullableProjectDirResponse { - return &NullableProjectDirResponse{value: val, isSet: true} +func NewNullableWorkspaceDirResponse(val *WorkspaceDirResponse) *NullableWorkspaceDirResponse { + return &NullableWorkspaceDirResponse{value: val, isSet: true} } -func (v NullableProjectDirResponse) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceDirResponse) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProjectDirResponse) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceDirResponse) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_project_info.go b/pkg/apiclient/model_workspace_info.go similarity index 67% rename from pkg/apiclient/model_project_info.go rename to pkg/apiclient/model_workspace_info.go index 3bdf2a543e..9d65cb3e74 100644 --- a/pkg/apiclient/model_project_info.go +++ b/pkg/apiclient/model_workspace_info.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the ProjectInfo type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProjectInfo{} +// checks if the WorkspaceInfo type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceInfo{} -// ProjectInfo struct for ProjectInfo -type ProjectInfo struct { +// WorkspaceInfo struct for WorkspaceInfo +type WorkspaceInfo struct { Created string `json:"created"` IsRunning bool `json:"isRunning"` Name string `json:"name"` @@ -28,14 +28,14 @@ type ProjectInfo struct { TargetId string `json:"targetId"` } -type _ProjectInfo ProjectInfo +type _WorkspaceInfo WorkspaceInfo -// NewProjectInfo instantiates a new ProjectInfo object +// NewWorkspaceInfo instantiates a new WorkspaceInfo object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProjectInfo(created string, isRunning bool, name string, targetId string) *ProjectInfo { - this := ProjectInfo{} +func NewWorkspaceInfo(created string, isRunning bool, name string, targetId string) *WorkspaceInfo { + this := WorkspaceInfo{} this.Created = created this.IsRunning = isRunning this.Name = name @@ -43,16 +43,16 @@ func NewProjectInfo(created string, isRunning bool, name string, targetId string return &this } -// NewProjectInfoWithDefaults instantiates a new ProjectInfo object +// NewWorkspaceInfoWithDefaults instantiates a new WorkspaceInfo object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProjectInfoWithDefaults() *ProjectInfo { - this := ProjectInfo{} +func NewWorkspaceInfoWithDefaults() *WorkspaceInfo { + this := WorkspaceInfo{} return &this } // GetCreated returns the Created field value -func (o *ProjectInfo) GetCreated() string { +func (o *WorkspaceInfo) GetCreated() string { if o == nil { var ret string return ret @@ -63,7 +63,7 @@ func (o *ProjectInfo) GetCreated() string { // GetCreatedOk returns a tuple with the Created field value // and a boolean to check if the value has been set. -func (o *ProjectInfo) GetCreatedOk() (*string, bool) { +func (o *WorkspaceInfo) GetCreatedOk() (*string, bool) { if o == nil { return nil, false } @@ -71,12 +71,12 @@ func (o *ProjectInfo) GetCreatedOk() (*string, bool) { } // SetCreated sets field value -func (o *ProjectInfo) SetCreated(v string) { +func (o *WorkspaceInfo) SetCreated(v string) { o.Created = v } // GetIsRunning returns the IsRunning field value -func (o *ProjectInfo) GetIsRunning() bool { +func (o *WorkspaceInfo) GetIsRunning() bool { if o == nil { var ret bool return ret @@ -87,7 +87,7 @@ func (o *ProjectInfo) GetIsRunning() bool { // GetIsRunningOk returns a tuple with the IsRunning field value // and a boolean to check if the value has been set. -func (o *ProjectInfo) GetIsRunningOk() (*bool, bool) { +func (o *WorkspaceInfo) GetIsRunningOk() (*bool, bool) { if o == nil { return nil, false } @@ -95,12 +95,12 @@ func (o *ProjectInfo) GetIsRunningOk() (*bool, bool) { } // SetIsRunning sets field value -func (o *ProjectInfo) SetIsRunning(v bool) { +func (o *WorkspaceInfo) SetIsRunning(v bool) { o.IsRunning = v } // GetName returns the Name field value -func (o *ProjectInfo) GetName() string { +func (o *WorkspaceInfo) GetName() string { if o == nil { var ret string return ret @@ -111,7 +111,7 @@ func (o *ProjectInfo) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *ProjectInfo) GetNameOk() (*string, bool) { +func (o *WorkspaceInfo) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -119,12 +119,12 @@ func (o *ProjectInfo) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *ProjectInfo) SetName(v string) { +func (o *WorkspaceInfo) SetName(v string) { o.Name = v } // GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. -func (o *ProjectInfo) GetProviderMetadata() string { +func (o *WorkspaceInfo) GetProviderMetadata() string { if o == nil || IsNil(o.ProviderMetadata) { var ret string return ret @@ -134,7 +134,7 @@ func (o *ProjectInfo) GetProviderMetadata() string { // GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProjectInfo) GetProviderMetadataOk() (*string, bool) { +func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool) { if o == nil || IsNil(o.ProviderMetadata) { return nil, false } @@ -142,7 +142,7 @@ func (o *ProjectInfo) GetProviderMetadataOk() (*string, bool) { } // HasProviderMetadata returns a boolean if a field has been set. -func (o *ProjectInfo) HasProviderMetadata() bool { +func (o *WorkspaceInfo) HasProviderMetadata() bool { if o != nil && !IsNil(o.ProviderMetadata) { return true } @@ -151,12 +151,12 @@ func (o *ProjectInfo) HasProviderMetadata() bool { } // SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. -func (o *ProjectInfo) SetProviderMetadata(v string) { +func (o *WorkspaceInfo) SetProviderMetadata(v string) { o.ProviderMetadata = &v } // GetTargetId returns the TargetId field value -func (o *ProjectInfo) GetTargetId() string { +func (o *WorkspaceInfo) GetTargetId() string { if o == nil { var ret string return ret @@ -167,7 +167,7 @@ func (o *ProjectInfo) GetTargetId() string { // GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *ProjectInfo) GetTargetIdOk() (*string, bool) { +func (o *WorkspaceInfo) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -175,11 +175,11 @@ func (o *ProjectInfo) GetTargetIdOk() (*string, bool) { } // SetTargetId sets field value -func (o *ProjectInfo) SetTargetId(v string) { +func (o *WorkspaceInfo) SetTargetId(v string) { o.TargetId = v } -func (o ProjectInfo) MarshalJSON() ([]byte, error) { +func (o WorkspaceInfo) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -187,7 +187,7 @@ func (o ProjectInfo) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProjectInfo) ToMap() (map[string]interface{}, error) { +func (o WorkspaceInfo) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["created"] = o.Created toSerialize["isRunning"] = o.IsRunning @@ -199,7 +199,7 @@ func (o ProjectInfo) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *ProjectInfo) UnmarshalJSON(data []byte) (err error) { +func (o *WorkspaceInfo) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -224,53 +224,53 @@ func (o *ProjectInfo) UnmarshalJSON(data []byte) (err error) { } } - varProjectInfo := _ProjectInfo{} + varWorkspaceInfo := _WorkspaceInfo{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varProjectInfo) + err = decoder.Decode(&varWorkspaceInfo) if err != nil { return err } - *o = ProjectInfo(varProjectInfo) + *o = WorkspaceInfo(varWorkspaceInfo) return err } -type NullableProjectInfo struct { - value *ProjectInfo +type NullableWorkspaceInfo struct { + value *WorkspaceInfo isSet bool } -func (v NullableProjectInfo) Get() *ProjectInfo { +func (v NullableWorkspaceInfo) Get() *WorkspaceInfo { return v.value } -func (v *NullableProjectInfo) Set(val *ProjectInfo) { +func (v *NullableWorkspaceInfo) Set(val *WorkspaceInfo) { v.value = val v.isSet = true } -func (v NullableProjectInfo) IsSet() bool { +func (v NullableWorkspaceInfo) IsSet() bool { return v.isSet } -func (v *NullableProjectInfo) Unset() { +func (v *NullableWorkspaceInfo) Unset() { v.value = nil v.isSet = false } -func NewNullableProjectInfo(val *ProjectInfo) *NullableProjectInfo { - return &NullableProjectInfo{value: val, isSet: true} +func NewNullableWorkspaceInfo(val *WorkspaceInfo) *NullableWorkspaceInfo { + return &NullableWorkspaceInfo{value: val, isSet: true} } -func (v NullableProjectInfo) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceInfo) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProjectInfo) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceInfo) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_project_state.go b/pkg/apiclient/model_workspace_state.go similarity index 64% rename from pkg/apiclient/model_project_state.go rename to pkg/apiclient/model_workspace_state.go index ce3831a395..9e08bd043d 100644 --- a/pkg/apiclient/model_project_state.go +++ b/pkg/apiclient/model_workspace_state.go @@ -16,39 +16,39 @@ import ( "fmt" ) -// checks if the ProjectState type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProjectState{} +// checks if the WorkspaceState type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceState{} -// ProjectState struct for ProjectState -type ProjectState struct { +// WorkspaceState struct for WorkspaceState +type WorkspaceState struct { GitStatus *GitStatus `json:"gitStatus,omitempty"` UpdatedAt string `json:"updatedAt"` Uptime int32 `json:"uptime"` } -type _ProjectState ProjectState +type _WorkspaceState WorkspaceState -// NewProjectState instantiates a new ProjectState object +// NewWorkspaceState instantiates a new WorkspaceState object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProjectState(updatedAt string, uptime int32) *ProjectState { - this := ProjectState{} +func NewWorkspaceState(updatedAt string, uptime int32) *WorkspaceState { + this := WorkspaceState{} this.UpdatedAt = updatedAt this.Uptime = uptime return &this } -// NewProjectStateWithDefaults instantiates a new ProjectState object +// NewWorkspaceStateWithDefaults instantiates a new WorkspaceState object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProjectStateWithDefaults() *ProjectState { - this := ProjectState{} +func NewWorkspaceStateWithDefaults() *WorkspaceState { + this := WorkspaceState{} return &this } // GetGitStatus returns the GitStatus field value if set, zero value otherwise. -func (o *ProjectState) GetGitStatus() GitStatus { +func (o *WorkspaceState) GetGitStatus() GitStatus { if o == nil || IsNil(o.GitStatus) { var ret GitStatus return ret @@ -58,7 +58,7 @@ func (o *ProjectState) GetGitStatus() GitStatus { // GetGitStatusOk returns a tuple with the GitStatus field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProjectState) GetGitStatusOk() (*GitStatus, bool) { +func (o *WorkspaceState) GetGitStatusOk() (*GitStatus, bool) { if o == nil || IsNil(o.GitStatus) { return nil, false } @@ -66,7 +66,7 @@ func (o *ProjectState) GetGitStatusOk() (*GitStatus, bool) { } // HasGitStatus returns a boolean if a field has been set. -func (o *ProjectState) HasGitStatus() bool { +func (o *WorkspaceState) HasGitStatus() bool { if o != nil && !IsNil(o.GitStatus) { return true } @@ -75,12 +75,12 @@ func (o *ProjectState) HasGitStatus() bool { } // SetGitStatus gets a reference to the given GitStatus and assigns it to the GitStatus field. -func (o *ProjectState) SetGitStatus(v GitStatus) { +func (o *WorkspaceState) SetGitStatus(v GitStatus) { o.GitStatus = &v } // GetUpdatedAt returns the UpdatedAt field value -func (o *ProjectState) GetUpdatedAt() string { +func (o *WorkspaceState) GetUpdatedAt() string { if o == nil { var ret string return ret @@ -91,7 +91,7 @@ func (o *ProjectState) GetUpdatedAt() string { // GetUpdatedAtOk returns a tuple with the UpdatedAt field value // and a boolean to check if the value has been set. -func (o *ProjectState) GetUpdatedAtOk() (*string, bool) { +func (o *WorkspaceState) GetUpdatedAtOk() (*string, bool) { if o == nil { return nil, false } @@ -99,12 +99,12 @@ func (o *ProjectState) GetUpdatedAtOk() (*string, bool) { } // SetUpdatedAt sets field value -func (o *ProjectState) SetUpdatedAt(v string) { +func (o *WorkspaceState) SetUpdatedAt(v string) { o.UpdatedAt = v } // GetUptime returns the Uptime field value -func (o *ProjectState) GetUptime() int32 { +func (o *WorkspaceState) GetUptime() int32 { if o == nil { var ret int32 return ret @@ -115,7 +115,7 @@ func (o *ProjectState) GetUptime() int32 { // GetUptimeOk returns a tuple with the Uptime field value // and a boolean to check if the value has been set. -func (o *ProjectState) GetUptimeOk() (*int32, bool) { +func (o *WorkspaceState) GetUptimeOk() (*int32, bool) { if o == nil { return nil, false } @@ -123,11 +123,11 @@ func (o *ProjectState) GetUptimeOk() (*int32, bool) { } // SetUptime sets field value -func (o *ProjectState) SetUptime(v int32) { +func (o *WorkspaceState) SetUptime(v int32) { o.Uptime = v } -func (o ProjectState) MarshalJSON() ([]byte, error) { +func (o WorkspaceState) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -135,7 +135,7 @@ func (o ProjectState) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProjectState) ToMap() (map[string]interface{}, error) { +func (o WorkspaceState) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.GitStatus) { toSerialize["gitStatus"] = o.GitStatus @@ -145,7 +145,7 @@ func (o ProjectState) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *ProjectState) UnmarshalJSON(data []byte) (err error) { +func (o *WorkspaceState) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -168,53 +168,53 @@ func (o *ProjectState) UnmarshalJSON(data []byte) (err error) { } } - varProjectState := _ProjectState{} + varWorkspaceState := _WorkspaceState{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varProjectState) + err = decoder.Decode(&varWorkspaceState) if err != nil { return err } - *o = ProjectState(varProjectState) + *o = WorkspaceState(varWorkspaceState) return err } -type NullableProjectState struct { - value *ProjectState +type NullableWorkspaceState struct { + value *WorkspaceState isSet bool } -func (v NullableProjectState) Get() *ProjectState { +func (v NullableWorkspaceState) Get() *WorkspaceState { return v.value } -func (v *NullableProjectState) Set(val *ProjectState) { +func (v *NullableWorkspaceState) Set(val *WorkspaceState) { v.value = val v.isSet = true } -func (v NullableProjectState) IsSet() bool { +func (v NullableWorkspaceState) IsSet() bool { return v.isSet } -func (v *NullableProjectState) Unset() { +func (v *NullableWorkspaceState) Unset() { v.value = nil v.isSet = false } -func NewNullableProjectState(val *ProjectState) *NullableProjectState { - return &NullableProjectState{value: val, isSet: true} +func NewNullableWorkspaceState(val *WorkspaceState) *NullableWorkspaceState { + return &NullableWorkspaceState{value: val, isSet: true} } -func (v NullableProjectState) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceState) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProjectState) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceState) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apikey/apikey.go b/pkg/apikey/apikey.go index 0b917a4b84..92f6bb8d8d 100644 --- a/pkg/apikey/apikey.go +++ b/pkg/apikey/apikey.go @@ -6,14 +6,14 @@ package apikey type ApiKeyType string const ( - ApiKeyTypeClient ApiKeyType = "client" - ApiKeyTypeProject ApiKeyType = "project" - ApiKeyTypeTarget ApiKeyType = "target" + ApiKeyTypeClient ApiKeyType = "client" + ApiKeyTypeWorkspace ApiKeyType = "workspace" + ApiKeyTypeTarget ApiKeyType = "target" ) type ApiKey struct { KeyHash string `json:"keyHash" validate:"required"` Type ApiKeyType `json:"type" validate:"required"` - // Project or client name + // Workspace or client name Name string `json:"name" validate:"required"` } // @name ApiKey diff --git a/pkg/build/build.go b/pkg/build/build.go index d745be27f0..c0b2ac4c63 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -9,8 +9,8 @@ import ( "time" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" - "github.com/daytonaio/daytona/pkg/target/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" ) type BuildState string diff --git a/pkg/build/builder.go b/pkg/build/builder.go index cda12f2ce9..11ed46ae83 100644 --- a/pkg/build/builder.go +++ b/pkg/build/builder.go @@ -21,15 +21,15 @@ type IBuilder interface { type Builder struct { id string - projectDir string + workspaceDir string image string containerRegistry *containerregistry.ContainerRegistry buildImageContainerRegistry *containerregistry.ContainerRegistry buildStore Store buildImageNamespace string loggerFactory logs.LoggerFactory - defaultProjectImage string - defaultProjectUser string + defaultWorkspaceImage string + defaultWorkspaceUser string } func (b *Builder) GetImageName(build Build) (string, error) { @@ -44,7 +44,7 @@ func (b *Builder) GetImageName(build Build) (string, error) { name := hex.EncodeToString(nameBytes[:])[:16] namespace := b.buildImageNamespace - imageName := fmt.Sprintf("%s%s/p-%s:%s", b.buildImageContainerRegistry.Server, namespace, name, tag) + imageName := fmt.Sprintf("%s%s/w-%s:%s", b.buildImageContainerRegistry.Server, namespace, name, tag) return imageName, nil } diff --git a/pkg/build/detect/detect.go b/pkg/build/detect/detect.go index ba5b8d3ea0..1276882eaa 100644 --- a/pkg/build/detect/detect.go +++ b/pkg/build/detect/detect.go @@ -9,7 +9,7 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) type BuilderType string @@ -19,7 +19,7 @@ var ( BuilderTypeImage BuilderType = "image" ) -func DetectProjectBuilderType(buildConfig *buildconfig.BuildConfig, projectDir string, sshClient *ssh.Client) (BuilderType, error) { +func DetectWorkspaceBuilderType(buildConfig *buildconfig.BuildConfig, workspaceDir string, sshClient *ssh.Client) (BuilderType, error) { if buildConfig == nil { return BuilderTypeImage, nil } @@ -29,20 +29,20 @@ func DetectProjectBuilderType(buildConfig *buildconfig.BuildConfig, projectDir s } if sshClient != nil { - if _, err := sshClient.ReadFile(path.Join(projectDir, ".devcontainer/devcontainer.json")); err == nil { + if _, err := sshClient.ReadFile(path.Join(workspaceDir, ".devcontainer/devcontainer.json")); err == nil { buildConfig.Devcontainer = &buildconfig.DevcontainerConfig{ FilePath: ".devcontainer/devcontainer.json", } return BuilderTypeDevcontainer, nil } - if _, err := sshClient.ReadFile(path.Join(projectDir, ".devcontainer.json")); err == nil { + if _, err := sshClient.ReadFile(path.Join(workspaceDir, ".devcontainer.json")); err == nil { buildConfig.Devcontainer = &buildconfig.DevcontainerConfig{ FilePath: ".devcontainer.json", } return BuilderTypeDevcontainer, nil } } else { - if devcontainerFilePath, pathError := findDevcontainerConfigFilePath(projectDir); pathError == nil { + if devcontainerFilePath, pathError := findDevcontainerConfigFilePath(workspaceDir); pathError == nil { buildConfig.Devcontainer = &buildconfig.DevcontainerConfig{ FilePath: devcontainerFilePath, } @@ -54,12 +54,12 @@ func DetectProjectBuilderType(buildConfig *buildconfig.BuildConfig, projectDir s return BuilderTypeImage, nil } -func findDevcontainerConfigFilePath(projectDir string) (string, error) { +func findDevcontainerConfigFilePath(workspaceDir string) (string, error) { devcontainerPath := ".devcontainer/devcontainer.json" - isDevcontainer, err := fileExists(filepath.Join(projectDir, devcontainerPath)) + isDevcontainer, err := fileExists(filepath.Join(workspaceDir, devcontainerPath)) if !isDevcontainer || err != nil { devcontainerPath = ".devcontainer.json" - isDevcontainer, err = fileExists(filepath.Join(projectDir, devcontainerPath)) + isDevcontainer, err = fileExists(filepath.Join(workspaceDir, devcontainerPath)) if err != nil { return devcontainerPath, nil } diff --git a/pkg/build/devcontainer.go b/pkg/build/devcontainer.go index 922545abf3..9aa87f85a6 100644 --- a/pkg/build/devcontainer.go +++ b/pkg/build/devcontainer.go @@ -28,7 +28,7 @@ type DevcontainerBuilder struct { } func (b *DevcontainerBuilder) Build(build Build) (string, string, error) { - builderType, err := detect.DetectProjectBuilderType(build.BuildConfig, b.projectDir, nil) + builderType, err := detect.DetectWorkspaceBuilderType(build.BuildConfig, b.workspaceDir, nil) if err != nil { return "", "", err } @@ -41,7 +41,7 @@ func (b *DevcontainerBuilder) Build(build Build) (string, string, error) { } func (b *DevcontainerBuilder) CleanUp() error { - return os.RemoveAll(b.projectDir) + return os.RemoveAll(b.workspaceDir) } func (b *DevcontainerBuilder) Publish(build Build) error { @@ -70,7 +70,7 @@ func (b *DevcontainerBuilder) buildDevcontainer(build Build) (string, string, er cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { - return b.defaultProjectImage, b.defaultProjectUser, err + return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err } dockerClient := docker.NewDockerClient(docker.DockerClientConfig{ @@ -79,12 +79,12 @@ func (b *DevcontainerBuilder) buildDevcontainer(build Build) (string, string, er err = dockerClient.PullImage(b.image, b.containerRegistry, buildLogger) if err != nil { - return b.defaultProjectImage, b.defaultProjectUser, err + return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err } containerId, remoteUser, err := dockerClient.CreateFromDevcontainer(docker.CreateDevcontainerOptions{ BuildConfig: build.BuildConfig, - ProjectName: build.Id, + WorkspaceName: build.Id, ContainerRegistry: b.buildImageContainerRegistry, BuilderImage: b.image, BuilderContainerRegistry: b.containerRegistry, @@ -92,26 +92,26 @@ func (b *DevcontainerBuilder) buildDevcontainer(build Build) (string, string, er IdLabels: map[string]string{ "daytona.build.id": build.Id, }, - ProjectDir: b.projectDir, - LogWriter: buildLogger, - EnvVars: build.EnvVars, + WorkspaceDir: b.workspaceDir, + LogWriter: buildLogger, + EnvVars: build.EnvVars, }) if err != nil { - return b.defaultProjectImage, b.defaultProjectUser, err + return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err } defer dockerClient.RemoveContainer(containerId) // nolint: errcheck imageName, err := b.GetImageName(build) if err != nil { - return b.defaultProjectImage, b.defaultProjectUser, err + return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err } _, err = cli.ContainerCommit(context.Background(), containerId, container.CommitOptions{ Reference: imageName, }) if err != nil { - return b.defaultProjectImage, b.defaultProjectUser, err + return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err } return imageName, string(remoteUser), err diff --git a/pkg/build/factory.go b/pkg/build/factory.go index 04b3830696..3e8b67ffe8 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -14,7 +14,7 @@ import ( ) type IBuilderFactory interface { - Create(build Build, projectDir string) (IBuilder, error) + Create(build Build, workspaceDir string) (IBuilder, error) CheckExistingBuild(build Build) (*Build, error) } @@ -25,8 +25,8 @@ type BuilderFactory struct { buildStore Store loggerFactory logs.LoggerFactory image string - defaultProjectImage string - defaultProjectUser string + defaultWorkspaceImage string + defaultWorkspaceUser string } type BuilderFactoryConfig struct { @@ -36,8 +36,8 @@ type BuilderFactoryConfig struct { BuildStore Store BuildImageNamespace string // Namespace to be used when tagging and pushing the build image LoggerFactory logs.LoggerFactory - DefaultProjectImage string - DefaultProjectUser string + DefaultWorkspaceImage string + DefaultWorkspaceUser string } func NewBuilderFactory(config BuilderFactoryConfig) IBuilderFactory { @@ -48,14 +48,14 @@ func NewBuilderFactory(config BuilderFactoryConfig) IBuilderFactory { buildImageContainerRegistry: config.BuildImageContainerRegistry, buildStore: config.BuildStore, loggerFactory: config.LoggerFactory, - defaultProjectImage: config.DefaultProjectImage, - defaultProjectUser: config.DefaultProjectUser, + defaultWorkspaceImage: config.DefaultWorkspaceImage, + defaultWorkspaceUser: config.DefaultWorkspaceUser, } } -func (f *BuilderFactory) Create(build Build, projectDir string) (IBuilder, error) { +func (f *BuilderFactory) Create(build Build, workspaceDir string) (IBuilder, error) { // TODO: Implement factory logic after adding prebuilds and other builder types - return f.newDevcontainerBuilder(projectDir) + return f.newDevcontainerBuilder(workspaceDir) } func (f *BuilderFactory) CheckExistingBuild(b Build) (*Build, error) { @@ -76,7 +76,7 @@ func (f *BuilderFactory) CheckExistingBuild(b Build) (*Build, error) { return build, nil } -func (f *BuilderFactory) newDevcontainerBuilder(projectDir string) (*DevcontainerBuilder, error) { +func (f *BuilderFactory) newDevcontainerBuilder(workspaceDir string) (*DevcontainerBuilder, error) { builderDockerPort, err := ports.GetAvailableEphemeralPort() if err != nil { return nil, err @@ -89,15 +89,15 @@ func (f *BuilderFactory) newDevcontainerBuilder(projectDir string) (*Devcontaine return &DevcontainerBuilder{ Builder: &Builder{ id: id, - projectDir: projectDir, + workspaceDir: workspaceDir, image: f.image, containerRegistry: f.containerRegistry, buildImageContainerRegistry: f.buildImageContainerRegistry, buildImageNamespace: f.buildImageNamespace, buildStore: f.buildStore, loggerFactory: f.loggerFactory, - defaultProjectImage: f.defaultProjectImage, - defaultProjectUser: f.defaultProjectUser, + defaultWorkspaceImage: f.defaultWorkspaceImage, + defaultWorkspaceUser: f.defaultWorkspaceUser, }, builderDockerPort: builderDockerPort, }, nil diff --git a/pkg/build/runner.go b/pkg/build/runner.go index d73b6a6d1d..d18510b861 100644 --- a/pkg/build/runner.go +++ b/pkg/build/runner.go @@ -51,12 +51,12 @@ type BuildRunner struct { } type BuildProcessConfig struct { - Builder IBuilder - BuildLogger logs.Logger - Build *Build - ProjectDir string - GitService git.IGitService - Wg *sync.WaitGroup + Builder IBuilder + BuildLogger logs.Logger + Build *Build + WorkspaceDir string + GitService git.IGitService + Wg *sync.WaitGroup } type GitProviderStore interface { @@ -120,9 +120,9 @@ func (r *BuildRunner) RunBuilds() { buildLogger := r.loggerFactory.CreateBuildLogger(b.Id, logs.LogSourceBuilder) defer buildLogger.Close() - projectDir := filepath.Join(r.basePath, b.Id, "project") + workspaceDir := filepath.Join(r.basePath, b.Id, "workspace") - builder, err := r.builderFactory.Create(*b, projectDir) + builder, err := r.builderFactory.Create(*b, workspaceDir) if err != nil { r.handleBuildError(*b, builder, err, buildLogger) return @@ -154,13 +154,13 @@ func (r *BuildRunner) RunBuilds() { b.BuildConfig.CachedBuild = GetCachedBuild(b, builds) go r.RunBuildProcess(BuildProcessConfig{ - Builder: builder, - BuildLogger: buildLogger, - Build: b, - ProjectDir: projectDir, + Builder: builder, + BuildLogger: buildLogger, + Build: b, + WorkspaceDir: workspaceDir, GitService: &git.Service{ - ProjectDir: projectDir, - LogWriter: buildLogger, + WorkspaceDir: workspaceDir, + LogWriter: buildLogger, }, Wg: &wg, }) diff --git a/pkg/build/runner_test.go b/pkg/build/runner_test.go index d6e3c8af97..d9d5a0ece3 100644 --- a/pkg/build/runner_test.go +++ b/pkg/build/runner_test.go @@ -129,12 +129,12 @@ func (s *BuildRunnerTestSuite) TestRunBuildProcess() { mockLogger.On("Write", mock.Anything).Return(0, nil) s.Runner.RunBuildProcess(build.BuildProcessConfig{ - Builder: &s.mockBuilder, - BuildLogger: mockLogger, - Build: mocks.MockBuild, - ProjectDir: "", - GitService: mockGitService, - Wg: nil, + Builder: &s.mockBuilder, + BuildLogger: mockLogger, + Build: mocks.MockBuild, + WorkspaceDir: "", + GitService: mockGitService, + Wg: nil, }) mockLogger.AssertExpectations(s.T()) diff --git a/pkg/build/store.go b/pkg/build/store.go index 446293b87f..7d885f04dd 100644 --- a/pkg/build/store.go +++ b/pkg/build/store.go @@ -6,7 +6,7 @@ package build import ( "errors" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) type Store interface { diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index 24371d2426..5c0966833e 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -18,7 +18,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -32,7 +32,7 @@ var AgentCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { setLogLevel() - agentMode := agent_config.ModeProject + agentMode := agent_config.ModeWorkspace if hostModeFlag { agentMode = agent_config.ModeHost @@ -42,20 +42,20 @@ var AgentCmd = &cobra.Command{ if err != nil { return err } - c.ProjectDir = filepath.Join(os.Getenv("HOME"), c.ProjectName) + c.WorkspaceDir = filepath.Join(os.Getenv("HOME"), c.WorkspaceName) configDir, err := config.GetConfigDir() if err != nil { return err } - if projectDir := os.Getenv("DAYTONA_PROJECT_DIR"); projectDir != "" { - c.ProjectDir = projectDir + if workspaceDir := os.Getenv("DAYTONA_WORKSPACE_DIR"); workspaceDir != "" { + c.WorkspaceDir = workspaceDir } - if _, err := os.Stat(c.ProjectDir); os.IsNotExist(err) { - if err := os.MkdirAll(c.ProjectDir, 0755); err != nil { - return fmt.Errorf("failed to create project directory: %w", err) + if _, err := os.Stat(c.WorkspaceDir); os.IsNotExist(err) { + if err := os.MkdirAll(c.WorkspaceDir, 0755); err != nil { + return fmt.Errorf("failed to create workspace directory: %w", err) } } @@ -72,24 +72,24 @@ var AgentCmd = &cobra.Command{ } git := &git.Service{ - ProjectDir: c.ProjectDir, + WorkspaceDir: c.WorkspaceDir, GitConfigFileName: filepath.Join(os.Getenv("HOME"), ".gitconfig"), LogWriter: gitLogWriter, } sshServer := &ssh.Server{ - ProjectDir: c.ProjectDir, - DefaultProjectDir: os.Getenv("HOME"), + WorkspaceDir: c.WorkspaceDir, + DefaultWorkspaceDir: os.Getenv("HOME"), } - tailscaleHostname := project.GetProjectHostname(c.TargetId, c.ProjectName) + tailscaleHostname := workspace.GetWorkspaceHostname(c.TargetId, c.WorkspaceName) if hostModeFlag { tailscaleHostname = c.TargetId } toolBoxServer := &toolbox.Server{ - ProjectDir: c.ProjectDir, - ConfigDir: configDir, + WorkspaceDir: c.WorkspaceDir, + ConfigDir: configDir, } telemetryEnabled := os.Getenv("DAYTONA_TELEMETRY_ENABLED") == "true" diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go index 344b7d4376..aeb2c42790 100644 --- a/pkg/cmd/agentmode/agent_mode.go +++ b/pkg/cmd/agentmode/agent_mode.go @@ -16,7 +16,7 @@ import ( ) var targetId = "" -var projectName = "" +var workspaceName = "" var agentModeRootCmd = &cobra.Command{ Use: "daytona", @@ -32,7 +32,7 @@ var agentModeRootCmd = &cobra.Command{ func Execute() error { cmd.SetupRootCommand(agentModeRootCmd) - agentModeRootCmd.AddGroup(&cobra.Group{ID: util.TARGET_GROUP, Title: "Project & Target"}) + agentModeRootCmd.AddGroup(&cobra.Group{ID: util.TARGET_GROUP, Title: "Workspace & Target"}) agentModeRootCmd.AddCommand(gitCredCmd) agentModeRootCmd.AddCommand(AgentCmd) agentModeRootCmd.AddCommand(startCmd) @@ -65,7 +65,7 @@ func init() { if targetIdEnv := os.Getenv("DAYTONA_TARGET_ID"); targetIdEnv != "" { targetId = targetIdEnv } - if projectNameEnv := os.Getenv("DAYTONA_PROJECT_NAME"); projectNameEnv != "" { - projectName = projectNameEnv + if workspaceNameEnv := os.Getenv("DAYTONA_WORKSPACE_NAME"); workspaceNameEnv != "" { + workspaceName = workspaceNameEnv } } diff --git a/pkg/cmd/agentmode/expose.go b/pkg/cmd/agentmode/expose.go index 5d81c34738..66568514b5 100644 --- a/pkg/cmd/agentmode/expose.go +++ b/pkg/cmd/agentmode/expose.go @@ -17,7 +17,7 @@ import ( var exposeCmd = &cobra.Command{ Use: "expose [PORT]", - Short: "Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the project", + Short: "Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace", Args: cobra.ExactArgs(1), GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/cmd/agentmode/forward.go b/pkg/cmd/agentmode/forward.go index 11979e8da3..efb28f0043 100644 --- a/pkg/cmd/agentmode/forward.go +++ b/pkg/cmd/agentmode/forward.go @@ -25,7 +25,7 @@ var portForwardCmd = &cobra.Command{ errChan := make(chan error) go func() { - errChan <- defaultPortForwardCmd.ForwardPublicPort(targetId, projectName, uint16(port), uint16(port)) + errChan <- defaultPortForwardCmd.ForwardPublicPort(targetId, workspaceName, uint16(port), uint16(port)) }() for { diff --git a/pkg/cmd/agentmode/git_cred.go b/pkg/cmd/agentmode/git_cred.go index c5d6013382..6341fca583 100644 --- a/pkg/cmd/agentmode/git_cred.go +++ b/pkg/cmd/agentmode/git_cred.go @@ -44,9 +44,9 @@ var gitCredCmd = &cobra.Command{ var gitProviderConfigId *string - for _, project := range target.Projects { - if project.Name == projectName { - gitProviderConfigId = project.GitProviderConfigId + for _, workspace := range target.Workspaces { + if workspace.Name == workspaceName { + gitProviderConfigId = workspace.GitProviderConfigId break } } diff --git a/pkg/cmd/agentmode/info.go b/pkg/cmd/agentmode/info.go index b1752aed25..d7b6effe9f 100644 --- a/pkg/cmd/agentmode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -14,7 +14,7 @@ import ( var infoCmd = &cobra.Command{ Use: "info", - Short: "Show project info", + Short: "Show workspace info", Aliases: []string{"view", "inspect"}, Args: cobra.ExactArgs(0), GroupID: util.TARGET_GROUP, diff --git a/pkg/cmd/agentmode/restart.go b/pkg/cmd/agentmode/restart.go index 25b364fee9..3dc454fa81 100644 --- a/pkg/cmd/agentmode/restart.go +++ b/pkg/cmd/agentmode/restart.go @@ -15,7 +15,7 @@ import ( var restartCmd = &cobra.Command{ Use: "restart", - Short: "Restart the project", + Short: "Restart the workspace", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { @@ -24,13 +24,13 @@ var restartCmd = &cobra.Command{ return err } - err = target_cmd.RestartTarget(apiClient, targetId, projectName) + err = target_cmd.RestartTarget(apiClient, targetId, workspaceName) if err != nil { return err } - if projectName != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully restarted", projectName, targetId)) + if workspaceName != "" { + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully restarted", workspaceName, targetId)) } else { views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) } diff --git a/pkg/cmd/agentmode/start.go b/pkg/cmd/agentmode/start.go index b74a96d152..8897f4ccf5 100644 --- a/pkg/cmd/agentmode/start.go +++ b/pkg/cmd/agentmode/start.go @@ -13,7 +13,7 @@ import ( var startCmd = &cobra.Command{ Use: "start", - Short: "Start the project", + Short: "Start the workspace", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { @@ -22,12 +22,12 @@ var startCmd = &cobra.Command{ return err } - err = target_cmd.StartTarget(apiClient, targetId, projectName) + err = target_cmd.StartTarget(apiClient, targetId, workspaceName) if err != nil { return err } - views.RenderInfoMessage("Project successfully started") + views.RenderInfoMessage("Workspace successfully started") return nil }, } diff --git a/pkg/cmd/agentmode/stop.go b/pkg/cmd/agentmode/stop.go index a6efb39b1f..22a058b7ae 100644 --- a/pkg/cmd/agentmode/stop.go +++ b/pkg/cmd/agentmode/stop.go @@ -15,7 +15,7 @@ import ( var stopCmd = &cobra.Command{ Use: "stop", - Short: "Stop the project", + Short: "Stop the workspace", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { @@ -24,13 +24,13 @@ var stopCmd = &cobra.Command{ return err } - err = target_cmd.StopTarget(apiClient, targetId, projectName) + err = target_cmd.StopTarget(apiClient, targetId, workspaceName) if err != nil { return err } - if projectName != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully stopped", projectName, targetId)) + if workspaceName != "" { + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully stopped", workspaceName, targetId)) } else { views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) } diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index d0e9dae270..fdbc53c8ea 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -19,11 +19,11 @@ import ( var buildRunCmd = &cobra.Command{ Use: "run", - Short: "Run a build from a project config", + Short: "Run a build from a workspace config", Aliases: []string{"create"}, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - var projectConfig *apiclient.ProjectConfig + var workspaceConfig *apiclient.WorkspaceConfig ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -31,21 +31,21 @@ var buildRunCmd = &cobra.Command{ return err } - projectConfigList, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - projectConfig = selection.GetProjectConfigFromPrompt(projectConfigList, 0, false, false, "Build") - if projectConfig == nil { + workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "Build") + if workspaceConfig == nil { return nil } - if projectConfig.BuildConfig == nil { - return errors.New("The chosen project config does not have a build configuration") + if workspaceConfig.BuildConfig == nil { + return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := target_util.GetBranchFromProjectConfig(projectConfig, apiClient, 0) + chosenBranch, err := target_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return err } @@ -55,7 +55,7 @@ var buildRunCmd = &cobra.Command{ return nil } - buildId, err := CreateBuild(apiClient, projectConfig, chosenBranch.Name, nil) + buildId, err := CreateBuild(apiClient, workspaceConfig, chosenBranch.Name, nil) if err != nil { return err } @@ -65,7 +65,7 @@ var buildRunCmd = &cobra.Command{ }, } -func CreateBuild(apiClient *apiclient.APIClient, projectConfig *apiclient.ProjectConfig, branch string, prebuildId *string) (string, error) { +func CreateBuild(apiClient *apiclient.APIClient, workspaceConfig *apiclient.WorkspaceConfig, branch string, prebuildId *string) (string, error) { ctx := context.Background() profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() @@ -73,20 +73,20 @@ func CreateBuild(apiClient *apiclient.APIClient, projectConfig *apiclient.Projec return "", apiclient_util.HandleErrorResponse(res, err) } - if projectConfig.BuildConfig == nil { - return "", errors.New("the chosen project config does not have a build configuration") + if workspaceConfig.BuildConfig == nil { + return "", errors.New("the chosen workspace config does not have a build configuration") } createBuildDto := apiclient.CreateBuildDTO{ - ProjectConfigName: projectConfig.Name, - Branch: branch, - PrebuildId: prebuildId, + WorkspaceConfigName: workspaceConfig.Name, + Branch: branch, + PrebuildId: prebuildId, } if profileData != nil { - createBuildDto.EnvVars = util.MergeEnvVars(profileData.EnvVars, projectConfig.EnvVars) + createBuildDto.EnvVars = util.MergeEnvVars(profileData.EnvVars, workspaceConfig.EnvVars) } else { - createBuildDto.EnvVars = util.MergeEnvVars(projectConfig.EnvVars) + createBuildDto.EnvVars = util.MergeEnvVars(workspaceConfig.EnvVars) } buildId, res, err := apiClient.BuildAPI.CreateBuild(ctx).CreateBuildDto(createBuildDto).Execute() diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 6388f58df7..369ba39760 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -23,12 +23,12 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/prebuild" . "github.com/daytonaio/daytona/pkg/cmd/profile" . "github.com/daytonaio/daytona/pkg/cmd/profiledata/env" - . "github.com/daytonaio/daytona/pkg/cmd/projectconfig" . "github.com/daytonaio/daytona/pkg/cmd/provider" . "github.com/daytonaio/daytona/pkg/cmd/server" . "github.com/daytonaio/daytona/pkg/cmd/target" . "github.com/daytonaio/daytona/pkg/cmd/targetconfig" . "github.com/daytonaio/daytona/pkg/cmd/telemetry" + . "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/telemetry" @@ -49,7 +49,7 @@ var rootCmd = &cobra.Command{ } func Execute() error { - rootCmd.AddGroup(&cobra.Group{ID: TARGET_GROUP, Title: "Targets & Projects"}) + rootCmd.AddGroup(&cobra.Group{ID: TARGET_GROUP, Title: "Targets & Workspaces"}) rootCmd.AddGroup(&cobra.Group{ID: SERVER_GROUP, Title: "Server"}) rootCmd.AddGroup(&cobra.Group{ID: PROFILE_GROUP, Title: "Profile"}) @@ -58,7 +58,7 @@ func Execute() error { rootCmd.AddCommand(SshProxyCmd) rootCmd.AddCommand(CreateCmd) rootCmd.AddCommand(DeleteCmd) - rootCmd.AddCommand(ProjectConfigCmd) + rootCmd.AddCommand(WorkspaceConfigCmd) rootCmd.AddCommand(ServeCmd) rootCmd.AddCommand(DaemonServeCmd) rootCmd.AddCommand(ServerCmd) @@ -212,7 +212,7 @@ func GetCmdTelemetryData(cmd *cobra.Command, flags []string) map[string]interfac source := telemetry.CLI_SOURCE if internal.AgentMode() { - source = telemetry.CLI_PROJECT_SOURCE + source = telemetry.CLI_WORKSPACE_SOURCE } calledAs := cmd.CalledAs() diff --git a/pkg/cmd/logs.go b/pkg/cmd/logs.go index d021e39380..0c75cd4e72 100644 --- a/pkg/cmd/logs.go +++ b/pkg/cmd/logs.go @@ -20,8 +20,8 @@ var followFlag bool var targetFlag bool var logsCmd = &cobra.Command{ - Use: "logs [TARGET] [PROJECT_NAME]", - Short: "View logs for a target/project", + Use: "logs [TARGET] [WORKSPACE_NAME]", + Short: "View logs for a target/workspace", Args: cobra.RangeArgs(0, 2), GroupID: util.TARGET_GROUP, Aliases: []string{"lg", "log"}, @@ -45,7 +45,7 @@ var logsCmd = &cobra.Command{ var ( showTargetLogs = true - projectNames []string + workspaceNames []string ) if len(args) == 0 { @@ -67,37 +67,37 @@ var logsCmd = &cobra.Command{ if target == nil { return errors.New("target not found") - } else if len(target.Projects) == 0 { - return errors.New("no projects found in target") + } else if len(target.Workspaces) == 0 { + return errors.New("no workspaces found in target") } if len(args) == 2 { - projects := util.ArrayMap(target.Projects, func(p apiclient.Project) string { - return p.Name + workspaces := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + return w.Name }) var found bool - for _, project := range projects { - if project == args[1] { + for _, workspace := range workspaces { + if workspace == args[1] { found = true break } } if !found { - return errors.New("project not found in target") + return errors.New("workspace not found in target") } - projectNames = append(projectNames, args[1]) + workspaceNames = append(workspaceNames, args[1]) if targetFlag { showTargetLogs = true } else { showTargetLogs = false } } else if !targetFlag { - projectNames = util.ArrayMap(target.Projects, func(p apiclient.Project) string { - return p.Name + workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + return w.Name }) } - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, followFlag, showTargetLogs, nil) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, followFlag, showTargetLogs, nil) return nil }, diff --git a/pkg/cmd/ports/forward.go b/pkg/cmd/ports/forward.go index 95df6c0b3e..53f54de39b 100644 --- a/pkg/cmd/ports/forward.go +++ b/pkg/cmd/ports/forward.go @@ -25,11 +25,11 @@ import ( var publicPreview bool var targetId string -var projectName string +var workspaceName string var PortForwardCmd = &cobra.Command{ - Use: "forward [PORT] [TARGET] [PROJECT]", - Short: "Forward a port from a project to your local machine", + Use: "forward [PORT] [TARGET] [WORKSPACE]", + Short: "Forward a port from a workspace to your local machine", GroupID: util.TARGET_GROUP, Args: cobra.RangeArgs(2, 3), RunE: func(cmd *cobra.Command, args []string) error { @@ -53,15 +53,15 @@ var PortForwardCmd = &cobra.Command{ targetId = target.Id if len(args) == 3 { - projectName = args[2] + workspaceName = args[2] } else { - projectName, err = apiclient.GetFirstProjectName(targetId, projectName, nil) + workspaceName, err = apiclient.GetFirstWorkspaceName(targetId, workspaceName, nil) if err != nil { return err } } - hostPort, errChan := tailscale.ForwardPort(targetId, projectName, uint16(port), activeProfile) + hostPort, errChan := tailscale.ForwardPort(targetId, workspaceName, uint16(port), activeProfile) if hostPort == nil { if err = <-errChan; err != nil { @@ -76,7 +76,7 @@ var PortForwardCmd = &cobra.Command{ if publicPreview { go func() { - errChan <- ForwardPublicPort(targetId, projectName, *hostPort, uint16(port)) + errChan <- ForwardPublicPort(targetId, workspaceName, *hostPort, uint16(port)) }() } @@ -93,7 +93,7 @@ func init() { PortForwardCmd.Flags().BoolVar(&publicPreview, "public", false, "Should be port be available publicly via an URL") } -func ForwardPublicPort(targetId, projectName string, hostPort, targetPort uint16) error { +func ForwardPublicPort(targetId, workspaceName string, hostPort, targetPort uint16) error { views.RenderInfoMessage("Forwarding port to a public URL...") apiClient, err := apiclient.GetApiClient(nil) @@ -107,7 +107,7 @@ func ForwardPublicPort(targetId, projectName string, hostPort, targetPort uint16 } h := fnv.New64() - h.Write([]byte(fmt.Sprintf("%s-%s-%s", targetId, projectName, serverConfig.Id))) + h.Write([]byte(fmt.Sprintf("%s-%s-%s", targetId, workspaceName, serverConfig.Id))) subDomain := fmt.Sprintf("%d-%s", targetPort, base64.RawURLEncoding.EncodeToString([]byte(fmt.Sprint(h.Sum64())))) diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/add.go index 2f609ecc9a..496bbd16e0 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/add.go @@ -13,8 +13,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" - "github.com/daytonaio/daytona/pkg/cmd/projectconfig" target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" + "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" "github.com/daytonaio/daytona/pkg/views/target/selection" @@ -22,13 +22,13 @@ import ( ) var prebuildAddCmd = &cobra.Command{ - Use: "add [PROJECT_CONFIG]", + Use: "add [WORKSPACE_CONFIG]", Short: "Add a prebuild configuration", Args: cobra.MaximumNArgs(1), Aliases: []string{"new", "create"}, RunE: func(cmd *cobra.Command, args []string) error { var prebuildAddView add.PrebuildAddView - var projectConfig *apiclient.ProjectConfig + var workspaceConfig *apiclient.WorkspaceConfig ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -50,32 +50,32 @@ var prebuildAddCmd = &cobra.Command{ commitIntervalFlag == 0 && triggerFilesFlag == nil { // Interactive CLI logic - projectConfigList, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - projectConfig = selection.GetProjectConfigFromPrompt(projectConfigList, 0, false, true, "Prebuild") - if projectConfig == nil { - return errors.New("No project config selected") + workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, true, "Prebuild") + if workspaceConfig == nil { + return errors.New("No workspace config selected") } - if projectConfig.Name == selection.NewProjectConfigIdentifier { - projectConfig, err = projectconfig.RunProjectConfigAddFlow(apiClient, gitProviders, ctx) + if workspaceConfig.Name == selection.NewWorkspaceConfigIdentifier { + workspaceConfig, err = workspaceconfig.RunWorkspaceConfigAddFlow(apiClient, gitProviders, ctx) if err != nil { return err } - if projectConfig == nil { + if workspaceConfig == nil { return nil } } - prebuildAddView.ProjectConfigName = projectConfig.Name - if projectConfig.BuildConfig == nil { - return errors.New("The chosen project config does not have a build configuration") + prebuildAddView.WorkspaceConfigName = workspaceConfig.Name + if workspaceConfig.BuildConfig == nil { + return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := target_util.GetBranchFromProjectConfig(projectConfig, apiClient, 0) + chosenBranch, err := target_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return err } @@ -90,22 +90,22 @@ var prebuildAddCmd = &cobra.Command{ } else { // Non-interactive mode: use provided arguments and flags if len(args) > 0 { - prebuildAddView.ProjectConfigName = args[0] + prebuildAddView.WorkspaceConfigName = args[0] - // Fetch the project configuration based on the provided argument - projectConfigTemp, res, err := apiClient.ProjectConfigAPI.GetProjectConfig(ctx, prebuildAddView.ProjectConfigName).Execute() + // Fetch the workspace configuration based on the provided argument + workspaceConfigTemp, res, err := apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, prebuildAddView.WorkspaceConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if projectConfigTemp == nil { - return errors.New("Invalid project config specified") + if workspaceConfigTemp == nil { + return errors.New("Invalid workspace config specified") } - prebuildAddView.ProjectConfigName = projectConfigTemp.Name - projectConfig = projectConfigTemp + prebuildAddView.WorkspaceConfigName = workspaceConfigTemp.Name + workspaceConfig = workspaceConfigTemp } else { - return errors.New("Project config must be specified when using flags") + return errors.New("Workspace config must be specified when using flags") } // Validate and handle required flags @@ -157,7 +157,7 @@ var prebuildAddCmd = &cobra.Command{ newPrebuild.TriggerFiles = prebuildAddView.TriggerFiles } - prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.ProjectConfigName).Prebuild(newPrebuild).Execute() + prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceConfigName).Prebuild(newPrebuild).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -165,7 +165,7 @@ var prebuildAddCmd = &cobra.Command{ views.RenderInfoMessage("Prebuild added successfully") if prebuildAddView.RunBuildOnAdd { - buildId, err := build.CreateBuild(apiClient, projectConfig, prebuildAddView.Branch, &prebuildId) + buildId, err := build.CreateBuild(apiClient, workspaceConfig, prebuildAddView.Branch, &prebuildId) if err != nil { return err } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index b17c4856a5..c120da37ee 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -18,14 +18,14 @@ import ( var forceFlag bool var prebuildDeleteCmd = &cobra.Command{ - Use: "delete [PROJECT_CONFIG] [PREBUILD]", + Use: "delete [WORKSPACE_CONFIG] [PREBUILD]", Short: "Delete a prebuild configuration", Aliases: []string{"remove", "rm"}, Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { var selectedPrebuild *apiclient.PrebuildDTO var selectedPrebuildId string - var selectedProjectConfigName string + var selectedWorkspaceConfigName string apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -37,8 +37,8 @@ var prebuildDeleteCmd = &cobra.Command{ var res *http.Response if len(args) == 1 { - selectedProjectConfigName = args[0] - prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForProjectConfig(context.Background(), selectedProjectConfigName).Execute() + selectedWorkspaceConfigName = args[0] + prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -59,13 +59,13 @@ var prebuildDeleteCmd = &cobra.Command{ return nil } selectedPrebuildId = selectedPrebuild.Id - selectedProjectConfigName = selectedPrebuild.ProjectConfigName + selectedWorkspaceConfigName = selectedPrebuild.WorkspaceConfigName } else { - selectedProjectConfigName = args[0] + selectedWorkspaceConfigName = args[0] selectedPrebuildId = args[1] } - res, err := apiClient.PrebuildAPI.DeletePrebuild(context.Background(), selectedProjectConfigName, selectedPrebuildId).Force(forceFlag).Execute() + res, err := apiClient.PrebuildAPI.DeletePrebuild(context.Background(), selectedWorkspaceConfigName, selectedPrebuildId).Force(forceFlag).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index 228bc413bb..283e43f55b 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -33,11 +33,11 @@ var prebuildInfoCmd = &cobra.Command{ if len(args) < 2 { var prebuilds []apiclient.PrebuildDTO - var selectedProjectConfigName string + var selectedWorkspaceConfigName string if len(args) == 1 { - selectedProjectConfigName = args[0] - prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForProjectConfig(context.Background(), selectedProjectConfigName).Execute() + selectedWorkspaceConfigName = args[0] + prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index 0c21a5b3ba..df09be4587 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -20,13 +20,13 @@ import ( ) var prebuildUpdateCmd = &cobra.Command{ - Use: "update [PROJECT_CONFIG] [PREBUILD_ID]", + Use: "update [WORKSPACE_CONFIG] [PREBUILD_ID]", Short: "Update a prebuild configuration", Args: cobra.MaximumNArgs(2), RunE: func(cmd *cobra.Command, args []string) error { var prebuildAddView add.PrebuildAddView var prebuild *apiclient.PrebuildDTO - var projectConfigRecieved string + var workspaceConfigRecieved string var retention int ctx := context.Background() @@ -50,13 +50,13 @@ var prebuildUpdateCmd = &cobra.Command{ if len(args) == 2 || (branchFlag != "" || retentionFlag != 0 || commitIntervalFlag != 0 || len(triggerFilesFlag) > 0) { // Non-interactive mode: use provided arguments and flags if len(args) < 2 { - return errors.New("Both project config name and prebuild ID must be specified when using flags") + return errors.New("Both workspace config name and prebuild ID must be specified when using flags") } - projectConfigRecieved = args[0] + workspaceConfigRecieved = args[0] prebuildID := args[1] - prebuild, res, err = apiClient.PrebuildAPI.GetPrebuild(ctx, projectConfigRecieved, prebuildID).Execute() + prebuild, res, err = apiClient.PrebuildAPI.GetPrebuild(ctx, workspaceConfigRecieved, prebuildID).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -79,18 +79,18 @@ var prebuildUpdateCmd = &cobra.Command{ } prebuildAddView.Branch = prebuild.Branch prebuildAddView.Retention = strconv.Itoa(int(prebuild.Retention)) - prebuildAddView.ProjectConfigName = projectConfigRecieved + prebuildAddView.WorkspaceConfigName = workspaceConfigRecieved prebuildAddView.TriggerFiles = prebuild.TriggerFiles prebuildAddView.CommitInterval = strconv.Itoa(int(*prebuild.CommitInterval)) retention = int(prebuild.Retention) } else { // Interactive mode: Prompt for details var prebuilds []apiclient.PrebuildDTO - var selectedProjectConfigName string + var selectedWorkspaceConfigName string if len(args) == 1 { - selectedProjectConfigName = args[0] - prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForProjectConfig(ctx, selectedProjectConfigName).Execute() + selectedWorkspaceConfigName = args[0] + prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(ctx, selectedWorkspaceConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -111,11 +111,11 @@ var prebuildUpdateCmd = &cobra.Command{ return nil } - projectConfigRecieved = prebuild.ProjectConfigName + workspaceConfigRecieved = prebuild.WorkspaceConfigName prebuildAddView = add.PrebuildAddView{ - Branch: prebuild.Branch, - Retention: strconv.Itoa(int(prebuild.Retention)), - ProjectConfigName: projectConfigRecieved, + Branch: prebuild.Branch, + Retention: strconv.Itoa(int(prebuild.Retention)), + WorkspaceConfigName: workspaceConfigRecieved, } retention, err = strconv.Atoi(prebuildAddView.Retention) if err != nil { @@ -155,7 +155,7 @@ var prebuildUpdateCmd = &cobra.Command{ newPrebuild.TriggerFiles = prebuildAddView.TriggerFiles } - prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.ProjectConfigName).Prebuild(newPrebuild).Execute() + prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceConfigName).Prebuild(newPrebuild).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -163,12 +163,12 @@ var prebuildUpdateCmd = &cobra.Command{ views.RenderInfoMessage("Prebuild updated successfully") if prebuildAddView.RunBuildOnAdd { - projectConfig, res, err := apiClient.ProjectConfigAPI.GetProjectConfig(ctx, prebuildAddView.ProjectConfigName).Execute() + workspaceConfig, res, err := apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, prebuildAddView.WorkspaceConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - buildId, err := build.CreateBuild(apiClient, projectConfig, *newPrebuild.Branch, &prebuildId) + buildId, err := build.CreateBuild(apiClient, workspaceConfig, *newPrebuild.Branch, &prebuildId) if err != nil { return err } diff --git a/pkg/cmd/profiledata/env/env.go b/pkg/cmd/profiledata/env/env.go index 045e17796a..0b77d8aead 100644 --- a/pkg/cmd/profiledata/env/env.go +++ b/pkg/cmd/profiledata/env/env.go @@ -10,7 +10,7 @@ import ( var EnvCmd = &cobra.Command{ Use: "env", - Short: "Manage profile environment variables that are added to all targets and projects", + Short: "Manage profile environment variables that are added to all targets and workspaces", GroupID: util.PROFILE_GROUP, } diff --git a/pkg/cmd/projectconfig/add.go b/pkg/cmd/projectconfig/add.go deleted file mode 100644 index 904ea442c1..0000000000 --- a/pkg/cmd/projectconfig/add.go +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig - -import ( - "context" - "errors" - "fmt" - "net/url" - - "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/create" - views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/spf13/cobra" -) - -var projectConfigAddCmd = &cobra.Command{ - Use: "add", - Aliases: []string{"new", "create"}, - Short: "Add a project config", - Args: cobra.MaximumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - var projectConfig *apiclient.ProjectConfig - var projectConfigName *string - ctx := context.Background() - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(args) == 0 { - projectConfig, err = RunProjectConfigAddFlow(apiClient, gitProviders, ctx) - if err != nil { - return err - } - if projectConfig == nil { - return nil - } - projectConfigName = &projectConfig.Name - } else { - projectConfigName, err = processCmdArgument(args[0], apiClient, ctx) - if err != nil { - return err - } - } - - if projectConfigName == nil { - return errors.New("project config name is required") - } - - views.RenderInfoMessage(fmt.Sprintf("Project config %s added successfully", *projectConfigName)) - return nil - }, -} - -func RunProjectConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.ProjectConfig, error) { - if target_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) { - return nil, errors.New("please provide the repository URL in order to set up custom project config details through the CLI") - } - - var createDtos []apiclient.CreateProjectDTO - existingProjectConfigNames, err := GetExistingProjectConfigNames(apiClient) - if err != nil { - return nil, err - } - - apiServerConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - projectDefaults := &views_util.ProjectConfigDefaults{ - BuildChoice: views_util.AUTOMATIC, - Image: &apiServerConfig.DefaultProjectImage, - ImageUser: &apiServerConfig.DefaultProjectUser, - DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, - } - - createDtos, err = target_util.GetProjectsCreationDataFromPrompt(target_util.ProjectsDataPromptConfig{ - UserGitProviders: gitProviders, - Manual: *projectConfigurationFlags.Manual, - MultiProject: false, - SkipBranchSelection: true, - ApiClient: apiClient, - Defaults: projectDefaults, - }) - - if err != nil { - if common.IsCtrlCAbort(err) { - return nil, nil - } else { - return nil, err - } - } - - create.ProjectsConfigurationChanged, err = create.RunProjectConfiguration(&createDtos, *projectDefaults, false) - if err != nil { - return nil, err - } - - if len(createDtos) == 0 { - return nil, errors.New("no projects found") - } - - if createDtos[0].Name == "" { - return nil, errors.New("project config name is required") - } - - initialSuggestion := createDtos[0].Name - - chosenName := target_util.GetSuggestedName(initialSuggestion, existingProjectConfigNames) - - submissionFormConfig := create.SubmissionFormConfig{ - ChosenName: &chosenName, - SuggestedName: chosenName, - ExistingNames: existingProjectConfigNames, - ProjectList: &createDtos, - NameLabel: "Project config", - Defaults: projectDefaults, - } - - pcFlag := false - err = create.RunSubmissionForm(submissionFormConfig, &pcFlag) - if err != nil { - return nil, err - } - - createProjectConfig := apiclient.CreateProjectConfigDTO{ - Name: chosenName, - BuildConfig: createDtos[0].BuildConfig, - Image: createDtos[0].Image, - User: createDtos[0].User, - RepositoryUrl: createDtos[0].Source.Repository.Url, - EnvVars: createDtos[0].EnvVars, - GitProviderConfigId: createDtos[0].GitProviderConfigId, - } - - res, err = apiClient.ProjectConfigAPI.SetProjectConfig(ctx).ProjectConfig(createProjectConfig).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - projectConfig := apiclient.ProjectConfig{ - BuildConfig: createProjectConfig.BuildConfig, - Default: false, - EnvVars: createProjectConfig.EnvVars, - Name: createProjectConfig.Name, - Prebuilds: nil, - RepositoryUrl: createProjectConfig.RepositoryUrl, - GitProviderConfigId: createProjectConfig.GitProviderConfigId, - } - - if createProjectConfig.Image != nil { - projectConfig.Image = *createProjectConfig.Image - } - - if createProjectConfig.User != nil { - projectConfig.User = *createProjectConfig.User - } - - if createProjectConfig.GitProviderConfigId == nil && *createProjectConfig.GitProviderConfigId == "" { - gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(createProjectConfig.RepositoryUrl)).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - projectConfig.GitProviderConfigId = &gitProviderConfigId - } - - return &projectConfig, nil -} - -func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx context.Context) (*string, error) { - if *projectConfigurationFlags.Builder != "" && *projectConfigurationFlags.Builder != views_util.DEVCONTAINER && *projectConfigurationFlags.DevcontainerPath != "" { - return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) - } - - apiServerConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - existingProjectConfigNames, err := GetExistingProjectConfigNames(apiClient) - if err != nil { - return nil, err - } - - repoUrl, err := util.GetValidatedUrl(argument) - if err != nil { - return nil, err - } - - _, res, err = apiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: repoUrl, - }).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - projectConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, projectConfigurationFlags.GitProviderConfig) - if err != nil { - return nil, err - } - - project, err := target_util.GetCreateProjectDtoFromFlags(projectConfigurationFlags) - if err != nil { - return nil, err - } - - var name string - if nameFlag != "" { - name = nameFlag - } else { - projectName := target_util.GetProjectNameFromRepo(repoUrl) - name = target_util.GetSuggestedName(projectName, existingProjectConfigNames) - } - - if project.GitProviderConfigId == nil || *project.GitProviderConfigId == "" { - gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(repoUrl)).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - *project.GitProviderConfigId = gitProviderConfigId - } - - newProjectConfig := apiclient.CreateProjectConfigDTO{ - Name: name, - BuildConfig: project.BuildConfig, - Image: project.Image, - User: project.User, - RepositoryUrl: repoUrl, - EnvVars: project.EnvVars, - GitProviderConfigId: project.GitProviderConfigId, - } - - if newProjectConfig.Image == nil { - newProjectConfig.Image = &apiServerConfig.DefaultProjectImage - } - - if newProjectConfig.User == nil { - newProjectConfig.User = &apiServerConfig.DefaultProjectUser - } - - res, err = apiClient.ProjectConfigAPI.SetProjectConfig(ctx).ProjectConfig(newProjectConfig).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - return &newProjectConfig.Name, nil -} - -func GetExistingProjectConfigNames(apiClient *apiclient.APIClient) ([]string, error) { - var existingProjectConfigNames []string - - existingProjectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(context.Background()).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - for _, pc := range existingProjectConfigs { - existingProjectConfigNames = append(existingProjectConfigNames, pc.Name) - } - - return existingProjectConfigNames, nil -} - -var nameFlag string - -var projectConfigurationFlags = target_util.ProjectConfigurationFlags{ - Builder: new(views_util.BuildChoice), - CustomImage: new(string), - CustomImageUser: new(string), - Branches: new([]string), - DevcontainerPath: new(string), - EnvVars: new([]string), - Manual: new(bool), - GitProviderConfig: new(string), -} - -func init() { - projectConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the project config name") - target_util.AddProjectConfigurationFlags(projectConfigAddCmd, projectConfigurationFlags, false) -} diff --git a/pkg/cmd/projectconfig/delete.go b/pkg/cmd/projectconfig/delete.go deleted file mode 100644 index 6f26239e0f..0000000000 --- a/pkg/cmd/projectconfig/delete.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig - -import ( - "context" - "fmt" - - "github.com/charmbracelet/huh" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" - views_util "github.com/daytonaio/daytona/pkg/views/util" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var allFlag bool -var yesFlag bool -var forceFlag bool - -var projectConfigDeleteCmd = &cobra.Command{ - Use: "delete", - Aliases: []string{"remove", "rm"}, - Short: "Delete a project config", - Args: cobra.MaximumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - var selectedProjectConfig *apiclient.ProjectConfig - var selectedProjectConfigName string - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - if allFlag { - if !yesFlag { - form := huh.NewForm( - huh.NewGroup( - huh.NewConfirm(). - Title("Delete all project configs?"). - Description("Are you sure you want to delete all project configs?"). - Value(&yesFlag), - ), - ).WithTheme(views.GetCustomTheme()) - - err := form.Run() - if err != nil { - return err - } - - if !yesFlag { - fmt.Println("Operation canceled.") - return nil - } - } - - projectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(projectConfigs) == 0 { - views_util.NotifyEmptyProjectConfigList(false) - return nil - } - - for _, projectConfig := range projectConfigs { - selectedProjectConfigName = projectConfig.Name - res, err := apiClient.ProjectConfigAPI.DeleteProjectConfig(context.Background(), selectedProjectConfigName).Execute() - if err != nil { - log.Error(apiclient_util.HandleErrorResponse(res, err)) - continue - } - views.RenderInfoMessage("Deleted project config: " + selectedProjectConfigName) - } - return nil - } - - if len(args) == 0 { - projectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(projectConfigs) == 0 { - views.RenderInfoMessage("No project configs found") - return nil - } - - selectedProjectConfig = selection.GetProjectConfigFromPrompt(projectConfigs, 0, false, false, "Delete") - if selectedProjectConfig == nil { - return nil - } - selectedProjectConfigName = selectedProjectConfig.Name - } else { - selectedProjectConfigName = args[0] - } - - res, err := apiClient.ProjectConfigAPI.DeleteProjectConfig(context.Background(), selectedProjectConfigName).Force(forceFlag).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - views.RenderInfoMessage("Project config deleted successfully") - return nil - }, -} - -func init() { - projectConfigDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all project configs") - projectConfigDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") - projectConfigDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") -} diff --git a/pkg/cmd/projectconfig/projectconfig.go b/pkg/cmd/projectconfig/projectconfig.go deleted file mode 100644 index 4037c2fca1..0000000000 --- a/pkg/cmd/projectconfig/projectconfig.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig - -import ( - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var ProjectConfigCmd = &cobra.Command{ - Use: "project-config", - Short: "Manage project configs", - Aliases: []string{"pc"}, - GroupID: util.TARGET_GROUP, -} - -func init() { - ProjectConfigCmd.AddCommand(projectConfigListCmd) - ProjectConfigCmd.AddCommand(projectConfigInfoCmd) - ProjectConfigCmd.AddCommand(projectConfigAddCmd) - ProjectConfigCmd.AddCommand(projectConfigUpdateCmd) - ProjectConfigCmd.AddCommand(projectConfigSetDefaultCmd) - ProjectConfigCmd.AddCommand(projectConfigDeleteCmd) - ProjectConfigCmd.AddCommand(projectConfigExportCmd) - ProjectConfigCmd.AddCommand(projectConfigImportCmd) -} diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 30c91f1fff..706cd9c499 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -33,10 +33,10 @@ import ( "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/profiledata" - "github.com/daytonaio/daytona/pkg/server/projectconfig" "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -60,7 +60,7 @@ var ServeCmd = &cobra.Command{ Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { if os.Getenv("USER") == "root" { - views.RenderInfoMessageBold("Running the server as root is not recommended because\nDaytona will not be able to remap project directory ownership.\nPlease run the server as a non-root user.") + views.RenderInfoMessageBold("Running the server as root is not recommended because\nDaytona will not be able to remap workspace directory ownership.\nPlease run the server as a non-root user.") } if log.GetLevel() < log.InfoLevel { @@ -221,7 +221,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - projectConfigStore, err := db.NewProjectConfigStore(dbConnection) + workspaceConfigStore, err := db.NewWorkspaceConfigStore(dbConnection) if err != nil { return nil, err } @@ -265,20 +265,20 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }) gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ - ConfigStore: gitProviderConfigStore, - ProjectConfigStore: projectConfigStore, + ConfigStore: gitProviderConfigStore, + WorkspaceConfigStore: workspaceConfigStore, }) prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) - projectConfigService := projectconfig.NewProjectConfigService(projectconfig.ProjectConfigServiceConfig{ + workspaceConfigService := workspaceconfig.NewWorkspaceConfigService(workspaceconfig.WorkspaceConfigServiceConfig{ PrebuildWebhookEndpoint: prebuildWebhookEndpoint, - ConfigStore: projectConfigStore, + ConfigStore: workspaceConfigStore, BuildService: buildService, GitProviderService: gitProviderService, }) - err = projectConfigService.StartRetentionPoller() + err = workspaceConfigService.StartRetentionPoller() if err != nil { return nil, err } @@ -350,12 +350,12 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ContainerRegistryService: containerRegistryService, BuilderImage: c.BuilderImage, BuildService: buildService, - ProjectConfigService: projectConfigService, + WorkspaceConfigService: workspaceConfigService, ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), ServerVersion: version, ServerUrl: headscaleUrl, - DefaultProjectImage: c.DefaultProjectImage, - DefaultProjectUser: c.DefaultProjectUser, + DefaultWorkspaceImage: c.DefaultWorkspaceImage, + DefaultWorkspaceUser: c.DefaultWorkspaceUser, Provisioner: provisioner, LoggerFactory: loggerFactory, TelemetryService: telemetryService, @@ -372,7 +372,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe TargetConfigService: targetConfigService, ContainerRegistryService: containerRegistryService, BuildService: buildService, - ProjectConfigService: projectConfigService, + WorkspaceConfigService: workspaceConfigService, LocalContainerRegistry: localContainerRegistry, ApiKeyService: apiKeyService, TargetService: targetService, @@ -456,8 +456,8 @@ func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetry BuildStore: buildStore, BuildImageNamespace: buildImageNamespace, LoggerFactory: loggerFactory, - DefaultProjectImage: c.DefaultProjectImage, - DefaultProjectUser: c.DefaultProjectUser, + DefaultWorkspaceImage: c.DefaultWorkspaceImage, + DefaultWorkspaceUser: c.DefaultWorkspaceUser, }) return build.NewBuildRunner(build.BuildRunnerInstanceConfig{ diff --git a/pkg/cmd/target/code.go b/pkg/cmd/target/code.go index 910ca5271a..aacd7269bf 100644 --- a/pkg/cmd/target/code.go +++ b/pkg/cmd/target/code.go @@ -28,7 +28,7 @@ import ( ) var CodeCmd = &cobra.Command{ - Use: "code [TARGET] [PROJECT]", + Use: "code [TARGET] [WORKSPACE]", Short: "Open a target in your preferred IDE", Args: cobra.RangeArgs(0, 2), Aliases: []string{"open"}, @@ -41,7 +41,7 @@ var CodeCmd = &cobra.Command{ ctx := context.Background() var targetId string - var projectName string + var workspaceName string var providerConfigId *string var ideId string var target *apiclient.TargetDTO @@ -87,23 +87,23 @@ var CodeCmd = &cobra.Command{ } if len(args) == 0 || len(args) == 1 { - selectedProject, err := selectTargetProject(targetId, &activeProfile) + selectedWorkspace, err := selectTargetWorkspace(targetId, &activeProfile) if err != nil { return err } - if selectedProject == nil { + if selectedWorkspace == nil { return nil } - projectName = selectedProject.Name - providerConfigId = selectedProject.GitProviderConfigId + workspaceName = selectedWorkspace.Name + providerConfigId = selectedWorkspace.GitProviderConfigId } if len(args) == 2 { - projectName = args[1] - for _, project := range target.Projects { - if project.Name == projectName { - providerConfigId = project.GitProviderConfigId + workspaceName = args[1] + for _, workspace := range target.Workspaces { + if workspace.Name == workspaceName { + providerConfigId = workspace.GitProviderConfigId break } } @@ -113,8 +113,8 @@ var CodeCmd = &cobra.Command{ ideId = ideFlag } - if !target_util.IsProjectRunning(target, projectName) { - wsRunningStatus, err := AutoStartTarget(target.Name, projectName) + if !target_util.IsWorkspaceRunning(target, workspaceName) { + wsRunningStatus, err := AutoStartTarget(target.Name, workspaceName) if err != nil { return err } @@ -125,7 +125,7 @@ var CodeCmd = &cobra.Command{ providerMetadata := "" if ideId != "ssh" { - providerMetadata, err = target_util.GetProjectProviderMetadata(target, projectName) + providerMetadata, err = target_util.GetWorkspaceProviderMetadata(target, workspaceName) if err != nil { return err } @@ -138,19 +138,19 @@ var CodeCmd = &cobra.Command{ yesFlag, _ := cmd.Flags().GetBool("yes") ideList := config.GetIdeList() - ide_views.RenderIdeOpeningMessage(target.Name, projectName, ideId, ideList) - return openIDE(ideId, activeProfile, targetId, projectName, providerMetadata, yesFlag, gpgKey) + ide_views.RenderIdeOpeningMessage(target.Name, workspaceName, ideId, ideList) + return openIDE(ideId, activeProfile, targetId, workspaceName, providerMetadata, yesFlag, gpgKey) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) == 1 { - return getProjectNameCompletions(cmd, args, toComplete) + return getWorkspaceNameCompletions(cmd, args, toComplete) } return getTargetNameCompletions() }, } -func selectTargetProject(targetId string, profile *config.Profile) (*apiclient.Project, error) { +func selectTargetWorkspace(targetId string, profile *config.Profile) (*apiclient.Workspace, error) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(profile) @@ -163,51 +163,51 @@ func selectTargetProject(targetId string, profile *config.Profile) (*apiclient.P return nil, apiclient_util.HandleErrorResponse(res, err) } - if len(targetInfo.Projects) > 1 { - selectedProject := selection.GetProjectFromPrompt(targetInfo.Projects, "Open") - if selectedProject == nil { + if len(targetInfo.Workspaces) > 1 { + selectedWorkspace := selection.GetWorkspaceFromPrompt(targetInfo.Workspaces, "Open") + if selectedWorkspace == nil { return nil, nil } - return selectedProject, nil - } else if len(targetInfo.Projects) == 1 { - return &targetInfo.Projects[0], nil + return selectedWorkspace, nil + } else if len(targetInfo.Workspaces) == 1 { + return &targetInfo.Workspaces[0], nil } - return nil, errors.New("no projects found in target") + return nil, errors.New("no workspaces found in target") } -func openIDE(ideId string, activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, yesFlag bool, gpgKey string) error { +func openIDE(ideId string, activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { telemetry.AdditionalData["ide"] = ideId switch ideId { case "vscode": - return ide.OpenVSCode(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVSCode(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "code-insiders": - return ide.OpenVSCodeInsiders(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVSCodeInsiders(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "ssh": - return ide.OpenTerminalSsh(activeProfile, targetId, projectName, gpgKey, nil) + return ide.OpenTerminalSsh(activeProfile, targetId, workspaceName, gpgKey, nil) case "browser": - return ide.OpenBrowserIDE(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenBrowserIDE(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "codium": - return ide.OpenVScodium(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVScodium(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "codium-insiders": - return ide.OpenVScodiumInsiders(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenVScodiumInsiders(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "cursor": - return ide.OpenCursor(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenCursor(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "jupyter": - return ide.OpenJupyterIDE(activeProfile, targetId, projectName, projectProviderMetadata, yesFlag, gpgKey) + return ide.OpenJupyterIDE(activeProfile, targetId, workspaceName, workspaceProviderMetadata, yesFlag, gpgKey) case "fleet": - return ide.OpenFleet(activeProfile, targetId, projectName, gpgKey) + return ide.OpenFleet(activeProfile, targetId, workspaceName, gpgKey) case "positron": - return ide.OpenPositron(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenPositron(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) case "zed": - return ide.OpenZed(activeProfile, targetId, projectName, gpgKey) + return ide.OpenZed(activeProfile, targetId, workspaceName, gpgKey) case "windsurf": - return ide.OpenWindsurf(activeProfile, targetId, projectName, projectProviderMetadata, gpgKey) + return ide.OpenWindsurf(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) default: _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] if ok { - return ide.OpenJetbrainsIDE(activeProfile, ideId, targetId, projectName, gpgKey) + return ide.OpenJetbrainsIDE(activeProfile, ideId, targetId, workspaceName, gpgKey) } } @@ -229,7 +229,7 @@ func init() { } -func AutoStartTarget(targetId string, projectName string) (bool, error) { +func AutoStartTarget(targetId string, workspaceName string) (bool, error) { if !yesFlag { if !ide_views.RunStartTargetForm(targetId) { return false, nil @@ -241,7 +241,7 @@ func AutoStartTarget(targetId string, projectName string) (bool, error) { return false, err } - err = StartTarget(apiClient, targetId, projectName) + err = StartTarget(apiClient, targetId, workspaceName) if err != nil { return false, err } diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index 0dc9784cf9..93086abe8a 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -22,7 +22,7 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/views" logs_view "github.com/daytonaio/daytona/pkg/views/logs" "github.com/daytonaio/daytona/pkg/views/target/create" @@ -39,15 +39,15 @@ import ( ) var CreateCmd = &cobra.Command{ - Use: "create [REPOSITORY_URL | PROJECT_CONFIG_NAME]...", + Use: "create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]...", Short: "Create a target", GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - var projects []apiclient.CreateProjectDTO + var workspaces []apiclient.CreateWorkspaceDTO var targetName string var existingTargetNames []string - var existingProjectConfigNames []string + var existingWorkspaceConfigNames []string promptUsingTUI := len(args) == 0 apiClient, err := apiclient_util.GetApiClient(nil) @@ -83,7 +83,7 @@ var CreateCmd = &cobra.Command{ } if promptUsingTUI { - err = processPrompting(ctx, apiClient, &targetName, &projects, existingTargetNames) + err = processPrompting(ctx, apiClient, &targetName, &workspaces, existingTargetNames) if err != nil { if common.IsCtrlCAbort(err) { return nil @@ -92,39 +92,39 @@ var CreateCmd = &cobra.Command{ } } } else { - existingProjectConfigNames, err = processCmdArguments(ctx, args, apiClient, &projects) + existingWorkspaceConfigNames, err = processCmdArguments(ctx, args, apiClient, &workspaces) if err != nil { return err } - initialSuggestion := projects[0].Name + initialSuggestion := workspaces[0].Name if targetName == "" { targetName = target_util.GetSuggestedName(initialSuggestion, existingTargetNames) } } - if targetName == "" || len(projects) == 0 { + if targetName == "" || len(workspaces) == 0 { return errors.New("target name and repository urls are required") } - projectNames := []string{} - for i := range projects { + workspaceNames := []string{} + for i := range workspaces { if profileData != nil && profileData.EnvVars != nil { - projects[i].EnvVars = util.MergeEnvVars(profileData.EnvVars, projects[i].EnvVars) + workspaces[i].EnvVars = util.MergeEnvVars(profileData.EnvVars, workspaces[i].EnvVars) } else { - projects[i].EnvVars = util.MergeEnvVars(projects[i].EnvVars) + workspaces[i].EnvVars = util.MergeEnvVars(workspaces[i].EnvVars) } - projectNames = append(projectNames, projects[i].Name) + workspaceNames = append(workspaceNames, workspaces[i].Name) } - for i, projectConfigName := range existingProjectConfigNames { - if projectConfigName == "" { + for i, workspaceConfigName := range existingWorkspaceConfigNames { + if workspaceConfigName == "" { continue } logs_view.DisplayLogEntry(logs.LogEntry{ - ProjectName: &projects[i].Name, - Msg: fmt.Sprintf("Using detected project config '%s'\n", projectConfigName), + WorkspaceName: &workspaces[i].Name, + Msg: fmt.Sprintf("Using detected workspace config '%s'\n", workspaceConfigName), }, i) } @@ -148,7 +148,7 @@ var CreateCmd = &cobra.Command{ return err } - logs_view.CalculateLongestPrefixLength(projectNames) + logs_view.CalculateLongestPrefixLength(workspaceNames) logs_view.DisplayLogEntry(logs.LogEntry{ Msg: "Request submitted\n", @@ -171,19 +171,19 @@ var CreateCmd = &cobra.Command{ id = stringid.TruncateID(id) logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadTargetLogs(logsContext, activeProfile, id, projectNames, true, true, nil) + go apiclient_util.ReadTargetLogs(logsContext, activeProfile, id, workspaceNames, true, true, nil) createdTarget, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(apiclient.CreateTargetDTO{ Id: id, Name: targetName, TargetConfig: targetConfig.Name, - Projects: projects, + Workspaces: workspaces, }).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) } - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, projects[0].GitProviderConfigId) + gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, workspaces[0].GitProviderConfigId) if err != nil { log.Warn(err) } @@ -228,13 +228,13 @@ var CreateCmd = &cobra.Command{ views.RenderCreationInfoMessage(fmt.Sprintf("Opening the target in %s ...", chosenIde.Name)) - projectName := targetInfo.Projects[0].Name - providerMetadata, err := target_util.GetProjectProviderMetadata(targetInfo, projectName) + workspaceName := targetInfo.Workspaces[0].Name + providerMetadata, err := target_util.GetWorkspaceProviderMetadata(targetInfo, workspaceName) if err != nil { return err } - return openIDE(chosenIdeId, activeProfile, createdTarget.Id, targetInfo.Projects[0].Name, providerMetadata, yesFlag, gpgKey) + return openIDE(chosenIdeId, activeProfile, createdTarget.Id, targetInfo.Workspaces[0].Name, providerMetadata, yesFlag, gpgKey) }, } @@ -242,9 +242,9 @@ var nameFlag string var targetConfigNameFlag string var noIdeFlag bool var blankFlag bool -var multiProjectFlag bool +var multiWorkspaceFlag bool -var projectConfigurationFlags = target_util.ProjectConfigurationFlags{ +var workspaceConfigurationFlags = target_util.WorkspaceConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -266,18 +266,18 @@ func init() { CreateCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the target name") CreateCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) CreateCmd.Flags().StringVarP(&targetConfigNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") - CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank project without using existing configurations") + CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank workspace without using existing configurations") CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the target in the IDE after target creation") - CreateCmd.Flags().BoolVar(&multiProjectFlag, "multi-project", false, "Target with multiple projects/repos") + CreateCmd.Flags().BoolVar(&multiWorkspaceFlag, "multi-workspace", false, "Target with multiple workspaces/repos") CreateCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") - CreateCmd.Flags().StringSliceVar(projectConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the projects") + CreateCmd.Flags().StringSliceVar(workspaceConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the workspaces") - target_util.AddProjectConfigurationFlags(CreateCmd, projectConfigurationFlags, true) + target_util.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) } -func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targetName *string, projects *[]apiclient.CreateProjectDTO, targetNames []string) error { - if target_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) || (projectConfigurationFlags.Branches != nil && len(*projectConfigurationFlags.Branches) > 0) { - return errors.New("please provide the repository URL in order to set up custom project details through the CLI") +func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targetName *string, workspaces *[]apiclient.CreateWorkspaceDTO, targetNames []string) error { + if target_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) || (workspaceConfigurationFlags.Branches != nil && len(*workspaceConfigurationFlags.Branches) > 0) { + return errors.New("please provide the repository URL in order to set up custom workspace details through the CLI") } gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute() @@ -285,7 +285,7 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targe return apiclient_util.HandleErrorResponse(res, err) } - projectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -295,40 +295,40 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targe return apiclient_util.HandleErrorResponse(res, err) } - projectDefaults := &views_util.ProjectConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ BuildChoice: views_util.AUTOMATIC, - Image: &apiServerConfig.DefaultProjectImage, - ImageUser: &apiServerConfig.DefaultProjectUser, + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - *projects, err = target_util.GetProjectsCreationDataFromPrompt(target_util.ProjectsDataPromptConfig{ + *workspaces, err = target_util.GetWorkspacesCreationDataFromPrompt(target_util.WorkspacesDataPromptConfig{ UserGitProviders: gitProviders, - ProjectConfigs: projectConfigs, - Manual: *projectConfigurationFlags.Manual, - MultiProject: multiProjectFlag, - BlankProject: blankFlag, + WorkspaceConfigs: workspaceConfigs, + Manual: *workspaceConfigurationFlags.Manual, + MultiWorkspace: multiWorkspaceFlag, + BlankWorkspace: blankFlag, ApiClient: apiClient, - Defaults: projectDefaults, + Defaults: workspaceDefaults, }) if err != nil { return err } - initialSuggestion := (*projects)[0].Name + initialSuggestion := (*workspaces)[0].Name suggestedName := target_util.GetSuggestedName(initialSuggestion, targetNames) - dedupProjectNames(projects) + dedupWorkspaceNames(workspaces) submissionFormConfig := create.SubmissionFormConfig{ ChosenName: targetName, SuggestedName: suggestedName, ExistingNames: targetNames, - ProjectList: projects, + WorkspaceList: workspaces, NameLabel: "Target", - Defaults: projectDefaults, + Defaults: workspaceDefaults, } pcImportFlag := false @@ -340,75 +340,75 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targe return nil } -func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apiclient.APIClient, projects *[]apiclient.CreateProjectDTO) ([]string, error) { +func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apiclient.APIClient, workspaces *[]apiclient.CreateWorkspaceDTO) ([]string, error) { if len(repoUrls) == 0 { return nil, fmt.Errorf("no repository URLs provided") } - if len(repoUrls) > 1 && target_util.CheckAnyProjectConfigurationFlagSet(projectConfigurationFlags) { - return nil, fmt.Errorf("can't set custom project configuration properties for multiple projects") + if len(repoUrls) > 1 && target_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { + return nil, fmt.Errorf("can't set custom workspace configuration properties for multiple workspaces") } - if *projectConfigurationFlags.Builder != "" && *projectConfigurationFlags.Builder != views_util.DEVCONTAINER && *projectConfigurationFlags.DevcontainerPath != "" { + if *workspaceConfigurationFlags.Builder != "" && *workspaceConfigurationFlags.Builder != views_util.DEVCONTAINER && *workspaceConfigurationFlags.DevcontainerPath != "" { return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) } - var projectConfig *apiclient.ProjectConfig + var workspaceConfig *apiclient.WorkspaceConfig - existingProjectConfigNames := []string{} + existingWorkspaceConfigNames := []string{} for i, repoUrl := range repoUrls { var branch *string - if len(*projectConfigurationFlags.Branches) > i { - branch = &(*projectConfigurationFlags.Branches)[i] + if len(*workspaceConfigurationFlags.Branches) > i { + branch = &(*workspaceConfigurationFlags.Branches)[i] } validatedUrl, err := util.GetValidatedUrl(repoUrl) if err == nil { // The argument is a Git URL - existingProjectConfigName, err := processGitURL(ctx, validatedUrl, apiClient, projects, branch) + existingWorkspaceConfigName, err := processGitURL(ctx, validatedUrl, apiClient, workspaces, branch) if err != nil { return nil, err } - if existingProjectConfigName != nil { - existingProjectConfigNames = append(existingProjectConfigNames, *existingProjectConfigName) + if existingWorkspaceConfigName != nil { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) } else { - existingProjectConfigNames = append(existingProjectConfigNames, "") + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") } continue } - // The argument is not a Git URL - try getting the project config - projectConfig, _, err = apiClient.ProjectConfigAPI.GetProjectConfig(ctx, repoUrl).Execute() + // The argument is not a Git URL - try getting the workspace config + workspaceConfig, _, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, repoUrl).Execute() if err != nil { - return nil, fmt.Errorf("failed to parse the URL or fetch the project config for '%s'", repoUrl) + return nil, fmt.Errorf("failed to parse the URL or fetch the workspace config for '%s'", repoUrl) } - existingProjectConfigName, err := target_util.AddProjectFromConfig(projectConfig, apiClient, projects, branch) + existingWorkspaceConfigName, err := target_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) if err != nil { return nil, err } - if existingProjectConfigName != nil { - existingProjectConfigNames = append(existingProjectConfigNames, *existingProjectConfigName) + if existingWorkspaceConfigName != nil { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) } else { - existingProjectConfigNames = append(existingProjectConfigNames, "") + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") } } - dedupProjectNames(projects) + dedupWorkspaceNames(workspaces) - return existingProjectConfigNames, nil + return existingWorkspaceConfigNames, nil } -func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.APIClient, projects *[]apiclient.CreateProjectDTO, branch *string) (*string, error) { +func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.APIClient, workspaces *[]apiclient.CreateWorkspaceDTO, branch *string) (*string, error) { encodedURLParam := url.QueryEscape(repoUrl) if !blankFlag { - projectConfig, res, err := apiClient.ProjectConfigAPI.GetDefaultProjectConfig(ctx, encodedURLParam).Execute() + workspaceConfig, res, err := apiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() if err == nil { - projectConfig.GitProviderConfigId = projectConfigurationFlags.GitProviderConfig - return target_util.AddProjectFromConfig(projectConfig, apiClient, projects, branch) + workspaceConfig.GitProviderConfigId = workspaceConfigurationFlags.GitProviderConfig + return target_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) } if res.StatusCode != http.StatusNotFound { @@ -424,24 +424,24 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API return nil, apiclient_util.HandleErrorResponse(res, err) } - projectName, err := target_util.GetSanitizedProjectName(repo.Name) + workspaceName, err := target_util.GetSanitizedWorkspaceName(repo.Name) if err != nil { return nil, err } - projectConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, projectConfigurationFlags.GitProviderConfig) + workspaceConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } - if projectConfigurationFlags.GitProviderConfig == nil || *projectConfigurationFlags.GitProviderConfig == "" { + if workspaceConfigurationFlags.GitProviderConfig == nil || *workspaceConfigurationFlags.GitProviderConfig == "" { gitProviderConfigs, res, err := apiClient.GitProviderAPI.ListGitProvidersForUrl(context.Background(), url.QueryEscape(repoUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } if len(gitProviderConfigs) == 1 { - projectConfigurationFlags.GitProviderConfig = &gitProviderConfigs[0].Id + workspaceConfigurationFlags.GitProviderConfig = &gitProviderConfigs[0].Id } else if len(gitProviderConfigs) > 1 { gp := selection.GetGitProviderConfigFromPrompt(selection.GetGitProviderConfigParams{ GitProviderConfigs: gitProviderConfigs, @@ -450,36 +450,36 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API if gp == nil { return nil, common.ErrCtrlCAbort } - projectConfigurationFlags.GitProviderConfig = &gp.Id + workspaceConfigurationFlags.GitProviderConfig = &gp.Id } } - project, err := target_util.GetCreateProjectDtoFromFlags(projectConfigurationFlags) + workspace, err := target_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) if err != nil { return nil, err } - project.Name = projectName - project.Source = apiclient.CreateProjectSourceDTO{ + workspace.Name = workspaceName + workspace.Source = apiclient.CreateWorkspaceSourceDTO{ Repository: *repo, } - *projects = append(*projects, *project) + *workspaces = append(*workspaces, *workspace) return nil, nil } func waitForDial(target *apiclient.Target, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { if target.TargetConfig == "local" && (activeProfile != nil && activeProfile.Id == "default") { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, target.Id, target.Projects[0].Name, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, target.Id, target.Workspaces[0].Name, gpgKey) if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, target.Id, target.Projects[0].Name) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, target.Id, target.Workspaces[0].Name) for { - sshCommand := exec.Command("ssh", projectHostname, "daytona", "version") + sshCommand := exec.Command("ssh", workspaceHostname, "daytona", "version") sshCommand.Stdin = nil sshCommand.Stdout = nil sshCommand.Stderr = &util.TraceLogWriter{} @@ -499,7 +499,7 @@ func waitForDial(target *apiclient.Target, activeProfile *config.Profile, tsConn go func() { for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(target.Id, target.Projects[0].Name), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(target.Id, target.Workspaces[0].Name), ssh_config.SSH_PORT)) if err == nil { connectChan <- dialConn.Close() return @@ -524,15 +524,15 @@ func waitForDial(target *apiclient.Target, activeProfile *config.Profile, tsConn } } -func dedupProjectNames(projects *[]apiclient.CreateProjectDTO) { - projectNames := map[string]int{} +func dedupWorkspaceNames(workspaces *[]apiclient.CreateWorkspaceDTO) { + workspaceNames := map[string]int{} - for i, project := range *projects { - if _, ok := projectNames[project.Name]; ok { - (*projects)[i].Name = fmt.Sprintf("%s-%d", project.Name, projectNames[project.Name]) - projectNames[project.Name]++ + for i, workspace := range *workspaces { + if _, ok := workspaceNames[workspace.Name]; ok { + (*workspaces)[i].Name = fmt.Sprintf("%s-%d", workspace.Name, workspaceNames[workspace.Name]) + workspaceNames[workspace.Name]++ } else { - projectNames[project.Name] = 2 + workspaceNames[workspace.Name] = 2 } } } diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index 38dcad80fe..31b479947c 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -16,7 +16,7 @@ import ( "github.com/spf13/cobra" ) -var restartProjectFlag string +var restartWorkspaceFlag string var RestartCmd = &cobra.Command{ Use: "restart [TARGET]", @@ -34,7 +34,7 @@ var RestartCmd = &cobra.Command{ } if len(args) == 0 { - if restartProjectFlag != "" { + if restartWorkspaceFlag != "" { err := cmd.Help() if err != nil { return err @@ -61,12 +61,12 @@ var RestartCmd = &cobra.Command{ targetId = args[0] } - err = RestartTarget(apiClient, targetId, restartProjectFlag) + err = RestartTarget(apiClient, targetId, restartWorkspaceFlag) if err != nil { return err } - if restartProjectFlag != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully restarted", restartProjectFlag, targetId)) + if restartWorkspaceFlag != "" { + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully restarted", restartWorkspaceFlag, targetId)) } else { views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) } @@ -78,13 +78,13 @@ var RestartCmd = &cobra.Command{ } func init() { - RestartCmd.Flags().StringVarP(&restartProjectFlag, "project", "p", "", "Restart a single project in the target (project name)") + RestartCmd.Flags().StringVarP(&restartWorkspaceFlag, "workspace", "w", "", "Restart a single workspace in the target (workspace name)") } -func RestartTarget(apiClient *apiclient.APIClient, targetId, projectName string) error { - err := StopTarget(apiClient, targetId, projectName) +func RestartTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) error { + err := StopTarget(apiClient, targetId, workspaceName) if err != nil { return err } - return StartTarget(apiClient, targetId, projectName) + return StartTarget(apiClient, targetId, workspaceName) } diff --git a/pkg/cmd/target/ssh-proxy.go b/pkg/cmd/target/ssh-proxy.go index fc80fbe0f1..c63ff4ee4c 100644 --- a/pkg/cmd/target/ssh-proxy.go +++ b/pkg/cmd/target/ssh-proxy.go @@ -16,7 +16,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" @@ -26,7 +26,7 @@ import ( ) var SshProxyCmd = &cobra.Command{ - Use: "ssh-proxy [PROFILE_ID] [TARGET_ID] [PROJECT]", + Use: "ssh-proxy [PROFILE_ID] [TARGET_ID] [WORKSPACE]", Args: cobra.RangeArgs(2, 3), Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { @@ -37,7 +37,7 @@ var SshProxyCmd = &cobra.Command{ profileId := args[0] targetId := args[1] - projectName := "" + workspaceName := "" profile, err := c.GetProfile(profileId) if err != nil { @@ -45,9 +45,9 @@ var SshProxyCmd = &cobra.Command{ } if len(args) == 3 { - projectName = args[2] + workspaceName = args[2] } else { - projectName, err = apiclient.GetFirstProjectName(targetId, projectName, &profile) + workspaceName, err = apiclient.GetFirstWorkspaceName(targetId, workspaceName, &profile) if err != nil { return err } @@ -60,12 +60,12 @@ var SshProxyCmd = &cobra.Command{ if target.TargetConfig == "local" && profile.Id == "default" { // If the target is local, we directly access the ssh port through the container - project := target.Projects[0] + workspace := target.Workspaces[0] - if project.Name != projectName { - for _, p := range target.Projects { - if p.Name == projectName { - project = p + if workspace.Name != workspaceName { + for _, w := range target.Workspaces { + if w.Name == workspaceName { + workspace = w break } } @@ -80,7 +80,7 @@ var SshProxyCmd = &cobra.Command{ ApiClient: cli, }) - containerName := dockerClient.GetProjectContainerName(conversion.ToProject(&project)) + containerName := dockerClient.GetWorkspaceContainerName(conversion.ToWorkspace(&workspace)) ctx := context.Background() @@ -139,7 +139,7 @@ var SshProxyCmd = &cobra.Command{ errChan := make(chan error) - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(targetId, projectName), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(targetId, workspaceName), ssh_config.SSH_PORT)) if err != nil { return err } diff --git a/pkg/cmd/target/ssh.go b/pkg/cmd/target/ssh.go index 2a1f40bb15..4357d11f80 100644 --- a/pkg/cmd/target/ssh.go +++ b/pkg/cmd/target/ssh.go @@ -31,8 +31,8 @@ var ( ) var SshCmd = &cobra.Command{ - Use: "ssh [TARGET] [PROJECT] [CMD...]", - Short: "SSH into a project using the terminal", + Use: "ssh [TARGET] [WORKSPACE] [CMD...]", + Short: "SSH into a workspace using the terminal", Args: cobra.ArbitraryArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { @@ -48,7 +48,7 @@ var SshCmd = &cobra.Command{ ctx := context.Background() var target *apiclient.TargetDTO - var projectName string + var workspaceName string var providerConfigId *string apiClient, err := apiclient_util.GetApiClient(&activeProfile) @@ -79,37 +79,36 @@ var SshCmd = &cobra.Command{ } if len(args) == 0 || len(args) == 1 { - selectedProject, err := selectTargetProject(target.Id, &activeProfile) + selectedWorkspace, err := selectTargetWorkspace(target.Id, &activeProfile) if err != nil { return err } - if selectedProject == nil { + if selectedWorkspace == nil { return nil } - projectName = selectedProject.Name - providerConfigId = selectedProject.GitProviderConfigId + workspaceName = selectedWorkspace.Name + providerConfigId = selectedWorkspace.GitProviderConfigId } if len(args) >= 2 { - projectName = args[1] - for _, project := range target.Projects { - if project.Name == projectName { - providerConfigId = project.GitProviderConfigId + workspaceName = args[1] + for _, workspace := range target.Workspaces { + if workspace.Name == workspaceName { + providerConfigId = workspace.GitProviderConfigId break } } } if edit { - err := editSSHConfig(activeProfile, target, projectName) + err := editSSHConfig(activeProfile, target, workspaceName) if err != nil { return err } - return nil } - if !target_util.IsProjectRunning(target, projectName) { - tgRunningStatus, err := AutoStartTarget(target.Name, projectName) + if !target_util.IsWorkspaceRunning(target, workspaceName) { + tgRunningStatus, err := AutoStartTarget(target.Name, workspaceName) if err != nil { return err } @@ -128,14 +127,14 @@ var SshCmd = &cobra.Command{ log.Warn(err) } - return ide.OpenTerminalSsh(activeProfile, target.Id, projectName, gpgKey, sshOptions, sshArgs...) + return ide.OpenTerminalSsh(activeProfile, target.Id, workspaceName, gpgKey, sshOptions, sshArgs...) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { if len(args) >= 2 { return nil, cobra.ShellCompDirectiveNoFileComp } if len(args) == 1 { - return getProjectNameCompletions(cmd, args, toComplete) + return getWorkspaceNameCompletions(cmd, args, toComplete) } return getTargetNameCompletions() @@ -144,11 +143,11 @@ var SshCmd = &cobra.Command{ func init() { SshCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") - SshCmd.Flags().BoolVarP(&edit, "edit", "e", false, "Edit the project's SSH config") + SshCmd.Flags().BoolVarP(&edit, "edit", "e", false, "Edit the workspace's SSH config") SshCmd.Flags().StringArrayVarP(&sshOptions, "option", "o", []string{}, "Specify SSH options in KEY=VALUE format.") } -func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, projectName string) error { +func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, workspaceName string) error { sshDir := filepath.Join(config.SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") sshConfig, err := config.ReadSshConfig(configPath) @@ -156,11 +155,11 @@ func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, pr return err } - hostLine := fmt.Sprintf("Host %s", config.GetProjectHostname(activeProfile.Id, target.Id, projectName)) + hostLine := fmt.Sprintf("Host %s", config.GetWorkspaceHostname(activeProfile.Id, target.Id, workspaceName)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(sshConfig) if matchedEntry == "" { - return fmt.Errorf("no SSH entry found for project %s", projectName) + return fmt.Errorf("no SSH entry found for workspace %s", workspaceName) } lines := strings.Split(matchedEntry, "\n") @@ -217,7 +216,7 @@ func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, pr if err != nil { return err } - views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s removed successfully", projectName)) + views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s removed successfully", workspaceName)) return nil } @@ -237,12 +236,12 @@ func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, pr modifiedContent += "\n" } - err = config.UpdateWorkspaceSshEntry(activeProfile.Id, target.Id, projectName, modifiedContent) + err = config.UpdateWorkspaceSshEntry(activeProfile.Id, target.Id, workspaceName, modifiedContent) if err != nil { return err } - views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s updated successfully", projectName)) + views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s updated successfully", workspaceName)) return nil } diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 57ba8c343b..7553522f84 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -29,7 +29,7 @@ const ( TARGET_STATE_STOPPED TargetState = "Unavailable" ) -var startProjectFlag string +var startWorkspaceFlag string var allFlag bool var codeFlag bool @@ -44,7 +44,7 @@ var StartCmd = &cobra.Command{ var ideId string var ideList []config.Ide var providerConfigId *string - projectProviderMetadata := "" + workspaceProviderMetadata := "" ctx := context.Background() @@ -58,7 +58,7 @@ var StartCmd = &cobra.Command{ } if len(args) == 0 { - if startProjectFlag != "" { + if startWorkspaceFlag != "" { return cmd.Help() } targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() @@ -100,27 +100,27 @@ var StartCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } targetId = targetInfo.Id - if startProjectFlag == "" { - startProjectFlag = targetInfo.Projects[0].Name - providerConfigId = targetInfo.Projects[0].GitProviderConfigId + if startWorkspaceFlag == "" { + startWorkspaceFlag = targetInfo.Workspaces[0].Name + providerConfigId = targetInfo.Workspaces[0].GitProviderConfigId } else { - for _, project := range targetInfo.Projects { - if project.Name == startProjectFlag { - providerConfigId = project.GitProviderConfigId + for _, workspace := range targetInfo.Workspaces { + if workspace.Name == startWorkspaceFlag { + providerConfigId = workspace.GitProviderConfigId break } } } if ideId != "ssh" { - projectProviderMetadata, err = target_util.GetProjectProviderMetadata(targetInfo, targetInfo.Projects[0].Name) + workspaceProviderMetadata, err = target_util.GetWorkspaceProviderMetadata(targetInfo, targetInfo.Workspaces[0].Name) if err != nil { return err } } } - err = StartTarget(apiClient, targetName, startProjectFlag) + err = StartTarget(apiClient, targetName, startWorkspaceFlag) if err != nil { return err } @@ -129,14 +129,14 @@ var StartCmd = &cobra.Command{ log.Warn(err) } - if startProjectFlag == "" { + if startWorkspaceFlag == "" { views.RenderInfoMessage(fmt.Sprintf("Target '%s' started successfully", targetName)) } else { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' started successfully", startProjectFlag, targetName)) + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' started successfully", startWorkspaceFlag, targetName)) if codeFlag { - ide_views.RenderIdeOpeningMessage(targetName, startProjectFlag, ideId, ideList) - err = openIDE(ideId, activeProfile, targetId, startProjectFlag, projectProviderMetadata, yesFlag, gpgKey) + ide_views.RenderIdeOpeningMessage(targetName, startWorkspaceFlag, ideId, ideList) + err = openIDE(ideId, activeProfile, targetId, startWorkspaceFlag, workspaceProviderMetadata, yesFlag, gpgKey) if err != nil { return err } @@ -160,12 +160,12 @@ var StartCmd = &cobra.Command{ } func init() { - StartCmd.PersistentFlags().StringVarP(&startProjectFlag, "project", "p", "", "Start a single project in the target (project name)") + StartCmd.PersistentFlags().StringVarP(&startWorkspaceFlag, "workspace", "w", "", "Start a single workspace in the target (workspace name)") StartCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Start all targets") StartCmd.PersistentFlags().BoolVarP(&codeFlag, "code", "c", false, "Open the target in the IDE after target start") StartCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") - err := StartCmd.RegisterFlagCompletionFunc("project", getProjectNameCompletions) + err := StartCmd.RegisterFlagCompletionFunc("workspace", getWorkspaceNameCompletions) if err != nil { log.Error("failed to register completion function: ", err) } @@ -195,7 +195,7 @@ func startAllTargets() error { return nil } -func getProjectNameCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { +func getWorkspaceNameCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -209,8 +209,8 @@ func getProjectNameCompletions(cmd *cobra.Command, args []string, toComplete str } var choices []string - for _, project := range target.Projects { - choices = append(choices, project.Name) + for _, workspace := range target.Workspaces { + choices = append(choices, workspace.Name) } return choices, cobra.ShellCompDirectiveDefault } @@ -249,15 +249,15 @@ func getAllTargetsByState(state TargetState) ([]string, cobra.ShellCompDirective var choices []string for _, target := range targetList { - for _, project := range target.Projects { - if project.State == nil { + for _, workspace := range target.Workspaces { + if workspace.State == nil { continue } - if state == TARGET_STATE_RUNNING && project.State.Uptime != 0 { + if state == TARGET_STATE_RUNNING && workspace.State.Uptime != 0 { choices = append(choices, target.Name) break } - if state == TARGET_STATE_STOPPED && project.State.Uptime == 0 { + if state == TARGET_STATE_STOPPED && workspace.State.Uptime == 0 { choices = append(choices, target.Name) break } @@ -267,9 +267,9 @@ func getAllTargetsByState(state TargetState) ([]string, cobra.ShellCompDirective return choices, cobra.ShellCompDirectiveNoFileComp } -func StartTarget(apiClient *apiclient.APIClient, targetId, projectName string) error { +func StartTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) error { ctx := context.Background() - var projectNames []string + var workspaceNames []string timeFormat := time.Now().Format("2006-01-02 15:04:05") from, err := time.Parse("2006-01-02 15:04:05", timeFormat) if err != nil { @@ -290,18 +290,18 @@ func StartTarget(apiClient *apiclient.APIClient, targetId, projectName string) e if err != nil { return err } - if projectName != "" { - projectNames = append(projectNames, projectName) + if workspaceName != "" { + workspaceNames = append(workspaceNames, workspaceName) } else { - projectNames = util.ArrayMap(target.Projects, func(p apiclient.Project) string { - return p.Name + workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + return w.Name }) } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadTargetLogs(logsContext, activeProfile, target.Id, projectNames, true, true, &from) + go apiclient_util.ReadTargetLogs(logsContext, activeProfile, target.Id, workspaceNames, true, true, &from) - if projectName == "" { + if workspaceName == "" { res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() if err != nil { stopLogs() @@ -311,7 +311,7 @@ func StartTarget(apiClient *apiclient.APIClient, targetId, projectName string) e stopLogs() return nil } else { - res, err := apiClient.TargetAPI.StartProject(ctx, targetId, projectName).Execute() + res, err := apiClient.TargetAPI.StartWorkspace(ctx, targetId, workspaceName).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go index f13a6be34c..21cca0a25b 100644 --- a/pkg/cmd/target/stop.go +++ b/pkg/cmd/target/stop.go @@ -19,7 +19,7 @@ import ( "github.com/spf13/cobra" ) -var stopProjectFlag string +var stopWorkspaceFlag string var StopCmd = &cobra.Command{ Use: "stop [TARGET]", @@ -55,7 +55,7 @@ var StopCmd = &cobra.Command{ } if len(args) == 0 { - if stopProjectFlag != "" { + if stopWorkspaceFlag != "" { return cmd.Help() } targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() @@ -77,17 +77,17 @@ var StopCmd = &cobra.Command{ continue } - projectNames := util.ArrayMap(target.Projects, func(p apiclient.Project) string { - return p.Name + workspaceNames := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + return w.Name }) - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, false, true, &from) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, false, true, &from) views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) } } else { targetId := args[0] - var projectNames []string + var workspaceNames []string - err = StopTarget(apiClient, targetId, stopProjectFlag) + err = StopTarget(apiClient, targetId, stopWorkspaceFlag) if err != nil { return err } @@ -97,18 +97,18 @@ var StopCmd = &cobra.Command{ return err } - if startProjectFlag != "" { - projectNames = append(projectNames, stopProjectFlag) + if startWorkspaceFlag != "" { + workspaceNames = append(workspaceNames, stopWorkspaceFlag) } else { - projectNames = util.ArrayMap(target.Projects, func(p apiclient.Project) string { - return p.Name + workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + return w.Name }) } - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, false, true, &from) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, false, true, &from) - if stopProjectFlag != "" { - views.RenderInfoMessage(fmt.Sprintf("Project '%s' from target '%s' successfully stopped", stopProjectFlag, targetId)) + if stopWorkspaceFlag != "" { + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully stopped", stopWorkspaceFlag, targetId)) } else { views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) } @@ -121,7 +121,7 @@ var StopCmd = &cobra.Command{ } func init() { - StopCmd.Flags().StringVarP(&stopProjectFlag, "project", "p", "", "Stop a single project in the target (project name)") + StopCmd.Flags().StringVarP(&stopWorkspaceFlag, "workspace", "w", "", "Stop a single workspace in the target (workspace name)") StopCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Stop all targets") } @@ -144,22 +144,22 @@ func stopAllTargets(activeProfile config.Profile, from time.Time) error { continue } - projectNames := util.ArrayMap(target.Projects, func(p apiclient.Project) string { - return p.Name + workspaceNames := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + return w.Name }) - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, projectNames, false, true, &from) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, false, true, &from) views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) } return nil } -func StopTarget(apiClient *apiclient.APIClient, targetId, projectName string) error { +func StopTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) error { ctx := context.Background() var message string var stopFunc func() error - if projectName == "" { + if workspaceName == "" { message = fmt.Sprintf("Target '%s' is stopping", targetId) stopFunc = func() error { res, err := apiClient.TargetAPI.StopTarget(ctx, targetId).Execute() @@ -169,9 +169,9 @@ func StopTarget(apiClient *apiclient.APIClient, targetId, projectName string) er return nil } } else { - message = fmt.Sprintf("Project '%s' from target '%s' is stopping", projectName, targetId) + message = fmt.Sprintf("Workspace '%s' from target '%s' is stopping", workspaceName, targetId) stopFunc = func() error { - res, err := apiClient.TargetAPI.StopProject(ctx, targetId, projectName).Execute() + res, err := apiClient.TargetAPI.StopWorkspace(ctx, targetId, workspaceName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/target/util/add_from_config.go b/pkg/cmd/target/util/add_from_config.go index 30b2de961b..18e558fb9e 100644 --- a/pkg/cmd/target/util/add_from_config.go +++ b/pkg/cmd/target/util/add_from_config.go @@ -11,14 +11,14 @@ import ( "github.com/daytonaio/daytona/pkg/common" ) -func AddProjectFromConfig(projectConfig *apiclient.ProjectConfig, apiClient *apiclient.APIClient, projects *[]apiclient.CreateProjectDTO, branchFlag *string) (*string, error) { +func AddWorkspaceFromConfig(workspaceConfig *apiclient.WorkspaceConfig, apiClient *apiclient.APIClient, workspaces *[]apiclient.CreateWorkspaceDTO, branchFlag *string) (*string, error) { chosenBranchName := "" if branchFlag != nil { chosenBranchName = *branchFlag } if chosenBranchName == "" { - chosenBranch, err := GetBranchFromProjectConfig(projectConfig, apiClient, 0) + chosenBranch, err := GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return nil, err } @@ -30,25 +30,25 @@ func AddProjectFromConfig(projectConfig *apiclient.ProjectConfig, apiClient *api } configRepo, res, err := apiClient.GitProviderAPI.GetGitContext(context.Background()).Repository(apiclient.GetRepositoryContext{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, Branch: &chosenBranchName, }).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - project := &apiclient.CreateProjectDTO{ - Name: projectConfig.Name, - GitProviderConfigId: projectConfig.GitProviderConfigId, - Source: apiclient.CreateProjectSourceDTO{ + workspace := &apiclient.CreateWorkspaceDTO{ + Name: workspaceConfig.Name, + GitProviderConfigId: workspaceConfig.GitProviderConfigId, + Source: apiclient.CreateWorkspaceSourceDTO{ Repository: *configRepo, }, - BuildConfig: projectConfig.BuildConfig, - Image: &projectConfig.Image, - User: &projectConfig.User, - EnvVars: projectConfig.EnvVars, + BuildConfig: workspaceConfig.BuildConfig, + Image: &workspaceConfig.Image, + User: &workspaceConfig.User, + EnvVars: workspaceConfig.EnvVars, } - *projects = append(*projects, *project) + *workspaces = append(*workspaces, *workspace) - return &projectConfig.Name, nil + return &workspaceConfig.Name, nil } diff --git a/pkg/cmd/target/util/branch_wizard.go b/pkg/cmd/target/util/branch_wizard.go index 39c7c3303b..c5b4670651 100644 --- a/pkg/cmd/target/util/branch_wizard.go +++ b/pkg/cmd/target/util/branch_wizard.go @@ -23,7 +23,7 @@ type BranchWizardConfig struct { NamespaceId string Namespace string ChosenRepo *apiclient.GitRepository - ProjectOrder int + WorkspaceOrder int ProviderId string } @@ -67,7 +67,7 @@ func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWiza } // User will either choose a branch or navigate the pages - branch, navigate := selection.GetBranchFromPrompt(branchList, config.ProjectOrder, selectionListOptions) + branch, navigate := selection.GetBranchFromPrompt(branchList, config.WorkspaceOrder, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { page++ @@ -150,7 +150,7 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e checkoutOptions = append(checkoutOptions, selection.CheckoutBranch) checkoutOptions = append(checkoutOptions, selection.CheckoutPR) - chosenCheckoutOption := selection.GetCheckoutOptionFromPrompt(config.ProjectOrder, checkoutOptions, parentIdentifier) + chosenCheckoutOption := selection.GetCheckoutOptionFromPrompt(config.WorkspaceOrder, checkoutOptions, parentIdentifier) if chosenCheckoutOption == (selection.CheckoutOption{}) { return nil, common.ErrCtrlCAbort @@ -213,7 +213,7 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e } // User will either choose a PR or navigate the pages - chosenPullRequest, navigate := selection.GetPullRequestFromPrompt(prList, config.ProjectOrder, selectionListOptions) + chosenPullRequest, navigate := selection.GetPullRequestFromPrompt(prList, config.WorkspaceOrder, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { page++ diff --git a/pkg/cmd/target/util/creation_data.go b/pkg/cmd/target/util/creation_data.go index e269a2e9a0..11b5a4afdf 100644 --- a/pkg/cmd/target/util/creation_data.go +++ b/pkg/cmd/target/util/creation_data.go @@ -22,28 +22,28 @@ import ( views_util "github.com/daytonaio/daytona/pkg/views/util" ) -type ProjectsDataPromptConfig struct { +type WorkspacesDataPromptConfig struct { UserGitProviders []apiclient.GitProvider - ProjectConfigs []apiclient.ProjectConfig + WorkspaceConfigs []apiclient.WorkspaceConfig Manual bool SkipBranchSelection bool - MultiProject bool - BlankProject bool + MultiWorkspace bool + BlankWorkspace bool ApiClient *apiclient.APIClient - Defaults *views_util.ProjectConfigDefaults + Defaults *views_util.WorkspaceConfigDefaults } -func GetProjectsCreationDataFromPrompt(config ProjectsDataPromptConfig) ([]apiclient.CreateProjectDTO, error) { - var projectList []apiclient.CreateProjectDTO - // keep track of visited repos, will help in keeping project names unique +func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]apiclient.CreateWorkspaceDTO, error) { + var workspaceList []apiclient.CreateWorkspaceDTO + // keep track of visited repos, will help in keeping workspace names unique // since these are later saved into the db under a unique constraint field. selectedRepos := make(map[string]int) - for i := 1; config.MultiProject || i == 1; i++ { + for i := 1; config.MultiWorkspace || i == 1; i++ { var err error if i > 2 { - addMore, err := create.RunAddMoreProjectsForm() + addMore, err := create.RunAddMoreWorkspacesForm() if err != nil { return nil, err } @@ -52,31 +52,31 @@ func GetProjectsCreationDataFromPrompt(config ProjectsDataPromptConfig) ([]apicl } } - if len(config.ProjectConfigs) > 0 && !config.BlankProject { - projectConfig := selection.GetProjectConfigFromPrompt(config.ProjectConfigs, i, true, false, "Use") - if projectConfig == nil { + if len(config.WorkspaceConfigs) > 0 && !config.BlankWorkspace { + workspaceConfig := selection.GetWorkspaceConfigFromPrompt(config.WorkspaceConfigs, i, true, false, "Use") + if workspaceConfig == nil { return nil, common.ErrCtrlCAbort } - projectNames := []string{} - for _, p := range projectList { - projectNames = append(projectNames, p.Name) + workspaceNames := []string{} + for _, w := range workspaceList { + workspaceNames = append(workspaceNames, w.Name) } // Append occurence number to keep duplicate entries unique - repoUrl := projectConfig.RepositoryUrl + repoUrl := workspaceConfig.RepositoryUrl if len(selectedRepos) > 0 && selectedRepos[repoUrl] > 1 { - projectConfig.Name += strconv.Itoa(selectedRepos[repoUrl]) + workspaceConfig.Name += strconv.Itoa(selectedRepos[repoUrl]) } - if projectConfig.Name != selection.BlankProjectIdentifier { - projectName := GetSuggestedName(projectConfig.Name, projectNames) + if workspaceConfig.Name != selection.BlankWorkspaceIdentifier { + workspaceName := GetSuggestedName(workspaceConfig.Name, workspaceNames) getRepoContext := apiclient.GetRepositoryContext{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, } - branch, err := GetBranchFromProjectConfig(projectConfig, config.ApiClient, i) + branch, err := GetBranchFromWorkspaceConfig(workspaceConfig, config.ApiClient, i) if err != nil { return nil, err } @@ -91,35 +91,35 @@ func GetProjectsCreationDataFromPrompt(config ProjectsDataPromptConfig) ([]apicl return nil, apiclient_util.HandleErrorResponse(res, err) } - createProjectDto := apiclient.CreateProjectDTO{ - Name: projectName, - GitProviderConfigId: projectConfig.GitProviderConfigId, - Source: apiclient.CreateProjectSourceDTO{ + createWorkspaceDto := apiclient.CreateWorkspaceDTO{ + Name: workspaceName, + GitProviderConfigId: workspaceConfig.GitProviderConfigId, + Source: apiclient.CreateWorkspaceSourceDTO{ Repository: *configRepo, }, - BuildConfig: projectConfig.BuildConfig, + BuildConfig: workspaceConfig.BuildConfig, Image: config.Defaults.Image, User: config.Defaults.ImageUser, - EnvVars: projectConfig.EnvVars, + EnvVars: workspaceConfig.EnvVars, } - if projectConfig.Image != "" { - createProjectDto.Image = &projectConfig.Image + if workspaceConfig.Image != "" { + createWorkspaceDto.Image = &workspaceConfig.Image } - if projectConfig.User != "" { - createProjectDto.User = &projectConfig.User + if workspaceConfig.User != "" { + createWorkspaceDto.User = &workspaceConfig.User } - if projectConfig.GitProviderConfigId == nil || *projectConfig.GitProviderConfigId == "" { - gitProviderConfigId, res, err := config.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(context.Background(), url.QueryEscape(projectConfig.RepositoryUrl)).Execute() + if workspaceConfig.GitProviderConfigId == nil || *workspaceConfig.GitProviderConfigId == "" { + gitProviderConfigId, res, err := config.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(context.Background(), url.QueryEscape(workspaceConfig.RepositoryUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - createProjectDto.GitProviderConfigId = &gitProviderConfigId + createWorkspaceDto.GitProviderConfigId = &gitProviderConfigId } - projectList = append(projectList, createProjectDto) + workspaceList = append(workspaceList, createWorkspaceDto) continue } } @@ -128,9 +128,9 @@ func GetProjectsCreationDataFromPrompt(config ProjectsDataPromptConfig) ([]apicl ApiClient: config.ApiClient, UserGitProviders: config.UserGitProviders, Manual: config.Manual, - MultiProject: config.MultiProject, + MultiWorkspace: config.MultiWorkspace, SkipBranchSelection: config.SkipBranchSelection, - ProjectOrder: i, + WorkspaceOrder: i, SelectedRepos: selectedRepos, }) if err != nil { @@ -167,20 +167,20 @@ func GetProjectsCreationDataFromPrompt(config ProjectsDataPromptConfig) ([]apicl return nil, apiclient_util.HandleErrorResponse(res, err) } - providerRepoName, err := GetSanitizedProjectName(providerRepo.Name) + providerRepoName, err := GetSanitizedWorkspaceName(providerRepo.Name) if err != nil { return nil, err } - projectList = append(projectList, newCreateProjectConfigDTO(config, providerRepo, providerRepoName, gitProviderConfigId)) + workspaceList = append(workspaceList, newCreateWorkspaceConfigDTO(config, providerRepo, providerRepoName, gitProviderConfigId)) } - return projectList, nil + return workspaceList, nil } -func GetProjectNameFromRepo(repoUrl string) string { - projectNameSlugRegex := regexp.MustCompile(`[^a-zA-Z0-9-]`) - return projectNameSlugRegex.ReplaceAllString(strings.TrimSuffix(strings.ToLower(filepath.Base(repoUrl)), ".git"), "-") +func GetWorkspaceNameFromRepo(repoUrl string) string { + workspaceNameSlugRegex := regexp.MustCompile(`[^a-zA-Z0-9-]`) + return workspaceNameSlugRegex.ReplaceAllString(strings.TrimSuffix(strings.ToLower(filepath.Base(repoUrl)), ".git"), "-") } func GetSuggestedName(initialSuggestion string, existingNames []string) string { @@ -200,23 +200,23 @@ func GetSuggestedName(initialSuggestion string, existingNames []string) string { } } -func GetSanitizedProjectName(projectName string) (string, error) { - projectName, err := url.QueryUnescape(projectName) +func GetSanitizedWorkspaceName(workspaceName string) (string, error) { + workspaceName, err := url.QueryUnescape(workspaceName) if err != nil { return "", err } - projectName = strings.ReplaceAll(projectName, " ", "-") + workspaceName = strings.ReplaceAll(workspaceName, " ", "-") - return projectName, nil + return workspaceName, nil } -func GetBranchFromProjectConfig(projectConfig *apiclient.ProjectConfig, apiClient *apiclient.APIClient, projectOrder int) (*apiclient.GitBranch, error) { +func GetBranchFromWorkspaceConfig(workspaceConfig *apiclient.WorkspaceConfig, apiClient *apiclient.APIClient, workspaceOrder int) (*apiclient.GitBranch, error) { ctx := context.Background() - encodedURLParam := url.QueryEscape(projectConfig.RepositoryUrl) + encodedURLParam := url.QueryEscape(workspaceConfig.RepositoryUrl) repoResponse, res, err := apiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, }).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) @@ -232,7 +232,7 @@ func GetBranchFromProjectConfig(projectConfig *apiclient.ProjectConfig, apiClien GitProviderConfigId: gitProviderConfigId, NamespaceId: repoResponse.Owner, ChosenRepo: repoResponse, - ProjectOrder: projectOrder, + WorkspaceOrder: workspaceOrder, } repo, err := SetBranchFromWizard(branchWizardConfig) @@ -250,34 +250,34 @@ func GetBranchFromProjectConfig(projectConfig *apiclient.ProjectConfig, apiClien }, nil } -func GetCreateProjectDtoFromFlags(projectConfigurationFlags ProjectConfigurationFlags) (*apiclient.CreateProjectDTO, error) { - project := &apiclient.CreateProjectDTO{ - GitProviderConfigId: projectConfigurationFlags.GitProviderConfig, +func GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags WorkspaceConfigurationFlags) (*apiclient.CreateWorkspaceDTO, error) { + workspace := &apiclient.CreateWorkspaceDTO{ + GitProviderConfigId: workspaceConfigurationFlags.GitProviderConfig, BuildConfig: &apiclient.BuildConfig{}, } - if *projectConfigurationFlags.Builder == views_util.DEVCONTAINER || *projectConfigurationFlags.DevcontainerPath != "" { + if *workspaceConfigurationFlags.Builder == views_util.DEVCONTAINER || *workspaceConfigurationFlags.DevcontainerPath != "" { devcontainerFilePath := create.DEVCONTAINER_FILEPATH - if *projectConfigurationFlags.DevcontainerPath != "" { - devcontainerFilePath = *projectConfigurationFlags.DevcontainerPath + if *workspaceConfigurationFlags.DevcontainerPath != "" { + devcontainerFilePath = *workspaceConfigurationFlags.DevcontainerPath } - project.BuildConfig.Devcontainer = &apiclient.DevcontainerConfig{ + workspace.BuildConfig.Devcontainer = &apiclient.DevcontainerConfig{ FilePath: devcontainerFilePath, } } - if *projectConfigurationFlags.Builder == views_util.NONE || *projectConfigurationFlags.CustomImage != "" || *projectConfigurationFlags.CustomImageUser != "" { - project.BuildConfig = nil - if *projectConfigurationFlags.CustomImage != "" || *projectConfigurationFlags.CustomImageUser != "" { - project.Image = projectConfigurationFlags.CustomImage - project.User = projectConfigurationFlags.CustomImageUser + if *workspaceConfigurationFlags.Builder == views_util.NONE || *workspaceConfigurationFlags.CustomImage != "" || *workspaceConfigurationFlags.CustomImageUser != "" { + workspace.BuildConfig = nil + if *workspaceConfigurationFlags.CustomImage != "" || *workspaceConfigurationFlags.CustomImageUser != "" { + workspace.Image = workspaceConfigurationFlags.CustomImage + workspace.User = workspaceConfigurationFlags.CustomImageUser } } envVars := make(map[string]string) - for _, envVar := range *projectConfigurationFlags.EnvVars { + for _, envVar := range *workspaceConfigurationFlags.EnvVars { parts := strings.SplitN(envVar, "=", 2) if len(parts) == 2 { envVars[parts[0]] = parts[1] @@ -286,9 +286,9 @@ func GetCreateProjectDtoFromFlags(projectConfigurationFlags ProjectConfiguration } } - project.EnvVars = envVars + workspace.EnvVars = envVars - return project, nil + return workspace, nil } func GetGitProviderConfigIdFromFlag(ctx context.Context, apiClient *apiclient.APIClient, gitProviderConfigFlag *string) (*string, error) { @@ -313,11 +313,11 @@ func GetGitProviderConfigIdFromFlag(ctx context.Context, apiClient *apiclient.AP return nil, fmt.Errorf("git provider config '%s' not found", *gitProviderConfigFlag) } -func newCreateProjectConfigDTO(config ProjectsDataPromptConfig, providerRepo *apiclient.GitRepository, providerRepoName string, gitProviderConfigId string) apiclient.CreateProjectDTO { - project := apiclient.CreateProjectDTO{ +func newCreateWorkspaceConfigDTO(config WorkspacesDataPromptConfig, providerRepo *apiclient.GitRepository, providerRepoName string, gitProviderConfigId string) apiclient.CreateWorkspaceDTO { + workspace := apiclient.CreateWorkspaceDTO{ Name: providerRepoName, GitProviderConfigId: &gitProviderConfigId, - Source: apiclient.CreateProjectSourceDTO{ + Source: apiclient.CreateWorkspaceSourceDTO{ Repository: *providerRepo, }, BuildConfig: &apiclient.BuildConfig{}, @@ -326,7 +326,7 @@ func newCreateProjectConfigDTO(config ProjectsDataPromptConfig, providerRepo *ap EnvVars: map[string]string{}, } - return project + return workspace } func createGetRepoContextFromRepository(providerRepo *apiclient.GitRepository) apiclient.GetRepositoryContext { diff --git a/pkg/cmd/target/util/repository_wizard.go b/pkg/cmd/target/util/repository_wizard.go index bc0987e420..5301185f8e 100644 --- a/pkg/cmd/target/util/repository_wizard.go +++ b/pkg/cmd/target/util/repository_wizard.go @@ -42,9 +42,9 @@ type RepositoryWizardConfig struct { ApiClient *apiclient.APIClient UserGitProviders []apiclient.GitProvider Manual bool - MultiProject bool + MultiWorkspace bool SkipBranchSelection bool - ProjectOrder int + WorkspaceOrder int SelectedRepos map[string]int } @@ -61,7 +61,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos } if (len(config.UserGitProviders) == 0 && len(samples) == 0) || config.Manual { - repo, err := create.GetRepositoryFromUrlInput(config.MultiProject, config.ProjectOrder, config.ApiClient, config.SelectedRepos) + repo, err := create.GetRepositoryFromUrlInput(config.MultiWorkspace, config.WorkspaceOrder, config.ApiClient, config.SelectedRepos) return repo, selection.CustomRepoIdentifier, err } @@ -84,13 +84,13 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos } } - gitProviderConfigId = selection.GetProviderIdFromPrompt(gitProviderViewList, config.ProjectOrder, len(samples) > 0) + gitProviderConfigId = selection.GetProviderIdFromPrompt(gitProviderViewList, config.WorkspaceOrder, len(samples) > 0) if gitProviderConfigId == "" { return nil, "", common.ErrCtrlCAbort } if gitProviderConfigId == selection.CustomRepoIdentifier { - repo, err := create.GetRepositoryFromUrlInput(config.MultiProject, config.ProjectOrder, config.ApiClient, config.SelectedRepos) + repo, err := create.GetRepositoryFromUrlInput(config.MultiWorkspace, config.WorkspaceOrder, config.ApiClient, config.SelectedRepos) return repo, selection.CustomRepoIdentifier, err } @@ -169,7 +169,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos CursorIndex: selectionListCursorIdx, } - namespaceId, navigate = selection.GetNamespaceIdFromPrompt(namespaceList, config.ProjectOrder, selectionListOptions) + namespaceId, navigate = selection.GetNamespaceIdFromPrompt(namespaceList, config.WorkspaceOrder, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { @@ -229,7 +229,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos } // User will either choose a repo or navigate the pages - chosenRepo, navigate = selection.GetRepositoryFromPrompt(providerRepos, config.ProjectOrder, config.SelectedRepos, selectionListOptions) + chosenRepo, navigate = selection.GetRepositoryFromPrompt(providerRepos, config.WorkspaceOrder, config.SelectedRepos, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { page++ @@ -253,7 +253,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos NamespaceId: namespaceId, Namespace: namespace, ChosenRepo: chosenRepo, - ProjectOrder: config.ProjectOrder, + WorkspaceOrder: config.WorkspaceOrder, ProviderId: providerId, }) diff --git a/pkg/cmd/target/util/target.go b/pkg/cmd/target/util/target.go index 94de8f6fb2..de394444e3 100644 --- a/pkg/cmd/target/util/target.go +++ b/pkg/cmd/target/util/target.go @@ -12,7 +12,7 @@ import ( "github.com/spf13/cobra" ) -type ProjectConfigurationFlags struct { +type WorkspaceConfigurationFlags struct { Builder *views_util.BuildChoice CustomImage *string CustomImageUser *string @@ -23,9 +23,9 @@ type ProjectConfigurationFlags struct { GitProviderConfig *string } -func AddProjectConfigurationFlags(cmd *cobra.Command, flags ProjectConfigurationFlags, multiProjectFlagException bool) { - cmd.Flags().StringVar(flags.CustomImage, "custom-image", "", "Create the project with the custom image passed as the flag value; Requires setting --custom-image-user flag as well") - cmd.Flags().StringVar(flags.CustomImageUser, "custom-image-user", "", "Create the project with the custom image user passed as the flag value; Requires setting --custom-image flag as well") +func AddWorkspaceConfigurationFlags(cmd *cobra.Command, flags WorkspaceConfigurationFlags, multiWorkspaceFlagException bool) { + cmd.Flags().StringVar(flags.CustomImage, "custom-image", "", "Create the workspace with the custom image passed as the flag value; Requires setting --custom-image-user flag as well") + cmd.Flags().StringVar(flags.CustomImageUser, "custom-image-user", "", "Create the workspace with the custom image user passed as the flag value; Requires setting --custom-image flag as well") cmd.Flags().StringVar(flags.DevcontainerPath, "devcontainer-path", "", "Automatically assign the devcontainer builder with the path passed as the flag value") cmd.Flags().Var(flags.Builder, "builder", fmt.Sprintf("Specify the builder (currently %s/%s/%s)", views_util.AUTOMATIC, views_util.DEVCONTAINER, views_util.NONE)) cmd.Flags().StringArrayVar(flags.EnvVars, "env", []string{}, "Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...')") @@ -38,36 +38,36 @@ func AddProjectConfigurationFlags(cmd *cobra.Command, flags ProjectConfiguration cmd.MarkFlagsMutuallyExclusive("devcontainer-path", "custom-image-user") cmd.MarkFlagsRequiredTogether("custom-image", "custom-image-user") - if multiProjectFlagException { - cmd.MarkFlagsMutuallyExclusive("multi-project", "custom-image") - cmd.MarkFlagsMutuallyExclusive("multi-project", "custom-image-user") - cmd.MarkFlagsMutuallyExclusive("multi-project", "devcontainer-path") - cmd.MarkFlagsMutuallyExclusive("multi-project", "builder") - cmd.MarkFlagsMutuallyExclusive("multi-project", "env") + if multiWorkspaceFlagException { + cmd.MarkFlagsMutuallyExclusive("multi-workspace", "custom-image") + cmd.MarkFlagsMutuallyExclusive("multi-workspace", "custom-image-user") + cmd.MarkFlagsMutuallyExclusive("multi-workspace", "devcontainer-path") + cmd.MarkFlagsMutuallyExclusive("multi-workspace", "builder") + cmd.MarkFlagsMutuallyExclusive("multi-workspace", "env") } } -func CheckAnyProjectConfigurationFlagSet(flags ProjectConfigurationFlags) bool { +func CheckAnyWorkspaceConfigurationFlagSet(flags WorkspaceConfigurationFlags) bool { return *flags.GitProviderConfig != "" || *flags.CustomImage != "" || *flags.CustomImageUser != "" || *flags.DevcontainerPath != "" || *flags.Builder != "" || len(*flags.EnvVars) > 0 } -func IsProjectRunning(target *apiclient.TargetDTO, projectName string) bool { - for _, project := range target.GetProjects() { - if project.GetName() == projectName { - return project.GetState().Uptime != 0 +func IsWorkspaceRunning(target *apiclient.TargetDTO, workspaceName string) bool { + for _, workspace := range target.GetWorkspaces() { + if workspace.GetName() == workspaceName { + return workspace.GetState().Uptime != 0 } } return false } -func GetProjectProviderMetadata(target *apiclient.TargetDTO, projectName string) (string, error) { +func GetWorkspaceProviderMetadata(target *apiclient.TargetDTO, workspaceName string) (string, error) { if target.Info != nil { - for _, project := range target.Info.Projects { - if project.Name == projectName { - if project.ProviderMetadata == nil { - return "", errors.New("project provider metadata is missing") + for _, workspace := range target.Info.Workspaces { + if workspace.Name == workspaceName { + if workspace.ProviderMetadata == nil { + return "", errors.New("workspace provider metadata is missing") } - return *project.ProviderMetadata, nil + return *workspace.ProviderMetadata, nil } } } diff --git a/pkg/cmd/workspaceconfig/add.go b/pkg/cmd/workspaceconfig/add.go new file mode 100644 index 0000000000..722c3d5db8 --- /dev/null +++ b/pkg/cmd/workspaceconfig/add.go @@ -0,0 +1,293 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig + +import ( + "context" + "errors" + "fmt" + "net/url" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/create" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/spf13/cobra" +) + +var workspaceConfigAddCmd = &cobra.Command{ + Use: "add", + Aliases: []string{"new", "create"}, + Short: "Add a workspace config", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + var workspaceConfig *apiclient.WorkspaceConfig + var workspaceConfigName *string + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(args) == 0 { + workspaceConfig, err = RunWorkspaceConfigAddFlow(apiClient, gitProviders, ctx) + if err != nil { + return err + } + if workspaceConfig == nil { + return nil + } + workspaceConfigName = &workspaceConfig.Name + } else { + workspaceConfigName, err = processCmdArgument(args[0], apiClient, ctx) + if err != nil { + return err + } + } + + if workspaceConfigName == nil { + return errors.New("workspace config name is required") + } + + views.RenderInfoMessage(fmt.Sprintf("Workspace config %s added successfully", *workspaceConfigName)) + return nil + }, +} + +func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.WorkspaceConfig, error) { + if target_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { + return nil, errors.New("please provide the repository URL in order to set up custom workspace config details through the CLI") + } + + var createDtos []apiclient.CreateWorkspaceDTO + existingWorkspaceConfigNames, err := getExistingWorkspaceConfigNames(apiClient) + if err != nil { + return nil, err + } + + apiServerConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + BuildChoice: views_util.AUTOMATIC, + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, + DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, + } + + createDtos, err = target_util.GetWorkspacesCreationDataFromPrompt(target_util.WorkspacesDataPromptConfig{ + UserGitProviders: gitProviders, + Manual: *workspaceConfigurationFlags.Manual, + MultiWorkspace: false, + SkipBranchSelection: true, + ApiClient: apiClient, + Defaults: workspaceDefaults, + }) + + if err != nil { + if common.IsCtrlCAbort(err) { + return nil, nil + } else { + return nil, err + } + } + + create.WorkspacesConfigurationChanged, err = create.RunWorkspaceConfiguration(&createDtos, *workspaceDefaults, false) + if err != nil { + return nil, err + } + + if len(createDtos) == 0 { + return nil, errors.New("no workspaces found") + } + + if createDtos[0].Name == "" { + return nil, errors.New("workspace config name is required") + } + + initialSuggestion := createDtos[0].Name + + chosenName := target_util.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) + + submissionFormConfig := create.SubmissionFormConfig{ + ChosenName: &chosenName, + SuggestedName: chosenName, + ExistingNames: existingWorkspaceConfigNames, + WorkspaceList: &createDtos, + NameLabel: "Workspace config", + Defaults: workspaceDefaults, + } + + err = create.RunSubmissionForm(submissionFormConfig, nil) + if err != nil { + return nil, err + } + + createWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ + Name: chosenName, + BuildConfig: createDtos[0].BuildConfig, + Image: createDtos[0].Image, + User: createDtos[0].User, + RepositoryUrl: createDtos[0].Source.Repository.Url, + EnvVars: createDtos[0].EnvVars, + GitProviderConfigId: createDtos[0].GitProviderConfigId, + } + + res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(createWorkspaceConfig).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + workspaceConfig := apiclient.WorkspaceConfig{ + BuildConfig: createWorkspaceConfig.BuildConfig, + Default: false, + EnvVars: createWorkspaceConfig.EnvVars, + Name: createWorkspaceConfig.Name, + Prebuilds: nil, + RepositoryUrl: createWorkspaceConfig.RepositoryUrl, + GitProviderConfigId: createWorkspaceConfig.GitProviderConfigId, + } + + if createWorkspaceConfig.Image != nil { + workspaceConfig.Image = *createWorkspaceConfig.Image + } + + if createWorkspaceConfig.User != nil { + workspaceConfig.User = *createWorkspaceConfig.User + } + + if createWorkspaceConfig.GitProviderConfigId == nil && *createWorkspaceConfig.GitProviderConfigId == "" { + gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(createWorkspaceConfig.RepositoryUrl)).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + workspaceConfig.GitProviderConfigId = &gitProviderConfigId + } + + return &workspaceConfig, nil +} + +func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx context.Context) (*string, error) { + if *workspaceConfigurationFlags.Builder != "" && *workspaceConfigurationFlags.Builder != views_util.DEVCONTAINER && *workspaceConfigurationFlags.DevcontainerPath != "" { + return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) + } + + apiServerConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + existingWorkspaceConfigNames, err := getExistingWorkspaceConfigNames(apiClient) + if err != nil { + return nil, err + } + + repoUrl, err := util.GetValidatedUrl(argument) + if err != nil { + return nil, err + } + + _, res, err = apiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + Url: repoUrl, + }).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + workspaceConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) + if err != nil { + return nil, err + } + + workspace, err := target_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) + if err != nil { + return nil, err + } + + var name string + if nameFlag != "" { + name = nameFlag + } else { + workspaceName := target_util.GetWorkspaceNameFromRepo(repoUrl) + name = target_util.GetSuggestedName(workspaceName, existingWorkspaceConfigNames) + } + + if workspace.GitProviderConfigId == nil || *workspace.GitProviderConfigId == "" { + gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(repoUrl)).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + *workspace.GitProviderConfigId = gitProviderConfigId + } + + newWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ + Name: name, + BuildConfig: workspace.BuildConfig, + Image: workspace.Image, + User: workspace.User, + RepositoryUrl: repoUrl, + EnvVars: workspace.EnvVars, + GitProviderConfigId: workspace.GitProviderConfigId, + } + + if newWorkspaceConfig.Image == nil { + newWorkspaceConfig.Image = &apiServerConfig.DefaultWorkspaceImage + } + + if newWorkspaceConfig.User == nil { + newWorkspaceConfig.User = &apiServerConfig.DefaultWorkspaceUser + } + + res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + return &newWorkspaceConfig.Name, nil +} + +func getExistingWorkspaceConfigNames(apiClient *apiclient.APIClient) ([]string, error) { + var existingWorkspaceConfigNames []string + + existingWorkspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + for _, wc := range existingWorkspaceConfigs { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, wc.Name) + } + + return existingWorkspaceConfigNames, nil +} + +var nameFlag string + +var workspaceConfigurationFlags = target_util.WorkspaceConfigurationFlags{ + Builder: new(views_util.BuildChoice), + CustomImage: new(string), + CustomImageUser: new(string), + Branches: new([]string), + DevcontainerPath: new(string), + EnvVars: new([]string), + Manual: new(bool), + GitProviderConfig: new(string), +} + +func init() { + workspaceConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace config name") + target_util.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) +} diff --git a/pkg/cmd/workspaceconfig/delete.go b/pkg/cmd/workspaceconfig/delete.go new file mode 100644 index 0000000000..fe89f02d58 --- /dev/null +++ b/pkg/cmd/workspaceconfig/delete.go @@ -0,0 +1,116 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig + +import ( + "context" + "fmt" + + "github.com/charmbracelet/huh" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var allFlag bool +var yesFlag bool +var forceFlag bool + +var workspaceConfigDeleteCmd = &cobra.Command{ + Use: "delete", + Aliases: []string{"remove", "rm"}, + Short: "Delete a workspace config", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + var selectedWorkspaceConfig *apiclient.WorkspaceConfig + var selectedWorkspaceConfigName string + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if allFlag { + if !yesFlag { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Delete all workspace configs?"). + Description("Are you sure you want to delete all workspace configs?"). + Value(&yesFlag), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + + if !yesFlag { + fmt.Println("Operation canceled.") + return nil + } + } + + workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceConfigs) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(false) + return nil + } + + for _, workspaceConfig := range workspaceConfigs { + selectedWorkspaceConfigName = workspaceConfig.Name + res, err := apiClient.WorkspaceConfigAPI.DeleteWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Execute() + if err != nil { + log.Error(apiclient_util.HandleErrorResponse(res, err)) + continue + } + views.RenderInfoMessage("Deleted workspace config: " + selectedWorkspaceConfigName) + } + return nil + } + + if len(args) == 0 { + workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceConfigs) == 0 { + views.RenderInfoMessage("No workspace configs found") + return nil + } + + selectedWorkspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigs, 0, false, false, "Delete") + if selectedWorkspaceConfig == nil { + return nil + } + selectedWorkspaceConfigName = selectedWorkspaceConfig.Name + } else { + selectedWorkspaceConfigName = args[0] + } + + res, err := apiClient.WorkspaceConfigAPI.DeleteWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Force(forceFlag).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + views.RenderInfoMessage("Workspace config deleted successfully") + return nil + }, +} + +func init() { + workspaceConfigDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspace configs") + workspaceConfigDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + workspaceConfigDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") +} diff --git a/pkg/cmd/projectconfig/export.go b/pkg/cmd/workspaceconfig/export.go similarity index 52% rename from pkg/cmd/projectconfig/export.go rename to pkg/cmd/workspaceconfig/export.go index 22d7d53995..647b7604ee 100644 --- a/pkg/cmd/projectconfig/export.go +++ b/pkg/cmd/workspaceconfig/export.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "context" @@ -14,18 +14,18 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) -var projectConfigExportCmd = &cobra.Command{ +var workspaceTemplateExportCmd = &cobra.Command{ Use: "export", Aliases: []string{"exp"}, - Short: "Export a project config", + Short: "Export a workspace template", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var selectedProjectConfig *apiclient.ProjectConfig + var selectedWorkspaceConfig *apiclient.WorkspaceConfig ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -34,27 +34,27 @@ var projectConfigExportCmd = &cobra.Command{ } if allFlag { - projectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(projectConfigs) == 0 { - views_util.NotifyEmptyProjectConfigList(true) + if len(workspaceConfigs) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(true) return nil } - return exportProjectConfigs(projectConfigs) + return exportWorkspaceConfigs(workspaceConfigs) } if len(args) == 0 { - projectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(projectConfigs) == 0 { - views_util.NotifyEmptyProjectConfigList(true) + if len(workspaceConfigs) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(true) return nil } @@ -62,8 +62,8 @@ var projectConfigExportCmd = &cobra.Command{ format.UnblockStdOut() } - selectedProjectConfig = selection.GetProjectConfigFromPrompt(projectConfigs, 0, false, false, "Export") - if selectedProjectConfig == nil { + selectedWorkspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigs, 0, false, false, "Export") + if selectedWorkspaceConfig == nil { return nil } @@ -72,32 +72,32 @@ var projectConfigExportCmd = &cobra.Command{ } } else { var res *http.Response - selectedProjectConfig, res, err = apiClient.ProjectConfigAPI.GetProjectConfig(ctx, args[0]).Execute() + selectedWorkspaceConfig, res, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } } - return exportProjectConfigs([]apiclient.ProjectConfig{*selectedProjectConfig}) + return exportWorkspaceConfigs([]apiclient.WorkspaceConfig{*selectedWorkspaceConfig}) }, } func init() { - projectConfigExportCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Export all project configs") - format.RegisterFormatFlag(projectConfigExportCmd) + workspaceTemplateExportCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Export all workspace templates") + format.RegisterFormatFlag(workspaceTemplateExportCmd) } -func exportProjectConfigs(projectConfigs []apiclient.ProjectConfig) error { - if len(projectConfigs) == 0 { +func exportWorkspaceConfigs(workspaceConfigs []apiclient.WorkspaceConfig) error { + if len(workspaceConfigs) == 0 { return nil } var pbFlag bool - for i := range projectConfigs { - projectConfigs[i].GitProviderConfigId = nil - if projectConfigs[i].Prebuilds != nil { - projectConfigs[i].Prebuilds = nil + for i := range workspaceConfigs { + workspaceConfigs[i].GitProviderConfigId = nil + if workspaceConfigs[i].Prebuilds != nil { + workspaceConfigs[i].Prebuilds = nil pbFlag = true } } @@ -105,22 +105,22 @@ func exportProjectConfigs(projectConfigs []apiclient.ProjectConfig) error { var data []byte var err error - if len(projectConfigs) == 1 { - data, err = json.MarshalIndent(projectConfigs[0], "", " ") - views.RenderContainerLayout("Prebuilds have been removed from the config.") + if len(workspaceConfigs) == 1 { + data, err = json.MarshalIndent(workspaceConfigs[0], "", " ") + views.RenderContainerLayout("Prebuilds have been removed from the template.") } else { - data, err = json.MarshalIndent(projectConfigs, "", " ") + data, err = json.MarshalIndent(workspaceConfigs, "", " ") if pbFlag { - views.RenderContainerLayout("Prebuilds have been removed from your configs.") + views.RenderContainerLayout("Prebuilds have been removed from your templates.") } } if format.FormatFlag != "" { - if len(projectConfigs) == 1 { - formattedData := format.NewFormatter(projectConfigs[0]) + if len(workspaceConfigs) == 1 { + formattedData := format.NewFormatter(workspaceConfigs[0]) formattedData.Print() } else { - formattedData := format.NewFormatter(projectConfigs) + formattedData := format.NewFormatter(workspaceConfigs) formattedData.Print() } return nil diff --git a/pkg/cmd/projectconfig/import.go b/pkg/cmd/workspaceconfig/import.go similarity index 61% rename from pkg/cmd/projectconfig/import.go rename to pkg/cmd/workspaceconfig/import.go index 238ab4ce6b..03dda5df5e 100644 --- a/pkg/cmd/projectconfig/import.go +++ b/pkg/cmd/workspaceconfig/import.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "context" @@ -15,18 +15,18 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/create" + "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) var filePath string -var projectConfigImportCmd = &cobra.Command{ +var workspaceTemplateImportCmd = &cobra.Command{ Use: "import", Aliases: []string{"imp"}, - Short: "Import project config from JSON", + Short: "Import workspace template from JSON", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { var inputText string @@ -37,7 +37,7 @@ var projectConfigImportCmd = &cobra.Command{ return err } - projectConfigList, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -61,8 +61,8 @@ var projectConfigImportCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewText(). - Title("Import Project-Config"). - Description("Enter Project-Config as a JSON or an array of JSON objects"). + Title("Import Workspace-Config"). + Description("Enter Workspace-Config as a JSON or an array of JSON objects"). CharLimit(-1). Value(&inputText), ), @@ -73,24 +73,24 @@ var projectConfigImportCmd = &cobra.Command{ } } - var config apiclient.ProjectConfig + var config apiclient.WorkspaceConfig err = json.Unmarshal([]byte(inputText), &config) if err == nil { - err = importProjectConfig(ctx, apiClient, config, &projectConfigList) + err = importWorkspaceConfig(ctx, apiClient, config, &workspaceConfigList) if err != nil { - return fmt.Errorf("error importing project config: %v", err) + return fmt.Errorf("error importing workspace config: %v", err) } } else { - var configs []apiclient.ProjectConfig + var configs []apiclient.WorkspaceConfig err = json.Unmarshal([]byte(inputText), &configs) if err != nil { return fmt.Errorf("invalid JSON input: %v", err) } for _, config := range configs { - err = importProjectConfig(ctx, apiClient, config, &projectConfigList) + err = importWorkspaceConfig(ctx, apiClient, config, &workspaceConfigList) if err != nil { - return fmt.Errorf("error importing project config: %v", err) + return fmt.Errorf("error importing workspace config: %v", err) } } } @@ -99,21 +99,21 @@ var projectConfigImportCmd = &cobra.Command{ } func init() { - projectConfigImportCmd.Flags().StringVarP(&filePath, "file", "f", "", "Import project config from a JSON file. Use '-' to read from stdin.") + workspaceTemplateImportCmd.Flags().StringVarP(&filePath, "file", "f", "", "Import workspace template from a JSON file. Use '-' to read from stdin.") } -func isProjectConfigAlreadyExists(configName string, projectConfigList *[]apiclient.ProjectConfig) bool { - for _, projectConfig := range *projectConfigList { - if projectConfig.Name == configName { +func isWorkspaceConfigAlreadyExists(configName string, workspaceConfigList *[]apiclient.WorkspaceConfig) bool { + for _, workspaceConfig := range *workspaceConfigList { + if workspaceConfig.Name == configName { return true } } return false } -func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, config apiclient.ProjectConfig, projectConfigList *[]apiclient.ProjectConfig) error { - if isProjectConfigAlreadyExists(config.Name, projectConfigList) { - return fmt.Errorf("project config already present with name \"%s\"", config.Name) +func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, config apiclient.WorkspaceConfig, workspaceConfigList *[]apiclient.WorkspaceConfig) error { + if isWorkspaceConfigAlreadyExists(config.Name, workspaceConfigList) { + return fmt.Errorf("workspace config already present with name \"%s\"", config.Name) } var verifiedGitProvider bool @@ -157,7 +157,7 @@ func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, co return apiclient_util.HandleErrorResponse(res, err) } - newProjectConfig := apiclient.CreateProjectConfigDTO{ + newWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ Name: config.Name, BuildConfig: config.BuildConfig, Image: &config.Image, @@ -167,15 +167,15 @@ func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, co GitProviderConfigId: config.GitProviderConfigId, } - if newProjectConfig.Image == nil { - newProjectConfig.Image = &apiServerConfig.DefaultProjectImage + if newWorkspaceConfig.Image == nil { + newWorkspaceConfig.Image = &apiServerConfig.DefaultWorkspaceImage } - if newProjectConfig.User == nil { - newProjectConfig.User = &apiServerConfig.DefaultProjectUser + if newWorkspaceConfig.User == nil { + newWorkspaceConfig.User = &apiServerConfig.DefaultWorkspaceUser } - existingProjectConfigNames, err := GetExistingProjectConfigNames(apiClient) + existingWorkspaceConfigNames, err := getExistingWorkspaceConfigNames(apiClient) if err != nil { return err } @@ -185,17 +185,17 @@ func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, co return apiclient_util.HandleErrorResponse(res, err) } - projectDefaults := &views_util.ProjectConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ BuildChoice: views_util.AUTOMATIC, - Image: &apiServerConfig.DefaultProjectImage, - ImageUser: &apiServerConfig.DefaultProjectUser, + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - createDto := []apiclient.CreateProjectDTO{ + createDto := []apiclient.CreateWorkspaceDTO{ { Name: config.Name, - Source: apiclient.CreateProjectSourceDTO{ + Source: apiclient.CreateWorkspaceSourceDTO{ Repository: apiclient.GitRepository{ Url: config.RepositoryUrl, }, @@ -206,7 +206,7 @@ func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, co }, } - create.ProjectsConfigurationChanged, err = create.RunProjectConfiguration(&createDto, *projectDefaults, true) + create.WorkspacesConfigurationChanged, err = create.RunWorkspaceConfiguration(&createDto, *workspaceDefaults, true) if err != nil { return err } @@ -214,10 +214,10 @@ func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, co submissionFormConfig := create.SubmissionFormConfig{ ChosenName: &config.Name, SuggestedName: config.Name, - ExistingNames: existingProjectConfigNames, - ProjectList: &createDto, - NameLabel: "Project config", - Defaults: projectDefaults, + ExistingNames: existingWorkspaceConfigNames, + WorkspaceList: &createDto, + NameLabel: "Workspace config", + Defaults: workspaceDefaults, } confirmation := true @@ -227,16 +227,16 @@ func importProjectConfig(ctx context.Context, apiClient *apiclient.APIClient, co } if confirmation { - res, err = apiClient.ProjectConfigAPI.SetProjectConfig(ctx).ProjectConfig(newProjectConfig).Execute() + res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - *projectConfigList = append(*projectConfigList, config) - views.RenderInfoMessage(fmt.Sprintf("Project config %s imported successfully", newProjectConfig.Name)) + *workspaceConfigList = append(*workspaceConfigList, config) + views.RenderInfoMessage(fmt.Sprintf("Workspace config %s imported successfully", newWorkspaceConfig.Name)) return nil } - views.RenderInfoMessage(fmt.Sprintf("Project config %s import cancelled", newProjectConfig.Name)) + views.RenderInfoMessage(fmt.Sprintf("Workspace config %s import cancelled", newWorkspaceConfig.Name)) return nil } diff --git a/pkg/cmd/projectconfig/info.go b/pkg/cmd/workspaceconfig/info.go similarity index 62% rename from pkg/cmd/projectconfig/info.go rename to pkg/cmd/workspaceconfig/info.go index c4254c0b3c..8f9e7d0c36 100644 --- a/pkg/cmd/projectconfig/info.go +++ b/pkg/cmd/workspaceconfig/info.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "context" @@ -10,15 +10,15 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - "github.com/daytonaio/daytona/pkg/views/projectconfig/info" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" "github.com/spf13/cobra" ) -var projectConfigInfoCmd = &cobra.Command{ +var workspaceConfigInfoCmd = &cobra.Command{ Use: "info", - Short: "Show project config info", + Short: "Show workspace config info", Aliases: []string{"view", "inspect"}, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -34,16 +34,16 @@ var projectConfigInfoCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - var projectConfig *apiclient.ProjectConfig + var workspaceConfig *apiclient.WorkspaceConfig if len(args) == 0 { - projectConfigList, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(projectConfigList) == 0 { - views_util.NotifyEmptyProjectConfigList(true) + if len(workspaceConfigList) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(true) return nil } @@ -51,34 +51,34 @@ var projectConfigInfoCmd = &cobra.Command{ format.UnblockStdOut() } - projectConfig = selection.GetProjectConfigFromPrompt(projectConfigList, 0, false, false, "View") + workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "View") if format.FormatFlag != "" { format.BlockStdOut() } } else { var res *http.Response - projectConfig, res, err = apiClient.ProjectConfigAPI.GetProjectConfig(ctx, args[0]).Execute() + workspaceConfig, res, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } } - if projectConfig == nil { + if workspaceConfig == nil { return nil } if format.FormatFlag != "" { - formattedData := format.NewFormatter(projectConfig) + formattedData := format.NewFormatter(workspaceConfig) formattedData.Print() return nil } - info.Render(projectConfig, apiServerConfig, false) + info.Render(workspaceConfig, apiServerConfig, false) return nil }, } func init() { - format.RegisterFormatFlag(projectConfigInfoCmd) + format.RegisterFormatFlag(workspaceConfigInfoCmd) } diff --git a/pkg/cmd/projectconfig/list.go b/pkg/cmd/workspaceconfig/list.go similarity index 68% rename from pkg/cmd/projectconfig/list.go rename to pkg/cmd/workspaceconfig/list.go index 34aec285c3..af4f3f036b 100644 --- a/pkg/cmd/projectconfig/list.go +++ b/pkg/cmd/workspaceconfig/list.go @@ -1,20 +1,20 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - projectconfig_view "github.com/daytonaio/daytona/pkg/views/projectconfig/list" + workspaceconfig_view "github.com/daytonaio/daytona/pkg/views/workspaceconfig/list" "github.com/spf13/cobra" ) -var projectConfigListCmd = &cobra.Command{ +var workspaceConfigListCmd = &cobra.Command{ Use: "list", - Short: "Lists project configs", + Short: "Lists workspace configs", Aliases: []string{"ls"}, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { @@ -40,22 +40,22 @@ var projectConfigListCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - projectConfigs, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(context.Background()).Execute() + workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } if format.FormatFlag != "" { - formattedData := format.NewFormatter(projectConfigs) + formattedData := format.NewFormatter(workspaceConfigs) formattedData.Print() return nil } - projectconfig_view.ListProjectConfigs(projectConfigs, apiServerConfig, specifyGitProviders) + workspaceconfig_view.ListWorkspaceConfigs(workspaceConfigs, apiServerConfig, specifyGitProviders) return nil }, } func init() { - format.RegisterFormatFlag(projectConfigListCmd) + format.RegisterFormatFlag(workspaceConfigListCmd) } diff --git a/pkg/cmd/projectconfig/setdefault.go b/pkg/cmd/workspaceconfig/setdefault.go similarity index 53% rename from pkg/cmd/projectconfig/setdefault.go rename to pkg/cmd/workspaceconfig/setdefault.go index 61cc31e311..8d1e1b7265 100644 --- a/pkg/cmd/projectconfig/setdefault.go +++ b/pkg/cmd/workspaceconfig/setdefault.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "context" @@ -14,12 +14,12 @@ import ( "github.com/spf13/cobra" ) -var projectConfigSetDefaultCmd = &cobra.Command{ +var workspaceConfigSetDefaultCmd = &cobra.Command{ Use: "set-default", - Short: "Set project config info", + Short: "Set workspace config info", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var projectConfigName string + var workspaceConfigName string ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -28,31 +28,31 @@ var projectConfigSetDefaultCmd = &cobra.Command{ } if len(args) == 0 { - projectConfigList, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(projectConfigList) == 0 { - views_util.NotifyEmptyProjectConfigList(true) + if len(workspaceConfigList) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(true) return nil } - projectConfig := selection.GetProjectConfigFromPrompt(projectConfigList, 0, false, false, "Make Default") - if projectConfig == nil { + workspaceConfig := selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "Make Default") + if workspaceConfig == nil { return nil } - projectConfigName = projectConfig.Name + workspaceConfigName = workspaceConfig.Name } else { - projectConfigName = args[0] + workspaceConfigName = args[0] } - res, err := apiClient.ProjectConfigAPI.SetDefaultProjectConfig(ctx, projectConfigName).Execute() + res, err := apiClient.WorkspaceConfigAPI.SetDefaultWorkspaceConfig(ctx, workspaceConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage(fmt.Sprintf("Project config '%s' set as default", projectConfigName)) + views.RenderInfoMessage(fmt.Sprintf("Workspace config '%s' set as default", workspaceConfigName)) return nil }, } diff --git a/pkg/cmd/projectconfig/update.go b/pkg/cmd/workspaceconfig/update.go similarity index 55% rename from pkg/cmd/projectconfig/update.go rename to pkg/cmd/workspaceconfig/update.go index 729465df27..f8d20944f1 100644 --- a/pkg/cmd/projectconfig/update.go +++ b/pkg/cmd/workspaceconfig/update.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "context" @@ -17,12 +17,12 @@ import ( "github.com/spf13/cobra" ) -var projectConfigUpdateCmd = &cobra.Command{ +var workspaceConfigUpdateCmd = &cobra.Command{ Use: "update", - Short: "Update a project config", + Short: "Update a workspace config", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var projectConfig *apiclient.ProjectConfig + var workspaceConfig *apiclient.WorkspaceConfig var res *http.Response ctx := context.Background() @@ -32,61 +32,61 @@ var projectConfigUpdateCmd = &cobra.Command{ } if len(args) == 0 { - projectConfigList, res, err := apiClient.ProjectConfigAPI.ListProjectConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(projectConfigList) == 0 { - views_util.NotifyEmptyProjectConfigList(true) + if len(workspaceConfigList) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(true) return nil } - projectConfig = selection.GetProjectConfigFromPrompt(projectConfigList, 0, false, false, "Update") - if projectConfig == nil { + workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "Update") + if workspaceConfig == nil { return nil } } else { - projectConfig, res, err = apiClient.ProjectConfigAPI.GetProjectConfig(ctx, args[0]).Execute() + workspaceConfig, res, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } } - if projectConfig == nil { + if workspaceConfig == nil { return nil } - createDto := []apiclient.CreateProjectDTO{ + createDto := []apiclient.CreateWorkspaceDTO{ { - Name: projectConfig.Name, - Source: apiclient.CreateProjectSourceDTO{ + Name: workspaceConfig.Name, + Source: apiclient.CreateWorkspaceSourceDTO{ Repository: apiclient.GitRepository{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, }, }, - BuildConfig: projectConfig.BuildConfig, - EnvVars: projectConfig.EnvVars, - GitProviderConfigId: projectConfig.GitProviderConfigId, + BuildConfig: workspaceConfig.BuildConfig, + EnvVars: workspaceConfig.EnvVars, + GitProviderConfigId: workspaceConfig.GitProviderConfigId, }, } - projectDefaults := &views_util.ProjectConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ BuildChoice: views_util.AUTOMATIC, - Image: &projectConfig.Image, - ImageUser: &projectConfig.User, + Image: &workspaceConfig.Image, + ImageUser: &workspaceConfig.User, } - if projectConfig.BuildConfig != nil && projectConfig.BuildConfig.Devcontainer != nil { - projectDefaults.DevcontainerFilePath = projectConfig.BuildConfig.Devcontainer.FilePath + if workspaceConfig.BuildConfig != nil && workspaceConfig.BuildConfig.Devcontainer != nil { + workspaceDefaults.DevcontainerFilePath = workspaceConfig.BuildConfig.Devcontainer.FilePath } - _, err = create.RunProjectConfiguration(&createDto, *projectDefaults, false) + _, err = create.RunWorkspaceConfiguration(&createDto, *workspaceDefaults, false) if err != nil { return err } - eligibleGitProviders, res, err := apiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(projectConfig.RepositoryUrl)).Execute() + eligibleGitProviders, res, err := apiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(workspaceConfig.RepositoryUrl)).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -96,7 +96,7 @@ var projectConfigUpdateCmd = &cobra.Command{ GitProviderConfigs: eligibleGitProviders, ActionVerb: "Use", WithNoneOption: true, - PreselectedGitProviderId: projectConfig.GitProviderConfigId, + PreselectedGitProviderId: workspaceConfig.GitProviderConfigId, }) if selectedGitProvider == nil { @@ -110,8 +110,8 @@ var projectConfigUpdateCmd = &cobra.Command{ } } - newProjectConfig := apiclient.CreateProjectConfigDTO{ - Name: projectConfig.Name, + newWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ + Name: workspaceConfig.Name, BuildConfig: createDto[0].BuildConfig, Image: createDto[0].Image, User: createDto[0].User, @@ -120,12 +120,12 @@ var projectConfigUpdateCmd = &cobra.Command{ GitProviderConfigId: createDto[0].GitProviderConfigId, } - res, err = apiClient.ProjectConfigAPI.SetProjectConfig(ctx).ProjectConfig(newProjectConfig).Execute() + res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage("Project config updated successfully") + views.RenderInfoMessage("Workspace config updated successfully") return nil }, } diff --git a/pkg/cmd/workspaceconfig/workspaceconfig.go b/pkg/cmd/workspaceconfig/workspaceconfig.go new file mode 100644 index 0000000000..1a8dd79267 --- /dev/null +++ b/pkg/cmd/workspaceconfig/workspaceconfig.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig + +import ( + "github.com/daytonaio/daytona/internal/util" + "github.com/spf13/cobra" +) + +var WorkspaceConfigCmd = &cobra.Command{ + Use: "workspace-config", + Short: "Manage workspace configs", + Aliases: []string{"wc"}, + GroupID: util.TARGET_GROUP, +} + +func init() { + WorkspaceConfigCmd.AddCommand(workspaceConfigListCmd) + WorkspaceConfigCmd.AddCommand(workspaceConfigInfoCmd) + WorkspaceConfigCmd.AddCommand(workspaceConfigAddCmd) + WorkspaceConfigCmd.AddCommand(workspaceConfigUpdateCmd) + WorkspaceConfigCmd.AddCommand(workspaceConfigSetDefaultCmd) + WorkspaceConfigCmd.AddCommand(workspaceConfigDeleteCmd) + WorkspaceConfigCmd.AddCommand(workspaceTemplateExportCmd) + WorkspaceConfigCmd.AddCommand(workspaceTemplateImportCmd) +} diff --git a/pkg/common/get_daytona_script.go b/pkg/common/get_daytona_script.go index b42c02b73d..7baaad64bd 100644 --- a/pkg/common/get_daytona_script.go +++ b/pkg/common/get_daytona_script.go @@ -34,7 +34,7 @@ try_download() { curl -fsSL "$url" -H "Authorization: Bearer $DAYTONA_SERVER_API_KEY" -o "$temp_file" && return 0 exit_code=$? else - echo "error: Make sure curl or wget is available in the project container" + echo "error: Make sure curl or wget is available in the workspace container" exit 127 fi >&2 echo "error: Daytona binary download failed. Exit Code: ${exit_code}" diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index d132073ea4..7087b7fe90 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" "gorm.io/gorm" ) diff --git a/pkg/db/dto/build.go b/pkg/db/dto/build.go index b1a08e29e3..54ea9b78b5 100644 --- a/pkg/db/dto/build.go +++ b/pkg/db/dto/build.go @@ -7,7 +7,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/target/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" ) type BuildDTO struct { @@ -16,7 +16,7 @@ type BuildDTO struct { Image *string `json:"image,omitempty"` User *string `json:"user,omitempty"` ContainerConfig containerconfig.ContainerConfig `gorm:"serializer:json"` - BuildConfig *ProjectBuildDTO `json:"build,omitempty" gorm:"serializer:json"` + BuildConfig *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` Repository RepositoryDTO `gorm:"serializer:json"` EnvVars map[string]string `json:"envVars" gorm:"serializer:json"` PrebuildId string `json:"prebuildId"` @@ -31,7 +31,7 @@ func ToBuildDTO(build *build.Build) BuildDTO { Image: build.Image, User: build.User, ContainerConfig: build.ContainerConfig, - BuildConfig: ToProjectBuildDTO(build.BuildConfig), + BuildConfig: ToWorkspaceBuildDTO(build.BuildConfig), Repository: ToRepositoryDTO(build.Repository), EnvVars: build.EnvVars, PrebuildId: build.PrebuildId, @@ -47,7 +47,7 @@ func ToBuild(buildDTO BuildDTO) *build.Build { Image: buildDTO.Image, User: buildDTO.User, ContainerConfig: buildDTO.ContainerConfig, - BuildConfig: ToProjectBuild(buildDTO.BuildConfig), + BuildConfig: ToWorkspaceBuild(buildDTO.BuildConfig), Repository: ToRepository(buildDTO.Repository), EnvVars: buildDTO.EnvVars, PrebuildId: buildDTO.PrebuildId, diff --git a/pkg/db/dto/project_config.go b/pkg/db/dto/project_config.go deleted file mode 100644 index 2051570521..0000000000 --- a/pkg/db/dto/project_config.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/target/project/config" -) - -type ProjectConfigDTO struct { - Name string `gorm:"primaryKey"` - Image string `json:"image"` - User string `json:"user"` - Build *ProjectBuildDTO `json:"build,omitempty" gorm:"serializer:json"` - RepositoryUrl string `json:"repositoryUrl"` - EnvVars map[string]string `json:"envVars" gorm:"serializer:json"` - Prebuilds []PrebuildDTO `gorm:"serializer:json"` - IsDefault bool `json:"isDefault"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} - -type PrebuildDTO struct { - Id string `json:"id"` - Branch string `json:"branch"` - CommitInterval *int `json:"commitInterval,omitempty"` - TriggerFiles []string `json:"triggerFiles,omitempty"` - Retention int `json:"retention"` -} - -func ToProjectConfigDTO(projectConfig *config.ProjectConfig) ProjectConfigDTO { - prebuilds := []PrebuildDTO{} - for _, prebuild := range projectConfig.Prebuilds { - prebuilds = append(prebuilds, ToPrebuildDTO(prebuild)) - } - - return ProjectConfigDTO{ - Name: projectConfig.Name, - Image: projectConfig.Image, - User: projectConfig.User, - Build: ToProjectBuildDTO(projectConfig.BuildConfig), - RepositoryUrl: projectConfig.RepositoryUrl, - EnvVars: projectConfig.EnvVars, - Prebuilds: prebuilds, - IsDefault: projectConfig.IsDefault, - GitProviderConfigId: projectConfig.GitProviderConfigId, - } -} - -func ToProjectConfig(projectConfigDTO ProjectConfigDTO) *config.ProjectConfig { - prebuilds := []*config.PrebuildConfig{} - for _, prebuildDTO := range projectConfigDTO.Prebuilds { - prebuilds = append(prebuilds, ToPrebuild(prebuildDTO)) - } - - return &config.ProjectConfig{ - Name: projectConfigDTO.Name, - Image: projectConfigDTO.Image, - User: projectConfigDTO.User, - BuildConfig: ToProjectBuild(projectConfigDTO.Build), - RepositoryUrl: projectConfigDTO.RepositoryUrl, - EnvVars: projectConfigDTO.EnvVars, - Prebuilds: prebuilds, - IsDefault: projectConfigDTO.IsDefault, - GitProviderConfigId: projectConfigDTO.GitProviderConfigId, - } -} - -func ToPrebuildDTO(prebuild *config.PrebuildConfig) PrebuildDTO { - return PrebuildDTO{ - Id: prebuild.Id, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, - } -} - -func ToPrebuild(prebuildDTO PrebuildDTO) *config.PrebuildConfig { - return &config.PrebuildConfig{ - Id: prebuildDTO.Id, - Branch: prebuildDTO.Branch, - CommitInterval: prebuildDTO.CommitInterval, - TriggerFiles: prebuildDTO.TriggerFiles, - Retention: prebuildDTO.Retention, - } -} diff --git a/pkg/db/dto/target.go b/pkg/db/dto/target.go index 7918c954d5..f5b4d37267 100644 --- a/pkg/db/dto/target.go +++ b/pkg/db/dto/target.go @@ -10,21 +10,21 @@ import ( ) type TargetDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name" gorm:"unique"` - TargetConfig string `json:"config"` - ApiKey string `json:"apiKey"` - Projects []ProjectDTO `gorm:"serializer:json"` + Id string `gorm:"primaryKey"` + Name string `json:"name" gorm:"unique"` + TargetConfig string `json:"config"` + ApiKey string `json:"apiKey"` + Workspaces []WorkspaceDTO `gorm:"serializer:json"` } -func (w TargetDTO) GetProject(name string) (*ProjectDTO, error) { - for _, project := range w.Projects { - if project.Name == name { - return &project, nil +func (w TargetDTO) GetWorkspace(name string) (*WorkspaceDTO, error) { + for _, workspace := range w.Workspaces { + if workspace.Name == name { + return &workspace, nil } } - return nil, errors.New("project not found") + return nil, errors.New("workspace not found") } func ToTargetDTO(target *target.Target) TargetDTO { @@ -35,8 +35,8 @@ func ToTargetDTO(target *target.Target) TargetDTO { ApiKey: target.ApiKey, } - for _, project := range target.Projects { - targetDTO.Projects = append(targetDTO.Projects, ToProjectDTO(project)) + for _, workspace := range target.Workspaces { + targetDTO.Workspaces = append(targetDTO.Workspaces, ToWorkspaceDTO(workspace)) } return targetDTO @@ -50,8 +50,8 @@ func ToTarget(targetDTO TargetDTO) *target.Target { ApiKey: targetDTO.ApiKey, } - for _, projectDTO := range targetDTO.Projects { - target.Projects = append(target.Projects, ToProject(projectDTO)) + for _, workspaceDTO := range targetDTO.Workspaces { + target.Workspaces = append(target.Workspaces, ToWorkspace(workspaceDTO)) } return &target diff --git a/pkg/db/dto/project.go b/pkg/db/dto/workspace.go similarity index 55% rename from pkg/db/dto/project.go rename to pkg/db/dto/workspace.go index d6c05a27dc..552070656e 100644 --- a/pkg/db/dto/project.go +++ b/pkg/db/dto/workspace.go @@ -5,8 +5,8 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) type RepositoryDTO struct { @@ -37,45 +37,45 @@ type GitStatusDTO struct { Behind int32 `json:"behind,omitempty"` } -type ProjectStateDTO struct { +type WorkspaceStateDTO struct { UpdatedAt string `json:"updatedAt"` Uptime uint64 `json:"uptime"` GitStatus *GitStatusDTO `json:"gitStatus"` } -type ProjectBuildDevcontainerDTO struct { +type WorkspaceBuildDevcontainerDTO struct { FilePath string `json:"filePath"` } -type ProjectBuildDTO struct { - Devcontainer *ProjectBuildDevcontainerDTO `json:"devcontainer"` +type WorkspaceBuildDTO struct { + Devcontainer *WorkspaceBuildDevcontainerDTO `json:"devcontainer"` } -type ProjectDTO struct { - Name string `json:"name"` - Image string `json:"image"` - User string `json:"user"` - Build *ProjectBuildDTO `json:"build,omitempty" gorm:"serializer:json"` - Repository RepositoryDTO `json:"repository" gorm:"serializer:json"` - TargetId string `json:"targetId"` - TargetConfig string `json:"targetConfig"` - ApiKey string `json:"apiKey"` - State *ProjectStateDTO `json:"state,omitempty" gorm:"serializer:json"` - GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` +type WorkspaceDTO struct { + Name string `json:"name"` + Image string `json:"image"` + User string `json:"user"` + Build *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` + Repository RepositoryDTO `json:"repository" gorm:"serializer:json"` + TargetId string `json:"targetId"` + TargetConfig string `json:"targetConfig"` + ApiKey string `json:"apiKey"` + State *WorkspaceStateDTO `json:"state,omitempty" gorm:"serializer:json"` + GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` } -func ToProjectDTO(project *project.Project) ProjectDTO { - return ProjectDTO{ - Name: project.Name, - Image: project.Image, - User: project.User, - Build: ToProjectBuildDTO(project.BuildConfig), - Repository: ToRepositoryDTO(project.Repository), - TargetId: project.TargetId, - TargetConfig: project.TargetConfig, - State: ToProjectStateDTO(project.State), - ApiKey: project.ApiKey, - GitProviderConfigId: project.GitProviderConfigId, +func ToWorkspaceDTO(workspace *workspace.Workspace) WorkspaceDTO { + return WorkspaceDTO{ + Name: workspace.Name, + Image: workspace.Image, + User: workspace.User, + Build: ToWorkspaceBuildDTO(workspace.BuildConfig), + Repository: ToRepositoryDTO(workspace.Repository), + TargetId: workspace.TargetId, + TargetConfig: workspace.TargetConfig, + State: ToWorkspaceStateDTO(workspace.State), + ApiKey: workspace.ApiKey, + GitProviderConfigId: workspace.GitProviderConfigId, } } @@ -96,7 +96,7 @@ func ToRepositoryDTO(repo *gitprovider.GitRepository) RepositoryDTO { return repoDTO } -func ToFileStatusDTO(status *project.FileStatus) *FileStatusDTO { +func ToFileStatusDTO(status *workspace.FileStatus) *FileStatusDTO { if status == nil { return nil } @@ -109,7 +109,7 @@ func ToFileStatusDTO(status *project.FileStatus) *FileStatusDTO { } } -func ToGitStatusDTO(status *project.GitStatus) *GitStatusDTO { +func ToGitStatusDTO(status *workspace.GitStatus) *GitStatusDTO { if status == nil { return nil } @@ -128,68 +128,68 @@ func ToGitStatusDTO(status *project.GitStatus) *GitStatusDTO { return statusDTO } -func ToProjectStateDTO(state *project.ProjectState) *ProjectStateDTO { +func ToWorkspaceStateDTO(state *workspace.WorkspaceState) *WorkspaceStateDTO { if state == nil { return nil } - return &ProjectStateDTO{ + return &WorkspaceStateDTO{ UpdatedAt: state.UpdatedAt, Uptime: state.Uptime, GitStatus: ToGitStatusDTO(state.GitStatus), } } -func ToProjectBuildDTO(build *buildconfig.BuildConfig) *ProjectBuildDTO { +func ToWorkspaceBuildDTO(build *buildconfig.BuildConfig) *WorkspaceBuildDTO { if build == nil { return nil } if build.Devcontainer == nil { - return &ProjectBuildDTO{} + return &WorkspaceBuildDTO{} } - return &ProjectBuildDTO{ - Devcontainer: &ProjectBuildDevcontainerDTO{ + return &WorkspaceBuildDTO{ + Devcontainer: &WorkspaceBuildDevcontainerDTO{ FilePath: build.Devcontainer.FilePath, }, } } -func ToProject(projectDTO ProjectDTO) *project.Project { - return &project.Project{ - Name: projectDTO.Name, - Image: projectDTO.Image, - User: projectDTO.User, - BuildConfig: ToProjectBuild(projectDTO.Build), - Repository: ToRepository(projectDTO.Repository), - TargetId: projectDTO.TargetId, - TargetConfig: projectDTO.TargetConfig, - State: ToProjectState(projectDTO.State), - ApiKey: projectDTO.ApiKey, - GitProviderConfigId: projectDTO.GitProviderConfigId, +func ToWorkspace(workspaceDTO WorkspaceDTO) *workspace.Workspace { + return &workspace.Workspace{ + Name: workspaceDTO.Name, + Image: workspaceDTO.Image, + User: workspaceDTO.User, + BuildConfig: ToWorkspaceBuild(workspaceDTO.Build), + Repository: ToRepository(workspaceDTO.Repository), + TargetId: workspaceDTO.TargetId, + TargetConfig: workspaceDTO.TargetConfig, + State: ToWorkspaceState(workspaceDTO.State), + ApiKey: workspaceDTO.ApiKey, + GitProviderConfigId: workspaceDTO.GitProviderConfigId, } } -func ToFileStatus(statusDTO *FileStatusDTO) *project.FileStatus { +func ToFileStatus(statusDTO *FileStatusDTO) *workspace.FileStatus { if statusDTO == nil { return nil } - return &project.FileStatus{ + return &workspace.FileStatus{ Name: statusDTO.Name, Extra: statusDTO.Extra, - Staging: project.Status(statusDTO.Staging), - Worktree: project.Status(statusDTO.Worktree), + Staging: workspace.Status(statusDTO.Staging), + Worktree: workspace.Status(statusDTO.Worktree), } } -func ToGitStatus(statusDTO *GitStatusDTO) *project.GitStatus { +func ToGitStatus(statusDTO *GitStatusDTO) *workspace.GitStatus { if statusDTO == nil { return nil } - status := &project.GitStatus{ + status := &workspace.GitStatus{ CurrentBranch: statusDTO.CurrentBranch, BranchPublished: statusDTO.BranchPublished, Ahead: int(statusDTO.Ahead), @@ -203,12 +203,12 @@ func ToGitStatus(statusDTO *GitStatusDTO) *project.GitStatus { return status } -func ToProjectState(stateDTO *ProjectStateDTO) *project.ProjectState { +func ToWorkspaceState(stateDTO *WorkspaceStateDTO) *workspace.WorkspaceState { if stateDTO == nil { return nil } - return &project.ProjectState{ + return &workspace.WorkspaceState{ UpdatedAt: stateDTO.UpdatedAt, Uptime: stateDTO.Uptime, GitStatus: ToGitStatus(stateDTO.GitStatus), @@ -232,7 +232,7 @@ func ToRepository(repoDTO RepositoryDTO) *gitprovider.GitRepository { return &repo } -func ToProjectBuild(buildDTO *ProjectBuildDTO) *buildconfig.BuildConfig { +func ToWorkspaceBuild(buildDTO *WorkspaceBuildDTO) *buildconfig.BuildConfig { if buildDTO == nil { return nil } diff --git a/pkg/db/dto/workspace_config.go b/pkg/db/dto/workspace_config.go new file mode 100644 index 0000000000..14422b59c2 --- /dev/null +++ b/pkg/db/dto/workspace_config.go @@ -0,0 +1,86 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import ( + "github.com/daytonaio/daytona/pkg/target/workspace/config" +) + +type WorkspaceConfigDTO struct { + Name string `gorm:"primaryKey"` + Image string `json:"image"` + User string `json:"user"` + Build *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` + RepositoryUrl string `json:"repositoryUrl"` + EnvVars map[string]string `json:"envVars" gorm:"serializer:json"` + Prebuilds []PrebuildDTO `gorm:"serializer:json"` + IsDefault bool `json:"isDefault"` + GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` +} + +type PrebuildDTO struct { + Id string `json:"id"` + Branch string `json:"branch"` + CommitInterval *int `json:"commitInterval,omitempty"` + TriggerFiles []string `json:"triggerFiles,omitempty"` + Retention int `json:"retention"` +} + +func ToWorkspaceConfigDTO(workspaceConfig *config.WorkspaceConfig) WorkspaceConfigDTO { + prebuilds := []PrebuildDTO{} + for _, prebuild := range workspaceConfig.Prebuilds { + prebuilds = append(prebuilds, ToPrebuildDTO(prebuild)) + } + + return WorkspaceConfigDTO{ + Name: workspaceConfig.Name, + Image: workspaceConfig.Image, + User: workspaceConfig.User, + Build: ToWorkspaceBuildDTO(workspaceConfig.BuildConfig), + RepositoryUrl: workspaceConfig.RepositoryUrl, + EnvVars: workspaceConfig.EnvVars, + Prebuilds: prebuilds, + IsDefault: workspaceConfig.IsDefault, + GitProviderConfigId: workspaceConfig.GitProviderConfigId, + } +} + +func ToWorkspaceConfig(workspaceConfigDTO WorkspaceConfigDTO) *config.WorkspaceConfig { + prebuilds := []*config.PrebuildConfig{} + for _, prebuildDTO := range workspaceConfigDTO.Prebuilds { + prebuilds = append(prebuilds, ToPrebuild(prebuildDTO)) + } + + return &config.WorkspaceConfig{ + Name: workspaceConfigDTO.Name, + Image: workspaceConfigDTO.Image, + User: workspaceConfigDTO.User, + BuildConfig: ToWorkspaceBuild(workspaceConfigDTO.Build), + RepositoryUrl: workspaceConfigDTO.RepositoryUrl, + EnvVars: workspaceConfigDTO.EnvVars, + Prebuilds: prebuilds, + IsDefault: workspaceConfigDTO.IsDefault, + GitProviderConfigId: workspaceConfigDTO.GitProviderConfigId, + } +} + +func ToPrebuildDTO(prebuild *config.PrebuildConfig) PrebuildDTO { + return PrebuildDTO{ + Id: prebuild.Id, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, + } +} + +func ToPrebuild(prebuildDTO PrebuildDTO) *config.PrebuildConfig { + return &config.PrebuildConfig{ + Id: prebuildDTO.Id, + Branch: prebuildDTO.Branch, + CommitInterval: prebuildDTO.CommitInterval, + TriggerFiles: prebuildDTO.TriggerFiles, + Retention: prebuildDTO.Retention, + } +} diff --git a/pkg/db/project_config_store.go b/pkg/db/project_config_store.go deleted file mode 100644 index df9ce01e87..0000000000 --- a/pkg/db/project_config_store.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "gorm.io/gorm" - - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" -) - -type ProjectConfigStore struct { - db *gorm.DB -} - -func NewProjectConfigStore(db *gorm.DB) (*ProjectConfigStore, error) { - err := db.AutoMigrate(&ProjectConfigDTO{}) - if err != nil { - return nil, err - } - - return &ProjectConfigStore{db: db}, nil -} - -func (s *ProjectConfigStore) List(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) { - projectConfigsDTOs := []ProjectConfigDTO{} - tx := processProjectConfigFilters(s.db, filter).Find(&projectConfigsDTOs) - - if tx.Error != nil { - return nil, tx.Error - } - - projectConfigs := []*config.ProjectConfig{} - for _, projectConfigDTO := range projectConfigsDTOs { - projectConfigs = append(projectConfigs, ToProjectConfig(projectConfigDTO)) - } - - return projectConfigs, nil -} - -func (s *ProjectConfigStore) Find(filter *config.ProjectConfigFilter) (*config.ProjectConfig, error) { - projectConfigDTO := ProjectConfigDTO{} - tx := processProjectConfigFilters(s.db, filter).First(&projectConfigDTO) - - if tx.Error != nil { - if IsRecordNotFound(tx.Error) { - return nil, config.ErrProjectConfigNotFound - } - return nil, tx.Error - } - - return ToProjectConfig(projectConfigDTO), nil -} - -func (s *ProjectConfigStore) Save(projectConfig *config.ProjectConfig) error { - tx := s.db.Save(ToProjectConfigDTO(projectConfig)) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (s *ProjectConfigStore) Delete(projectConfig *config.ProjectConfig) error { - tx := s.db.Delete(ToProjectConfigDTO(projectConfig)) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return config.ErrProjectConfigNotFound - } - - return nil -} - -func processProjectConfigFilters(tx *gorm.DB, filter *config.ProjectConfigFilter) *gorm.DB { - if filter != nil { - if filter.Name != nil { - tx = tx.Where("name = ?", *filter.Name) - } - if filter.Url != nil { - tx = tx.Where("repository_url = ?", *filter.Url) - } - if filter.Default != nil { - tx = tx.Where("is_default = ?", *filter.Default) - } - if filter.GitProviderConfigId != nil { - tx = tx.Where("git_provider_config_id = ?", *filter.GitProviderConfigId) - } - } - - return tx -} diff --git a/pkg/db/workspace_config_store.go b/pkg/db/workspace_config_store.go new file mode 100644 index 0000000000..eb2d3edbe1 --- /dev/null +++ b/pkg/db/workspace_config_store.go @@ -0,0 +1,94 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + + . "github.com/daytonaio/daytona/pkg/db/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" +) + +type WorkspaceConfigStore struct { + db *gorm.DB +} + +func NewWorkspaceConfigStore(db *gorm.DB) (*WorkspaceConfigStore, error) { + err := db.AutoMigrate(&WorkspaceConfigDTO{}) + if err != nil { + return nil, err + } + + return &WorkspaceConfigStore{db: db}, nil +} + +func (s *WorkspaceConfigStore) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { + workspaceConfigDTOs := []WorkspaceConfigDTO{} + tx := processWorkspaceConfigFilters(s.db, filter).Find(&workspaceConfigDTOs) + + if tx.Error != nil { + return nil, tx.Error + } + + workspaceConfigs := []*config.WorkspaceConfig{} + for _, workspaceConfigDTO := range workspaceConfigDTOs { + workspaceConfigs = append(workspaceConfigs, ToWorkspaceConfig(workspaceConfigDTO)) + } + + return workspaceConfigs, nil +} + +func (s *WorkspaceConfigStore) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { + workspaceConfigDTO := WorkspaceConfigDTO{} + tx := processWorkspaceConfigFilters(s.db, filter).First(&workspaceConfigDTO) + + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, config.ErrWorkspaceConfigNotFound + } + return nil, tx.Error + } + + return ToWorkspaceConfig(workspaceConfigDTO), nil +} + +func (s *WorkspaceConfigStore) Save(workspaceConfig *config.WorkspaceConfig) error { + tx := s.db.Save(ToWorkspaceConfigDTO(workspaceConfig)) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *WorkspaceConfigStore) Delete(workspaceConfig *config.WorkspaceConfig) error { + tx := s.db.Delete(ToWorkspaceConfigDTO(workspaceConfig)) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return config.ErrWorkspaceConfigNotFound + } + + return nil +} + +func processWorkspaceConfigFilters(tx *gorm.DB, filter *config.WorkspaceConfigFilter) *gorm.DB { + if filter != nil { + if filter.Name != nil { + tx = tx.Where("name = ?", *filter.Name) + } + if filter.Url != nil { + tx = tx.Where("repository_url = ?", *filter.Url) + } + if filter.Default != nil { + tx = tx.Where("is_default = ?", *filter.Default) + } + if filter.GitProviderConfigId != nil { + tx = tx.Where("git_provider_config_id = ?", *filter.GitProviderConfigId) + } + } + + return tx +} diff --git a/pkg/docker/README.md b/pkg/docker/README.md index c8ebdbf555..19ab403f07 100644 --- a/pkg/docker/README.md +++ b/pkg/docker/README.md @@ -1,7 +1,7 @@ ## Package Purpose -The purpose of the `docker` package is to provide a single library that providers can use to easily create targets and projects. -Most providers will import the package and call commands from the `DockerClient` in order to create targets and projects on provided targets. +The purpose of the `docker` package is to provide a single library that providers can use to easily create targets and workspaces. +Most providers will import the package and call commands from the `DockerClient` in order to create targets and workspaces on provided targets. ## Usage diff --git a/pkg/docker/client.go b/pkg/docker/client.go index ea9d8eda11..ccf99ba066 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -12,16 +12,16 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/ssh" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" ) -type CreateProjectOptions struct { - Project *project.Project - ProjectDir string +type CreateWorkspaceOptions struct { + Workspace *workspace.Workspace + WorkspaceDir string ContainerRegistry *containerregistry.ContainerRegistry LogWriter io.Writer Gpc *gitprovider.GitProviderConfig @@ -31,20 +31,20 @@ type CreateProjectOptions struct { } type IDockerClient interface { - CreateProject(opts *CreateProjectOptions) error + CreateWorkspace(opts *CreateWorkspaceOptions) error CreateTarget(target *target.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error - DestroyProject(project *project.Project, projectDir string, sshClient *ssh.Client) error + DestroyWorkspace(workspace *workspace.Workspace, workspaceDir string, sshClient *ssh.Client) error DestroyTarget(target *target.Target, targetDir string, sshClient *ssh.Client) error - StartProject(opts *CreateProjectOptions, daytonaDownloadUrl string) error - StopProject(project *project.Project, logWriter io.Writer) error + StartWorkspace(opts *CreateWorkspaceOptions, daytonaDownloadUrl string) error + StopWorkspace(workspace *workspace.Workspace, logWriter io.Writer) error - GetProjectInfo(project *project.Project) (*project.ProjectInfo, error) - GetTargetInfo(ws *target.Target) (*target.TargetInfo, error) + GetWorkspaceInfo(workspace *workspace.Workspace) (*workspace.WorkspaceInfo, error) + GetTargetInfo(t *target.Target) (*target.TargetInfo, error) - GetProjectContainerName(project *project.Project) string - GetProjectVolumeName(project *project.Project) string + GetWorkspaceContainerName(workspace *workspace.Workspace) string + GetWorkspaceVolumeName(workspace *workspace.Workspace) string ExecSync(containerID string, config container.ExecOptions, outputWriter io.Writer) (*ExecResult, error) GetContainerLogs(containerName string, logWriter io.Writer) error PullImage(imageName string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error @@ -69,29 +69,29 @@ type DockerClient struct { apiClient client.APIClient } -func (d *DockerClient) GetProjectContainerName(project *project.Project) string { +func (d *DockerClient) GetWorkspaceContainerName(workspace *workspace.Workspace) string { containers, err := d.apiClient.ContainerList(context.Background(), container.ListOptions{ - Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.target.id=%s", project.TargetId)), filters.Arg("label", fmt.Sprintf("daytona.project.name=%s", project.Name))), + Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.target.id=%s", workspace.TargetId)), filters.Arg("label", fmt.Sprintf("daytona.workspace.name=%s", workspace.Name))), All: true, }) if err != nil || len(containers) == 0 { - return project.TargetId + "-" + project.Name + return workspace.TargetId + "-" + workspace.Name } return containers[0].ID } -func (d *DockerClient) GetProjectVolumeName(project *project.Project) string { - return project.TargetId + "-" + project.Name +func (d *DockerClient) GetWorkspaceVolumeName(workspace *workspace.Workspace) string { + return workspace.TargetId + "-" + workspace.Name } func (d *DockerClient) getComposeContainers(c types.ContainerJSON) (string, []types.Container, error) { ctx := context.Background() for k, v := range c.Config.Labels { - if k == "com.docker.compose.project" { + if k == "com.docker.compose.workspace" { containers, err := d.apiClient.ContainerList(ctx, container.ListOptions{ - Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("com.docker.compose.project=%s", v))), + Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("com.docker.compose.workspace=%s", v))), }) return v, containers, err } diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index 24021cc1c0..93706f61bb 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -10,12 +10,12 @@ import ( "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" "github.com/stretchr/testify/suite" ) -var project1 = &project.Project{ +var workspace1 = &workspace.Workspace{ Name: "test", Repository: &gitprovider.GitRepository{ Id: "123", @@ -33,8 +33,8 @@ var target1 = &target.Target{ Id: "123", Name: "test", TargetConfig: "local", - Projects: []*project.Project{ - project1, + Workspaces: []*workspace.Workspace{ + workspace1, }, } diff --git a/pkg/docker/container_logs_test.go b/pkg/docker/container_logs_test.go index 04c2855aba..da50705e09 100644 --- a/pkg/docker/container_logs_test.go +++ b/pkg/docker/container_logs_test.go @@ -17,7 +17,7 @@ import ( func (s *DockerClientTestSuite) TestGetContainerLogs() { s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) logWriter := io.MultiWriter(&util.DebugLogWriter{}) s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(types.ContainerJSON{ diff --git a/pkg/docker/create.go b/pkg/docker/create.go index 35ce258b93..a19de2fb7b 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -35,24 +35,24 @@ func (d *DockerClient) CreateTarget(target *target.Target, targetDir string, log return err } -func (d *DockerClient) CreateProject(opts *CreateProjectOptions) error { - // pulledImages map keeps track of pulled images for project creation in order to avoid pulling the same image multiple times +func (d *DockerClient) CreateWorkspace(opts *CreateWorkspaceOptions) error { + // pulledImages map keeps track of pulled images for workspace creation in order to avoid pulling the same image multiple times // This is only an optimisation for images with tag 'latest' pulledImages := map[string]bool{} - if opts.Project.BuildConfig != nil { + if opts.Workspace.BuildConfig != nil { err := d.PullImage(opts.BuilderImage, opts.BuilderContainerRegistry, opts.LogWriter) if err != nil { return err } pulledImages[opts.BuilderImage] = true - err = d.cloneProjectRepository(opts) + err = d.cloneWorkspaceRepository(opts) if err != nil { return err } - builderType, err := detect.DetectProjectBuilderType(opts.Project.BuildConfig, opts.ProjectDir, opts.SshClient) + builderType, err := detect.DetectWorkspaceBuilderType(opts.Workspace.BuildConfig, opts.WorkspaceDir, opts.SshClient) if err != nil { return err } @@ -62,25 +62,25 @@ func (d *DockerClient) CreateProject(opts *CreateProjectOptions) error { _, _, err := d.CreateFromDevcontainer(d.toCreateDevcontainerOptions(opts, true)) return err case detect.BuilderTypeImage: - return d.createProjectFromImage(opts, pulledImages, true) + return d.createWorkspaceFromImage(opts, pulledImages, true) default: return fmt.Errorf("unknown builder type: %s", builderType) } } - return d.createProjectFromImage(opts, pulledImages, false) + return d.createWorkspaceFromImage(opts, pulledImages, false) } -func (d *DockerClient) cloneProjectRepository(opts *CreateProjectOptions) error { +func (d *DockerClient) cloneWorkspaceRepository(opts *CreateWorkspaceOptions) error { ctx := context.Background() if opts.SshClient != nil { - err := opts.SshClient.Exec(fmt.Sprintf("mkdir -p %s", opts.ProjectDir), nil) + err := opts.SshClient.Exec(fmt.Sprintf("mkdir -p %s", opts.WorkspaceDir), nil) if err != nil { return err } } else { - err := os.MkdirAll(opts.ProjectDir, 0755) + err := os.MkdirAll(opts.WorkspaceDir, 0755) if err != nil { return err } @@ -95,10 +95,10 @@ func (d *DockerClient) cloneProjectRepository(opts *CreateProjectOptions) error } gitService := git.Service{ - ProjectDir: fmt.Sprintf("/workdir/%s-%s", opts.Project.TargetId, opts.Project.Name), + WorkspaceDir: fmt.Sprintf("/workdir/%s-%s", opts.Workspace.TargetId, opts.Workspace.Name), } - cloneCmd := gitService.CloneRepositoryCmd(opts.Project.Repository, auth) + cloneCmd := gitService.CloneRepositoryCmd(opts.Workspace.Repository, auth) c, err := d.apiClient.ContainerCreate(ctx, &container.Config{ Image: opts.BuilderImage, @@ -111,11 +111,11 @@ func (d *DockerClient) cloneProjectRepository(opts *CreateProjectOptions) error Mounts: []mount.Mount{ { Type: mount.TypeBind, - Source: filepath.Dir(opts.ProjectDir), + Source: filepath.Dir(opts.WorkspaceDir), Target: "/workdir", }, }, - }, nil, nil, fmt.Sprintf("git-clone-%s-%s", opts.Project.TargetId, opts.Project.Name)) + }, nil, nil, fmt.Sprintf("git-clone-%s-%s", opts.Workspace.TargetId, opts.Workspace.Name)) if err != nil { return err } @@ -158,7 +158,7 @@ func (d *DockerClient) cloneProjectRepository(opts *CreateProjectOptions) error return nil } -func (d *DockerClient) updateContainerUserUidGid(containerId string, opts *CreateProjectOptions) (string, error) { +func (d *DockerClient) updateContainerUserUidGid(containerId string, opts *CreateWorkspaceOptions) (string, error) { currentUser, err := user.Current() if err != nil { return "", err @@ -200,20 +200,20 @@ func (d *DockerClient) updateContainerUserUidGid(containerId string, opts *Creat return containerUser, nil } -func (d *DockerClient) toCreateDevcontainerOptions(opts *CreateProjectOptions, prebuild bool) CreateDevcontainerOptions { +func (d *DockerClient) toCreateDevcontainerOptions(opts *CreateWorkspaceOptions, prebuild bool) CreateDevcontainerOptions { return CreateDevcontainerOptions{ - ProjectDir: opts.ProjectDir, - ProjectName: opts.Project.Name, - BuildConfig: opts.Project.BuildConfig, + WorkspaceDir: opts.WorkspaceDir, + WorkspaceName: opts.Workspace.Name, + BuildConfig: opts.Workspace.BuildConfig, LogWriter: opts.LogWriter, SshClient: opts.SshClient, ContainerRegistry: opts.ContainerRegistry, BuilderImage: opts.BuilderImage, BuilderContainerRegistry: opts.BuilderContainerRegistry, - EnvVars: opts.Project.EnvVars, + EnvVars: opts.Workspace.EnvVars, IdLabels: map[string]string{ - "daytona.target.id": opts.Project.TargetId, - "daytona.project.name": opts.Project.Name, + "daytona.target.id": opts.Workspace.TargetId, + "daytona.workspace.name": opts.Workspace.Name, }, Prebuild: prebuild, } diff --git a/pkg/docker/create_devcontainer.go b/pkg/docker/create_devcontainer.go index 06e361aca0..90dd4342ce 100644 --- a/pkg/docker/create_devcontainer.go +++ b/pkg/docker/create_devcontainer.go @@ -21,7 +21,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/mount" @@ -35,14 +35,14 @@ type RemoteUser string type DevcontainerPaths struct { OverridesDir string OverridesTarget string - ProjectTarget string + WorkspaceDirTarget string TargetConfigFilePath string } type CreateDevcontainerOptions struct { - ProjectDir string + WorkspaceDir string // Name of the project inside the devcontainer - ProjectName string + WorkspaceName string BuildConfig *buildconfig.BuildConfig LogWriter io.Writer SshClient *ssh.Client @@ -57,12 +57,12 @@ type CreateDevcontainerOptions struct { func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (string, RemoteUser, error) { // Ensure that the devcontainer config exists if opts.SshClient != nil { - _, err := opts.SshClient.ReadFile(path.Join(opts.ProjectDir, opts.BuildConfig.Devcontainer.FilePath)) + _, err := opts.SshClient.ReadFile(path.Join(opts.WorkspaceDir, opts.BuildConfig.Devcontainer.FilePath)) if err != nil { return "", "", err } } else { - _, err := os.Stat(filepath.Join(opts.ProjectDir, opts.BuildConfig.Devcontainer.FilePath)) + _, err := os.Stat(filepath.Join(opts.WorkspaceDir, opts.BuildConfig.Devcontainer.FilePath)) if err != nil { return "", "", err } @@ -75,7 +75,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s ctx := context.Background() - paths := d.getDevcontainerPaths(opts.ProjectDir, opts.BuildConfig.Devcontainer.FilePath) + paths := d.getDevcontainerPaths(opts.WorkspaceDir, opts.BuildConfig.Devcontainer.FilePath) if opts.SshClient != nil { err = opts.SshClient.Exec(fmt.Sprintf("mkdir -p %s", paths.OverridesDir), opts.LogWriter) @@ -95,7 +95,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s } if opts.Prebuild { - err = d.runInitializeCommand(opts.ProjectDir, config.MergedConfiguration.InitializeCommand, opts.LogWriter, opts.SshClient) + err = d.runInitializeCommand(opts.WorkspaceDir, config.MergedConfiguration.InitializeCommand, opts.LogWriter, opts.SshClient) if err != nil { return "", "", err } @@ -134,12 +134,12 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s envVars[k] = v } - // If the workspaceFolder is not set in the devcontainer.json, we set it to /workspaces/ + // If the workspaceFolder is not set in the devcontainer.json, we set it to /workspaces/ if _, ok := devcontainerConfig["workspaceFolder"].(string); !ok { - workspaceFolder = fmt.Sprintf("/workspaces/%s", opts.ProjectName) + workspaceFolder = fmt.Sprintf("/workspaces/%s", opts.WorkspaceName) devcontainerConfig["workspaceFolder"] = workspaceFolder } - devcontainerConfig["workspaceMount"] = fmt.Sprintf("source=%s,target=%s,type=bind", opts.ProjectDir, workspaceFolder) + devcontainerConfig["workspaceMount"] = fmt.Sprintf("source=%s,target=%s,type=bind", opts.WorkspaceDir, workspaceFolder) delete(devcontainerConfig, "initializeCommand") @@ -148,7 +148,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s getComposeFilePath := func(composeFilePath string) (string, error) { if opts.SshClient != nil { - composeFilePath = path.Join(paths.ProjectTarget, filepath.Dir(opts.BuildConfig.Devcontainer.FilePath), composeFilePath) + composeFilePath = path.Join(opts.WorkspaceDir, filepath.Dir(opts.BuildConfig.Devcontainer.FilePath), composeFilePath) composeFileContent, err := d.getRemoteComposeContent(&opts, paths, socketForwardId, composeFilePath) if err != nil { @@ -161,7 +161,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s return "", err } } else { - composeFilePath = filepath.Join(opts.ProjectDir, filepath.Dir(opts.BuildConfig.Devcontainer.FilePath), composeFilePath) + composeFilePath = filepath.Join(opts.WorkspaceDir, filepath.Dir(opts.BuildConfig.Devcontainer.FilePath), composeFilePath) } return composeFilePath, nil @@ -202,17 +202,17 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s return "", "", err } - project.Name = fmt.Sprintf("%s-%s", opts.ProjectName, util.Hash(opts.ProjectDir)) + project.Name = fmt.Sprintf("%s-%s", opts.WorkspaceName, util.Hash(opts.WorkspaceDir)) for _, service := range project.Services { if service.Build != nil { - if strings.HasPrefix(service.Build.Context, opts.ProjectDir) { - service.Build.Context = strings.Replace(service.Build.Context, opts.ProjectDir, paths.ProjectTarget, 1) + if strings.HasPrefix(service.Build.Context, opts.WorkspaceDir) { + service.Build.Context = strings.Replace(service.Build.Context, opts.WorkspaceDir, paths.WorkspaceDirTarget, 1) } } for i, v := range service.Volumes { - if strings.HasPrefix(v.Source, paths.ProjectTarget) { - service.Volumes[i].Source = strings.Replace(v.Source, paths.ProjectTarget, opts.ProjectDir, 1) + if strings.HasPrefix(v.Source, paths.WorkspaceDirTarget) { + service.Volumes[i].Source = strings.Replace(v.Source, paths.WorkspaceDirTarget, opts.WorkspaceDir, 1) } } } @@ -243,7 +243,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s devcontainerConfig["dockerComposeFile"] = path.Join(paths.OverridesTarget, "daytona-compose-override.yml") } - envVars["DAYTONA_PROJECT_DIR"] = workspaceFolder + envVars["DAYTONA_WORKSPACE_DIR"] = workspaceFolder devcontainerConfig["containerEnv"] = envVars @@ -268,7 +268,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s devcontainerCmd := []string{ "devcontainer", "up", - "--workspace-folder=" + paths.ProjectTarget, + "--workspace-folder=" + paths.WorkspaceDirTarget, "--config=" + paths.TargetConfigFilePath, "--override-config=" + path.Join(paths.OverridesTarget, "devcontainer.json"), "--skip-non-blocking-commands", @@ -292,7 +292,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s devcontainerCmd = append(devcontainerCmd, "--prebuild") } - output, err := d.execDevcontainerCommand(strings.Join(devcontainerCmd, " "), &opts, paths, paths.ProjectTarget, socketForwardId, true, []mount.Mount{ + output, err := d.execDevcontainerCommand(strings.Join(devcontainerCmd, " "), &opts, paths, paths.WorkspaceDirTarget, socketForwardId, true, []mount.Mount{ { Type: mount.TypeBind, Source: paths.OverridesDir, @@ -383,7 +383,7 @@ func (d *DockerClient) readDevcontainerConfig(opts *CreateDevcontainerOptions, p // We need to override localEnvs to the host env variables // FIXME: This will not work for features that require localEnv - configEnvOverride, err := d.execDevcontainerCommand(strings.Join(cmd, " "), opts, paths, paths.ProjectTarget, socketForwardId, false, nil) + configEnvOverride, err := d.execDevcontainerCommand(strings.Join(cmd, " "), opts, paths, paths.WorkspaceDirTarget, socketForwardId, false, nil) if err != nil { return "", nil, err } @@ -413,7 +413,7 @@ func (d *DockerClient) readDevcontainerConfig(opts *CreateDevcontainerOptions, p devcontainerCmd := append([]string{}, []string{ "devcontainer", "read-configuration", - "--workspace-folder=" + paths.ProjectTarget, + "--workspace-folder=" + paths.WorkspaceDirTarget, "--config=" + paths.TargetConfigFilePath, "--override-config=" + path.Join(paths.OverridesTarget, "devcontainer.json"), "--include-merged-configuration", @@ -422,7 +422,7 @@ func (d *DockerClient) readDevcontainerConfig(opts *CreateDevcontainerOptions, p "1", }...) - output, err := d.execDevcontainerCommand(strings.Join(devcontainerCmd, " "), opts, paths, paths.ProjectTarget, socketForwardId, false, []mount.Mount{ + output, err := d.execDevcontainerCommand(strings.Join(devcontainerCmd, " "), opts, paths, paths.WorkspaceDirTarget, socketForwardId, false, []mount.Mount{ { Type: mount.TypeBind, Source: paths.OverridesDir, @@ -526,8 +526,8 @@ func (d *DockerClient) execDevcontainerCommand(cmd string, opts *CreateDevcontai mounts := []mount.Mount{ { Type: mount.TypeBind, - Source: opts.ProjectDir, - Target: paths.ProjectTarget, + Source: opts.WorkspaceDir, + Target: paths.WorkspaceDirTarget, }, } @@ -618,17 +618,17 @@ func (d *DockerClient) getRemoteComposeContent(opts *CreateDevcontainerOptions, return output[nameIndex:], nil } -func (d *DockerClient) getDevcontainerPaths(projectDir string, devcontainerFilePath string) DevcontainerPaths { - projectTarget := path.Join("/project", filepath.Base(projectDir)) - targetConfigFilePath := path.Join(projectTarget, devcontainerFilePath) +func (d *DockerClient) getDevcontainerPaths(workspaceDir string, devcontainerFilePath string) DevcontainerPaths { + workspaceDirTarget := path.Join("/project", filepath.Base(workspaceDir)) + targetConfigFilePath := path.Join(workspaceDirTarget, devcontainerFilePath) - overridesDir := filepath.Join(filepath.Dir(projectDir), fmt.Sprintf("%s-data", filepath.Base(projectDir))) + overridesDir := filepath.Join(filepath.Dir(workspaceDir), fmt.Sprintf("%s-data", filepath.Base(workspaceDir))) overridesTarget := "/tmp/overrides" return DevcontainerPaths{ OverridesDir: overridesDir, OverridesTarget: overridesTarget, - ProjectTarget: projectTarget, + WorkspaceDirTarget: workspaceDirTarget, TargetConfigFilePath: targetConfigFilePath, } } diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index 17e660ff43..35d1e36205 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -10,45 +10,45 @@ import ( "time" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/docker/go-connections/nat" log "github.com/sirupsen/logrus" ) -// pulledImages map keeps track of pulled images for project creation in order to avoid pulling the same image multiple times +// pulledImages map keeps track of pulled images for workspace creation in order to avoid pulling the same image multiple times // This is only an optimisation for images with tag 'latest' -func (d *DockerClient) createProjectFromImage(opts *CreateProjectOptions, pulledImages map[string]bool, mountProjectDir bool) error { - if pulledImages[opts.Project.Image] { - return d.initProjectContainer(opts, mountProjectDir) +func (d *DockerClient) createWorkspaceFromImage(opts *CreateWorkspaceOptions, pulledImages map[string]bool, mountWorkspaceDir bool) error { + if pulledImages[opts.Workspace.Image] { + return d.initWorkspaceContainer(opts, mountWorkspaceDir) } - err := d.PullImage(opts.Project.Image, opts.ContainerRegistry, opts.LogWriter) + err := d.PullImage(opts.Workspace.Image, opts.ContainerRegistry, opts.LogWriter) if err != nil { return err } - pulledImages[opts.Project.Image] = true + pulledImages[opts.Workspace.Image] = true - return d.initProjectContainer(opts, mountProjectDir) + return d.initWorkspaceContainer(opts, mountWorkspaceDir) } -func (d *DockerClient) initProjectContainer(opts *CreateProjectOptions, mountProjectDir bool) error { +func (d *DockerClient) initWorkspaceContainer(opts *CreateWorkspaceOptions, mountWorkspaceDir bool) error { ctx := context.Background() mounts := []mount.Mount{} - if mountProjectDir { + if mountWorkspaceDir { mounts = append(mounts, mount.Mount{ Type: mount.TypeBind, - Source: opts.ProjectDir, - Target: fmt.Sprintf("/home/%s/%s", opts.Project.User, opts.Project.Name), + Source: opts.WorkspaceDir, + Target: fmt.Sprintf("/home/%s/%s", opts.Workspace.User, opts.Workspace.Name), }) } var availablePort *uint16 var portBindings map[nat.Port][]nat.PortBinding - if opts.Project.TargetConfig == "local" { + if opts.Workspace.TargetConfig == "local" { p, err := ports.GetAvailableEphemeralPort() if err != nil { log.Error(err) @@ -64,14 +64,14 @@ func (d *DockerClient) initProjectContainer(opts *CreateProjectOptions, mountPro } } - c, err := d.apiClient.ContainerCreate(ctx, GetContainerCreateConfig(opts.Project, availablePort), &container.HostConfig{ + c, err := d.apiClient.ContainerCreate(ctx, GetContainerCreateConfig(opts.Workspace, availablePort), &container.HostConfig{ Privileged: true, Mounts: mounts, ExtraHosts: []string{ "host.docker.internal:host-gateway", }, PortBindings: portBindings, - }, nil, nil, d.GetProjectContainerName(opts.Project)) + }, nil, nil, d.GetWorkspaceContainerName(opts.Workspace)) if err != nil { return err } @@ -92,7 +92,7 @@ func (d *DockerClient) initProjectContainer(opts *CreateProjectOptions, mountPro } }() - if runtime.GOOS != "windows" && mountProjectDir { + if runtime.GOOS != "windows" && mountWorkspaceDir { _, err = d.updateContainerUserUidGid(c.ID, opts) } @@ -106,17 +106,17 @@ func (d *DockerClient) initProjectContainer(opts *CreateProjectOptions, mountPro return nil } -func GetContainerCreateConfig(project *project.Project, toolboxApiHostPort *uint16) *container.Config { +func GetContainerCreateConfig(workspace *workspace.Workspace, toolboxApiHostPort *uint16) *container.Config { envVars := []string{} - for key, value := range project.EnvVars { + for key, value := range workspace.EnvVars { envVars = append(envVars, fmt.Sprintf("%s=%s", key, value)) } labels := map[string]string{ - "daytona.target.id": project.TargetId, - "daytona.project.name": project.Name, - "daytona.project.repository.url": project.Repository.Url, + "daytona.target.id": workspace.TargetId, + "daytona.workspace.name": workspace.Name, + "daytona.workspace.repository.url": workspace.Repository.Url, } if toolboxApiHostPort != nil { @@ -129,10 +129,10 @@ func GetContainerCreateConfig(project *project.Project, toolboxApiHostPort *uint } return &container.Config{ - Hostname: project.Name, - Image: project.Image, + Hostname: workspace.Name, + Image: workspace.Image, Labels: labels, - User: project.User, + User: workspace.User, Env: envVars, Entrypoint: []string{"sleep", "infinity"}, AttachStdout: true, diff --git a/pkg/docker/create_test.go b/pkg/docker/create_test.go index f215d0294b..050232dc37 100644 --- a/pkg/docker/create_test.go +++ b/pkg/docker/create_test.go @@ -33,23 +33,23 @@ func (s *DockerClientTestSuite) TestCreateTarget() { require.Nil(s.T(), err) } -func (s *DockerClientTestSuite) TestCreateProject() { +func (s *DockerClientTestSuite) TestCreateWorkspace() { s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) var networkingConfig *network.NetworkingConfig var platform *v1.Platform - projectDir := os.TempDir() + workspaceDir := os.TempDir() - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) s.mockClient.On("ImageList", mock.Anything, image.ListOptions{ - Filters: filters.NewArgs(filters.Arg("reference", project1.Image)), + Filters: filters.NewArgs(filters.Arg("reference", workspace1.Image)), }, ).Return([]image.Summary{}, nil) - s.mockClient.On("ImagePull", mock.Anything, project1.Image, mock.Anything).Return(t_docker.NewPipeReader(""), nil) + s.mockClient.On("ImagePull", mock.Anything, workspace1.Image, mock.Anything).Return(t_docker.NewPipeReader(""), nil) s.mockClient.On("ImagePull", mock.Anything, "daytonaio/workspace-project", mock.Anything).Return(t_docker.NewPipeReader(""), nil) s.mockClient.On("ContainerRemove", mock.Anything, mock.Anything, container.RemoveOptions{RemoveVolumes: true, Force: true}).Return(nil) @@ -76,13 +76,13 @@ func (s *DockerClientTestSuite) TestCreateProject() { Mounts: []mount.Mount{ { Type: mount.TypeBind, - Source: filepath.Dir(projectDir), + Source: filepath.Dir(workspaceDir), Target: "/workdir", }, }, - }, networkingConfig, platform, fmt.Sprintf("git-clone-%s-%s", project1.TargetId, project1.Name), + }, networkingConfig, platform, fmt.Sprintf("git-clone-%s-%s", workspace1.TargetId, workspace1.Name), ).Return(container.CreateResponse{ID: "123"}, nil) - s.mockClient.On("ContainerCreate", mock.Anything, docker.GetContainerCreateConfig(project1, nil), + s.mockClient.On("ContainerCreate", mock.Anything, docker.GetContainerCreateConfig(workspace1, nil), &container.HostConfig{ Privileged: true, ExtraHosts: []string{ @@ -91,8 +91,8 @@ func (s *DockerClientTestSuite) TestCreateProject() { Mounts: []mount.Mount{ { Type: mount.TypeBind, - Source: projectDir, - Target: fmt.Sprintf("/home/%s/%s", project1.User, project1.Name), + Source: workspaceDir, + Target: fmt.Sprintf("/home/%s/%s", workspace1.User, workspace1.Name), }, }, }, @@ -101,9 +101,9 @@ func (s *DockerClientTestSuite) TestCreateProject() { containerName, ).Return(container.CreateResponse{ID: "123"}, nil) - err := s.dockerClient.CreateProject(&docker.CreateProjectOptions{ - Project: project1, - ProjectDir: projectDir, + err := s.dockerClient.CreateWorkspace(&docker.CreateWorkspaceOptions{ + Workspace: workspace1, + WorkspaceDir: workspaceDir, ContainerRegistry: nil, LogWriter: nil, Gpc: nil, diff --git a/pkg/docker/destroy.go b/pkg/docker/destroy.go index cdb1a8b71c..6684b04460 100644 --- a/pkg/docker/destroy.go +++ b/pkg/docker/destroy.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/ssh" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) @@ -23,23 +23,23 @@ func (d *DockerClient) DestroyTarget(target *target.Target, targetDir string, ss } } -func (d *DockerClient) DestroyProject(project *project.Project, projectDir string, sshClient *ssh.Client) error { - err := d.removeProjectContainer(project) +func (d *DockerClient) DestroyWorkspace(workspace *workspace.Workspace, workspaceDir string, sshClient *ssh.Client) error { + err := d.removeWorkspaceContainer(workspace) if err != nil { return err } if sshClient == nil { - return os.RemoveAll(projectDir) + return os.RemoveAll(workspaceDir) } else { - return sshClient.Exec(fmt.Sprintf("rm -rf %s", projectDir), nil) + return sshClient.Exec(fmt.Sprintf("rm -rf %s", workspaceDir), nil) } } -func (d *DockerClient) removeProjectContainer(p *project.Project) error { +func (d *DockerClient) removeWorkspaceContainer(w *workspace.Workspace) error { ctx := context.Background() - containerName := d.GetProjectContainerName(p) + containerName := d.GetWorkspaceContainerName(w) c, err := d.apiClient.ContainerInspect(ctx, containerName) if err != nil { diff --git a/pkg/docker/destroy_test.go b/pkg/docker/destroy_test.go index e18f1d58db..594eb6621d 100644 --- a/pkg/docker/destroy_test.go +++ b/pkg/docker/destroy_test.go @@ -22,10 +22,10 @@ func (s *DockerClientTestSuite) TestDestroyTarget() { require.True(s.T(), os.IsNotExist(err)) } -func (s *DockerClientTestSuite) TestDestroyProject() { +func (s *DockerClientTestSuite) TestDestroyWorkspace() { s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(types.ContainerJSON{ Config: &container.Config{}, @@ -38,13 +38,13 @@ func (s *DockerClientTestSuite) TestDestroyProject() { }, ).Return(nil) - s.mockClient.On("VolumeRemove", mock.Anything, s.dockerClient.GetProjectVolumeName(project1), true).Return(nil) + s.mockClient.On("VolumeRemove", mock.Anything, s.dockerClient.GetWorkspaceVolumeName(workspace1), true).Return(nil) - projectDir := s.T().TempDir() + workspaceDir := s.T().TempDir() - err := s.dockerClient.DestroyProject(project1, projectDir, nil) + err := s.dockerClient.DestroyWorkspace(workspace1, workspaceDir, nil) require.Nil(s.T(), err) - _, err = os.Stat(projectDir) + _, err = os.Stat(workspaceDir) require.True(s.T(), os.IsNotExist(err)) } diff --git a/pkg/docker/exec_test.go b/pkg/docker/exec_test.go index f64e1af70f..b3577da712 100644 --- a/pkg/docker/exec_test.go +++ b/pkg/docker/exec_test.go @@ -18,13 +18,13 @@ import ( func (s *DockerClientTestSuite) TestExecSync() { s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) - s.setupExecTest([]string{"test-cmd"}, containerName, project1.User, []string{}, "") + s.setupExecTest([]string{"test-cmd"}, containerName, workspace1.User, []string{}, "") result, err := s.dockerClient.ExecSync(containerName, container.ExecOptions{ Cmd: []string{"test-cmd"}, - User: project1.User, + User: workspace1.User, }, io.Discard) require.Nil(s.T(), err) require.Equal(s.T(), 0, result.ExitCode) diff --git a/pkg/docker/info.go b/pkg/docker/info.go index a54cf4762b..73783f744b 100644 --- a/pkg/docker/info.go +++ b/pkg/docker/info.go @@ -9,7 +9,7 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) @@ -23,22 +23,22 @@ func (d *DockerClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, erro ProviderMetadata: fmt.Sprintf(TargetMetadataFormat, t.Id), } - projectInfos := []*project.ProjectInfo{} - for _, project := range t.Projects { - projectInfo, err := d.GetProjectInfo(project) + workspaceInfos := []*workspace.WorkspaceInfo{} + for _, workspace := range t.Workspaces { + workspaceInfo, err := d.GetWorkspaceInfo(workspace) if err != nil { return nil, err } - projectInfos = append(projectInfos, projectInfo) + workspaceInfos = append(workspaceInfos, workspaceInfo) } - targetInfo.Projects = projectInfos + targetInfo.Workspaces = workspaceInfos return targetInfo, nil } -func (d *DockerClient) GetProjectInfo(p *project.Project) (*project.ProjectInfo, error) { +func (d *DockerClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.WorkspaceInfo, error) { isRunning := true - info, err := d.getContainerInfo(p) + info, err := d.getContainerInfo(w) if err != nil { if client.IsErrNotFound(err) { isRunning = false @@ -48,16 +48,16 @@ func (d *DockerClient) GetProjectInfo(p *project.Project) (*project.ProjectInfo, } if info == nil || info.State == nil { - return &project.ProjectInfo{ - Name: p.Name, + return &workspace.WorkspaceInfo{ + Name: w.Name, IsRunning: isRunning, Created: "", ProviderMetadata: ContainerNotFoundMetadata, }, nil } - projectInfo := &project.ProjectInfo{ - Name: p.Name, + workspaceInfo := &workspace.WorkspaceInfo{ + Name: w.Name, IsRunning: isRunning, Created: info.Created, } @@ -67,16 +67,16 @@ func (d *DockerClient) GetProjectInfo(p *project.Project) (*project.ProjectInfo, if err != nil { return nil, err } - projectInfo.ProviderMetadata = string(metadata) + workspaceInfo.ProviderMetadata = string(metadata) } - return projectInfo, nil + return workspaceInfo, nil } -func (d *DockerClient) getContainerInfo(p *project.Project) (*types.ContainerJSON, error) { +func (d *DockerClient) getContainerInfo(w *workspace.Workspace) (*types.ContainerJSON, error) { ctx := context.Background() - info, err := d.apiClient.ContainerInspect(ctx, d.GetProjectContainerName(p)) + info, err := d.apiClient.ContainerInspect(ctx, d.GetWorkspaceContainerName(w)) if err != nil { return nil, err } diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go index 3d64acd570..f1efa11913 100644 --- a/pkg/docker/info_test.go +++ b/pkg/docker/info_test.go @@ -14,10 +14,10 @@ import ( "github.com/stretchr/testify/require" ) -func (s *DockerClientTestSuite) TestGetProjectInfo() { +func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) inspectResult := types.ContainerJSON{ ContainerJSONBase: &types.ContainerJSONBase{ @@ -36,23 +36,23 @@ func (s *DockerClientTestSuite) TestGetProjectInfo() { s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(inspectResult, nil) - projectInfo, err := s.dockerClient.GetProjectInfo(project1) + workspaceInfo, err := s.dockerClient.GetWorkspaceInfo(workspace1) require.Nil(s.T(), err) - require.Equal(s.T(), project1.Name, projectInfo.Name) - require.Equal(s.T(), projectInfo.IsRunning, inspectResult.State.Running) - require.Equal(s.T(), projectInfo.Created, inspectResult.Created) - require.Equal(s.T(), projectInfo.ProviderMetadata, metadata) + require.Equal(s.T(), workspace1.Name, workspaceInfo.Name) + require.Equal(s.T(), workspaceInfo.IsRunning, inspectResult.State.Running) + require.Equal(s.T(), workspaceInfo.Created, inspectResult.Created) + require.Equal(s.T(), workspaceInfo.ProviderMetadata, metadata) } func (s *DockerClientTestSuite) TestGetTargetInfo() { - targetWithoutProjects := &target.Target{ + targetWithoutWorkspaces := &target.Target{ Id: "123", Name: "test", TargetConfig: "local", } - targetInfo, err := s.dockerClient.GetTargetInfo(targetWithoutProjects) + targetInfo, err := s.dockerClient.GetTargetInfo(targetWithoutWorkspaces) require.Nil(s.T(), err) - require.Equal(s.T(), targetInfo.Name, targetWithoutProjects.Name) - require.Equal(s.T(), targetInfo.ProviderMetadata, fmt.Sprintf(docker.TargetMetadataFormat, targetWithoutProjects.Id)) + require.Equal(s.T(), targetInfo.Name, targetWithoutWorkspaces.Name) + require.Equal(s.T(), targetInfo.ProviderMetadata, fmt.Sprintf(docker.TargetMetadataFormat, targetWithoutWorkspaces.Id)) } diff --git a/pkg/docker/start.go b/pkg/docker/start.go index 15e1209bf4..2bd5bef1ce 100644 --- a/pkg/docker/start.go +++ b/pkg/docker/start.go @@ -12,15 +12,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/detect" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types/container" ) -func (d *DockerClient) StartProject(opts *CreateProjectOptions, daytonaDownloadUrl string) error { +func (d *DockerClient) StartWorkspace(opts *CreateWorkspaceOptions, daytonaDownloadUrl string) error { var err error - containerUser := opts.Project.User + containerUser := opts.Workspace.User - builderType, err := detect.DetectProjectBuilderType(opts.Project.BuildConfig, opts.ProjectDir, opts.SshClient) + builderType, err := detect.DetectWorkspaceBuilderType(opts.Workspace.BuildConfig, opts.WorkspaceDir, opts.SshClient) if err != nil { return err } @@ -28,10 +28,10 @@ func (d *DockerClient) StartProject(opts *CreateProjectOptions, daytonaDownloadU switch builderType { case detect.BuilderTypeDevcontainer: var remoteUser RemoteUser - remoteUser, err = d.startDevcontainerProject(opts) + remoteUser, err = d.startDevcontainerWorkspace(opts) containerUser = string(remoteUser) case detect.BuilderTypeImage: - err = d.startImageProject(opts) + err = d.startImageWorkspace(opts) default: return fmt.Errorf("unknown builder type: %s", builderType) } @@ -40,18 +40,18 @@ func (d *DockerClient) StartProject(opts *CreateProjectOptions, daytonaDownloadU return err } - return d.startDaytonaAgent(opts.Project, containerUser, daytonaDownloadUrl, opts.LogWriter) + return d.startDaytonaAgent(opts.Workspace, containerUser, daytonaDownloadUrl, opts.LogWriter) } -func (d *DockerClient) startDaytonaAgent(p *project.Project, containerUser, daytonaDownloadUrl string, logWriter io.Writer) error { +func (d *DockerClient) startDaytonaAgent(w *workspace.Workspace, containerUser, daytonaDownloadUrl string, logWriter io.Writer) error { errChan := make(chan error) - r, w := io.Pipe() - writer := io.MultiWriter(w, logWriter) + r, pipeW := io.Pipe() + writer := io.MultiWriter(pipeW, logWriter) go func() { - result, err := d.ExecSync(d.GetProjectContainerName(p), container.ExecOptions{ - Cmd: []string{"sh", "-c", util.GetProjectStartScript(daytonaDownloadUrl, p.ApiKey)}, + result, err := d.ExecSync(d.GetWorkspaceContainerName(w), container.ExecOptions{ + Cmd: []string{"sh", "-c", util.GetWorkspaceStartScript(daytonaDownloadUrl, w.ApiKey)}, AttachStdout: true, AttachStderr: true, User: containerUser, diff --git a/pkg/docker/start_devcontainer.go b/pkg/docker/start_devcontainer.go index 5faa263271..0d00a83d4f 100644 --- a/pkg/docker/start_devcontainer.go +++ b/pkg/docker/start_devcontainer.go @@ -11,7 +11,7 @@ import ( "github.com/docker/docker/api/types/mount" ) -func (d *DockerClient) startDevcontainerProject(opts *CreateProjectOptions) (RemoteUser, error) { +func (d *DockerClient) startDevcontainerWorkspace(opts *CreateWorkspaceOptions) (RemoteUser, error) { go func() { err := d.runDevcontainerUserCommands(opts) if err != nil { @@ -23,7 +23,7 @@ func (d *DockerClient) startDevcontainerProject(opts *CreateProjectOptions) (Rem return remoteUser, err } -func (d *DockerClient) runDevcontainerUserCommands(opts *CreateProjectOptions) error { +func (d *DockerClient) runDevcontainerUserCommands(opts *CreateWorkspaceOptions) error { socketForwardId, err := d.ensureDockerSockForward(opts.BuilderImage, opts.BuilderContainerRegistry, opts.LogWriter) if err != nil { return err @@ -31,23 +31,23 @@ func (d *DockerClient) runDevcontainerUserCommands(opts *CreateProjectOptions) e opts.LogWriter.Write([]byte("Running devcontainer user commands...\n")) - paths := d.getDevcontainerPaths(opts.ProjectDir, opts.Project.BuildConfig.Devcontainer.FilePath) + paths := d.getDevcontainerPaths(opts.WorkspaceDir, opts.Workspace.BuildConfig.Devcontainer.FilePath) devcontainerCmd := []string{ "devcontainer", "run-user-commands", - "--workspace-folder=" + paths.ProjectTarget, + "--workspace-folder=" + paths.WorkspaceDirTarget, "--config=" + paths.TargetConfigFilePath, "--override-config=" + path.Join(paths.OverridesTarget, "devcontainer.json"), - "--id-label=daytona.target.id=" + opts.Project.TargetId, - "--id-label=daytona.project.name=" + opts.Project.Name, + "--id-label=daytona.target.id=" + opts.Workspace.TargetId, + "--id-label=daytona.workspace.name=" + opts.Workspace.Name, } cmd := strings.Join(devcontainerCmd, " ") createDevcontainerOptions := d.toCreateDevcontainerOptions(opts, true) - _, err = d.execDevcontainerCommand(cmd, &createDevcontainerOptions, paths, paths.ProjectTarget, socketForwardId, true, []mount.Mount{ + _, err = d.execDevcontainerCommand(cmd, &createDevcontainerOptions, paths, paths.WorkspaceDirTarget, socketForwardId, true, []mount.Mount{ { Type: mount.TypeBind, Source: paths.OverridesDir, diff --git a/pkg/docker/start_image.go b/pkg/docker/start_image.go index 1ed95a784e..238707bd54 100644 --- a/pkg/docker/start_image.go +++ b/pkg/docker/start_image.go @@ -20,8 +20,8 @@ type FeatureItem struct { // Add other fields as needed } -func (d *DockerClient) startImageProject(opts *CreateProjectOptions) error { - containerName := d.GetProjectContainerName(opts.Project) +func (d *DockerClient) startImageWorkspace(opts *CreateWorkspaceOptions) error { + containerName := d.GetWorkspaceContainerName(opts.Workspace) ctx := context.Background() c, err := d.apiClient.ContainerInspect(ctx, containerName) @@ -109,7 +109,7 @@ func (d *DockerClient) startImageProject(opts *CreateProjectOptions) error { return nil } -func executeEntrypoints(ctx context.Context, cli client.APIClient, containerID string, features []FeatureItem, opts *CreateProjectOptions) error { +func executeEntrypoints(ctx context.Context, cli client.APIClient, containerID string, features []FeatureItem, opts *CreateWorkspaceOptions) error { for _, feature := range features { if feature.Entrypoint != "" { execConfig := container.ExecOptions{ diff --git a/pkg/docker/start_test.go b/pkg/docker/start_test.go index 72a4574155..93f6847879 100644 --- a/pkg/docker/start_test.go +++ b/pkg/docker/start_test.go @@ -12,12 +12,12 @@ import ( "github.com/stretchr/testify/require" ) -func (s *DockerClientTestSuite) TestStartProject() { +func (s *DockerClientTestSuite) TestStartWorkspace() { s.T().Skip("TODO: figure out how to properly test the output of exec") s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) s.mockClient.On("ContainerStart", mock.Anything, containerName, container.StartOptions{}).Return(nil) s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(types.ContainerJSON{ @@ -41,10 +41,10 @@ func (s *DockerClientTestSuite) TestStartProject() { }, }, nil) - s.setupExecTest([]string{"sh", "-c", util.GetProjectStartScript("", project1.ApiKey)}, containerName, project1.User, []string{}, "Daytona Agent started") + s.setupExecTest([]string{"sh", "-c", util.GetWorkspaceStartScript("", workspace1.ApiKey)}, containerName, workspace1.User, []string{}, "Daytona Agent started") - err := s.dockerClient.StartProject(&docker.CreateProjectOptions{ - Project: project1, + err := s.dockerClient.StartWorkspace(&docker.CreateWorkspaceOptions{ + Workspace: workspace1, }, "") require.Nil(s.T(), err) } diff --git a/pkg/docker/stop.go b/pkg/docker/stop.go index 3efc0a3f54..22c776f2b3 100644 --- a/pkg/docker/stop.go +++ b/pkg/docker/stop.go @@ -10,17 +10,17 @@ import ( "strings" "time" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" ) -func (d *DockerClient) StopProject(p *project.Project, logWriter io.Writer) error { - return d.stopProjectContainer(p, logWriter) +func (d *DockerClient) StopWorkspace(w *workspace.Workspace, logWriter io.Writer) error { + return d.stopWorkspaceContainer(w, logWriter) } -func (d *DockerClient) stopProjectContainer(p *project.Project, logWriter io.Writer) error { - containerName := d.GetProjectContainerName(p) +func (d *DockerClient) stopWorkspaceContainer(w *workspace.Workspace, logWriter io.Writer) error { + containerName := d.GetWorkspaceContainerName(w) ctx := context.Background() err := d.apiClient.ContainerStop(ctx, containerName, container.StopOptions{}) diff --git a/pkg/docker/stop_test.go b/pkg/docker/stop_test.go index 6188f2e43c..18b6ff74e4 100644 --- a/pkg/docker/stop_test.go +++ b/pkg/docker/stop_test.go @@ -10,10 +10,10 @@ import ( "github.com/stretchr/testify/require" ) -func (s *DockerClientTestSuite) TestStopProject() { +func (s *DockerClientTestSuite) TestStopWorkspace() { s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - containerName := s.dockerClient.GetProjectContainerName(project1) + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) s.mockClient.On("ContainerStop", mock.Anything, containerName, container.StopOptions{}).Return(nil) s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(types.ContainerJSON{ @@ -27,6 +27,6 @@ func (s *DockerClientTestSuite) TestStopProject() { }, }, nil) - err := s.dockerClient.StopProject(project1, nil) + err := s.dockerClient.StopWorkspace(workspace1, nil) require.Nil(s.T(), err) } diff --git a/pkg/git/add.go b/pkg/git/add.go index b78aae41d3..5ea0d7c00a 100644 --- a/pkg/git/add.go +++ b/pkg/git/add.go @@ -6,7 +6,7 @@ package git import "github.com/go-git/go-git/v5" func (s *Service) Add(files []string) error { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return err } diff --git a/pkg/git/branch.go b/pkg/git/branch.go index f97c799bb2..d605892fd6 100644 --- a/pkg/git/branch.go +++ b/pkg/git/branch.go @@ -9,7 +9,7 @@ import ( ) func (s *Service) CreateBranch(name string) error { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return err } @@ -26,7 +26,7 @@ func (s *Service) CreateBranch(name string) error { } func (s *Service) ListBranches() ([]string, error) { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return []string{}, err } diff --git a/pkg/git/clone.go b/pkg/git/clone.go index 6e5fae4f6d..0f05c827f2 100644 --- a/pkg/git/clone.go +++ b/pkg/git/clone.go @@ -38,13 +38,13 @@ func (s *Service) CloneRepository(repo *gitprovider.GitRepository, auth *http.Ba cloneOptions.ReferenceName = plumbing.ReferenceName("refs/heads/" + repo.Branch) - _, err := git.PlainClone(s.ProjectDir, false, cloneOptions) + _, err := git.PlainClone(s.WorkspaceDir, false, cloneOptions) if err != nil { return err } if repo.Target == gitprovider.CloneTargetCommit { - r, err := git.PlainOpen(s.ProjectDir) + r, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return err } @@ -78,10 +78,10 @@ func (s *Service) CloneRepositoryCmd(repo *gitprovider.GitRepository, auth *http cloneUrl = fmt.Sprintf("%s://%s:%s@%s", strings.Split(cloneUrl, "://")[0], auth.Username, auth.Password, strings.SplitN(cloneUrl, "://", 2)[1]) } - cloneCmd = append(cloneCmd, cloneUrl, s.ProjectDir) + cloneCmd = append(cloneCmd, cloneUrl, s.WorkspaceDir) if repo.Target == gitprovider.CloneTargetCommit { - cloneCmd = append(cloneCmd, "&&", "cd", s.ProjectDir) + cloneCmd = append(cloneCmd, "&&", "cd", s.WorkspaceDir) cloneCmd = append(cloneCmd, "&&", "git", "checkout", repo.Sha) } diff --git a/pkg/git/commit.go b/pkg/git/commit.go index 6acd3583dd..b515207413 100644 --- a/pkg/git/commit.go +++ b/pkg/git/commit.go @@ -6,7 +6,7 @@ package git import "github.com/go-git/go-git/v5" func (s *Service) Commit(message string, options *git.CommitOptions) (string, error) { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return "", err } diff --git a/pkg/git/config.go b/pkg/git/config.go index b1a6638e02..1c6695bdc6 100644 --- a/pkg/git/config.go +++ b/pkg/git/config.go @@ -45,7 +45,7 @@ func (s *Service) SetGitConfig(userData *gitprovider.GitUser, providerConfig *gi return err } } - _, err = cfg.Section("safe").NewKey("directory", s.ProjectDir) + _, err = cfg.Section("safe").NewKey("directory", s.WorkspaceDir) if err != nil { return err } diff --git a/pkg/git/log.go b/pkg/git/log.go index dca50c0b59..79d92f2c36 100644 --- a/pkg/git/log.go +++ b/pkg/git/log.go @@ -10,7 +10,7 @@ import ( ) func (s *Service) Log() ([]GitCommitInfo, error) { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return []GitCommitInfo{}, err } diff --git a/pkg/git/pull.go b/pkg/git/pull.go index bd86ccd188..5ae24ba201 100644 --- a/pkg/git/pull.go +++ b/pkg/git/pull.go @@ -10,7 +10,7 @@ import ( ) func (s *Service) Pull(auth *http.BasicAuth) error { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return err } diff --git a/pkg/git/push.go b/pkg/git/push.go index abbd23d89f..6d98822754 100644 --- a/pkg/git/push.go +++ b/pkg/git/push.go @@ -10,7 +10,7 @@ import ( ) func (s *Service) Push(auth *http.BasicAuth) error { - repo, err := git.PlainOpen(s.ProjectDir) + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return err } diff --git a/pkg/git/service.go b/pkg/git/service.go index a95ab78769..f30c119275 100644 --- a/pkg/git/service.go +++ b/pkg/git/service.go @@ -9,20 +9,20 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/transport/http" ) -var MapStatus map[git.StatusCode]project.Status = map[git.StatusCode]project.Status{ - git.Unmodified: project.Unmodified, - git.Untracked: project.Untracked, - git.Modified: project.Modified, - git.Added: project.Added, - git.Deleted: project.Deleted, - git.Renamed: project.Renamed, - git.Copied: project.Copied, - git.UpdatedButUnmerged: project.UpdatedButUnmerged, +var MapStatus map[git.StatusCode]workspace.Status = map[git.StatusCode]workspace.Status{ + git.Unmodified: workspace.Unmodified, + git.Untracked: workspace.Untracked, + git.Modified: workspace.Modified, + git.Added: workspace.Added, + git.Deleted: workspace.Deleted, + git.Renamed: workspace.Renamed, + git.Copied: workspace.Copied, + git.UpdatedButUnmerged: workspace.UpdatedButUnmerged, } type IGitService interface { @@ -30,18 +30,18 @@ type IGitService interface { CloneRepositoryCmd(repo *gitprovider.GitRepository, auth *http.BasicAuth) []string RepositoryExists() (bool, error) SetGitConfig(userData *gitprovider.GitUser, providerConfig *gitprovider.GitProviderConfig) error - GetGitStatus() (*project.GitStatus, error) + GetGitStatus() (*workspace.GitStatus, error) } type Service struct { - ProjectDir string + WorkspaceDir string GitConfigFileName string LogWriter io.Writer OpenRepository *git.Repository } func (s *Service) RepositoryExists() (bool, error) { - _, err := os.Stat(filepath.Join(s.ProjectDir, ".git")) + _, err := os.Stat(filepath.Join(s.WorkspaceDir, ".git")) if os.IsNotExist(err) { return false, nil } diff --git a/pkg/git/service_test.go b/pkg/git/service_test.go index f1d7ad4b26..32ba546ed1 100644 --- a/pkg/git/service_test.go +++ b/pkg/git/service_test.go @@ -61,7 +61,7 @@ func NewGitServiceTestSuite() *GitServiceTestSuite { func (s *GitServiceTestSuite) SetupTest() { s.gitService = &git.Service{ - ProjectDir: "/workdir", + WorkspaceDir: "/workdir", } } diff --git a/pkg/git/status.go b/pkg/git/status.go index f8f202a080..4456ba103f 100644 --- a/pkg/git/status.go +++ b/pkg/git/status.go @@ -9,12 +9,12 @@ import ( "strconv" "strings" - "github.com/daytonaio/daytona/pkg/workspace/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/go-git/go-git/v5" ) -func (s *Service) GetGitStatus() (*project.GitStatus, error) { - repo, err := git.PlainOpen(s.ProjectDir) +func (s *Service) GetGitStatus() (*workspace.GitStatus, error) { + repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return nil, err } @@ -34,9 +34,9 @@ func (s *Service) GetGitStatus() (*project.GitStatus, error) { return nil, err } - files := []*project.FileStatus{} + files := []*workspace.FileStatus{} for path, file := range status { - files = append(files, &project.FileStatus{ + files = append(files, &workspace.FileStatus{ Name: path, Extra: file.Extra, Staging: MapStatus[file.Staging], @@ -54,7 +54,7 @@ func (s *Service) GetGitStatus() (*project.GitStatus, error) { return nil, err } - return &project.GitStatus{ + return &workspace.GitStatus{ CurrentBranch: ref.Name().Short(), Files: files, BranchPublished: branchPublished, @@ -72,7 +72,7 @@ func (s *Service) isBranchPublished() (bool, error) { } func (s *Service) getUpstreamBranch() (string, error) { - cmd := exec.Command("git", "-C", s.ProjectDir, "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}") + cmd := exec.Command("git", "-C", s.WorkspaceDir, "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}") out, err := cmd.CombinedOutput() if err != nil { return "", nil @@ -90,7 +90,7 @@ func (s *Service) getAheadBehindInfo() (int, int, error) { return 0, 0, nil } - cmd := exec.Command("git", "-C", s.ProjectDir, "rev-list", "--left-right", "--count", fmt.Sprintf("%s...HEAD", upstream)) + cmd := exec.Command("git", "-C", s.WorkspaceDir, "rev-list", "--left-right", "--count", fmt.Sprintf("%s...HEAD", upstream)) out, err := cmd.CombinedOutput() if err != nil { return 0, 0, nil diff --git a/pkg/ide/browser.go b/pkg/ide/browser.go index 3296df4b49..b44a535566 100644 --- a/pkg/ide/browser.go +++ b/pkg/ide/browser.go @@ -23,17 +23,17 @@ import ( const startVSCodeServerCommand = "$HOME/vscode-server/bin/openvscode-server --start-server --port=63000 --host=0.0.0.0 --without-connection-token --disable-workspace-trust --default-folder=" -func OpenBrowserIDE(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgKey string) error { +func OpenBrowserIDE(activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, gpgKey string) error { // Download and start IDE - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) if err != nil { return err } views.RenderInfoMessageBold("Downloading OpenVSCode Server...") - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - installServerCommand := exec.Command("ssh", projectHostname, "curl -fsSL https://download.daytona.io/daytona/get-openvscode-server.sh | sh") + installServerCommand := exec.Command("ssh", workspaceHostname, "curl -fsSL https://download.daytona.io/daytona/get-openvscode-server.sh | sh") installServerCommand.Stdout = io.Writer(&util.DebugLogWriter{}) installServerCommand.Stderr = io.Writer(&util.DebugLogWriter{}) @@ -42,7 +42,7 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, projectName s return err } - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } @@ -50,7 +50,7 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, projectName s views.RenderInfoMessageBold("Starting OpenVSCode Server...") go func() { - startServerCommand := exec.CommandContext(context.Background(), "ssh", projectHostname, fmt.Sprintf("%s%s", startVSCodeServerCommand, projectDir)) + startServerCommand := exec.CommandContext(context.Background(), "ssh", workspaceHostname, fmt.Sprintf("%s%s", startVSCodeServerCommand, workspaceDir)) startServerCommand.Stdout = io.Writer(&util.DebugLogWriter{}) startServerCommand.Stderr = io.Writer(&util.DebugLogWriter{}) @@ -61,7 +61,7 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, projectName s }() // Forward IDE port - browserPort, errChan := tailscale.ForwardPort(targetId, projectName, 63000, activeProfile) + browserPort, errChan := tailscale.ForwardPort(targetId, workspaceName, 63000, activeProfile) if browserPort == nil { if err := <-errChan; err != nil { return err @@ -77,18 +77,18 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, projectName s time.Sleep(500 * time.Millisecond) } - views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s IDE port to %s.\nOpening browser...\n", projectName, ideURL)) + views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s IDE port to %s.\nOpening browser...\n", workspaceName, ideURL)) err = browser.OpenURL(ideURL) if err != nil { log.Error("Error opening URL: " + err.Error()) } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - err = setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Browser, "*/vscode-server/bin/openvscode-server", "$HOME/.openvscode-server/data/Machine/settings.json", ".daytona-customizations-lock-vscode-browser") + err = setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Browser, "*/vscode-server/bin/openvscode-server", "$HOME/.openvscode-server/data/Machine/settings.json", ".daytona-customizations-lock-vscode-browser") if err != nil { log.Errorf("Error setting up IDE customizations: %s", err) } diff --git a/pkg/ide/cursor.go b/pkg/ide/cursor.go index 9a0ec5e469..107207bf27 100644 --- a/pkg/ide/cursor.go +++ b/pkg/ide/cursor.go @@ -14,20 +14,20 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenCursor(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenCursor(activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetCursorBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgkey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) cursorCommand := exec.Command(path, "--disable-extension", "ms-vscode-remote.remote-containers", "--folder-uri", commandArgument) @@ -36,11 +36,11 @@ func OpenCursor(activeProfile config.Profile, targetId string, projectName strin return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.cursor-server/*/bin/cursor-server", "$HOME/.cursor-server/data/Machine/settings.json", ".daytona-customizations-lock-cursor") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.cursor-server/*/bin/cursor-server", "$HOME/.cursor-server/data/Machine/settings.json", ".daytona-customizations-lock-cursor") } func GetCursorBinaryPath() (string, error) { diff --git a/pkg/ide/fleet.go b/pkg/ide/fleet.go index 854332eb11..3958ed5323 100644 --- a/pkg/ide/fleet.go +++ b/pkg/ide/fleet.go @@ -13,18 +13,18 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenFleet(activeProfile config.Profile, targetId string, projectName string, gpgKey string) error { +func OpenFleet(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string) error { if err := CheckFleetInstallation(); err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } - ideURL := fmt.Sprintf("fleet://fleet.ssh/%s?pwd=%s", projectHostname, projectDir) + ideURL := fmt.Sprintf("fleet://fleet.ssh/%s?pwd=%s", workspaceHostname, workspaceDir) err = browser.OpenURL(ideURL) if err != nil { diff --git a/pkg/ide/jetbrains.go b/pkg/ide/jetbrains.go index f6e1b324e6..e5c54d0a56 100644 --- a/pkg/ide/jetbrains.go +++ b/pkg/ide/jetbrains.go @@ -23,25 +23,25 @@ import ( "github.com/pkg/browser" ) -func OpenJetbrainsIDE(activeProfile config.Profile, ide, targetId, projectName string, gpgKey string) error { +func OpenJetbrainsIDE(activeProfile config.Profile, ide, targetId, workspaceName string, gpgKey string) error { err := IsJetBrainsGatewayInstalled() if err != nil { return err } - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) jbIde, ok := jetbrains.GetIdes()[jetbrains.Id(ide)] if !ok { return errors.New("IDE not found") } - home, err := util.GetHomeDir(activeProfile, targetId, projectName, gpgKey) + home, err := util.GetHomeDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } @@ -50,7 +50,7 @@ func OpenJetbrainsIDE(activeProfile config.Profile, ide, targetId, projectName s downloadUrl := "" - remoteOs, err := util.GetRemoteOS(projectHostname) + remoteOs, err := util.GetRemoteOS(workspaceHostname) if err != nil { return err } @@ -69,25 +69,25 @@ func OpenJetbrainsIDE(activeProfile config.Profile, ide, targetId, projectName s return errors.New("JetBrains remote IDEs are only supported on Linux.") } - err = downloadJetbrainsIDE(projectHostname, downloadUrl, downloadPath) + err = downloadJetbrainsIDE(workspaceHostname, downloadUrl, downloadPath) if err != nil { return err } - gatewayUrl := fmt.Sprintf("jetbrains-gateway://connect#host=%s&type=ssh&deploy=false&projectPath=%s&user=daytona&port=%d&idePath=%s", projectHostname, projectDir, ssh_config.SSH_PORT, url.QueryEscape(downloadPath)) + gatewayUrl := fmt.Sprintf("jetbrains-gateway://connect#host=%s&type=ssh&deploy=false&projectPath=%s&user=daytona&port=%d&idePath=%s", workspaceHostname, workspaceDir, ssh_config.SSH_PORT, url.QueryEscape(downloadPath)) return browser.OpenURL(gatewayUrl) } -func downloadJetbrainsIDE(projectHostname, downloadUrl, downloadPath string) error { - if isAlreadyDownloaded(projectHostname, downloadPath) { +func downloadJetbrainsIDE(workspaceHostname, downloadUrl, downloadPath string) error { + if isAlreadyDownloaded(workspaceHostname, downloadPath) { views.RenderInfoMessage("JetBrains IDE already downloaded. Opening...") return nil } - views.RenderInfoMessage(fmt.Sprintf("Downloading the IDE into the project from %s...", downloadUrl)) + views.RenderInfoMessage(fmt.Sprintf("Downloading the IDE into the workspace from %s...", downloadUrl)) - downloadIdeCmd := exec.Command("ssh", projectHostname, fmt.Sprintf("mkdir -p %s && wget -q --show-progress --progress=bar:force -pO- %s | tar -xzC %s --strip-components=1", downloadPath, downloadUrl, downloadPath)) + downloadIdeCmd := exec.Command("ssh", workspaceHostname, fmt.Sprintf("mkdir -p %s && wget -q --show-progress --progress=bar:force -pO- %s | tar -xzC %s --strip-components=1", downloadPath, downloadUrl, downloadPath)) downloadIdeCmd.Stdout = os.Stdout downloadIdeCmd.Stderr = os.Stderr @@ -101,8 +101,8 @@ func downloadJetbrainsIDE(projectHostname, downloadUrl, downloadPath string) err return nil } -func isAlreadyDownloaded(projectHostname, downloadPath string) bool { - statCmd := exec.Command("ssh", projectHostname, fmt.Sprintf("stat %s", downloadPath)) +func isAlreadyDownloaded(workspaceHostname, downloadPath string) bool { + statCmd := exec.Command("ssh", workspaceHostname, fmt.Sprintf("stat %s", downloadPath)) err := statCmd.Run() return err == nil } diff --git a/pkg/ide/jupyter.go b/pkg/ide/jupyter.go index 27ba89b261..512a92394c 100644 --- a/pkg/ide/jupyter.go +++ b/pkg/ide/jupyter.go @@ -26,32 +26,32 @@ import ( const startJupyterCommand = "notebook --no-browser --port=8888 --ip=0.0.0.0 --NotebookApp.token='' --NotebookApp.password=''" // OpenJupyterIDE manages the installation and startup of a Jupyter IDE on a remote target. -func OpenJupyterIDE(activeProfile config.Profile, targetId, projectName, projectProviderMetadata string, yesFlag bool, gpgKey string) error { +func OpenJupyterIDE(activeProfile config.Profile, targetId, workspaceName, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { // Ensure SSH config entry is added - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) // Check and install Python if necessary - if err := ensurePythonInstalled(projectHostname, yesFlag); err != nil { + if err := ensurePythonInstalled(workspaceHostname, yesFlag); err != nil { return err } // Check and install pip if necessary - if err := ensurePipInstalled(projectHostname, yesFlag); err != nil { + if err := ensurePipInstalled(workspaceHostname, yesFlag); err != nil { return err } // Check and install Jupyter Notebook if necessary - if err := ensureJupyterInstalled(projectHostname); err != nil { + if err := ensureJupyterInstalled(workspaceHostname); err != nil { return err } // Start Jupyter Notebook server - if err := startJupyterServer(projectHostname, activeProfile, targetId, projectName, gpgKey); err != nil { + if err := startJupyterServer(workspaceHostname, activeProfile, targetId, workspaceName, gpgKey); err != nil { return err } @@ -216,8 +216,8 @@ func ensureJupyterInstalled(hostname string) error { } // startJupyterServer starts the Jupyter Notebook server on the remote target. -func startJupyterServer(hostname string, activeProfile config.Profile, targetId, projectName string, gpgKey string) error { - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) +func startJupyterServer(hostname string, activeProfile config.Profile, targetId, workspaceName string, gpgKey string) error { + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } @@ -226,7 +226,7 @@ func startJupyterServer(hostname string, activeProfile config.Profile, targetId, // Start Jupyter Notebook server in the background go func() { - cmd := exec.CommandContext(context.Background(), "ssh", hostname, fmt.Sprintf(". ~/.jupyter_venv/bin/activate && cd %s && jupyter %s", projectDir, startJupyterCommand)) + cmd := exec.CommandContext(context.Background(), "ssh", hostname, fmt.Sprintf(". ~/.jupyter_venv/bin/activate && cd %s && jupyter %s", workspaceDir, startJupyterCommand)) cmd.Stdout = io.Writer(&util.DebugLogWriter{}) cmd.Stderr = io.Writer(&util.DebugLogWriter{}) if err := cmd.Run(); err != nil { @@ -235,7 +235,7 @@ func startJupyterServer(hostname string, activeProfile config.Profile, targetId, }() // Forward the IDE port - browserPort, errChan := tailscale.ForwardPort(targetId, projectName, 8888, activeProfile) + browserPort, errChan := tailscale.ForwardPort(targetId, workspaceName, 8888, activeProfile) if browserPort == nil { if err := <-errChan; err != nil { return err @@ -246,7 +246,7 @@ func startJupyterServer(hostname string, activeProfile config.Profile, targetId, ideURL := fmt.Sprintf("http://localhost:%d", *browserPort) waitForPort(*browserPort) - views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s Jupyter Notebook port to %s.\nOpening browser...\n", projectName, ideURL)) + views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s Jupyter Notebook port to %s.\nOpening browser...\n", workspaceName, ideURL)) if err := browser.OpenURL(ideURL); err != nil { log.Error("Error opening URL: " + err.Error()) diff --git a/pkg/ide/positron.go b/pkg/ide/positron.go index f54ae3543a..0842696756 100644 --- a/pkg/ide/positron.go +++ b/pkg/ide/positron.go @@ -15,20 +15,20 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenPositron(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenPositron(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetPositronBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) if runtime.GOARCH == "arm64" { printPositronDisclaimer() } @@ -39,11 +39,11 @@ func OpenPositron(activeProfile config.Profile, targetId string, projectName str return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.positron-server/*/bin/positron-server", "$HOME/.positron-server/data/Machine/settings.json", ".daytona-customizations-lock-positron") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.positron-server/*/bin/positron-server", "$HOME/.positron-server/data/Machine/settings.json", ".daytona-customizations-lock-positron") } func GetPositronBinaryPath() (string, error) { diff --git a/pkg/ide/terminal.go b/pkg/ide/terminal.go index ee286d05bd..945bb6c4d3 100644 --- a/pkg/ide/terminal.go +++ b/pkg/ide/terminal.go @@ -12,8 +12,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func OpenTerminalSsh(activeProfile config.Profile, targetId string, projectName string, gpgKey string, sshOptions []string, args ...string) error { - if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, projectName, gpgKey); err != nil { +func OpenTerminalSsh(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string, sshOptions []string, args ...string) error { + if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey); err != nil { return err } @@ -23,8 +23,8 @@ func OpenTerminalSsh(activeProfile config.Profile, targetId string, projectName return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - cmdArgs := buildCommandArgs(projectHostname, parsedOptions, args...) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + cmdArgs := buildCommandArgs(workspaceHostname, parsedOptions, args...) sshCommand := exec.Command("ssh", cmdArgs...) sshCommand.Stdin = os.Stdin @@ -50,8 +50,8 @@ func parseSshOptions(sshOptions []string) (map[string]string, error) { return parsedOptions, nil } -func buildCommandArgs(projectHostname string, parsedOptions map[string]string, args ...string) []string { - cmdArgs := []string{projectHostname} +func buildCommandArgs(workspaceHostname string, parsedOptions map[string]string, args ...string) []string { + cmdArgs := []string{workspaceHostname} for key, value := range parsedOptions { cmdArgs = append(cmdArgs, "-o", fmt.Sprintf("%s=%s", key, value)) } diff --git a/pkg/ide/vscode-insiders.go b/pkg/ide/vscode-insiders.go index 3f63cb8b7f..f753714aaf 100644 --- a/pkg/ide/vscode-insiders.go +++ b/pkg/ide/vscode-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgKey string) error { +func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { path, err := GetVSCodeInsidersBinaryPath() if err != nil { return err @@ -23,14 +23,14 @@ func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, projectNa return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgKey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) vscCommand := exec.Command(path, "--disable-extension", "ms-vscode-remote.remote-containers", "--folder-uri", commandArgument) @@ -39,11 +39,11 @@ func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, projectNa return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.vscode-server-insiders/*/bin/code-server-insiders", "$HOME/.vscode-server-insiders/data/Machine/settings.json", ".daytona-customizations-lock-vscode-insiders") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.vscode-server-insiders/*/bin/code-server-insiders", "$HOME/.vscode-server-insiders/data/Machine/settings.json", ".daytona-customizations-lock-vscode-insiders") } func GetVSCodeInsidersBinaryPath() (string, error) { diff --git a/pkg/ide/vscode.go b/pkg/ide/vscode.go index f37248adbd..46aae1fb1d 100644 --- a/pkg/ide/vscode.go +++ b/pkg/ide/vscode.go @@ -19,21 +19,21 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenVSCode(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgKey string) error { +func OpenVSCode(activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, gpgKey string) error { CheckAndAlertVSCodeInstalled() err := installRemoteSSHExtension("code") if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) vscCommand := exec.Command("code", "--disable-extension", "ms-vscode-remote.remote-containers", "--folder-uri", commandArgument) @@ -42,16 +42,16 @@ func OpenVSCode(activeProfile config.Profile, targetId string, projectName strin return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.vscode-server/*/bin/code-server", "$HOME/.vscode-server/data/Machine/settings.json", ".daytona-customizations-lock-vscode") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.vscode-server/*/bin/code-server", "$HOME/.vscode-server/data/Machine/settings.json", ".daytona-customizations-lock-vscode") } -func setupVSCodeCustomizations(projectHostname string, projectProviderMetadata string, tool devcontainer.Tool, codeServerPath string, settingsPath string, lockFileName string) error { +func setupVSCodeCustomizations(workspaceHostname string, workspaceProviderMetadata string, tool devcontainer.Tool, codeServerPath string, settingsPath string, lockFileName string) error { // Check if customizations are already set up - err := exec.Command("ssh", projectHostname, "test", "-f", fmt.Sprintf("$HOME/%s-%s", lockFileName, string(tool))).Run() + err := exec.Command("ssh", workspaceHostname, "test", "-f", fmt.Sprintf("$HOME/%s-%s", lockFileName, string(tool))).Run() if err == nil { return nil } @@ -59,7 +59,7 @@ func setupVSCodeCustomizations(projectHostname string, projectProviderMetadata s fmt.Println("Setting up IDE customizations...") var metadata map[string]interface{} - if err := json.Unmarshal([]byte(projectProviderMetadata), &metadata); err != nil { + if err := json.Unmarshal([]byte(workspaceProviderMetadata), &metadata); err != nil { return err } @@ -94,7 +94,7 @@ func setupVSCodeCustomizations(projectHostname string, projectProviderMetadata s time.Sleep(2 * time.Second) // Wait for code to be installed var err error - if vscodePath, err = exec.Command("ssh", projectHostname, "find", "$HOME", "-path", fmt.Sprintf(`"%s"`, codeServerPath)).Output(); err == nil && len(vscodePath) > 0 { + if vscodePath, err = exec.Command("ssh", workspaceHostname, "find", "$HOME", "-path", fmt.Sprintf(`"%s"`, codeServerPath)).Output(); err == nil && len(vscodePath) > 0 { break } } @@ -106,7 +106,7 @@ func setupVSCodeCustomizations(projectHostname string, projectProviderMetadata s } args := []string{ - projectHostname, + workspaceHostname, strings.TrimRight(string(vscodePath), "\n"), "--accept-server-license-terms", } @@ -122,14 +122,14 @@ func setupVSCodeCustomizations(projectHostname string, projectProviderMetadata s } } - err := setupVSCodeSettings(projectHostname, mergedCustomizations, settingsPath) + err := setupVSCodeSettings(workspaceHostname, mergedCustomizations, settingsPath) if err != nil { log.Errorf("Failed to set IDE settings: %s", err) } } // Create lock file to indicate that customizations are set up - err = exec.Command("ssh", projectHostname, "touch", fmt.Sprintf("$HOME/%s-%s", lockFileName, string(tool))).Run() + err = exec.Command("ssh", workspaceHostname, "touch", fmt.Sprintf("$HOME/%s-%s", lockFileName, string(tool))).Run() if err != nil { return err } @@ -138,12 +138,12 @@ func setupVSCodeCustomizations(projectHostname string, projectProviderMetadata s return nil } -func setupVSCodeSettings(projectHostname string, customizations *devcontainer.Customizations, settingsPath string) error { +func setupVSCodeSettings(workspaceHostname string, customizations *devcontainer.Customizations, settingsPath string) error { if customizations == nil { return nil } - content, err := exec.Command("ssh", projectHostname, "cat", settingsPath).Output() + content, err := exec.Command("ssh", workspaceHostname, "cat", settingsPath).Output() if err != nil { content = []byte("{}") } @@ -170,7 +170,7 @@ func setupVSCodeSettings(projectHostname string, customizations *devcontainer.Cu return err } - err = exec.Command("ssh", projectHostname, "echo", fmt.Sprintf(`'%s'`, string(settingsJson)), ">", settingsPath).Run() + err = exec.Command("ssh", workspaceHostname, "echo", fmt.Sprintf(`'%s'`, string(settingsJson)), ">", settingsPath).Run() if err != nil { return err } diff --git a/pkg/ide/vscodium-insiders.go b/pkg/ide/vscodium-insiders.go index 7db918e98e..22e727814b 100644 --- a/pkg/ide/vscodium-insiders.go +++ b/pkg/ide/vscodium-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetCodiumInsidersBinaryPath() if err != nil { return err @@ -23,14 +23,15 @@ func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, project if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) codiumInsidersCommand := exec.Command(path, "--disable-extension", "ms-vscode-remote.remote-containers", "--folder-uri", commandArgument) @@ -39,11 +40,11 @@ func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, project return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.vscodium-server-insiders/*/bin/codium-server-insiders", "$HOME/.vscodium-server-insiders/data/Machine/settings.json", ".daytona-customizations-lock-codium-insiders") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.vscodium-server-insiders/*/bin/codium-server-insiders", "$HOME/.vscodium-server-insiders/data/Machine/settings.json", ".daytona-customizations-lock-codium-insiders") } func GetCodiumInsidersBinaryPath() (string, error) { diff --git a/pkg/ide/vscodium.go b/pkg/ide/vscodium.go index 4d9bf68a94..b1be03618c 100644 --- a/pkg/ide/vscodium.go +++ b/pkg/ide/vscodium.go @@ -16,7 +16,7 @@ import ( const requiredExtension = "jeanp413.open-remote-ssh" -func OpenVScodium(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenVScodium(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetCodiumBinaryPath() if err != nil { return err @@ -26,14 +26,15 @@ func OpenVScodium(activeProfile config.Profile, targetId string, projectName str if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) codiumCommand := exec.Command(path, "--disable-extension", "ms-vscode-remote.remote-containers", "--folder-uri", commandArgument) @@ -42,11 +43,11 @@ func OpenVScodium(activeProfile config.Profile, targetId string, projectName str return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.vscodium-server/*/bin/codium-server", "$HOME/.vscodium-server/data/Machine/settings.json", ".daytona-customizations-lock-codium") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.vscodium-server/*/bin/codium-server", "$HOME/.vscodium-server/data/Machine/settings.json", ".daytona-customizations-lock-codium") } func GetCodiumBinaryPath() (string, error) { diff --git a/pkg/ide/windsurf.go b/pkg/ide/windsurf.go index 7984007d5c..339e54d0e7 100644 --- a/pkg/ide/windsurf.go +++ b/pkg/ide/windsurf.go @@ -13,20 +13,20 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenWindsurf(activeProfile config.Profile, targetId string, projectName string, projectProviderMetadata string, gpgkey string) error { +func OpenWindsurf(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetWindsurfBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) if err != nil { return err } - commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", projectHostname, projectDir) + commandArgument := fmt.Sprintf("vscode-remote://ssh-remote+%s/%s", workspaceHostname, workspaceDir) windsurfCommand := exec.Command(path, "--disable-extension", "ms-vscode-remote.remote-containers", "--folder-uri", commandArgument) @@ -35,11 +35,11 @@ func OpenWindsurf(activeProfile config.Profile, targetId string, projectName str return err } - if projectProviderMetadata == "" { + if workspaceProviderMetadata == "" { return nil } - return setupVSCodeCustomizations(projectHostname, projectProviderMetadata, devcontainer.Vscode, "*/.windsurf-server/*/bin/windsurf-server", "$HOME/.windsurf-server/data/Machine/settings.json", ".daytona-customizations-lock-windsurf") + return setupVSCodeCustomizations(workspaceHostname, workspaceProviderMetadata, devcontainer.Vscode, "*/.windsurf-server/*/bin/windsurf-server", "$HOME/.windsurf-server/data/Machine/settings.json", ".daytona-customizations-lock-windsurf") } func GetWindsurfBinaryPath() (string, error) { diff --git a/pkg/ide/zed.go b/pkg/ide/zed.go index 1bc939a965..a8c1d574ac 100644 --- a/pkg/ide/zed.go +++ b/pkg/ide/zed.go @@ -14,19 +14,19 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenZed(activeProfile config.Profile, targetId, projectName, gpgKey string) error { +func OpenZed(activeProfile config.Profile, targetId, workspaceName, gpgKey string) error { path, err := GetZedBinaryPath() if err != nil { return err } - projectHostname := config.GetProjectHostname(activeProfile.Id, targetId, projectName) - projectDir, err := util.GetProjectDir(activeProfile, targetId, projectName, gpgKey) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) if err != nil { return err } printDisclaimer() - zedCmd := exec.Command(path, fmt.Sprintf("ssh://%s%s", projectHostname, projectDir)) + zedCmd := exec.Command(path, fmt.Sprintf("ssh://%s%s", workspaceHostname, workspaceDir)) err = zedCmd.Run() if err != nil { diff --git a/pkg/logs/logger.go b/pkg/logs/logger.go index 3c88daa5d6..32118ad848 100644 --- a/pkg/logs/logger.go +++ b/pkg/logs/logger.go @@ -23,21 +23,21 @@ const ( ) type LogEntry struct { - Source string `json:"source"` - TargetId *string `json:"targetId,omitempty"` - ProjectName *string `json:"projectName,omitempty"` - BuildId *string `json:"buildId,omitempty"` - Msg string `json:"msg"` - Level string `json:"level"` - Time string `json:"time"` + Source string `json:"source"` + TargetId *string `json:"targetId,omitempty"` + WorkspaceName *string `json:"workspaceName,omitempty"` + BuildId *string `json:"buildId,omitempty"` + Msg string `json:"msg"` + Level string `json:"level"` + Time string `json:"time"` } type LoggerFactory interface { CreateTargetLogger(targetId string, source LogSource) Logger - CreateProjectLogger(targetId, projectName string, source LogSource) Logger + CreateWorkspaceLogger(targetId, workspaceName string, source LogSource) Logger CreateBuildLogger(buildId string, source LogSource) Logger CreateTargetLogReader(targetId string) (io.Reader, error) - CreateProjectLogReader(targetId, projectName string) (io.Reader, error) + CreateWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) CreateBuildLogReader(buildId string) (io.Reader, error) } diff --git a/pkg/logs/project.go b/pkg/logs/workspace.go similarity index 51% rename from pkg/logs/project.go rename to pkg/logs/workspace.go index 0e05bc6176..06c81b317e 100644 --- a/pkg/logs/project.go +++ b/pkg/logs/workspace.go @@ -13,18 +13,18 @@ import ( "github.com/sirupsen/logrus" ) -type projectLogger struct { - logsDir string - targetId string - projectName string - logFile *os.File - logger *logrus.Logger - source LogSource +type workspaceLogger struct { + logsDir string + targetId string + workspaceName string + logFile *os.File + logger *logrus.Logger + source LogSource } -func (pl *projectLogger) Write(p []byte) (n int, err error) { +func (pl *workspaceLogger) Write(p []byte) (n int, err error) { if pl.logFile == nil { - filePath := filepath.Join(pl.logsDir, pl.targetId, pl.projectName, "log") + filePath := filepath.Join(pl.logsDir, pl.targetId, pl.workspaceName, "log") err = os.MkdirAll(filepath.Dir(filePath), 0755) if err != nil { return len(p), err @@ -42,7 +42,7 @@ func (pl *projectLogger) Write(p []byte) (n int, err error) { entry.Msg = string(p) entry.Source = string(pl.source) entry.TargetId = &pl.targetId - entry.ProjectName = &pl.projectName + entry.WorkspaceName = &pl.workspaceName entry.Time = time.Now().Format(time.RFC3339) b, err := json.Marshal(entry) @@ -60,7 +60,7 @@ func (pl *projectLogger) Write(p []byte) (n int, err error) { return len(p), nil } -func (pl *projectLogger) Close() error { +func (pl *workspaceLogger) Close() error { if pl.logFile != nil { err := pl.logFile.Close() pl.logFile = nil @@ -69,32 +69,32 @@ func (pl *projectLogger) Close() error { return nil } -func (pl *projectLogger) Cleanup() error { - projectLogsDir := filepath.Join(pl.logsDir, pl.targetId, pl.projectName) +func (pl *workspaceLogger) Cleanup() error { + workspaceLogsDir := filepath.Join(pl.logsDir, pl.targetId, pl.workspaceName) - _, err := os.Stat(projectLogsDir) + _, err := os.Stat(workspaceLogsDir) if os.IsNotExist(err) { return nil } else if err != nil { return err } - return os.RemoveAll(projectLogsDir) + return os.RemoveAll(workspaceLogsDir) } -func (l *loggerFactoryImpl) CreateProjectLogger(targetId, projectName string, source LogSource) Logger { +func (l *loggerFactoryImpl) CreateWorkspaceLogger(targetId, workspaceName string, source LogSource) Logger { logger := logrus.New() - return &projectLogger{ - targetId: targetId, - logsDir: l.targetLogsDir, - projectName: projectName, - logger: logger, - source: source, + return &workspaceLogger{ + targetId: targetId, + logsDir: l.targetLogsDir, + workspaceName: workspaceName, + logger: logger, + source: source, } } -func (l *loggerFactoryImpl) CreateProjectLogReader(targetId, projectName string) (io.Reader, error) { - filePath := filepath.Join(l.targetLogsDir, targetId, projectName, "log") +func (l *loggerFactoryImpl) CreateWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) { + filePath := filepath.Join(l.targetLogsDir, targetId, workspaceName, "log") return os.Open(filePath) } diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index af658bfd3e..182a538f2b 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -8,7 +8,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider/util" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/hashicorp/go-plugin" ) @@ -26,11 +26,11 @@ type Provider interface { DestroyTarget(*TargetRequest) (*util.Empty, error) GetTargetInfo(*TargetRequest) (*target.TargetInfo, error) - CreateProject(*ProjectRequest) (*util.Empty, error) - StartProject(*ProjectRequest) (*util.Empty, error) - StopProject(*ProjectRequest) (*util.Empty, error) - DestroyProject(*ProjectRequest) (*util.Empty, error) - GetProjectInfo(*ProjectRequest) (*project.ProjectInfo, error) + CreateWorkspace(*WorkspaceRequest) (*util.Empty, error) + StartWorkspace(*WorkspaceRequest) (*util.Empty, error) + StopWorkspace(*WorkspaceRequest) (*util.Empty, error) + DestroyWorkspace(*WorkspaceRequest) (*util.Empty, error) + GetWorkspaceInfo(*WorkspaceRequest) (*workspace.WorkspaceInfo, error) } type ProviderPlugin struct { diff --git a/pkg/provider/rpc_client.go b/pkg/provider/rpc_client.go index db6281fa8e..bfa5928968 100644 --- a/pkg/provider/rpc_client.go +++ b/pkg/provider/rpc_client.go @@ -8,7 +8,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider/util" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) type ProviderRPCClient struct { @@ -71,28 +71,28 @@ func (m *ProviderRPCClient) GetTargetInfo(targetReq *TargetRequest) (*target.Tar return &response, err } -func (m *ProviderRPCClient) CreateProject(projectReq *ProjectRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.CreateProject", projectReq, new(util.Empty)) +func (m *ProviderRPCClient) CreateWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.CreateWorkspace", workspaceReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) StartProject(projectReq *ProjectRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.StartProject", projectReq, new(util.Empty)) +func (m *ProviderRPCClient) StartWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.StartWorkspace", workspaceReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) StopProject(projectReq *ProjectRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.StopProject", projectReq, new(util.Empty)) +func (m *ProviderRPCClient) StopWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.StopWorkspace", workspaceReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) DestroyProject(projectReq *ProjectRequest) (*util.Empty, error) { - err := m.client.Call("Plugin.DestroyProject", projectReq, new(util.Empty)) +func (m *ProviderRPCClient) DestroyWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { + err := m.client.Call("Plugin.DestroyWorkspace", workspaceReq, new(util.Empty)) return new(util.Empty), err } -func (m *ProviderRPCClient) GetProjectInfo(projectReq *ProjectRequest) (*project.ProjectInfo, error) { - var resp project.ProjectInfo - err := m.client.Call("Plugin.GetProjectInfo", projectReq, &resp) +func (m *ProviderRPCClient) GetWorkspaceInfo(workspaceReq *WorkspaceRequest) (*workspace.WorkspaceInfo, error) { + var resp workspace.WorkspaceInfo + err := m.client.Call("Plugin.GetWorkspaceInfo", workspaceReq, &resp) return &resp, err } diff --git a/pkg/provider/rpc_server.go b/pkg/provider/rpc_server.go index 691411dec6..54e5d5fc5e 100644 --- a/pkg/provider/rpc_server.go +++ b/pkg/provider/rpc_server.go @@ -6,7 +6,7 @@ package provider import ( "github.com/daytonaio/daytona/pkg/provider/util" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) type ProviderRPCServer struct { @@ -87,28 +87,28 @@ func (m *ProviderRPCServer) GetTargetInfo(arg *TargetRequest, resp *target.Targe return nil } -func (m *ProviderRPCServer) CreateProject(arg *ProjectRequest, resp *util.Empty) error { - _, err := m.Impl.CreateProject(arg) +func (m *ProviderRPCServer) CreateWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { + _, err := m.Impl.CreateWorkspace(arg) return err } -func (m *ProviderRPCServer) StartProject(arg *ProjectRequest, resp *util.Empty) error { - _, err := m.Impl.StartProject(arg) +func (m *ProviderRPCServer) StartWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { + _, err := m.Impl.StartWorkspace(arg) return err } -func (m *ProviderRPCServer) StopProject(arg *ProjectRequest, resp *util.Empty) error { - _, err := m.Impl.StopProject(arg) +func (m *ProviderRPCServer) StopWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { + _, err := m.Impl.StopWorkspace(arg) return err } -func (m *ProviderRPCServer) DestroyProject(arg *ProjectRequest, resp *util.Empty) error { - _, err := m.Impl.DestroyProject(arg) +func (m *ProviderRPCServer) DestroyWorkspace(arg *WorkspaceRequest, resp *util.Empty) error { + _, err := m.Impl.DestroyWorkspace(arg) return err } -func (m *ProviderRPCServer) GetProjectInfo(arg *ProjectRequest, resp *project.ProjectInfo) error { - info, err := m.Impl.GetProjectInfo(arg) +func (m *ProviderRPCServer) GetWorkspaceInfo(arg *WorkspaceRequest, resp *workspace.WorkspaceInfo) error { + info, err := m.Impl.GetWorkspaceInfo(arg) if err != nil { return err } diff --git a/pkg/provider/types.go b/pkg/provider/types.go index 9447244fc0..6a1f08e1c6 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -7,7 +7,7 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) type ProviderInfo struct { @@ -36,10 +36,10 @@ type TargetRequest struct { Target *target.Target } -type ProjectRequest struct { +type WorkspaceRequest struct { TargetConfigOptions string ContainerRegistry *containerregistry.ContainerRegistry - Project *project.Project + Workspace *workspace.Workspace GitProviderConfig *gitprovider.GitProviderConfig BuilderImage string BuilderContainerRegistry *containerregistry.ContainerRegistry diff --git a/pkg/provider/util/project_start_script.go b/pkg/provider/util/workspace_start_script.go similarity index 96% rename from pkg/provider/util/project_start_script.go rename to pkg/provider/util/workspace_start_script.go index f3d86dfc11..837253509d 100644 --- a/pkg/provider/util/project_start_script.go +++ b/pkg/provider/util/workspace_start_script.go @@ -96,7 +96,7 @@ if test -n "$MISSING_DEPS"; then fi ` -func GetProjectStartScript(daytonaDownloadUrl string, apiKey string) string { +func GetWorkspaceStartScript(daytonaDownloadUrl string, apiKey string) string { return fmt.Sprintf(` %s # Download and install Daytona agent diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index 6a4d55ea56..10d0e0d76b 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -22,15 +22,15 @@ func (p *Provisioner) CreateTarget(target *target.Target, targetConfig *provider return err } -func (p *Provisioner) CreateProject(params ProjectParams) error { +func (p *Provisioner) CreateWorkspace(params WorkspaceParams) error { targetProvider, err := p.providerManager.GetProvider(params.TargetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).CreateProject(&provider.ProjectRequest{ + _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ TargetConfigOptions: params.TargetConfig.Options, - Project: params.Project, + Workspace: params.Workspace, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, BuilderImage: params.BuilderImage, diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index 2e989e0122..998f52e182 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -6,7 +6,7 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) func (p *Provisioner) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error { @@ -23,15 +23,15 @@ func (p *Provisioner) DestroyTarget(target *target.Target, targetConfig *provide return err } -func (p *Provisioner) DestroyProject(proj *project.Project, targetConfig *provider.TargetConfig) error { +func (p *Provisioner) DestroyWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).DestroyProject(&provider.ProjectRequest{ + _, err = (*targetProvider).DestroyWorkspace(&provider.WorkspaceRequest{ TargetConfigOptions: targetConfig.Options, - Project: proj, + Workspace: ws, }) return err diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index 3a21ee2e9a..58fdbee3b7 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -11,11 +11,11 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) -type ProjectParams struct { - Project *project.Project +type WorkspaceParams struct { + Workspace *workspace.Workspace TargetConfig *provider.TargetConfig ContainerRegistry *containerregistry.ContainerRegistry GitProviderConfig *gitprovider.GitProviderConfig @@ -30,10 +30,10 @@ type IProvisioner interface { GetTargetInfo(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error - CreateProject(params ProjectParams) error - DestroyProject(project *project.Project, targetConfig *provider.TargetConfig) error - StartProject(params ProjectParams) error - StopProject(project *project.Project, targetConfig *provider.TargetConfig) error + CreateWorkspace(params WorkspaceParams) error + DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error + StartWorkspace(params WorkspaceParams) error + StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error } type ProvisionerConfig struct { diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index f71a1f6e59..ff05d0bc8c 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -22,15 +22,15 @@ func (p *Provisioner) StartTarget(target *target.Target, targetConfig *provider. return err } -func (p *Provisioner) StartProject(params ProjectParams) error { +func (p *Provisioner) StartWorkspace(params WorkspaceParams) error { targetProvider, err := p.providerManager.GetProvider(params.TargetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).StartProject(&provider.ProjectRequest{ + _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ TargetConfigOptions: params.TargetConfig.Options, - Project: params.Project, + Workspace: params.Workspace, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, BuilderImage: params.BuilderImage, diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index efda1d5ee6..cc77456865 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -6,7 +6,7 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) func (p *Provisioner) StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error { @@ -23,15 +23,15 @@ func (p *Provisioner) StopTarget(target *target.Target, targetConfig *provider.T return err } -func (p *Provisioner) StopProject(proj *project.Project, targetConfig *provider.TargetConfig) error { +func (p *Provisioner) StopWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { return err } - _, err = (*targetProvider).StopProject(&provider.ProjectRequest{ + _, err = (*targetProvider).StopWorkspace(&provider.WorkspaceRequest{ TargetConfigOptions: targetConfig.Options, - Project: proj, + Workspace: ws, }) return err diff --git a/pkg/server/apikeys/apikeys_test.go b/pkg/server/apikeys/apikeys_test.go index 9e88b26786..9ab9ca3092 100644 --- a/pkg/server/apikeys/apikeys_test.go +++ b/pkg/server/apikeys/apikeys_test.go @@ -28,7 +28,7 @@ func (s *ApiKeyServiceTestSuite) TestRevoke() { keyNames := []string{} keyNames = append(keyNames, clientKeyNames[1:]...) - keyNames = append(keyNames, projectKeyNames...) + keyNames = append(keyNames, workspaceKeyNames...) for _, keyName := range keyNames { apiKey, _ := s.apiKeyStore.FindByName(keyName) expectedKeys = append(expectedKeys, apiKey) @@ -49,7 +49,7 @@ func (s *ApiKeyServiceTestSuite) TestGenerate() { keyNames := []string{} keyNames = append(keyNames, clientKeyNames...) - keyNames = append(keyNames, projectKeyNames...) + keyNames = append(keyNames, workspaceKeyNames...) for _, keyName := range keyNames { apiKey, _ := s.apiKeyStore.FindByName(keyName) expectedKeys = append(expectedKeys, apiKey) diff --git a/pkg/server/apikeys/service.go b/pkg/server/apikeys/service.go index 272dec8d60..83b1c5074d 100644 --- a/pkg/server/apikeys/service.go +++ b/pkg/server/apikeys/service.go @@ -7,7 +7,7 @@ import "github.com/daytonaio/daytona/pkg/apikey" type IApiKeyService interface { Generate(keyType apikey.ApiKeyType, name string) (string, error) - IsProjectApiKey(apiKey string) bool + IsWorkspaceApiKey(apiKey string) bool IsTargetApiKey(apiKey string) bool IsValidApiKey(apiKey string) bool ListClientKeys() ([]*apikey.ApiKey, error) diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index cb6f74849d..9b4ef92d2e 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -13,7 +13,7 @@ import ( ) var clientKeyNames []string = []string{"client1", "client2", "client3"} -var projectKeyNames []string = []string{"project1", "project2"} +var workspaceKeyNames []string = []string{"workspace1", "workspace2"} type ApiKeyServiceTestSuite struct { suite.Suite @@ -35,8 +35,8 @@ func (s *ApiKeyServiceTestSuite) SetupTest() { _, _ = s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) } - for _, keyName := range projectKeyNames { - _, _ = s.apiKeyService.Generate(apikey.ApiKeyTypeProject, keyName) + for _, keyName := range workspaceKeyNames { + _, _ = s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) } } diff --git a/pkg/server/apikeys/validate.go b/pkg/server/apikeys/validate.go index a065a91db5..c5372011cf 100644 --- a/pkg/server/apikeys/validate.go +++ b/pkg/server/apikeys/validate.go @@ -15,7 +15,7 @@ func (s *ApiKeyService) IsValidApiKey(apiKey string) bool { return err == nil } -func (s *ApiKeyService) IsProjectApiKey(apiKey string) bool { +func (s *ApiKeyService) IsWorkspaceApiKey(apiKey string) bool { keyHash := apikeys.HashKey(apiKey) key, err := s.apiKeyStore.Find(keyHash) @@ -23,7 +23,7 @@ func (s *ApiKeyService) IsProjectApiKey(apiKey string) bool { return false } - if key.Type != apikey.ApiKeyTypeProject { + if key.Type != apikey.ApiKeyTypeWorkspace { return false } diff --git a/pkg/server/apikeys/validate_test.go b/pkg/server/apikeys/validate_test.go index 996c93ce7a..040100062f 100644 --- a/pkg/server/apikeys/validate_test.go +++ b/pkg/server/apikeys/validate_test.go @@ -10,7 +10,7 @@ func (s *ApiKeyServiceTestSuite) TestIsValidKey_True() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeProject, keyName) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) require.Nil(err) res := s.apiKeyService.IsValidApiKey(apiKey) @@ -26,19 +26,19 @@ func (s *ApiKeyServiceTestSuite) TestIsValidKey_False() { require.False(res) } -func (s *ApiKeyServiceTestSuite) TestIsProjectApiKey_True() { - keyName := "projectKey" +func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_True() { + keyName := "workspaceKey" require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeProject, keyName) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) require.Nil(err) - res := s.apiKeyService.IsProjectApiKey(apiKey) + res := s.apiKeyService.IsWorkspaceApiKey(apiKey) require.True(res) } -func (s *ApiKeyServiceTestSuite) TestIsProjectApiKey_False() { +func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_False() { keyName := "clientKey" require := s.Require() @@ -46,7 +46,7 @@ func (s *ApiKeyServiceTestSuite) TestIsProjectApiKey_False() { apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) require.Nil(err) - res := s.apiKeyService.IsProjectApiKey(apiKey) + res := s.apiKeyService.IsWorkspaceApiKey(apiKey) require.False(res) } diff --git a/pkg/server/builds/dto/builds.go b/pkg/server/builds/dto/builds.go index 03cb9df14b..989b4a7916 100644 --- a/pkg/server/builds/dto/builds.go +++ b/pkg/server/builds/dto/builds.go @@ -5,7 +5,7 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) type BuildCreationData struct { diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index f7582bd423..d140d71fee 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/target/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" "github.com/docker/docker/pkg/stringid" ) diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index ed4804dad2..9aaefde7ca 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" - "github.com/daytonaio/daytona/pkg/target/project/containerconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" "github.com/stretchr/testify/suite" ) diff --git a/pkg/server/defaults.go b/pkg/server/defaults.go index 03b94bcfe1..a99d8839f0 100644 --- a/pkg/server/defaults.go +++ b/pkg/server/defaults.go @@ -23,8 +23,8 @@ const defaultSamplesIndexUrl = "https://raw.githubusercontent.com/daytonaio/dayt const defaultHeadscalePort = 3987 const defaultApiPort = 3986 const defaultBuilderImage = "daytonaio/workspace-project:latest" -const defaultProjectImage = "daytonaio/workspace-project:latest" -const defaultProjectUser = "daytona" +const defaultWorkspaceImage = "daytonaio/workspace-project:latest" +const defaultWorkspaceUser = "daytona" const defaultLocalBuilderRegistryPort = 3988 const defaultLocalBuilderRegistryImage = "registry:2.8.3" @@ -183,8 +183,8 @@ func getDefaultConfig() (*Config, error) { BinariesPath: binariesPath, Frps: getDefaultFRPSConfig(), LogFile: getDefaultLogFileConfig(), - DefaultProjectImage: defaultProjectImage, - DefaultProjectUser: defaultProjectUser, + DefaultWorkspaceImage: defaultWorkspaceImage, + DefaultWorkspaceUser: defaultWorkspaceUser, BuilderImage: defaultBuilderImage, LocalBuilderRegistryPort: defaultLocalBuilderRegistryPort, LocalBuilderRegistryImage: defaultLocalBuilderRegistryImage, diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index d4baf22866..ef716dac60 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -3,7 +3,7 @@ package gitproviders -import "github.com/daytonaio/daytona/pkg/target/project/config" +import "github.com/daytonaio/daytona/pkg/target/workspace/config" func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { gitProvider, err := s.configStore.Find(gitProviderId) @@ -11,8 +11,8 @@ func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { return err } - // Check if project configs need to be updated - projectConfigs, err := s.projectConfigStore.List(&config.ProjectConfigFilter{ + // Check if workspace configs need to be updated + workspaceConfigs, err := s.workspaceConfigStore.List(&config.WorkspaceConfigFilter{ GitProviderConfigId: &gitProviderId, }) @@ -20,9 +20,9 @@ func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { return err } - for _, projectConfig := range projectConfigs { - projectConfig.GitProviderConfigId = nil - err = s.projectConfigStore.Save(projectConfig) + for _, workspaceConfig := range workspaceConfigs { + workspaceConfig.GitProviderConfigId = nil + err = s.workspaceConfigStore.Save(workspaceConfig) if err != nil { return err } diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index 3fbc109d02..bbec5d149b 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project/config" + "github.com/daytonaio/daytona/pkg/target/workspace/config" ) type IGitProviderService interface { @@ -33,25 +33,25 @@ type IGitProviderService interface { UnregisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, id string) error } -type ProjectConfigStore interface { - Save(projectConfig *config.ProjectConfig) error - List(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) +type WorkspaceConfigStore interface { + Save(workspaceConfig *config.WorkspaceConfig) error + List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) } type GitProviderServiceConfig struct { - ConfigStore gitprovider.ConfigStore - ProjectConfigStore ProjectConfigStore + ConfigStore gitprovider.ConfigStore + WorkspaceConfigStore WorkspaceConfigStore } type GitProviderService struct { - configStore gitprovider.ConfigStore - projectConfigStore ProjectConfigStore + configStore gitprovider.ConfigStore + workspaceConfigStore WorkspaceConfigStore } func NewGitProviderService(config GitProviderServiceConfig) IGitProviderService { return &GitProviderService{ - configStore: config.ConfigStore, - projectConfigStore: config.ProjectConfigStore, + configStore: config.ConfigStore, + workspaceConfigStore: config.WorkspaceConfigStore, } } diff --git a/pkg/server/projectconfig/service.go b/pkg/server/projectconfig/service.go deleted file mode 100644 index 56d4e0f55e..0000000000 --- a/pkg/server/projectconfig/service.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig - -import ( - "strings" - - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" -) - -type IProjectConfigService interface { - Save(projectConfig *config.ProjectConfig) error - Find(filter *config.ProjectConfigFilter) (*config.ProjectConfig, error) - List(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) - SetDefault(projectConfigName string) error - Delete(projectConfigName string, force bool) []error - - SetPrebuild(projectConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) - FindPrebuild(projectConfigFilter *config.ProjectConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) - ListPrebuilds(projectConfigFilter *config.ProjectConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) - DeletePrebuild(projectConfigName string, id string, force bool) []error - - StartRetentionPoller() error - EnforceRetentionPolicy() error - ProcessGitEvent(gitprovider.GitEventData) error -} - -type ProjectConfigServiceConfig struct { - PrebuildWebhookEndpoint string - ConfigStore config.Store - BuildService builds.IBuildService - GitProviderService gitproviders.IGitProviderService -} - -type ProjectConfigService struct { - prebuildWebhookEndpoint string - configStore config.Store - buildService builds.IBuildService - gitProviderService gitproviders.IGitProviderService -} - -func NewProjectConfigService(config ProjectConfigServiceConfig) IProjectConfigService { - - return &ProjectConfigService{ - prebuildWebhookEndpoint: config.PrebuildWebhookEndpoint, - configStore: config.ConfigStore, - buildService: config.BuildService, - gitProviderService: config.GitProviderService, - } -} - -func (s *ProjectConfigService) List(filter *config.ProjectConfigFilter) ([]*config.ProjectConfig, error) { - return s.configStore.List(filter) -} - -func (s *ProjectConfigService) SetDefault(projectConfigName string) error { - projectConfig, err := s.Find(&config.ProjectConfigFilter{ - Name: &projectConfigName, - }) - if err != nil { - return err - } - - defaultProjectConfig, err := s.Find(&config.ProjectConfigFilter{ - Url: &projectConfig.RepositoryUrl, - Default: util.Pointer(true), - }) - if err != nil && err != config.ErrProjectConfigNotFound { - return err - } - - if defaultProjectConfig != nil { - defaultProjectConfig.IsDefault = false - err := s.configStore.Save(defaultProjectConfig) - if err != nil { - return err - } - } - - projectConfig.IsDefault = true - return s.configStore.Save(projectConfig) -} - -func (s *ProjectConfigService) Find(filter *config.ProjectConfigFilter) (*config.ProjectConfig, error) { - if filter != nil && filter.Url != nil { - cleanedUrl := util.CleanUpRepositoryUrl(*filter.Url) - if !strings.HasSuffix(cleanedUrl, ".git") { - cleanedUrl = cleanedUrl + ".git" - } - filter.Url = util.Pointer(cleanedUrl) - } - return s.configStore.Find(filter) -} - -func (s *ProjectConfigService) Save(projectConfig *config.ProjectConfig) error { - projectConfig.RepositoryUrl = util.CleanUpRepositoryUrl(projectConfig.RepositoryUrl) - - err := s.configStore.Save(projectConfig) - if err != nil { - return err - } - - return s.SetDefault(projectConfig.Name) -} - -func (s *ProjectConfigService) Delete(projectConfigName string, force bool) []error { - pc, err := s.Find(&config.ProjectConfigFilter{ - Name: &projectConfigName, - }) - if err != nil { - return []error{err} - } - - // DeletePrebuild handles deleting the builds and removing the webhook - for _, prebuild := range pc.Prebuilds { - errs := s.DeletePrebuild(pc.Name, prebuild.Id, force) - if len(errs) > 0 { - return errs - } - } - - err = s.configStore.Delete(pc) - if err != nil { - return []error{err} - } - - return nil -} diff --git a/pkg/server/projectconfig/service_test.go b/pkg/server/projectconfig/service_test.go deleted file mode 100644 index 2e2985c102..0000000000 --- a/pkg/server/projectconfig/service_test.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package projectconfig_test - -import ( - "testing" - - git_provider_mock "github.com/daytonaio/daytona/internal/testing/gitprovider/mocks" - projectconfig_internal "github.com/daytonaio/daytona/internal/testing/server/projectconfig" - "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/server/projectconfig" - "github.com/daytonaio/daytona/pkg/target/project/config" - "github.com/stretchr/testify/suite" -) - -var projectConfig1Image = "image1" -var projectConfig1User = "user1" - -var projectConfig1 *config.ProjectConfig = &config.ProjectConfig{ - Name: "pc1", - Image: projectConfig1Image, - User: projectConfig1User, - BuildConfig: nil, - RepositoryUrl: repository1.Url, - IsDefault: true, - Prebuilds: []*config.PrebuildConfig{ - prebuild1, - prebuild2, - }, -} - -var projectConfig2 *config.ProjectConfig = &config.ProjectConfig{ - Name: "pc2", - Image: "image2", - User: "user2", - BuildConfig: nil, - RepositoryUrl: "https://github.com/daytonaio/daytona.git", -} - -var projectConfig3 *config.ProjectConfig = &config.ProjectConfig{ - Name: "pc3", - Image: "image3", - User: "user3", - BuildConfig: nil, - RepositoryUrl: "https://github.com/daytonaio/daytona3.git", -} - -var projectConfig4 *config.ProjectConfig = &config.ProjectConfig{ - Name: "pc4", - Image: "image4", - User: "user4", - BuildConfig: nil, - RepositoryUrl: "https://github.com/daytonaio/daytona4.git", -} - -var expectedProjectConfigs []*config.ProjectConfig -var expectedFilteredProjectConfigs []*config.ProjectConfig - -var expectedProjectConfigsMap map[string]*config.ProjectConfig -var expectedFilteredProjectConfigsMap map[string]*config.ProjectConfig - -type ProjectConfigServiceTestSuite struct { - suite.Suite - projectConfigService projectconfig.IProjectConfigService - projectConfigStore config.Store - gitProviderService mocks.MockGitProviderService - buildService mocks.MockBuildService - gitProvider git_provider_mock.MockGitProvider -} - -func NewConfigServiceTestSuite() *ProjectConfigServiceTestSuite { - return &ProjectConfigServiceTestSuite{} -} - -func (s *ProjectConfigServiceTestSuite) SetupTest() { - expectedProjectConfigs = []*config.ProjectConfig{ - projectConfig1, projectConfig2, projectConfig3, - } - - expectedPrebuilds = []*config.PrebuildConfig{ - prebuild1, prebuild2, - } - - expectedProjectConfigsMap = map[string]*config.ProjectConfig{ - projectConfig1.Name: projectConfig1, - projectConfig2.Name: projectConfig2, - projectConfig3.Name: projectConfig3, - } - - expectedPrebuildsMap = map[string]*config.PrebuildConfig{ - prebuild1.Id: prebuild1, - prebuild2.Id: prebuild2, - } - - expectedFilteredProjectConfigs = []*config.ProjectConfig{ - projectConfig1, projectConfig2, - } - - expectedFilteredPrebuilds = []*config.PrebuildConfig{ - prebuild1, - } - - expectedFilteredProjectConfigsMap = map[string]*config.ProjectConfig{ - projectConfig1.Name: projectConfig1, - projectConfig2.Name: projectConfig2, - } - - expectedFilteredPrebuildsMap = map[string]*config.PrebuildConfig{ - prebuild1.Id: prebuild1, - } - - s.projectConfigStore = projectconfig_internal.NewInMemoryProjectConfigStore() - s.projectConfigService = projectconfig.NewProjectConfigService(projectconfig.ProjectConfigServiceConfig{ - ConfigStore: s.projectConfigStore, - GitProviderService: &s.gitProviderService, - BuildService: &s.buildService, - }) - - for _, pc := range expectedProjectConfigs { - _ = s.projectConfigStore.Save(pc) - } -} - -func TestProjectConfigService(t *testing.T) { - suite.Run(t, NewConfigServiceTestSuite()) -} - -func (s *ProjectConfigServiceTestSuite) TestList() { - require := s.Require() - - projectConfigs, err := s.projectConfigService.List(nil) - require.Nil(err) - require.ElementsMatch(expectedProjectConfigs, projectConfigs) -} - -func (s *ProjectConfigServiceTestSuite) TestFind() { - require := s.Require() - - projectConfig, err := s.projectConfigService.Find(&config.ProjectConfigFilter{ - Name: &projectConfig1.Name, - }) - require.Nil(err) - require.Equal(projectConfig1, projectConfig) -} -func (s *ProjectConfigServiceTestSuite) TestSetDefault() { - require := s.Require() - - err := s.projectConfigService.SetDefault(projectConfig2.Name) - require.Nil(err) - - projectConfig, err := s.projectConfigService.Find(&config.ProjectConfigFilter{ - Url: util.Pointer(projectConfig1.RepositoryUrl), - Default: util.Pointer(true), - }) - require.Nil(err) - - require.Equal(projectConfig2, projectConfig) -} - -func (s *ProjectConfigServiceTestSuite) TestSave() { - expectedProjectConfigs = append(expectedProjectConfigs, projectConfig4) - - require := s.Require() - - err := s.projectConfigService.Save(projectConfig4) - require.Nil(err) - - projectConfigs, err := s.projectConfigService.List(nil) - require.Nil(err) - require.ElementsMatch(expectedProjectConfigs, projectConfigs) -} - -func (s *ProjectConfigServiceTestSuite) TestDelete() { - expectedProjectConfigs = expectedProjectConfigs[:2] - - require := s.Require() - - err := s.projectConfigService.Delete(projectConfig3.Name, false) - require.Nil(err) - - projectConfigs, errs := s.projectConfigService.List(nil) - require.Nil(errs) - require.ElementsMatch(expectedProjectConfigs, projectConfigs) -} - -func (s *ProjectConfigServiceTestSuite) AfterTest(_, _ string) { - s.gitProviderService.AssertExpectations(s.T()) - s.gitProviderService.ExpectedCalls = nil - s.buildService.AssertExpectations(s.T()) - s.buildService.ExpectedCalls = nil - s.gitProvider.AssertExpectations(s.T()) - s.gitProvider.ExpectedCalls = nil -} diff --git a/pkg/server/server.go b/pkg/server/server.go index ec652e5c7c..beba393d27 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -13,9 +13,9 @@ import ( "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/profiledata" - "github.com/daytonaio/daytona/pkg/server/projectconfig" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/hashicorp/go-plugin" @@ -29,7 +29,7 @@ type ServerInstanceConfig struct { TargetConfigService targetconfigs.ITargetConfigService ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService - ProjectConfigService projectconfig.IProjectConfigService + WorkspaceConfigService workspaceconfig.IWorkspaceConfigService LocalContainerRegistry ILocalContainerRegistry TargetService targets.ITargetService ApiKeyService apikeys.IApiKeyService @@ -58,7 +58,7 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { TargetConfigService: serverConfig.TargetConfigService, ContainerRegistryService: serverConfig.ContainerRegistryService, BuildService: serverConfig.BuildService, - ProjectConfigService: serverConfig.ProjectConfigService, + WorkspaceConfigService: serverConfig.WorkspaceConfigService, LocalContainerRegistry: serverConfig.LocalContainerRegistry, TargetService: serverConfig.TargetService, ApiKeyService: serverConfig.ApiKeyService, @@ -80,7 +80,7 @@ type Server struct { TargetConfigService targetconfigs.ITargetConfigService ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService - ProjectConfigService projectconfig.IProjectConfigService + WorkspaceConfigService workspaceconfig.IWorkspaceConfigService LocalContainerRegistry ILocalContainerRegistry TargetService targets.ITargetService ApiKeyService apikeys.IApiKeyService diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index b53512136e..aba484b1d2 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -21,8 +21,8 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" @@ -68,19 +68,19 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT } target.ApiKey = apiKey - target.Projects = []*project.Project{} + target.Workspaces = []*workspace.Workspace{} - for _, projectDto := range req.Projects { - p := conversion.CreateDtoToProject(projectDto) + for _, workspaceDto := range req.Workspaces { + w := conversion.CreateDtoToWorkspace(workspaceDto) - isValidProjectName := regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`).MatchString - if !isValidProjectName(p.Name) { - return nil, ErrInvalidProjectName + isValidWorkspaceName := regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`).MatchString + if !isValidWorkspaceName(w.Name) { + return nil, ErrInvalidWorkspaceName } - p.Repository.Url = util.CleanUpRepositoryUrl(p.Repository.Url) - if p.GitProviderConfigId == nil || *p.GitProviderConfigId == "" { - configs, err := s.gitProviderService.ListConfigsForUrl(p.Repository.Url) + w.Repository.Url = util.CleanUpRepositoryUrl(w.Repository.Url) + if w.GitProviderConfigId == nil || *w.GitProviderConfigId == "" { + configs, err := s.gitProviderService.ListConfigsForUrl(w.Repository.Url) if err != nil { return nil, err } @@ -90,42 +90,42 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT } if len(configs) == 1 { - p.GitProviderConfigId = &configs[0].Id + w.GitProviderConfigId = &configs[0].Id } } - if p.Repository.Sha == "" { - sha, err := s.gitProviderService.GetLastCommitSha(p.Repository) + if w.Repository.Sha == "" { + sha, err := s.gitProviderService.GetLastCommitSha(w.Repository) if err != nil { return nil, err } - p.Repository.Sha = sha + w.Repository.Sha = sha } - if p.BuildConfig != nil { - cachedBuild, err := s.getCachedBuildForProject(p) + if w.BuildConfig != nil { + cachedBuild, err := s.getCachedBuildForWorkspace(w) if err == nil { - p.BuildConfig.CachedBuild = cachedBuild + w.BuildConfig.CachedBuild = cachedBuild } } - if p.Image == "" { - p.Image = s.defaultProjectImage + if w.Image == "" { + w.Image = s.defaultWorkspaceImage } - if p.User == "" { - p.User = s.defaultProjectUser + if w.User == "" { + w.User = s.defaultWorkspaceUser } - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeProject, fmt.Sprintf("%s/%s", target.Id, p.Name)) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, fmt.Sprintf("%s/%s", target.Id, w.Name)) if err != nil { return nil, err } - p.TargetId = target.Id - p.ApiKey = apiKey - p.TargetConfig = target.TargetConfig - target.Projects = append(target.Projects, p) + w.TargetId = target.Id + w.ApiKey = apiKey + w.TargetConfig = target.TargetConfig + target.Workspaces = append(target.Workspaces, w) } err = s.targetStore.Save(target) @@ -160,10 +160,10 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT return target, err } -func (s *TargetService) createProject(p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { - logWriter.Write([]byte(fmt.Sprintf("Creating project %s\n", p.Name))) +func (s *TargetService) createWorkspace(w *workspace.Workspace, targetConfig *provider.TargetConfig, logWriter io.Writer) error { + logWriter.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) - cr, err := s.containerRegistryService.FindByImageName(p.Image) + cr, err := s.containerRegistryService.FindByImageName(w.Image) if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { return err } @@ -175,15 +175,15 @@ func (s *TargetService) createProject(p *project.Project, targetConfig *provider var gc *gitprovider.GitProviderConfig - if p.GitProviderConfigId != nil { - gc, err = s.gitProviderService.GetConfig(*p.GitProviderConfigId) + if w.GitProviderConfigId != nil { + gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) if err != nil && !gitprovider.IsGitProviderNotFound(err) { return err } } - err = s.provisioner.CreateProject(provisioner.ProjectParams{ - Project: p, + err = s.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ + Workspace: w, TargetConfig: targetConfig, ContainerRegistry: cr, GitProviderConfig: gc, @@ -194,7 +194,7 @@ func (s *TargetService) createProject(p *project.Project, targetConfig *provider return err } - logWriter.Write([]byte(fmt.Sprintf("Project %s created\n", p.Name))) + logWriter.Write([]byte(fmt.Sprintf("Workspace %s created\n", w.Name))) return nil } @@ -217,33 +217,33 @@ func (s *TargetService) createTarget(ctx context.Context, t *target.Target, targ return nil, err } - for i, p := range t.Projects { - projectLogger := s.loggerFactory.CreateProjectLogger(t.Id, p.Name, logs.LogSourceServer) - defer projectLogger.Close() + for i, w := range t.Workspaces { + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(t.Id, w.Name, logs.LogSourceServer) + defer workspaceLogger.Close() - projectWithEnv := *p - projectWithEnv.EnvVars = project.GetProjectEnvVars(p, project.ProjectEnvVarParams{ + workspaceWithEnv := *w + workspaceWithEnv.EnvVars = workspace.GetWorkspaceEnvVars(w, workspace.WorkspaceEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - for k, v := range p.EnvVars { - projectWithEnv.EnvVars[k] = v + for k, v := range w.EnvVars { + workspaceWithEnv.EnvVars[k] = v } var err error - p = &projectWithEnv + w = &workspaceWithEnv - t.Projects[i] = p + t.Workspaces[i] = w err = s.targetStore.Save(t) if err != nil { return nil, err } - err = s.createProject(p, targetConfig, projectLogger) + err = s.createWorkspace(w, targetConfig, workspaceLogger) if err != nil { return nil, err } @@ -259,17 +259,17 @@ func (s *TargetService) createTarget(ctx context.Context, t *target.Target, targ return t, nil } -func (s *TargetService) getCachedBuildForProject(p *project.Project) (*buildconfig.CachedBuild, error) { +func (s *TargetService) getCachedBuildForWorkspace(w *workspace.Workspace) (*buildconfig.CachedBuild, error) { validStates := &[]build.BuildState{ build.BuildState(build.BuildStatePublished), } build, err := s.buildService.Find(&build.Filter{ States: validStates, - RepositoryUrl: &p.Repository.Url, - Branch: &p.Repository.Branch, - EnvVars: &p.EnvVars, - BuildConfig: p.BuildConfig, + RepositoryUrl: &w.Repository.Url, + Branch: &w.Repository.Branch, + EnvVars: &w.EnvVars, + BuildConfig: w.BuildConfig, GetNewest: util.Pointer(true), }) if err != nil { diff --git a/pkg/server/targets/dto/target.go b/pkg/server/targets/dto/target.go index f8b256681b..f8242b4889 100644 --- a/pkg/server/targets/dto/target.go +++ b/pkg/server/targets/dto/target.go @@ -6,8 +6,8 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) type TargetDTO struct { @@ -15,28 +15,28 @@ type TargetDTO struct { Info *target.TargetInfo `json:"info" validate:"optional"` } // @name TargetDTO -type ProjectDTO struct { - project.Project - Info *project.ProjectInfo `json:"info" validate:"optional"` -} // @name ProjectDTO +type WorkspaceDTO struct { + workspace.Workspace + Info *workspace.WorkspaceInfo `json:"info" validate:"optional"` +} // @name WorkspaceDTO type CreateTargetDTO struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - TargetConfig string `json:"targetConfig" validate:"required"` - Projects []CreateProjectDTO `json:"projects" validate:"required,gt=0,dive"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` + Workspaces []CreateWorkspaceDTO `json:"workspaces" validate:"required,gt=0,dive"` } // @name CreateTargetDTO -type CreateProjectDTO struct { +type CreateWorkspaceDTO struct { Name string `json:"name" validate:"required"` Image *string `json:"image,omitempty" validate:"optional"` User *string `json:"user,omitempty" validate:"optional"` BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` - Source CreateProjectSourceDTO `json:"source" validate:"required"` + Source CreateWorkspaceSourceDTO `json:"source" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name CreateProjectDTO +} // @name CreateWorkspaceDTO -type CreateProjectSourceDTO struct { +type CreateWorkspaceSourceDTO struct { Repository *gitprovider.GitRepository `json:"repository" validate:"required"` -} // @name CreateProjectSourceDTO +} // @name CreateWorkspaceSourceDTO diff --git a/pkg/server/targets/error.go b/pkg/server/targets/error.go index cdc6318016..6bd276f9bc 100644 --- a/pkg/server/targets/error.go +++ b/pkg/server/targets/error.go @@ -8,10 +8,10 @@ import ( ) var ( - ErrTargetAlreadyExists = errors.New("target already exists") - ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") - ErrTargetNotFound = errors.New("target not found") - ErrProjectNotFound = errors.New("project not found") - ErrInvalidProjectName = errors.New("project name is not valid. Only [a-zA-Z0-9-_.] are allowed") - ErrInvalidProjectConfig = errors.New("project config is invalid") + ErrTargetAlreadyExists = errors.New("target already exists") + ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") + ErrTargetNotFound = errors.New("target not found") + ErrWorkspaceNotFound = errors.New("workspace not found") + ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") + ErrInvalidWorkspaceConfig = errors.New("workspace config is invalid") ) diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 25608bc1c4..08d4746520 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -26,9 +26,9 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error return err } - for _, project := range target.Projects { + for _, workspace := range target.Workspaces { // todo: go routines - err := s.provisioner.DestroyProject(project, targetConfig) + err := s.provisioner.DestroyWorkspace(workspace, targetConfig) if err != nil { return err } @@ -45,16 +45,16 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error log.Error(err) } - for _, project := range target.Projects { - err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, project.Name)) + for _, workspace := range target.Workspaces { + err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, workspace.Name)) if err != nil { // Should not fail the whole operation if the API key cannot be revoked log.Error(err) } - projectLogger := s.loggerFactory.CreateProjectLogger(target.Id, project.Name, logs.LogSourceServer) - err = projectLogger.Cleanup() + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(target.Id, workspace.Name, logs.LogSourceServer) + err = workspaceLogger.Cleanup() if err != nil { - // Should not fail the whole operation if the project logger cannot be cleaned up + // Should not fail the whole operation if the workspace logger cannot be cleaned up log.Error(err) } } @@ -99,9 +99,9 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) targetConfig, _ := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) - for _, project := range target.Projects { + for _, workspace := range target.Workspaces { // todo: go routines - err := s.provisioner.DestroyProject(project, targetConfig) + err := s.provisioner.DestroyWorkspace(workspace, targetConfig) if err != nil { log.Error(err) } @@ -117,14 +117,14 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) log.Error(err) } - for _, project := range target.Projects { - err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, project.Name)) + for _, workspace := range target.Workspaces { + err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, workspace.Name)) if err != nil { log.Error(err) } - projectLogger := s.loggerFactory.CreateProjectLogger(target.Id, project.Name, logs.LogSourceServer) - err = projectLogger.Cleanup() + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(target.Id, workspace.Name, logs.LogSourceServer) + err = workspaceLogger.Cleanup() if err != nil { log.Error(err) } diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 55fbc50011..e2ef76aa6e 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -15,10 +15,10 @@ import ( "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/projectconfig" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -32,10 +32,10 @@ type ITargetService interface { RemoveTarget(ctx context.Context, targetId string) error ForceRemoveTarget(ctx context.Context, targetId string) error - GetProjectLogReader(targetId, projectName string) (io.Reader, error) - SetProjectState(targetId string, projectName string, state *project.ProjectState) (*target.Target, error) - StartProject(ctx context.Context, targetId string, projectName string) error - StopProject(ctx context.Context, targetId string, projectName string) error + GetWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) + SetWorkspaceState(targetId string, workspaceName string, state *workspace.WorkspaceState) (*target.Target, error) + StartWorkspace(ctx context.Context, targetId string, workspaceName string) error + StopWorkspace(ctx context.Context, targetId string, workspaceName string) error } type targetConfigStore interface { @@ -47,13 +47,13 @@ type TargetServiceConfig struct { TargetConfigStore targetConfigStore ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService - ProjectConfigService projectconfig.IProjectConfigService + WorkspaceConfigService workspaceconfig.IWorkspaceConfigService ServerApiUrl string ServerUrl string ServerVersion string Provisioner provisioner.IProvisioner - DefaultProjectImage string - DefaultProjectUser string + DefaultWorkspaceImage string + DefaultWorkspaceUser string BuilderImage string ApiKeyService apikeys.IApiKeyService LoggerFactory logs.LoggerFactory @@ -67,12 +67,12 @@ func NewTargetService(config TargetServiceConfig) ITargetService { targetConfigStore: config.TargetConfigStore, containerRegistryService: config.ContainerRegistryService, buildService: config.BuildService, - projectConfigService: config.ProjectConfigService, + workspaceConfigService: config.WorkspaceConfigService, serverApiUrl: config.ServerApiUrl, serverUrl: config.ServerUrl, serverVersion: config.ServerVersion, - defaultProjectImage: config.DefaultProjectImage, - defaultProjectUser: config.DefaultProjectUser, + defaultWorkspaceImage: config.DefaultWorkspaceImage, + defaultWorkspaceUser: config.DefaultWorkspaceUser, provisioner: config.Provisioner, loggerFactory: config.LoggerFactory, apiKeyService: config.ApiKeyService, @@ -87,40 +87,40 @@ type TargetService struct { targetConfigStore targetConfigStore containerRegistryService containerregistries.IContainerRegistryService buildService builds.IBuildService - projectConfigService projectconfig.IProjectConfigService + workspaceConfigService workspaceconfig.IWorkspaceConfigService provisioner provisioner.IProvisioner apiKeyService apikeys.IApiKeyService serverApiUrl string serverUrl string serverVersion string - defaultProjectImage string - defaultProjectUser string + defaultWorkspaceImage string + defaultWorkspaceUser string builderImage string loggerFactory logs.LoggerFactory gitProviderService gitproviders.IGitProviderService telemetryService telemetry.TelemetryService } -func (s *TargetService) SetProjectState(targetId, projectName string, state *project.ProjectState) (*target.Target, error) { +func (s *TargetService) SetWorkspaceState(targetId, workspaceName string, state *workspace.WorkspaceState) (*target.Target, error) { tg, err := s.targetStore.Find(targetId) if err != nil { return nil, err } - for _, project := range tg.Projects { - if project.Name == projectName { - project.State = state + for _, workspace := range tg.Workspaces { + if workspace.Name == workspaceName { + workspace.State = state return tg, s.targetStore.Save(tg) } } - return nil, errors.New("project not found") + return nil, errors.New("workspace not found") } func (s *TargetService) GetTargetLogReader(targetId string) (io.Reader, error) { return s.loggerFactory.CreateTargetLogReader(targetId) } -func (s *TargetService) GetProjectLogReader(targetId, projectName string) (io.Reader, error) { - return s.loggerFactory.CreateProjectLogReader(targetId, projectName) +func (s *TargetService) GetWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) { + return s.loggerFactory.CreateWorkspaceLogReader(targetId, workspaceName) } diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 2fb20ed65e..d305e1bc40 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -22,7 +22,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -31,8 +31,8 @@ import ( const serverApiUrl = "http://localhost:3986" const serverUrl = "http://localhost:3987" const serverVersion = "0.0.0-test" -const defaultProjectUser = "daytona" -const defaultProjectImage = "daytonaio/workspace-project:latest" +const defaultWorkspaceUser = "daytona" +const defaultWorkspaceImage = "daytonaio/workspace-project:latest" var targetConfig = provider.TargetConfig{ Name: "test-target-config", @@ -59,11 +59,11 @@ var createTargetDTO = dto.CreateTargetDTO{ Name: "test", Id: "test", TargetConfig: targetConfig.Name, - Projects: []dto.CreateProjectDTO{ + Workspaces: []dto.CreateWorkspaceDTO{ { - Name: "project1", + Name: "workspace1", GitProviderConfigId: &gitProviderConfig.Id, - Source: dto.CreateProjectSourceDTO{ + Source: dto.CreateWorkspaceSourceDTO{ Repository: &gitprovider.GitRepository{ Id: "123", Url: "https://github.com/daytonaio/daytona", @@ -72,8 +72,8 @@ var createTargetDTO = dto.CreateTargetDTO{ Sha: "sha1", }, }, - Image: util.Pointer(defaultProjectImage), - User: util.Pointer(defaultProjectUser), + Image: util.Pointer(defaultWorkspaceImage), + User: util.Pointer(defaultWorkspaceUser), }, }, } @@ -81,9 +81,9 @@ var createTargetDTO = dto.CreateTargetDTO{ var targetInfo = target.TargetInfo{ Name: createTargetDTO.Name, ProviderMetadata: "provider-metadata-test", - Projects: []*project.ProjectInfo{ + Workspaces: []*workspace.WorkspaceInfo{ { - Name: createTargetDTO.Projects[0].Name, + Name: createTargetDTO.Workspaces[0].Name, Created: "1 min ago", IsRunning: true, ProviderMetadata: "provider-metadata-test", @@ -100,7 +100,7 @@ func TestTargetService(t *testing.T) { containerRegistryService := mocks.NewMockContainerRegistryService() - projectConfigService := mocks.NewMockProjectConfigService() + workspaceConfigService := mocks.NewMockWorkspaceConfigService() targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() err := targetConfigStore.Save(&targetConfig) @@ -120,11 +120,11 @@ func TestTargetService(t *testing.T) { ServerUrl: serverUrl, ServerVersion: serverVersion, ContainerRegistryService: containerRegistryService, - ProjectConfigService: projectConfigService, - DefaultProjectImage: defaultProjectImage, - DefaultProjectUser: defaultProjectUser, + WorkspaceConfigService: workspaceConfigService, + DefaultWorkspaceImage: defaultWorkspaceImage, + DefaultWorkspaceUser: defaultWorkspaceUser, ApiKeyService: apiKeyService, - BuilderImage: defaultProjectImage, + BuilderImage: defaultWorkspaceImage, Provisioner: mockProvisioner, LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), GitProviderService: gitProviderService, @@ -133,50 +133,51 @@ func TestTargetService(t *testing.T) { t.Run("CreateTarget", func(t *testing.T) { var containerRegistry *containerregistry.ContainerRegistry - containerRegistryService.On("FindByImageName", defaultProjectImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) + containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) mockProvisioner.On("CreateTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Generate", apikey.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) - gitProviderService.On("GetLastCommitSha", createTargetDTO.Projects[0].Source.Repository).Return("123", nil) + gitProviderService.On("GetLastCommitSha", createTargetDTO.Workspaces[0].Source.Repository).Return("123", nil) - for _, project := range createTargetDTO.Projects { - apiKeyService.On("Generate", apikey.ApiKeyTypeProject, fmt.Sprintf("%s/%s", createTargetDTO.Id, project.Name)).Return(project.Name, nil) + for _, workspace := range createTargetDTO.Workspaces { + apiKeyService.On("Generate", apikey.ApiKeyTypeWorkspace, fmt.Sprintf("%s/%s", createTargetDTO.Id, workspace.Name)).Return(workspace.Name, nil) } - proj := &project.Project{ - Name: createTargetDTO.Projects[0].Name, - Image: *createTargetDTO.Projects[0].Image, - User: *createTargetDTO.Projects[0].User, - BuildConfig: createTargetDTO.Projects[0].BuildConfig, - Repository: createTargetDTO.Projects[0].Source.Repository, - ApiKey: createTargetDTO.Projects[0].Name, - GitProviderConfigId: createTargetDTO.Projects[0].GitProviderConfigId, + + ws := &workspace.Workspace{ + Name: createTargetDTO.Workspaces[0].Name, + Image: *createTargetDTO.Workspaces[0].Image, + User: *createTargetDTO.Workspaces[0].User, + BuildConfig: createTargetDTO.Workspaces[0].BuildConfig, + Repository: createTargetDTO.Workspaces[0].Source.Repository, + ApiKey: createTargetDTO.Workspaces[0].Name, + GitProviderConfigId: createTargetDTO.Workspaces[0].GitProviderConfigId, TargetId: createTargetDTO.Id, TargetConfig: createTargetDTO.TargetConfig, } - proj.EnvVars = project.GetProjectEnvVars(proj, project.ProjectEnvVarParams{ + ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ ApiUrl: serverApiUrl, ServerUrl: serverUrl, ServerVersion: serverVersion, ClientId: "test", }, false) - mockProvisioner.On("CreateProject", provisioner.ProjectParams{ - Project: proj, + mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ + Workspace: ws, TargetConfig: &targetConfig, ContainerRegistry: containerRegistry, GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultProjectImage, + BuilderImage: defaultWorkspaceImage, BuilderImageContainerRegistry: containerRegistry, }).Return(nil) - mockProvisioner.On("StartProject", provisioner.ProjectParams{ - Project: proj, + mockProvisioner.On("StartWorkspace", provisioner.WorkspaceParams{ + Workspace: ws, TargetConfig: &targetConfig, ContainerRegistry: containerRegistry, GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultProjectImage, + BuilderImage: defaultWorkspaceImage, BuilderImageContainerRegistry: containerRegistry, }).Return(nil) @@ -187,7 +188,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, target) - targetEquals(t, createTargetDTO, target, defaultProjectImage) + targetEquals(t, createTargetDTO, target, defaultWorkspaceImage) }) t.Run("CreateTarget fails when target already exists", func(t *testing.T) { @@ -213,7 +214,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, target) - targetDtoEquals(t, createTargetDTO, *target, targetInfo, defaultProjectImage, true) + targetDtoEquals(t, createTargetDTO, *target, targetInfo, defaultWorkspaceImage, true) }) t.Run("GetTarget fails when target not found", func(t *testing.T) { @@ -233,7 +234,7 @@ func TestTargetService(t *testing.T) { target := targets[0] - targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultProjectImage, verbose) + targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultWorkspaceImage, verbose) }) t.Run("ListTargets - verbose", func(t *testing.T) { @@ -247,48 +248,48 @@ func TestTargetService(t *testing.T) { target := targets[0] - targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultProjectImage, verbose) + targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultWorkspaceImage, verbose) }) t.Run("StartTarget", func(t *testing.T) { mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StartProject", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) err := service.StartTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) - t.Run("StartProject", func(t *testing.T) { + t.Run("StartWorkspace", func(t *testing.T) { mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StartProject", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) - err := service.StartProject(ctx, createTargetDTO.Id, createTargetDTO.Projects[0].Name) + err := service.StartWorkspace(ctx, createTargetDTO.Id, createTargetDTO.Workspaces[0].Name) require.Nil(t, err) }) t.Run("StopTarget", func(t *testing.T) { mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StopProject", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) err := service.StopTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) - t.Run("StopProject", func(t *testing.T) { + t.Run("StopWorkspace", func(t *testing.T) { mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StopProject", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) - err := service.StopProject(ctx, createTargetDTO.Id, createTargetDTO.Projects[0].Name) + err := service.StopWorkspace(ctx, createTargetDTO.Id, createTargetDTO.Workspaces[0].Name) require.Nil(t, err) }) t.Run("RemoveTarget", func(t *testing.T) { mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("DestroyProject", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveTarget(ctx, createTargetDTO.Id) @@ -304,7 +305,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("DestroyProject", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveTarget(ctx, createTargetDTO.Id) @@ -315,24 +316,24 @@ func TestTargetService(t *testing.T) { require.Equal(t, targets.ErrTargetNotFound, err) }) - t.Run("SetProjectState", func(t *testing.T) { + t.Run("SetWorkspaceState", func(t *testing.T) { tg, err := service.CreateTarget(ctx, createTargetDTO) require.Nil(t, err) - projectName := tg.Projects[0].Name + workspaceName := tg.Workspaces[0].Name updatedAt := time.Now().Format(time.RFC1123) - res, err := service.SetProjectState(tg.Id, projectName, &project.ProjectState{ + res, err := service.SetWorkspaceState(tg.Id, workspaceName, &workspace.WorkspaceState{ UpdatedAt: updatedAt, Uptime: 10, - GitStatus: &project.GitStatus{ + GitStatus: &workspace.GitStatus{ CurrentBranch: "main", }, }) require.Nil(t, err) - project, err := res.GetProject(projectName) + workspace, err := res.GetWorkspace(workspaceName) require.Nil(t, err) - require.Equal(t, "main", project.State.GitStatus.CurrentBranch) + require.Equal(t, "main", workspace.State.GitStatus.CurrentBranch) }) t.Cleanup(func() { @@ -341,25 +342,25 @@ func TestTargetService(t *testing.T) { }) } -func targetEquals(t *testing.T, req dto.CreateTargetDTO, target *target.Target, projectImage string) { +func targetEquals(t *testing.T, req dto.CreateTargetDTO, target *target.Target, workspaceImage string) { t.Helper() require.Equal(t, req.Id, target.Id) require.Equal(t, req.Name, target.Name) require.Equal(t, req.TargetConfig, target.TargetConfig) - for i, project := range target.Projects { - require.Equal(t, req.Projects[i].Name, project.Name) - require.Equal(t, req.Projects[i].Source.Repository.Id, project.Repository.Id) - require.Equal(t, req.Projects[i].Source.Repository.Url, project.Repository.Url) - require.Equal(t, req.Projects[i].Source.Repository.Name, project.Repository.Name) - require.Equal(t, project.ApiKey, project.Name) - require.Equal(t, project.TargetConfig, req.TargetConfig) - require.Equal(t, project.Image, projectImage) + for i, workspace := range target.Workspaces { + require.Equal(t, req.Workspaces[i].Name, workspace.Name) + require.Equal(t, req.Workspaces[i].Source.Repository.Id, workspace.Repository.Id) + require.Equal(t, req.Workspaces[i].Source.Repository.Url, workspace.Repository.Url) + require.Equal(t, req.Workspaces[i].Source.Repository.Name, workspace.Repository.Name) + require.Equal(t, workspace.ApiKey, workspace.Name) + require.Equal(t, workspace.TargetConfig, req.TargetConfig) + require.Equal(t, workspace.Image, workspaceImage) } } -func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, projectImage string, verbose bool) { +func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, workspaceImage string, verbose bool) { t.Helper() require.Equal(t, req.Id, target.Id) @@ -373,20 +374,20 @@ func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO require.Nil(t, target.Info) } - for i, project := range target.Projects { - require.Equal(t, req.Projects[i].Name, project.Name) - require.Equal(t, req.Projects[i].Source.Repository.Id, project.Repository.Id) - require.Equal(t, req.Projects[i].Source.Repository.Url, project.Repository.Url) - require.Equal(t, req.Projects[i].Source.Repository.Name, project.Repository.Name) - require.Equal(t, project.ApiKey, project.Name) - require.Equal(t, project.TargetConfig, req.TargetConfig) - require.Equal(t, project.Image, projectImage) + for i, workspace := range target.Workspaces { + require.Equal(t, req.Workspaces[i].Name, workspace.Name) + require.Equal(t, req.Workspaces[i].Source.Repository.Id, workspace.Repository.Id) + require.Equal(t, req.Workspaces[i].Source.Repository.Url, workspace.Repository.Url) + require.Equal(t, req.Workspaces[i].Source.Repository.Name, workspace.Repository.Name) + require.Equal(t, workspace.ApiKey, workspace.Name) + require.Equal(t, workspace.TargetConfig, req.TargetConfig) + require.Equal(t, workspace.Image, workspaceImage) if verbose { - require.Equal(t, target.Info.Projects[i].Name, targetInfo.Projects[i].Name) - require.Equal(t, target.Info.Projects[i].Created, targetInfo.Projects[i].Created) - require.Equal(t, target.Info.Projects[i].IsRunning, targetInfo.Projects[i].IsRunning) - require.Equal(t, target.Info.Projects[i].ProviderMetadata, targetInfo.Projects[i].ProviderMetadata) + require.Equal(t, target.Info.Workspaces[i].Name, targetInfo.Workspaces[i].Name) + require.Equal(t, target.Info.Workspaces[i].Created, targetInfo.Workspaces[i].Created) + require.Equal(t, target.Info.Workspaces[i].IsRunning, targetInfo.Workspaces[i].IsRunning) + require.Equal(t, target.Info.Workspaces[i].ProviderMetadata, targetInfo.Workspaces[i].ProviderMetadata) } } } diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index 6b78ebe897..a090ae47be 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" @@ -59,15 +59,15 @@ func (s *TargetService) StartTarget(ctx context.Context, targetId string) error return err } -func (s *TargetService) StartProject(ctx context.Context, targetId, projectName string) error { +func (s *TargetService) StartWorkspace(ctx context.Context, targetId, workspaceName string) error { w, err := s.targetStore.Find(targetId) if err != nil { return ErrTargetNotFound } - project, err := w.GetProject(projectName) + workspace, err := w.GetWorkspace(workspaceName) if err != nil { - return ErrProjectNotFound + return ErrWorkspaceNotFound } targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) @@ -75,10 +75,10 @@ func (s *TargetService) StartProject(ctx context.Context, targetId, projectName return err } - projectLogger := s.loggerFactory.CreateProjectLogger(w.Id, project.Name, logs.LogSourceServer) - defer projectLogger.Close() + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(w.Id, workspace.Name, logs.LogSourceServer) + defer workspaceLogger.Close() - return s.startProject(ctx, project, targetConfig, projectLogger) + return s.startWorkspace(ctx, workspace, targetConfig, workspaceLogger) } func (s *TargetService) startTarget(ctx context.Context, t *target.Target, targetConfig *provider.TargetConfig, targetLogger io.Writer) error { @@ -96,11 +96,11 @@ func (s *TargetService) startTarget(ctx context.Context, t *target.Target, targe return err } - for _, project := range t.Projects { - projectLogger := s.loggerFactory.CreateProjectLogger(t.Id, project.Name, logs.LogSourceServer) - defer projectLogger.Close() + for _, workspace := range t.Workspaces { + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(t.Id, workspace.Name, logs.LogSourceServer) + defer workspaceLogger.Close() - err = s.startProject(ctx, project, targetConfig, projectLogger) + err = s.startWorkspace(ctx, workspace, targetConfig, workspaceLogger) if err != nil { return err } @@ -111,18 +111,18 @@ func (s *TargetService) startTarget(ctx context.Context, t *target.Target, targe return nil } -func (s *TargetService) startProject(ctx context.Context, p *project.Project, targetConfig *provider.TargetConfig, logWriter io.Writer) error { - logWriter.Write([]byte(fmt.Sprintf("Starting project %s\n", p.Name))) +func (s *TargetService) startWorkspace(ctx context.Context, w *workspace.Workspace, targetConfig *provider.TargetConfig, logWriter io.Writer) error { + logWriter.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) - projectToStart := *p - projectToStart.EnvVars = project.GetProjectEnvVars(p, project.ProjectEnvVarParams{ + workspaceToStart := *w + workspaceToStart.EnvVars = workspace.GetWorkspaceEnvVars(w, workspace.WorkspaceEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - cr, err := s.containerRegistryService.FindByImageName(p.Image) + cr, err := s.containerRegistryService.FindByImageName(w.Image) if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { return err } @@ -134,15 +134,15 @@ func (s *TargetService) startProject(ctx context.Context, p *project.Project, ta var gc *gitprovider.GitProviderConfig - if p.GitProviderConfigId != nil { - gc, err = s.gitProviderService.GetConfig(*p.GitProviderConfigId) + if w.GitProviderConfigId != nil { + gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) if err != nil && !gitprovider.IsGitProviderNotFound(err) { return err } } - err = s.provisioner.StartProject(provisioner.ProjectParams{ - Project: &projectToStart, + err = s.provisioner.StartWorkspace(provisioner.WorkspaceParams{ + Workspace: &workspaceToStart, TargetConfig: targetConfig, ContainerRegistry: cr, GitProviderConfig: gc, @@ -153,7 +153,7 @@ func (s *TargetService) startProject(ctx context.Context, p *project.Project, ta return err } - logWriter.Write([]byte(fmt.Sprintf("Project %s started\n", p.Name))) + logWriter.Write([]byte(fmt.Sprintf("Workspace %s started\n", w.Name))) return nil } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index 00e0eb3b0d..06e410dcad 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -23,15 +23,15 @@ func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { return err } - for _, project := range target.Projects { + for _, workspace := range target.Workspaces { // todo: go routines - err := s.provisioner.StopProject(project, targetConfig) + err := s.provisioner.StopWorkspace(workspace, targetConfig) if err != nil { return err } - if project.State != nil { - project.State.Uptime = 0 - project.State.UpdatedAt = time.Now().Format(time.RFC1123) + if workspace.State != nil { + workspace.State.Uptime = 0 + workspace.State.UpdatedAt = time.Now().Format(time.RFC1123) } } @@ -60,15 +60,15 @@ func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { return err } -func (s *TargetService) StopProject(ctx context.Context, targetId, projectName string) error { +func (s *TargetService) StopWorkspace(ctx context.Context, targetId, workspaceName string) error { w, err := s.targetStore.Find(targetId) if err != nil { return ErrTargetNotFound } - project, err := w.GetProject(projectName) + workspace, err := w.GetWorkspace(workspaceName) if err != nil { - return ErrProjectNotFound + return ErrWorkspaceNotFound } targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) @@ -76,14 +76,14 @@ func (s *TargetService) StopProject(ctx context.Context, targetId, projectName s return err } - err = s.provisioner.StopProject(project, targetConfig) + err = s.provisioner.StopWorkspace(workspace, targetConfig) if err != nil { return err } - if project.State != nil { - project.State.Uptime = 0 - project.State.UpdatedAt = time.Now().Format(time.RFC1123) + if workspace.State != nil { + workspace.State.Uptime = 0 + workspace.State.UpdatedAt = time.Now().Format(time.RFC1123) } return s.targetStore.Save(w) diff --git a/pkg/server/types.go b/pkg/server/types.go index f4ade4a774..fa59ede047 100644 --- a/pkg/server/types.go +++ b/pkg/server/types.go @@ -46,9 +46,9 @@ type Config struct { HeadscalePort uint32 `json:"headscalePort" validate:"required"` BinariesPath string `json:"binariesPath" validate:"required"` LogFile *LogFileConfig `json:"logFile" validate:"required"` - DefaultProjectImage string `json:"defaultProjectImage" validate:"required"` - DefaultProjectUser string `json:"defaultProjectUser" validate:"required"` BuilderImage string `json:"builderImage" validate:"required"` + DefaultWorkspaceImage string `json:"defaultWorkspaceImage" validate:"required"` + DefaultWorkspaceUser string `json:"defaultWorkspaceUser" validate:"required"` LocalBuilderRegistryPort uint32 `json:"localBuilderRegistryPort" validate:"required"` LocalBuilderRegistryImage string `json:"localBuilderRegistryImage" validate:"required"` BuilderRegistryServer string `json:"builderRegistryServer" validate:"required"` diff --git a/pkg/server/projectconfig/dto/projectconfig.go b/pkg/server/workspaceconfig/dto/workspaceconfig.go similarity index 67% rename from pkg/server/projectconfig/dto/projectconfig.go rename to pkg/server/workspaceconfig/dto/workspaceconfig.go index 15f036a2e9..1a83aceeda 100644 --- a/pkg/server/projectconfig/dto/projectconfig.go +++ b/pkg/server/workspaceconfig/dto/workspaceconfig.go @@ -4,10 +4,10 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) -type CreateProjectConfigDTO struct { +type CreateWorkspaceConfigDTO struct { Name string `json:"name" validate:"required"` Image *string `json:"image,omitempty" validate:"optional"` User *string `json:"user,omitempty" validate:"optional"` @@ -15,15 +15,15 @@ type CreateProjectConfigDTO struct { RepositoryUrl string `json:"repositoryUrl" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name CreateProjectConfigDTO +} // @name CreateWorkspaceConfigDTO type PrebuildDTO struct { - Id string `json:"id" validate:"required"` - ProjectConfigName string `json:"projectConfigName" validate:"required"` - Branch string `json:"branch" validate:"required"` - CommitInterval *int `json:"commitInterval" validate:"optional"` - TriggerFiles []string `json:"triggerFiles" validate:"optional"` - Retention int `json:"retention" validate:"required"` + Id string `json:"id" validate:"required"` + WorkspaceConfigName string `json:"workspaceConfigName" validate:"required"` + Branch string `json:"branch" validate:"required"` + CommitInterval *int `json:"commitInterval" validate:"optional"` + TriggerFiles []string `json:"triggerFiles" validate:"optional"` + Retention int `json:"retention" validate:"required"` } // @name PrebuildDTO type CreatePrebuildDTO struct { diff --git a/pkg/server/projectconfig/prebuild.go b/pkg/server/workspaceconfig/prebuild.go similarity index 67% rename from pkg/server/projectconfig/prebuild.go rename to pkg/server/workspaceconfig/prebuild.go index f154fba0d4..a5b2a60d58 100644 --- a/pkg/server/projectconfig/prebuild.go +++ b/pkg/server/workspaceconfig/prebuild.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig +package workspaceconfig import ( "errors" @@ -12,39 +12,39 @@ import ( "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" - "github.com/daytonaio/daytona/pkg/target/project/containerconfig" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" log "github.com/sirupsen/logrus" ) -func (s *ProjectConfigService) SetPrebuild(projectConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { - projectConfig, err := s.Find(&config.ProjectConfigFilter{ - Name: &projectConfigName, +func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { + workspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + Name: &workspaceConfigName, }) if err != nil { return nil, err } - existingPrebuild, _ := projectConfig.FindPrebuild(&config.PrebuildFilter{ + existingPrebuild, _ := workspaceConfig.FindPrebuild(&config.PrebuildFilter{ Branch: &createPrebuildDto.Branch, }) if existingPrebuild != nil && createPrebuildDto.Id == nil { - return nil, errors.New("prebuild for the specified project config and branch already exists") + return nil, errors.New("prebuild for the specified workspace config and branch already exists") } if createPrebuildDto.CommitInterval == nil && len(createPrebuildDto.TriggerFiles) == 0 { return nil, errors.New("either the commit interval or trigger files must be specified") } - gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(projectConfig.RepositoryUrl) + gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(workspaceConfig.RepositoryUrl) if err != nil { return nil, err } repository, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, }) if err != nil { return nil, err @@ -66,7 +66,7 @@ func (s *ProjectConfigService) SetPrebuild(projectConfigName string, createPrebu } } - err = projectConfig.SetPrebuild(prebuild) + err = workspaceConfig.SetPrebuild(prebuild) if err != nil { return nil, err } @@ -86,7 +86,7 @@ func (s *ProjectConfigService) SetPrebuild(projectConfigName string, createPrebu } } - err = s.configStore.Save(projectConfig) + err = s.configStore.Save(workspaceConfig) if err != nil { if newWebhookId != "" { err = s.gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repository, newWebhookId) @@ -99,52 +99,52 @@ func (s *ProjectConfigService) SetPrebuild(projectConfigName string, createPrebu } return &dto.PrebuildDTO{ - Id: prebuild.Id, - ProjectConfigName: projectConfig.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, + Id: prebuild.Id, + WorkspaceConfigName: workspaceConfig.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, }, nil } -func (s *ProjectConfigService) FindPrebuild(projectConfigFilter *config.ProjectConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) { - pc, err := s.configStore.Find(projectConfigFilter) +func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) { + wc, err := s.configStore.Find(workspaceConfigFilter) if err != nil { - return nil, config.ErrProjectConfigNotFound + return nil, config.ErrWorkspaceConfigNotFound } - prebuild, err := pc.FindPrebuild(prebuildFilter) + prebuild, err := wc.FindPrebuild(prebuildFilter) if err != nil { return nil, err } return &dto.PrebuildDTO{ - Id: prebuild.Id, - ProjectConfigName: pc.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, + Id: prebuild.Id, + WorkspaceConfigName: wc.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, }, nil } -func (s *ProjectConfigService) ListPrebuilds(projectConfigFilter *config.ProjectConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) { var result []*dto.PrebuildDTO - pcs, err := s.configStore.List(projectConfigFilter) + wcs, err := s.configStore.List(workspaceConfigFilter) if err != nil { - return nil, config.ErrProjectConfigNotFound + return nil, config.ErrWorkspaceConfigNotFound } - for _, pc := range pcs { - for _, prebuild := range pc.Prebuilds { + for _, wc := range wcs { + for _, prebuild := range wc.Prebuilds { result = append(result, &dto.PrebuildDTO{ - Id: prebuild.Id, - ProjectConfigName: pc.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, + Id: prebuild.Id, + WorkspaceConfigName: wc.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, }) } } @@ -152,31 +152,31 @@ func (s *ProjectConfigService) ListPrebuilds(projectConfigFilter *config.Project return result, nil } -func (s *ProjectConfigService) DeletePrebuild(projectConfigName string, id string, force bool) []error { - projectConfig, err := s.Find(&config.ProjectConfigFilter{ - Name: &projectConfigName, +func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id string, force bool) []error { + workspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + Name: &workspaceConfigName, }) if err != nil { return []error{err} } - // Get all prebuilds for this project config's repository URL and + // Get all prebuilds for this workspace config's repository URL and // if this is the last prebuild, unregister the Git provider webhook - prebuilds, err := s.ListPrebuilds(&config.ProjectConfigFilter{ - Url: &projectConfig.RepositoryUrl, + prebuilds, err := s.ListPrebuilds(&config.WorkspaceConfigFilter{ + Url: &workspaceConfig.RepositoryUrl, }, nil) if err != nil { return []error{err} } if len(prebuilds) == 1 { - gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(projectConfig.RepositoryUrl) + gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(workspaceConfig.RepositoryUrl) if err != nil { return []error{err} } repository, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: projectConfig.RepositoryUrl, + Url: workspaceConfig.RepositoryUrl, }) if err != nil { return []error{err} @@ -216,12 +216,12 @@ func (s *ProjectConfigService) DeletePrebuild(projectConfigName string, id strin } } - err = projectConfig.RemovePrebuild(id) + err = workspaceConfig.RemovePrebuild(id) if err != nil { return []error{err} } - err = s.configStore.Save(projectConfig) + err = s.configStore.Save(workspaceConfig) if err != nil { return []error{err} } @@ -229,10 +229,10 @@ func (s *ProjectConfigService) DeletePrebuild(projectConfigName string, id strin return nil } -func (s *ProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { +func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { var buildsToTrigger []build.Build - projectConfigs, err := s.List(&config.ProjectConfigFilter{ + workspaceConfigs, err := s.List(&config.WorkspaceConfigFilter{ Url: &data.Url, }) if err != nil { @@ -250,8 +250,8 @@ func (s *ProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) er return fmt.Errorf("failed to get repository context: %s", err) } - for _, projectConfig := range projectConfigs { - prebuild, err := projectConfig.FindPrebuild(&config.PrebuildFilter{ + for _, workspaceConfig := range workspaceConfigs { + prebuild, err := workspaceConfig.FindPrebuild(&config.PrebuildFilter{ Branch: &data.Branch, }) if err != nil || prebuild == nil { @@ -263,12 +263,12 @@ func (s *ProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) er if slicesHaveCommonEntry(prebuild.TriggerFiles, data.AffectedFiles) { buildsToTrigger = append(buildsToTrigger, build.Build{ ContainerConfig: containerconfig.ContainerConfig{ - Image: projectConfig.Image, - User: projectConfig.User, + Image: workspaceConfig.Image, + User: workspaceConfig.User, }, - BuildConfig: projectConfig.BuildConfig, + BuildConfig: workspaceConfig.BuildConfig, Repository: repo, - EnvVars: projectConfig.EnvVars, + EnvVars: workspaceConfig.EnvVars, PrebuildId: prebuild.Id, }) continue @@ -282,12 +282,12 @@ func (s *ProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) er if err != nil { buildsToTrigger = append(buildsToTrigger, build.Build{ ContainerConfig: containerconfig.ContainerConfig{ - Image: projectConfig.Image, - User: projectConfig.User, + Image: workspaceConfig.Image, + User: workspaceConfig.User, }, - BuildConfig: projectConfig.BuildConfig, + BuildConfig: workspaceConfig.BuildConfig, Repository: repo, - EnvVars: projectConfig.EnvVars, + EnvVars: workspaceConfig.EnvVars, PrebuildId: prebuild.Id, }) continue @@ -302,12 +302,12 @@ func (s *ProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) er if prebuild.CommitInterval != nil && commitsRange >= *prebuild.CommitInterval { buildsToTrigger = append(buildsToTrigger, build.Build{ ContainerConfig: containerconfig.ContainerConfig{ - Image: projectConfig.Image, - User: projectConfig.User, + Image: workspaceConfig.Image, + User: workspaceConfig.User, }, - BuildConfig: projectConfig.BuildConfig, + BuildConfig: workspaceConfig.BuildConfig, Repository: repo, - EnvVars: projectConfig.EnvVars, + EnvVars: workspaceConfig.EnvVars, PrebuildId: prebuild.Id, }) } @@ -333,7 +333,7 @@ func (s *ProjectConfigService) ProcessGitEvent(data gitprovider.GitEventData) er } // Marks the [retention] oldest published builds for deletion for each prebuild -func (s *ProjectConfigService) EnforceRetentionPolicy() error { +func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { prebuilds, err := s.ListPrebuilds(nil, nil) if err != nil { return err @@ -383,7 +383,7 @@ func (s *ProjectConfigService) EnforceRetentionPolicy() error { return nil } -func (s *ProjectConfigService) StartRetentionPoller() error { +func (s *WorkspaceConfigService) StartRetentionPoller() error { scheduler := build.NewCronScheduler() err := scheduler.AddFunc(build.DEFAULT_POLL_INTERVAL, func() { diff --git a/pkg/server/projectconfig/prebuild_test.go b/pkg/server/workspaceconfig/prebuild_test.go similarity index 72% rename from pkg/server/projectconfig/prebuild_test.go rename to pkg/server/workspaceconfig/prebuild_test.go index b498abc332..cddee3a951 100644 --- a/pkg/server/projectconfig/prebuild_test.go +++ b/pkg/server/workspaceconfig/prebuild_test.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package projectconfig_test +package workspaceconfig_test import ( "time" @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/server/projectconfig/dto" - "github.com/daytonaio/daytona/pkg/target/project/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" ) var prebuild1 *config.PrebuildConfig = &config.PrebuildConfig{ @@ -39,12 +39,12 @@ var prebuild3 *config.PrebuildConfig = &config.PrebuildConfig{ } var prebuild1Dto *dto.PrebuildDTO = &dto.PrebuildDTO{ - ProjectConfigName: projectConfig1.Name, - Id: prebuild1.Id, - Branch: prebuild1.Branch, - CommitInterval: prebuild1.CommitInterval, - Retention: prebuild1.Retention, - TriggerFiles: prebuild1.TriggerFiles, + WorkspaceConfigName: workspaceConfig1.Name, + Id: prebuild1.Id, + Branch: prebuild1.Branch, + CommitInterval: prebuild1.CommitInterval, + Retention: prebuild1.Retention, + TriggerFiles: prebuild1.TriggerFiles, } var repository1 *gitprovider.GitRepository = &gitprovider.GitRepository{ @@ -59,7 +59,7 @@ var expectedFilteredPrebuilds []*config.PrebuildConfig var expectedPrebuildsMap map[string]*config.PrebuildConfig var expectedFilteredPrebuildsMap map[string]*config.PrebuildConfig -func (s *ProjectConfigServiceTestSuite) TestSetPrebuild() { +func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { require := s.Require() s.gitProviderService.On("GetGitProviderForUrl", repository1.Url).Return(&s.gitProvider, "github", nil) @@ -68,7 +68,7 @@ func (s *ProjectConfigServiceTestSuite) TestSetPrebuild() { }).Return(repository1, nil) s.gitProviderService.On("GetPrebuildWebhook", "github", repository1, "").Return(util.Pointer("webhook-id"), nil) - newPrebuildDto, err := s.projectConfigService.SetPrebuild(projectConfig1.Name, dto.CreatePrebuildDTO{ + newPrebuildDto, err := s.workspaceConfigService.SetPrebuild(workspaceConfig1.Name, dto.CreatePrebuildDTO{ Id: &prebuild3.Id, Branch: prebuild3.Branch, CommitInterval: prebuild3.CommitInterval, @@ -77,36 +77,36 @@ func (s *ProjectConfigServiceTestSuite) TestSetPrebuild() { }) require.Nil(err) - prebuildDtos, err := s.projectConfigService.ListPrebuilds(&config.ProjectConfigFilter{ - Name: &projectConfig1.Name, + prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&config.WorkspaceConfigFilter{ + Name: &workspaceConfig1.Name, }, nil) require.Nil(err) require.Contains(prebuildDtos, newPrebuildDto) } -func (s *ProjectConfigServiceTestSuite) TestFindPrebuild() { +func (s *WorkspaceConfigServiceTestSuite) TestFindPrebuild() { require := s.Require() - prebuild, err := s.projectConfigService.FindPrebuild(&config.ProjectConfigFilter{ - Name: &projectConfig1.Name, + prebuild, err := s.workspaceConfigService.FindPrebuild(&config.WorkspaceConfigFilter{ + Name: &workspaceConfig1.Name, }, &config.PrebuildFilter{ Id: &prebuild1.Id, }) require.Nil(err) require.Equal(prebuild1Dto, prebuild) } -func (s *ProjectConfigServiceTestSuite) TestListPrebuilds() { +func (s *WorkspaceConfigServiceTestSuite) TestListPrebuilds() { require := s.Require() - prebuildDtos, err := s.projectConfigService.ListPrebuilds(&config.ProjectConfigFilter{ - Name: &projectConfig1.Name, + prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&config.WorkspaceConfigFilter{ + Name: &workspaceConfig1.Name, }, nil) require.Nil(err) require.Contains(prebuildDtos, prebuild1Dto) } -func (s *ProjectConfigServiceTestSuite) TestDeletePrebuild() { +func (s *WorkspaceConfigServiceTestSuite) TestDeletePrebuild() { expectedPrebuilds = expectedPrebuilds[:1] require := s.Require() @@ -115,11 +115,11 @@ func (s *ProjectConfigServiceTestSuite) TestDeletePrebuild() { PrebuildIds: &[]string{prebuild2.Id}, }, false).Return([]error{}) - err := s.projectConfigService.DeletePrebuild(projectConfig1.Name, prebuild2.Id, false) + err := s.workspaceConfigService.DeletePrebuild(workspaceConfig1.Name, prebuild2.Id, false) require.Nil(err) - prebuildDtos, errs := s.projectConfigService.ListPrebuilds(&config.ProjectConfigFilter{ - Name: &projectConfig1.Name, + prebuildDtos, errs := s.workspaceConfigService.ListPrebuilds(&config.WorkspaceConfigFilter{ + Name: &workspaceConfig1.Name, }, nil) require.Nil(errs) require.ElementsMatch([]*dto.PrebuildDTO{ @@ -127,7 +127,7 @@ func (s *ProjectConfigServiceTestSuite) TestDeletePrebuild() { }, prebuildDtos) } -func (s *ProjectConfigServiceTestSuite) TestProcessGitEventCommitInterval() { +func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventCommitInterval() { require := s.Require() s.gitProviderService.On("GetGitProviderForUrl", repository1.Url).Return(&s.gitProvider, "github", nil) @@ -138,8 +138,8 @@ func (s *ProjectConfigServiceTestSuite) TestProcessGitEventCommitInterval() { s.buildService.On("Create", build_dto.BuildCreationData{ PrebuildId: prebuild1.Id, Repository: repository1, - User: projectConfig1.User, - Image: projectConfig1.Image, + User: workspaceConfig1.User, + Image: workspaceConfig1.Image, }).Return("", nil) s.buildService.On("Find", &build.Filter{ @@ -161,11 +161,11 @@ func (s *ProjectConfigServiceTestSuite) TestProcessGitEventCommitInterval() { s.gitProvider.On("GetCommitsRange", repository1, repository1.Sha, data.Sha).Return(3, nil) - err := s.projectConfigService.ProcessGitEvent(data) + err := s.workspaceConfigService.ProcessGitEvent(data) require.Nil(err) } -func (s *ProjectConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { +func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { require := s.Require() s.gitProviderService.On("GetGitProviderForUrl", repository1.Url).Return(&s.gitProvider, "github", nil) @@ -176,8 +176,8 @@ func (s *ProjectConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { s.buildService.On("Create", build_dto.BuildCreationData{ PrebuildId: prebuild1.Id, Repository: repository1, - User: projectConfig1.User, - Image: projectConfig1.Image, + User: workspaceConfig1.User, + Image: workspaceConfig1.Image, }).Return("", nil) data := gitprovider.GitEventData{ @@ -190,11 +190,11 @@ func (s *ProjectConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { }, } - err := s.projectConfigService.ProcessGitEvent(data) + err := s.workspaceConfigService.ProcessGitEvent(data) require.Nil(err) } -func (s *ProjectConfigServiceTestSuite) TestEnforceRetentionPolicy() { +func (s *WorkspaceConfigServiceTestSuite) TestEnforceRetentionPolicy() { require := s.Require() s.buildService.On("List", &build.Filter{ @@ -230,6 +230,6 @@ func (s *ProjectConfigServiceTestSuite) TestEnforceRetentionPolicy() { Id: util.Pointer("1"), }, false).Return([]error{}) - err := s.projectConfigService.EnforceRetentionPolicy() + err := s.workspaceConfigService.EnforceRetentionPolicy() require.Nil(err) } diff --git a/pkg/server/workspaceconfig/service.go b/pkg/server/workspaceconfig/service.go new file mode 100644 index 0000000000..38d2b621fd --- /dev/null +++ b/pkg/server/workspaceconfig/service.go @@ -0,0 +1,133 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig + +import ( + "strings" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/target/workspace/config" +) + +type IWorkspaceConfigService interface { + Save(workspaceConfig *config.WorkspaceConfig) error + Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) + List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) + SetDefault(workspaceConfigName string) error + Delete(workspaceConfigName string, force bool) []error + + SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) + FindPrebuild(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) + ListPrebuilds(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) + DeletePrebuild(workspaceConfigName string, id string, force bool) []error + + StartRetentionPoller() error + EnforceRetentionPolicy() error + ProcessGitEvent(gitprovider.GitEventData) error +} + +type WorkspaceConfigServiceConfig struct { + PrebuildWebhookEndpoint string + ConfigStore config.Store + BuildService builds.IBuildService + GitProviderService gitproviders.IGitProviderService +} + +type WorkspaceConfigService struct { + prebuildWebhookEndpoint string + configStore config.Store + buildService builds.IBuildService + gitProviderService gitproviders.IGitProviderService +} + +func NewWorkspaceConfigService(config WorkspaceConfigServiceConfig) IWorkspaceConfigService { + return &WorkspaceConfigService{ + prebuildWebhookEndpoint: config.PrebuildWebhookEndpoint, + configStore: config.ConfigStore, + buildService: config.BuildService, + gitProviderService: config.GitProviderService, + } +} + +func (s *WorkspaceConfigService) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { + return s.configStore.List(filter) +} + +func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { + workspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + Name: &workspaceConfigName, + }) + if err != nil { + return err + } + + defaultWorkspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + Url: &workspaceConfig.RepositoryUrl, + Default: util.Pointer(true), + }) + if err != nil && err != config.ErrWorkspaceConfigNotFound { + return err + } + + if defaultWorkspaceConfig != nil { + defaultWorkspaceConfig.IsDefault = false + err := s.configStore.Save(defaultWorkspaceConfig) + if err != nil { + return err + } + } + + workspaceConfig.IsDefault = true + return s.configStore.Save(workspaceConfig) +} + +func (s *WorkspaceConfigService) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { + if filter != nil && filter.Url != nil { + cleanedUrl := util.CleanUpRepositoryUrl(*filter.Url) + if !strings.HasSuffix(cleanedUrl, ".git") { + cleanedUrl = cleanedUrl + ".git" + } + filter.Url = util.Pointer(cleanedUrl) + } + return s.configStore.Find(filter) +} + +func (s *WorkspaceConfigService) Save(workspaceConfig *config.WorkspaceConfig) error { + workspaceConfig.RepositoryUrl = util.CleanUpRepositoryUrl(workspaceConfig.RepositoryUrl) + + err := s.configStore.Save(workspaceConfig) + if err != nil { + return err + } + + return s.SetDefault(workspaceConfig.Name) +} + +func (s *WorkspaceConfigService) Delete(workspaceConfigName string, force bool) []error { + wc, err := s.Find(&config.WorkspaceConfigFilter{ + Name: &workspaceConfigName, + }) + if err != nil { + return []error{err} + } + + // DeletePrebuild handles deleting the builds and removing the webhook + for _, prebuild := range wc.Prebuilds { + errs := s.DeletePrebuild(wc.Name, prebuild.Id, force) + if len(errs) > 0 { + return errs + } + } + + err = s.configStore.Delete(wc) + if err != nil { + return []error{err} + } + + return nil +} diff --git a/pkg/server/workspaceconfig/service_test.go b/pkg/server/workspaceconfig/service_test.go new file mode 100644 index 0000000000..3a1768a781 --- /dev/null +++ b/pkg/server/workspaceconfig/service_test.go @@ -0,0 +1,195 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaceconfig_test + +import ( + "testing" + + git_provider_mock "github.com/daytonaio/daytona/internal/testing/gitprovider/mocks" + "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" + workspaceconfig_internal "github.com/daytonaio/daytona/internal/testing/server/workspaceconfig" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/stretchr/testify/suite" +) + +var workspaceConfig1Image = "image1" +var workspaceConfig1User = "user1" + +var workspaceConfig1 *config.WorkspaceConfig = &config.WorkspaceConfig{ + Name: "wc1", + Image: workspaceConfig1Image, + User: workspaceConfig1User, + BuildConfig: nil, + RepositoryUrl: repository1.Url, + IsDefault: true, + Prebuilds: []*config.PrebuildConfig{ + prebuild1, + prebuild2, + }, +} + +var workspaceConfig2 *config.WorkspaceConfig = &config.WorkspaceConfig{ + Name: "wc2", + Image: "image2", + User: "user2", + BuildConfig: nil, + RepositoryUrl: "https://github.com/daytonaio/daytona.git", +} + +var workspaceConfig3 *config.WorkspaceConfig = &config.WorkspaceConfig{ + Name: "wc3", + Image: "image3", + User: "user3", + BuildConfig: nil, + RepositoryUrl: "https://github.com/daytonaio/daytona3.git", +} + +var workspaceConfig4 *config.WorkspaceConfig = &config.WorkspaceConfig{ + Name: "wc4", + Image: "image4", + User: "user4", + BuildConfig: nil, + RepositoryUrl: "https://github.com/daytonaio/daytona4.git", +} + +var expectedWorkspaceConfigs []*config.WorkspaceConfig +var expectedFilteredWorkspaceConfigs []*config.WorkspaceConfig + +var expectedWorkspaceConfigsMap map[string]*config.WorkspaceConfig +var expectedFilteredWorkspaceConfigsMap map[string]*config.WorkspaceConfig + +type WorkspaceConfigServiceTestSuite struct { + suite.Suite + workspaceConfigService workspaceconfig.IWorkspaceConfigService + workspaceConfigStore config.Store + gitProviderService mocks.MockGitProviderService + buildService mocks.MockBuildService + gitProvider git_provider_mock.MockGitProvider +} + +func NewConfigServiceTestSuite() *WorkspaceConfigServiceTestSuite { + return &WorkspaceConfigServiceTestSuite{} +} + +func (s *WorkspaceConfigServiceTestSuite) SetupTest() { + expectedWorkspaceConfigs = []*config.WorkspaceConfig{ + workspaceConfig1, workspaceConfig2, workspaceConfig3, + } + + expectedPrebuilds = []*config.PrebuildConfig{ + prebuild1, prebuild2, + } + + expectedWorkspaceConfigsMap = map[string]*config.WorkspaceConfig{ + workspaceConfig1.Name: workspaceConfig1, + workspaceConfig2.Name: workspaceConfig2, + workspaceConfig3.Name: workspaceConfig3, + } + + expectedPrebuildsMap = map[string]*config.PrebuildConfig{ + prebuild1.Id: prebuild1, + prebuild2.Id: prebuild2, + } + + expectedFilteredWorkspaceConfigs = []*config.WorkspaceConfig{ + workspaceConfig1, workspaceConfig2, + } + + expectedFilteredPrebuilds = []*config.PrebuildConfig{ + prebuild1, + } + + expectedFilteredWorkspaceConfigsMap = map[string]*config.WorkspaceConfig{ + workspaceConfig1.Name: workspaceConfig1, + workspaceConfig2.Name: workspaceConfig2, + } + + expectedFilteredPrebuildsMap = map[string]*config.PrebuildConfig{ + prebuild1.Id: prebuild1, + } + + s.workspaceConfigStore = workspaceconfig_internal.NewInMemoryWorkspaceConfigStore() + s.workspaceConfigService = workspaceconfig.NewWorkspaceConfigService(workspaceconfig.WorkspaceConfigServiceConfig{ + ConfigStore: s.workspaceConfigStore, + GitProviderService: &s.gitProviderService, + BuildService: &s.buildService, + }) + + for _, wc := range expectedWorkspaceConfigs { + _ = s.workspaceConfigStore.Save(wc) + } +} + +func TestWorkspaceConfigService(t *testing.T) { + suite.Run(t, NewConfigServiceTestSuite()) +} + +func (s *WorkspaceConfigServiceTestSuite) TestList() { + require := s.Require() + + workspaceConfigs, err := s.workspaceConfigService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedWorkspaceConfigs, workspaceConfigs) +} + +func (s *WorkspaceConfigServiceTestSuite) TestFind() { + require := s.Require() + + workspaceConfig, err := s.workspaceConfigService.Find(&config.WorkspaceConfigFilter{ + Name: &workspaceConfig1.Name, + }) + require.Nil(err) + require.Equal(workspaceConfig1, workspaceConfig) +} +func (s *WorkspaceConfigServiceTestSuite) TestSetDefault() { + require := s.Require() + + err := s.workspaceConfigService.SetDefault(workspaceConfig2.Name) + require.Nil(err) + + workspaceConfig, err := s.workspaceConfigService.Find(&config.WorkspaceConfigFilter{ + Url: util.Pointer(workspaceConfig1.RepositoryUrl), + Default: util.Pointer(true), + }) + require.Nil(err) + + require.Equal(workspaceConfig2, workspaceConfig) +} + +func (s *WorkspaceConfigServiceTestSuite) TestSave() { + expectedWorkspaceConfigs = append(expectedWorkspaceConfigs, workspaceConfig4) + + require := s.Require() + + err := s.workspaceConfigService.Save(workspaceConfig4) + require.Nil(err) + + workspaceConfigs, err := s.workspaceConfigService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedWorkspaceConfigs, workspaceConfigs) +} + +func (s *WorkspaceConfigServiceTestSuite) TestDelete() { + expectedWorkspaceConfigs = expectedWorkspaceConfigs[:2] + + require := s.Require() + + err := s.workspaceConfigService.Delete(workspaceConfig3.Name, false) + require.Nil(err) + + workspaceConfigs, errs := s.workspaceConfigService.List(nil) + require.Nil(errs) + require.ElementsMatch(expectedWorkspaceConfigs, workspaceConfigs) +} + +func (s *WorkspaceConfigServiceTestSuite) AfterTest(_, _ string) { + s.gitProviderService.AssertExpectations(s.T()) + s.gitProviderService.ExpectedCalls = nil + s.buildService.AssertExpectations(s.T()) + s.buildService.ExpectedCalls = nil + s.gitProvider.AssertExpectations(s.T()) + s.gitProvider.ExpectedCalls = nil +} diff --git a/pkg/target/project/config/store.go b/pkg/target/project/config/store.go deleted file mode 100644 index 2cb788bed2..0000000000 --- a/pkg/target/project/config/store.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package config - -import "errors" - -type ProjectConfigFilter struct { - Name *string - Url *string - Default *bool - PrebuildId *string - GitProviderConfigId *string -} - -type PrebuildFilter struct { - ProjectConfigName *string - Id *string - Branch *string - CommitInterval *int - TriggerFiles *[]string -} - -type Store interface { - List(filter *ProjectConfigFilter) ([]*ProjectConfig, error) - Find(filter *ProjectConfigFilter) (*ProjectConfig, error) - Save(projectConfig *ProjectConfig) error - Delete(projectConfig *ProjectConfig) error -} - -var ( - ErrProjectConfigNotFound = errors.New("project config not found") - ErrPrebuildNotFound = errors.New("prebuild not found") -) - -func IsProjectConfigNotFound(err error) bool { - return err.Error() == ErrProjectConfigNotFound.Error() -} - -func IsPrebuildNotFound(err error) bool { - return err.Error() == ErrPrebuildNotFound.Error() -} diff --git a/pkg/target/target.go b/pkg/target/target.go index b179e7273a..f31cdfd00f 100644 --- a/pkg/target/target.go +++ b/pkg/target/target.go @@ -6,31 +6,31 @@ package target import ( "errors" - "github.com/daytonaio/daytona/pkg/target/project" + "github.com/daytonaio/daytona/pkg/target/workspace" ) type Target struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - Projects []*project.Project `json:"projects" validate:"required"` - TargetConfig string `json:"targetConfig" validate:"required"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"-"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + Workspaces []*workspace.Workspace `json:"workspaces" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` + ApiKey string `json:"-"` + EnvVars map[string]string `json:"-"` } // @name Target type TargetInfo struct { - Name string `json:"name" validate:"required"` - Projects []*project.ProjectInfo `json:"projects" validate:"required"` - ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` + Name string `json:"name" validate:"required"` + Workspaces []*workspace.WorkspaceInfo `json:"workspaces" validate:"required"` + ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` } // @name TargetInfo -func (t *Target) GetProject(projectName string) (*project.Project, error) { - for _, project := range t.Projects { - if project.Name == projectName { - return project, nil +func (t *Target) GetWorkspace(workspaceName string) (*workspace.Workspace, error) { + for _, workspace := range t.Workspaces { + if workspace.Name == workspaceName { + return workspace, nil } } - return nil, errors.New("project not found") + return nil, errors.New("workspace not found") } type TargetEnvVarParams struct { diff --git a/pkg/target/project/buildconfig/config.go b/pkg/target/workspace/buildconfig/config.go similarity index 100% rename from pkg/target/project/buildconfig/config.go rename to pkg/target/workspace/buildconfig/config.go diff --git a/pkg/target/project/config/config.go b/pkg/target/workspace/config/config.go similarity index 69% rename from pkg/target/project/config/config.go rename to pkg/target/workspace/config/config.go index 9b4ac10863..1193430b45 100644 --- a/pkg/target/project/config/config.go +++ b/pkg/target/workspace/config/config.go @@ -6,10 +6,10 @@ package config import ( "errors" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) -type ProjectConfig struct { +type WorkspaceConfig struct { Name string `json:"name" validate:"required"` Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` @@ -19,9 +19,9 @@ type ProjectConfig struct { IsDefault bool `json:"default" validate:"required"` Prebuilds []*PrebuildConfig `json:"prebuilds" validate:"optional"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name ProjectConfig +} // @name WorkspaceConfig -func (pc *ProjectConfig) SetPrebuild(p *PrebuildConfig) error { +func (wc *WorkspaceConfig) SetPrebuild(p *PrebuildConfig) error { newPrebuild := PrebuildConfig{ Id: p.Id, Branch: p.Branch, @@ -30,19 +30,19 @@ func (pc *ProjectConfig) SetPrebuild(p *PrebuildConfig) error { Retention: p.Retention, } - for _, pb := range pc.Prebuilds { + for _, pb := range wc.Prebuilds { if pb.Id == p.Id { *pb = newPrebuild return nil } } - pc.Prebuilds = append(pc.Prebuilds, &newPrebuild) + wc.Prebuilds = append(wc.Prebuilds, &newPrebuild) return nil } -func (pc *ProjectConfig) FindPrebuild(filter *PrebuildFilter) (*PrebuildConfig, error) { - for _, pb := range pc.Prebuilds { +func (wc *WorkspaceConfig) FindPrebuild(filter *PrebuildFilter) (*PrebuildConfig, error) { + for _, pb := range wc.Prebuilds { if pb.Match(filter) { return pb, nil } @@ -51,14 +51,14 @@ func (pc *ProjectConfig) FindPrebuild(filter *PrebuildFilter) (*PrebuildConfig, return nil, errors.New("prebuild not found") } -func (pc *ProjectConfig) ListPrebuilds(filter *PrebuildFilter) ([]*PrebuildConfig, error) { +func (wc *WorkspaceConfig) ListPrebuilds(filter *PrebuildFilter) ([]*PrebuildConfig, error) { if filter == nil { - return pc.Prebuilds, nil + return wc.Prebuilds, nil } prebuilds := []*PrebuildConfig{} - for _, pb := range pc.Prebuilds { + for _, pb := range wc.Prebuilds { if pb.Match(filter) { prebuilds = append(prebuilds, pb) } @@ -67,15 +67,15 @@ func (pc *ProjectConfig) ListPrebuilds(filter *PrebuildFilter) ([]*PrebuildConfi return prebuilds, nil } -func (pc *ProjectConfig) RemovePrebuild(id string) error { +func (wc *WorkspaceConfig) RemovePrebuild(id string) error { newPrebuilds := []*PrebuildConfig{} - for _, pb := range pc.Prebuilds { + for _, pb := range wc.Prebuilds { if pb.Id != id { newPrebuilds = append(newPrebuilds, pb) } } - pc.Prebuilds = newPrebuilds + wc.Prebuilds = newPrebuilds return nil } diff --git a/pkg/target/project/config/prebuild.go b/pkg/target/workspace/config/prebuild.go similarity index 100% rename from pkg/target/project/config/prebuild.go rename to pkg/target/workspace/config/prebuild.go diff --git a/pkg/target/workspace/config/store.go b/pkg/target/workspace/config/store.go new file mode 100644 index 0000000000..b54218101f --- /dev/null +++ b/pkg/target/workspace/config/store.go @@ -0,0 +1,42 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package config + +import "errors" + +type WorkspaceConfigFilter struct { + Name *string + Url *string + Default *bool + PrebuildId *string + GitProviderConfigId *string +} + +type PrebuildFilter struct { + WorkspaceConfigName *string + Id *string + Branch *string + CommitInterval *int + TriggerFiles *[]string +} + +type Store interface { + List(filter *WorkspaceConfigFilter) ([]*WorkspaceConfig, error) + Find(filter *WorkspaceConfigFilter) (*WorkspaceConfig, error) + Save(workspaceConfig *WorkspaceConfig) error + Delete(workspaceConfig *WorkspaceConfig) error +} + +var ( + ErrWorkspaceConfigNotFound = errors.New("workspace config not found") + ErrPrebuildNotFound = errors.New("prebuild not found") +) + +func IsWorkspaceConfigNotFound(err error) bool { + return err.Error() == ErrWorkspaceConfigNotFound.Error() +} + +func IsPrebuildNotFound(err error) bool { + return err.Error() == ErrPrebuildNotFound.Error() +} diff --git a/pkg/target/project/containerconfig/config.go b/pkg/target/workspace/containerconfig/config.go similarity index 100% rename from pkg/target/project/containerconfig/config.go rename to pkg/target/workspace/containerconfig/config.go diff --git a/pkg/target/project/project.go b/pkg/target/workspace/workspace.go similarity index 72% rename from pkg/target/project/project.go rename to pkg/target/workspace/workspace.go index 403bbf47d9..450ba5b3fd 100644 --- a/pkg/target/project/project.go +++ b/pkg/target/workspace/workspace.go @@ -1,17 +1,17 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package project +package workspace import ( "fmt" "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/project/buildconfig" + "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) -type Project struct { +type Workspace struct { Name string `json:"name" validate:"required"` Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` @@ -21,23 +21,23 @@ type Project struct { TargetId string `json:"targetId" validate:"required"` ApiKey string `json:"-"` TargetConfig string `json:"targetConfig" validate:"required"` - State *ProjectState `json:"state,omitempty" validate:"optional"` + State *WorkspaceState `json:"state,omitempty" validate:"optional"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` -} // @name Project +} // @name Workspace -type ProjectInfo struct { +type WorkspaceInfo struct { Name string `json:"name" validate:"required"` Created string `json:"created" validate:"required"` IsRunning bool `json:"isRunning" validate:"required"` ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` TargetId string `json:"targetId" validate:"required"` -} // @name ProjectInfo +} // @name WorkspaceInfo -type ProjectState struct { +type WorkspaceState struct { UpdatedAt string `json:"updatedAt" validate:"required"` Uptime uint64 `json:"uptime" validate:"required"` GitStatus *GitStatus `json:"gitStatus" validate:"optional"` -} // @name ProjectState +} // @name WorkspaceState type GitStatus struct { CurrentBranch string `json:"currentBranch" validate:"required"` @@ -68,23 +68,23 @@ const ( UpdatedButUnmerged Status = "Updated but unmerged" ) -type ProjectEnvVarParams struct { +type WorkspaceEnvVarParams struct { ApiUrl string ServerUrl string ServerVersion string ClientId string } -func GetProjectEnvVars(project *Project, params ProjectEnvVarParams, telemetryEnabled bool) map[string]string { +func GetWorkspaceEnvVars(workspace *Workspace, params WorkspaceEnvVarParams, telemetryEnabled bool) map[string]string { envVars := map[string]string{ - "DAYTONA_TARGET_ID": project.TargetId, - "DAYTONA_PROJECT_NAME": project.Name, - "DAYTONA_WS_PROJECT_REPOSITORY_URL": project.Repository.Url, - "DAYTONA_SERVER_API_KEY": project.ApiKey, - "DAYTONA_SERVER_VERSION": params.ServerVersion, - "DAYTONA_SERVER_URL": params.ServerUrl, - "DAYTONA_SERVER_API_URL": params.ApiUrl, - "DAYTONA_CLIENT_ID": params.ClientId, + "DAYTONA_TARGET_ID": workspace.TargetId, + "DAYTONA_WORKSPACE_NAME": workspace.Name, + "DAYTONA_WORKSPACE_REPOSITORY_URL": workspace.Repository.Url, + "DAYTONA_SERVER_API_KEY": workspace.ApiKey, + "DAYTONA_SERVER_VERSION": params.ServerVersion, + "DAYTONA_SERVER_URL": params.ServerUrl, + "DAYTONA_SERVER_API_URL": params.ApiUrl, + "DAYTONA_CLIENT_ID": params.ClientId, // (HOME) will be replaced at runtime "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", } @@ -96,14 +96,14 @@ func GetProjectEnvVars(project *Project, params ProjectEnvVarParams, telemetryEn return envVars } -func GetProjectHostname(targetId string, projectName string) string { +func GetWorkspaceHostname(targetId string, workspaceName string) string { // Replace special chars with hyphen to form valid hostname // String resulting in consecutive hyphens is also valid - projectName = strings.ReplaceAll(projectName, "_", "-") - projectName = strings.ReplaceAll(projectName, "*", "-") - projectName = strings.ReplaceAll(projectName, ".", "-") + workspaceName = strings.ReplaceAll(workspaceName, "_", "-") + workspaceName = strings.ReplaceAll(workspaceName, "*", "-") + workspaceName = strings.ReplaceAll(workspaceName, ".", "-") - hostname := fmt.Sprintf("%s-%s", targetId, projectName) + hostname := fmt.Sprintf("%s-%s", targetId, workspaceName) if len(hostname) > 63 { return hostname[:63] diff --git a/pkg/telemetry/constants.go b/pkg/telemetry/constants.go index b2d38df4b7..3c4ff1287f 100644 --- a/pkg/telemetry/constants.go +++ b/pkg/telemetry/constants.go @@ -20,7 +20,7 @@ var ( type TelemetrySource string var ( - CLI_SOURCE TelemetrySource = "cli" - CLI_PROJECT_SOURCE TelemetrySource = "cli-project" - AGENT_SOURCE TelemetrySource = "agent" + CLI_SOURCE TelemetrySource = "cli" + CLI_WORKSPACE_SOURCE TelemetrySource = "cli-workspace" + AGENT_SOURCE TelemetrySource = "agent" ) diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index 4727a75d5a..c9e9074ec1 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -44,21 +44,21 @@ func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfi if target != nil { props["target_id"] = target.Id - props["target_n_projects"] = len(target.Projects) + props["target_n_workspaces"] = len(target.Workspaces) publicRepos := []string{} publicImages := []string{} builders := map[string]int{} - for _, project := range target.Projects { - if isImagePublic(project.Image) { - publicImages = append(publicImages, project.Image) + for _, workspace := range target.Workspaces { + if isImagePublic(workspace.Image) { + publicImages = append(publicImages, workspace.Image) } - if project.Repository != nil && isPublic(project.Repository.Url) { - publicRepos = append(publicRepos, project.Repository.Url) + if workspace.Repository != nil && isPublic(workspace.Repository.Url) { + publicRepos = append(publicRepos, workspace.Repository.Url) } - if project.BuildConfig == nil { + if workspace.BuildConfig == nil { builders["none"]++ - } else if project.BuildConfig.Devcontainer != nil { + } else if workspace.BuildConfig.Devcontainer != nil { builders["devcontainer"]++ } else { builders["automatic"]++ diff --git a/pkg/views/build/info/view.go b/pkg/views/build/info/view.go index 96acfb87ea..bad0d66fd0 100644 --- a/pkg/views/build/info/view.go +++ b/pkg/views/build/info/view.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - projectconfig_info "github.com/daytonaio/daytona/pkg/views/projectconfig/info" views_util "github.com/daytonaio/daytona/pkg/views/util" + workspaceconfig_info "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" "golang.org/x/term" ) @@ -45,15 +45,15 @@ func Render(b *apiclient.Build, apiServerConfig *apiclient.ServerConfig, forceUn output += getInfoLine("User", *b.User) + "\n" } - if projectconfig_info.GetLabelFromBuild(b.BuildConfig) != "" { - projectDefaults := &views_util.ProjectConfigDefaults{ - Image: &apiServerConfig.DefaultProjectImage, - ImageUser: &apiServerConfig.DefaultProjectUser, + if workspaceconfig_info.GetLabelFromBuild(b.BuildConfig) != "" { + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, } - _, buildChoice := views_util.GetProjectBuildChoice(apiclient.CreateProjectDTO{ + _, buildChoice := views_util.GetWorkspaceBuildChoice(apiclient.CreateWorkspaceDTO{ BuildConfig: b.BuildConfig, - }, projectDefaults) + }, workspaceDefaults) output += getInfoLine("Build", buildChoice) + "\n" } diff --git a/pkg/views/ide/code.go b/pkg/views/ide/code.go index b4d7278b1d..891f3465dc 100644 --- a/pkg/views/ide/code.go +++ b/pkg/views/ide/code.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func RenderIdeOpeningMessage(target, projectName, ideId string, ideList []config.Ide) { +func RenderIdeOpeningMessage(target, workspaceName, ideId string, ideList []config.Ide) { ideName := "" for _, ide := range ideList { if ide.Id == ideId { @@ -18,5 +18,5 @@ func RenderIdeOpeningMessage(target, projectName, ideId string, ideList []config break } } - views.RenderInfoMessage(fmt.Sprintf("Opening the project '%s' from target '%s' in %s", projectName, target, ideName)) + views.RenderInfoMessage(fmt.Sprintf("Opening workspace '%s' from target '%s' in %s", workspaceName, target, ideName)) } diff --git a/pkg/views/logs/display.go b/pkg/views/logs/display.go index 10b11e1e8c..bd4d6d456b 100644 --- a/pkg/views/logs/display.go +++ b/pkg/views/logs/display.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -var FIRST_PROJECT_INDEX = 0 +var FIRST_WORKSPACE_INDEX = 0 var STATIC_INDEX = -1 var TARGET_PREFIX = "TARGET" var PROVIDER_PREFIX = "PROVIDER" @@ -34,8 +34,8 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { prefixColor := getPrefixColor(index, logEntry.Source) var prefixText string - if logEntry.ProjectName != nil { - prefixText = *logEntry.ProjectName + if logEntry.WorkspaceName != nil { + prefixText = *logEntry.WorkspaceName } if logEntry.BuildId != nil { @@ -88,10 +88,10 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { fmt.Print(result) } -func CalculateLongestPrefixLength(projectNames []string) { - for _, projectName := range projectNames { - if len(projectName) > longestPrefixLength { - longestPrefixLength = len(projectName) +func CalculateLongestPrefixLength(workspaceNames []string) { + for _, workspaceName := range workspaceNames { + if len(workspaceName) > longestPrefixLength { + longestPrefixLength = len(workspaceName) } } } diff --git a/pkg/views/prebuild/add/add.go b/pkg/views/prebuild/add/add.go index 950c0862ef..e4247e27e7 100644 --- a/pkg/views/prebuild/add/add.go +++ b/pkg/views/prebuild/add/add.go @@ -19,12 +19,12 @@ var DEFAULT_COMMIT_INTERVAL = "10" var DEFAULT_RETENTION = "3" type PrebuildAddView struct { - ProjectConfigName string - Branch string - CommitInterval string - TriggerFiles []string - Retention string - RunBuildOnAdd bool + WorkspaceConfigName string + Branch string + CommitInterval string + TriggerFiles []string + Retention string + RunBuildOnAdd bool } func PrebuildCreationView(prebuildAddView *PrebuildAddView, editing bool) { diff --git a/pkg/views/prebuild/info/view.go b/pkg/views/prebuild/info/view.go index 148c9eb7ed..74c2e448f4 100644 --- a/pkg/views/prebuild/info/view.go +++ b/pkg/views/prebuild/info/view.go @@ -32,7 +32,7 @@ func Render(prebuild *apiclient.PrebuildDTO, forceUnstyled bool) { output += getInfoLine("ID", prebuild.Id) + "\n" - output += getInfoLine("Project config", prebuild.ProjectConfigName) + "\n" + output += getInfoLine("Workspace config", prebuild.WorkspaceConfigName) + "\n" output += getInfoLine("Branch", views.GetBranchNameLabel(prebuild.Branch)) + "\n" diff --git a/pkg/views/prebuild/list/view.go b/pkg/views/prebuild/list/view.go index 3ff2f1a241..e0ba9f9a7c 100644 --- a/pkg/views/prebuild/list/view.go +++ b/pkg/views/prebuild/list/view.go @@ -17,11 +17,11 @@ import ( var maxTriggerFilesStringLength = 24 type rowData struct { - ProjectConfigName string - Branch string - CommitInterval string - TriggerFiles string - Retention string + WorkspaceConfigName string + Branch string + CommitInterval string + TriggerFiles string + Retention string } func ListPrebuilds(prebuildList []apiclient.PrebuildDTO) { @@ -37,7 +37,7 @@ func ListPrebuilds(prebuildList []apiclient.PrebuildDTO) { } table := util.GetTableView(data, []string{ - "Project Config", "Branch", "Commit Interval", "Trigger files", "Build Retention", + "Workspace Config", "Branch", "Commit Interval", "Trigger files", "Build Retention", }, nil, func() { renderUnstyledList(prebuildList) }) @@ -46,10 +46,10 @@ func ListPrebuilds(prebuildList []apiclient.PrebuildDTO) { } func renderUnstyledList(prebuildList []apiclient.PrebuildDTO) { - for _, pc := range prebuildList { - info.Render(&pc, true) + for _, wc := range prebuildList { + info.Render(&wc, true) - if pc.Id != prebuildList[len(prebuildList)-1].Id { + if wc.Id != prebuildList[len(prebuildList)-1].Id { fmt.Printf("\n%s\n\n", views.SeparatorString) } } @@ -58,7 +58,7 @@ func renderUnstyledList(prebuildList []apiclient.PrebuildDTO) { func getRowFromData(prebuildConfig apiclient.PrebuildDTO) []string { var data rowData - data.ProjectConfigName = prebuildConfig.ProjectConfigName + views_util.AdditionalPropertyPadding + data.WorkspaceConfigName = prebuildConfig.WorkspaceConfigName + views_util.AdditionalPropertyPadding data.Branch = prebuildConfig.Branch if prebuildConfig.CommitInterval != nil { data.CommitInterval = strconv.Itoa(int(*prebuildConfig.CommitInterval)) @@ -69,7 +69,7 @@ func getRowFromData(prebuildConfig apiclient.PrebuildDTO) []string { data.Retention = strconv.Itoa(int(prebuildConfig.Retention)) return []string{ - views.NameStyle.Render(data.ProjectConfigName), + views.NameStyle.Render(data.WorkspaceConfigName), views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(data.Branch)), views.ActiveStyle.Render(data.CommitInterval), views.DefaultRowDataStyle.Render(data.TriggerFiles), diff --git a/pkg/views/projectconfig/list/view.go b/pkg/views/projectconfig/list/view.go deleted file mode 100644 index b87b0d10dd..0000000000 --- a/pkg/views/projectconfig/list/view.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package list - -import ( - "fmt" - - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/projectconfig/info" - views_util "github.com/daytonaio/daytona/pkg/views/util" -) - -type rowData struct { - Name string - Repository string - Build string - Prebuilds string - IsDefault string -} - -func ListProjectConfigs(projectConfigList []apiclient.ProjectConfig, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) { - if len(projectConfigList) == 0 { - views_util.NotifyEmptyProjectConfigList(true) - return - } - - data := [][]string{} - - for _, pc := range projectConfigList { - data = append(data, getRowFromData(pc, apiServerConfig, specifyGitProviders)) - } - - table := views_util.GetTableView(data, []string{ - "Name", "Repository", "Build", "Prebuild rules", "Default", - }, nil, func() { - renderUnstyledList(projectConfigList, apiServerConfig) - }) - - fmt.Println(table) -} - -func renderUnstyledList(projectConfigList []apiclient.ProjectConfig, apiServerConfig *apiclient.ServerConfig) { - for _, pc := range projectConfigList { - info.Render(&pc, apiServerConfig, true) - - if pc.Name != projectConfigList[len(projectConfigList)-1].Name { - fmt.Printf("\n%s\n\n", views.SeparatorString) - } - } -} - -func getRowFromData(projectConfig apiclient.ProjectConfig, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) []string { - var isDefault string - var data rowData - - data.Name = projectConfig.Name + views_util.AdditionalPropertyPadding - data.Repository = util.GetRepositorySlugFromUrl(projectConfig.RepositoryUrl, specifyGitProviders) - data.Prebuilds = "None" - - projectDefaults := &views_util.ProjectConfigDefaults{ - Image: &apiServerConfig.DefaultProjectImage, - ImageUser: &apiServerConfig.DefaultProjectUser, - } - - createProjectDto := apiclient.CreateProjectDTO{ - BuildConfig: projectConfig.BuildConfig, - } - - _, data.Build = views_util.GetProjectBuildChoice(createProjectDto, projectDefaults) - - if projectConfig.Default { - isDefault = views.ActiveStyle.Render("Yes") - } else { - isDefault = views.InactiveStyle.Render("/") - } - - if len(projectConfig.Prebuilds) > 0 { - data.Prebuilds = fmt.Sprintf("%d", len(projectConfig.Prebuilds)) - } - - return []string{ - views.NameStyle.Render(data.Name), - views.DefaultRowDataStyle.Render(data.Repository), - views.DefaultRowDataStyle.Render(data.Build), - views.DefaultRowDataStyle.Render(data.Prebuilds), - isDefault, - } -} diff --git a/pkg/views/server/config.go b/pkg/views/server/config.go index 38ef02e011..f86c7b7623 100644 --- a/pkg/views/server/config.go +++ b/pkg/views/server/config.go @@ -23,9 +23,9 @@ func RenderConfig(config *server.Config) { output += fmt.Sprintf("%s %d", views.GetPropertyKey("API Port: "), config.ApiPort) + "\n\n" - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default Project Image: "), config.DefaultProjectImage) + "\n\n" + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default Workspace Image: "), config.DefaultWorkspaceImage) + "\n\n" - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default Project User: "), config.DefaultProjectUser) + "\n\n" + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default Workspace User: "), config.DefaultWorkspaceUser) + "\n\n" output += fmt.Sprintf("%s %s", views.GetPropertyKey("FRPS Domain: "), config.Frps.Domain) + "\n\n" diff --git a/pkg/views/server/configure.go b/pkg/views/server/configure.go index 6808c3a5a7..d382d8309e 100644 --- a/pkg/views/server/configure.go +++ b/pkg/views/server/configure.go @@ -77,11 +77,11 @@ func (m *Model) createForm(containerRegistries []apiclient.ContainerRegistry) *h ), huh.NewGroup( huh.NewInput(). - Title("Default Project Image"). - Value(&m.config.DefaultProjectImage), + Title("Default Workspace Image"). + Value(&m.config.DefaultWorkspaceImage), huh.NewInput(). - Title("Default Project User"). - Value(&m.config.DefaultProjectUser), + Title("Default Workspace User"). + Value(&m.config.DefaultWorkspaceUser), ), huh.NewGroup( huh.NewInput(). diff --git a/pkg/views/target/create/configuration.go b/pkg/views/target/create/configuration.go index 6e8cb1b8f2..08795f987b 100644 --- a/pkg/views/target/create/configuration.go +++ b/pkg/views/target/create/configuration.go @@ -5,7 +5,6 @@ package create import ( "errors" - "log" "path/filepath" "github.com/charmbracelet/bubbles/key" @@ -25,7 +24,7 @@ const ( var configurationHelpLine = lipgloss.NewStyle().Foreground(views.Gray).Render("enter: next f10: advanced configuration") -type ProjectConfigurationData struct { +type WorkspaceConfigurationData struct { BuildChoice string DevcontainerFilePath string Image string @@ -33,8 +32,8 @@ type ProjectConfigurationData struct { EnvVars map[string]string } -func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePath string, currentProject *apiclient.CreateProjectDTO, defaults *views_util.ProjectConfigDefaults) *ProjectConfigurationData { - projectConfigurationData := &ProjectConfigurationData{ +func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePath string, currentWorkspace *apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults) *WorkspaceConfigurationData { + workspaceConfigurationData := &WorkspaceConfigurationData{ BuildChoice: string(buildChoice), DevcontainerFilePath: defaults.DevcontainerFilePath, Image: *defaults.Image, @@ -42,103 +41,103 @@ func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePa EnvVars: map[string]string{}, } - if currentProject.Image != nil { - projectConfigurationData.Image = *currentProject.Image + if currentWorkspace.Image != nil { + workspaceConfigurationData.Image = *currentWorkspace.Image } - if currentProject.User != nil { - projectConfigurationData.User = *currentProject.User + if currentWorkspace.User != nil { + workspaceConfigurationData.User = *currentWorkspace.User } - if currentProject.EnvVars != nil { - projectConfigurationData.EnvVars = currentProject.EnvVars + if currentWorkspace.EnvVars != nil { + workspaceConfigurationData.EnvVars = currentWorkspace.EnvVars } - return projectConfigurationData + return workspaceConfigurationData } -func RunProjectConfiguration(projectList *[]apiclient.CreateProjectDTO, defaults views_util.ProjectConfigDefaults, isConfigImport bool) (bool, error) { - var currentProject *apiclient.CreateProjectDTO +func RunWorkspaceConfiguration(workspaceList *[]apiclient.CreateWorkspaceDTO, defaults views_util.WorkspaceConfigDefaults, isTemplateImport bool) (bool, error) { + var currentWorkspace *apiclient.CreateWorkspaceDTO - if len(*projectList) > 1 { - currentProject = selection.GetProjectRequestFromPrompt(projectList) - if currentProject == nil { + if len(*workspaceList) > 1 { + currentWorkspace = selection.GetWorkspaceRequestFromPrompt(workspaceList) + if currentWorkspace == nil { return false, common.ErrCtrlCAbort } } else { - currentProject = &((*projectList)[0]) + currentWorkspace = &((*workspaceList)[0]) } - if currentProject.Name == selection.DoneConfiguring.Name { + if currentWorkspace.Name == selection.DoneConfiguring.Name { return false, nil } devContainerFilePath := defaults.DevcontainerFilePath builderChoice := views_util.AUTOMATIC - if currentProject.BuildConfig != nil { - if currentProject.BuildConfig.Devcontainer != nil { + if currentWorkspace.BuildConfig != nil { + if currentWorkspace.BuildConfig.Devcontainer != nil { builderChoice = views_util.DEVCONTAINER - devContainerFilePath = currentProject.BuildConfig.Devcontainer.FilePath + devContainerFilePath = currentWorkspace.BuildConfig.Devcontainer.FilePath } } else { - if currentProject.Image == nil && currentProject.User == nil || - *currentProject.Image == *defaults.Image && *currentProject.User == *defaults.ImageUser { + if currentWorkspace.Image == nil && currentWorkspace.User == nil || + *currentWorkspace.Image == *defaults.Image && *currentWorkspace.User == *defaults.ImageUser { builderChoice = views_util.NONE } else { builderChoice = views_util.CUSTOMIMAGE } } - projectConfigurationData := NewConfigurationData(builderChoice, devContainerFilePath, currentProject, &defaults) + workspaceConfigurationData := NewConfigurationData(builderChoice, devContainerFilePath, currentWorkspace, &defaults) - if !isConfigImport { - form := GetProjectConfigurationForm(projectConfigurationData) + if !isTemplateImport { + form := GetWorkspaceConfigurationForm(workspaceConfigurationData) err := form.WithProgramOptions(tea.WithAltScreen()).Run() if err != nil { - log.Fatal(err) + return false, err } } - for i := range *projectList { - if (*projectList)[i].Name == currentProject.Name { - if projectConfigurationData.BuildChoice == string(views_util.NONE) { - (*projectList)[i].BuildConfig = nil - (*projectList)[i].Image = defaults.Image - (*projectList)[i].User = defaults.ImageUser + for i := range *workspaceList { + if (*workspaceList)[i].Name == currentWorkspace.Name { + if workspaceConfigurationData.BuildChoice == string(views_util.NONE) { + (*workspaceList)[i].BuildConfig = nil + (*workspaceList)[i].Image = defaults.Image + (*workspaceList)[i].User = defaults.ImageUser } - if projectConfigurationData.BuildChoice == string(views_util.CUSTOMIMAGE) { - (*projectList)[i].BuildConfig = nil - (*projectList)[i].Image = &projectConfigurationData.Image - (*projectList)[i].User = &projectConfigurationData.User + if workspaceConfigurationData.BuildChoice == string(views_util.CUSTOMIMAGE) { + (*workspaceList)[i].BuildConfig = nil + (*workspaceList)[i].Image = &workspaceConfigurationData.Image + (*workspaceList)[i].User = &workspaceConfigurationData.User } - if projectConfigurationData.BuildChoice == string(views_util.AUTOMATIC) { - (*projectList)[i].BuildConfig = &apiclient.BuildConfig{} - (*projectList)[i].Image = defaults.Image - (*projectList)[i].User = defaults.ImageUser + if workspaceConfigurationData.BuildChoice == string(views_util.AUTOMATIC) { + (*workspaceList)[i].BuildConfig = &apiclient.BuildConfig{} + (*workspaceList)[i].Image = defaults.Image + (*workspaceList)[i].User = defaults.ImageUser } - if projectConfigurationData.BuildChoice == string(views_util.DEVCONTAINER) { - (*projectList)[i].BuildConfig = &apiclient.BuildConfig{ + if workspaceConfigurationData.BuildChoice == string(views_util.DEVCONTAINER) { + (*workspaceList)[i].BuildConfig = &apiclient.BuildConfig{ Devcontainer: &apiclient.DevcontainerConfig{ - FilePath: projectConfigurationData.DevcontainerFilePath, + FilePath: workspaceConfigurationData.DevcontainerFilePath, }, } - (*projectList)[i].Image = nil - (*projectList)[i].User = nil + (*workspaceList)[i].Image = nil + (*workspaceList)[i].User = nil } - (*projectList)[i].EnvVars = projectConfigurationData.EnvVars + (*workspaceList)[i].EnvVars = workspaceConfigurationData.EnvVars } } - if len(*projectList) == 1 { + if len(*workspaceList) == 1 { return true, nil } - return RunProjectConfiguration(projectList, defaults, isConfigImport) + return RunWorkspaceConfiguration(workspaceList, defaults, isTemplateImport) } func validateDevcontainerFilename(filename string) error { @@ -149,7 +148,7 @@ func validateDevcontainerFilename(filename string) error { return nil } -func GetProjectConfigurationForm(projectConfiguration *ProjectConfigurationData) *huh.Form { +func GetWorkspaceConfigurationForm(workspaceConfiguration *WorkspaceConfigurationData) *huh.Form { buildOptions := []huh.Option[string]{ {Key: "Automatic", Value: string(views_util.AUTOMATIC)}, {Key: "Devcontainer", Value: string(views_util.DEVCONTAINER)}, @@ -164,27 +163,27 @@ func GetProjectConfigurationForm(projectConfiguration *ProjectConfigurationData) Options( buildOptions..., ). - Value(&projectConfiguration.BuildChoice), + Value(&workspaceConfiguration.BuildChoice), ).WithHeight(8), huh.NewGroup( huh.NewInput(). Title("Custom container image"). - Value(&projectConfiguration.Image), + Value(&workspaceConfiguration.Image), huh.NewInput(). Title("Container user"). - Value(&projectConfiguration.User), + Value(&workspaceConfiguration.User), ).WithHeight(5).WithHideFunc(func() bool { - return projectConfiguration.BuildChoice != string(views_util.CUSTOMIMAGE) + return workspaceConfiguration.BuildChoice != string(views_util.CUSTOMIMAGE) }), huh.NewGroup( huh.NewInput(). Title("Devcontainer file path"). - Value(&projectConfiguration.DevcontainerFilePath).Validate(validateDevcontainerFilename), + Value(&workspaceConfiguration.DevcontainerFilePath).Validate(validateDevcontainerFilename), ).WithHeight(5).WithHideFunc(func() bool { - return projectConfiguration.BuildChoice != string(views_util.DEVCONTAINER) + return workspaceConfiguration.BuildChoice != string(views_util.DEVCONTAINER) }), huh.NewGroup( - views.GetEnvVarsInput(&projectConfiguration.EnvVars), + views.GetEnvVarsInput(&workspaceConfiguration.EnvVars), ).WithHeight(12), ).WithTheme(views.GetCustomTheme()) diff --git a/pkg/views/target/create/summary.go b/pkg/views/target/create/summary.go index 8627636711..c25dc21bc5 100644 --- a/pkg/views/target/create/summary.go +++ b/pkg/views/target/create/summary.go @@ -18,47 +18,47 @@ import ( views_util "github.com/daytonaio/daytona/pkg/views/util" ) -type ProjectDetail string +type WorkspaceDetail string const ( - Build ProjectDetail = "Build" - DevcontainerConfig ProjectDetail = "Devcontainer Config" - Image ProjectDetail = "Image" - User ProjectDetail = "User" - EnvVars ProjectDetail = "Env Vars" - EMPTY_STRING = "" - DEFAULT_PADDING = 21 + Build WorkspaceDetail = "Build" + DevcontainerConfig WorkspaceDetail = "Devcontainer Config" + Image WorkspaceDetail = "Image" + User WorkspaceDetail = "User" + EnvVars WorkspaceDetail = "Env Vars" + EMPTY_STRING = "" + DEFAULT_PADDING = 21 ) type SummaryModel struct { - lg *lipgloss.Renderer - styles *Styles - form *huh.Form - width int - quitting bool - name string - projectList []apiclient.CreateProjectDTO - defaults *views_util.ProjectConfigDefaults - nameLabel string + lg *lipgloss.Renderer + styles *Styles + form *huh.Form + width int + quitting bool + name string + workspaceList []apiclient.CreateWorkspaceDTO + defaults *views_util.WorkspaceConfigDefaults + nameLabel string } type SubmissionFormConfig struct { ChosenName *string SuggestedName string ExistingNames []string - ProjectList *[]apiclient.CreateProjectDTO + WorkspaceList *[]apiclient.CreateWorkspaceDTO NameLabel string - Defaults *views_util.ProjectConfigDefaults + Defaults *views_util.WorkspaceConfigDefaults } var configureCheck bool var userCancelled bool -var ProjectsConfigurationChanged bool +var WorkspacesConfigurationChanged bool -func RunSubmissionForm(config SubmissionFormConfig, pcImport *bool) error { +func RunSubmissionForm(config SubmissionFormConfig, wtImport *bool) error { configureCheck = false - m := NewSummaryModel(config, pcImport) + m := NewSummaryModel(config, wtImport) if _, err := tea.NewProgram(m, tea.WithAltScreen()).Run(); err != nil { return err @@ -73,19 +73,19 @@ func RunSubmissionForm(config SubmissionFormConfig, pcImport *bool) error { } if config.Defaults.Image == nil || config.Defaults.ImageUser == nil { - return errors.New("default project entries are not set") + return errors.New("default workspace entries are not set") } var err error - ProjectsConfigurationChanged, err = RunProjectConfiguration(config.ProjectList, *config.Defaults, *pcImport) + WorkspacesConfigurationChanged, err = RunWorkspaceConfiguration(config.WorkspaceList, *config.Defaults, *wtImport) if err != nil { return err } - return RunSubmissionForm(config, pcImport) + return RunSubmissionForm(config, wtImport) } -func RenderSummary(name string, projectList []apiclient.CreateProjectDTO, defaults *views_util.ProjectConfigDefaults, nameLabel string) (string, error) { +func RenderSummary(name string, workspaceList []apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults, nameLabel string) (string, error) { var output string if name == "" { output = views.GetStyledMainTitle("SUMMARY") @@ -95,16 +95,16 @@ func RenderSummary(name string, projectList []apiclient.CreateProjectDTO, defaul output += "\n\n" - for i := range projectList { - if len(projectList) == 1 { - output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render("Project"), (projectList[i].Source.Repository.Url)) + for i := range workspaceList { + if len(workspaceList) == 1 { + output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render("Workspace"), (workspaceList[i].Source.Repository.Url)) } else { - output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render(fmt.Sprintf("%s #%d", "Project", i+1)), (projectList[i].Source.Repository.Url)) + output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render(fmt.Sprintf("%s #%d", "Workspace", i+1)), (workspaceList[i].Source.Repository.Url)) } - projectBuildChoice, choiceName := views_util.GetProjectBuildChoice(projectList[i], defaults) - output += renderProjectDetails(projectList[i], projectBuildChoice, choiceName) - if i < len(projectList)-1 { + workspaceBuildChoice, choiceName := views_util.GetWorkspaceBuildChoice(workspaceList[i], defaults) + output += renderWorkspaceDetails(workspaceList[i], workspaceBuildChoice, choiceName) + if i < len(workspaceList)-1 { output += "\n\n" } } @@ -112,57 +112,57 @@ func RenderSummary(name string, projectList []apiclient.CreateProjectDTO, defaul return output, nil } -func renderProjectDetails(project apiclient.CreateProjectDTO, buildChoice views_util.BuildChoice, choiceName string) string { - output := projectDetailOutput(Build, choiceName) +func renderWorkspaceDetails(workspace apiclient.CreateWorkspaceDTO, buildChoice views_util.BuildChoice, choiceName string) string { + output := workspaceDetailOutput(Build, choiceName) if buildChoice == views_util.DEVCONTAINER { - if project.BuildConfig != nil { - if project.BuildConfig.Devcontainer != nil { + if workspace.BuildConfig != nil { + if workspace.BuildConfig.Devcontainer != nil { output += "\n" - output += projectDetailOutput(DevcontainerConfig, project.BuildConfig.Devcontainer.FilePath) + output += workspaceDetailOutput(DevcontainerConfig, workspace.BuildConfig.Devcontainer.FilePath) } } } else { - if project.Image != nil { + if workspace.Image != nil { if output != "" { output += "\n" } - output += projectDetailOutput(Image, *project.Image) + output += workspaceDetailOutput(Image, *workspace.Image) } - if project.User != nil { + if workspace.User != nil { if output != "" { output += "\n" } - output += projectDetailOutput(User, *project.User) + output += workspaceDetailOutput(User, *workspace.User) } } - if len(project.EnvVars) > 0 { + if len(workspace.EnvVars) > 0 { if output != "" { output += "\n" } var envVars string - for key, val := range project.EnvVars { + for key, val := range workspace.EnvVars { envVars += fmt.Sprintf("%s=%s; ", key, val) } - output += projectDetailOutput(EnvVars, strings.TrimSuffix(envVars, "; ")) + output += workspaceDetailOutput(EnvVars, strings.TrimSuffix(envVars, "; ")) } return output } -func projectDetailOutput(projectDetailKey ProjectDetail, projectDetailValue string) string { - return fmt.Sprintf("\t%s%-*s%s", lipgloss.NewStyle().Foreground(views.Green).Render(string(projectDetailKey)), DEFAULT_PADDING-len(string(projectDetailKey)), EMPTY_STRING, projectDetailValue) +func workspaceDetailOutput(workspaceDetailKey WorkspaceDetail, workspaceDetailValue string) string { + return fmt.Sprintf("\t%s%-*s%s", lipgloss.NewStyle().Foreground(views.Green).Render(string(workspaceDetailKey)), DEFAULT_PADDING-len(string(workspaceDetailKey)), EMPTY_STRING, workspaceDetailValue) } -func NewSummaryModel(config SubmissionFormConfig, pcImport *bool) SummaryModel { +func NewSummaryModel(config SubmissionFormConfig, wtImport *bool) SummaryModel { m := SummaryModel{width: maxWidth} m.lg = lipgloss.DefaultRenderer() m.styles = NewStyles(m.lg) m.name = *config.ChosenName - m.projectList = *config.ProjectList + m.workspaceList = *config.WorkspaceList m.defaults = config.Defaults m.nameLabel = config.NameLabel @@ -170,7 +170,7 @@ func NewSummaryModel(config SubmissionFormConfig, pcImport *bool) SummaryModel { *config.ChosenName = config.SuggestedName } - if !*pcImport { + if !*wtImport { m.form = huh.NewForm( huh.NewGroup( huh.NewInput(). @@ -197,7 +197,7 @@ func NewSummaryModel(config SubmissionFormConfig, pcImport *bool) SummaryModel { huh.NewGroup( huh.NewConfirm(). Title("Is the above information correct?"). - Value(pcImport), + Value(wtImport), ), ).WithShowHelp(false).WithTheme(views.GetCustomTheme()) } @@ -250,8 +250,8 @@ func (m SummaryModel) View() string { view := m.form.WithHeight(5).View() + "\n" + configurationHelpLine - if len(m.projectList) > 1 || len(m.projectList) == 1 && ProjectsConfigurationChanged { - summary, err := RenderSummary(m.name, m.projectList, m.defaults, m.nameLabel) + if len(m.workspaceList) > 1 || len(m.workspaceList) == 1 && WorkspacesConfigurationChanged { + summary, err := RenderSummary(m.name, m.workspaceList, m.defaults, m.nameLabel) if err != nil { log.Fatal(err) } diff --git a/pkg/views/target/create/view.go b/pkg/views/target/create/view.go index 7cb652dc3d..61b10fb834 100644 --- a/pkg/views/target/create/view.go +++ b/pkg/views/target/create/view.go @@ -62,15 +62,15 @@ type Model struct { width int } -func GetRepositoryFromUrlInput(multiProject bool, projectOrder int, apiClient *apiclient.APIClient, selectedRepos map[string]int) (*apiclient.GitRepository, error) { +func GetRepositoryFromUrlInput(multiWorkspace bool, workspaceOrder int, apiClient *apiclient.APIClient, selectedRepos map[string]int) (*apiclient.GitRepository, error) { m := Model{width: maxWidth} m.lg = lipgloss.DefaultRenderer() m.styles = NewStyles(m.lg) title := "Git repository" - if multiProject { - title = getOrderNumberString(projectOrder) + " project repository" + if multiWorkspace { + title = getOrderNumberString(workspaceOrder) + " workspace repository" } var initialRepoUrl string @@ -82,7 +82,7 @@ func GetRepositoryFromUrlInput(multiProject bool, projectOrder int, apiClient *a initialRepoInput := huh.NewInput(). Title(title). Value(&initialRepoUrl). - Key("initialProjectRepo"). + Key("initialWorkspaceRepo"). Validate(func(str string) error { if str == previousRepoUrl && previousError != nil { return previousError @@ -125,7 +125,7 @@ func GetRepositoryFromUrlInput(multiProject bool, projectOrder int, apiClient *a return repo, nil } -func RunAddMoreProjectsForm() (bool, error) { +func RunAddMoreWorkspacesForm() (bool, error) { m := Model{width: maxWidth} m.lg = lipgloss.DefaultRenderer() m.styles = NewStyles(m.lg) @@ -134,7 +134,7 @@ func RunAddMoreProjectsForm() (bool, error) { confirmInput := huh.NewConfirm(). - Title("Add another project?"). + Title("Add another workspace?"). Value(&addMore) m.form = huh.NewForm( diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index 68c8905604..45ea1de940 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -45,10 +45,10 @@ func Render(target *apiclient.TargetDTO, ide string, forceUnstyled bool) { output += getInfoLine("Editor", ide) + "\n" } - if len(target.Projects) == 1 { - output += getSingleProjectOutput(&target.Projects[0], isCreationView) + if len(target.Workspaces) == 1 { + output += getSingleWorkspaceOutput(&target.Workspaces[0], isCreationView) } else { - output += getProjectsOutputs(target.Projects, isCreationView) + output += getWorkspacesOutputs(target.Workspaces, isCreationView) } terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) @@ -86,49 +86,49 @@ func renderTUIView(output string, width int, isCreationView bool) { fmt.Println(content) } -func getSingleProjectOutput(project *apiclient.Project, isCreationView bool) string { +func getSingleWorkspaceOutput(workspace *apiclient.Workspace, isCreationView bool) string { var output string var repositoryUrl string - repositoryUrl = project.Repository.Url + repositoryUrl = workspace.Repository.Url repositoryUrl = strings.TrimPrefix(repositoryUrl, "https://") repositoryUrl = strings.TrimPrefix(repositoryUrl, "http://") - if project.State != nil { - output += getInfoLineState("State", project.State) + "\n" - output += getInfoLineGitStatus("Branch", project.State.GitStatus) + "\n" + if workspace.State != nil { + output += getInfoLineState("State", workspace.State) + "\n" + output += getInfoLineGitStatus("Branch", workspace.State.GitStatus) + "\n" } - output += getInfoLinePrNumber(project.Repository.PrNumber, project.Repository, project.State) + output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) if !isCreationView { - output += getInfoLine("Target Config", project.TargetConfig) + "\n" + output += getInfoLine("Target Config", workspace.TargetConfig) + "\n" } output += getInfoLine("Repository", repositoryUrl) if !isCreationView { output += "\n" - output += getInfoLine("Project", project.Name) + output += getInfoLine("Workspace", workspace.Name) } return output } -func getProjectsOutputs(projects []apiclient.Project, isCreationView bool) string { +func getWorkspacesOutputs(workspaces []apiclient.Workspace, isCreationView bool) string { var output string - for i, project := range projects { - output += getInfoLine(fmt.Sprintf("Project #%d", i+1), project.Name) - output += getInfoLineState("State", project.State) - if project.State != nil { - output += getInfoLineGitStatus("Branch", project.State.GitStatus) + for i, workspace := range workspaces { + output += getInfoLine(fmt.Sprintf("Workspace #%d", i+1), workspace.Name) + output += getInfoLineState("State", workspace.State) + if workspace.State != nil { + output += getInfoLineGitStatus("Branch", workspace.State.GitStatus) } - output += getInfoLinePrNumber(project.Repository.PrNumber, project.Repository, project.State) + output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) if !isCreationView { - output += getInfoLine("Target Config", project.TargetConfig) + output += getInfoLine("Target Config", workspace.TargetConfig) } - output += getInfoLine("Repository", project.Repository.Url) - if project.Name != projects[len(projects)-1].Name { + output += getInfoLine("Repository", workspace.Repository.Url) + if workspace.Name != workspaces[len(workspaces)-1].Name { output += "\n" } } @@ -139,7 +139,7 @@ func getInfoLine(key, value string) string { return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + propertyValueStyle.Render(value) + "\n" } -func getInfoLineState(key string, state *apiclient.ProjectState) string { +func getInfoLineState(key string, state *apiclient.WorkspaceState) string { var uptime int var stateProperty string @@ -204,7 +204,7 @@ func getInfoLineGitStatus(key string, status *apiclient.GitStatus) string { return output } -func getInfoLinePrNumber(PrNumber *int32, repo apiclient.GitRepository, state *apiclient.ProjectState) string { +func getInfoLinePrNumber(PrNumber *int32, repo apiclient.GitRepository, state *apiclient.WorkspaceState) string { if PrNumber != nil && (state == nil || state.GitStatus.CurrentBranch == repo.Branch) { return getInfoLine("PR Number", fmt.Sprintf("#%d", *PrNumber)) + "\n" } diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index c29f1d31f2..1bf11590b4 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -40,15 +40,15 @@ func ListTargets(targetList []apiclient.TargetDTO, specifyGitProviders bool, ver var rowData *RowData var row []string - if len(target.Projects) == 1 { + if len(target.Workspaces) == 1 { rowData = getTargetTableRowData(target, specifyGitProviders) row = getRowFromRowData(*rowData, false) data = append(data, row) } else { row = getRowFromRowData(RowData{Name: target.Name}, true) data = append(data, row) - for _, project := range target.Projects { - rowData = getProjectTableRowData(target, project, specifyGitProviders) + for _, workspace := range target.Workspaces { + rowData = getWorkspaceTableRowData(target, workspace, specifyGitProviders) if rowData == nil { continue } @@ -91,7 +91,7 @@ func renderUnstyledList(targetList []apiclient.TargetDTO) { } } -func getRowFromRowData(rowData RowData, isMultiProjectAccordion bool) []string { +func getRowFromRowData(rowData RowData, isMultiWorkspaceAccordion bool) []string { var state string if rowData.Status == "" { state = views.InactiveStyle.Render("STOPPED") @@ -99,7 +99,7 @@ func getRowFromRowData(rowData RowData, isMultiProjectAccordion bool) []string { state = views.ActiveStyle.Render("RUNNING") } - if isMultiProjectAccordion { + if isMultiWorkspaceAccordion { return []string{rowData.Name, "", "", "", "", ""} } @@ -124,13 +124,13 @@ func SortTargets(targetList *[]apiclient.TargetDTO, verbose bool) { sort.Slice(*targetList, func(i, j int) bool { t1 := (*targetList)[i] t2 := (*targetList)[j] - if t1.Info == nil || t2.Info == nil || t1.Info.Projects == nil || t2.Info.Projects == nil { + if t1.Info == nil || t2.Info == nil || t1.Info.Workspaces == nil || t2.Info.Workspaces == nil { return true } - if len(t1.Info.Projects) == 0 || len(t2.Info.Projects) == 0 { + if len(t1.Info.Workspaces) == 0 || len(t2.Info.Workspaces) == 0 { return true } - return t1.Info.Projects[0].Created > t2.Info.Projects[0].Created + return t1.Info.Workspaces[0].Created > t2.Info.Workspaces[0].Created }) return } @@ -138,10 +138,10 @@ func SortTargets(targetList *[]apiclient.TargetDTO, verbose bool) { sort.Slice(*targetList, func(i, j int) bool { t1 := (*targetList)[i] t2 := (*targetList)[j] - if len(t1.Projects) == 0 || len(t2.Projects) == 0 || t1.Projects[0].State == nil || t2.Projects[0].State == nil { + if len(t1.Workspaces) == 0 || len(t2.Workspaces) == 0 || t1.Workspaces[0].State == nil || t2.Workspaces[0].State == nil { return true } - return t1.Projects[0].State.Uptime < t2.Projects[0].State.Uptime + return t1.Workspaces[0].State.Uptime < t2.Workspaces[0].State.Uptime }) } @@ -149,42 +149,42 @@ func SortTargets(targetList *[]apiclient.TargetDTO, verbose bool) { func getTargetTableRowData(target apiclient.TargetDTO, specifyGitProviders bool) *RowData { rowData := RowData{"", "", "", "", "", ""} rowData.Name = target.Name + views_util.AdditionalPropertyPadding - if len(target.Projects) > 0 { - rowData.Repository = util.GetRepositorySlugFromUrl(target.Projects[0].Repository.Url, specifyGitProviders) - rowData.Branch = target.Projects[0].Repository.Branch + if len(target.Workspaces) > 0 { + rowData.Repository = util.GetRepositorySlugFromUrl(target.Workspaces[0].Repository.Url, specifyGitProviders) + rowData.Branch = target.Workspaces[0].Repository.Branch } rowData.TargetConfig = target.TargetConfig + views_util.AdditionalPropertyPadding - if target.Info != nil && target.Info.Projects != nil && len(target.Info.Projects) > 0 { - rowData.Created = util.FormatTimestamp(target.Info.Projects[0].Created) + if target.Info != nil && target.Info.Workspaces != nil && len(target.Info.Workspaces) > 0 { + rowData.Created = util.FormatTimestamp(target.Info.Workspaces[0].Created) } - if len(target.Projects) > 0 && target.Projects[0].State != nil && target.Projects[0].State.Uptime > 0 { - rowData.Status = util.FormatUptime(target.Projects[0].State.Uptime) + if len(target.Workspaces) > 0 && target.Workspaces[0].State != nil && target.Workspaces[0].State.Uptime > 0 { + rowData.Status = util.FormatUptime(target.Workspaces[0].State.Uptime) } return &rowData } -func getProjectTableRowData(targetDTO apiclient.TargetDTO, project apiclient.Project, specifyGitProviders bool) *RowData { +func getWorkspaceTableRowData(targetDTO apiclient.TargetDTO, workspace apiclient.Workspace, specifyGitProviders bool) *RowData { rowData := RowData{"", "", "", "", "", ""} - rowData.Name = " └ " + project.Name + rowData.Name = " └ " + workspace.Name - rowData.Repository = util.GetRepositorySlugFromUrl(project.Repository.Url, specifyGitProviders) - rowData.Branch = project.Repository.Branch + rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) + rowData.Branch = workspace.Repository.Branch - rowData.TargetConfig = project.TargetConfig + views_util.AdditionalPropertyPadding + rowData.TargetConfig = workspace.TargetConfig + views_util.AdditionalPropertyPadding - if project.State != nil && project.State.Uptime > 0 { - rowData.Status = util.FormatUptime(project.State.Uptime) + if workspace.State != nil && workspace.State.Uptime > 0 { + rowData.Status = util.FormatUptime(workspace.State.Uptime) } - if targetDTO.Info == nil || targetDTO.Info.Projects == nil { + if targetDTO.Info == nil || targetDTO.Info.Workspaces == nil { return &rowData } - for _, projectInfo := range targetDTO.Info.Projects { - if projectInfo.Name == project.Name { - rowData.Created = util.FormatTimestamp(projectInfo.Created) + for _, workspaceInfo := range targetDTO.Info.Workspaces { + if workspaceInfo.Name == workspace.Name { + rowData.Created = util.FormatTimestamp(workspaceInfo.Created) break } } diff --git a/pkg/views/target/selection/branch.go b/pkg/views/target/selection/branch.go index 6f9a471a66..365233b130 100644 --- a/pkg/views/target/selection/branch.go +++ b/pkg/views/target/selection/branch.go @@ -14,7 +14,7 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -func selectBranchPrompt(branches []apiclient.GitBranch, projectOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { +func selectBranchPrompt(branches []apiclient.GitBranch, workspaceOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { items := []list.Item{} for _, branch := range branches { @@ -32,8 +32,8 @@ func selectBranchPrompt(branches []apiclient.GitBranch, projectOrder int, select l := views.GetStyledSelectList(items, selectionListOptions) title := "Choose a Branch" - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle @@ -58,11 +58,11 @@ func selectBranchPrompt(branches []apiclient.GitBranch, projectOrder int, select } } -func GetBranchFromPrompt(branches []apiclient.GitBranch, projectOrder int, selectionListOptions views.SelectionListOptions) (*apiclient.GitBranch, string) { +func GetBranchFromPrompt(branches []apiclient.GitBranch, workspaceOrder int, selectionListOptions views.SelectionListOptions) (*apiclient.GitBranch, string) { choiceChan := make(chan string) navChan := make(chan string) - go selectBranchPrompt(branches, projectOrder, selectionListOptions, choiceChan, navChan) + go selectBranchPrompt(branches, workspaceOrder, selectionListOptions, choiceChan, navChan) select { case branchName := <-choiceChan: diff --git a/pkg/views/target/selection/checkout.go b/pkg/views/target/selection/checkout.go index 19ee6c23d5..96d3f47580 100644 --- a/pkg/views/target/selection/checkout.go +++ b/pkg/views/target/selection/checkout.go @@ -24,7 +24,7 @@ var ( CheckoutPR = CheckoutOption{Title: "Pull/Merge requests", Id: "pullrequest"} ) -func selectCheckoutPrompt(checkoutOptions []CheckoutOption, projectOrder int, parentIdentifier string, choiceChan chan<- string) { +func selectCheckoutPrompt(checkoutOptions []CheckoutOption, workspaceOrder int, parentIdentifier string, choiceChan chan<- string) { items := []list.Item{} for _, checkoutOption := range checkoutOptions { @@ -38,8 +38,8 @@ func selectCheckoutPrompt(checkoutOptions []CheckoutOption, projectOrder int, pa l := views.GetStyledSelectList(items, listOptions) title := "Cloning Options" - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle @@ -58,10 +58,10 @@ func selectCheckoutPrompt(checkoutOptions []CheckoutOption, projectOrder int, pa } } -func GetCheckoutOptionFromPrompt(projectOrder int, checkoutOptions []CheckoutOption, parentIdentifier string) CheckoutOption { +func GetCheckoutOptionFromPrompt(workspaceOrder int, checkoutOptions []CheckoutOption, parentIdentifier string) CheckoutOption { choiceChan := make(chan string) - go selectCheckoutPrompt(checkoutOptions, projectOrder, parentIdentifier, choiceChan) + go selectCheckoutPrompt(checkoutOptions, workspaceOrder, parentIdentifier, choiceChan) checkoutOptionId := <-choiceChan diff --git a/pkg/views/target/selection/gitprovider.go b/pkg/views/target/selection/gitprovider.go index a2aa54c0b8..70dfd61b6f 100644 --- a/pkg/views/target/selection/gitprovider.go +++ b/pkg/views/target/selection/gitprovider.go @@ -17,7 +17,7 @@ import ( var titleStyle = lipgloss.NewStyle() -func selectGitProviderPrompt(gitProviders []gitprovider_view.GitProviderView, projectOrder int, choiceChan chan<- string, samplesEnabled bool) { +func selectGitProviderPrompt(gitProviders []gitprovider_view.GitProviderView, workspaceOrder int, choiceChan chan<- string, samplesEnabled bool) { items := []list.Item{} for _, provider := range gitProviders { @@ -36,8 +36,8 @@ func selectGitProviderPrompt(gitProviders []gitprovider_view.GitProviderView, pr l := views.GetStyledSelectList(items) title := "Choose a Git Provider" - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle @@ -56,9 +56,9 @@ func selectGitProviderPrompt(gitProviders []gitprovider_view.GitProviderView, pr } } -func GetProviderIdFromPrompt(gitProviders []gitprovider_view.GitProviderView, projectOrder int, samplesEnabled bool) string { +func GetProviderIdFromPrompt(gitProviders []gitprovider_view.GitProviderView, workspaceOrder int, samplesEnabled bool) string { choiceChan := make(chan string) - go selectGitProviderPrompt(gitProviders, projectOrder, choiceChan, samplesEnabled) + go selectGitProviderPrompt(gitProviders, workspaceOrder, choiceChan, samplesEnabled) return <-choiceChan } diff --git a/pkg/views/target/selection/namespace.go b/pkg/views/target/selection/namespace.go index 7678de8216..3d454fb31b 100644 --- a/pkg/views/target/selection/namespace.go +++ b/pkg/views/target/selection/namespace.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func selectNamespacePrompt(namespaces []apiclient.GitNamespace, projectOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { +func selectNamespacePrompt(namespaces []apiclient.GitNamespace, workspaceOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { items := []list.Item{} var desc string @@ -34,8 +34,8 @@ func selectNamespacePrompt(namespaces []apiclient.GitNamespace, projectOrder int l := views.GetStyledSelectList(items, selectionListOptions) title := "Choose a Namespace" - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle @@ -60,11 +60,11 @@ func selectNamespacePrompt(namespaces []apiclient.GitNamespace, projectOrder int } } -func GetNamespaceIdFromPrompt(namespaces []apiclient.GitNamespace, projectOrder int, selectionListOptions views.SelectionListOptions) (string, string) { +func GetNamespaceIdFromPrompt(namespaces []apiclient.GitNamespace, workspaceOrder int, selectionListOptions views.SelectionListOptions) (string, string) { choiceChan := make(chan string) navChan := make(chan string) - go selectNamespacePrompt(namespaces, projectOrder, selectionListOptions, choiceChan, navChan) + go selectNamespacePrompt(namespaces, workspaceOrder, selectionListOptions, choiceChan, navChan) select { case choice := <-choiceChan: diff --git a/pkg/views/target/selection/prebuild.go b/pkg/views/target/selection/prebuild.go index fee06f6992..6d36b32f78 100644 --- a/pkg/views/target/selection/prebuild.go +++ b/pkg/views/target/selection/prebuild.go @@ -25,7 +25,7 @@ func selectPrebuildPrompt(prebuilds []apiclient.PrebuildDTO, actionVerb string, items := []list.Item{} for _, pb := range prebuilds { - title := fmt.Sprintf("%s (%s)", pb.ProjectConfigName, views.GetBranchNameLabel(pb.Branch)) + title := fmt.Sprintf("%s (%s)", pb.WorkspaceConfigName, views.GetBranchNameLabel(pb.Branch)) desc := pb.Id if pb.CommitInterval != nil { diff --git a/pkg/views/target/selection/projectconfig.go b/pkg/views/target/selection/projectconfig.go deleted file mode 100644 index b9783b6043..0000000000 --- a/pkg/views/target/selection/projectconfig.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package selection - -import ( - "fmt" - "os" - - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" -) - -var BlankProjectIdentifier = "" -var NewProjectConfigIdentifier = "" - -func GetProjectConfigFromPrompt(projectConfigs []apiclient.ProjectConfig, projectOrder int, showBlankOption, withNewProjectConfig bool, actionVerb string) *apiclient.ProjectConfig { - choiceChan := make(chan *apiclient.ProjectConfig) - go selectProjectConfigPrompt(projectConfigs, projectOrder, showBlankOption, withNewProjectConfig, actionVerb, choiceChan) - return <-choiceChan -} - -func selectProjectConfigPrompt(projectConfigs []apiclient.ProjectConfig, projectOrder int, showBlankOption, withNewProjectConfig bool, actionVerb string, choiceChan chan<- *apiclient.ProjectConfig) { - items := []list.Item{} - - if showBlankOption { - newItem := item[apiclient.ProjectConfig]{title: "Make a blank project", desc: "(default project configuration)", choiceProperty: apiclient.ProjectConfig{ - Name: BlankProjectIdentifier, - }} - items = append(items, newItem) - } - - for _, pc := range projectConfigs { - projectConfigName := pc.Name - if pc.Name == "" { - projectConfigName = "Unnamed Project Config" - } - - newItem := item[apiclient.ProjectConfig]{title: projectConfigName, desc: pc.RepositoryUrl, choiceProperty: pc} - items = append(items, newItem) - } - - if withNewProjectConfig { - newItem := item[apiclient.ProjectConfig]{title: "+ Create a new project configuration", desc: "", choiceProperty: apiclient.ProjectConfig{ - Name: NewProjectConfigIdentifier, - }} - items = append(items, newItem) - } - - d := list.NewDefaultDelegate() - - d.Styles.SelectedTitle = lipgloss.NewStyle(). - Border(lipgloss.NormalBorder(), false, false, false, true). - BorderForeground(views.Green). - Foreground(views.Green). - Bold(true). - Padding(0, 0, 0, 1) - - d.Styles.SelectedDesc = d.Styles.SelectedTitle.Foreground(views.DimmedGreen) - - l := list.New(items, d, 0, 0) - - l.Styles.FilterPrompt = lipgloss.NewStyle().Foreground(views.Green) - l.Styles.FilterCursor = lipgloss.NewStyle().Foreground(views.Green) - - l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) - l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) - - title := "Select a Project Config To " + actionVerb - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) - } - l.Title = views.GetStyledMainTitle(title) - l.Styles.Title = titleStyle - - m := model[apiclient.ProjectConfig]{list: l} - - p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() - if err != nil { - fmt.Println("Error running program:", err) - os.Exit(1) - } - - if m, ok := p.(model[apiclient.ProjectConfig]); ok && m.choice != nil { - choiceChan <- m.choice - } else { - choiceChan <- nil - } -} diff --git a/pkg/views/target/selection/pullrequest.go b/pkg/views/target/selection/pullrequest.go index c0c4332123..13bfe341f0 100644 --- a/pkg/views/target/selection/pullrequest.go +++ b/pkg/views/target/selection/pullrequest.go @@ -14,7 +14,7 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -func selectPullRequestPrompt(pullRequests []apiclient.GitPullRequest, projectOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { +func selectPullRequestPrompt(pullRequests []apiclient.GitPullRequest, workspaceOrder int, selectionListOptions views.SelectionListOptions, choiceChan chan<- string, navChan chan<- string) { items := []list.Item{} for _, pr := range pullRequests { @@ -34,8 +34,8 @@ func selectPullRequestPrompt(pullRequests []apiclient.GitPullRequest, projectOrd l := views.GetStyledSelectList(items, selectionListOptions) title := "Choose a Pull/Merge Request" - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle @@ -59,11 +59,11 @@ func selectPullRequestPrompt(pullRequests []apiclient.GitPullRequest, projectOrd } } -func GetPullRequestFromPrompt(pullRequests []apiclient.GitPullRequest, projectOrder int, selectionListOptions views.SelectionListOptions) (*apiclient.GitPullRequest, string) { +func GetPullRequestFromPrompt(pullRequests []apiclient.GitPullRequest, workspaceOrder int, selectionListOptions views.SelectionListOptions) (*apiclient.GitPullRequest, string) { choiceChan := make(chan string) navChan := make(chan string) - go selectPullRequestPrompt(pullRequests, projectOrder, selectionListOptions, choiceChan, navChan) + go selectPullRequestPrompt(pullRequests, workspaceOrder, selectionListOptions, choiceChan, navChan) select { case pullRequestName := <-choiceChan: diff --git a/pkg/views/target/selection/repository.go b/pkg/views/target/selection/repository.go index 5557a08013..0e9aed6ead 100644 --- a/pkg/views/target/selection/repository.go +++ b/pkg/views/target/selection/repository.go @@ -14,7 +14,7 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -func selectRepositoryPrompt(repositories []apiclient.GitRepository, projectOrder int, choiceChan chan<- string, navChan chan<- string, selectedRepos map[string]int, selectionListOptions views.SelectionListOptions) { +func selectRepositoryPrompt(repositories []apiclient.GitRepository, workspaceOrder int, choiceChan chan<- string, navChan chan<- string, selectedRepos map[string]int, selectionListOptions views.SelectionListOptions) { items := []list.Item{} for _, repository := range repositories { @@ -34,8 +34,8 @@ func selectRepositoryPrompt(repositories []apiclient.GitRepository, projectOrder l := views.GetStyledSelectList(items, selectionListOptions) title := "Choose a Repository" - if projectOrder > 1 { - title += fmt.Sprintf(" (Project #%d)", projectOrder) + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle @@ -61,11 +61,11 @@ func selectRepositoryPrompt(repositories []apiclient.GitRepository, projectOrder } } -func GetRepositoryFromPrompt(repositories []apiclient.GitRepository, projectOrder int, selectedRepos map[string]int, selectionListOptions views.SelectionListOptions) (*apiclient.GitRepository, string) { +func GetRepositoryFromPrompt(repositories []apiclient.GitRepository, workspaceOrder int, selectedRepos map[string]int, selectionListOptions views.SelectionListOptions) (*apiclient.GitRepository, string) { choiceChan := make(chan string) navChan := make(chan string) - go selectRepositoryPrompt(repositories, projectOrder, choiceChan, navChan, selectedRepos, selectionListOptions) + go selectRepositoryPrompt(repositories, workspaceOrder, choiceChan, navChan, selectedRepos, selectionListOptions) select { case choice := <-choiceChan: diff --git a/pkg/views/target/selection/target.go b/pkg/views/target/selection/target.go index c45bda76ce..e8227e9869 100644 --- a/pkg/views/target/selection/target.go +++ b/pkg/views/target/selection/target.go @@ -24,38 +24,38 @@ func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, ac // Populate items with titles and descriptions from targets. for _, target := range targets { - var projectsInfo []string + var workspacesInfo []string - if len(target.Projects) == 0 { + if len(target.Workspaces) == 0 { continue } - if len(target.Projects) == 1 { - projectsInfo = append(projectsInfo, util.GetRepositorySlugFromUrl(target.Projects[0].Repository.Url, true)) + if len(target.Workspaces) == 1 { + workspacesInfo = append(workspacesInfo, util.GetRepositorySlugFromUrl(target.Workspaces[0].Repository.Url, true)) } else { - for _, project := range target.Projects { - projectsInfo = append(projectsInfo, project.Name) + for _, workspace := range target.Workspaces { + workspacesInfo = append(workspacesInfo, workspace.Name) } } // Get the time if available uptime := "" createdTime := "" - if target.Info != nil && target.Info.Projects != nil && len(target.Info.Projects) > 0 { - createdTime = util.FormatTimestamp(target.Info.Projects[0].Created) + if target.Info != nil && target.Info.Workspaces != nil && len(target.Info.Workspaces) > 0 { + createdTime = util.FormatTimestamp(target.Info.Workspaces[0].Created) } - if len(target.Projects) > 0 && target.Projects[0].State != nil { - if target.Projects[0].State.Uptime == 0 { + if len(target.Workspaces) > 0 && target.Workspaces[0].State != nil { + if target.Workspaces[0].State.Uptime == 0 { uptime = "STOPPED" } else { - uptime = fmt.Sprintf("up %s", util.FormatUptime(target.Projects[0].State.Uptime)) + uptime = fmt.Sprintf("up %s", util.FormatUptime(target.Workspaces[0].State.Uptime)) } } newItem := item[apiclient.TargetDTO]{ title: target.Name, id: target.Id, - desc: strings.Join(projectsInfo, ", "), + desc: strings.Join(workspacesInfo, ", "), createdTime: createdTime, uptime: uptime, targetConfig: target.TargetConfig, diff --git a/pkg/views/target/selection/project.go b/pkg/views/target/selection/workspace.go similarity index 63% rename from pkg/views/target/selection/project.go rename to pkg/views/target/selection/workspace.go index 373a0546bc..5e98459f08 100644 --- a/pkg/views/target/selection/project.go +++ b/pkg/views/target/selection/workspace.go @@ -15,22 +15,22 @@ import ( "github.com/charmbracelet/lipgloss" ) -func GetProjectFromPrompt(projects []apiclient.Project, actionVerb string) *apiclient.Project { - choiceChan := make(chan *apiclient.Project) - go selectProjectPrompt(projects, actionVerb, choiceChan) +func GetWorkspaceFromPrompt(workspaces []apiclient.Workspace, actionVerb string) *apiclient.Workspace { + choiceChan := make(chan *apiclient.Workspace) + go selectWorkspacePrompt(workspaces, actionVerb, choiceChan) return <-choiceChan } -func selectProjectPrompt(projects []apiclient.Project, actionVerb string, choiceChan chan<- *apiclient.Project) { +func selectWorkspacePrompt(workspaces []apiclient.Workspace, actionVerb string, choiceChan chan<- *apiclient.Workspace) { items := []list.Item{} - for _, project := range projects { - projectName := project.Name - if project.Name == "" { - projectName = "Unnamed Project" + for _, workspace := range workspaces { + workspaceName := workspace.Name + if workspace.Name == "" { + workspaceName = "Unnamed Workspace" } - newItem := item[apiclient.Project]{title: projectName, desc: "", choiceProperty: project} + newItem := item[apiclient.Workspace]{title: workspaceName, desc: "", choiceProperty: workspace} items = append(items, newItem) } @@ -53,9 +53,9 @@ func selectProjectPrompt(projects []apiclient.Project, actionVerb string, choice l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) - m := model[apiclient.Project]{list: l} + m := model[apiclient.Workspace]{list: l} - m.list.Title = views.GetStyledMainTitle("Select a Project To " + actionVerb) + m.list.Title = views.GetStyledMainTitle("Select a Workspace To " + actionVerb) m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() @@ -64,7 +64,7 @@ func selectProjectPrompt(projects []apiclient.Project, actionVerb string, choice os.Exit(1) } - if m, ok := p.(model[apiclient.Project]); ok && m.choice != nil { + if m, ok := p.(model[apiclient.Workspace]); ok && m.choice != nil { choiceChan <- m.choice } else { choiceChan <- nil diff --git a/pkg/views/target/selection/workspaceconfig.go b/pkg/views/target/selection/workspaceconfig.go new file mode 100644 index 0000000000..75921666c3 --- /dev/null +++ b/pkg/views/target/selection/workspaceconfig.go @@ -0,0 +1,93 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package selection + +import ( + "fmt" + "os" + + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" +) + +var BlankWorkspaceIdentifier = "" +var NewWorkspaceConfigIdentifier = "" + +func GetWorkspaceConfigFromPrompt(workspaceConfigs []apiclient.WorkspaceConfig, workspaceOrder int, showBlankOption, withNewWorkspaceConfig bool, actionVerb string) *apiclient.WorkspaceConfig { + choiceChan := make(chan *apiclient.WorkspaceConfig) + go selectWorkspaceConfigPrompt(workspaceConfigs, workspaceOrder, showBlankOption, withNewWorkspaceConfig, actionVerb, choiceChan) + return <-choiceChan +} + +func selectWorkspaceConfigPrompt(workspaceConfigs []apiclient.WorkspaceConfig, workspaceOrder int, showBlankOption, withNewWorkspaceConfig bool, actionVerb string, choiceChan chan<- *apiclient.WorkspaceConfig) { + items := []list.Item{} + + if showBlankOption { + newItem := item[apiclient.WorkspaceConfig]{title: "Make a blank workspace", desc: "(default workspace configuration)", choiceProperty: apiclient.WorkspaceConfig{ + Name: BlankWorkspaceIdentifier, + }} + items = append(items, newItem) + } + + for _, wc := range workspaceConfigs { + workspaceConfigName := wc.Name + if wc.Name == "" { + workspaceConfigName = "Unnamed Workspace Config" + } + + newItem := item[apiclient.WorkspaceConfig]{title: workspaceConfigName, desc: wc.RepositoryUrl, choiceProperty: wc} + items = append(items, newItem) + } + + if withNewWorkspaceConfig { + newItem := item[apiclient.WorkspaceConfig]{title: "+ Create a new workspace configuration", desc: "", choiceProperty: apiclient.WorkspaceConfig{ + Name: NewWorkspaceConfigIdentifier, + }} + items = append(items, newItem) + } + + d := list.NewDefaultDelegate() + + d.Styles.SelectedTitle = lipgloss.NewStyle(). + Border(lipgloss.NormalBorder(), false, false, false, true). + BorderForeground(views.Green). + Foreground(views.Green). + Bold(true). + Padding(0, 0, 0, 1) + + d.Styles.SelectedDesc = d.Styles.SelectedTitle.Foreground(views.DimmedGreen) + + l := list.New(items, d, 0, 0) + + l.Styles.FilterPrompt = lipgloss.NewStyle().Foreground(views.Green) + l.Styles.FilterCursor = lipgloss.NewStyle().Foreground(views.Green) + + l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) + l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) + + title := "Select a Workspace Config To " + actionVerb + if workspaceOrder > 1 { + title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) + } + l.Title = views.GetStyledMainTitle(title) + l.Styles.Title = titleStyle + + m := model[apiclient.WorkspaceConfig]{list: l} + + p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() + if err != nil { + fmt.Println("Error running program:", err) + os.Exit(1) + } + + if m, ok := p.(model[apiclient.WorkspaceConfig]); ok && m.choice != nil { + choiceChan <- m.choice + } else { + choiceChan <- nil + } +} diff --git a/pkg/views/target/selection/projectrequest.go b/pkg/views/target/selection/workspacerequest.go similarity index 55% rename from pkg/views/target/selection/projectrequest.go rename to pkg/views/target/selection/workspacerequest.go index 81e1449713..3f035ce58a 100644 --- a/pkg/views/target/selection/projectrequest.go +++ b/pkg/views/target/selection/workspacerequest.go @@ -19,60 +19,60 @@ import ( ) var doneConfiguringName = "DoneConfiguringName" -var DoneConfiguring = apiclient.CreateProjectDTO{ +var DoneConfiguring = apiclient.CreateWorkspaceDTO{ Name: doneConfiguringName, } -type projectRequestItem struct { - item[apiclient.CreateProjectDTO] +type workspaceRequestItem struct { + item[apiclient.CreateWorkspaceDTO] name, image, user, devcontainerConfig string - project apiclient.CreateProjectDTO + workspace apiclient.CreateWorkspaceDTO } -type projectRequestItemDelegate struct { - ItemDelegate[apiclient.CreateProjectDTO] +type workspaceRequestItemDelegate struct { + ItemDelegate[apiclient.CreateWorkspaceDTO] } -type projectRequestModel struct { - model[apiclient.CreateProjectDTO] +type workspaceRequestModel struct { + model[apiclient.CreateWorkspaceDTO] } -func selectProjectRequestPrompt(projects *[]apiclient.CreateProjectDTO, choiceChan chan<- *apiclient.CreateProjectDTO) { +func selectWorkspaceRequestPrompt(workspaces *[]apiclient.CreateWorkspaceDTO, choiceChan chan<- *apiclient.CreateWorkspaceDTO) { items := []list.Item{} - for _, project := range *projects { + for _, workspace := range *workspaces { var name string var image string var user string var devcontainerConfig string - name = fmt.Sprintf("%s %s", "Project:", project.Name) - if project.Image != nil { - image = fmt.Sprintf("%s %s", "Image:", *project.Image) + name = fmt.Sprintf("%s %s", "Workspace:", workspace.Name) + if workspace.Image != nil { + image = fmt.Sprintf("%s %s", "Image:", *workspace.Image) } - if project.User != nil { - user = fmt.Sprintf("%s %s", "User:", *project.User) + if workspace.User != nil { + user = fmt.Sprintf("%s %s", "User:", *workspace.User) } - if project.BuildConfig != nil && project.BuildConfig.Devcontainer != nil { - devcontainerConfig = fmt.Sprintf("%s %s", "Devcontainer Config:", project.BuildConfig.Devcontainer.FilePath) + if workspace.BuildConfig != nil && workspace.BuildConfig.Devcontainer != nil { + devcontainerConfig = fmt.Sprintf("%s %s", "Devcontainer Config:", workspace.BuildConfig.Devcontainer.FilePath) } - newItem := projectRequestItem{name: name, image: image, user: user, project: project, devcontainerConfig: devcontainerConfig} + newItem := workspaceRequestItem{name: name, image: image, user: user, workspace: workspace, devcontainerConfig: devcontainerConfig} newItem.SetId(name) items = append(items, newItem) } - newItem := projectRequestItem{name: "Done configuring", image: "Return to summary view", user: "", project: DoneConfiguring} + newItem := workspaceRequestItem{name: "Done configuring", image: "Return to summary view", user: "", workspace: DoneConfiguring} items = append(items, newItem) l := views.GetStyledSelectList(items) - l.SetDelegate(projectRequestItemDelegate{}) + l.SetDelegate(workspaceRequestItemDelegate{}) - m := projectRequestModel{} + m := workspaceRequestModel{} m.list = l - m.list.Title = "Choose a Project To Configure" + m.list.Title = "Choose a Workspace To Configure" m.list.AdditionalShortHelpKeys = func() []key.Binding { return []key.Binding{ @@ -89,22 +89,22 @@ func selectProjectRequestPrompt(projects *[]apiclient.CreateProjectDTO, choiceCh os.Exit(1) } - if m, ok := p.(projectRequestModel); ok && m.choice != nil { + if m, ok := p.(workspaceRequestModel); ok && m.choice != nil { choiceChan <- m.choice } else { choiceChan <- nil } } -func GetProjectRequestFromPrompt(projects *[]apiclient.CreateProjectDTO) *apiclient.CreateProjectDTO { - choiceChan := make(chan *apiclient.CreateProjectDTO) +func GetWorkspaceRequestFromPrompt(workspaces *[]apiclient.CreateWorkspaceDTO) *apiclient.CreateWorkspaceDTO { + choiceChan := make(chan *apiclient.CreateWorkspaceDTO) - go selectProjectRequestPrompt(projects, choiceChan) + go selectWorkspaceRequestPrompt(workspaces, choiceChan) return <-choiceChan } -func (m projectRequestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m workspaceRequestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch keypress := msg.String(); keypress { @@ -112,9 +112,9 @@ func (m projectRequestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, tea.Quit case "enter": - i, ok := m.list.SelectedItem().(projectRequestItem) + i, ok := m.list.SelectedItem().(workspaceRequestItem) if ok { - m.choice = &i.project + m.choice = &i.workspace } return m, tea.Quit case "f10": @@ -131,8 +131,8 @@ func (m projectRequestModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd } -func (d projectRequestItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) { - i, _ := listItem.(projectRequestItem) +func (d workspaceRequestItemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) { + i, _ := listItem.(workspaceRequestItem) s := strings.Builder{} var isSelected = index == m.Index() @@ -153,7 +153,7 @@ func (d projectRequestItemDelegate) Render(w io.Writer, m list.Model, index int, } // Render to the terminal - if i.project.Name == DoneConfiguring.Name { + if i.workspace.Name == DoneConfiguring.Name { s.WriteRune('\n') s.WriteString(name) s.WriteRune('\n') @@ -177,13 +177,13 @@ func (d projectRequestItemDelegate) Render(w io.Writer, m list.Model, index int, fmt.Fprint(w, s.String()) } -func (d projectRequestItemDelegate) Height() int { +func (d workspaceRequestItemDelegate) Height() int { height := lipgloss.NewStyle().GetVerticalFrameSize() + 10 return height } -func (i projectRequestItem) Name() string { return i.name } -func (i projectRequestItem) Image() string { return i.image } -func (i projectRequestItem) User() string { return i.user } -func (i projectRequestItem) DevcontainerConfig() string { return i.devcontainerConfig } -func (i projectRequestItem) SetId(id string) { i.id = id } +func (i workspaceRequestItem) Name() string { return i.name } +func (i workspaceRequestItem) Image() string { return i.image } +func (i workspaceRequestItem) User() string { return i.user } +func (i workspaceRequestItem) DevcontainerConfig() string { return i.devcontainerConfig } +func (i workspaceRequestItem) SetId(id string) { i.id = id } diff --git a/pkg/views/util/build_choice.go b/pkg/views/util/build_choice.go index fc786196d6..ac18c7578b 100644 --- a/pkg/views/util/build_choice.go +++ b/pkg/views/util/build_choice.go @@ -18,25 +18,25 @@ const ( NONE BuildChoice = "none" ) -type ProjectConfigDefaults struct { +type WorkspaceConfigDefaults struct { BuildChoice BuildChoice Image *string ImageUser *string DevcontainerFilePath string } -func GetProjectBuildChoice(project apiclient.CreateProjectDTO, defaults *ProjectConfigDefaults) (BuildChoice, string) { - if project.BuildConfig == nil { - if project.Image != nil && project.User != nil && +func GetWorkspaceBuildChoice(workspace apiclient.CreateWorkspaceDTO, defaults *WorkspaceConfigDefaults) (BuildChoice, string) { + if workspace.BuildConfig == nil { + if workspace.Image != nil && workspace.User != nil && defaults.Image != nil && defaults.ImageUser != nil && - *project.Image == *defaults.Image && - *project.User == *defaults.ImageUser { + *workspace.Image == *defaults.Image && + *workspace.User == *defaults.ImageUser { return NONE, "None" } else { return CUSTOMIMAGE, "Custom Image" } } else { - if project.BuildConfig.Devcontainer != nil { + if workspace.BuildConfig.Devcontainer != nil { return DEVCONTAINER, "Devcontainer" } else { return AUTOMATIC, "Automatic" diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index e7affff1ff..a8707a5405 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -26,10 +26,10 @@ func NotifyEmptyTargetConfigList(tip bool) { } } -func NotifyEmptyProjectConfigList(tip bool) { - views.RenderInfoMessageBold("No project configs found") +func NotifyEmptyWorkspaceConfigList(tip bool) { + views.RenderInfoMessageBold("No workspace configs found") if tip { - views.RenderTip("Use 'daytona project-config add' to add a project config") + views.RenderTip("Use 'daytona workspace-config add' to add a workspace config") } } diff --git a/pkg/views/projectconfig/info/view.go b/pkg/views/workspaceconfig/info/view.go similarity index 63% rename from pkg/views/projectconfig/info/view.go rename to pkg/views/workspaceconfig/info/view.go index 84ffd20f37..34e76d7416 100644 --- a/pkg/views/projectconfig/info/view.go +++ b/pkg/views/workspaceconfig/info/view.go @@ -27,61 +27,61 @@ var propertyValueStyle = lipgloss.NewStyle(). var prebuildDetailStyle = propertyNameStyle -func Render(projectConfig *apiclient.ProjectConfig, apiServerConfig *apiclient.ServerConfig, forceUnstyled bool) { +func Render(workspaceConfig *apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig, forceUnstyled bool) { var output string output += "\n\n" - output += views.GetStyledMainTitle("Project Config Info") + "\n\n" + output += views.GetStyledMainTitle("Workspace Config Info") + "\n\n" - output += getInfoLine("Name", projectConfig.Name) + "\n" + output += getInfoLine("Name", workspaceConfig.Name) + "\n" - output += getInfoLine("Repository", projectConfig.RepositoryUrl) + "\n" + output += getInfoLine("Repository", workspaceConfig.RepositoryUrl) + "\n" gitProviderConfig := "/" - if projectConfig.GitProviderConfigId != nil { - gitProviderConfig = *projectConfig.GitProviderConfigId + if workspaceConfig.GitProviderConfigId != nil { + gitProviderConfig = *workspaceConfig.GitProviderConfigId } output += getInfoLine("Git Provider ID", gitProviderConfig) + "\n" - if projectConfig.Default { + if workspaceConfig.Default { output += getInfoLine("Default", "Yes") + "\n" } - if GetLabelFromBuild(projectConfig.BuildConfig) != "" { - projectDefaults := &views_util.ProjectConfigDefaults{ - Image: &apiServerConfig.DefaultProjectImage, - ImageUser: &apiServerConfig.DefaultProjectUser, + if GetLabelFromBuild(workspaceConfig.BuildConfig) != "" { + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, } - createProjectDto := apiclient.CreateProjectDTO{ - BuildConfig: projectConfig.BuildConfig, + createWorkspaceDto := apiclient.CreateWorkspaceDTO{ + BuildConfig: workspaceConfig.BuildConfig, } - _, buildChoice := views_util.GetProjectBuildChoice(createProjectDto, projectDefaults) + _, buildChoice := views_util.GetWorkspaceBuildChoice(createWorkspaceDto, workspaceDefaults) output += getInfoLine("Build", buildChoice) + "\n" } - if projectConfig.Image != "" { - output += getInfoLine("Image", projectConfig.Image) + "\n" + if workspaceConfig.Image != "" { + output += getInfoLine("Image", workspaceConfig.Image) + "\n" } - if projectConfig.User != "" { - output += getInfoLine("User", projectConfig.User) + "\n" + if workspaceConfig.User != "" { + output += getInfoLine("User", workspaceConfig.User) + "\n" } - if projectConfig.BuildConfig != nil && projectConfig.BuildConfig.Devcontainer != nil { - output += getInfoLine("Devcontainer path", projectConfig.BuildConfig.Devcontainer.FilePath) + "\n" + if workspaceConfig.BuildConfig != nil && workspaceConfig.BuildConfig.Devcontainer != nil { + output += getInfoLine("Devcontainer path", workspaceConfig.BuildConfig.Devcontainer.FilePath) + "\n" } - prebuildCount := len(projectConfig.Prebuilds) + prebuildCount := len(workspaceConfig.Prebuilds) if prebuildCount > 0 { if prebuildCount == 1 { - output += getInfoLine("Prebuild: ", getPrebuildLine(projectConfig.Prebuilds[0], nil)) + "\n" + output += getInfoLine("Prebuild: ", getPrebuildLine(workspaceConfig.Prebuilds[0], nil)) + "\n" } else { output += getInfoLine("Prebuilds: ", "") + "\n" - for i, prebuild := range projectConfig.Prebuilds { - if len(projectConfig.Prebuilds) != 1 { + for i, prebuild := range workspaceConfig.Prebuilds { + if len(workspaceConfig.Prebuilds) != 1 { output += getPrebuildLine(prebuild, util.Pointer(i+1)) + "\n" } else { output += getPrebuildLine(prebuild, nil) + "\n" diff --git a/pkg/views/workspaceconfig/list/view.go b/pkg/views/workspaceconfig/list/view.go new file mode 100644 index 0000000000..fd992b6fcc --- /dev/null +++ b/pkg/views/workspaceconfig/list/view.go @@ -0,0 +1,91 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package list + +import ( + "fmt" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" +) + +type rowData struct { + Name string + Repository string + Build string + Prebuilds string + IsDefault string +} + +func ListWorkspaceConfigs(workspaceConfigList []apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) { + if len(workspaceConfigList) == 0 { + views_util.NotifyEmptyWorkspaceConfigList(true) + return + } + + data := [][]string{} + + for _, wc := range workspaceConfigList { + data = append(data, getRowFromData(wc, apiServerConfig, specifyGitProviders)) + } + + table := views_util.GetTableView(data, []string{ + "Name", "Repository", "Build", "Prebuild rules", "Default", + }, nil, func() { + renderUnstyledList(workspaceConfigList, apiServerConfig) + }) + + fmt.Println(table) +} + +func renderUnstyledList(workspaceConfigList []apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig) { + for _, wc := range workspaceConfigList { + info.Render(&wc, apiServerConfig, true) + + if wc.Name != workspaceConfigList[len(workspaceConfigList)-1].Name { + fmt.Printf("\n%s\n\n", views.SeparatorString) + } + } +} + +func getRowFromData(workspaceConfig apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) []string { + var isDefault string + var data rowData + + data.Name = workspaceConfig.Name + views_util.AdditionalPropertyPadding + data.Repository = util.GetRepositorySlugFromUrl(workspaceConfig.RepositoryUrl, specifyGitProviders) + data.Prebuilds = "None" + + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, + } + + createWorkspaceDto := apiclient.CreateWorkspaceDTO{ + BuildConfig: workspaceConfig.BuildConfig, + } + + _, data.Build = views_util.GetWorkspaceBuildChoice(createWorkspaceDto, workspaceDefaults) + + if workspaceConfig.Default { + isDefault = views.ActiveStyle.Render("Yes") + } else { + isDefault = views.InactiveStyle.Render("/") + } + + if len(workspaceConfig.Prebuilds) > 0 { + data.Prebuilds = fmt.Sprintf("%d", len(workspaceConfig.Prebuilds)) + } + + return []string{ + views.NameStyle.Render(data.Name), + views.DefaultRowDataStyle.Render(data.Repository), + views.DefaultRowDataStyle.Render(data.Build), + views.DefaultRowDataStyle.Render(data.Prebuilds), + isDefault, + } +} From 940a09046bb04bb667d85fe74c686085dc8e9764 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 4 Nov 2024 08:26:25 +0000 Subject: [PATCH 04/76] refactor: detach workspace from target - replace target id with name in list cmd (#1307) - target logger and create command output update (#1306) - Workspaces are now their own model with their own API and Service BREAKING CHANGES: - provider interface changes - target model changes - SSH hostname changes - target is not part of the hostname Signed-off-by: Toma Puljak Signed-off-by: Luka Brecic --- .vscode/launch.json | 2 +- cmd/daytona/config/ssh_file.go | 56 +- docs/agent_mode/daytona.md | 34 + docs/agent_mode/daytona_agent.md | 25 + docs/agent_mode/daytona_agent_logs.md | 24 + docs/agent_mode/daytona_autocomplete.md | 18 + docs/agent_mode/daytona_docs.md | 18 + docs/agent_mode/daytona_expose.md | 18 + docs/agent_mode/daytona_forward.md | 18 + docs/agent_mode/daytona_info.md | 24 + docs/agent_mode/daytona_list.md | 25 + docs/agent_mode/daytona_logs.md | 25 + docs/agent_mode/daytona_restart.md | 18 + docs/agent_mode/daytona_start.md | 18 + docs/agent_mode/daytona_stop.md | 18 + docs/agent_mode/daytona_version.md | 18 + docs/daytona.md | 53 + docs/daytona_api-key.md | 17 + docs/daytona_api-key_generate.md | 18 + docs/daytona_api-key_list.md | 24 + docs/daytona_api-key_revoke.md | 24 + docs/daytona_autocomplete.md | 18 + docs/daytona_build.md | 19 + docs/daytona_build_delete.md | 26 + docs/daytona_build_info.md | 24 + docs/daytona_build_list.md | 24 + docs/daytona_build_logs.md | 24 + docs/daytona_build_run.md | 18 + docs/daytona_code.md | 25 + docs/daytona_config.md | 25 + docs/daytona_container-registry.md | 17 + docs/daytona_container-registry_delete.md | 18 + docs/daytona_container-registry_list.md | 24 + docs/daytona_container-registry_set.md | 26 + docs/daytona_create.md | 38 + docs/daytona_delete.md | 26 + docs/daytona_docs.md | 18 + docs/daytona_env.md | 16 + docs/daytona_env_list.md | 24 + docs/daytona_env_set.md | 18 + docs/daytona_forward.md | 24 + docs/daytona_git-providers.md | 18 + docs/daytona_git-providers_add.md | 18 + docs/daytona_git-providers_delete.md | 25 + docs/daytona_git-providers_list.md | 24 + docs/daytona_git-providers_update.md | 18 + docs/daytona_ide.md | 18 + docs/daytona_info.md | 24 + docs/daytona_list.md | 25 + docs/daytona_logs.md | 25 + docs/daytona_prebuild.md | 19 + docs/daytona_prebuild_add.md | 28 + docs/daytona_prebuild_delete.md | 24 + docs/daytona_prebuild_info.md | 24 + docs/daytona_prebuild_list.md | 24 + docs/daytona_prebuild_update.md | 28 + docs/daytona_profile.md | 19 + docs/daytona_profile_add.md | 26 + docs/daytona_profile_delete.md | 18 + docs/daytona_profile_edit.md | 26 + docs/daytona_profile_list.md | 24 + docs/daytona_provider.md | 18 + docs/daytona_provider_install.md | 24 + docs/daytona_provider_list.md | 24 + docs/daytona_provider_uninstall.md | 18 + docs/daytona_provider_update.md | 24 + docs/daytona_purge.md | 29 + docs/daytona_serve.md | 18 + docs/daytona_server.md | 30 + docs/daytona_server_config.md | 24 + docs/daytona_server_configure.md | 18 + docs/daytona_server_logs.md | 27 + docs/daytona_server_logs_list.md | 18 + docs/daytona_server_restart.md | 18 + docs/daytona_server_start.md | 18 + docs/daytona_server_stop.md | 18 + docs/daytona_ssh.md | 25 + docs/daytona_start.md | 26 + docs/daytona_target-config.md | 18 + docs/daytona_target-config_list.md | 24 + docs/daytona_target-config_remove.md | 24 + docs/daytona_target-config_set-default.md | 18 + docs/daytona_target-config_set.md | 18 + docs/daytona_target.md | 20 + docs/daytona_target_delete.md | 26 + docs/daytona_target_info.md | 24 + docs/daytona_target_list.md | 25 + docs/daytona_target_restart.md | 18 + docs/daytona_target_start.md | 25 + docs/daytona_target_stop.md | 24 + docs/daytona_telemetry.md | 16 + docs/daytona_telemetry_disable.md | 18 + docs/daytona_telemetry_enable.md | 18 + docs/daytona_use.md | 18 + docs/daytona_version.md | 18 + docs/daytona_whoami.md | 24 + docs/daytona_workspace-config.md | 20 + docs/daytona_workspace-config_add.md | 31 + docs/daytona_workspace-config_delete.md | 26 + docs/daytona_workspace-config_info.md | 24 + docs/daytona_workspace-config_list.md | 24 + docs/daytona_workspace-config_set-default.md | 18 + docs/daytona_workspace-config_update.md | 18 + hack/docs/agent_mode/daytona.yaml | 25 + hack/docs/agent_mode/daytona_agent.yaml | 14 + hack/docs/agent_mode/daytona_agent_logs.yaml | 14 + .../docs/agent_mode/daytona_autocomplete.yaml | 9 + hack/docs/agent_mode/daytona_docs.yaml | 9 + hack/docs/agent_mode/daytona_expose.yaml | 10 + hack/docs/agent_mode/daytona_forward.yaml | 9 + hack/docs/agent_mode/daytona_info.yaml | 13 + hack/docs/agent_mode/daytona_list.yaml | 17 + hack/docs/agent_mode/daytona_logs.yaml | 18 + hack/docs/agent_mode/daytona_restart.yaml | 9 + hack/docs/agent_mode/daytona_start.yaml | 9 + hack/docs/agent_mode/daytona_stop.yaml | 9 + hack/docs/agent_mode/daytona_version.yaml | 9 + hack/docs/daytona.yaml | 44 + hack/docs/daytona_api-key.yaml | 11 + hack/docs/daytona_api-key_generate.yaml | 9 + hack/docs/daytona_api-key_list.yaml | 13 + hack/docs/daytona_api-key_revoke.yaml | 14 + hack/docs/daytona_autocomplete.yaml | 9 + hack/docs/daytona_build.yaml | 13 + hack/docs/daytona_build_delete.yaml | 20 + hack/docs/daytona_build_info.yaml | 13 + hack/docs/daytona_build_list.yaml | 13 + hack/docs/daytona_build_logs.yaml | 14 + hack/docs/daytona_build_run.yaml | 9 + hack/docs/daytona_code.yaml | 18 + hack/docs/daytona_config.yaml | 17 + hack/docs/daytona_container-registry.yaml | 11 + .../daytona_container-registry_delete.yaml | 9 + .../docs/daytona_container-registry_list.yaml | 13 + hack/docs/daytona_container-registry_set.yaml | 19 + hack/docs/daytona_create.yaml | 57 + hack/docs/daytona_delete.yaml | 22 + hack/docs/daytona_docs.yaml | 9 + hack/docs/daytona_env.yaml | 11 + hack/docs/daytona_env_list.yaml | 13 + hack/docs/daytona_env_set.yaml | 9 + hack/docs/daytona_forward.yaml | 13 + hack/docs/daytona_git-providers.yaml | 12 + hack/docs/daytona_git-providers_add.yaml | 9 + hack/docs/daytona_git-providers_delete.yaml | 18 + hack/docs/daytona_git-providers_list.yaml | 13 + hack/docs/daytona_git-providers_update.yaml | 9 + hack/docs/daytona_ide.yaml | 9 + hack/docs/daytona_info.yaml | 13 + hack/docs/daytona_list.yaml | 17 + hack/docs/daytona_logs.yaml | 18 + hack/docs/daytona_prebuild.yaml | 13 + hack/docs/daytona_prebuild_add.yaml | 30 + hack/docs/daytona_prebuild_delete.yaml | 14 + hack/docs/daytona_prebuild_info.yaml | 13 + hack/docs/daytona_prebuild_list.yaml | 13 + hack/docs/daytona_prebuild_update.yaml | 30 + hack/docs/daytona_profile.yaml | 13 + hack/docs/daytona_profile_add.yaml | 19 + hack/docs/daytona_profile_delete.yaml | 9 + hack/docs/daytona_profile_edit.yaml | 19 + hack/docs/daytona_profile_list.yaml | 13 + hack/docs/daytona_provider.yaml | 12 + hack/docs/daytona_provider_install.yaml | 14 + hack/docs/daytona_provider_list.yaml | 13 + hack/docs/daytona_provider_uninstall.yaml | 9 + hack/docs/daytona_provider_update.yaml | 14 + hack/docs/daytona_purge.yaml | 20 + hack/docs/daytona_serve.yaml | 9 + hack/docs/daytona_server.yaml | 20 + hack/docs/daytona_server_config.yaml | 13 + hack/docs/daytona_server_configure.yaml | 9 + hack/docs/daytona_server_logs.yaml | 21 + hack/docs/daytona_server_logs_list.yaml | 9 + hack/docs/daytona_server_restart.yaml | 9 + hack/docs/daytona_server_start.yaml | 9 + hack/docs/daytona_server_stop.yaml | 9 + hack/docs/daytona_ssh.yaml | 18 + hack/docs/daytona_start.yaml | 22 + hack/docs/daytona_target-config.yaml | 12 + hack/docs/daytona_target-config_list.yaml | 13 + hack/docs/daytona_target-config_remove.yaml | 14 + .../daytona_target-config_set-default.yaml | 9 + hack/docs/daytona_target-config_set.yaml | 9 + hack/docs/daytona_target.yaml | 14 + hack/docs/daytona_target_delete.yaml | 22 + hack/docs/daytona_target_info.yaml | 13 + hack/docs/daytona_target_list.yaml | 17 + hack/docs/daytona_target_restart.yaml | 9 + hack/docs/daytona_target_start.yaml | 18 + hack/docs/daytona_target_stop.yaml | 14 + hack/docs/daytona_telemetry.yaml | 10 + hack/docs/daytona_telemetry_disable.yaml | 9 + hack/docs/daytona_telemetry_enable.yaml | 9 + hack/docs/daytona_use.yaml | 9 + hack/docs/daytona_version.yaml | 9 + hack/docs/daytona_whoami.yaml | 13 + hack/docs/daytona_workspace-config.yaml | 14 + hack/docs/daytona_workspace-config_add.yaml | 32 + .../docs/daytona_workspace-config_delete.yaml | 22 + hack/docs/daytona_workspace-config_info.yaml | 13 + hack/docs/daytona_workspace-config_list.yaml | 13 + .../daytona_workspace-config_set-default.yaml | 9 + .../docs/daytona_workspace-config_update.yaml | 9 + internal/cmd/tailscale/forward.go | 6 +- internal/testing/agent/mocks/apiserver.go | 10 +- internal/testing/docker/mocks/client.go | 2 +- internal/testing/git/mocks/gitservice.go | 2 +- .../testing/server/targets/mocks/builder.go | 4 +- .../server/targets/mocks/provisioner.go | 7 +- .../server/targets/mocks/workspace_config.go | 4 +- .../targets/mocks/workspace_config_service.go | 2 +- .../testing/server/workspaceconfig/store.go | 2 +- internal/testing/server/workspaces/store.go | 51 + internal/util/apiclient/api_client.go | 27 +- .../util/apiclient/conversion/workspace.go | 14 +- .../util/apiclient/websocket_log_reader.go | 75 +- internal/util/path.go | 16 +- pkg/agent/agent.go | 37 +- pkg/agent/agent_test.go | 16 +- pkg/agent/config/config.go | 18 +- pkg/agent/types.go | 2 + pkg/api/controllers/build/build.go | 2 +- pkg/api/controllers/log/websocket.go | 15 +- pkg/api/controllers/target/dto/dto.go | 2 +- pkg/api/controllers/target/start.go | 26 - pkg/api/controllers/target/stop.go | 26 - pkg/api/controllers/workspace/create.go | 43 + pkg/api/controllers/workspace/dto/dto.go | 11 + pkg/api/controllers/workspace/remove.go | 55 + pkg/api/controllers/workspace/start.go | 36 + .../workspace.go => workspace/state.go} | 14 +- pkg/api/controllers/workspace/stop.go | 36 + pkg/api/controllers/workspace/toolbox/fs.go | 55 +- pkg/api/controllers/workspace/toolbox/git.go | 43 +- pkg/api/controllers/workspace/toolbox/lsp.go | 25 +- .../controllers/workspace/toolbox/process.go | 5 +- .../controllers/workspace/toolbox/session.go | 15 +- .../controllers/workspace/toolbox/toolbox.go | 38 +- pkg/api/controllers/workspace/workspace.go | 86 ++ .../workspaceconfig/prebuild/prebuild.go | 2 +- .../workspaceconfig/workspace_config.go | 2 +- pkg/api/docs/docs.go | 749 ++++++------- pkg/api/docs/swagger.json | 749 ++++++------- pkg/api/docs/swagger.yaml | 580 +++++----- pkg/api/server.go | 31 +- pkg/apiclient/README.md | 81 +- pkg/apiclient/api/openapi.yaml | 996 +++++++----------- pkg/apiclient/api_target.go | 342 ------ pkg/apiclient/api_workspace.go | 847 +++++++++++++++ pkg/apiclient/api_workspace_toolbox.go | 316 ++---- pkg/apiclient/client.go | 3 + pkg/apiclient/docs/CreateTargetDTO.md | 23 +- pkg/apiclient/docs/CreateWorkspaceDTO.md | 44 +- pkg/apiclient/docs/Target.md | 23 +- pkg/apiclient/docs/TargetAPI.md | 220 +--- pkg/apiclient/docs/TargetDTO.md | 23 +- pkg/apiclient/docs/TargetInfo.md | 23 +- pkg/apiclient/docs/WorkspaceAPI.md | 495 +++++++++ pkg/apiclient/docs/WorkspaceDTO.md | 302 ++++++ pkg/apiclient/docs/WorkspaceToolboxAPI.md | 306 ++---- .../{Workspace.md => WorkspaceViewDTO.md} | 127 ++- pkg/apiclient/model_create_target_dto.go | 36 +- pkg/apiclient/model_create_workspace_dto.go | 58 +- pkg/apiclient/model_target.go | 36 +- pkg/apiclient/model_target_dto.go | 30 +- pkg/apiclient/model_target_info.go | 34 +- pkg/apiclient/model_workspace_dto.go | 496 +++++++++ ...rkspace.go => model_workspace_view_dto.go} | 180 ++-- pkg/build/build.go | 4 +- pkg/build/detect/detect.go | 2 +- pkg/build/store.go | 2 +- pkg/cmd/agent/agent.go | 41 +- pkg/cmd/agentmode/agent_mode.go | 6 +- pkg/cmd/agentmode/forward.go | 2 +- pkg/cmd/agentmode/git_cred.go | 15 +- pkg/cmd/agentmode/info.go | 2 +- pkg/cmd/agentmode/restart.go | 38 +- pkg/cmd/agentmode/start.go | 30 +- pkg/cmd/agentmode/stop.go | 38 +- pkg/cmd/build/delete.go | 2 +- pkg/cmd/build/info.go | 2 +- pkg/cmd/build/logs.go | 2 +- pkg/cmd/build/run.go | 6 +- pkg/cmd/cmd.go | 6 +- pkg/cmd/gitprovider/delete.go | 2 +- pkg/cmd/gitprovider/update.go | 2 +- pkg/cmd/logs.go | 143 ++- pkg/cmd/ports/forward.go | 47 +- pkg/cmd/prebuild/add.go | 6 +- pkg/cmd/prebuild/delete.go | 2 +- pkg/cmd/prebuild/info.go | 2 +- pkg/cmd/prebuild/update.go | 2 +- pkg/cmd/server/serve.go | 19 + pkg/cmd/target/code.go | 250 ----- pkg/cmd/target/delete.go | 24 +- pkg/cmd/target/info.go | 8 +- pkg/cmd/target/list.go | 20 +- pkg/cmd/target/restart.go | 45 +- pkg/cmd/target/start.go | 243 ++--- pkg/cmd/target/stop.go | 89 +- pkg/cmd/target/target.go | 25 + pkg/cmd/workspace/code.go | 183 ++++ pkg/cmd/{target => workspace}/create.go | 97 +- pkg/cmd/workspace/delete.go | 202 ++++ pkg/cmd/workspace/info.go | 82 ++ pkg/cmd/workspace/list.go | 74 ++ pkg/cmd/{target => workspace}/ssh-proxy.go | 37 +- pkg/cmd/{target => workspace}/ssh.go | 82 +- pkg/cmd/workspace/start.go | 246 +++++ .../util/add_from_config.go | 0 .../util/branch_wizard.go | 2 +- .../util/creation_data.go | 4 +- .../util/get_target_config.go | 0 .../util/repository_wizard.go | 4 +- pkg/cmd/{target => workspace}/util/target.go | 25 - pkg/cmd/workspaceconfig/add.go | 22 +- pkg/cmd/workspaceconfig/delete.go | 2 +- pkg/cmd/workspaceconfig/export.go | 2 +- pkg/cmd/workspaceconfig/import.go | 4 +- pkg/cmd/workspaceconfig/info.go | 2 +- pkg/cmd/workspaceconfig/setdefault.go | 2 +- pkg/cmd/workspaceconfig/update.go | 4 +- pkg/db/build_store.go | 2 +- pkg/db/dto/build.go | 2 +- pkg/db/dto/target.go | 29 +- pkg/db/dto/workspace.go | 20 +- pkg/db/dto/workspace_config.go | 2 +- pkg/db/workspace_config_store.go | 2 +- pkg/db/workspace_store.go | 74 ++ pkg/docker/client.go | 2 +- pkg/docker/client_test.go | 16 +- pkg/docker/create.go | 2 +- pkg/docker/create_devcontainer.go | 2 +- pkg/docker/create_image.go | 4 +- pkg/docker/destroy.go | 2 +- pkg/docker/info.go | 12 +- pkg/docker/start.go | 2 +- pkg/docker/stop.go | 2 +- pkg/git/service.go | 2 +- pkg/git/status.go | 2 +- pkg/ide/browser.go | 12 +- pkg/ide/cursor.go | 6 +- pkg/ide/fleet.go | 6 +- pkg/ide/jetbrains.go | 8 +- pkg/ide/jupyter.go | 16 +- pkg/ide/positron.go | 6 +- pkg/ide/terminal.go | 6 +- pkg/ide/vscode-insiders.go | 6 +- pkg/ide/vscode.go | 6 +- pkg/ide/vscodium-insiders.go | 6 +- pkg/ide/vscodium.go | 6 +- pkg/ide/windsurf.go | 6 +- pkg/ide/zed.go | 6 +- pkg/logs/logger.go | 12 +- pkg/logs/target.go | 24 +- pkg/logs/workspace.go | 15 +- pkg/provider/provider.go | 2 +- pkg/provider/rpc_client.go | 2 +- pkg/provider/rpc_server.go | 2 +- pkg/provider/types.go | 2 +- pkg/provisioner/destroy.go | 2 +- pkg/provisioner/info.go | 41 +- pkg/provisioner/provisioner.go | 3 +- pkg/provisioner/stop.go | 2 +- pkg/server/builds/dto/builds.go | 2 +- pkg/server/builds/service.go | 2 +- pkg/server/builds/service_test.go | 4 +- pkg/server/gitproviders/remove.go | 2 +- pkg/server/gitproviders/service.go | 2 +- pkg/server/server.go | 4 + pkg/server/targets/create.go | 226 +--- pkg/server/targets/dto/target.go | 29 +- pkg/server/targets/error.go | 9 +- pkg/server/targets/get.go | 4 +- pkg/server/targets/list.go | 4 +- pkg/server/targets/remove.go | 82 +- pkg/server/targets/service.go | 106 +- pkg/server/targets/service_test.go | 202 +--- pkg/server/targets/start.go | 136 +-- pkg/server/targets/stop.go | 56 +- .../workspaceconfig/dto/workspaceconfig.go | 2 +- pkg/server/workspaceconfig/prebuild.go | 4 +- pkg/server/workspaceconfig/prebuild_test.go | 2 +- pkg/server/workspaceconfig/service.go | 2 +- pkg/server/workspaceconfig/service_test.go | 2 +- pkg/server/workspaces/create.go | 229 ++++ pkg/server/workspaces/dto/workspace.go | 31 + pkg/server/workspaces/error.go | 15 + pkg/server/workspaces/get.go | 69 ++ pkg/server/workspaces/list.go | 80 ++ pkg/server/workspaces/remove.go | 117 ++ pkg/server/workspaces/service.go | 119 +++ pkg/server/workspaces/service_test.go | 353 +++++++ pkg/server/workspaces/start.go | 114 ++ pkg/server/workspaces/stop.go | 66 ++ pkg/target/target.go | 31 +- pkg/telemetry/server_events.go | 60 +- pkg/views/ide/start_target.go | 4 +- pkg/views/logs/display.go | 25 +- pkg/views/target/info/view.go | 155 +-- pkg/views/target/list/view.go | 151 +-- pkg/views/target/selection/target.go | 34 - pkg/views/target/selection/view.go | 21 +- pkg/views/util/empty_list.go | 7 + .../create/configuration.go | 2 +- .../{target => workspace}/create/summary.go | 0 .../{target => workspace}/create/view.go | 0 pkg/views/workspace/info/view.go | 184 ++++ pkg/views/workspace/list/view.go | 148 +++ .../{target => workspace}/selection/branch.go | 0 .../{target => workspace}/selection/build.go | 0 .../selection/checkout.go | 0 .../{target => workspace}/selection/common.go | 0 .../selection/gitprovider.go | 0 .../selection/gitproviderconfig.go | 0 .../selection/namespace.go | 0 .../selection/prebuild.go | 0 .../selection/pullrequest.go | 0 .../selection/repository.go | 0 .../{target => workspace}/selection/sample.go | 0 pkg/views/workspace/selection/view.go | 227 ++++ .../selection/workspace.go | 12 +- .../selection/workspaceconfig.go | 0 .../selection/workspacerequest.go | 0 .../workspace/buildconfig/config.go | 0 pkg/{target => }/workspace/config/config.go | 2 +- pkg/{target => }/workspace/config/prebuild.go | 0 pkg/{target => }/workspace/config/store.go | 0 .../workspace/containerconfig/config.go | 0 pkg/workspace/store.go | 26 + pkg/{target => }/workspace/workspace.go | 16 +- 432 files changed, 11721 insertions(+), 5788 deletions(-) create mode 100644 docs/agent_mode/daytona.md create mode 100644 docs/agent_mode/daytona_agent.md create mode 100644 docs/agent_mode/daytona_agent_logs.md create mode 100644 docs/agent_mode/daytona_autocomplete.md create mode 100644 docs/agent_mode/daytona_docs.md create mode 100644 docs/agent_mode/daytona_expose.md create mode 100644 docs/agent_mode/daytona_forward.md create mode 100644 docs/agent_mode/daytona_info.md create mode 100644 docs/agent_mode/daytona_list.md create mode 100644 docs/agent_mode/daytona_logs.md create mode 100644 docs/agent_mode/daytona_restart.md create mode 100644 docs/agent_mode/daytona_start.md create mode 100644 docs/agent_mode/daytona_stop.md create mode 100644 docs/agent_mode/daytona_version.md create mode 100644 docs/daytona.md create mode 100644 docs/daytona_api-key.md create mode 100644 docs/daytona_api-key_generate.md create mode 100644 docs/daytona_api-key_list.md create mode 100644 docs/daytona_api-key_revoke.md create mode 100644 docs/daytona_autocomplete.md create mode 100644 docs/daytona_build.md create mode 100644 docs/daytona_build_delete.md create mode 100644 docs/daytona_build_info.md create mode 100644 docs/daytona_build_list.md create mode 100644 docs/daytona_build_logs.md create mode 100644 docs/daytona_build_run.md create mode 100644 docs/daytona_code.md create mode 100644 docs/daytona_config.md create mode 100644 docs/daytona_container-registry.md create mode 100644 docs/daytona_container-registry_delete.md create mode 100644 docs/daytona_container-registry_list.md create mode 100644 docs/daytona_container-registry_set.md create mode 100644 docs/daytona_create.md create mode 100644 docs/daytona_delete.md create mode 100644 docs/daytona_docs.md create mode 100644 docs/daytona_env.md create mode 100644 docs/daytona_env_list.md create mode 100644 docs/daytona_env_set.md create mode 100644 docs/daytona_forward.md create mode 100644 docs/daytona_git-providers.md create mode 100644 docs/daytona_git-providers_add.md create mode 100644 docs/daytona_git-providers_delete.md create mode 100644 docs/daytona_git-providers_list.md create mode 100644 docs/daytona_git-providers_update.md create mode 100644 docs/daytona_ide.md create mode 100644 docs/daytona_info.md create mode 100644 docs/daytona_list.md create mode 100644 docs/daytona_logs.md create mode 100644 docs/daytona_prebuild.md create mode 100644 docs/daytona_prebuild_add.md create mode 100644 docs/daytona_prebuild_delete.md create mode 100644 docs/daytona_prebuild_info.md create mode 100644 docs/daytona_prebuild_list.md create mode 100644 docs/daytona_prebuild_update.md create mode 100644 docs/daytona_profile.md create mode 100644 docs/daytona_profile_add.md create mode 100644 docs/daytona_profile_delete.md create mode 100644 docs/daytona_profile_edit.md create mode 100644 docs/daytona_profile_list.md create mode 100644 docs/daytona_provider.md create mode 100644 docs/daytona_provider_install.md create mode 100644 docs/daytona_provider_list.md create mode 100644 docs/daytona_provider_uninstall.md create mode 100644 docs/daytona_provider_update.md create mode 100644 docs/daytona_purge.md create mode 100644 docs/daytona_serve.md create mode 100644 docs/daytona_server.md create mode 100644 docs/daytona_server_config.md create mode 100644 docs/daytona_server_configure.md create mode 100644 docs/daytona_server_logs.md create mode 100644 docs/daytona_server_logs_list.md create mode 100644 docs/daytona_server_restart.md create mode 100644 docs/daytona_server_start.md create mode 100644 docs/daytona_server_stop.md create mode 100644 docs/daytona_ssh.md create mode 100644 docs/daytona_start.md create mode 100644 docs/daytona_target-config.md create mode 100644 docs/daytona_target-config_list.md create mode 100644 docs/daytona_target-config_remove.md create mode 100644 docs/daytona_target-config_set-default.md create mode 100644 docs/daytona_target-config_set.md create mode 100644 docs/daytona_target.md create mode 100644 docs/daytona_target_delete.md create mode 100644 docs/daytona_target_info.md create mode 100644 docs/daytona_target_list.md create mode 100644 docs/daytona_target_restart.md create mode 100644 docs/daytona_target_start.md create mode 100644 docs/daytona_target_stop.md create mode 100644 docs/daytona_telemetry.md create mode 100644 docs/daytona_telemetry_disable.md create mode 100644 docs/daytona_telemetry_enable.md create mode 100644 docs/daytona_use.md create mode 100644 docs/daytona_version.md create mode 100644 docs/daytona_whoami.md create mode 100644 docs/daytona_workspace-config.md create mode 100644 docs/daytona_workspace-config_add.md create mode 100644 docs/daytona_workspace-config_delete.md create mode 100644 docs/daytona_workspace-config_info.md create mode 100644 docs/daytona_workspace-config_list.md create mode 100644 docs/daytona_workspace-config_set-default.md create mode 100644 docs/daytona_workspace-config_update.md create mode 100644 hack/docs/agent_mode/daytona.yaml create mode 100644 hack/docs/agent_mode/daytona_agent.yaml create mode 100644 hack/docs/agent_mode/daytona_agent_logs.yaml create mode 100644 hack/docs/agent_mode/daytona_autocomplete.yaml create mode 100644 hack/docs/agent_mode/daytona_docs.yaml create mode 100644 hack/docs/agent_mode/daytona_expose.yaml create mode 100644 hack/docs/agent_mode/daytona_forward.yaml create mode 100644 hack/docs/agent_mode/daytona_info.yaml create mode 100644 hack/docs/agent_mode/daytona_list.yaml create mode 100644 hack/docs/agent_mode/daytona_logs.yaml create mode 100644 hack/docs/agent_mode/daytona_restart.yaml create mode 100644 hack/docs/agent_mode/daytona_start.yaml create mode 100644 hack/docs/agent_mode/daytona_stop.yaml create mode 100644 hack/docs/agent_mode/daytona_version.yaml create mode 100644 hack/docs/daytona.yaml create mode 100644 hack/docs/daytona_api-key.yaml create mode 100644 hack/docs/daytona_api-key_generate.yaml create mode 100644 hack/docs/daytona_api-key_list.yaml create mode 100644 hack/docs/daytona_api-key_revoke.yaml create mode 100644 hack/docs/daytona_autocomplete.yaml create mode 100644 hack/docs/daytona_build.yaml create mode 100644 hack/docs/daytona_build_delete.yaml create mode 100644 hack/docs/daytona_build_info.yaml create mode 100644 hack/docs/daytona_build_list.yaml create mode 100644 hack/docs/daytona_build_logs.yaml create mode 100644 hack/docs/daytona_build_run.yaml create mode 100644 hack/docs/daytona_code.yaml create mode 100644 hack/docs/daytona_config.yaml create mode 100644 hack/docs/daytona_container-registry.yaml create mode 100644 hack/docs/daytona_container-registry_delete.yaml create mode 100644 hack/docs/daytona_container-registry_list.yaml create mode 100644 hack/docs/daytona_container-registry_set.yaml create mode 100644 hack/docs/daytona_create.yaml create mode 100644 hack/docs/daytona_delete.yaml create mode 100644 hack/docs/daytona_docs.yaml create mode 100644 hack/docs/daytona_env.yaml create mode 100644 hack/docs/daytona_env_list.yaml create mode 100644 hack/docs/daytona_env_set.yaml create mode 100644 hack/docs/daytona_forward.yaml create mode 100644 hack/docs/daytona_git-providers.yaml create mode 100644 hack/docs/daytona_git-providers_add.yaml create mode 100644 hack/docs/daytona_git-providers_delete.yaml create mode 100644 hack/docs/daytona_git-providers_list.yaml create mode 100644 hack/docs/daytona_git-providers_update.yaml create mode 100644 hack/docs/daytona_ide.yaml create mode 100644 hack/docs/daytona_info.yaml create mode 100644 hack/docs/daytona_list.yaml create mode 100644 hack/docs/daytona_logs.yaml create mode 100644 hack/docs/daytona_prebuild.yaml create mode 100644 hack/docs/daytona_prebuild_add.yaml create mode 100644 hack/docs/daytona_prebuild_delete.yaml create mode 100644 hack/docs/daytona_prebuild_info.yaml create mode 100644 hack/docs/daytona_prebuild_list.yaml create mode 100644 hack/docs/daytona_prebuild_update.yaml create mode 100644 hack/docs/daytona_profile.yaml create mode 100644 hack/docs/daytona_profile_add.yaml create mode 100644 hack/docs/daytona_profile_delete.yaml create mode 100644 hack/docs/daytona_profile_edit.yaml create mode 100644 hack/docs/daytona_profile_list.yaml create mode 100644 hack/docs/daytona_provider.yaml create mode 100644 hack/docs/daytona_provider_install.yaml create mode 100644 hack/docs/daytona_provider_list.yaml create mode 100644 hack/docs/daytona_provider_uninstall.yaml create mode 100644 hack/docs/daytona_provider_update.yaml create mode 100644 hack/docs/daytona_purge.yaml create mode 100644 hack/docs/daytona_serve.yaml create mode 100644 hack/docs/daytona_server.yaml create mode 100644 hack/docs/daytona_server_config.yaml create mode 100644 hack/docs/daytona_server_configure.yaml create mode 100644 hack/docs/daytona_server_logs.yaml create mode 100644 hack/docs/daytona_server_logs_list.yaml create mode 100644 hack/docs/daytona_server_restart.yaml create mode 100644 hack/docs/daytona_server_start.yaml create mode 100644 hack/docs/daytona_server_stop.yaml create mode 100644 hack/docs/daytona_ssh.yaml create mode 100644 hack/docs/daytona_start.yaml create mode 100644 hack/docs/daytona_target-config.yaml create mode 100644 hack/docs/daytona_target-config_list.yaml create mode 100644 hack/docs/daytona_target-config_remove.yaml create mode 100644 hack/docs/daytona_target-config_set-default.yaml create mode 100644 hack/docs/daytona_target-config_set.yaml create mode 100644 hack/docs/daytona_target.yaml create mode 100644 hack/docs/daytona_target_delete.yaml create mode 100644 hack/docs/daytona_target_info.yaml create mode 100644 hack/docs/daytona_target_list.yaml create mode 100644 hack/docs/daytona_target_restart.yaml create mode 100644 hack/docs/daytona_target_start.yaml create mode 100644 hack/docs/daytona_target_stop.yaml create mode 100644 hack/docs/daytona_telemetry.yaml create mode 100644 hack/docs/daytona_telemetry_disable.yaml create mode 100644 hack/docs/daytona_telemetry_enable.yaml create mode 100644 hack/docs/daytona_use.yaml create mode 100644 hack/docs/daytona_version.yaml create mode 100644 hack/docs/daytona_whoami.yaml create mode 100644 hack/docs/daytona_workspace-config.yaml create mode 100644 hack/docs/daytona_workspace-config_add.yaml create mode 100644 hack/docs/daytona_workspace-config_delete.yaml create mode 100644 hack/docs/daytona_workspace-config_info.yaml create mode 100644 hack/docs/daytona_workspace-config_list.yaml create mode 100644 hack/docs/daytona_workspace-config_set-default.yaml create mode 100644 hack/docs/daytona_workspace-config_update.yaml create mode 100644 internal/testing/server/workspaces/store.go create mode 100644 pkg/api/controllers/workspace/create.go create mode 100644 pkg/api/controllers/workspace/dto/dto.go create mode 100644 pkg/api/controllers/workspace/remove.go create mode 100644 pkg/api/controllers/workspace/start.go rename pkg/api/controllers/{target/workspace.go => workspace/state.go} (74%) create mode 100644 pkg/api/controllers/workspace/stop.go create mode 100644 pkg/api/controllers/workspace/workspace.go create mode 100644 pkg/apiclient/api_workspace.go create mode 100644 pkg/apiclient/docs/WorkspaceAPI.md create mode 100644 pkg/apiclient/docs/WorkspaceDTO.md rename pkg/apiclient/docs/{Workspace.md => WorkspaceViewDTO.md} (58%) create mode 100644 pkg/apiclient/model_workspace_dto.go rename pkg/apiclient/{model_workspace.go => model_workspace_view_dto.go} (62%) delete mode 100644 pkg/cmd/target/code.go create mode 100644 pkg/cmd/target/target.go create mode 100644 pkg/cmd/workspace/code.go rename pkg/cmd/{target => workspace}/create.go (83%) create mode 100644 pkg/cmd/workspace/delete.go create mode 100644 pkg/cmd/workspace/info.go create mode 100644 pkg/cmd/workspace/list.go rename pkg/cmd/{target => workspace}/ssh-proxy.go (77%) rename pkg/cmd/{target => workspace}/ssh.go (68%) create mode 100644 pkg/cmd/workspace/start.go rename pkg/cmd/{target => workspace}/util/add_from_config.go (100%) rename pkg/cmd/{target => workspace}/util/branch_wizard.go (99%) rename pkg/cmd/{target => workspace}/util/creation_data.go (98%) rename pkg/cmd/{target => workspace}/util/get_target_config.go (100%) rename pkg/cmd/{target => workspace}/util/repository_wizard.go (98%) rename pkg/cmd/{target => workspace}/util/target.go (78%) create mode 100644 pkg/db/workspace_store.go create mode 100644 pkg/server/workspaces/create.go create mode 100644 pkg/server/workspaces/dto/workspace.go create mode 100644 pkg/server/workspaces/error.go create mode 100644 pkg/server/workspaces/get.go create mode 100644 pkg/server/workspaces/list.go create mode 100644 pkg/server/workspaces/remove.go create mode 100644 pkg/server/workspaces/service.go create mode 100644 pkg/server/workspaces/service_test.go create mode 100644 pkg/server/workspaces/start.go create mode 100644 pkg/server/workspaces/stop.go rename pkg/views/{target => workspace}/create/configuration.go (99%) rename pkg/views/{target => workspace}/create/summary.go (100%) rename pkg/views/{target => workspace}/create/view.go (100%) create mode 100644 pkg/views/workspace/info/view.go create mode 100644 pkg/views/workspace/list/view.go rename pkg/views/{target => workspace}/selection/branch.go (100%) rename pkg/views/{target => workspace}/selection/build.go (100%) rename pkg/views/{target => workspace}/selection/checkout.go (100%) rename pkg/views/{target => workspace}/selection/common.go (100%) rename pkg/views/{target => workspace}/selection/gitprovider.go (100%) rename pkg/views/{target => workspace}/selection/gitproviderconfig.go (100%) rename pkg/views/{target => workspace}/selection/namespace.go (100%) rename pkg/views/{target => workspace}/selection/prebuild.go (100%) rename pkg/views/{target => workspace}/selection/pullrequest.go (100%) rename pkg/views/{target => workspace}/selection/repository.go (100%) rename pkg/views/{target => workspace}/selection/sample.go (100%) create mode 100644 pkg/views/workspace/selection/view.go rename pkg/views/{target => workspace}/selection/workspace.go (76%) rename pkg/views/{target => workspace}/selection/workspaceconfig.go (100%) rename pkg/views/{target => workspace}/selection/workspacerequest.go (100%) rename pkg/{target => }/workspace/buildconfig/config.go (100%) rename pkg/{target => }/workspace/config/config.go (97%) rename pkg/{target => }/workspace/config/prebuild.go (100%) rename pkg/{target => }/workspace/config/store.go (100%) rename pkg/{target => }/workspace/containerconfig/config.go (100%) create mode 100644 pkg/workspace/store.go rename pkg/{target => }/workspace/workspace.go (88%) diff --git a/.vscode/launch.json b/.vscode/launch.json index 286e4cbb39..db5687dc81 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,7 +13,7 @@ "console": "integratedTerminal", "env": { "DAYTONA_TARGET_ID": "TARGET_ID", - "DAYTONA_WORKSPACE_NAME": "WORKSPACE_NAME", + "DAYTONA_WORKSPACE_ID": "WORKSPACE_ID", "DAYTONA_SERVER_URL": "http://localhost:3986", "DAYTONA_SERVER_API_KEY": "1234567890", }, diff --git a/cmd/daytona/config/ssh_file.go b/cmd/daytona/config/ssh_file.go index 57f1a5c990..d10de0d2ac 100644 --- a/cmd/daytona/config/ssh_file.go +++ b/cmd/daytona/config/ssh_file.go @@ -114,21 +114,21 @@ func UnlinkSshFiles() error { // Add ssh entry -func generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsPath string, gpgForward bool) (string, error) { +func generateSshConfigEntry(profileId, workspaceName, knownHostsPath string, gpgForward bool) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } tab := "\t" - workspaceHostname := GetWorkspaceHostname(profileId, targetId, workspaceName) + workspaceHostname := GetWorkspaceHostname(profileId, workspaceName) config := fmt.Sprintf("Host %s\n"+ tab+"User daytona\n"+ tab+"StrictHostKeyChecking no\n"+ tab+"UserKnownHostsFile %s\n"+ - tab+"ProxyCommand \"%s\" ssh-proxy %s %s %s\n"+ - tab+"ForwardAgent yes\n", workspaceHostname, knownHostsPath, daytonaPath, profileId, targetId, workspaceName) + tab+"ProxyCommand \"%s\" ssh-proxy %s %s\n"+ + tab+"ForwardAgent yes\n", workspaceHostname, knownHostsPath, daytonaPath, profileId, workspaceName) if gpgForward { localSocket, err := getLocalGPGSocket() @@ -153,7 +153,7 @@ func generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsPath s return config, nil } -func EnsureSshConfigEntryAdded(profileId, targetName, workspaceName string, gpgKey string) error { +func EnsureSshConfigEntryAdded(profileId, workspaceId string, gpgKey string) error { err := ensureSshFilesLinked() if err != nil { return err @@ -171,10 +171,10 @@ func EnsureSshConfigEntryAdded(profileId, targetName, workspaceName string, gpgK } var configGenerated bool - regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, targetName, workspaceName)) - regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, targetName, workspaceName)) + regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, workspaceId)) + regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, workspaceId)) if !regexWithoutGPG.MatchString(existingContent) { - newContent, err := appendSshConfigEntry(configPath, profileId, targetName, workspaceName, knownHostsFile, false, existingContent) + newContent, err := appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile, false, existingContent) if err != nil { return err } @@ -183,12 +183,12 @@ func EnsureSshConfigEntryAdded(profileId, targetName, workspaceName string, gpgK } if gpgKey != "" && !regexWithGPG.MatchString(existingContent) { - _, err := appendSshConfigEntry(configPath, profileId, targetName, workspaceName, knownHostsFile, true, existingContent) + _, err := appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile, true, existingContent) if err != nil { return err } - workspaceHostname := GetWorkspaceHostname(profileId, targetName, workspaceName) + workspaceHostname := GetWorkspaceHostname(profileId, workspaceId) err = ExportGPGKey(gpgKey, workspaceHostname) if err != nil { return err @@ -198,11 +198,11 @@ func EnsureSshConfigEntryAdded(profileId, targetName, workspaceName string, gpgK } if !configGenerated { - updatedContent, err := regenerateProxyCommand(existingContent, profileId, targetName, workspaceName) + updatedContent, err := regenerateProxyCommand(existingContent, profileId, workspaceId) if err != nil { return err } - err = UpdateWorkspaceSshEntry(profileId, targetName, workspaceName, updatedContent) + err = UpdateWorkspaceSshEntry(profileId, workspaceId, updatedContent) if err != nil { return err } @@ -211,21 +211,21 @@ func EnsureSshConfigEntryAdded(profileId, targetName, workspaceName string, gpgK return nil } -func regenerateProxyCommand(existingContent, profileId, targetId, workspaceName string) (string, error) { +func regenerateProxyCommand(existingContent, profileId, workspaceId string) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } - hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, targetId, workspaceName)) + hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, workspaceId)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(existingContent) if matchedEntry == "" { - return "", fmt.Errorf("no SSH entry found for workspace %s", workspaceName) + return "", fmt.Errorf("no SSH entry found for workspace %s", workspaceId) } re := regexp.MustCompile(`(?m)^\s*ProxyCommand\s+.*$`) - updatedContent := re.ReplaceAllString(matchedEntry, fmt.Sprintf("\tProxyCommand \"%s\" ssh-proxy %s %s %s", daytonaPath, profileId, targetId, workspaceName)) + updatedContent := re.ReplaceAllString(matchedEntry, fmt.Sprintf("\tProxyCommand \"%s\" ssh-proxy %s %s", daytonaPath, profileId, workspaceId)) return updatedContent, nil } @@ -237,8 +237,8 @@ func getKnownHostsFile() string { return "/dev/null" } -func appendSshConfigEntry(configPath, profileId, targetId, workspaceName, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { - data, err := generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsFile, gpgForward) +func appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { + data, err := generateSshConfigEntry(profileId, workspaceId, knownHostsFile, gpgForward) if err != nil { return "", err } @@ -249,7 +249,7 @@ func appendSshConfigEntry(configPath, profileId, targetId, workspaceName, knownH } // We want to remove the config entry gpg counterpart - configCounterpart, err := generateSshConfigEntry(profileId, targetId, workspaceName, knownHostsFile, !gpgForward) + configCounterpart, err := generateSshConfigEntry(profileId, workspaceId, knownHostsFile, !gpgForward) if err != nil { return "", err } @@ -328,8 +328,8 @@ func writeSshConfig(configPath, newContent string) error { return nil } -// RemoveTargetSshEntries removes all SSH entries for a given profileId and targetId -func RemoveTargetSshEntries(profileId, targetId string) error { +// RemoveTargetSshEntries removes all SSH entries for a given profileId and workspaceId +func RemoveWorkspaceSshEntries(profileId, workspaceId string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -339,7 +339,9 @@ func RemoveTargetSshEntries(profileId, targetId string) error { return err } - regex := regexp.MustCompile(fmt.Sprintf(`Host %s-%s-\w+\s*\n(?:\t.*\n?)*`, profileId, targetId)) + // Define the regex pattern to match Host entries for the given profileId and workspaceId + regex := regexp.MustCompile(fmt.Sprintf(`Host %s-%s\n(?:\t.*\n?)*`, profileId, workspaceId)) + contentToDelete := regex.FindString(existingContent) if contentToDelete == "" { return nil @@ -352,7 +354,7 @@ func RemoveTargetSshEntries(profileId, targetId string) error { return writeSshConfig(configPath, newContent) } -func UpdateWorkspaceSshEntry(profileId, targetId, workspaceName, updatedContent string) error { +func UpdateWorkspaceSshEntry(profileId, workspaceId, updatedContent string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -361,11 +363,11 @@ func UpdateWorkspaceSshEntry(profileId, targetId, workspaceName, updatedContent return err } - hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, targetId, workspaceName)) + hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, workspaceId)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) oldContent := regex.FindString(existingContent) if oldContent == "" { - return fmt.Errorf("no SSH entry found for workspace %s", workspaceName) + return fmt.Errorf("no SSH entry found for workspace %s", workspaceId) } existingContent = strings.ReplaceAll(existingContent, oldContent, updatedContent) @@ -377,8 +379,8 @@ func UpdateWorkspaceSshEntry(profileId, targetId, workspaceName, updatedContent return nil } -func GetWorkspaceHostname(profileId, targetId, workspaceName string) string { - return fmt.Sprintf("%s-%s-%s", profileId, targetId, workspaceName) +func GetWorkspaceHostname(profileId, workspaceName string) string { + return fmt.Sprintf("%s-%s", profileId, workspaceName) } func init() { diff --git a/docs/agent_mode/daytona.md b/docs/agent_mode/daytona.md new file mode 100644 index 0000000000..e6bc63f1ca --- /dev/null +++ b/docs/agent_mode/daytona.md @@ -0,0 +1,34 @@ +## daytona + +Daytona is a Dev Environment Manager + +### Synopsis + +Daytona is a Dev Environment Manager + +``` +daytona [flags] +``` + +### Options + +``` + --help help for daytona + -v, --version Display the version of Daytona +``` + +### SEE ALSO + +* [daytona agent](daytona_agent.md) - Start the agent process +* [daytona autocomplete](daytona_autocomplete.md) - Adds a completion script for your shell environment +* [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. +* [daytona expose](daytona_expose.md) - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace +* [daytona forward](daytona_forward.md) - Forward a port publicly via an URL +* [daytona info](daytona_info.md) - Show workspace info +* [daytona list](daytona_list.md) - List targets +* [daytona logs](daytona_logs.md) - View logs for a target/workspace +* [daytona restart](daytona_restart.md) - Restart the workspace +* [daytona start](daytona_start.md) - Start the workspace +* [daytona stop](daytona_stop.md) - Stop the workspace +* [daytona version](daytona_version.md) - Print the version number + diff --git a/docs/agent_mode/daytona_agent.md b/docs/agent_mode/daytona_agent.md new file mode 100644 index 0000000000..7c19d6cdae --- /dev/null +++ b/docs/agent_mode/daytona_agent.md @@ -0,0 +1,25 @@ +## daytona agent + +Start the agent process + +``` +daytona agent [flags] +``` + +### Options + +``` + --host Run the agent in host mode +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona agent logs](daytona_agent_logs.md) - Output Daytona Agent logs + diff --git a/docs/agent_mode/daytona_agent_logs.md b/docs/agent_mode/daytona_agent_logs.md new file mode 100644 index 0000000000..b0947b016c --- /dev/null +++ b/docs/agent_mode/daytona_agent_logs.md @@ -0,0 +1,24 @@ +## daytona agent logs + +Output Daytona Agent logs + +``` +daytona agent logs [flags] +``` + +### Options + +``` + -f, --follow Follow logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona agent](daytona_agent.md) - Start the agent process + diff --git a/docs/agent_mode/daytona_autocomplete.md b/docs/agent_mode/daytona_autocomplete.md new file mode 100644 index 0000000000..2a2d749125 --- /dev/null +++ b/docs/agent_mode/daytona_autocomplete.md @@ -0,0 +1,18 @@ +## daytona autocomplete + +Adds a completion script for your shell environment + +``` +daytona autocomplete [bash|zsh|fish|powershell] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_docs.md b/docs/agent_mode/daytona_docs.md new file mode 100644 index 0000000000..612505ce71 --- /dev/null +++ b/docs/agent_mode/daytona_docs.md @@ -0,0 +1,18 @@ +## daytona docs + +Opens the Daytona documentation in your default browser. + +``` +daytona docs [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_expose.md b/docs/agent_mode/daytona_expose.md new file mode 100644 index 0000000000..10710ddb16 --- /dev/null +++ b/docs/agent_mode/daytona_expose.md @@ -0,0 +1,18 @@ +## daytona expose + +Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace + +``` +daytona expose [PORT] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_forward.md b/docs/agent_mode/daytona_forward.md new file mode 100644 index 0000000000..926b4ae0d3 --- /dev/null +++ b/docs/agent_mode/daytona_forward.md @@ -0,0 +1,18 @@ +## daytona forward + +Forward a port publicly via an URL + +``` +daytona forward [PORT] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_info.md b/docs/agent_mode/daytona_info.md new file mode 100644 index 0000000000..6b2340360f --- /dev/null +++ b/docs/agent_mode/daytona_info.md @@ -0,0 +1,24 @@ +## daytona info + +Show workspace info + +``` +daytona info [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_list.md b/docs/agent_mode/daytona_list.md new file mode 100644 index 0000000000..9bf836328a --- /dev/null +++ b/docs/agent_mode/daytona_list.md @@ -0,0 +1,25 @@ +## daytona list + +List targets + +``` +daytona list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) + -v, --verbose Show verbose output +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_logs.md b/docs/agent_mode/daytona_logs.md new file mode 100644 index 0000000000..d29fc8990a --- /dev/null +++ b/docs/agent_mode/daytona_logs.md @@ -0,0 +1,25 @@ +## daytona logs + +View logs for a target/workspace + +``` +daytona logs [TARGET] [WORKSPACE_NAME] [flags] +``` + +### Options + +``` + -f, --follow Follow logs + -w, --target View target logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_restart.md b/docs/agent_mode/daytona_restart.md new file mode 100644 index 0000000000..4953c7e673 --- /dev/null +++ b/docs/agent_mode/daytona_restart.md @@ -0,0 +1,18 @@ +## daytona restart + +Restart the workspace + +``` +daytona restart [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_start.md b/docs/agent_mode/daytona_start.md new file mode 100644 index 0000000000..3baa6d8938 --- /dev/null +++ b/docs/agent_mode/daytona_start.md @@ -0,0 +1,18 @@ +## daytona start + +Start the workspace + +``` +daytona start [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_stop.md b/docs/agent_mode/daytona_stop.md new file mode 100644 index 0000000000..7631814021 --- /dev/null +++ b/docs/agent_mode/daytona_stop.md @@ -0,0 +1,18 @@ +## daytona stop + +Stop the workspace + +``` +daytona stop [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/agent_mode/daytona_version.md b/docs/agent_mode/daytona_version.md new file mode 100644 index 0000000000..2f0f9fb6a6 --- /dev/null +++ b/docs/agent_mode/daytona_version.md @@ -0,0 +1,18 @@ +## daytona version + +Print the version number + +``` +daytona version [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona.md b/docs/daytona.md new file mode 100644 index 0000000000..5ca9b7228f --- /dev/null +++ b/docs/daytona.md @@ -0,0 +1,53 @@ +## daytona + +Daytona is a Dev Environment Manager + +### Synopsis + +Daytona is a Dev Environment Manager + +``` +daytona [flags] +``` + +### Options + +``` + --help help for daytona + -v, --version Display the version of Daytona +``` + +### SEE ALSO + +* [daytona api-key](daytona_api-key.md) - Api Key commands +* [daytona autocomplete](daytona_autocomplete.md) - Adds a completion script for your shell environment +* [daytona build](daytona_build.md) - Manage builds +* [daytona code](daytona_code.md) - Open a workspace in your preferred IDE +* [daytona config](daytona_config.md) - Output Daytona configuration +* [daytona container-registry](daytona_container-registry.md) - Manage container registries +* [daytona create](daytona_create.md) - Create a target +* [daytona delete](daytona_delete.md) - Delete a workspace +* [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. +* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces +* [daytona forward](daytona_forward.md) - Forward a port from a workspace to your local machine +* [daytona git-providers](daytona_git-providers.md) - Manage Git providers +* [daytona ide](daytona_ide.md) - Choose the default IDE +* [daytona info](daytona_info.md) - Show target info +* [daytona list](daytona_list.md) - List targets +* [daytona logs](daytona_logs.md) - View logs for a target/workspace +* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds +* [daytona profile](daytona_profile.md) - Manage profiles +* [daytona provider](daytona_provider.md) - Manage providers +* [daytona purge](daytona_purge.md) - Purges all Daytona data from the current device +* [daytona serve](daytona_serve.md) - Run the server process in the current terminal session +* [daytona server](daytona_server.md) - Start the server process in daemon mode +* [daytona ssh](daytona_ssh.md) - SSH into a workspace using the terminal +* [daytona start](daytona_start.md) - Start a workspace +* [daytona target](daytona_target.md) - Manage targets +* [daytona target-config](daytona_target-config.md) - Manage target configs +* [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection +* [daytona use](daytona_use.md) - Use profile [PROFILE_NAME] +* [daytona version](daytona_version.md) - Print the version number +* [daytona whoami](daytona_whoami.md) - Display information about the active user +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/docs/daytona_api-key.md b/docs/daytona_api-key.md new file mode 100644 index 0000000000..11ac2ece14 --- /dev/null +++ b/docs/daytona_api-key.md @@ -0,0 +1,17 @@ +## daytona api-key + +Api Key commands + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona api-key generate](daytona_api-key_generate.md) - Generate a new API key +* [daytona api-key list](daytona_api-key_list.md) - List API keys +* [daytona api-key revoke](daytona_api-key_revoke.md) - Revoke an API key + diff --git a/docs/daytona_api-key_generate.md b/docs/daytona_api-key_generate.md new file mode 100644 index 0000000000..66d7b563d4 --- /dev/null +++ b/docs/daytona_api-key_generate.md @@ -0,0 +1,18 @@ +## daytona api-key generate + +Generate a new API key + +``` +daytona api-key generate [NAME] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona api-key](daytona_api-key.md) - Api Key commands + diff --git a/docs/daytona_api-key_list.md b/docs/daytona_api-key_list.md new file mode 100644 index 0000000000..f83d10fa1d --- /dev/null +++ b/docs/daytona_api-key_list.md @@ -0,0 +1,24 @@ +## daytona api-key list + +List API keys + +``` +daytona api-key list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona api-key](daytona_api-key.md) - Api Key commands + diff --git a/docs/daytona_api-key_revoke.md b/docs/daytona_api-key_revoke.md new file mode 100644 index 0000000000..90366c5c1b --- /dev/null +++ b/docs/daytona_api-key_revoke.md @@ -0,0 +1,24 @@ +## daytona api-key revoke + +Revoke an API key + +``` +daytona api-key revoke [NAME] [flags] +``` + +### Options + +``` + -y, --yes Skip confirmation prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona api-key](daytona_api-key.md) - Api Key commands + diff --git a/docs/daytona_autocomplete.md b/docs/daytona_autocomplete.md new file mode 100644 index 0000000000..2a2d749125 --- /dev/null +++ b/docs/daytona_autocomplete.md @@ -0,0 +1,18 @@ +## daytona autocomplete + +Adds a completion script for your shell environment + +``` +daytona autocomplete [bash|zsh|fish|powershell] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_build.md b/docs/daytona_build.md new file mode 100644 index 0000000000..498d794854 --- /dev/null +++ b/docs/daytona_build.md @@ -0,0 +1,19 @@ +## daytona build + +Manage builds + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona build delete](daytona_build_delete.md) - Delete a build +* [daytona build info](daytona_build_info.md) - Show build info +* [daytona build list](daytona_build_list.md) - List all builds +* [daytona build logs](daytona_build_logs.md) - View logs for build +* [daytona build run](daytona_build_run.md) - Run a build from a workspace config + diff --git a/docs/daytona_build_delete.md b/docs/daytona_build_delete.md new file mode 100644 index 0000000000..7e8710a650 --- /dev/null +++ b/docs/daytona_build_delete.md @@ -0,0 +1,26 @@ +## daytona build delete + +Delete a build + +``` +daytona build delete [BUILD] [flags] +``` + +### Options + +``` + -a, --all Delete ALL builds + -f, --force Force delete build + --prebuild-id string Delete ALL builds from prebuild +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona build](daytona_build.md) - Manage builds + diff --git a/docs/daytona_build_info.md b/docs/daytona_build_info.md new file mode 100644 index 0000000000..4f287ead34 --- /dev/null +++ b/docs/daytona_build_info.md @@ -0,0 +1,24 @@ +## daytona build info + +Show build info + +``` +daytona build info [BUILD] [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona build](daytona_build.md) - Manage builds + diff --git a/docs/daytona_build_list.md b/docs/daytona_build_list.md new file mode 100644 index 0000000000..8f338d5618 --- /dev/null +++ b/docs/daytona_build_list.md @@ -0,0 +1,24 @@ +## daytona build list + +List all builds + +``` +daytona build list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona build](daytona_build.md) - Manage builds + diff --git a/docs/daytona_build_logs.md b/docs/daytona_build_logs.md new file mode 100644 index 0000000000..3ac0187e57 --- /dev/null +++ b/docs/daytona_build_logs.md @@ -0,0 +1,24 @@ +## daytona build logs + +View logs for build + +``` +daytona build logs [flags] +``` + +### Options + +``` + -f, --follow Follow logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona build](daytona_build.md) - Manage builds + diff --git a/docs/daytona_build_run.md b/docs/daytona_build_run.md new file mode 100644 index 0000000000..8d7f3ab13a --- /dev/null +++ b/docs/daytona_build_run.md @@ -0,0 +1,18 @@ +## daytona build run + +Run a build from a workspace config + +``` +daytona build run [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona build](daytona_build.md) - Manage builds + diff --git a/docs/daytona_code.md b/docs/daytona_code.md new file mode 100644 index 0000000000..2f3bb7273f --- /dev/null +++ b/docs/daytona_code.md @@ -0,0 +1,25 @@ +## daytona code + +Open a workspace in your preferred IDE + +``` +daytona code [WORKSPACE] [flags] +``` + +### Options + +``` + -i, --ide string Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_config.md b/docs/daytona_config.md new file mode 100644 index 0000000000..1adb37b7f0 --- /dev/null +++ b/docs/daytona_config.md @@ -0,0 +1,25 @@ +## daytona config + +Output Daytona configuration + +``` +daytona config [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) + -k, --show-api-keys Show API keys +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_container-registry.md b/docs/daytona_container-registry.md new file mode 100644 index 0000000000..f101ccfbd7 --- /dev/null +++ b/docs/daytona_container-registry.md @@ -0,0 +1,17 @@ +## daytona container-registry + +Manage container registries + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona container-registry delete](daytona_container-registry_delete.md) - Delete a container registry +* [daytona container-registry list](daytona_container-registry_list.md) - Lists container registries +* [daytona container-registry set](daytona_container-registry_set.md) - Set container registry + diff --git a/docs/daytona_container-registry_delete.md b/docs/daytona_container-registry_delete.md new file mode 100644 index 0000000000..bbf017d9f9 --- /dev/null +++ b/docs/daytona_container-registry_delete.md @@ -0,0 +1,18 @@ +## daytona container-registry delete + +Delete a container registry + +``` +daytona container-registry delete [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona container-registry](daytona_container-registry.md) - Manage container registries + diff --git a/docs/daytona_container-registry_list.md b/docs/daytona_container-registry_list.md new file mode 100644 index 0000000000..ca07652b86 --- /dev/null +++ b/docs/daytona_container-registry_list.md @@ -0,0 +1,24 @@ +## daytona container-registry list + +Lists container registries + +``` +daytona container-registry list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona container-registry](daytona_container-registry.md) - Manage container registries + diff --git a/docs/daytona_container-registry_set.md b/docs/daytona_container-registry_set.md new file mode 100644 index 0000000000..dd3ed61d0c --- /dev/null +++ b/docs/daytona_container-registry_set.md @@ -0,0 +1,26 @@ +## daytona container-registry set + +Set container registry + +``` +daytona container-registry set [flags] +``` + +### Options + +``` + -p, --password string Password + -s, --server string Server + -u, --username string Username +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona container-registry](daytona_container-registry.md) - Manage container registries + diff --git a/docs/daytona_create.md b/docs/daytona_create.md new file mode 100644 index 0000000000..0618c04375 --- /dev/null +++ b/docs/daytona_create.md @@ -0,0 +1,38 @@ +## daytona create + +Create a target + +``` +daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] +``` + +### Options + +``` + --blank Create a blank workspace without using existing configurations + --branch strings Specify the Git branches to use in the workspaces + --builder BuildChoice Specify the builder (currently auto/devcontainer/none) + --custom-image string Create the workspace with the custom image passed as the flag value; Requires setting --custom-image-user flag as well + --custom-image-user string Create the workspace with the custom image user passed as the flag value; Requires setting --custom-image flag as well + --devcontainer-path string Automatically assign the devcontainer builder with the path passed as the flag value + --env stringArray Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') + --git-provider-config string Specify the Git provider configuration ID or alias + -i, --ide string Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + --manual Manually enter the Git repository + --multi-workspace Target with multiple workspaces/repos + --name string Specify the target name + -n, --no-ide Do not open the target in the IDE after target creation + -t, --target string Specify the target (e.g. 'local') + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_delete.md b/docs/daytona_delete.md new file mode 100644 index 0000000000..33e0cdfb89 --- /dev/null +++ b/docs/daytona_delete.md @@ -0,0 +1,26 @@ +## daytona delete + +Delete a workspace + +``` +daytona delete [WORKSPACE] [flags] +``` + +### Options + +``` + -a, --all Delete all workspaces + -f, --force Delete a workspace by force + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_docs.md b/docs/daytona_docs.md new file mode 100644 index 0000000000..612505ce71 --- /dev/null +++ b/docs/daytona_docs.md @@ -0,0 +1,18 @@ +## daytona docs + +Opens the Daytona documentation in your default browser. + +``` +daytona docs [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_env.md b/docs/daytona_env.md new file mode 100644 index 0000000000..575d1bb82b --- /dev/null +++ b/docs/daytona_env.md @@ -0,0 +1,16 @@ +## daytona env + +Manage profile environment variables that are added to all targets and workspaces + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona env list](daytona_env_list.md) - List profile environment variables +* [daytona env set](daytona_env_set.md) - Set profile environment variables + diff --git a/docs/daytona_env_list.md b/docs/daytona_env_list.md new file mode 100644 index 0000000000..f0691768b5 --- /dev/null +++ b/docs/daytona_env_list.md @@ -0,0 +1,24 @@ +## daytona env list + +List profile environment variables + +``` +daytona env list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces + diff --git a/docs/daytona_env_set.md b/docs/daytona_env_set.md new file mode 100644 index 0000000000..8016ad9d39 --- /dev/null +++ b/docs/daytona_env_set.md @@ -0,0 +1,18 @@ +## daytona env set + +Set profile environment variables + +``` +daytona env set [KEY=VALUE]... [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces + diff --git a/docs/daytona_forward.md b/docs/daytona_forward.md new file mode 100644 index 0000000000..f07282c793 --- /dev/null +++ b/docs/daytona_forward.md @@ -0,0 +1,24 @@ +## daytona forward + +Forward a port from a workspace to your local machine + +``` +daytona forward [PORT] [WORKSPACE] [flags] +``` + +### Options + +``` + --public Should be port be available publicly via an URL +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_git-providers.md b/docs/daytona_git-providers.md new file mode 100644 index 0000000000..702fdac3a3 --- /dev/null +++ b/docs/daytona_git-providers.md @@ -0,0 +1,18 @@ +## daytona git-providers + +Manage Git providers + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona git-providers add](daytona_git-providers_add.md) - Register a Git provider +* [daytona git-providers delete](daytona_git-providers_delete.md) - Unregister a Git provider +* [daytona git-providers list](daytona_git-providers_list.md) - Lists your registered Git providers +* [daytona git-providers update](daytona_git-providers_update.md) - Update a Git provider + diff --git a/docs/daytona_git-providers_add.md b/docs/daytona_git-providers_add.md new file mode 100644 index 0000000000..d7b20b69cb --- /dev/null +++ b/docs/daytona_git-providers_add.md @@ -0,0 +1,18 @@ +## daytona git-providers add + +Register a Git provider + +``` +daytona git-providers add [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-providers](daytona_git-providers.md) - Manage Git providers + diff --git a/docs/daytona_git-providers_delete.md b/docs/daytona_git-providers_delete.md new file mode 100644 index 0000000000..ab7a22aa23 --- /dev/null +++ b/docs/daytona_git-providers_delete.md @@ -0,0 +1,25 @@ +## daytona git-providers delete + +Unregister a Git provider + +``` +daytona git-providers delete [flags] +``` + +### Options + +``` + -a, --all Remove all Git providers + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-providers](daytona_git-providers.md) - Manage Git providers + diff --git a/docs/daytona_git-providers_list.md b/docs/daytona_git-providers_list.md new file mode 100644 index 0000000000..a99673badb --- /dev/null +++ b/docs/daytona_git-providers_list.md @@ -0,0 +1,24 @@ +## daytona git-providers list + +Lists your registered Git providers + +``` +daytona git-providers list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-providers](daytona_git-providers.md) - Manage Git providers + diff --git a/docs/daytona_git-providers_update.md b/docs/daytona_git-providers_update.md new file mode 100644 index 0000000000..164f00de24 --- /dev/null +++ b/docs/daytona_git-providers_update.md @@ -0,0 +1,18 @@ +## daytona git-providers update + +Update a Git provider + +``` +daytona git-providers update [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-providers](daytona_git-providers.md) - Manage Git providers + diff --git a/docs/daytona_ide.md b/docs/daytona_ide.md new file mode 100644 index 0000000000..3674d95883 --- /dev/null +++ b/docs/daytona_ide.md @@ -0,0 +1,18 @@ +## daytona ide + +Choose the default IDE + +``` +daytona ide [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_info.md b/docs/daytona_info.md new file mode 100644 index 0000000000..8ae541bb98 --- /dev/null +++ b/docs/daytona_info.md @@ -0,0 +1,24 @@ +## daytona info + +Show target info + +``` +daytona info [TARGET] [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_list.md b/docs/daytona_list.md new file mode 100644 index 0000000000..9bf836328a --- /dev/null +++ b/docs/daytona_list.md @@ -0,0 +1,25 @@ +## daytona list + +List targets + +``` +daytona list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) + -v, --verbose Show verbose output +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_logs.md b/docs/daytona_logs.md new file mode 100644 index 0000000000..d29fc8990a --- /dev/null +++ b/docs/daytona_logs.md @@ -0,0 +1,25 @@ +## daytona logs + +View logs for a target/workspace + +``` +daytona logs [TARGET] [WORKSPACE_NAME] [flags] +``` + +### Options + +``` + -f, --follow Follow logs + -w, --target View target logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_prebuild.md b/docs/daytona_prebuild.md new file mode 100644 index 0000000000..8fbe49c684 --- /dev/null +++ b/docs/daytona_prebuild.md @@ -0,0 +1,19 @@ +## daytona prebuild + +Manage prebuilds + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona prebuild add](daytona_prebuild_add.md) - Add a prebuild configuration +* [daytona prebuild delete](daytona_prebuild_delete.md) - Delete a prebuild configuration +* [daytona prebuild info](daytona_prebuild_info.md) - Show prebuild configuration info +* [daytona prebuild list](daytona_prebuild_list.md) - List prebuild configurations +* [daytona prebuild update](daytona_prebuild_update.md) - Update a prebuild configuration + diff --git a/docs/daytona_prebuild_add.md b/docs/daytona_prebuild_add.md new file mode 100644 index 0000000000..736d45f192 --- /dev/null +++ b/docs/daytona_prebuild_add.md @@ -0,0 +1,28 @@ +## daytona prebuild add + +Add a prebuild configuration + +``` +daytona prebuild add [WORKSPACE_CONFIG] [flags] +``` + +### Options + +``` + -b, --branch string Git branch for the prebuild + -c, --commit-interval int Commit interval for running a prebuild - leave blank to ignore push events + -r, --retention int Maximum number of resulting builds stored at a time + --run Run the prebuild once after adding it + -t, --trigger-files strings Full paths of files whose changes should explicitly trigger a prebuild +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds + diff --git a/docs/daytona_prebuild_delete.md b/docs/daytona_prebuild_delete.md new file mode 100644 index 0000000000..56e5d4015e --- /dev/null +++ b/docs/daytona_prebuild_delete.md @@ -0,0 +1,24 @@ +## daytona prebuild delete + +Delete a prebuild configuration + +``` +daytona prebuild delete [WORKSPACE_CONFIG] [PREBUILD] [flags] +``` + +### Options + +``` + -f, --force Force delete prebuild +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds + diff --git a/docs/daytona_prebuild_info.md b/docs/daytona_prebuild_info.md new file mode 100644 index 0000000000..70eea63dd1 --- /dev/null +++ b/docs/daytona_prebuild_info.md @@ -0,0 +1,24 @@ +## daytona prebuild info + +Show prebuild configuration info + +``` +daytona prebuild info [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds + diff --git a/docs/daytona_prebuild_list.md b/docs/daytona_prebuild_list.md new file mode 100644 index 0000000000..a00151506a --- /dev/null +++ b/docs/daytona_prebuild_list.md @@ -0,0 +1,24 @@ +## daytona prebuild list + +List prebuild configurations + +``` +daytona prebuild list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds + diff --git a/docs/daytona_prebuild_update.md b/docs/daytona_prebuild_update.md new file mode 100644 index 0000000000..1b735fecef --- /dev/null +++ b/docs/daytona_prebuild_update.md @@ -0,0 +1,28 @@ +## daytona prebuild update + +Update a prebuild configuration + +``` +daytona prebuild update [WORKSPACE_CONFIG] [PREBUILD_ID] [flags] +``` + +### Options + +``` + -b, --branch string Git branch for the prebuild + -c, --commit-interval int Commit interval for running a prebuild - leave blank to ignore push events + -r, --retention int Maximum number of resulting builds stored at a time + --run Run the prebuild once after updating it + -t, --trigger-files strings Full paths of files whose changes should explicitly trigger a prebuild +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona prebuild](daytona_prebuild.md) - Manage prebuilds + diff --git a/docs/daytona_profile.md b/docs/daytona_profile.md new file mode 100644 index 0000000000..2226adeae0 --- /dev/null +++ b/docs/daytona_profile.md @@ -0,0 +1,19 @@ +## daytona profile + +Manage profiles + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona profile add](daytona_profile_add.md) - Add profile +* [daytona profile delete](daytona_profile_delete.md) - Delete profile [PROFILE_NAME] +* [daytona profile edit](daytona_profile_edit.md) - Edit profile [PROFILE_NAME] +* [daytona profile list](daytona_profile_list.md) - List profiles +* [daytona profile use](daytona_profile_use.md) - Use profile [PROFILE_NAME] + diff --git a/docs/daytona_profile_add.md b/docs/daytona_profile_add.md new file mode 100644 index 0000000000..12ea0fa96d --- /dev/null +++ b/docs/daytona_profile_add.md @@ -0,0 +1,26 @@ +## daytona profile add + +Add profile + +``` +daytona profile add [flags] +``` + +### Options + +``` + -k, --api-key string API Key + -a, --api-url string API URL + -n, --name string Profile name +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona profile](daytona_profile.md) - Manage profiles + diff --git a/docs/daytona_profile_delete.md b/docs/daytona_profile_delete.md new file mode 100644 index 0000000000..d8ed86d359 --- /dev/null +++ b/docs/daytona_profile_delete.md @@ -0,0 +1,18 @@ +## daytona profile delete + +Delete profile [PROFILE_NAME] + +``` +daytona profile delete [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona profile](daytona_profile.md) - Manage profiles + diff --git a/docs/daytona_profile_edit.md b/docs/daytona_profile_edit.md new file mode 100644 index 0000000000..79be7454f4 --- /dev/null +++ b/docs/daytona_profile_edit.md @@ -0,0 +1,26 @@ +## daytona profile edit + +Edit profile [PROFILE_NAME] + +``` +daytona profile edit [flags] +``` + +### Options + +``` + -k, --api-key string API Key + -a, --api-url string API URL + -n, --name string Profile name +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona profile](daytona_profile.md) - Manage profiles + diff --git a/docs/daytona_profile_list.md b/docs/daytona_profile_list.md new file mode 100644 index 0000000000..348bec7028 --- /dev/null +++ b/docs/daytona_profile_list.md @@ -0,0 +1,24 @@ +## daytona profile list + +List profiles + +``` +daytona profile list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona profile](daytona_profile.md) - Manage profiles + diff --git a/docs/daytona_provider.md b/docs/daytona_provider.md new file mode 100644 index 0000000000..b509313b07 --- /dev/null +++ b/docs/daytona_provider.md @@ -0,0 +1,18 @@ +## daytona provider + +Manage providers + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona provider install](daytona_provider_install.md) - Install provider +* [daytona provider list](daytona_provider_list.md) - List installed providers +* [daytona provider uninstall](daytona_provider_uninstall.md) - Uninstall provider +* [daytona provider update](daytona_provider_update.md) - Update provider + diff --git a/docs/daytona_provider_install.md b/docs/daytona_provider_install.md new file mode 100644 index 0000000000..71c36d175d --- /dev/null +++ b/docs/daytona_provider_install.md @@ -0,0 +1,24 @@ +## daytona provider install + +Install provider + +``` +daytona provider install [flags] +``` + +### Options + +``` + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona provider](daytona_provider.md) - Manage providers + diff --git a/docs/daytona_provider_list.md b/docs/daytona_provider_list.md new file mode 100644 index 0000000000..d78d0f4f65 --- /dev/null +++ b/docs/daytona_provider_list.md @@ -0,0 +1,24 @@ +## daytona provider list + +List installed providers + +``` +daytona provider list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona provider](daytona_provider.md) - Manage providers + diff --git a/docs/daytona_provider_uninstall.md b/docs/daytona_provider_uninstall.md new file mode 100644 index 0000000000..04fdf4e149 --- /dev/null +++ b/docs/daytona_provider_uninstall.md @@ -0,0 +1,18 @@ +## daytona provider uninstall + +Uninstall provider + +``` +daytona provider uninstall [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona provider](daytona_provider.md) - Manage providers + diff --git a/docs/daytona_provider_update.md b/docs/daytona_provider_update.md new file mode 100644 index 0000000000..9e41020273 --- /dev/null +++ b/docs/daytona_provider_update.md @@ -0,0 +1,24 @@ +## daytona provider update + +Update provider + +``` +daytona provider update [flags] +``` + +### Options + +``` + -a, --all Update all providers +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona provider](daytona_provider.md) - Manage providers + diff --git a/docs/daytona_purge.md b/docs/daytona_purge.md new file mode 100644 index 0000000000..b34cf5c858 --- /dev/null +++ b/docs/daytona_purge.md @@ -0,0 +1,29 @@ +## daytona purge + +Purges all Daytona data from the current device + +### Synopsis + +Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. + +``` +daytona purge [flags] +``` + +### Options + +``` + -f, --force Delete all targets by force + -y, --yes Execute purge without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_serve.md b/docs/daytona_serve.md new file mode 100644 index 0000000000..f19d30acae --- /dev/null +++ b/docs/daytona_serve.md @@ -0,0 +1,18 @@ +## daytona serve + +Run the server process in the current terminal session + +``` +daytona serve [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_server.md b/docs/daytona_server.md new file mode 100644 index 0000000000..bffb71a5e9 --- /dev/null +++ b/docs/daytona_server.md @@ -0,0 +1,30 @@ +## daytona server + +Start the server process in daemon mode + +``` +daytona server [flags] +``` + +### Options + +``` + -y, --yes Skip the confirmation prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona server config](daytona_server_config.md) - Output local Daytona Server config +* [daytona server configure](daytona_server_configure.md) - Configure Daytona Server +* [daytona server logs](daytona_server_logs.md) - Output Daytona Server logs +* [daytona server restart](daytona_server_restart.md) - Restarts the Daytona Server daemon +* [daytona server start](daytona_server_start.md) - Start the Daytona Server daemon +* [daytona server stop](daytona_server_stop.md) - Stops the Daytona Server daemon + diff --git a/docs/daytona_server_config.md b/docs/daytona_server_config.md new file mode 100644 index 0000000000..ff2eb80a78 --- /dev/null +++ b/docs/daytona_server_config.md @@ -0,0 +1,24 @@ +## daytona server config + +Output local Daytona Server config + +``` +daytona server config [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode + diff --git a/docs/daytona_server_configure.md b/docs/daytona_server_configure.md new file mode 100644 index 0000000000..4c9bbbcde4 --- /dev/null +++ b/docs/daytona_server_configure.md @@ -0,0 +1,18 @@ +## daytona server configure + +Configure Daytona Server + +``` +daytona server configure [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode + diff --git a/docs/daytona_server_logs.md b/docs/daytona_server_logs.md new file mode 100644 index 0000000000..94447c34f5 --- /dev/null +++ b/docs/daytona_server_logs.md @@ -0,0 +1,27 @@ +## daytona server logs + +Output Daytona Server logs + +``` +daytona server logs [flags] +``` + +### Options + +``` + --file string Read specific log file + -f, --follow Follow logs + -l, --local Read local server log files +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode +* [daytona server logs list](daytona_server_logs_list.md) - Lists Daytona Server Log Files + diff --git a/docs/daytona_server_logs_list.md b/docs/daytona_server_logs_list.md new file mode 100644 index 0000000000..377d96d9f6 --- /dev/null +++ b/docs/daytona_server_logs_list.md @@ -0,0 +1,18 @@ +## daytona server logs list + +Lists Daytona Server Log Files + +``` +daytona server logs list [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server logs](daytona_server_logs.md) - Output Daytona Server logs + diff --git a/docs/daytona_server_restart.md b/docs/daytona_server_restart.md new file mode 100644 index 0000000000..1857fb1402 --- /dev/null +++ b/docs/daytona_server_restart.md @@ -0,0 +1,18 @@ +## daytona server restart + +Restarts the Daytona Server daemon + +``` +daytona server restart [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode + diff --git a/docs/daytona_server_start.md b/docs/daytona_server_start.md new file mode 100644 index 0000000000..95bb3859f9 --- /dev/null +++ b/docs/daytona_server_start.md @@ -0,0 +1,18 @@ +## daytona server start + +Start the Daytona Server daemon + +``` +daytona server start [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode + diff --git a/docs/daytona_server_stop.md b/docs/daytona_server_stop.md new file mode 100644 index 0000000000..1852546025 --- /dev/null +++ b/docs/daytona_server_stop.md @@ -0,0 +1,18 @@ +## daytona server stop + +Stops the Daytona Server daemon + +``` +daytona server stop [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode + diff --git a/docs/daytona_ssh.md b/docs/daytona_ssh.md new file mode 100644 index 0000000000..8864a7060e --- /dev/null +++ b/docs/daytona_ssh.md @@ -0,0 +1,25 @@ +## daytona ssh + +SSH into a workspace using the terminal + +``` +daytona ssh [WORKSPACE] [CMD...] [flags] +``` + +### Options + +``` + -o, --option stringArray Specify SSH options in KEY=VALUE format. + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_start.md b/docs/daytona_start.md new file mode 100644 index 0000000000..4edea44931 --- /dev/null +++ b/docs/daytona_start.md @@ -0,0 +1,26 @@ +## daytona start + +Start a workspace + +``` +daytona start [WORKSPACE] [flags] +``` + +### Options + +``` + -a, --all Start all targets + -c, --code Open the target in the IDE after target start + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_target-config.md b/docs/daytona_target-config.md new file mode 100644 index 0000000000..3effd3ca45 --- /dev/null +++ b/docs/daytona_target-config.md @@ -0,0 +1,18 @@ +## daytona target-config + +Manage target configs + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona target-config list](daytona_target-config_list.md) - List target configs +* [daytona target-config remove](daytona_target-config_remove.md) - Remove target config +* [daytona target-config set](daytona_target-config_set.md) - Set target config +* [daytona target-config set-default](daytona_target-config_set-default.md) - Set default target config + diff --git a/docs/daytona_target-config_list.md b/docs/daytona_target-config_list.md new file mode 100644 index 0000000000..b14c9641fd --- /dev/null +++ b/docs/daytona_target-config_list.md @@ -0,0 +1,24 @@ +## daytona target-config list + +List target configs + +``` +daytona target-config list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target-config](daytona_target-config.md) - Manage target configs + diff --git a/docs/daytona_target-config_remove.md b/docs/daytona_target-config_remove.md new file mode 100644 index 0000000000..aebe62cfb7 --- /dev/null +++ b/docs/daytona_target-config_remove.md @@ -0,0 +1,24 @@ +## daytona target-config remove + +Remove target config + +``` +daytona target-config remove [CONFIG_NAME] [flags] +``` + +### Options + +``` + -y, --yes Confirm deletion of all targets without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target-config](daytona_target-config.md) - Manage target configs + diff --git a/docs/daytona_target-config_set-default.md b/docs/daytona_target-config_set-default.md new file mode 100644 index 0000000000..60aa9b6f7c --- /dev/null +++ b/docs/daytona_target-config_set-default.md @@ -0,0 +1,18 @@ +## daytona target-config set-default + +Set default target config + +``` +daytona target-config set-default [CONFIG_NAME] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target-config](daytona_target-config.md) - Manage target configs + diff --git a/docs/daytona_target-config_set.md b/docs/daytona_target-config_set.md new file mode 100644 index 0000000000..fb453a3699 --- /dev/null +++ b/docs/daytona_target-config_set.md @@ -0,0 +1,18 @@ +## daytona target-config set + +Set target config + +``` +daytona target-config set [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target-config](daytona_target-config.md) - Manage target configs + diff --git a/docs/daytona_target.md b/docs/daytona_target.md new file mode 100644 index 0000000000..4b68b6dcd7 --- /dev/null +++ b/docs/daytona_target.md @@ -0,0 +1,20 @@ +## daytona target + +Manage targets + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona target delete](daytona_target_delete.md) - Delete a target +* [daytona target info](daytona_target_info.md) - Show target info +* [daytona target list](daytona_target_list.md) - List targets +* [daytona target restart](daytona_target_restart.md) - Restart a target +* [daytona target start](daytona_target_start.md) - Start a target +* [daytona target stop](daytona_target_stop.md) - Stop a target + diff --git a/docs/daytona_target_delete.md b/docs/daytona_target_delete.md new file mode 100644 index 0000000000..ebaef073a3 --- /dev/null +++ b/docs/daytona_target_delete.md @@ -0,0 +1,26 @@ +## daytona target delete + +Delete a target + +``` +daytona target delete [TARGET] [flags] +``` + +### Options + +``` + -a, --all Delete all targets + -f, --force Delete a target by force + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_info.md b/docs/daytona_target_info.md new file mode 100644 index 0000000000..4a6f443995 --- /dev/null +++ b/docs/daytona_target_info.md @@ -0,0 +1,24 @@ +## daytona target info + +Show target info + +``` +daytona target info [TARGET] [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_list.md b/docs/daytona_target_list.md new file mode 100644 index 0000000000..d14e23a888 --- /dev/null +++ b/docs/daytona_target_list.md @@ -0,0 +1,25 @@ +## daytona target list + +List targets + +``` +daytona target list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) + -v, --verbose Show verbose output +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_restart.md b/docs/daytona_target_restart.md new file mode 100644 index 0000000000..d31dbdbff8 --- /dev/null +++ b/docs/daytona_target_restart.md @@ -0,0 +1,18 @@ +## daytona target restart + +Restart a target + +``` +daytona target restart [TARGET] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_start.md b/docs/daytona_target_start.md new file mode 100644 index 0000000000..7fd21e4873 --- /dev/null +++ b/docs/daytona_target_start.md @@ -0,0 +1,25 @@ +## daytona target start + +Start a target + +``` +daytona target start [TARGET] [flags] +``` + +### Options + +``` + -a, --all Start all targets + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_stop.md b/docs/daytona_target_stop.md new file mode 100644 index 0000000000..714942afcb --- /dev/null +++ b/docs/daytona_target_stop.md @@ -0,0 +1,24 @@ +## daytona target stop + +Stop a target + +``` +daytona target stop [TARGET] [flags] +``` + +### Options + +``` + -a, --all Stop all targets +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_telemetry.md b/docs/daytona_telemetry.md new file mode 100644 index 0000000000..68d4c9726a --- /dev/null +++ b/docs/daytona_telemetry.md @@ -0,0 +1,16 @@ +## daytona telemetry + +Manage telemetry collection + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona telemetry disable](daytona_telemetry_disable.md) - Disable telemetry collection +* [daytona telemetry enable](daytona_telemetry_enable.md) - Enable telemetry collection + diff --git a/docs/daytona_telemetry_disable.md b/docs/daytona_telemetry_disable.md new file mode 100644 index 0000000000..f062a90208 --- /dev/null +++ b/docs/daytona_telemetry_disable.md @@ -0,0 +1,18 @@ +## daytona telemetry disable + +Disable telemetry collection + +``` +daytona telemetry disable [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection + diff --git a/docs/daytona_telemetry_enable.md b/docs/daytona_telemetry_enable.md new file mode 100644 index 0000000000..2e8c71acd6 --- /dev/null +++ b/docs/daytona_telemetry_enable.md @@ -0,0 +1,18 @@ +## daytona telemetry enable + +Enable telemetry collection + +``` +daytona telemetry enable [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection + diff --git a/docs/daytona_use.md b/docs/daytona_use.md new file mode 100644 index 0000000000..b1921191ca --- /dev/null +++ b/docs/daytona_use.md @@ -0,0 +1,18 @@ +## daytona use + +Use profile [PROFILE_NAME] + +``` +daytona use [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_version.md b/docs/daytona_version.md new file mode 100644 index 0000000000..2f0f9fb6a6 --- /dev/null +++ b/docs/daytona_version.md @@ -0,0 +1,18 @@ +## daytona version + +Print the version number + +``` +daytona version [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_whoami.md b/docs/daytona_whoami.md new file mode 100644 index 0000000000..b7c5683b89 --- /dev/null +++ b/docs/daytona_whoami.md @@ -0,0 +1,24 @@ +## daytona whoami + +Display information about the active user + +``` +daytona whoami [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_workspace-config.md b/docs/daytona_workspace-config.md new file mode 100644 index 0000000000..375c80a6ab --- /dev/null +++ b/docs/daytona_workspace-config.md @@ -0,0 +1,20 @@ +## daytona workspace-config + +Manage workspace configs + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona workspace-config add](daytona_workspace-config_add.md) - Add a workspace config +* [daytona workspace-config delete](daytona_workspace-config_delete.md) - Delete a workspace config +* [daytona workspace-config info](daytona_workspace-config_info.md) - Show workspace config info +* [daytona workspace-config list](daytona_workspace-config_list.md) - Lists workspace configs +* [daytona workspace-config set-default](daytona_workspace-config_set-default.md) - Set workspace config info +* [daytona workspace-config update](daytona_workspace-config_update.md) - Update a workspace config + diff --git a/docs/daytona_workspace-config_add.md b/docs/daytona_workspace-config_add.md new file mode 100644 index 0000000000..64d30511d9 --- /dev/null +++ b/docs/daytona_workspace-config_add.md @@ -0,0 +1,31 @@ +## daytona workspace-config add + +Add a workspace config + +``` +daytona workspace-config add [flags] +``` + +### Options + +``` + --builder BuildChoice Specify the builder (currently auto/devcontainer/none) + --custom-image string Create the workspace with the custom image passed as the flag value; Requires setting --custom-image-user flag as well + --custom-image-user string Create the workspace with the custom image user passed as the flag value; Requires setting --custom-image flag as well + --devcontainer-path string Automatically assign the devcontainer builder with the path passed as the flag value + --env stringArray Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') + --git-provider-config string Specify the Git provider configuration ID or alias + --manual Manually enter the Git repository + --name string Specify the workspace config name +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/docs/daytona_workspace-config_delete.md b/docs/daytona_workspace-config_delete.md new file mode 100644 index 0000000000..876865722c --- /dev/null +++ b/docs/daytona_workspace-config_delete.md @@ -0,0 +1,26 @@ +## daytona workspace-config delete + +Delete a workspace config + +``` +daytona workspace-config delete [flags] +``` + +### Options + +``` + -a, --all Delete all workspace configs + -f, --force Force delete prebuild + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/docs/daytona_workspace-config_info.md b/docs/daytona_workspace-config_info.md new file mode 100644 index 0000000000..71c0f4e022 --- /dev/null +++ b/docs/daytona_workspace-config_info.md @@ -0,0 +1,24 @@ +## daytona workspace-config info + +Show workspace config info + +``` +daytona workspace-config info [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/docs/daytona_workspace-config_list.md b/docs/daytona_workspace-config_list.md new file mode 100644 index 0000000000..aa183e5661 --- /dev/null +++ b/docs/daytona_workspace-config_list.md @@ -0,0 +1,24 @@ +## daytona workspace-config list + +Lists workspace configs + +``` +daytona workspace-config list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/docs/daytona_workspace-config_set-default.md b/docs/daytona_workspace-config_set-default.md new file mode 100644 index 0000000000..564daabf3f --- /dev/null +++ b/docs/daytona_workspace-config_set-default.md @@ -0,0 +1,18 @@ +## daytona workspace-config set-default + +Set workspace config info + +``` +daytona workspace-config set-default [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/docs/daytona_workspace-config_update.md b/docs/daytona_workspace-config_update.md new file mode 100644 index 0000000000..734a480160 --- /dev/null +++ b/docs/daytona_workspace-config_update.md @@ -0,0 +1,18 @@ +## daytona workspace-config update + +Update a workspace config + +``` +daytona workspace-config update [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs + diff --git a/hack/docs/agent_mode/daytona.yaml b/hack/docs/agent_mode/daytona.yaml new file mode 100644 index 0000000000..be0c604e58 --- /dev/null +++ b/hack/docs/agent_mode/daytona.yaml @@ -0,0 +1,25 @@ +name: daytona +synopsis: Daytona is a Dev Environment Manager +description: Daytona is a Dev Environment Manager +usage: daytona [flags] +options: + - name: help + default_value: "false" + usage: help for daytona + - name: version + shorthand: v + default_value: "false" + usage: Display the version of Daytona +see_also: + - daytona agent - Start the agent process + - daytona autocomplete - Adds a completion script for your shell environment + - daytona docs - Opens the Daytona documentation in your default browser. + - daytona expose - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace + - daytona forward - Forward a port publicly via an URL + - daytona info - Show workspace info + - daytona list - List targets + - daytona logs - View logs for a target/workspace + - daytona restart - Restart the workspace + - daytona start - Start the workspace + - daytona stop - Stop the workspace + - daytona version - Print the version number diff --git a/hack/docs/agent_mode/daytona_agent.yaml b/hack/docs/agent_mode/daytona_agent.yaml new file mode 100644 index 0000000000..5034cc17be --- /dev/null +++ b/hack/docs/agent_mode/daytona_agent.yaml @@ -0,0 +1,14 @@ +name: daytona agent +synopsis: Start the agent process +usage: daytona agent [flags] +options: + - name: host + default_value: "false" + usage: Run the agent in host mode +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona agent logs - Output Daytona Agent logs diff --git a/hack/docs/agent_mode/daytona_agent_logs.yaml b/hack/docs/agent_mode/daytona_agent_logs.yaml new file mode 100644 index 0000000000..7ff3b8e0a3 --- /dev/null +++ b/hack/docs/agent_mode/daytona_agent_logs.yaml @@ -0,0 +1,14 @@ +name: daytona agent logs +synopsis: Output Daytona Agent logs +usage: daytona agent logs [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona agent - Start the agent process diff --git a/hack/docs/agent_mode/daytona_autocomplete.yaml b/hack/docs/agent_mode/daytona_autocomplete.yaml new file mode 100644 index 0000000000..3d7cd97846 --- /dev/null +++ b/hack/docs/agent_mode/daytona_autocomplete.yaml @@ -0,0 +1,9 @@ +name: daytona autocomplete +synopsis: Adds a completion script for your shell environment +usage: daytona autocomplete [bash|zsh|fish|powershell] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_docs.yaml b/hack/docs/agent_mode/daytona_docs.yaml new file mode 100644 index 0000000000..2eb2502768 --- /dev/null +++ b/hack/docs/agent_mode/daytona_docs.yaml @@ -0,0 +1,9 @@ +name: daytona docs +synopsis: Opens the Daytona documentation in your default browser. +usage: daytona docs [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_expose.yaml b/hack/docs/agent_mode/daytona_expose.yaml new file mode 100644 index 0000000000..776659b284 --- /dev/null +++ b/hack/docs/agent_mode/daytona_expose.yaml @@ -0,0 +1,10 @@ +name: daytona expose +synopsis: | + Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace +usage: daytona expose [PORT] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_forward.yaml b/hack/docs/agent_mode/daytona_forward.yaml new file mode 100644 index 0000000000..a6b70eea12 --- /dev/null +++ b/hack/docs/agent_mode/daytona_forward.yaml @@ -0,0 +1,9 @@ +name: daytona forward +synopsis: Forward a port publicly via an URL +usage: daytona forward [PORT] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_info.yaml b/hack/docs/agent_mode/daytona_info.yaml new file mode 100644 index 0000000000..6d9a8ef626 --- /dev/null +++ b/hack/docs/agent_mode/daytona_info.yaml @@ -0,0 +1,13 @@ +name: daytona info +synopsis: Show workspace info +usage: daytona info [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_list.yaml b/hack/docs/agent_mode/daytona_list.yaml new file mode 100644 index 0000000000..08be0d7c58 --- /dev/null +++ b/hack/docs/agent_mode/daytona_list.yaml @@ -0,0 +1,17 @@ +name: daytona list +synopsis: List targets +usage: daytona list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) + - name: verbose + shorthand: v + default_value: "false" + usage: Show verbose output +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_logs.yaml b/hack/docs/agent_mode/daytona_logs.yaml new file mode 100644 index 0000000000..5ae83c6de5 --- /dev/null +++ b/hack/docs/agent_mode/daytona_logs.yaml @@ -0,0 +1,18 @@ +name: daytona logs +synopsis: View logs for a target/workspace +usage: daytona logs [TARGET] [WORKSPACE_NAME] [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs + - name: target + shorthand: w + default_value: "false" + usage: View target logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_restart.yaml b/hack/docs/agent_mode/daytona_restart.yaml new file mode 100644 index 0000000000..e26f0ebb3b --- /dev/null +++ b/hack/docs/agent_mode/daytona_restart.yaml @@ -0,0 +1,9 @@ +name: daytona restart +synopsis: Restart the workspace +usage: daytona restart [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_start.yaml b/hack/docs/agent_mode/daytona_start.yaml new file mode 100644 index 0000000000..8751a52ba3 --- /dev/null +++ b/hack/docs/agent_mode/daytona_start.yaml @@ -0,0 +1,9 @@ +name: daytona start +synopsis: Start the workspace +usage: daytona start [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_stop.yaml b/hack/docs/agent_mode/daytona_stop.yaml new file mode 100644 index 0000000000..7bfbfe3d24 --- /dev/null +++ b/hack/docs/agent_mode/daytona_stop.yaml @@ -0,0 +1,9 @@ +name: daytona stop +synopsis: Stop the workspace +usage: daytona stop [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_version.yaml b/hack/docs/agent_mode/daytona_version.yaml new file mode 100644 index 0000000000..02035a7170 --- /dev/null +++ b/hack/docs/agent_mode/daytona_version.yaml @@ -0,0 +1,9 @@ +name: daytona version +synopsis: Print the version number +usage: daytona version [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml new file mode 100644 index 0000000000..293b544fed --- /dev/null +++ b/hack/docs/daytona.yaml @@ -0,0 +1,44 @@ +name: daytona +synopsis: Daytona is a Dev Environment Manager +description: Daytona is a Dev Environment Manager +usage: daytona [flags] +options: + - name: help + default_value: "false" + usage: help for daytona + - name: version + shorthand: v + default_value: "false" + usage: Display the version of Daytona +see_also: + - daytona api-key - Api Key commands + - daytona autocomplete - Adds a completion script for your shell environment + - daytona build - Manage builds + - daytona code - Open a workspace in your preferred IDE + - daytona config - Output Daytona configuration + - daytona container-registry - Manage container registries + - daytona create - Create a target + - daytona delete - Delete a workspace + - daytona docs - Opens the Daytona documentation in your default browser. + - daytona env - Manage profile environment variables that are added to all targets and workspaces + - daytona forward - Forward a port from a workspace to your local machine + - daytona git-providers - Manage Git providers + - daytona ide - Choose the default IDE + - daytona info - Show target info + - daytona list - List targets + - daytona logs - View logs for a target/workspace + - daytona prebuild - Manage prebuilds + - daytona profile - Manage profiles + - daytona provider - Manage providers + - daytona purge - Purges all Daytona data from the current device + - daytona serve - Run the server process in the current terminal session + - daytona server - Start the server process in daemon mode + - daytona ssh - SSH into a workspace using the terminal + - daytona start - Start a workspace + - daytona target - Manage targets + - daytona target-config - Manage target configs + - daytona telemetry - Manage telemetry collection + - daytona use - Use profile [PROFILE_NAME] + - daytona version - Print the version number + - daytona whoami - Display information about the active user + - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_api-key.yaml b/hack/docs/daytona_api-key.yaml new file mode 100644 index 0000000000..a886de682c --- /dev/null +++ b/hack/docs/daytona_api-key.yaml @@ -0,0 +1,11 @@ +name: daytona api-key +synopsis: Api Key commands +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona api-key generate - Generate a new API key + - daytona api-key list - List API keys + - daytona api-key revoke - Revoke an API key diff --git a/hack/docs/daytona_api-key_generate.yaml b/hack/docs/daytona_api-key_generate.yaml new file mode 100644 index 0000000000..988087f62b --- /dev/null +++ b/hack/docs/daytona_api-key_generate.yaml @@ -0,0 +1,9 @@ +name: daytona api-key generate +synopsis: Generate a new API key +usage: daytona api-key generate [NAME] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona api-key - Api Key commands diff --git a/hack/docs/daytona_api-key_list.yaml b/hack/docs/daytona_api-key_list.yaml new file mode 100644 index 0000000000..d46b49b95d --- /dev/null +++ b/hack/docs/daytona_api-key_list.yaml @@ -0,0 +1,13 @@ +name: daytona api-key list +synopsis: List API keys +usage: daytona api-key list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona api-key - Api Key commands diff --git a/hack/docs/daytona_api-key_revoke.yaml b/hack/docs/daytona_api-key_revoke.yaml new file mode 100644 index 0000000000..2009ac9ee1 --- /dev/null +++ b/hack/docs/daytona_api-key_revoke.yaml @@ -0,0 +1,14 @@ +name: daytona api-key revoke +synopsis: Revoke an API key +usage: daytona api-key revoke [NAME] [flags] +options: + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Skip confirmation prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona api-key - Api Key commands diff --git a/hack/docs/daytona_autocomplete.yaml b/hack/docs/daytona_autocomplete.yaml new file mode 100644 index 0000000000..3d7cd97846 --- /dev/null +++ b/hack/docs/daytona_autocomplete.yaml @@ -0,0 +1,9 @@ +name: daytona autocomplete +synopsis: Adds a completion script for your shell environment +usage: daytona autocomplete [bash|zsh|fish|powershell] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_build.yaml b/hack/docs/daytona_build.yaml new file mode 100644 index 0000000000..972e9c42de --- /dev/null +++ b/hack/docs/daytona_build.yaml @@ -0,0 +1,13 @@ +name: daytona build +synopsis: Manage builds +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona build delete - Delete a build + - daytona build info - Show build info + - daytona build list - List all builds + - daytona build logs - View logs for build + - daytona build run - Run a build from a workspace config diff --git a/hack/docs/daytona_build_delete.yaml b/hack/docs/daytona_build_delete.yaml new file mode 100644 index 0000000000..36b845e633 --- /dev/null +++ b/hack/docs/daytona_build_delete.yaml @@ -0,0 +1,20 @@ +name: daytona build delete +synopsis: Delete a build +usage: daytona build delete [BUILD] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Delete ALL builds + - name: force + shorthand: f + default_value: "false" + usage: Force delete build + - name: prebuild-id + usage: Delete ALL builds from prebuild +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona build - Manage builds diff --git a/hack/docs/daytona_build_info.yaml b/hack/docs/daytona_build_info.yaml new file mode 100644 index 0000000000..1deaf0f3b9 --- /dev/null +++ b/hack/docs/daytona_build_info.yaml @@ -0,0 +1,13 @@ +name: daytona build info +synopsis: Show build info +usage: daytona build info [BUILD] [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona build - Manage builds diff --git a/hack/docs/daytona_build_list.yaml b/hack/docs/daytona_build_list.yaml new file mode 100644 index 0000000000..35c86da275 --- /dev/null +++ b/hack/docs/daytona_build_list.yaml @@ -0,0 +1,13 @@ +name: daytona build list +synopsis: List all builds +usage: daytona build list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona build - Manage builds diff --git a/hack/docs/daytona_build_logs.yaml b/hack/docs/daytona_build_logs.yaml new file mode 100644 index 0000000000..653c6e435c --- /dev/null +++ b/hack/docs/daytona_build_logs.yaml @@ -0,0 +1,14 @@ +name: daytona build logs +synopsis: View logs for build +usage: daytona build logs [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona build - Manage builds diff --git a/hack/docs/daytona_build_run.yaml b/hack/docs/daytona_build_run.yaml new file mode 100644 index 0000000000..71dc903ecf --- /dev/null +++ b/hack/docs/daytona_build_run.yaml @@ -0,0 +1,9 @@ +name: daytona build run +synopsis: Run a build from a workspace config +usage: daytona build run [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona build - Manage builds diff --git a/hack/docs/daytona_code.yaml b/hack/docs/daytona_code.yaml new file mode 100644 index 0000000000..681575d51c --- /dev/null +++ b/hack/docs/daytona_code.yaml @@ -0,0 +1,18 @@ +name: daytona code +synopsis: Open a workspace in your preferred IDE +usage: daytona code [WORKSPACE] [flags] +options: + - name: ide + shorthand: i + usage: | + Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_config.yaml b/hack/docs/daytona_config.yaml new file mode 100644 index 0000000000..9bf7563015 --- /dev/null +++ b/hack/docs/daytona_config.yaml @@ -0,0 +1,17 @@ +name: daytona config +synopsis: Output Daytona configuration +usage: daytona config [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) + - name: show-api-keys + shorthand: k + default_value: "false" + usage: Show API keys +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_container-registry.yaml b/hack/docs/daytona_container-registry.yaml new file mode 100644 index 0000000000..8157d18d0d --- /dev/null +++ b/hack/docs/daytona_container-registry.yaml @@ -0,0 +1,11 @@ +name: daytona container-registry +synopsis: Manage container registries +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona container-registry delete - Delete a container registry + - daytona container-registry list - Lists container registries + - daytona container-registry set - Set container registry diff --git a/hack/docs/daytona_container-registry_delete.yaml b/hack/docs/daytona_container-registry_delete.yaml new file mode 100644 index 0000000000..8200c586fd --- /dev/null +++ b/hack/docs/daytona_container-registry_delete.yaml @@ -0,0 +1,9 @@ +name: daytona container-registry delete +synopsis: Delete a container registry +usage: daytona container-registry delete [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_container-registry_list.yaml b/hack/docs/daytona_container-registry_list.yaml new file mode 100644 index 0000000000..be84cb144c --- /dev/null +++ b/hack/docs/daytona_container-registry_list.yaml @@ -0,0 +1,13 @@ +name: daytona container-registry list +synopsis: Lists container registries +usage: daytona container-registry list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_container-registry_set.yaml b/hack/docs/daytona_container-registry_set.yaml new file mode 100644 index 0000000000..b4ca3426b9 --- /dev/null +++ b/hack/docs/daytona_container-registry_set.yaml @@ -0,0 +1,19 @@ +name: daytona container-registry set +synopsis: Set container registry +usage: daytona container-registry set [flags] +options: + - name: password + shorthand: p + usage: Password + - name: server + shorthand: s + usage: Server + - name: username + shorthand: u + usage: Username +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_create.yaml b/hack/docs/daytona_create.yaml new file mode 100644 index 0000000000..45329bd8e9 --- /dev/null +++ b/hack/docs/daytona_create.yaml @@ -0,0 +1,57 @@ +name: daytona create +synopsis: Create a target +usage: daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] +options: + - name: blank + default_value: "false" + usage: | + Create a blank workspace without using existing configurations + - name: branch + default_value: '[]' + usage: Specify the Git branches to use in the workspaces + - name: builder + usage: Specify the builder (currently auto/devcontainer/none) + - name: custom-image + usage: | + Create the workspace with the custom image passed as the flag value; Requires setting --custom-image-user flag as well + - name: custom-image-user + usage: | + Create the workspace with the custom image user passed as the flag value; Requires setting --custom-image flag as well + - name: devcontainer-path + usage: | + Automatically assign the devcontainer builder with the path passed as the flag value + - name: env + default_value: '[]' + usage: | + Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') + - name: git-provider-config + usage: Specify the Git provider configuration ID or alias + - name: ide + shorthand: i + usage: | + Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + - name: manual + default_value: "false" + usage: Manually enter the Git repository + - name: multi-workspace + default_value: "false" + usage: Target with multiple workspaces/repos + - name: name + usage: Specify the target name + - name: no-ide + shorthand: "n" + default_value: "false" + usage: Do not open the target in the IDE after target creation + - name: target + shorthand: t + usage: Specify the target (e.g. 'local') + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_delete.yaml b/hack/docs/daytona_delete.yaml new file mode 100644 index 0000000000..f7e3545122 --- /dev/null +++ b/hack/docs/daytona_delete.yaml @@ -0,0 +1,22 @@ +name: daytona delete +synopsis: Delete a workspace +usage: daytona delete [WORKSPACE] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Delete all workspaces + - name: force + shorthand: f + default_value: "false" + usage: Delete a workspace by force + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Confirm deletion without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_docs.yaml b/hack/docs/daytona_docs.yaml new file mode 100644 index 0000000000..2eb2502768 --- /dev/null +++ b/hack/docs/daytona_docs.yaml @@ -0,0 +1,9 @@ +name: daytona docs +synopsis: Opens the Daytona documentation in your default browser. +usage: daytona docs [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_env.yaml b/hack/docs/daytona_env.yaml new file mode 100644 index 0000000000..6f4d207d35 --- /dev/null +++ b/hack/docs/daytona_env.yaml @@ -0,0 +1,11 @@ +name: daytona env +synopsis: | + Manage profile environment variables that are added to all targets and workspaces +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona env list - List profile environment variables + - daytona env set - Set profile environment variables diff --git a/hack/docs/daytona_env_list.yaml b/hack/docs/daytona_env_list.yaml new file mode 100644 index 0000000000..383a0495d4 --- /dev/null +++ b/hack/docs/daytona_env_list.yaml @@ -0,0 +1,13 @@ +name: daytona env list +synopsis: List profile environment variables +usage: daytona env list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona env - Manage profile environment variables that are added to all targets and workspaces diff --git a/hack/docs/daytona_env_set.yaml b/hack/docs/daytona_env_set.yaml new file mode 100644 index 0000000000..99893fdbc0 --- /dev/null +++ b/hack/docs/daytona_env_set.yaml @@ -0,0 +1,9 @@ +name: daytona env set +synopsis: Set profile environment variables +usage: daytona env set [KEY=VALUE]... [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona env - Manage profile environment variables that are added to all targets and workspaces diff --git a/hack/docs/daytona_forward.yaml b/hack/docs/daytona_forward.yaml new file mode 100644 index 0000000000..2e0a52361d --- /dev/null +++ b/hack/docs/daytona_forward.yaml @@ -0,0 +1,13 @@ +name: daytona forward +synopsis: Forward a port from a workspace to your local machine +usage: daytona forward [PORT] [WORKSPACE] [flags] +options: + - name: public + default_value: "false" + usage: Should be port be available publicly via an URL +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_git-providers.yaml b/hack/docs/daytona_git-providers.yaml new file mode 100644 index 0000000000..0d80b38486 --- /dev/null +++ b/hack/docs/daytona_git-providers.yaml @@ -0,0 +1,12 @@ +name: daytona git-providers +synopsis: Manage Git providers +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona git-providers add - Register a Git provider + - daytona git-providers delete - Unregister a Git provider + - daytona git-providers list - Lists your registered Git providers + - daytona git-providers update - Update a Git provider diff --git a/hack/docs/daytona_git-providers_add.yaml b/hack/docs/daytona_git-providers_add.yaml new file mode 100644 index 0000000000..5eca9c0e79 --- /dev/null +++ b/hack/docs/daytona_git-providers_add.yaml @@ -0,0 +1,9 @@ +name: daytona git-providers add +synopsis: Register a Git provider +usage: daytona git-providers add [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_git-providers_delete.yaml b/hack/docs/daytona_git-providers_delete.yaml new file mode 100644 index 0000000000..95d0109933 --- /dev/null +++ b/hack/docs/daytona_git-providers_delete.yaml @@ -0,0 +1,18 @@ +name: daytona git-providers delete +synopsis: Unregister a Git provider +usage: daytona git-providers delete [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Remove all Git providers + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Confirm deletion without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_git-providers_list.yaml b/hack/docs/daytona_git-providers_list.yaml new file mode 100644 index 0000000000..002423af47 --- /dev/null +++ b/hack/docs/daytona_git-providers_list.yaml @@ -0,0 +1,13 @@ +name: daytona git-providers list +synopsis: Lists your registered Git providers +usage: daytona git-providers list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_git-providers_update.yaml b/hack/docs/daytona_git-providers_update.yaml new file mode 100644 index 0000000000..3782e8afda --- /dev/null +++ b/hack/docs/daytona_git-providers_update.yaml @@ -0,0 +1,9 @@ +name: daytona git-providers update +synopsis: Update a Git provider +usage: daytona git-providers update [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_ide.yaml b/hack/docs/daytona_ide.yaml new file mode 100644 index 0000000000..6ee01c616d --- /dev/null +++ b/hack/docs/daytona_ide.yaml @@ -0,0 +1,9 @@ +name: daytona ide +synopsis: Choose the default IDE +usage: daytona ide [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_info.yaml b/hack/docs/daytona_info.yaml new file mode 100644 index 0000000000..6c96f1013e --- /dev/null +++ b/hack/docs/daytona_info.yaml @@ -0,0 +1,13 @@ +name: daytona info +synopsis: Show target info +usage: daytona info [TARGET] [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_list.yaml b/hack/docs/daytona_list.yaml new file mode 100644 index 0000000000..08be0d7c58 --- /dev/null +++ b/hack/docs/daytona_list.yaml @@ -0,0 +1,17 @@ +name: daytona list +synopsis: List targets +usage: daytona list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) + - name: verbose + shorthand: v + default_value: "false" + usage: Show verbose output +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_logs.yaml b/hack/docs/daytona_logs.yaml new file mode 100644 index 0000000000..5ae83c6de5 --- /dev/null +++ b/hack/docs/daytona_logs.yaml @@ -0,0 +1,18 @@ +name: daytona logs +synopsis: View logs for a target/workspace +usage: daytona logs [TARGET] [WORKSPACE_NAME] [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs + - name: target + shorthand: w + default_value: "false" + usage: View target logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_prebuild.yaml b/hack/docs/daytona_prebuild.yaml new file mode 100644 index 0000000000..d667986aa0 --- /dev/null +++ b/hack/docs/daytona_prebuild.yaml @@ -0,0 +1,13 @@ +name: daytona prebuild +synopsis: Manage prebuilds +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona prebuild add - Add a prebuild configuration + - daytona prebuild delete - Delete a prebuild configuration + - daytona prebuild info - Show prebuild configuration info + - daytona prebuild list - List prebuild configurations + - daytona prebuild update - Update a prebuild configuration diff --git a/hack/docs/daytona_prebuild_add.yaml b/hack/docs/daytona_prebuild_add.yaml new file mode 100644 index 0000000000..8e6624cb21 --- /dev/null +++ b/hack/docs/daytona_prebuild_add.yaml @@ -0,0 +1,30 @@ +name: daytona prebuild add +synopsis: Add a prebuild configuration +usage: daytona prebuild add [WORKSPACE_CONFIG] [flags] +options: + - name: branch + shorthand: b + usage: Git branch for the prebuild + - name: commit-interval + shorthand: c + default_value: "0" + usage: | + Commit interval for running a prebuild - leave blank to ignore push events + - name: retention + shorthand: r + default_value: "0" + usage: Maximum number of resulting builds stored at a time + - name: run + default_value: "false" + usage: Run the prebuild once after adding it + - name: trigger-files + shorthand: t + default_value: '[]' + usage: | + Full paths of files whose changes should explicitly trigger a prebuild +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_delete.yaml b/hack/docs/daytona_prebuild_delete.yaml new file mode 100644 index 0000000000..c2f21435e3 --- /dev/null +++ b/hack/docs/daytona_prebuild_delete.yaml @@ -0,0 +1,14 @@ +name: daytona prebuild delete +synopsis: Delete a prebuild configuration +usage: daytona prebuild delete [WORKSPACE_CONFIG] [PREBUILD] [flags] +options: + - name: force + shorthand: f + default_value: "false" + usage: Force delete prebuild +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_info.yaml b/hack/docs/daytona_prebuild_info.yaml new file mode 100644 index 0000000000..82a7246c6e --- /dev/null +++ b/hack/docs/daytona_prebuild_info.yaml @@ -0,0 +1,13 @@ +name: daytona prebuild info +synopsis: Show prebuild configuration info +usage: daytona prebuild info [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_list.yaml b/hack/docs/daytona_prebuild_list.yaml new file mode 100644 index 0000000000..d70deff793 --- /dev/null +++ b/hack/docs/daytona_prebuild_list.yaml @@ -0,0 +1,13 @@ +name: daytona prebuild list +synopsis: List prebuild configurations +usage: daytona prebuild list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_prebuild_update.yaml b/hack/docs/daytona_prebuild_update.yaml new file mode 100644 index 0000000000..d6081e097f --- /dev/null +++ b/hack/docs/daytona_prebuild_update.yaml @@ -0,0 +1,30 @@ +name: daytona prebuild update +synopsis: Update a prebuild configuration +usage: daytona prebuild update [WORKSPACE_CONFIG] [PREBUILD_ID] [flags] +options: + - name: branch + shorthand: b + usage: Git branch for the prebuild + - name: commit-interval + shorthand: c + default_value: "0" + usage: | + Commit interval for running a prebuild - leave blank to ignore push events + - name: retention + shorthand: r + default_value: "0" + usage: Maximum number of resulting builds stored at a time + - name: run + default_value: "false" + usage: Run the prebuild once after updating it + - name: trigger-files + shorthand: t + default_value: '[]' + usage: | + Full paths of files whose changes should explicitly trigger a prebuild +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona prebuild - Manage prebuilds diff --git a/hack/docs/daytona_profile.yaml b/hack/docs/daytona_profile.yaml new file mode 100644 index 0000000000..a9cc38d245 --- /dev/null +++ b/hack/docs/daytona_profile.yaml @@ -0,0 +1,13 @@ +name: daytona profile +synopsis: Manage profiles +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona profile add - Add profile + - daytona profile delete - Delete profile [PROFILE_NAME] + - daytona profile edit - Edit profile [PROFILE_NAME] + - daytona profile list - List profiles + - daytona use - Use profile [PROFILE_NAME] diff --git a/hack/docs/daytona_profile_add.yaml b/hack/docs/daytona_profile_add.yaml new file mode 100644 index 0000000000..c2c08730a2 --- /dev/null +++ b/hack/docs/daytona_profile_add.yaml @@ -0,0 +1,19 @@ +name: daytona profile add +synopsis: Add profile +usage: daytona profile add [flags] +options: + - name: api-key + shorthand: k + usage: API Key + - name: api-url + shorthand: a + usage: API URL + - name: name + shorthand: "n" + usage: Profile name +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona profile - Manage profiles diff --git a/hack/docs/daytona_profile_delete.yaml b/hack/docs/daytona_profile_delete.yaml new file mode 100644 index 0000000000..95628ac7c8 --- /dev/null +++ b/hack/docs/daytona_profile_delete.yaml @@ -0,0 +1,9 @@ +name: daytona profile delete +synopsis: Delete profile [PROFILE_NAME] +usage: daytona profile delete [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona profile - Manage profiles diff --git a/hack/docs/daytona_profile_edit.yaml b/hack/docs/daytona_profile_edit.yaml new file mode 100644 index 0000000000..a2c71353d6 --- /dev/null +++ b/hack/docs/daytona_profile_edit.yaml @@ -0,0 +1,19 @@ +name: daytona profile edit +synopsis: Edit profile [PROFILE_NAME] +usage: daytona profile edit [flags] +options: + - name: api-key + shorthand: k + usage: API Key + - name: api-url + shorthand: a + usage: API URL + - name: name + shorthand: "n" + usage: Profile name +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona profile - Manage profiles diff --git a/hack/docs/daytona_profile_list.yaml b/hack/docs/daytona_profile_list.yaml new file mode 100644 index 0000000000..e483577021 --- /dev/null +++ b/hack/docs/daytona_profile_list.yaml @@ -0,0 +1,13 @@ +name: daytona profile list +synopsis: List profiles +usage: daytona profile list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona profile - Manage profiles diff --git a/hack/docs/daytona_provider.yaml b/hack/docs/daytona_provider.yaml new file mode 100644 index 0000000000..168c2228ed --- /dev/null +++ b/hack/docs/daytona_provider.yaml @@ -0,0 +1,12 @@ +name: daytona provider +synopsis: Manage providers +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona provider install - Install provider + - daytona provider list - List installed providers + - daytona provider uninstall - Uninstall provider + - daytona provider update - Update provider diff --git a/hack/docs/daytona_provider_install.yaml b/hack/docs/daytona_provider_install.yaml new file mode 100644 index 0000000000..29886e0613 --- /dev/null +++ b/hack/docs/daytona_provider_install.yaml @@ -0,0 +1,14 @@ +name: daytona provider install +synopsis: Install provider +usage: daytona provider install [flags] +options: + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona provider - Manage providers diff --git a/hack/docs/daytona_provider_list.yaml b/hack/docs/daytona_provider_list.yaml new file mode 100644 index 0000000000..9ffae1cfce --- /dev/null +++ b/hack/docs/daytona_provider_list.yaml @@ -0,0 +1,13 @@ +name: daytona provider list +synopsis: List installed providers +usage: daytona provider list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona provider - Manage providers diff --git a/hack/docs/daytona_provider_uninstall.yaml b/hack/docs/daytona_provider_uninstall.yaml new file mode 100644 index 0000000000..eb84417597 --- /dev/null +++ b/hack/docs/daytona_provider_uninstall.yaml @@ -0,0 +1,9 @@ +name: daytona provider uninstall +synopsis: Uninstall provider +usage: daytona provider uninstall [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona provider - Manage providers diff --git a/hack/docs/daytona_provider_update.yaml b/hack/docs/daytona_provider_update.yaml new file mode 100644 index 0000000000..cf042fcfb9 --- /dev/null +++ b/hack/docs/daytona_provider_update.yaml @@ -0,0 +1,14 @@ +name: daytona provider update +synopsis: Update provider +usage: daytona provider update [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Update all providers +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona provider - Manage providers diff --git a/hack/docs/daytona_purge.yaml b/hack/docs/daytona_purge.yaml new file mode 100644 index 0000000000..7d28219871 --- /dev/null +++ b/hack/docs/daytona_purge.yaml @@ -0,0 +1,20 @@ +name: daytona purge +synopsis: Purges all Daytona data from the current device +description: | + Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. +usage: daytona purge [flags] +options: + - name: force + shorthand: f + default_value: "false" + usage: Delete all targets by force + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Execute purge without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_serve.yaml b/hack/docs/daytona_serve.yaml new file mode 100644 index 0000000000..ed180bb7a8 --- /dev/null +++ b/hack/docs/daytona_serve.yaml @@ -0,0 +1,9 @@ +name: daytona serve +synopsis: Run the server process in the current terminal session +usage: daytona serve [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_server.yaml b/hack/docs/daytona_server.yaml new file mode 100644 index 0000000000..6f19f3150f --- /dev/null +++ b/hack/docs/daytona_server.yaml @@ -0,0 +1,20 @@ +name: daytona server +synopsis: Start the server process in daemon mode +usage: daytona server [flags] +options: + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Skip the confirmation prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona server config - Output local Daytona Server config + - daytona server configure - Configure Daytona Server + - daytona server logs - Output Daytona Server logs + - daytona server restart - Restarts the Daytona Server daemon + - daytona server start - Start the Daytona Server daemon + - daytona server stop - Stops the Daytona Server daemon diff --git a/hack/docs/daytona_server_config.yaml b/hack/docs/daytona_server_config.yaml new file mode 100644 index 0000000000..1fb4da88d6 --- /dev/null +++ b/hack/docs/daytona_server_config.yaml @@ -0,0 +1,13 @@ +name: daytona server config +synopsis: Output local Daytona Server config +usage: daytona server config [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_configure.yaml b/hack/docs/daytona_server_configure.yaml new file mode 100644 index 0000000000..877dc2399c --- /dev/null +++ b/hack/docs/daytona_server_configure.yaml @@ -0,0 +1,9 @@ +name: daytona server configure +synopsis: Configure Daytona Server +usage: daytona server configure [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_logs.yaml b/hack/docs/daytona_server_logs.yaml new file mode 100644 index 0000000000..eee2c53036 --- /dev/null +++ b/hack/docs/daytona_server_logs.yaml @@ -0,0 +1,21 @@ +name: daytona server logs +synopsis: Output Daytona Server logs +usage: daytona server logs [flags] +options: + - name: file + usage: Read specific log file + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs + - name: local + shorthand: l + default_value: "false" + usage: Read local server log files +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode + - daytona server logs list - Lists Daytona Server Log Files diff --git a/hack/docs/daytona_server_logs_list.yaml b/hack/docs/daytona_server_logs_list.yaml new file mode 100644 index 0000000000..cc9ff0349c --- /dev/null +++ b/hack/docs/daytona_server_logs_list.yaml @@ -0,0 +1,9 @@ +name: daytona server logs list +synopsis: Lists Daytona Server Log Files +usage: daytona server logs list [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server logs - Output Daytona Server logs diff --git a/hack/docs/daytona_server_restart.yaml b/hack/docs/daytona_server_restart.yaml new file mode 100644 index 0000000000..1b6ab08abe --- /dev/null +++ b/hack/docs/daytona_server_restart.yaml @@ -0,0 +1,9 @@ +name: daytona server restart +synopsis: Restarts the Daytona Server daemon +usage: daytona server restart [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_start.yaml b/hack/docs/daytona_server_start.yaml new file mode 100644 index 0000000000..16b6a1410e --- /dev/null +++ b/hack/docs/daytona_server_start.yaml @@ -0,0 +1,9 @@ +name: daytona server start +synopsis: Start the Daytona Server daemon +usage: daytona server start [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_server_stop.yaml b/hack/docs/daytona_server_stop.yaml new file mode 100644 index 0000000000..1d1b0005fd --- /dev/null +++ b/hack/docs/daytona_server_stop.yaml @@ -0,0 +1,9 @@ +name: daytona server stop +synopsis: Stops the Daytona Server daemon +usage: daytona server stop [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode diff --git a/hack/docs/daytona_ssh.yaml b/hack/docs/daytona_ssh.yaml new file mode 100644 index 0000000000..1d8b64e592 --- /dev/null +++ b/hack/docs/daytona_ssh.yaml @@ -0,0 +1,18 @@ +name: daytona ssh +synopsis: SSH into a workspace using the terminal +usage: daytona ssh [WORKSPACE] [CMD...] [flags] +options: + - name: option + shorthand: o + default_value: '[]' + usage: Specify SSH options in KEY=VALUE format. + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_start.yaml b/hack/docs/daytona_start.yaml new file mode 100644 index 0000000000..9078fc247e --- /dev/null +++ b/hack/docs/daytona_start.yaml @@ -0,0 +1,22 @@ +name: daytona start +synopsis: Start a workspace +usage: daytona start [WORKSPACE] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Start all targets + - name: code + shorthand: c + default_value: "false" + usage: Open the target in the IDE after target start + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_target-config.yaml b/hack/docs/daytona_target-config.yaml new file mode 100644 index 0000000000..60577252ee --- /dev/null +++ b/hack/docs/daytona_target-config.yaml @@ -0,0 +1,12 @@ +name: daytona target-config +synopsis: Manage target configs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona target-config list - List target configs + - daytona target-config remove - Remove target config + - daytona target-config set - Set target config + - daytona target-config set-default - Set default target config diff --git a/hack/docs/daytona_target-config_list.yaml b/hack/docs/daytona_target-config_list.yaml new file mode 100644 index 0000000000..a96c7f7908 --- /dev/null +++ b/hack/docs/daytona_target-config_list.yaml @@ -0,0 +1,13 @@ +name: daytona target-config list +synopsis: List target configs +usage: daytona target-config list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_remove.yaml b/hack/docs/daytona_target-config_remove.yaml new file mode 100644 index 0000000000..8ee216a64d --- /dev/null +++ b/hack/docs/daytona_target-config_remove.yaml @@ -0,0 +1,14 @@ +name: daytona target-config remove +synopsis: Remove target config +usage: daytona target-config remove [CONFIG_NAME] [flags] +options: + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Confirm deletion of all targets without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_set-default.yaml b/hack/docs/daytona_target-config_set-default.yaml new file mode 100644 index 0000000000..dc6fe9e01e --- /dev/null +++ b/hack/docs/daytona_target-config_set-default.yaml @@ -0,0 +1,9 @@ +name: daytona target-config set-default +synopsis: Set default target config +usage: daytona target-config set-default [CONFIG_NAME] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target-config_set.yaml b/hack/docs/daytona_target-config_set.yaml new file mode 100644 index 0000000000..21c4fa5447 --- /dev/null +++ b/hack/docs/daytona_target-config_set.yaml @@ -0,0 +1,9 @@ +name: daytona target-config set +synopsis: Set target config +usage: daytona target-config set [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target.yaml b/hack/docs/daytona_target.yaml new file mode 100644 index 0000000000..efa976f7e0 --- /dev/null +++ b/hack/docs/daytona_target.yaml @@ -0,0 +1,14 @@ +name: daytona target +synopsis: Manage targets +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona target delete - Delete a target + - daytona target info - Show target info + - daytona target list - List targets + - daytona target restart - Restart a target + - daytona target start - Start a target + - daytona target stop - Stop a target diff --git a/hack/docs/daytona_target_delete.yaml b/hack/docs/daytona_target_delete.yaml new file mode 100644 index 0000000000..e077d4a81b --- /dev/null +++ b/hack/docs/daytona_target_delete.yaml @@ -0,0 +1,22 @@ +name: daytona target delete +synopsis: Delete a target +usage: daytona target delete [TARGET] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Delete all targets + - name: force + shorthand: f + default_value: "false" + usage: Delete a target by force + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Confirm deletion without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_info.yaml b/hack/docs/daytona_target_info.yaml new file mode 100644 index 0000000000..b8305ad0cc --- /dev/null +++ b/hack/docs/daytona_target_info.yaml @@ -0,0 +1,13 @@ +name: daytona target info +synopsis: Show target info +usage: daytona target info [TARGET] [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_list.yaml b/hack/docs/daytona_target_list.yaml new file mode 100644 index 0000000000..7837a01f3b --- /dev/null +++ b/hack/docs/daytona_target_list.yaml @@ -0,0 +1,17 @@ +name: daytona target list +synopsis: List targets +usage: daytona target list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) + - name: verbose + shorthand: v + default_value: "false" + usage: Show verbose output +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_restart.yaml b/hack/docs/daytona_target_restart.yaml new file mode 100644 index 0000000000..ca315b438e --- /dev/null +++ b/hack/docs/daytona_target_restart.yaml @@ -0,0 +1,9 @@ +name: daytona target restart +synopsis: Restart a target +usage: daytona target restart [TARGET] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_start.yaml b/hack/docs/daytona_target_start.yaml new file mode 100644 index 0000000000..1803c22237 --- /dev/null +++ b/hack/docs/daytona_target_start.yaml @@ -0,0 +1,18 @@ +name: daytona target start +synopsis: Start a target +usage: daytona target start [TARGET] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Start all targets + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_stop.yaml b/hack/docs/daytona_target_stop.yaml new file mode 100644 index 0000000000..356033dafe --- /dev/null +++ b/hack/docs/daytona_target_stop.yaml @@ -0,0 +1,14 @@ +name: daytona target stop +synopsis: Stop a target +usage: daytona target stop [TARGET] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Stop all targets +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_telemetry.yaml b/hack/docs/daytona_telemetry.yaml new file mode 100644 index 0000000000..996ac41725 --- /dev/null +++ b/hack/docs/daytona_telemetry.yaml @@ -0,0 +1,10 @@ +name: daytona telemetry +synopsis: Manage telemetry collection +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona telemetry disable - Disable telemetry collection + - daytona telemetry enable - Enable telemetry collection diff --git a/hack/docs/daytona_telemetry_disable.yaml b/hack/docs/daytona_telemetry_disable.yaml new file mode 100644 index 0000000000..38039dca01 --- /dev/null +++ b/hack/docs/daytona_telemetry_disable.yaml @@ -0,0 +1,9 @@ +name: daytona telemetry disable +synopsis: Disable telemetry collection +usage: daytona telemetry disable [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona telemetry - Manage telemetry collection diff --git a/hack/docs/daytona_telemetry_enable.yaml b/hack/docs/daytona_telemetry_enable.yaml new file mode 100644 index 0000000000..a32bc5050e --- /dev/null +++ b/hack/docs/daytona_telemetry_enable.yaml @@ -0,0 +1,9 @@ +name: daytona telemetry enable +synopsis: Enable telemetry collection +usage: daytona telemetry enable [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona telemetry - Manage telemetry collection diff --git a/hack/docs/daytona_use.yaml b/hack/docs/daytona_use.yaml new file mode 100644 index 0000000000..171159b88a --- /dev/null +++ b/hack/docs/daytona_use.yaml @@ -0,0 +1,9 @@ +name: daytona use +synopsis: Use profile [PROFILE_NAME] +usage: daytona use [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_version.yaml b/hack/docs/daytona_version.yaml new file mode 100644 index 0000000000..02035a7170 --- /dev/null +++ b/hack/docs/daytona_version.yaml @@ -0,0 +1,9 @@ +name: daytona version +synopsis: Print the version number +usage: daytona version [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_whoami.yaml b/hack/docs/daytona_whoami.yaml new file mode 100644 index 0000000000..ff8fd58784 --- /dev/null +++ b/hack/docs/daytona_whoami.yaml @@ -0,0 +1,13 @@ +name: daytona whoami +synopsis: Display information about the active user +usage: daytona whoami [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_workspace-config.yaml b/hack/docs/daytona_workspace-config.yaml new file mode 100644 index 0000000000..9cfdaccbfc --- /dev/null +++ b/hack/docs/daytona_workspace-config.yaml @@ -0,0 +1,14 @@ +name: daytona workspace-config +synopsis: Manage workspace configs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona workspace-config add - Add a workspace config + - daytona workspace-config delete - Delete a workspace config + - daytona workspace-config info - Show workspace config info + - daytona workspace-config list - Lists workspace configs + - daytona workspace-config set-default - Set workspace config info + - daytona workspace-config update - Update a workspace config diff --git a/hack/docs/daytona_workspace-config_add.yaml b/hack/docs/daytona_workspace-config_add.yaml new file mode 100644 index 0000000000..60c7e5dd2a --- /dev/null +++ b/hack/docs/daytona_workspace-config_add.yaml @@ -0,0 +1,32 @@ +name: daytona workspace-config add +synopsis: Add a workspace config +usage: daytona workspace-config add [flags] +options: + - name: builder + usage: Specify the builder (currently auto/devcontainer/none) + - name: custom-image + usage: | + Create the workspace with the custom image passed as the flag value; Requires setting --custom-image-user flag as well + - name: custom-image-user + usage: | + Create the workspace with the custom image user passed as the flag value; Requires setting --custom-image flag as well + - name: devcontainer-path + usage: | + Automatically assign the devcontainer builder with the path passed as the flag value + - name: env + default_value: '[]' + usage: | + Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') + - name: git-provider-config + usage: Specify the Git provider configuration ID or alias + - name: manual + default_value: "false" + usage: Manually enter the Git repository + - name: name + usage: Specify the workspace config name +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_workspace-config_delete.yaml b/hack/docs/daytona_workspace-config_delete.yaml new file mode 100644 index 0000000000..cd1d8ca487 --- /dev/null +++ b/hack/docs/daytona_workspace-config_delete.yaml @@ -0,0 +1,22 @@ +name: daytona workspace-config delete +synopsis: Delete a workspace config +usage: daytona workspace-config delete [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Delete all workspace configs + - name: force + shorthand: f + default_value: "false" + usage: Force delete prebuild + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Confirm deletion without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_workspace-config_info.yaml b/hack/docs/daytona_workspace-config_info.yaml new file mode 100644 index 0000000000..3957065c22 --- /dev/null +++ b/hack/docs/daytona_workspace-config_info.yaml @@ -0,0 +1,13 @@ +name: daytona workspace-config info +synopsis: Show workspace config info +usage: daytona workspace-config info [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_workspace-config_list.yaml b/hack/docs/daytona_workspace-config_list.yaml new file mode 100644 index 0000000000..4e90b3054d --- /dev/null +++ b/hack/docs/daytona_workspace-config_list.yaml @@ -0,0 +1,13 @@ +name: daytona workspace-config list +synopsis: Lists workspace configs +usage: daytona workspace-config list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_workspace-config_set-default.yaml b/hack/docs/daytona_workspace-config_set-default.yaml new file mode 100644 index 0000000000..022dfb9c11 --- /dev/null +++ b/hack/docs/daytona_workspace-config_set-default.yaml @@ -0,0 +1,9 @@ +name: daytona workspace-config set-default +synopsis: Set workspace config info +usage: daytona workspace-config set-default [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_workspace-config_update.yaml b/hack/docs/daytona_workspace-config_update.yaml new file mode 100644 index 0000000000..04f4d07cb7 --- /dev/null +++ b/hack/docs/daytona_workspace-config_update.yaml @@ -0,0 +1,9 @@ +name: daytona workspace-config update +synopsis: Update a workspace config +usage: daytona workspace-config update [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona workspace-config - Manage workspace configs diff --git a/internal/cmd/tailscale/forward.go b/internal/cmd/tailscale/forward.go index 9918374333..b69f4179f2 100644 --- a/internal/cmd/tailscale/forward.go +++ b/internal/cmd/tailscale/forward.go @@ -11,11 +11,11 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "tailscale.com/tsnet" ) -func ForwardPort(targetId, workspaceName string, targetPort uint16, profile config.Profile) (*uint16, chan error) { +func ForwardPort(workspaceId string, targetPort uint16, profile config.Profile) (*uint16, chan error) { hostPort := targetPort errChan := make(chan error) var err error @@ -47,7 +47,7 @@ func ForwardPort(targetId, workspaceName string, targetPort uint16, profile conf return } - targetUrl := fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(targetId, workspaceName), targetPort) + targetUrl := fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(workspaceId), targetPort) go handlePortConnection(conn, tsConn, targetUrl, errChan) } diff --git a/internal/testing/agent/mocks/apiserver.go b/internal/testing/agent/mocks/apiserver.go index 79b224ddb5..4ef0a85a6f 100644 --- a/internal/testing/agent/mocks/apiserver.go +++ b/internal/testing/agent/mocks/apiserver.go @@ -12,11 +12,10 @@ import ( "testing" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/target" "github.com/gin-gonic/gin" ) -func NewMockRestServer(t *testing.T, target *target.Target) *httptest.Server { +func NewMockRestServer(t *testing.T) *httptest.Server { router := gin.Default() serverController := router.Group("/server") { @@ -37,13 +36,6 @@ func NewMockRestServer(t *testing.T, target *target.Target) *httptest.Server { }) } - targetController := router.Group("/target") - { - targetController.GET("/:targetId", func(ctx *gin.Context) { - ctx.JSON(http.StatusOK, target) - }) - } - gitproviderController := router.Group("/gitprovider") { gitproviderController.GET("/for-url/:url", func(ctx *gin.Context) { diff --git a/internal/testing/docker/mocks/client.go b/internal/testing/docker/mocks/client.go index 86a6241fde..eea229c2ff 100644 --- a/internal/testing/docker/mocks/client.go +++ b/internal/testing/docker/mocks/client.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/git/mocks/gitservice.go b/internal/testing/git/mocks/gitservice.go index 74cba6abc6..bdcf4e2ebd 100644 --- a/internal/testing/git/mocks/gitservice.go +++ b/internal/testing/git/mocks/gitservice.go @@ -7,7 +7,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/server/targets/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go index 130d2028d4..04b637d924 100644 --- a/internal/testing/server/targets/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/containerconfig" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/server/targets/mocks/provisioner.go b/internal/testing/server/targets/mocks/provisioner.go index cdae7d0e53..5815acf5a8 100644 --- a/internal/testing/server/targets/mocks/provisioner.go +++ b/internal/testing/server/targets/mocks/provisioner.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/stretchr/testify/mock" ) @@ -67,3 +67,8 @@ func (p *mockProvisioner) StopTarget(target *target.Target, targetConfig *provid args := p.Called(target, targetConfig) return args.Error(0) } + +func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { + args := p.Called(ctx, w, targetConfig) + return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) +} diff --git a/internal/testing/server/targets/mocks/workspace_config.go b/internal/testing/server/targets/mocks/workspace_config.go index 2a527b6712..c1c239d01f 100644 --- a/internal/testing/server/targets/mocks/workspace_config.go +++ b/internal/testing/server/targets/mocks/workspace_config.go @@ -6,8 +6,8 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/config" ) var MockWorkspaceConfig = config.WorkspaceConfig{ diff --git a/internal/testing/server/targets/mocks/workspace_config_service.go b/internal/testing/server/targets/mocks/workspace_config_service.go index 60767d4d9c..adc65f422a 100644 --- a/internal/testing/server/targets/mocks/workspace_config_service.go +++ b/internal/testing/server/targets/mocks/workspace_config_service.go @@ -8,7 +8,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" "github.com/stretchr/testify/mock" ) diff --git a/internal/testing/server/workspaceconfig/store.go b/internal/testing/server/workspaceconfig/store.go index 164aeda53a..747031ca45 100644 --- a/internal/testing/server/workspaceconfig/store.go +++ b/internal/testing/server/workspaceconfig/store.go @@ -8,7 +8,7 @@ package workspaceconfig import ( "fmt" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" ) type InMemoryWorkspaceConfigStore struct { diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go new file mode 100644 index 0000000000..fa705ebaa4 --- /dev/null +++ b/internal/testing/server/workspaces/store.go @@ -0,0 +1,51 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import "github.com/daytonaio/daytona/pkg/workspace" + +type InMemoryWorkspaceStore struct { + workspaces map[string]*workspace.Workspace +} + +func NewInMemoryWorkspaceStore() workspace.Store { + return &InMemoryWorkspaceStore{ + workspaces: make(map[string]*workspace.Workspace), + } +} + +func (s *InMemoryWorkspaceStore) List() ([]*workspace.WorkspaceViewDTO, error) { + workspaceViewDTOs := []*workspace.WorkspaceViewDTO{} + for _, w := range s.workspaces { + workspaceViewDTOs = append(workspaceViewDTOs, &workspace.WorkspaceViewDTO{Workspace: *w}) + } + + return workspaceViewDTOs, nil +} + +func (s *InMemoryWorkspaceStore) Find(idOrName string) (*workspace.WorkspaceViewDTO, error) { + t, ok := s.workspaces[idOrName] + if !ok { + for _, w := range s.workspaces { + if w.Name == idOrName { + return &workspace.WorkspaceViewDTO{Workspace: *w}, nil + } + } + return nil, workspace.ErrWorkspaceNotFound + } + + return &workspace.WorkspaceViewDTO{Workspace: *t}, nil +} + +func (s *InMemoryWorkspaceStore) Save(workspace *workspace.Workspace) error { + s.workspaces[workspace.Id] = workspace + return nil +} + +func (s *InMemoryWorkspaceStore) Delete(workspace *workspace.Workspace) error { + delete(s.workspaces, workspace.Id) + return nil +} diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index a471475e7b..5a89c6716e 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -5,7 +5,6 @@ package apiclient import ( "context" - "errors" "fmt" "net/http" "net/url" @@ -131,32 +130,18 @@ func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, error return target, nil } -func GetFirstWorkspaceName(targetId string, workspaceName string, profile *config.Profile) (string, error) { +func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceDTO, error) { ctx := context.Background() - apiClient, err := GetApiClient(profile) + apiClient, err := GetApiClient(nil) if err != nil { - return "", err + return nil, err } - targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() + workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceNameOrId).Verbose(verbose).Execute() if err != nil { - return "", HandleErrorResponse(res, err) - } - - if workspaceName == "" { - if len(targetInfo.Workspaces) == 0 { - return "", errors.New("no workspaces found in target") - } - - return targetInfo.Workspaces[0].Name, nil - } - - for _, workspace := range targetInfo.Workspaces { - if workspace.Name == workspaceName { - return workspace.Name, nil - } + return nil, HandleErrorResponse(res, err) } - return "", errors.New("workspace not found in target") + return workspace, nil } diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go index b47072f0fa..c28a74c0f2 100644 --- a/internal/util/apiclient/conversion/workspace.go +++ b/internal/util/apiclient/conversion/workspace.go @@ -6,14 +6,14 @@ package conversion import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" - workspace_dto "github.com/daytonaio/daytona/pkg/server/targets/dto" wc_dto "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + workspace_dto "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/config" ) -func ToWorkspace(workspaceDTO *apiclient.Workspace) *workspace.Workspace { +func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *workspace.Workspace { if workspaceDTO == nil { return nil } @@ -50,12 +50,12 @@ func ToWorkspace(workspaceDTO *apiclient.Workspace) *workspace.Workspace { } workspace := &workspace.Workspace{ + Id: workspaceDTO.Id, Name: workspaceDTO.Name, Image: workspaceDTO.Image, User: workspaceDTO.User, BuildConfig: workspaceBuild, Repository: repository, - TargetConfig: workspaceDTO.TargetConfig, TargetId: workspaceDTO.TargetId, State: workspaceState, GitProviderConfigId: workspaceDTO.GitProviderConfigId, @@ -174,10 +174,12 @@ func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) func CreateDtoToWorkspace(createWorkspaceDto workspace_dto.CreateWorkspaceDTO) *workspace.Workspace { w := &workspace.Workspace{ + Id: createWorkspaceDto.Id, Name: createWorkspaceDto.Name, BuildConfig: createWorkspaceDto.BuildConfig, Repository: createWorkspaceDto.Source.Repository, EnvVars: createWorkspaceDto.EnvVars, + TargetId: createWorkspaceDto.TargetId, GitProviderConfigId: createWorkspaceDto.GitProviderConfigId, } diff --git a/internal/util/apiclient/websocket_log_reader.go b/internal/util/apiclient/websocket_log_reader.go index 14b4ee2e8c..ba9989a66c 100644 --- a/internal/util/apiclient/websocket_log_reader.go +++ b/internal/util/apiclient/websocket_log_reader.go @@ -6,7 +6,6 @@ package apiclient import ( "context" "fmt" - "sync" "time" "github.com/daytonaio/daytona/cmd/daytona/config" @@ -18,62 +17,46 @@ import ( var targetLogsStarted bool -func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId string, workspaceNames []string, follow, showTargetLogs bool, from *time.Time) { - var wg sync.WaitGroup +func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId string, follow bool, from *time.Time) { query := "" if follow { query = "follow=true" } - if !showTargetLogs { - targetLogsStarted = true - } - logs_view.CalculateLongestPrefixLength(workspaceNames) - - for index, workspaceName := range workspaceNames { - wg.Add(1) - go func(workspaceName string, from *time.Time) { - defer wg.Done() - - for { - // Make sure target logs started before showing any workspace logs - if !targetLogsStarted { - time.Sleep(250 * time.Millisecond) - continue - } - - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s/%s", targetId, workspaceName), &activeProfile, &query) - // We want to retry getting the logs if it fails - if err != nil { - log.Trace(HandleErrorResponse(res, err)) - time.Sleep(500 * time.Millisecond) - continue - } + for { + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", targetId), &activeProfile, &query) + // We want to retry getting the logs if it fails + if err != nil { + log.Trace(HandleErrorResponse(res, err)) + time.Sleep(250 * time.Millisecond) + continue + } - readJSONLog(ctx, ws, index, from) - ws.Close() - break - } - }(workspaceName, from) + readJSONLog(ctx, ws, logs_view.STATIC_INDEX, from) + ws.Close() + break } +} - if showTargetLogs { - for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", targetId), &activeProfile, &query) - // We want to retry getting the logs if it fails - if err != nil { - log.Trace(HandleErrorResponse(res, err)) - time.Sleep(250 * time.Millisecond) - continue - } +func ReadWorkspaceLogs(ctx context.Context, index int, activeProfile config.Profile, workspaceId string, follow bool, from *time.Time) { + query := "" + if follow { + query = "follow=true" + } - readJSONLog(ctx, ws, logs_view.STATIC_INDEX, from) - ws.Close() - break + for { + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s", workspaceId), &activeProfile, &query) + // We want to retry getting the logs if it fails + if err != nil { + log.Trace(HandleErrorResponse(res, err)) + time.Sleep(500 * time.Millisecond) + continue } - } - wg.Wait() + readJSONLog(ctx, ws, index, from) + ws.Close() + break + } } func ReadBuildLogs(ctx context.Context, activeProfile config.Profile, buildId string, query string) { diff --git a/internal/util/path.go b/internal/util/path.go index 62b51be06b..b367946653 100644 --- a/internal/util/path.go +++ b/internal/util/path.go @@ -11,13 +11,13 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func GetHomeDir(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string) (string, error) { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) +func GetHomeDir(activeProfile config.Profile, workspaceId string, gpgKey string) (string, error) { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return "", err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) homeDir, err := exec.Command("ssh", workspaceHostname, "echo", "$HOME").Output() if err != nil { @@ -27,13 +27,13 @@ func GetHomeDir(activeProfile config.Profile, targetId string, workspaceName str return strings.TrimRight(string(homeDir), "\n"), nil } -func GetWorkspaceDir(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string) (string, error) { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) +func GetWorkspaceDir(activeProfile config.Profile, workspaceId string, gpgKey string) (string, error) { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return "", err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) daytonaWorkspaceDir, err := exec.Command("ssh", workspaceHostname, "echo", "$DAYTONA_WORKSPACE_DIR").Output() if err != nil { @@ -44,10 +44,10 @@ func GetWorkspaceDir(activeProfile config.Profile, targetId string, workspaceNam return strings.TrimRight(string(daytonaWorkspaceDir), "\n"), nil } - homeDir, err := GetHomeDir(activeProfile, targetId, workspaceName, gpgKey) + homeDir, err := GetHomeDir(activeProfile, workspaceId, gpgKey) if err != nil { return "", err } - return path.Join(homeDir, workspaceName), nil + return path.Join(homeDir, workspaceId), nil } diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index bb89156166..542e79a981 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -19,7 +19,7 @@ import ( agent_config "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/go-git/go-git/v5/plumbing/transport/http" log "github.com/sirupsen/logrus" ) @@ -72,13 +72,8 @@ func (a *Agent) startWorkspaceMode() error { } if a.Config.SkipClone == "" { - workspace, err := a.getWorkspace() - if err != nil { - return err - } - // Ignoring error because we don't want to fail if the git provider is not found - gitProvider, _ := a.getGitProvider(workspace.Repository.Url) + gitProvider, _ := a.getGitProvider(a.Workspace.Repository.Url) var auth *http.BasicAuth if gitProvider != nil { @@ -97,7 +92,7 @@ func (a *Agent) startWorkspaceMode() error { if stat, err := os.Stat(a.Config.WorkspaceDir); err == nil { ownerUid := stat.Sys().(*syscall.Stat_t).Uid if ownerUid != uint32(os.Getuid()) { - chownCmd := exec.Command("sudo", "chown", "-R", fmt.Sprintf("%s:%s", workspace.User, workspace.User), a.Config.WorkspaceDir) + chownCmd := exec.Command("sudo", "chown", "-R", fmt.Sprintf("%s:%s", a.Workspace.User, a.Workspace.User), a.Config.WorkspaceDir) err = chownCmd.Run() if err != nil { log.Error(err) @@ -106,7 +101,7 @@ func (a *Agent) startWorkspaceMode() error { } log.Info("Cloning repository...") - err = a.Git.CloneRepository(workspace.Repository, auth) + err = a.Git.CloneRepository(a.Workspace.Repository, auth) if err != nil { log.Error(fmt.Sprintf("failed to clone repository: %s", err)) } else { @@ -157,28 +152,6 @@ func (a *Agent) startWorkspaceMode() error { return nil } -func (a *Agent) getWorkspace() (*workspace.Workspace, error) { - ctx := context.Background() - - apiClient, err := apiclient_util.GetAgentApiClient(a.Config.Server.ApiUrl, a.Config.Server.ApiKey, a.Config.ClientId, a.TelemetryEnabled) - if err != nil { - return nil, err - } - - target, res, err := apiClient.TargetAPI.GetTarget(ctx, a.Config.TargetId).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - for _, workspace := range target.Workspaces { - if workspace.Name == a.Config.WorkspaceName { - return conversion.ToWorkspace(&workspace), nil - } - } - - return nil, errors.New("workspace not found") -} - func (a *Agent) getGitProvider(repoUrl string) (*apiclient.GitProvider, error) { ctx := context.Background() @@ -264,7 +237,7 @@ func (a *Agent) updateWorkspaceState() error { } uptime := a.uptime() - res, err := apiClient.TargetAPI.SetWorkspaceState(context.Background(), a.Config.TargetId, a.Config.WorkspaceName).SetState(apiclient.SetWorkspaceState{ + res, err := apiClient.WorkspaceAPI.SetWorkspaceState(context.Background(), a.Config.WorkspaceId).SetState(apiclient.SetWorkspaceState{ Uptime: uptime, GitStatus: conversion.ToGitStatusDTO(gitStatus), }).Execute() diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 6f67b3746c..c603e5d727 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -17,18 +17,18 @@ import ( "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) var workspace1 = &workspace.Workspace{ + Id: "123", Name: "test", Repository: &gitprovider.GitRepository{ Id: "123", Url: "https://github.com/daytonaio/daytona", Name: "daytona", }, - TargetId: "123", - TargetConfig: "local", + TargetId: "123", State: &workspace.WorkspaceState{ UpdatedAt: "123", Uptime: 148, @@ -40,9 +40,6 @@ var target1 = &target.Target{ Id: "123", Name: "test", TargetConfig: "local", - Workspaces: []*workspace.Workspace{ - workspace1, - }, } var gitStatus1 = &workspace.GitStatus{ @@ -56,8 +53,8 @@ var gitStatus1 = &workspace.GitStatus{ } var mockConfig = &config.Config{ - TargetId: target1.Id, - WorkspaceName: workspace1.Name, + TargetId: target1.Id, + WorkspaceId: workspace1.Id, Server: config.DaytonaServerConfig{ ApiKey: "test-api-key", }, @@ -68,7 +65,7 @@ func TestAgent(t *testing.T) { buf := bytes.Buffer{} log.SetOutput(&buf) - apiServer := mocks.NewMockRestServer(t, target1) + apiServer := mocks.NewMockRestServer(t) defer apiServer.Close() mockConfig.Server.ApiUrl = apiServer.URL @@ -91,6 +88,7 @@ func TestAgent(t *testing.T) { Ssh: mockSshServer, Tailscale: mockTailscaleServer, Toolbox: mockToolboxServer, + Workspace: workspace1, } t.Run("Start agent", func(t *testing.T) { diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index 17bed4bfb2..6b3e285f3b 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -21,13 +21,13 @@ type DaytonaServerConfig struct { } type Config struct { - WorkspaceDir string - ClientId string `envconfig:"DAYTONA_CLIENT_ID" validate:"required"` - WorkspaceName string `envconfig:"DAYTONA_WORKSPACE_NAME"` - TargetId string `envconfig:"DAYTONA_TARGET_ID" validate:"required"` - LogFilePath *string `envconfig:"DAYTONA_AGENT_LOG_FILE_PATH"` - Server DaytonaServerConfig - Mode Mode + WorkspaceDir string + ClientId string `envconfig:"DAYTONA_CLIENT_ID" validate:"required"` + WorkspaceId string `envconfig:"DAYTONA_WORKSPACE_ID"` + TargetId string `envconfig:"DAYTONA_TARGET_ID" validate:"required"` + LogFilePath *string `envconfig:"DAYTONA_AGENT_LOG_FILE_PATH"` + Server DaytonaServerConfig + Mode Mode SkipClone string `envconfig:"DAYTONA_SKIP_CLONE"` } @@ -66,8 +66,8 @@ func GetConfig(mode Mode) (*Config, error) { } if config.Mode == ModeWorkspace { - if config.WorkspaceName == "" { - return nil, errors.New("DAYTONA_WORKSPACE_NAME is required in workspace mode") + if config.WorkspaceId == "" { + return nil, errors.New("DAYTONA_WORKSPACE_ID is required in workspace mode") } } diff --git a/pkg/agent/types.go b/pkg/agent/types.go index f01687761a..02405a531f 100644 --- a/pkg/agent/types.go +++ b/pkg/agent/types.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/git" + "github.com/daytonaio/daytona/pkg/workspace" ) type SshServer interface { @@ -32,4 +33,5 @@ type Agent struct { LogWriter io.Writer TelemetryEnabled bool startTime time.Time + Workspace *workspace.Workspace } diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index a2cbc435e2..2b724d0e16 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server" builds_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" "github.com/gin-gonic/gin" ) diff --git a/pkg/api/controllers/log/websocket.go b/pkg/api/controllers/log/websocket.go index 1ab58f1473..65c2fbc920 100644 --- a/pkg/api/controllers/log/websocket.go +++ b/pkg/api/controllers/log/websocket.go @@ -152,27 +152,26 @@ func ReadTargetLog(ginCtx *gin.Context) { if retry { for { - wsLogReader, err := server.TargetService.GetTargetLogReader(targetId) + targetLogReader, err := server.TargetService.GetTargetLogReader(targetId) if err == nil { - ReadLog(ginCtx, wsLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ginCtx, targetLogReader, util.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) } } - wsLogReader, err := server.TargetService.GetTargetLogReader(targetId) + targetLogReader, err := server.TargetService.GetTargetLogReader(targetId) if err != nil { ginCtx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ginCtx, wsLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ginCtx, targetLogReader, util.ReadJSONLog, writeJSONToWs) } func ReadWorkspaceLog(ginCtx *gin.Context) { - targetId := ginCtx.Param("targetId") - workspaceName := ginCtx.Param("workspaceName") + workspaceId := ginCtx.Param("workspaceId") retryQuery := ginCtx.DefaultQuery("retry", "true") retry := retryQuery == "true" @@ -180,7 +179,7 @@ func ReadWorkspaceLog(ginCtx *gin.Context) { if retry { for { - workspaceLogReader, err := server.TargetService.GetWorkspaceLogReader(targetId, workspaceName) + workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(workspaceId) if err == nil { ReadLog(ginCtx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) return @@ -189,7 +188,7 @@ func ReadWorkspaceLog(ginCtx *gin.Context) { } } - workspaceLogReader, err := server.TargetService.GetWorkspaceLogReader(targetId, workspaceName) + workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(workspaceId) if err != nil { ginCtx.AbortWithError(http.StatusInternalServerError, err) return diff --git a/pkg/api/controllers/target/dto/dto.go b/pkg/api/controllers/target/dto/dto.go index 487635ac46..cc9237f7d9 100644 --- a/pkg/api/controllers/target/dto/dto.go +++ b/pkg/api/controllers/target/dto/dto.go @@ -3,7 +3,7 @@ package dto -import "github.com/daytonaio/daytona/pkg/target/workspace" +import "github.com/daytonaio/daytona/pkg/workspace" type SetWorkspaceState struct { Uptime uint64 `json:"uptime" validate:"required"` diff --git a/pkg/api/controllers/target/start.go b/pkg/api/controllers/target/start.go index d38ae9d782..0104bdcf4e 100644 --- a/pkg/api/controllers/target/start.go +++ b/pkg/api/controllers/target/start.go @@ -34,29 +34,3 @@ func StartTarget(ctx *gin.Context) { ctx.Status(200) } - -// StartWorkspace godoc -// -// @Tags target -// @Summary Start workspace -// @Description Start workspace -// @Param targetId path string true "Target ID or Name" -// @Param workspaceId path string true "Workspace ID" -// @Success 200 -// @Router /target/{targetId}/{workspaceId}/start [post] -// -// @id StartWorkspace -func StartWorkspace(ctx *gin.Context) { - targetId := ctx.Param("targetId") - workspaceId := ctx.Param("workspaceId") - - server := server.GetInstance(nil) - - err := server.TargetService.StartWorkspace(ctx.Request.Context(), targetId, workspaceId) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start workspace %s: %w", workspaceId, err)) - return - } - - ctx.Status(200) -} diff --git a/pkg/api/controllers/target/stop.go b/pkg/api/controllers/target/stop.go index be8a694384..681aaf511d 100644 --- a/pkg/api/controllers/target/stop.go +++ b/pkg/api/controllers/target/stop.go @@ -34,29 +34,3 @@ func StopTarget(ctx *gin.Context) { ctx.Status(200) } - -// StopWorkspace godoc -// -// @Tags target -// @Summary Stop workspace -// @Description Stop workspace -// @Param targetId path string true "Target ID or Name" -// @Param workspaceId path string true "Workspace ID" -// @Success 200 -// @Router /target/{targetId}/{workspaceId}/stop [post] -// -// @id StopWorkspace -func StopWorkspace(ctx *gin.Context) { - targetId := ctx.Param("targetId") - workspaceId := ctx.Param("workspaceId") - - server := server.GetInstance(nil) - - err := server.TargetService.StopWorkspace(ctx.Request.Context(), targetId, workspaceId) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %w", workspaceId, err)) - return - } - - ctx.Status(200) -} diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go new file mode 100644 index 0000000000..4d0740cbb7 --- /dev/null +++ b/pkg/api/controllers/workspace/create.go @@ -0,0 +1,43 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/gin-gonic/gin" +) + +// CreateWorkspace godoc +// +// @Tags workspace +// @Summary Create a workspace +// @Description Create a workspace +// @Param workspace body CreateWorkspaceDTO true "Create workspace" +// @Produce json +// @Success 200 {object} WorkspaceViewDTO +// @Router /workspace [post] +// +// @id CreateWorkspace +func CreateWorkspace(ctx *gin.Context) { + var createWorkspaceReq dto.CreateWorkspaceDTO + err := ctx.BindJSON(&createWorkspaceReq) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + w, err := server.WorkspaceService.CreateWorkspace(ctx.Request.Context(), createWorkspaceReq) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create workspace: %w", err)) + return + } + + ctx.JSON(200, w) +} diff --git a/pkg/api/controllers/workspace/dto/dto.go b/pkg/api/controllers/workspace/dto/dto.go new file mode 100644 index 0000000000..cc9237f7d9 --- /dev/null +++ b/pkg/api/controllers/workspace/dto/dto.go @@ -0,0 +1,11 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import "github.com/daytonaio/daytona/pkg/workspace" + +type SetWorkspaceState struct { + Uptime uint64 `json:"uptime" validate:"required"` + GitStatus *workspace.GitStatus `json:"gitStatus,omitempty" validate:"optional"` +} // @name SetWorkspaceState diff --git a/pkg/api/controllers/workspace/remove.go b/pkg/api/controllers/workspace/remove.go new file mode 100644 index 0000000000..0c33d6804a --- /dev/null +++ b/pkg/api/controllers/workspace/remove.go @@ -0,0 +1,55 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "errors" + "fmt" + "net/http" + "strconv" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// RemoveWorkspace godoc +// +// @Tags workspace +// @Summary Remove workspace +// @Description Remove workspace +// @Param workspaceId path string true "Workspace ID" +// @Param force query bool false "Force" +// @Success 200 +// @Router /workspace/{workspaceId} [delete] +// +// @id RemoveWorkspace +func RemoveWorkspace(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + forceQuery := ctx.Query("force") + var err error + force := false + + if forceQuery != "" { + force, err = strconv.ParseBool(forceQuery) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) + return + } + } + + server := server.GetInstance(nil) + + if force { + err = server.WorkspaceService.ForceRemoveWorkspace(ctx.Request.Context(), workspaceId) + } else { + err = server.WorkspaceService.RemoveWorkspace(ctx.Request.Context(), workspaceId) + } + + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove workspace: %w", err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/workspace/start.go b/pkg/api/controllers/workspace/start.go new file mode 100644 index 0000000000..164e0ac29f --- /dev/null +++ b/pkg/api/controllers/workspace/start.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// StartWorkspace godoc +// +// @Tags workspace +// @Summary Start workspace +// @Description Start workspace +// @Param workspaceId path string true "Workspace ID or Name" +// @Success 200 +// @Router /workspace/{workspaceId}/start [post] +// +// @id StartWorkspace +func StartWorkspace(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + server := server.GetInstance(nil) + + err := server.WorkspaceService.StartWorkspace(ctx.Request.Context(), workspaceId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start workspace %s: %w", workspaceId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/target/workspace.go b/pkg/api/controllers/workspace/state.go similarity index 74% rename from pkg/api/controllers/target/workspace.go rename to pkg/api/controllers/workspace/state.go index 002817f6ce..8db98f4255 100644 --- a/pkg/api/controllers/target/workspace.go +++ b/pkg/api/controllers/workspace/state.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "fmt" @@ -10,24 +10,22 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/gin-gonic/gin" ) // SetWorkspaceState godoc // -// @Tags target +// @Tags workspace // @Summary Set workspace state // @Description Set workspace state -// @Param targetId path string true "Target ID or Name" // @Param workspaceId path string true "Workspace ID" // @Param setState body SetWorkspaceState true "Set State" // @Success 200 -// @Router /target/{targetId}/{workspaceId}/state [post] +// @Router /workspace/{workspaceId}/state [post] // // @id SetWorkspaceState func SetWorkspaceState(ctx *gin.Context) { - targetId := ctx.Param("targetId") workspaceId := ctx.Param("workspaceId") var setWorkspaceStateDTO dto.SetWorkspaceState @@ -39,13 +37,13 @@ func SetWorkspaceState(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.TargetService.SetWorkspaceState(targetId, workspaceId, &workspace.WorkspaceState{ + _, err = server.WorkspaceService.SetWorkspaceState(workspaceId, &workspace.WorkspaceState{ Uptime: setWorkspaceStateDTO.Uptime, UpdatedAt: time.Now().Format(time.RFC1123), GitStatus: setWorkspaceStateDTO.GitStatus, }) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop target %s: %w", targetId, err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set workspace state for %s: %w", workspaceId, err)) return } diff --git a/pkg/api/controllers/workspace/stop.go b/pkg/api/controllers/workspace/stop.go new file mode 100644 index 0000000000..84e43ea9db --- /dev/null +++ b/pkg/api/controllers/workspace/stop.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// StopWorkspace godoc +// +// @Tags workspace +// @Summary Stop workspace +// @Description Stop workspace +// @Param workspaceId path string true "Workspace ID or Name" +// @Success 200 +// @Router /workspace/{workspaceId}/stop [post] +// +// @id StopWorkspace +func StopWorkspace(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + server := server.GetInstance(nil) + + err := server.WorkspaceService.StopWorkspace(ctx.Request.Context(), workspaceId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %w", workspaceId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/workspace/toolbox/fs.go b/pkg/api/controllers/workspace/toolbox/fs.go index 35854ecd6e..7c61e91e93 100644 --- a/pkg/api/controllers/workspace/toolbox/fs.go +++ b/pkg/api/controllers/workspace/toolbox/fs.go @@ -9,14 +9,13 @@ import "github.com/gin-gonic/gin" // // @Tags workspace toolbox // @Summary Create folder -// @Description Create folder inside workspace project +// @Description Create folder inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Param mode query string true "Mode" // @Success 201 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/folder [post] +// @Router /workspace/{workspaceId}/toolbox/files/folder [post] // // @id FsCreateFolder func FsCreateFolder(ctx *gin.Context) { @@ -27,13 +26,12 @@ func FsCreateFolder(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Delete file -// @Description Delete file inside workspace project +// @Description Delete file inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Success 204 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files [delete] +// @Router /workspace/{workspaceId}/toolbox/files [delete] // // @id FsDeleteFile func FsDeleteFile(ctx *gin.Context) { @@ -44,13 +42,12 @@ func FsDeleteFile(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Download file -// @Description Download file from workspace project +// @Description Download file from a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Success 200 {file} file "response contains the file" -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/download [get] +// @Router /workspace/{workspaceId}/toolbox/files/download [get] // // @id FsDownloadFile func FsDownloadFile(ctx *gin.Context) { @@ -61,14 +58,13 @@ func FsDownloadFile(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Search for text/pattern in files -// @Description Search for text/pattern inside workspace project files +// @Description Search for text/pattern inside a workspace files // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Param pattern query string true "Pattern" // @Success 200 {array} Match -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/find [get] +// @Router /workspace/{workspaceId}/toolbox/files/find [get] // // @id FsFindInFiles func FsFindInFiles(ctx *gin.Context) { @@ -79,13 +75,12 @@ func FsFindInFiles(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Get file info -// @Description Get file info inside workspace project +// @Description Get file info inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Success 200 {object} FileInfo -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/info [get] +// @Router /workspace/{workspaceId}/toolbox/files/info [get] // // @id FsGetFileDetails func FsGetFileDetails(ctx *gin.Context) { @@ -96,13 +91,12 @@ func FsGetFileDetails(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary List files -// @Description List files inside workspace project +// @Description List files inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string false "Path" // @Success 200 {array} FileInfo -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files [get] +// @Router /workspace/{workspaceId}/toolbox/files [get] // // @id FsListFiles func FsListFiles(ctx *gin.Context) { @@ -113,14 +107,13 @@ func FsListFiles(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Create folder -// @Description Create folder inside workspace project +// @Description Create folder inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param source query string true "Source path" // @Param destination query string true "Destination path" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/move [post] +// @Router /workspace/{workspaceId}/toolbox/files/move [post] // // @id FsMoveFile func FsMoveFile(ctx *gin.Context) { @@ -131,13 +124,12 @@ func FsMoveFile(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Repleace text/pattern in files -// @Description Repleace text/pattern in mutilple files inside workspace project +// @Description Repleace text/pattern in mutilple files inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param replace body ReplaceRequest true "ReplaceParams" // @Success 200 {array} ReplaceResult -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/replace [post] +// @Router /workspace/{workspaceId}/toolbox/files/replace [post] // // @id FsReplaceInFiles func FsReplaceInFiles(ctx *gin.Context) { @@ -148,14 +140,13 @@ func FsReplaceInFiles(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Search for files -// @Description Search for files inside workspace project +// @Description Search for files inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Param pattern query string true "Pattern" // @Success 200 {object} SearchFilesResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/search [get] +// @Router /workspace/{workspaceId}/toolbox/files/search [get] // // @id FsSearchFiles func FsSearchFiles(ctx *gin.Context) { @@ -166,16 +157,15 @@ func FsSearchFiles(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Set file owner/group/permissions -// @Description Set file owner/group/permissions inside workspace project +// @Description Set file owner/group/permissions inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Param owner query string false "Owner" // @Param group query string false "Group" // @Param mode query string false "Mode" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/permissions [post] +// @Router /workspace/{workspaceId}/toolbox/files/permissions [post] // // @id FsSetFilePermissions func FsSetFilePermissions(ctx *gin.Context) { @@ -186,14 +176,13 @@ func FsSetFilePermissions(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Upload file -// @Description Upload file inside workspace project +// @Description Upload file inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path" // @Param file formData file true "File" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/files/upload [post] +// @Router /workspace/{workspaceId}/toolbox/files/upload [post] // // @id FsUploadFile func FsUploadFile(ctx *gin.Context) { diff --git a/pkg/api/controllers/workspace/toolbox/git.go b/pkg/api/controllers/workspace/toolbox/git.go index ac25efb75a..62f81f6e0e 100644 --- a/pkg/api/controllers/workspace/toolbox/git.go +++ b/pkg/api/controllers/workspace/toolbox/git.go @@ -12,10 +12,9 @@ import "github.com/gin-gonic/gin" // @Description Add files to git commit // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body GitAddRequest true "GitAddRequest" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/add [post] +// @Router /workspace/{workspaceId}/toolbox/git/add [post] // // @id GitAddFiles func GitAddFiles(ctx *gin.Context) { @@ -26,13 +25,12 @@ func GitAddFiles(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Clone git repository -// @Description Clone git repository inside workspace project +// @Description Clone git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body GitCloneRequest true "GitCloneRequest" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/clone [post] +// @Router /workspace/{workspaceId}/toolbox/git/clone [post] // // @id GitCloneRepository func GitCloneRepository(ctx *gin.Context) { @@ -43,13 +41,12 @@ func GitCloneRepository(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Commit changes -// @Description Commit changes to git repository inside workspace project +// @Description Commit changes to git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body GitCommitRequest true "GitCommitRequest" // @Success 200 {object} GitCommitResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/commit [post] +// @Router /workspace/{workspaceId}/toolbox/git/commit [post] // // @id GitCommitChanges func GitCommitChanges(ctx *gin.Context) { @@ -60,13 +57,12 @@ func GitCommitChanges(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Create branch -// @Description Create branch on git repository inside workspace project +// @Description Create branch on git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body GitBranchRequest true "GitBranchRequest" // @Success 201 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/branches [post] +// @Router /workspace/{workspaceId}/toolbox/git/branches [post] // // @id GitCreateBranch func GitCreateBranch(ctx *gin.Context) { @@ -77,13 +73,12 @@ func GitCreateBranch(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Get commit history -// @Description Get commit history from git repository inside workspace project +// @Description Get commit history from git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path to git repository" // @Success 200 {array} GitCommitInfo -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/history [get] +// @Router /workspace/{workspaceId}/toolbox/git/history [get] // // @id GitCommitHistory func GitCommitHistory(ctx *gin.Context) { @@ -94,13 +89,12 @@ func GitCommitHistory(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Get branch list -// @Description Get branch list from git repository inside workspace project +// @Description Get branch list from git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path to git repository" // @Success 200 {object} ListBranchResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/branches [get] +// @Router /workspace/{workspaceId}/toolbox/git/branches [get] // // @id GitBranchList func GitBranchList(ctx *gin.Context) { @@ -111,13 +105,12 @@ func GitBranchList(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Pull changes -// @Description Pull changes from remote to git repository inside workspace project +// @Description Pull changes from remote to git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body GitRepoRequest true "Git pull request" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/pull [post] +// @Router /workspace/{workspaceId}/toolbox/git/pull [post] // // @id GitPullChanges func GitPullChanges(ctx *gin.Context) { @@ -128,13 +121,12 @@ func GitPullChanges(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Push changes -// @Description Push changes to remote from git repository inside workspace project +// @Description Push changes to remote from git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body GitRepoRequest true "Git push request" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/push [post] +// @Router /workspace/{workspaceId}/toolbox/git/push [post] // // @id GitPushChanges func GitPushChanges(ctx *gin.Context) { @@ -145,13 +137,12 @@ func GitPushChanges(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Get git status -// @Description Get status from git repository inside workspace project +// @Description Get status from git repository inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param path query string true "Path to git repository" // @Success 200 {object} GitStatus -// @Router /workspace/{workspaceId}/{projectId}/toolbox/git/status [get] +// @Router /workspace/{workspaceId}/toolbox/git/status [get] // // @id GitGitStatus func GitStatus(ctx *gin.Context) { diff --git a/pkg/api/controllers/workspace/toolbox/lsp.go b/pkg/api/controllers/workspace/toolbox/lsp.go index 24640d835d..5f77b10e0a 100644 --- a/pkg/api/controllers/workspace/toolbox/lsp.go +++ b/pkg/api/controllers/workspace/toolbox/lsp.go @@ -9,13 +9,12 @@ import "github.com/gin-gonic/gin" // // @Tags workspace toolbox // @Summary Start Lsp server -// @Description Start Lsp server process inside workspace project +// @Description Start Lsp server process inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body LspServerRequest true "LspServerRequest" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/start [post] +// @Router /workspace/{workspaceId}/toolbox/lsp/start [post] // // @id LspStart func LspStart(ctx *gin.Context) { @@ -26,13 +25,12 @@ func LspStart(ctx *gin.Context) { // // @Tags workspace toolbox // @Summary Stop Lsp server -// @Description Stop Lsp server process inside workspace project +// @Description Stop Lsp server process inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body LspServerRequest true "LspServerRequest" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/stop [post] +// @Router /workspace/{workspaceId}/toolbox/lsp/stop [post] // // @id LspStop func LspStop(ctx *gin.Context) { @@ -46,10 +44,9 @@ func LspStop(ctx *gin.Context) { // @Description The document open notification is sent from the client to the server to signal newly opened text documents. // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body LspDocumentRequest true "LspDocumentRequest" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open [post] +// @Router /workspace/{workspaceId}/toolbox/lsp/did-open [post] // // @id LspDidOpen func LspDidOpen(ctx *gin.Context) { @@ -63,10 +60,9 @@ func LspDidOpen(ctx *gin.Context) { // @Description The document close notification is sent from the client to the server when the document got closed in the client. // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body LspDocumentRequest true "LspDocumentRequest" // @Success 200 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close [post] +// @Router /workspace/{workspaceId}/toolbox/lsp/did-close [post] // // @id LspDidClose func LspDidClose(ctx *gin.Context) { @@ -80,12 +76,11 @@ func LspDidClose(ctx *gin.Context) { // @Description The document symbol request is sent from the client to the server. // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param languageId query string true "Language ID" // @Param pathToProject query string true "Path to project" // @Param uri query string true "Document Uri" // @Success 200 {array} LspSymbol -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols [get] +// @Router /workspace/{workspaceId}/toolbox/lsp/document-symbols [get] // // @id LspDocumentSymbols func LspDocumentSymbols(ctx *gin.Context) { @@ -99,12 +94,11 @@ func LspDocumentSymbols(ctx *gin.Context) { // @Description The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string. // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param languageId query string true "Language ID" // @Param pathToProject query string true "Path to project" // @Param query query string true "Symbol Query" // @Success 200 {array} LspSymbol -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols [get] +// @Router /workspace/{workspaceId}/toolbox/lsp/workspace-symbols [get] // // @id LspWorkspaceSymbols func LspWorkspaceSymbols(ctx *gin.Context) { @@ -118,10 +112,9 @@ func LspWorkspaceSymbols(ctx *gin.Context) { // @Description The Completion request is sent from the client to the server to compute completion items at a given cursor position. // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body LspCompletionParams true "LspCompletionParams" // @Success 200 {object} CompletionList -// @Router /workspace/{workspaceId}/{projectId}/toolbox/lsp/completions [post] +// @Router /workspace/{workspaceId}/toolbox/lsp/completions [post] // // @id LspCompletions func LspCompletions(ctx *gin.Context) { diff --git a/pkg/api/controllers/workspace/toolbox/process.go b/pkg/api/controllers/workspace/toolbox/process.go index 2d87730cdc..073252a43a 100644 --- a/pkg/api/controllers/workspace/toolbox/process.go +++ b/pkg/api/controllers/workspace/toolbox/process.go @@ -9,13 +9,12 @@ import "github.com/gin-gonic/gin" // // @Tags workspace toolbox // @Summary Execute command -// @Description Execute command synchronously inside workspace project +// @Description Execute command synchronously inside a workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body ExecuteRequest true "Execute command request" // @Success 200 {object} ExecuteResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/process/execute [post] +// @Router /workspace/{workspaceId}/toolbox/process/execute [post] // // @id ProcessExecuteCommand func ProcessExecuteCommand(ctx *gin.Context) { diff --git a/pkg/api/controllers/workspace/toolbox/session.go b/pkg/api/controllers/workspace/toolbox/session.go index 80d078f813..de194181d4 100644 --- a/pkg/api/controllers/workspace/toolbox/session.go +++ b/pkg/api/controllers/workspace/toolbox/session.go @@ -12,10 +12,9 @@ import "github.com/gin-gonic/gin" // @Description Create exec session inside workspace project // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param params body CreateSessionRequest true "Create session request" // @Success 201 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/process/session [post] +// @Router /workspace/{workspaceId}/toolbox/process/session [post] // // @id CreateSession func CreateSession(ctx *gin.Context) { @@ -29,11 +28,10 @@ func CreateSession(ctx *gin.Context) { // @Description Execute command inside a session inside workspace project // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param sessionId path string true "Session ID" // @Param params body SessionExecuteRequest true "Execute command request" // @Success 200 {object} SessionExecuteResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec [post] +// @Router /workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec [post] // // @id SessionExecuteCommand func SessionExecuteCommand(ctx *gin.Context) { @@ -47,10 +45,9 @@ func SessionExecuteCommand(ctx *gin.Context) { // @Description Delete a session inside workspace project // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param sessionId path string true "Session ID" // @Success 204 -// @Router /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId} [delete] +// @Router /workspace/{workspaceId}/toolbox/process/session/{sessionId} [delete] // // @id DeleteSession func DeleteSession(ctx *gin.Context) { @@ -64,9 +61,8 @@ func DeleteSession(ctx *gin.Context) { // @Description List sessions inside workspace project // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Success 200 {array} Session -// @Router /workspace/{workspaceId}/{projectId}/toolbox/process/session [get] +// @Router /workspace/{workspaceId}/toolbox/process/session [get] // // @id ListSessions func ListSessions(ctx *gin.Context) { @@ -80,11 +76,10 @@ func ListSessions(ctx *gin.Context) { // @Description Get logs of a command inside a session inside workspace project // @Description Connect with websocket to get a stream of the logs // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Param sessionId path string true "Session ID" // @Param commandId path string true "Command ID" // @Success 200 {string} string "command logs" -// @Router /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs [get] +// @Router /workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs [get] // // @id GetSessionCommandLogs func GetSessionCommandLogs(ctx *gin.Context) { diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index cd057f21ca..c5a650d247 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -16,8 +16,8 @@ import ( "github.com/daytonaio/daytona/pkg/agent/toolbox/config" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) @@ -29,9 +29,8 @@ import ( // @Description Get workspace directory // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param projectId path string true "Project ID" // @Success 200 {object} WorkspaceDirResponse -// @Router /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir [get] +// @Router /workspace/{workspaceId}/toolbox/workspace-dir [get] // // @id GetWorkspaceDir func GetWorkspaceDir(ctx *gin.Context) { @@ -45,14 +44,13 @@ var upgrader = websocket.Upgrader{ } func forwardRequestToToolbox(ctx *gin.Context) { - targetId := ctx.Param("targetId") workspaceId := ctx.Param("workspaceId") server := server.GetInstance(nil) - tg, err := server.TargetService.GetTarget(ctx.Request.Context(), targetId, true) + w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, true) if err != nil { - if errors.Is(err, targets.ErrTargetNotFound) { + if errors.Is(err, workspaces.ErrWorkspaceNotFound) { ctx.AbortWithError(http.StatusNotFound, err) return } @@ -60,34 +58,18 @@ func forwardRequestToToolbox(ctx *gin.Context) { return } - var workspaceInfo *workspace.WorkspaceInfo - found := false - for _, w := range tg.Info.Workspaces { - if w.Name == workspaceId { - workspaceInfo = w - found = true - break - } - } - - if !found { - ctx.AbortWithError(http.StatusNotFound, errors.New("workspace not found")) - return - } - var client *http.Client var websocketDialer *websocket.Dialer - projectHostname := workspace.GetWorkspaceHostname(tg.Id, workspaceId) - route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/%s/toolbox/", targetId, workspaceId), "", 1) + workspaceHostname := workspace.GetWorkspaceHostname(w.Id) + route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/toolbox/", workspaceId), "", 1) query := ctx.Request.URL.Query().Encode() scheme := "http" if ctx.Request.Header.Get("Upgrade") == "websocket" { scheme = "ws" } - - reqUrl := fmt.Sprintf("%s://%s:%d/%s?%s", scheme, projectHostname, config.TOOLBOX_API_PORT, route, query) + reqUrl := fmt.Sprintf("%s://%s:%d/%s?%s", scheme, workspaceHostname, config.TOOLBOX_API_PORT, route, query) client = server.TailscaleServer.HTTPClient() websocketDialer = &websocket.Dialer{ NetDial: func(network, addr string) (net.Conn, error) { @@ -95,9 +77,9 @@ func forwardRequestToToolbox(ctx *gin.Context) { }, } - if tg.TargetConfig == "local" { + if w.TargetId == "local" && w.Info != nil && w.Info.ProviderMetadata != "" { var metadata map[string]interface{} - err := json.Unmarshal([]byte(workspaceInfo.ProviderMetadata), &metadata) + err := json.Unmarshal([]byte(w.Info.ProviderMetadata), &metadata) if err == nil { if toolboxPortString, ok := metadata["daytona.toolbox.api.hostPort"]; ok { toolboxPort, err := strconv.ParseUint(toolboxPortString.(string), 10, 16) diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go new file mode 100644 index 0000000000..0e3e018595 --- /dev/null +++ b/pkg/api/controllers/workspace/workspace.go @@ -0,0 +1,86 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "errors" + "fmt" + "net/http" + "strconv" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// GetWorkspace godoc +// +// @Tags workspace +// @Summary Get workspace info +// @Description Get workspace info +// @Produce json +// @Param workspaceId path string true "Workspace ID or Name" +// @Param verbose query bool false "Verbose" +// @Success 200 {object} WorkspaceDTO +// @Router /workspace/{workspaceId} [get] +// +// @id GetWorkspace +func GetWorkspace(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + verboseQuery := ctx.Query("verbose") + verbose := false + var err error + + if verboseQuery != "" { + verbose, err = strconv.ParseBool(verboseQuery) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for verbose flag")) + return + } + } + + server := server.GetInstance(nil) + + w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, verbose) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace: %w", err)) + return + } + + ctx.JSON(200, w) +} + +// ListWorkspaces godoc +// +// @Tags workspace +// @Summary List workspaces +// @Description List workspaces +// @Produce json +// @Success 200 {array} WorkspaceDTO +// @Router /workspace [get] +// @Param verbose query bool false "Verbose" +// +// @id ListWorkspaces +func ListWorkspaces(ctx *gin.Context) { + verboseQuery := ctx.Query("verbose") + verbose := false + var err error + + if verboseQuery != "" { + verbose, err = strconv.ParseBool(verboseQuery) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for verbose flag")) + return + } + } + + server := server.GetInstance(nil) + + workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), verbose) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspaces: %w", err)) + return + } + + ctx.JSON(200, workspaceList) +} diff --git a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go index df287daaef..34ad0c16ff 100644 --- a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go +++ b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" "github.com/gin-gonic/gin" ) diff --git a/pkg/api/controllers/workspaceconfig/workspace_config.go b/pkg/api/controllers/workspaceconfig/workspace_config.go index afe7cd20e2..059e38ea6e 100644 --- a/pkg/api/controllers/workspaceconfig/workspace_config.go +++ b/pkg/api/controllers/workspaceconfig/workspace_config.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index cfaefaecd2..9e3acd4e37 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1421,104 +1421,64 @@ const docTemplate = `{ } } }, - "/target/{targetId}/{workspaceId}/start": { - "post": { - "description": "Start workspace", + "/workspace": { + "get": { + "description": "List workspaces", + "produces": [ + "application/json" + ], "tags": [ - "target" + "workspace" ], - "summary": "Start workspace", - "operationId": "StartWorkspace", + "summary": "List workspaces", + "operationId": "ListWorkspaces", "parameters": [ { - "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace ID", - "name": "workspaceId", - "in": "path", - "required": true + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/WorkspaceDTO" + } + } } } - } - }, - "/target/{targetId}/{workspaceId}/state": { + }, "post": { - "description": "Set workspace state", + "description": "Create a workspace", + "produces": [ + "application/json" + ], "tags": [ - "target" + "workspace" ], - "summary": "Set workspace state", - "operationId": "SetWorkspaceState", + "summary": "Create a workspace", + "operationId": "CreateWorkspace", "parameters": [ { - "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace ID", - "name": "workspaceId", - "in": "path", - "required": true - }, - { - "description": "Set State", - "name": "setState", + "description": "Create workspace", + "name": "workspace", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/SetWorkspaceState" + "$ref": "#/definitions/CreateWorkspaceDTO" } } ], "responses": { "200": { - "description": "OK" - } - } - } - }, - "/target/{targetId}/{workspaceId}/stop": { - "post": { - "description": "Stop workspace", - "tags": [ - "target" - ], - "summary": "Stop workspace", - "operationId": "StopWorkspace", - "parameters": [ - { - "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace ID", - "name": "workspaceId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceViewDTO" + } } } } @@ -1881,17 +1841,78 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files": { + "/workspace/{workspaceId}": { "get": { - "description": "List files inside workspace project", + "description": "Get workspace info", "produces": [ "application/json" ], "tags": [ - "workspace toolbox" + "workspace" ], - "summary": "List files", - "operationId": "FsListFiles", + "summary": "Get workspace info", + "operationId": "GetWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceDTO" + } + } + } + }, + "delete": { + "description": "Remove workspace", + "tags": [ + "workspace" + ], + "summary": "Remove workspace", + "operationId": "RemoveWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/start": { + "post": { + "description": "Start workspace", + "tags": [ + "workspace" + ], + "summary": "Start workspace", + "operationId": "StartWorkspace", "parameters": [ { "type": "string", @@ -1899,11 +1920,88 @@ const docTemplate = `{ "name": "workspaceId", "in": "path", "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/state": { + "post": { + "description": "Set workspace state", + "tags": [ + "workspace" + ], + "summary": "Set workspace state", + "operationId": "SetWorkspaceState", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true }, + { + "description": "Set State", + "name": "setState", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetWorkspaceState" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/stop": { + "post": { + "description": "Stop workspace", + "tags": [ + "workspace" + ], + "summary": "Stop workspace", + "operationId": "StopWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/toolbox/files": { + "get": { + "description": "List files inside a workspace", + "produces": [ + "application/json" + ], + "tags": [ + "workspace toolbox" + ], + "summary": "List files", + "operationId": "FsListFiles", + "parameters": [ { "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Workspace ID or Name", + "name": "workspaceId", "in": "path", "required": true }, @@ -1927,7 +2025,7 @@ const docTemplate = `{ } }, "delete": { - "description": "Delete file inside workspace project", + "description": "Delete file inside a workspace", "produces": [ "application/json" ], @@ -1944,13 +2042,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -1966,9 +2057,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/download": { + "/workspace/{workspaceId}/toolbox/files/download": { "get": { - "description": "Download file from workspace project", + "description": "Download file from a workspace", "produces": [ "application/json" ], @@ -1985,13 +2076,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2010,9 +2094,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/find": { + "/workspace/{workspaceId}/toolbox/files/find": { "get": { - "description": "Search for text/pattern inside workspace project files", + "description": "Search for text/pattern inside a workspace files", "produces": [ "application/json" ], @@ -2029,13 +2113,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2064,9 +2141,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/folder": { + "/workspace/{workspaceId}/toolbox/files/folder": { "post": { - "description": "Create folder inside workspace project", + "description": "Create folder inside a workspace", "produces": [ "application/json" ], @@ -2083,13 +2160,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2112,9 +2182,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/info": { + "/workspace/{workspaceId}/toolbox/files/info": { "get": { - "description": "Get file info inside workspace project", + "description": "Get file info inside a workspace", "produces": [ "application/json" ], @@ -2131,13 +2201,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2156,9 +2219,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/move": { + "/workspace/{workspaceId}/toolbox/files/move": { "post": { - "description": "Create folder inside workspace project", + "description": "Create folder inside a workspace", "produces": [ "application/json" ], @@ -2175,13 +2238,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Source path", @@ -2204,9 +2260,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/permissions": { + "/workspace/{workspaceId}/toolbox/files/permissions": { "post": { - "description": "Set file owner/group/permissions inside workspace project", + "description": "Set file owner/group/permissions inside a workspace", "produces": [ "application/json" ], @@ -2223,13 +2279,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2263,9 +2312,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/replace": { + "/workspace/{workspaceId}/toolbox/files/replace": { "post": { - "description": "Repleace text/pattern in mutilple files inside workspace project", + "description": "Repleace text/pattern in mutilple files inside a workspace", "produces": [ "application/json" ], @@ -2282,13 +2331,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "ReplaceParams", "name": "replace", @@ -2312,9 +2354,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/search": { + "/workspace/{workspaceId}/toolbox/files/search": { "get": { - "description": "Search for files inside workspace project", + "description": "Search for files inside a workspace", "produces": [ "application/json" ], @@ -2331,13 +2373,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2363,9 +2398,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/upload": { + "/workspace/{workspaceId}/toolbox/files/upload": { "post": { - "description": "Upload file inside workspace project", + "description": "Upload file inside a workspace", "produces": [ "application/json" ], @@ -2382,13 +2417,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2411,7 +2439,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/add": { + "/workspace/{workspaceId}/toolbox/git/add": { "post": { "description": "Add files to git commit", "produces": [ @@ -2430,13 +2458,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitAddRequest", "name": "params", @@ -2454,9 +2475,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/branches": { + "/workspace/{workspaceId}/toolbox/git/branches": { "get": { - "description": "Get branch list from git repository inside workspace project", + "description": "Get branch list from git repository inside a workspace", "produces": [ "application/json" ], @@ -2473,13 +2494,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path to git repository", @@ -2498,7 +2512,7 @@ const docTemplate = `{ } }, "post": { - "description": "Create branch on git repository inside workspace project", + "description": "Create branch on git repository inside a workspace", "produces": [ "application/json" ], @@ -2515,13 +2529,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitBranchRequest", "name": "params", @@ -2539,9 +2546,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/clone": { + "/workspace/{workspaceId}/toolbox/git/clone": { "post": { - "description": "Clone git repository inside workspace project", + "description": "Clone git repository inside a workspace", "produces": [ "application/json" ], @@ -2558,13 +2565,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitCloneRequest", "name": "params", @@ -2582,9 +2582,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/commit": { + "/workspace/{workspaceId}/toolbox/git/commit": { "post": { - "description": "Commit changes to git repository inside workspace project", + "description": "Commit changes to git repository inside a workspace", "produces": [ "application/json" ], @@ -2601,13 +2601,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitCommitRequest", "name": "params", @@ -2628,9 +2621,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/history": { + "/workspace/{workspaceId}/toolbox/git/history": { "get": { - "description": "Get commit history from git repository inside workspace project", + "description": "Get commit history from git repository inside a workspace", "produces": [ "application/json" ], @@ -2647,13 +2640,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path to git repository", @@ -2675,9 +2661,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/pull": { + "/workspace/{workspaceId}/toolbox/git/pull": { "post": { - "description": "Pull changes from remote to git repository inside workspace project", + "description": "Pull changes from remote to git repository inside a workspace", "produces": [ "application/json" ], @@ -2694,13 +2680,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Git pull request", "name": "params", @@ -2718,9 +2697,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/push": { + "/workspace/{workspaceId}/toolbox/git/push": { "post": { - "description": "Push changes to remote from git repository inside workspace project", + "description": "Push changes to remote from git repository inside a workspace", "produces": [ "application/json" ], @@ -2737,13 +2716,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Git push request", "name": "params", @@ -2761,9 +2733,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/status": { + "/workspace/{workspaceId}/toolbox/git/status": { "get": { - "description": "Get status from git repository inside workspace project", + "description": "Get status from git repository inside a workspace", "produces": [ "application/json" ], @@ -2780,13 +2752,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path to git repository", @@ -2805,7 +2770,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/completions": { + "/workspace/{workspaceId}/toolbox/lsp/completions": { "post": { "description": "The Completion request is sent from the client to the server to compute completion items at a given cursor position.", "produces": [ @@ -2824,13 +2789,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspCompletionParams", "name": "params", @@ -2851,7 +2809,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close": { + "/workspace/{workspaceId}/toolbox/lsp/did-close": { "post": { "description": "The document close notification is sent from the client to the server when the document got closed in the client.", "produces": [ @@ -2870,13 +2828,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspDocumentRequest", "name": "params", @@ -2894,7 +2845,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open": { + "/workspace/{workspaceId}/toolbox/lsp/did-open": { "post": { "description": "The document open notification is sent from the client to the server to signal newly opened text documents.", "produces": [ @@ -2913,13 +2864,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspDocumentRequest", "name": "params", @@ -2937,7 +2881,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols": { + "/workspace/{workspaceId}/toolbox/lsp/document-symbols": { "get": { "description": "The document symbol request is sent from the client to the server.", "produces": [ @@ -2956,13 +2900,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Language ID", @@ -2998,9 +2935,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/start": { + "/workspace/{workspaceId}/toolbox/lsp/start": { "post": { - "description": "Start Lsp server process inside workspace project", + "description": "Start Lsp server process inside a workspace", "produces": [ "application/json" ], @@ -3017,13 +2954,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspServerRequest", "name": "params", @@ -3041,9 +2971,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/stop": { + "/workspace/{workspaceId}/toolbox/lsp/stop": { "post": { - "description": "Stop Lsp server process inside workspace project", + "description": "Stop Lsp server process inside a workspace", "produces": [ "application/json" ], @@ -3060,13 +2990,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspServerRequest", "name": "params", @@ -3084,7 +3007,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols": { + "/workspace/{workspaceId}/toolbox/lsp/workspace-symbols": { "get": { "description": "The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.", "produces": [ @@ -3103,13 +3026,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Language ID", @@ -3145,9 +3061,9 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/execute": { + "/workspace/{workspaceId}/toolbox/process/execute": { "post": { - "description": "Execute command synchronously inside workspace project", + "description": "Execute command synchronously inside a workspace", "produces": [ "application/json" ], @@ -3164,13 +3080,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Execute command request", "name": "params", @@ -3191,7 +3100,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session": { + "/workspace/{workspaceId}/toolbox/process/session": { "get": { "description": "List sessions inside workspace project", "produces": [ @@ -3209,13 +3118,6 @@ const docTemplate = `{ "name": "workspaceId", "in": "path", "required": true - }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true } ], "responses": { @@ -3248,13 +3150,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Create session request", "name": "params", @@ -3272,7 +3167,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}": { + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}": { "delete": { "description": "Delete a session inside workspace project", "produces": [ @@ -3291,13 +3186,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Session ID", @@ -3313,7 +3201,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs": { + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs": { "get": { "description": "Get logs of a command inside a session inside workspace project\nConnect with websocket to get a stream of the logs", "tags": [ @@ -3329,13 +3217,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Session ID", @@ -3361,7 +3242,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec": { + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec": { "post": { "description": "Execute command inside a session inside workspace project", "produces": [ @@ -3380,13 +3261,6 @@ const docTemplate = `{ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Session ID", @@ -3414,7 +3288,7 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/workspace-dir": { + "/workspace/{workspaceId}/toolbox/workspace-dir": { "get": { "description": "Get workspace directory", "produces": [ @@ -3432,13 +3306,6 @@ const docTemplate = `{ "name": "workspaceId", "in": "path", "required": true - }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true } ], "responses": { @@ -3758,8 +3625,7 @@ const docTemplate = `{ "required": [ "id", "name", - "targetConfig", - "workspaces" + "targetConfig" ], "properties": { "id": { @@ -3770,12 +3636,6 @@ const docTemplate = `{ }, "targetConfig": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/CreateWorkspaceDTO" - } } } }, @@ -3817,8 +3677,10 @@ const docTemplate = `{ "type": "object", "required": [ "envVars", + "id", "name", - "source" + "source", + "targetId" ], "properties": { "buildConfig": { @@ -3833,6 +3695,9 @@ const docTemplate = `{ "gitProviderConfigId": { "type": "string" }, + "id": { + "type": "string" + }, "image": { "type": "string" }, @@ -3842,6 +3707,9 @@ const docTemplate = `{ "source": { "$ref": "#/definitions/CreateWorkspaceSourceDTO" }, + "targetId": { + "type": "string" + }, "user": { "type": "string" } @@ -4957,8 +4825,7 @@ const docTemplate = `{ "required": [ "id", "name", - "targetConfig", - "workspaces" + "targetConfig" ], "properties": { "id": { @@ -4969,12 +4836,6 @@ const docTemplate = `{ }, "targetConfig": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/Workspace" - } } } }, @@ -5050,8 +4911,7 @@ const docTemplate = `{ "required": [ "id", "name", - "targetConfig", - "workspaces" + "targetConfig" ], "properties": { "id": { @@ -5065,20 +4925,13 @@ const docTemplate = `{ }, "targetConfig": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/Workspace" - } } } }, "TargetInfo": { "type": "object", "required": [ - "name", - "workspaces" + "name" ], "properties": { "name": { @@ -5086,30 +4939,26 @@ const docTemplate = `{ }, "providerMetadata": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/WorkspaceInfo" - } } } }, - "Workspace": { + "WorkspaceConfig": { "type": "object", "required": [ + "default", "envVars", "image", "name", - "repository", - "targetConfig", - "targetId", + "repositoryUrl", "user" ], "properties": { "buildConfig": { "$ref": "#/definitions/BuildConfig" }, + "default": { + "type": "boolean" + }, "envVars": { "type": "object", "additionalProperties": { @@ -5125,16 +4974,13 @@ const docTemplate = `{ "name": { "type": "string" }, - "repository": { - "$ref": "#/definitions/GitRepository" - }, - "state": { - "$ref": "#/definitions/WorkspaceState" - }, - "targetConfig": { - "type": "string" + "prebuilds": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildConfig" + } }, - "targetId": { + "repositoryUrl": { "type": "string" }, "user": { @@ -5142,23 +4988,22 @@ const docTemplate = `{ } } }, - "WorkspaceConfig": { + "WorkspaceDTO": { "type": "object", "required": [ - "default", "envVars", + "id", "image", "name", - "repositoryUrl", + "repository", + "targetId", + "targetName", "user" ], "properties": { "buildConfig": { "$ref": "#/definitions/BuildConfig" }, - "default": { - "type": "boolean" - }, "envVars": { "type": "object", "additionalProperties": { @@ -5168,19 +5013,28 @@ const docTemplate = `{ "gitProviderConfigId": { "type": "string" }, + "id": { + "type": "string" + }, "image": { "type": "string" }, + "info": { + "$ref": "#/definitions/WorkspaceInfo" + }, "name": { "type": "string" }, - "prebuilds": { - "type": "array", - "items": { - "$ref": "#/definitions/PrebuildConfig" - } + "repository": { + "$ref": "#/definitions/GitRepository" }, - "repositoryUrl": { + "state": { + "$ref": "#/definitions/WorkspaceState" + }, + "targetId": { + "type": "string" + }, + "targetName": { "type": "string" }, "user": { @@ -5240,6 +5094,57 @@ const docTemplate = `{ } } }, + "WorkspaceViewDTO": { + "type": "object", + "required": [ + "envVars", + "id", + "image", + "name", + "repository", + "targetId", + "targetName", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repository": { + "$ref": "#/definitions/GitRepository" + }, + "state": { + "$ref": "#/definitions/WorkspaceState" + }, + "targetId": { + "type": "string" + }, + "targetName": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, "apikey.ApiKeyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index c0bb7a5529..20b0ca1487 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1418,104 +1418,64 @@ } } }, - "/target/{targetId}/{workspaceId}/start": { - "post": { - "description": "Start workspace", + "/workspace": { + "get": { + "description": "List workspaces", + "produces": [ + "application/json" + ], "tags": [ - "target" + "workspace" ], - "summary": "Start workspace", - "operationId": "StartWorkspace", + "summary": "List workspaces", + "operationId": "ListWorkspaces", "parameters": [ { - "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace ID", - "name": "workspaceId", - "in": "path", - "required": true + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" } ], "responses": { "200": { - "description": "OK" + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/WorkspaceDTO" + } + } } } - } - }, - "/target/{targetId}/{workspaceId}/state": { + }, "post": { - "description": "Set workspace state", + "description": "Create a workspace", + "produces": [ + "application/json" + ], "tags": [ - "target" + "workspace" ], - "summary": "Set workspace state", - "operationId": "SetWorkspaceState", + "summary": "Create a workspace", + "operationId": "CreateWorkspace", "parameters": [ { - "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace ID", - "name": "workspaceId", - "in": "path", - "required": true - }, - { - "description": "Set State", - "name": "setState", + "description": "Create workspace", + "name": "workspace", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/SetWorkspaceState" + "$ref": "#/definitions/CreateWorkspaceDTO" } } ], "responses": { "200": { - "description": "OK" - } - } - } - }, - "/target/{targetId}/{workspaceId}/stop": { - "post": { - "description": "Stop workspace", - "tags": [ - "target" - ], - "summary": "Stop workspace", - "operationId": "StopWorkspace", - "parameters": [ - { - "type": "string", - "description": "Target ID or Name", - "name": "targetId", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace ID", - "name": "workspaceId", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceViewDTO" + } } } } @@ -1878,17 +1838,78 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files": { + "/workspace/{workspaceId}": { "get": { - "description": "List files inside workspace project", + "description": "Get workspace info", "produces": [ "application/json" ], "tags": [ - "workspace toolbox" + "workspace" ], - "summary": "List files", - "operationId": "FsListFiles", + "summary": "Get workspace info", + "operationId": "GetWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Verbose", + "name": "verbose", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceDTO" + } + } + } + }, + "delete": { + "description": "Remove workspace", + "tags": [ + "workspace" + ], + "summary": "Remove workspace", + "operationId": "RemoveWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/start": { + "post": { + "description": "Start workspace", + "tags": [ + "workspace" + ], + "summary": "Start workspace", + "operationId": "StartWorkspace", "parameters": [ { "type": "string", @@ -1896,11 +1917,88 @@ "name": "workspaceId", "in": "path", "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/state": { + "post": { + "description": "Set workspace state", + "tags": [ + "workspace" + ], + "summary": "Set workspace state", + "operationId": "SetWorkspaceState", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true }, + { + "description": "Set State", + "name": "setState", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetWorkspaceState" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/stop": { + "post": { + "description": "Stop workspace", + "tags": [ + "workspace" + ], + "summary": "Stop workspace", + "operationId": "StopWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/toolbox/files": { + "get": { + "description": "List files inside a workspace", + "produces": [ + "application/json" + ], + "tags": [ + "workspace toolbox" + ], + "summary": "List files", + "operationId": "FsListFiles", + "parameters": [ { "type": "string", - "description": "Project ID", - "name": "projectId", + "description": "Workspace ID or Name", + "name": "workspaceId", "in": "path", "required": true }, @@ -1924,7 +2022,7 @@ } }, "delete": { - "description": "Delete file inside workspace project", + "description": "Delete file inside a workspace", "produces": [ "application/json" ], @@ -1941,13 +2039,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -1963,9 +2054,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/download": { + "/workspace/{workspaceId}/toolbox/files/download": { "get": { - "description": "Download file from workspace project", + "description": "Download file from a workspace", "produces": [ "application/json" ], @@ -1982,13 +2073,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2007,9 +2091,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/find": { + "/workspace/{workspaceId}/toolbox/files/find": { "get": { - "description": "Search for text/pattern inside workspace project files", + "description": "Search for text/pattern inside a workspace files", "produces": [ "application/json" ], @@ -2026,13 +2110,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2061,9 +2138,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/folder": { + "/workspace/{workspaceId}/toolbox/files/folder": { "post": { - "description": "Create folder inside workspace project", + "description": "Create folder inside a workspace", "produces": [ "application/json" ], @@ -2080,13 +2157,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2109,9 +2179,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/info": { + "/workspace/{workspaceId}/toolbox/files/info": { "get": { - "description": "Get file info inside workspace project", + "description": "Get file info inside a workspace", "produces": [ "application/json" ], @@ -2128,13 +2198,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2153,9 +2216,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/move": { + "/workspace/{workspaceId}/toolbox/files/move": { "post": { - "description": "Create folder inside workspace project", + "description": "Create folder inside a workspace", "produces": [ "application/json" ], @@ -2172,13 +2235,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Source path", @@ -2201,9 +2257,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/permissions": { + "/workspace/{workspaceId}/toolbox/files/permissions": { "post": { - "description": "Set file owner/group/permissions inside workspace project", + "description": "Set file owner/group/permissions inside a workspace", "produces": [ "application/json" ], @@ -2220,13 +2276,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2260,9 +2309,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/replace": { + "/workspace/{workspaceId}/toolbox/files/replace": { "post": { - "description": "Repleace text/pattern in mutilple files inside workspace project", + "description": "Repleace text/pattern in mutilple files inside a workspace", "produces": [ "application/json" ], @@ -2279,13 +2328,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "ReplaceParams", "name": "replace", @@ -2309,9 +2351,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/search": { + "/workspace/{workspaceId}/toolbox/files/search": { "get": { - "description": "Search for files inside workspace project", + "description": "Search for files inside a workspace", "produces": [ "application/json" ], @@ -2328,13 +2370,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2360,9 +2395,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/files/upload": { + "/workspace/{workspaceId}/toolbox/files/upload": { "post": { - "description": "Upload file inside workspace project", + "description": "Upload file inside a workspace", "produces": [ "application/json" ], @@ -2379,13 +2414,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path", @@ -2408,7 +2436,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/add": { + "/workspace/{workspaceId}/toolbox/git/add": { "post": { "description": "Add files to git commit", "produces": [ @@ -2427,13 +2455,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitAddRequest", "name": "params", @@ -2451,9 +2472,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/branches": { + "/workspace/{workspaceId}/toolbox/git/branches": { "get": { - "description": "Get branch list from git repository inside workspace project", + "description": "Get branch list from git repository inside a workspace", "produces": [ "application/json" ], @@ -2470,13 +2491,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path to git repository", @@ -2495,7 +2509,7 @@ } }, "post": { - "description": "Create branch on git repository inside workspace project", + "description": "Create branch on git repository inside a workspace", "produces": [ "application/json" ], @@ -2512,13 +2526,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitBranchRequest", "name": "params", @@ -2536,9 +2543,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/clone": { + "/workspace/{workspaceId}/toolbox/git/clone": { "post": { - "description": "Clone git repository inside workspace project", + "description": "Clone git repository inside a workspace", "produces": [ "application/json" ], @@ -2555,13 +2562,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitCloneRequest", "name": "params", @@ -2579,9 +2579,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/commit": { + "/workspace/{workspaceId}/toolbox/git/commit": { "post": { - "description": "Commit changes to git repository inside workspace project", + "description": "Commit changes to git repository inside a workspace", "produces": [ "application/json" ], @@ -2598,13 +2598,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "GitCommitRequest", "name": "params", @@ -2625,9 +2618,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/history": { + "/workspace/{workspaceId}/toolbox/git/history": { "get": { - "description": "Get commit history from git repository inside workspace project", + "description": "Get commit history from git repository inside a workspace", "produces": [ "application/json" ], @@ -2644,13 +2637,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path to git repository", @@ -2672,9 +2658,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/pull": { + "/workspace/{workspaceId}/toolbox/git/pull": { "post": { - "description": "Pull changes from remote to git repository inside workspace project", + "description": "Pull changes from remote to git repository inside a workspace", "produces": [ "application/json" ], @@ -2691,13 +2677,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Git pull request", "name": "params", @@ -2715,9 +2694,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/push": { + "/workspace/{workspaceId}/toolbox/git/push": { "post": { - "description": "Push changes to remote from git repository inside workspace project", + "description": "Push changes to remote from git repository inside a workspace", "produces": [ "application/json" ], @@ -2734,13 +2713,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Git push request", "name": "params", @@ -2758,9 +2730,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/git/status": { + "/workspace/{workspaceId}/toolbox/git/status": { "get": { - "description": "Get status from git repository inside workspace project", + "description": "Get status from git repository inside a workspace", "produces": [ "application/json" ], @@ -2777,13 +2749,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Path to git repository", @@ -2802,7 +2767,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/completions": { + "/workspace/{workspaceId}/toolbox/lsp/completions": { "post": { "description": "The Completion request is sent from the client to the server to compute completion items at a given cursor position.", "produces": [ @@ -2821,13 +2786,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspCompletionParams", "name": "params", @@ -2848,7 +2806,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close": { + "/workspace/{workspaceId}/toolbox/lsp/did-close": { "post": { "description": "The document close notification is sent from the client to the server when the document got closed in the client.", "produces": [ @@ -2867,13 +2825,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspDocumentRequest", "name": "params", @@ -2891,7 +2842,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open": { + "/workspace/{workspaceId}/toolbox/lsp/did-open": { "post": { "description": "The document open notification is sent from the client to the server to signal newly opened text documents.", "produces": [ @@ -2910,13 +2861,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspDocumentRequest", "name": "params", @@ -2934,7 +2878,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols": { + "/workspace/{workspaceId}/toolbox/lsp/document-symbols": { "get": { "description": "The document symbol request is sent from the client to the server.", "produces": [ @@ -2953,13 +2897,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Language ID", @@ -2995,9 +2932,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/start": { + "/workspace/{workspaceId}/toolbox/lsp/start": { "post": { - "description": "Start Lsp server process inside workspace project", + "description": "Start Lsp server process inside a workspace", "produces": [ "application/json" ], @@ -3014,13 +2951,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspServerRequest", "name": "params", @@ -3038,9 +2968,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/stop": { + "/workspace/{workspaceId}/toolbox/lsp/stop": { "post": { - "description": "Stop Lsp server process inside workspace project", + "description": "Stop Lsp server process inside a workspace", "produces": [ "application/json" ], @@ -3057,13 +2987,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "LspServerRequest", "name": "params", @@ -3081,7 +3004,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols": { + "/workspace/{workspaceId}/toolbox/lsp/workspace-symbols": { "get": { "description": "The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.", "produces": [ @@ -3100,13 +3023,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Language ID", @@ -3142,9 +3058,9 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/execute": { + "/workspace/{workspaceId}/toolbox/process/execute": { "post": { - "description": "Execute command synchronously inside workspace project", + "description": "Execute command synchronously inside a workspace", "produces": [ "application/json" ], @@ -3161,13 +3077,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Execute command request", "name": "params", @@ -3188,7 +3097,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session": { + "/workspace/{workspaceId}/toolbox/process/session": { "get": { "description": "List sessions inside workspace project", "produces": [ @@ -3206,13 +3115,6 @@ "name": "workspaceId", "in": "path", "required": true - }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true } ], "responses": { @@ -3245,13 +3147,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "description": "Create session request", "name": "params", @@ -3269,7 +3164,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}": { + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}": { "delete": { "description": "Delete a session inside workspace project", "produces": [ @@ -3288,13 +3183,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Session ID", @@ -3310,7 +3198,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs": { + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs": { "get": { "description": "Get logs of a command inside a session inside workspace project\nConnect with websocket to get a stream of the logs", "tags": [ @@ -3326,13 +3214,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Session ID", @@ -3358,7 +3239,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec": { + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec": { "post": { "description": "Execute command inside a session inside workspace project", "produces": [ @@ -3377,13 +3258,6 @@ "in": "path", "required": true }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true - }, { "type": "string", "description": "Session ID", @@ -3411,7 +3285,7 @@ } } }, - "/workspace/{workspaceId}/{projectId}/toolbox/workspace-dir": { + "/workspace/{workspaceId}/toolbox/workspace-dir": { "get": { "description": "Get workspace directory", "produces": [ @@ -3429,13 +3303,6 @@ "name": "workspaceId", "in": "path", "required": true - }, - { - "type": "string", - "description": "Project ID", - "name": "projectId", - "in": "path", - "required": true } ], "responses": { @@ -3755,8 +3622,7 @@ "required": [ "id", "name", - "targetConfig", - "workspaces" + "targetConfig" ], "properties": { "id": { @@ -3767,12 +3633,6 @@ }, "targetConfig": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/CreateWorkspaceDTO" - } } } }, @@ -3814,8 +3674,10 @@ "type": "object", "required": [ "envVars", + "id", "name", - "source" + "source", + "targetId" ], "properties": { "buildConfig": { @@ -3830,6 +3692,9 @@ "gitProviderConfigId": { "type": "string" }, + "id": { + "type": "string" + }, "image": { "type": "string" }, @@ -3839,6 +3704,9 @@ "source": { "$ref": "#/definitions/CreateWorkspaceSourceDTO" }, + "targetId": { + "type": "string" + }, "user": { "type": "string" } @@ -4954,8 +4822,7 @@ "required": [ "id", "name", - "targetConfig", - "workspaces" + "targetConfig" ], "properties": { "id": { @@ -4966,12 +4833,6 @@ }, "targetConfig": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/Workspace" - } } } }, @@ -5047,8 +4908,7 @@ "required": [ "id", "name", - "targetConfig", - "workspaces" + "targetConfig" ], "properties": { "id": { @@ -5062,20 +4922,13 @@ }, "targetConfig": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/Workspace" - } } } }, "TargetInfo": { "type": "object", "required": [ - "name", - "workspaces" + "name" ], "properties": { "name": { @@ -5083,30 +4936,26 @@ }, "providerMetadata": { "type": "string" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/WorkspaceInfo" - } } } }, - "Workspace": { + "WorkspaceConfig": { "type": "object", "required": [ + "default", "envVars", "image", "name", - "repository", - "targetConfig", - "targetId", + "repositoryUrl", "user" ], "properties": { "buildConfig": { "$ref": "#/definitions/BuildConfig" }, + "default": { + "type": "boolean" + }, "envVars": { "type": "object", "additionalProperties": { @@ -5122,16 +4971,13 @@ "name": { "type": "string" }, - "repository": { - "$ref": "#/definitions/GitRepository" - }, - "state": { - "$ref": "#/definitions/WorkspaceState" - }, - "targetConfig": { - "type": "string" + "prebuilds": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildConfig" + } }, - "targetId": { + "repositoryUrl": { "type": "string" }, "user": { @@ -5139,23 +4985,22 @@ } } }, - "WorkspaceConfig": { + "WorkspaceDTO": { "type": "object", "required": [ - "default", "envVars", + "id", "image", "name", - "repositoryUrl", + "repository", + "targetId", + "targetName", "user" ], "properties": { "buildConfig": { "$ref": "#/definitions/BuildConfig" }, - "default": { - "type": "boolean" - }, "envVars": { "type": "object", "additionalProperties": { @@ -5165,19 +5010,28 @@ "gitProviderConfigId": { "type": "string" }, + "id": { + "type": "string" + }, "image": { "type": "string" }, + "info": { + "$ref": "#/definitions/WorkspaceInfo" + }, "name": { "type": "string" }, - "prebuilds": { - "type": "array", - "items": { - "$ref": "#/definitions/PrebuildConfig" - } + "repository": { + "$ref": "#/definitions/GitRepository" }, - "repositoryUrl": { + "state": { + "$ref": "#/definitions/WorkspaceState" + }, + "targetId": { + "type": "string" + }, + "targetName": { "type": "string" }, "user": { @@ -5237,6 +5091,57 @@ } } }, + "WorkspaceViewDTO": { + "type": "object", + "required": [ + "envVars", + "id", + "image", + "name", + "repository", + "targetId", + "targetName", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repository": { + "$ref": "#/definitions/GitRepository" + }, + "state": { + "$ref": "#/definitions/WorkspaceState" + }, + "targetId": { + "type": "string" + }, + "targetName": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, "apikey.ApiKeyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index f94c15bbcc..f78b6104eb 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -211,15 +211,10 @@ definitions: type: string targetConfig: type: string - workspaces: - items: - $ref: '#/definitions/CreateWorkspaceDTO' - type: array required: - id - name - targetConfig - - workspaces type: object CreateWorkspaceConfigDTO: properties: @@ -254,18 +249,24 @@ definitions: type: object gitProviderConfigId: type: string + id: + type: string image: type: string name: type: string source: $ref: '#/definitions/CreateWorkspaceSourceDTO' + targetId: + type: string user: type: string required: - envVars + - id - name - source + - targetId type: object CreateWorkspaceSourceDTO: properties: @@ -1031,15 +1032,10 @@ definitions: type: string targetConfig: type: string - workspaces: - items: - $ref: '#/definitions/Workspace' - type: array required: - id - name - targetConfig - - workspaces type: object TargetConfig: properties: @@ -1104,15 +1100,10 @@ definitions: type: string targetConfig: type: string - workspaces: - items: - $ref: '#/definitions/Workspace' - type: array required: - id - name - targetConfig - - workspaces type: object TargetInfo: properties: @@ -1120,18 +1111,15 @@ definitions: type: string providerMetadata: type: string - workspaces: - items: - $ref: '#/definitions/WorkspaceInfo' - type: array required: - name - - workspaces type: object - Workspace: + WorkspaceConfig: properties: buildConfig: $ref: '#/definitions/BuildConfig' + default: + type: boolean envVars: additionalProperties: type: string @@ -1142,55 +1130,58 @@ definitions: type: string name: type: string - repository: - $ref: '#/definitions/GitRepository' - state: - $ref: '#/definitions/WorkspaceState' - targetConfig: - type: string - targetId: + prebuilds: + items: + $ref: '#/definitions/PrebuildConfig' + type: array + repositoryUrl: type: string user: type: string required: + - default - envVars - image - name - - repository - - targetConfig - - targetId + - repositoryUrl - user type: object - WorkspaceConfig: + WorkspaceDTO: properties: buildConfig: $ref: '#/definitions/BuildConfig' - default: - type: boolean envVars: additionalProperties: type: string type: object gitProviderConfigId: type: string + id: + type: string image: type: string + info: + $ref: '#/definitions/WorkspaceInfo' name: type: string - prebuilds: - items: - $ref: '#/definitions/PrebuildConfig' - type: array - repositoryUrl: + repository: + $ref: '#/definitions/GitRepository' + state: + $ref: '#/definitions/WorkspaceState' + targetId: + type: string + targetName: type: string user: type: string required: - - default - envVars + - id - image - name - - repositoryUrl + - repository + - targetId + - targetName - user type: object WorkspaceDirResponse: @@ -1228,6 +1219,42 @@ definitions: - updatedAt - uptime type: object + WorkspaceViewDTO: + properties: + buildConfig: + $ref: '#/definitions/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + id: + type: string + image: + type: string + name: + type: string + repository: + $ref: '#/definitions/GitRepository' + state: + $ref: '#/definitions/WorkspaceState' + targetId: + type: string + targetName: + type: string + user: + type: string + required: + - envVars + - id + - image + - name + - repository + - targetId + - targetName + - user + type: object apikey.ApiKeyType: enum: - client @@ -2201,107 +2228,79 @@ paths: summary: Get target info tags: - target - /target/{targetId}/{workspaceId}/start: + /target/{targetId}/start: post: - description: Start workspace - operationId: StartWorkspace + description: Start target + operationId: StartTarget parameters: - description: Target ID or Name in: path name: targetId required: true type: string - - description: Workspace ID - in: path - name: workspaceId - required: true - type: string responses: "200": description: OK - summary: Start workspace + summary: Start target tags: - target - /target/{targetId}/{workspaceId}/state: + /target/{targetId}/stop: post: - description: Set workspace state - operationId: SetWorkspaceState + description: Stop target + operationId: StopTarget parameters: - description: Target ID or Name in: path name: targetId required: true type: string - - description: Workspace ID - in: path - name: workspaceId - required: true - type: string - - description: Set State - in: body - name: setState - required: true - schema: - $ref: '#/definitions/SetWorkspaceState' responses: "200": description: OK - summary: Set workspace state - tags: - - target - /target/{targetId}/{workspaceId}/stop: - post: - description: Stop workspace - operationId: StopWorkspace - parameters: - - description: Target ID or Name - in: path - name: targetId - required: true - type: string - - description: Workspace ID - in: path - name: workspaceId - required: true - type: string - responses: - "200": - description: OK - summary: Stop workspace + summary: Stop target tags: - target - /target/{targetId}/start: - post: - description: Start target - operationId: StartTarget + /workspace: + get: + description: List workspaces + operationId: ListWorkspaces parameters: - - description: Target ID or Name - in: path - name: targetId - required: true - type: string + - description: Verbose + in: query + name: verbose + type: boolean + produces: + - application/json responses: "200": description: OK - summary: Start target + schema: + items: + $ref: '#/definitions/WorkspaceDTO' + type: array + summary: List workspaces tags: - - target - /target/{targetId}/stop: + - workspace post: - description: Stop target - operationId: StopTarget + description: Create a workspace + operationId: CreateWorkspace parameters: - - description: Target ID or Name - in: path - name: targetId + - description: Create workspace + in: body + name: workspace required: true - type: string + schema: + $ref: '#/definitions/CreateWorkspaceDTO' + produces: + - application/json responses: "200": description: OK - summary: Stop target + schema: + $ref: '#/definitions/WorkspaceViewDTO' + summary: Create a workspace tags: - - target + - workspace /workspace-config: get: description: List workspace configs @@ -2542,19 +2541,111 @@ paths: summary: ProcessGitEvent tags: - prebuild - /workspace/{workspaceId}/{projectId}/toolbox/files: + /workspace/{workspaceId}: delete: - description: Delete file inside workspace project - operationId: FsDeleteFile + description: Remove workspace + operationId: RemoveWorkspace + parameters: + - description: Workspace ID + in: path + name: workspaceId + required: true + type: string + - description: Force + in: query + name: force + type: boolean + responses: + "200": + description: OK + summary: Remove workspace + tags: + - workspace + get: + description: Get workspace info + operationId: GetWorkspace parameters: - description: Workspace ID or Name in: path name: workspaceId required: true type: string - - description: Project ID + - description: Verbose + in: query + name: verbose + type: boolean + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/WorkspaceDTO' + summary: Get workspace info + tags: + - workspace + /workspace/{workspaceId}/start: + post: + description: Start workspace + operationId: StartWorkspace + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + type: string + responses: + "200": + description: OK + summary: Start workspace + tags: + - workspace + /workspace/{workspaceId}/state: + post: + description: Set workspace state + operationId: SetWorkspaceState + parameters: + - description: Workspace ID in: path - name: projectId + name: workspaceId + required: true + type: string + - description: Set State + in: body + name: setState + required: true + schema: + $ref: '#/definitions/SetWorkspaceState' + responses: + "200": + description: OK + summary: Set workspace state + tags: + - workspace + /workspace/{workspaceId}/stop: + post: + description: Stop workspace + operationId: StopWorkspace + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + type: string + responses: + "200": + description: OK + summary: Stop workspace + tags: + - workspace + /workspace/{workspaceId}/toolbox/files: + delete: + description: Delete file inside a workspace + operationId: FsDeleteFile + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId required: true type: string - description: Path @@ -2571,7 +2662,7 @@ paths: tags: - workspace toolbox get: - description: List files inside workspace project + description: List files inside a workspace operationId: FsListFiles parameters: - description: Workspace ID or Name @@ -2579,11 +2670,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2600,9 +2686,9 @@ paths: summary: List files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/download: + /workspace/{workspaceId}/toolbox/files/download: get: - description: Download file from workspace project + description: Download file from a workspace operationId: FsDownloadFile parameters: - description: Workspace ID or Name @@ -2610,11 +2696,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2630,9 +2711,9 @@ paths: summary: Download file tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/find: + /workspace/{workspaceId}/toolbox/files/find: get: - description: Search for text/pattern inside workspace project files + description: Search for text/pattern inside a workspace files operationId: FsFindInFiles parameters: - description: Workspace ID or Name @@ -2640,11 +2721,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2667,9 +2743,9 @@ paths: summary: Search for text/pattern in files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/folder: + /workspace/{workspaceId}/toolbox/files/folder: post: - description: Create folder inside workspace project + description: Create folder inside a workspace operationId: FsCreateFolder parameters: - description: Workspace ID or Name @@ -2677,11 +2753,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2700,9 +2771,9 @@ paths: summary: Create folder tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/info: + /workspace/{workspaceId}/toolbox/files/info: get: - description: Get file info inside workspace project + description: Get file info inside a workspace operationId: FsGetFileDetails parameters: - description: Workspace ID or Name @@ -2710,11 +2781,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2730,9 +2796,9 @@ paths: summary: Get file info tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/move: + /workspace/{workspaceId}/toolbox/files/move: post: - description: Create folder inside workspace project + description: Create folder inside a workspace operationId: FsMoveFile parameters: - description: Workspace ID or Name @@ -2740,11 +2806,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Source path in: query name: source @@ -2763,9 +2824,9 @@ paths: summary: Create folder tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/permissions: + /workspace/{workspaceId}/toolbox/files/permissions: post: - description: Set file owner/group/permissions inside workspace project + description: Set file owner/group/permissions inside a workspace operationId: FsSetFilePermissions parameters: - description: Workspace ID or Name @@ -2773,11 +2834,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2803,9 +2859,9 @@ paths: summary: Set file owner/group/permissions tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/replace: + /workspace/{workspaceId}/toolbox/files/replace: post: - description: Repleace text/pattern in mutilple files inside workspace project + description: Repleace text/pattern in mutilple files inside a workspace operationId: FsReplaceInFiles parameters: - description: Workspace ID or Name @@ -2813,11 +2869,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: ReplaceParams in: body name: replace @@ -2836,9 +2887,9 @@ paths: summary: Repleace text/pattern in files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/search: + /workspace/{workspaceId}/toolbox/files/search: get: - description: Search for files inside workspace project + description: Search for files inside a workspace operationId: FsSearchFiles parameters: - description: Workspace ID or Name @@ -2846,11 +2897,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2871,9 +2917,9 @@ paths: summary: Search for files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/upload: + /workspace/{workspaceId}/toolbox/files/upload: post: - description: Upload file inside workspace project + description: Upload file inside a workspace operationId: FsUploadFile parameters: - description: Workspace ID or Name @@ -2881,11 +2927,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path in: query name: path @@ -2904,7 +2945,7 @@ paths: summary: Upload file tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/add: + /workspace/{workspaceId}/toolbox/git/add: post: description: Add files to git commit operationId: GitAddFiles @@ -2914,11 +2955,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: GitAddRequest in: body name: params @@ -2933,9 +2969,9 @@ paths: summary: Add files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/branches: + /workspace/{workspaceId}/toolbox/git/branches: get: - description: Get branch list from git repository inside workspace project + description: Get branch list from git repository inside a workspace operationId: GitBranchList parameters: - description: Workspace ID or Name @@ -2943,11 +2979,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path to git repository in: query name: path @@ -2964,7 +2995,7 @@ paths: tags: - workspace toolbox post: - description: Create branch on git repository inside workspace project + description: Create branch on git repository inside a workspace operationId: GitCreateBranch parameters: - description: Workspace ID or Name @@ -2972,11 +3003,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: GitBranchRequest in: body name: params @@ -2991,9 +3017,9 @@ paths: summary: Create branch tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/clone: + /workspace/{workspaceId}/toolbox/git/clone: post: - description: Clone git repository inside workspace project + description: Clone git repository inside a workspace operationId: GitCloneRepository parameters: - description: Workspace ID or Name @@ -3001,11 +3027,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: GitCloneRequest in: body name: params @@ -3020,9 +3041,9 @@ paths: summary: Clone git repository tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/commit: + /workspace/{workspaceId}/toolbox/git/commit: post: - description: Commit changes to git repository inside workspace project + description: Commit changes to git repository inside a workspace operationId: GitCommitChanges parameters: - description: Workspace ID or Name @@ -3030,11 +3051,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: GitCommitRequest in: body name: params @@ -3051,9 +3067,9 @@ paths: summary: Commit changes tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/history: + /workspace/{workspaceId}/toolbox/git/history: get: - description: Get commit history from git repository inside workspace project + description: Get commit history from git repository inside a workspace operationId: GitCommitHistory parameters: - description: Workspace ID or Name @@ -3061,11 +3077,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path to git repository in: query name: path @@ -3083,9 +3094,9 @@ paths: summary: Get commit history tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/pull: + /workspace/{workspaceId}/toolbox/git/pull: post: - description: Pull changes from remote to git repository inside workspace project + description: Pull changes from remote to git repository inside a workspace operationId: GitPullChanges parameters: - description: Workspace ID or Name @@ -3093,11 +3104,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Git pull request in: body name: params @@ -3112,9 +3118,9 @@ paths: summary: Pull changes tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/push: + /workspace/{workspaceId}/toolbox/git/push: post: - description: Push changes to remote from git repository inside workspace project + description: Push changes to remote from git repository inside a workspace operationId: GitPushChanges parameters: - description: Workspace ID or Name @@ -3122,11 +3128,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Git push request in: body name: params @@ -3141,9 +3142,9 @@ paths: summary: Push changes tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/status: + /workspace/{workspaceId}/toolbox/git/status: get: - description: Get status from git repository inside workspace project + description: Get status from git repository inside a workspace operationId: GitGitStatus parameters: - description: Workspace ID or Name @@ -3151,11 +3152,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Path to git repository in: query name: path @@ -3171,7 +3167,7 @@ paths: summary: Get git status tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/completions: + /workspace/{workspaceId}/toolbox/lsp/completions: post: description: The Completion request is sent from the client to the server to compute completion items at a given cursor position. @@ -3182,11 +3178,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: LspCompletionParams in: body name: params @@ -3203,7 +3194,7 @@ paths: summary: Get Lsp Completions tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close: + /workspace/{workspaceId}/toolbox/lsp/did-close: post: description: The document close notification is sent from the client to the server when the document got closed in the client. @@ -3214,11 +3205,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: LspDocumentRequest in: body name: params @@ -3233,7 +3219,7 @@ paths: summary: Call Lsp DidClose tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open: + /workspace/{workspaceId}/toolbox/lsp/did-open: post: description: The document open notification is sent from the client to the server to signal newly opened text documents. @@ -3244,11 +3230,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: LspDocumentRequest in: body name: params @@ -3263,7 +3244,7 @@ paths: summary: Call Lsp DidOpen tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols: + /workspace/{workspaceId}/toolbox/lsp/document-symbols: get: description: The document symbol request is sent from the client to the server. operationId: LspDocumentSymbols @@ -3273,11 +3254,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Language ID in: query name: languageId @@ -3305,9 +3281,9 @@ paths: summary: Call Lsp DocumentSymbols tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/start: + /workspace/{workspaceId}/toolbox/lsp/start: post: - description: Start Lsp server process inside workspace project + description: Start Lsp server process inside a workspace operationId: LspStart parameters: - description: Workspace ID or Name @@ -3315,11 +3291,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: LspServerRequest in: body name: params @@ -3334,9 +3305,9 @@ paths: summary: Start Lsp server tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/stop: + /workspace/{workspaceId}/toolbox/lsp/stop: post: - description: Stop Lsp server process inside workspace project + description: Stop Lsp server process inside a workspace operationId: LspStop parameters: - description: Workspace ID or Name @@ -3344,11 +3315,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: LspServerRequest in: body name: params @@ -3363,7 +3329,7 @@ paths: summary: Stop Lsp server tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols: + /workspace/{workspaceId}/toolbox/lsp/workspace-symbols: get: description: The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string. @@ -3374,11 +3340,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Language ID in: query name: languageId @@ -3406,9 +3367,9 @@ paths: summary: Call Lsp WorkspaceSymbols tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/execute: + /workspace/{workspaceId}/toolbox/process/execute: post: - description: Execute command synchronously inside workspace project + description: Execute command synchronously inside a workspace operationId: ProcessExecuteCommand parameters: - description: Workspace ID or Name @@ -3416,11 +3377,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Execute command request in: body name: params @@ -3437,7 +3393,7 @@ paths: summary: Execute command tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/session: + /workspace/{workspaceId}/toolbox/process/session: get: description: List sessions inside workspace project operationId: ListSessions @@ -3447,11 +3403,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string produces: - application/json responses: @@ -3473,11 +3424,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Create session request in: body name: params @@ -3492,7 +3438,7 @@ paths: summary: Create exec session tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}: + /workspace/{workspaceId}/toolbox/process/session/{sessionId}: delete: description: Delete a session inside workspace project operationId: DeleteSession @@ -3502,11 +3448,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Session ID in: path name: sessionId @@ -3520,7 +3461,7 @@ paths: summary: Delete session tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs: + /workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs: get: description: |- Get logs of a command inside a session inside workspace project @@ -3532,11 +3473,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Session ID in: path name: sessionId @@ -3555,7 +3491,7 @@ paths: summary: Get session command logs tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec: + /workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec: post: description: Execute command inside a session inside workspace project operationId: SessionExecuteCommand @@ -3565,11 +3501,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string - description: Session ID in: path name: sessionId @@ -3591,7 +3522,7 @@ paths: summary: Execute command in session tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir: + /workspace/{workspaceId}/toolbox/workspace-dir: get: description: Get workspace directory operationId: GetWorkspaceDir @@ -3601,11 +3532,6 @@ paths: name: workspaceId required: true type: string - - description: Project ID - in: path - name: projectId - required: true - type: string produces: - application/json responses: diff --git a/pkg/api/server.go b/pkg/api/server.go index 896b575f77..5fa8554437 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -45,6 +45,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/server" "github.com/daytonaio/daytona/pkg/api/controllers/target" "github.com/daytonaio/daytona/pkg/api/controllers/targetconfig" + "github.com/daytonaio/daytona/pkg/api/controllers/workspace" "github.com/daytonaio/daytona/pkg/api/controllers/workspace/toolbox" "github.com/daytonaio/daytona/pkg/api/controllers/workspaceconfig" "github.com/daytonaio/daytona/pkg/api/controllers/workspaceconfig/prebuild" @@ -142,7 +143,17 @@ func (a *ApiServer) Start() error { targetController := protected.Group("/target") { - toolboxController := targetController.Group("/:targetId/:projectId/toolbox") + targetController.GET("/:targetId", target.GetTarget) + targetController.GET("", target.ListTargets) + targetController.POST("", target.CreateTarget) + targetController.POST("/:targetId/start", target.StartTarget) + targetController.POST("/:targetId/stop", target.StopTarget) + targetController.DELETE("/:targetId", target.RemoveTarget) + } + + workspaceController := protected.Group("/workspace") + { + toolboxController := workspaceController.Group("/:workspaceId/toolbox") { toolboxController.GET("/workspace-dir", toolbox.GetWorkspaceDir) @@ -204,14 +215,12 @@ func (a *ApiServer) Start() error { } } - targetController.GET("/:targetId", target.GetTarget) - targetController.GET("", target.ListTargets) - targetController.POST("", target.CreateTarget) - targetController.POST("/:targetId/start", target.StartTarget) - targetController.POST("/:targetId/stop", target.StopTarget) - targetController.DELETE("/:targetId", target.RemoveTarget) - targetController.POST("/:targetId/:workspaceId/start", target.StartWorkspace) - targetController.POST("/:targetId/:workspaceId/stop", target.StopWorkspace) + workspaceController.GET("/:workspaceId", workspace.GetWorkspace) + workspaceController.GET("", workspace.ListWorkspaces) + workspaceController.POST("", workspace.CreateWorkspace) + workspaceController.DELETE("/:workspaceId", workspace.RemoveWorkspace) + workspaceController.POST("/:workspaceId/start", workspace.StartWorkspace) + workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) } workspaceConfigController := protected.Group("/workspace-config") @@ -280,7 +289,7 @@ func (a *ApiServer) Start() error { { logController.GET("/server", log_controller.ReadServerLog) logController.GET("/target/:targetId", log_controller.ReadTargetLog) - logController.GET("/target/:targetId/:workspaceName", log_controller.ReadWorkspaceLog) + logController.GET("/workspace/:workspaceId", log_controller.ReadWorkspaceLog) logController.GET("/build/:buildId", log_controller.ReadBuildLog) } @@ -323,7 +332,7 @@ func (a *ApiServer) Start() error { workspaceGroup := protected.Group("/") workspaceGroup.Use(middlewares.WorkspaceAuthMiddleware()) { - workspaceGroup.POST(targetController.BasePath()+"/:targetId/:workspaceId/state", target.SetWorkspaceState) + workspaceGroup.POST(workspaceController.BasePath()+"/:workspaceId/state", workspace.SetWorkspaceState) } a.httpServer = &http.Server{ diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 766882dbd4..e9e8cf712d 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -126,55 +126,59 @@ Class | Method | HTTP request | Description *TargetAPI* | [**GetTarget**](docs/TargetAPI.md#gettarget) | **Get** /target/{targetId} | Get target info *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets *TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target -*TargetAPI* | [**SetWorkspaceState**](docs/TargetAPI.md#setworkspacestate) | **Post** /target/{targetId}/{workspaceId}/state | Set workspace state *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target -*TargetAPI* | [**StartWorkspace**](docs/TargetAPI.md#startworkspace) | **Post** /target/{targetId}/{workspaceId}/start | Start workspace *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target -*TargetAPI* | [**StopWorkspace**](docs/TargetAPI.md#stopworkspace) | **Post** /target/{targetId}/{workspaceId}/stop | Stop workspace *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs *TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configName} | Remove a target config *TargetConfigAPI* | [**SetDefaultTargetConfig**](docs/TargetConfigAPI.md#setdefaulttargetconfig) | **Patch** /target-config/{configName}/set-default | Set target config to default *TargetConfigAPI* | [**SetTargetConfig**](docs/TargetConfigAPI.md#settargetconfig) | **Put** /target-config | Set a target config +*WorkspaceAPI* | [**CreateWorkspace**](docs/WorkspaceAPI.md#createworkspace) | **Post** /workspace | Create a workspace +*WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info +*WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces +*WorkspaceAPI* | [**RemoveWorkspace**](docs/WorkspaceAPI.md#removeworkspace) | **Delete** /workspace/{workspaceId} | Remove workspace +*WorkspaceAPI* | [**SetWorkspaceState**](docs/WorkspaceAPI.md#setworkspacestate) | **Post** /workspace/{workspaceId}/state | Set workspace state +*WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace +*WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace *WorkspaceConfigAPI* | [**DeleteWorkspaceConfig**](docs/WorkspaceConfigAPI.md#deleteworkspaceconfig) | **Delete** /workspace-config/{configName} | Delete workspace config data *WorkspaceConfigAPI* | [**GetDefaultWorkspaceConfig**](docs/WorkspaceConfigAPI.md#getdefaultworkspaceconfig) | **Get** /workspace-config/default/{gitUrl} | Get workspace configs by git url *WorkspaceConfigAPI* | [**GetWorkspaceConfig**](docs/WorkspaceConfigAPI.md#getworkspaceconfig) | **Get** /workspace-config/{configName} | Get workspace config data *WorkspaceConfigAPI* | [**ListWorkspaceConfigs**](docs/WorkspaceConfigAPI.md#listworkspaceconfigs) | **Get** /workspace-config | List workspace configs *WorkspaceConfigAPI* | [**SetDefaultWorkspaceConfig**](docs/WorkspaceConfigAPI.md#setdefaultworkspaceconfig) | **Patch** /workspace-config/{configName}/set-default | Set workspace config to default *WorkspaceConfigAPI* | [**SetWorkspaceConfig**](docs/WorkspaceConfigAPI.md#setworkspaceconfig) | **Put** /workspace-config | Set workspace config data -*WorkspaceToolboxAPI* | [**CreateSession**](docs/WorkspaceToolboxAPI.md#createsession) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/session | Create exec session -*WorkspaceToolboxAPI* | [**DeleteSession**](docs/WorkspaceToolboxAPI.md#deletesession) | **Delete** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId} | Delete session -*WorkspaceToolboxAPI* | [**FsCreateFolder**](docs/WorkspaceToolboxAPI.md#fscreatefolder) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/folder | Create folder -*WorkspaceToolboxAPI* | [**FsDeleteFile**](docs/WorkspaceToolboxAPI.md#fsdeletefile) | **Delete** /workspace/{workspaceId}/{projectId}/toolbox/files | Delete file -*WorkspaceToolboxAPI* | [**FsDownloadFile**](docs/WorkspaceToolboxAPI.md#fsdownloadfile) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/download | Download file -*WorkspaceToolboxAPI* | [**FsFindInFiles**](docs/WorkspaceToolboxAPI.md#fsfindinfiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/find | Search for text/pattern in files -*WorkspaceToolboxAPI* | [**FsGetFileDetails**](docs/WorkspaceToolboxAPI.md#fsgetfiledetails) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/info | Get file info -*WorkspaceToolboxAPI* | [**FsListFiles**](docs/WorkspaceToolboxAPI.md#fslistfiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files | List files -*WorkspaceToolboxAPI* | [**FsMoveFile**](docs/WorkspaceToolboxAPI.md#fsmovefile) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/move | Create folder -*WorkspaceToolboxAPI* | [**FsReplaceInFiles**](docs/WorkspaceToolboxAPI.md#fsreplaceinfiles) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/replace | Repleace text/pattern in files -*WorkspaceToolboxAPI* | [**FsSearchFiles**](docs/WorkspaceToolboxAPI.md#fssearchfiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/search | Search for files -*WorkspaceToolboxAPI* | [**FsSetFilePermissions**](docs/WorkspaceToolboxAPI.md#fssetfilepermissions) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/permissions | Set file owner/group/permissions -*WorkspaceToolboxAPI* | [**FsUploadFile**](docs/WorkspaceToolboxAPI.md#fsuploadfile) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/upload | Upload file -*WorkspaceToolboxAPI* | [**GetSessionCommandLogs**](docs/WorkspaceToolboxAPI.md#getsessioncommandlogs) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs | Get session command logs -*WorkspaceToolboxAPI* | [**GetWorkspaceDir**](docs/WorkspaceToolboxAPI.md#getworkspacedir) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir | Get workspace dir -*WorkspaceToolboxAPI* | [**GitAddFiles**](docs/WorkspaceToolboxAPI.md#gitaddfiles) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/add | Add files -*WorkspaceToolboxAPI* | [**GitBranchList**](docs/WorkspaceToolboxAPI.md#gitbranchlist) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/branches | Get branch list -*WorkspaceToolboxAPI* | [**GitCloneRepository**](docs/WorkspaceToolboxAPI.md#gitclonerepository) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/clone | Clone git repository -*WorkspaceToolboxAPI* | [**GitCommitChanges**](docs/WorkspaceToolboxAPI.md#gitcommitchanges) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/commit | Commit changes -*WorkspaceToolboxAPI* | [**GitCommitHistory**](docs/WorkspaceToolboxAPI.md#gitcommithistory) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/history | Get commit history -*WorkspaceToolboxAPI* | [**GitCreateBranch**](docs/WorkspaceToolboxAPI.md#gitcreatebranch) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/branches | Create branch -*WorkspaceToolboxAPI* | [**GitGitStatus**](docs/WorkspaceToolboxAPI.md#gitgitstatus) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/status | Get git status -*WorkspaceToolboxAPI* | [**GitPullChanges**](docs/WorkspaceToolboxAPI.md#gitpullchanges) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/pull | Pull changes -*WorkspaceToolboxAPI* | [**GitPushChanges**](docs/WorkspaceToolboxAPI.md#gitpushchanges) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/push | Push changes -*WorkspaceToolboxAPI* | [**ListSessions**](docs/WorkspaceToolboxAPI.md#listsessions) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/process/session | List sessions -*WorkspaceToolboxAPI* | [**LspCompletions**](docs/WorkspaceToolboxAPI.md#lspcompletions) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/completions | Get Lsp Completions -*WorkspaceToolboxAPI* | [**LspDidClose**](docs/WorkspaceToolboxAPI.md#lspdidclose) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close | Call Lsp DidClose -*WorkspaceToolboxAPI* | [**LspDidOpen**](docs/WorkspaceToolboxAPI.md#lspdidopen) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open | Call Lsp DidOpen -*WorkspaceToolboxAPI* | [**LspDocumentSymbols**](docs/WorkspaceToolboxAPI.md#lspdocumentsymbols) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols | Call Lsp DocumentSymbols -*WorkspaceToolboxAPI* | [**LspStart**](docs/WorkspaceToolboxAPI.md#lspstart) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/start | Start Lsp server -*WorkspaceToolboxAPI* | [**LspStop**](docs/WorkspaceToolboxAPI.md#lspstop) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/stop | Stop Lsp server -*WorkspaceToolboxAPI* | [**LspWorkspaceSymbols**](docs/WorkspaceToolboxAPI.md#lspworkspacesymbols) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols | Call Lsp WorkspaceSymbols -*WorkspaceToolboxAPI* | [**ProcessExecuteCommand**](docs/WorkspaceToolboxAPI.md#processexecutecommand) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/execute | Execute command -*WorkspaceToolboxAPI* | [**SessionExecuteCommand**](docs/WorkspaceToolboxAPI.md#sessionexecutecommand) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec | Execute command in session +*WorkspaceToolboxAPI* | [**CreateSession**](docs/WorkspaceToolboxAPI.md#createsession) | **Post** /workspace/{workspaceId}/toolbox/process/session | Create exec session +*WorkspaceToolboxAPI* | [**DeleteSession**](docs/WorkspaceToolboxAPI.md#deletesession) | **Delete** /workspace/{workspaceId}/toolbox/process/session/{sessionId} | Delete session +*WorkspaceToolboxAPI* | [**FsCreateFolder**](docs/WorkspaceToolboxAPI.md#fscreatefolder) | **Post** /workspace/{workspaceId}/toolbox/files/folder | Create folder +*WorkspaceToolboxAPI* | [**FsDeleteFile**](docs/WorkspaceToolboxAPI.md#fsdeletefile) | **Delete** /workspace/{workspaceId}/toolbox/files | Delete file +*WorkspaceToolboxAPI* | [**FsDownloadFile**](docs/WorkspaceToolboxAPI.md#fsdownloadfile) | **Get** /workspace/{workspaceId}/toolbox/files/download | Download file +*WorkspaceToolboxAPI* | [**FsFindInFiles**](docs/WorkspaceToolboxAPI.md#fsfindinfiles) | **Get** /workspace/{workspaceId}/toolbox/files/find | Search for text/pattern in files +*WorkspaceToolboxAPI* | [**FsGetFileDetails**](docs/WorkspaceToolboxAPI.md#fsgetfiledetails) | **Get** /workspace/{workspaceId}/toolbox/files/info | Get file info +*WorkspaceToolboxAPI* | [**FsListFiles**](docs/WorkspaceToolboxAPI.md#fslistfiles) | **Get** /workspace/{workspaceId}/toolbox/files | List files +*WorkspaceToolboxAPI* | [**FsMoveFile**](docs/WorkspaceToolboxAPI.md#fsmovefile) | **Post** /workspace/{workspaceId}/toolbox/files/move | Create folder +*WorkspaceToolboxAPI* | [**FsReplaceInFiles**](docs/WorkspaceToolboxAPI.md#fsreplaceinfiles) | **Post** /workspace/{workspaceId}/toolbox/files/replace | Repleace text/pattern in files +*WorkspaceToolboxAPI* | [**FsSearchFiles**](docs/WorkspaceToolboxAPI.md#fssearchfiles) | **Get** /workspace/{workspaceId}/toolbox/files/search | Search for files +*WorkspaceToolboxAPI* | [**FsSetFilePermissions**](docs/WorkspaceToolboxAPI.md#fssetfilepermissions) | **Post** /workspace/{workspaceId}/toolbox/files/permissions | Set file owner/group/permissions +*WorkspaceToolboxAPI* | [**FsUploadFile**](docs/WorkspaceToolboxAPI.md#fsuploadfile) | **Post** /workspace/{workspaceId}/toolbox/files/upload | Upload file +*WorkspaceToolboxAPI* | [**GetSessionCommandLogs**](docs/WorkspaceToolboxAPI.md#getsessioncommandlogs) | **Get** /workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs | Get session command logs +*WorkspaceToolboxAPI* | [**GetWorkspaceDir**](docs/WorkspaceToolboxAPI.md#getworkspacedir) | **Get** /workspace/{workspaceId}/toolbox/workspace-dir | Get workspace dir +*WorkspaceToolboxAPI* | [**GitAddFiles**](docs/WorkspaceToolboxAPI.md#gitaddfiles) | **Post** /workspace/{workspaceId}/toolbox/git/add | Add files +*WorkspaceToolboxAPI* | [**GitBranchList**](docs/WorkspaceToolboxAPI.md#gitbranchlist) | **Get** /workspace/{workspaceId}/toolbox/git/branches | Get branch list +*WorkspaceToolboxAPI* | [**GitCloneRepository**](docs/WorkspaceToolboxAPI.md#gitclonerepository) | **Post** /workspace/{workspaceId}/toolbox/git/clone | Clone git repository +*WorkspaceToolboxAPI* | [**GitCommitChanges**](docs/WorkspaceToolboxAPI.md#gitcommitchanges) | **Post** /workspace/{workspaceId}/toolbox/git/commit | Commit changes +*WorkspaceToolboxAPI* | [**GitCommitHistory**](docs/WorkspaceToolboxAPI.md#gitcommithistory) | **Get** /workspace/{workspaceId}/toolbox/git/history | Get commit history +*WorkspaceToolboxAPI* | [**GitCreateBranch**](docs/WorkspaceToolboxAPI.md#gitcreatebranch) | **Post** /workspace/{workspaceId}/toolbox/git/branches | Create branch +*WorkspaceToolboxAPI* | [**GitGitStatus**](docs/WorkspaceToolboxAPI.md#gitgitstatus) | **Get** /workspace/{workspaceId}/toolbox/git/status | Get git status +*WorkspaceToolboxAPI* | [**GitPullChanges**](docs/WorkspaceToolboxAPI.md#gitpullchanges) | **Post** /workspace/{workspaceId}/toolbox/git/pull | Pull changes +*WorkspaceToolboxAPI* | [**GitPushChanges**](docs/WorkspaceToolboxAPI.md#gitpushchanges) | **Post** /workspace/{workspaceId}/toolbox/git/push | Push changes +*WorkspaceToolboxAPI* | [**ListSessions**](docs/WorkspaceToolboxAPI.md#listsessions) | **Get** /workspace/{workspaceId}/toolbox/process/session | List sessions +*WorkspaceToolboxAPI* | [**LspCompletions**](docs/WorkspaceToolboxAPI.md#lspcompletions) | **Post** /workspace/{workspaceId}/toolbox/lsp/completions | Get Lsp Completions +*WorkspaceToolboxAPI* | [**LspDidClose**](docs/WorkspaceToolboxAPI.md#lspdidclose) | **Post** /workspace/{workspaceId}/toolbox/lsp/did-close | Call Lsp DidClose +*WorkspaceToolboxAPI* | [**LspDidOpen**](docs/WorkspaceToolboxAPI.md#lspdidopen) | **Post** /workspace/{workspaceId}/toolbox/lsp/did-open | Call Lsp DidOpen +*WorkspaceToolboxAPI* | [**LspDocumentSymbols**](docs/WorkspaceToolboxAPI.md#lspdocumentsymbols) | **Get** /workspace/{workspaceId}/toolbox/lsp/document-symbols | Call Lsp DocumentSymbols +*WorkspaceToolboxAPI* | [**LspStart**](docs/WorkspaceToolboxAPI.md#lspstart) | **Post** /workspace/{workspaceId}/toolbox/lsp/start | Start Lsp server +*WorkspaceToolboxAPI* | [**LspStop**](docs/WorkspaceToolboxAPI.md#lspstop) | **Post** /workspace/{workspaceId}/toolbox/lsp/stop | Stop Lsp server +*WorkspaceToolboxAPI* | [**LspWorkspaceSymbols**](docs/WorkspaceToolboxAPI.md#lspworkspacesymbols) | **Get** /workspace/{workspaceId}/toolbox/lsp/workspace-symbols | Call Lsp WorkspaceSymbols +*WorkspaceToolboxAPI* | [**ProcessExecuteCommand**](docs/WorkspaceToolboxAPI.md#processexecutecommand) | **Post** /workspace/{workspaceId}/toolbox/process/execute | Execute command +*WorkspaceToolboxAPI* | [**SessionExecuteCommand**](docs/WorkspaceToolboxAPI.md#sessionexecutecommand) | **Post** /workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec | Execute command in session ## Documentation For Models @@ -258,11 +262,12 @@ Class | Method | HTTP request | Description - [TargetConfigProperty](docs/TargetConfigProperty.md) - [TargetDTO](docs/TargetDTO.md) - [TargetInfo](docs/TargetInfo.md) - - [Workspace](docs/Workspace.md) - [WorkspaceConfig](docs/WorkspaceConfig.md) + - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) - [WorkspaceInfo](docs/WorkspaceInfo.md) - [WorkspaceState](docs/WorkspaceState.md) + - [WorkspaceViewDTO](docs/WorkspaceViewDTO.md) ## Documentation For Authorization diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 5df465f00c..66b87565ef 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -1012,86 +1012,49 @@ paths: summary: Stop target tags: - target - /target/{targetId}/{workspaceId}/start: - post: - description: Start workspace - operationId: StartWorkspace + /workspace: + get: + description: List workspaces + operationId: ListWorkspaces parameters: - - description: Target ID or Name - in: path - name: targetId - required: true - schema: - type: string - - description: Workspace ID - in: path - name: workspaceId - required: true + - description: Verbose + in: query + name: verbose schema: - type: string + type: boolean responses: "200": - content: {} + content: + application/json: + schema: + items: + $ref: '#/components/schemas/WorkspaceDTO' + type: array description: OK - summary: Start workspace + summary: List workspaces tags: - - target - /target/{targetId}/{workspaceId}/state: + - workspace post: - description: Set workspace state - operationId: SetWorkspaceState - parameters: - - description: Target ID or Name - in: path - name: targetId - required: true - schema: - type: string - - description: Workspace ID - in: path - name: workspaceId - required: true - schema: - type: string + description: Create a workspace + operationId: CreateWorkspace requestBody: content: '*/*': schema: - $ref: '#/components/schemas/SetWorkspaceState' - description: Set State - required: true - responses: - "200": - content: {} - description: OK - summary: Set workspace state - tags: - - target - x-codegen-request-body-name: setState - /target/{targetId}/{workspaceId}/stop: - post: - description: Stop workspace - operationId: StopWorkspace - parameters: - - description: Target ID or Name - in: path - name: targetId - required: true - schema: - type: string - - description: Workspace ID - in: path - name: workspaceId + $ref: '#/components/schemas/CreateWorkspaceDTO' + description: Create workspace required: true - schema: - type: string responses: "200": - content: {} + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceViewDTO' description: OK - summary: Stop workspace + summary: Create a workspace tags: - - target + - workspace + x-codegen-request-body-name: workspace /workspace-config: get: description: List workspace configs @@ -1349,10 +1312,102 @@ paths: summary: Set workspace config to default tags: - workspace-config - /workspace/{workspaceId}/{projectId}/toolbox/files: + /workspace/{workspaceId}: delete: - description: Delete file inside workspace project - operationId: FsDeleteFile + description: Remove workspace + operationId: RemoveWorkspace + parameters: + - description: Workspace ID + in: path + name: workspaceId + required: true + schema: + type: string + - description: Force + in: query + name: force + schema: + type: boolean + responses: + "200": + content: {} + description: OK + summary: Remove workspace + tags: + - workspace + get: + description: Get workspace info + operationId: GetWorkspace + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + schema: + type: string + - description: Verbose + in: query + name: verbose + schema: + type: boolean + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceDTO' + description: OK + summary: Get workspace info + tags: + - workspace + /workspace/{workspaceId}/start: + post: + description: Start workspace + operationId: StartWorkspace + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Start workspace + tags: + - workspace + /workspace/{workspaceId}/state: + post: + description: Set workspace state + operationId: SetWorkspaceState + parameters: + - description: Workspace ID + in: path + name: workspaceId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/SetWorkspaceState' + description: Set State + required: true + responses: + "200": + content: {} + description: OK + summary: Set workspace state + tags: + - workspace + x-codegen-request-body-name: setState + /workspace/{workspaceId}/stop: + post: + description: Stop workspace + operationId: StopWorkspace parameters: - description: Workspace ID or Name in: path @@ -1360,9 +1415,21 @@ paths: required: true schema: type: string - - description: Project ID + responses: + "200": + content: {} + description: OK + summary: Stop workspace + tags: + - workspace + /workspace/{workspaceId}/toolbox/files: + delete: + description: Delete file inside a workspace + operationId: FsDeleteFile + parameters: + - description: Workspace ID or Name in: path - name: projectId + name: workspaceId required: true schema: type: string @@ -1380,7 +1447,7 @@ paths: tags: - workspace toolbox get: - description: List files inside workspace project + description: List files inside a workspace operationId: FsListFiles parameters: - description: Workspace ID or Name @@ -1389,12 +1456,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1412,9 +1473,9 @@ paths: summary: List files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/download: + /workspace/{workspaceId}/toolbox/files/download: get: - description: Download file from workspace project + description: Download file from a workspace operationId: FsDownloadFile parameters: - description: Workspace ID or Name @@ -1423,12 +1484,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1446,9 +1501,9 @@ paths: summary: Download file tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/find: + /workspace/{workspaceId}/toolbox/files/find: get: - description: Search for text/pattern inside workspace project files + description: Search for text/pattern inside a workspace files operationId: FsFindInFiles parameters: - description: Workspace ID or Name @@ -1457,12 +1512,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1487,9 +1536,9 @@ paths: summary: Search for text/pattern in files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/folder: + /workspace/{workspaceId}/toolbox/files/folder: post: - description: Create folder inside workspace project + description: Create folder inside a workspace operationId: FsCreateFolder parameters: - description: Workspace ID or Name @@ -1498,12 +1547,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1523,9 +1566,9 @@ paths: summary: Create folder tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/info: + /workspace/{workspaceId}/toolbox/files/info: get: - description: Get file info inside workspace project + description: Get file info inside a workspace operationId: FsGetFileDetails parameters: - description: Workspace ID or Name @@ -1534,12 +1577,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1556,9 +1593,9 @@ paths: summary: Get file info tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/move: + /workspace/{workspaceId}/toolbox/files/move: post: - description: Create folder inside workspace project + description: Create folder inside a workspace operationId: FsMoveFile parameters: - description: Workspace ID or Name @@ -1567,12 +1604,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Source path in: query name: source @@ -1592,9 +1623,9 @@ paths: summary: Create folder tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/permissions: + /workspace/{workspaceId}/toolbox/files/permissions: post: - description: Set file owner/group/permissions inside workspace project + description: Set file owner/group/permissions inside a workspace operationId: FsSetFilePermissions parameters: - description: Workspace ID or Name @@ -1603,12 +1634,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1637,9 +1662,9 @@ paths: summary: Set file owner/group/permissions tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/replace: + /workspace/{workspaceId}/toolbox/files/replace: post: - description: Repleace text/pattern in mutilple files inside workspace project + description: Repleace text/pattern in mutilple files inside a workspace operationId: FsReplaceInFiles parameters: - description: Workspace ID or Name @@ -1648,12 +1673,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -1674,9 +1693,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: replace - /workspace/{workspaceId}/{projectId}/toolbox/files/search: + /workspace/{workspaceId}/toolbox/files/search: get: - description: Search for files inside workspace project + description: Search for files inside a workspace operationId: FsSearchFiles parameters: - description: Workspace ID or Name @@ -1685,12 +1704,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1713,9 +1726,9 @@ paths: summary: Search for files tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/files/upload: + /workspace/{workspaceId}/toolbox/files/upload: post: - description: Upload file inside workspace project + description: Upload file inside a workspace operationId: FsUploadFile parameters: - description: Workspace ID or Name @@ -1724,12 +1737,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path in: query name: path @@ -1749,7 +1756,7 @@ paths: summary: Upload file tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/add: + /workspace/{workspaceId}/toolbox/git/add: post: description: Add files to git commit operationId: GitAddFiles @@ -1760,12 +1767,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -1781,9 +1782,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/git/branches: + /workspace/{workspaceId}/toolbox/git/branches: get: - description: Get branch list from git repository inside workspace project + description: Get branch list from git repository inside a workspace operationId: GitBranchList parameters: - description: Workspace ID or Name @@ -1792,12 +1793,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path to git repository in: query name: path @@ -1815,7 +1810,7 @@ paths: tags: - workspace toolbox post: - description: Create branch on git repository inside workspace project + description: Create branch on git repository inside a workspace operationId: GitCreateBranch parameters: - description: Workspace ID or Name @@ -1824,12 +1819,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -1845,9 +1834,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/git/clone: + /workspace/{workspaceId}/toolbox/git/clone: post: - description: Clone git repository inside workspace project + description: Clone git repository inside a workspace operationId: GitCloneRepository parameters: - description: Workspace ID or Name @@ -1856,12 +1845,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -1877,9 +1860,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/git/commit: + /workspace/{workspaceId}/toolbox/git/commit: post: - description: Commit changes to git repository inside workspace project + description: Commit changes to git repository inside a workspace operationId: GitCommitChanges parameters: - description: Workspace ID or Name @@ -1888,12 +1871,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -1912,9 +1889,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/git/history: + /workspace/{workspaceId}/toolbox/git/history: get: - description: Get commit history from git repository inside workspace project + description: Get commit history from git repository inside a workspace operationId: GitCommitHistory parameters: - description: Workspace ID or Name @@ -1923,12 +1900,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path to git repository in: query name: path @@ -1947,9 +1918,9 @@ paths: summary: Get commit history tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/git/pull: + /workspace/{workspaceId}/toolbox/git/pull: post: - description: Pull changes from remote to git repository inside workspace project + description: Pull changes from remote to git repository inside a workspace operationId: GitPullChanges parameters: - description: Workspace ID or Name @@ -1958,12 +1929,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -1979,9 +1944,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/git/push: + /workspace/{workspaceId}/toolbox/git/push: post: - description: Push changes to remote from git repository inside workspace project + description: Push changes to remote from git repository inside a workspace operationId: GitPushChanges parameters: - description: Workspace ID or Name @@ -1990,12 +1955,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2011,9 +1970,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/git/status: + /workspace/{workspaceId}/toolbox/git/status: get: - description: Get status from git repository inside workspace project + description: Get status from git repository inside a workspace operationId: GitGitStatus parameters: - description: Workspace ID or Name @@ -2022,12 +1981,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Path to git repository in: query name: path @@ -2044,7 +1997,7 @@ paths: summary: Get git status tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/completions: + /workspace/{workspaceId}/toolbox/lsp/completions: post: description: The Completion request is sent from the client to the server to compute completion items at a given cursor position. @@ -2056,12 +2009,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2080,7 +2027,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close: + /workspace/{workspaceId}/toolbox/lsp/did-close: post: description: The document close notification is sent from the client to the server when the document got closed in the client. @@ -2092,12 +2039,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2113,7 +2054,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open: + /workspace/{workspaceId}/toolbox/lsp/did-open: post: description: The document open notification is sent from the client to the server to signal newly opened text documents. @@ -2125,12 +2066,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2146,7 +2081,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols: + /workspace/{workspaceId}/toolbox/lsp/document-symbols: get: description: The document symbol request is sent from the client to the server. operationId: LspDocumentSymbols @@ -2157,12 +2092,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Language ID in: query name: languageId @@ -2193,9 +2122,9 @@ paths: summary: Call Lsp DocumentSymbols tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/lsp/start: + /workspace/{workspaceId}/toolbox/lsp/start: post: - description: Start Lsp server process inside workspace project + description: Start Lsp server process inside a workspace operationId: LspStart parameters: - description: Workspace ID or Name @@ -2204,12 +2133,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2225,9 +2148,9 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/lsp/stop: + /workspace/{workspaceId}/toolbox/lsp/stop: post: - description: Stop Lsp server process inside workspace project + description: Stop Lsp server process inside a workspace operationId: LspStop parameters: - description: Workspace ID or Name @@ -2236,12 +2159,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2257,7 +2174,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols: + /workspace/{workspaceId}/toolbox/lsp/workspace-symbols: get: description: The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string. @@ -2269,12 +2186,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Language ID in: query name: languageId @@ -2305,9 +2216,9 @@ paths: summary: Call Lsp WorkspaceSymbols tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/execute: + /workspace/{workspaceId}/toolbox/process/execute: post: - description: Execute command synchronously inside workspace project + description: Execute command synchronously inside a workspace operationId: ProcessExecuteCommand parameters: - description: Workspace ID or Name @@ -2316,12 +2227,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2340,7 +2245,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/process/session: + /workspace/{workspaceId}/toolbox/process/session: get: description: List sessions inside workspace project operationId: ListSessions @@ -2351,12 +2256,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string responses: "200": content: @@ -2379,12 +2278,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string requestBody: content: '*/*': @@ -2400,7 +2293,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}: + /workspace/{workspaceId}/toolbox/process/session/{sessionId}: delete: description: Delete a session inside workspace project operationId: DeleteSession @@ -2411,12 +2304,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Session ID in: path name: sessionId @@ -2430,7 +2317,7 @@ paths: summary: Delete session tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs: + /workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs: get: description: |- Get logs of a command inside a session inside workspace project @@ -2443,12 +2330,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Session ID in: path name: sessionId @@ -2471,7 +2352,7 @@ paths: summary: Get session command logs tags: - workspace toolbox - /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec: + /workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec: post: description: Execute command inside a session inside workspace project operationId: SessionExecuteCommand @@ -2482,12 +2363,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string - description: Session ID in: path name: sessionId @@ -2512,7 +2387,7 @@ paths: tags: - workspace toolbox x-codegen-request-body-name: params - /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir: + /workspace/{workspaceId}/toolbox/workspace-dir: get: description: Get workspace directory operationId: GetWorkspaceDir @@ -2523,12 +2398,6 @@ paths: required: true schema: type: string - - description: Project ID - in: path - name: projectId - required: true - schema: - type: string responses: "200": content: @@ -2855,55 +2724,6 @@ components: targetConfig: targetConfig name: name id: id - workspaces: - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - envVars: - key: envVars - name: name - source: - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - envVars: - key: envVars - name: name - source: - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user properties: id: type: string @@ -2911,15 +2731,10 @@ components: type: string targetConfig: type: string - workspaces: - items: - $ref: '#/components/schemas/CreateWorkspaceDTO' - type: array required: - id - name - targetConfig - - workspaces type: object CreateWorkspaceConfigDTO: example: @@ -2968,9 +2783,11 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image + targetId: targetId envVars: key: envVars name: name + id: id source: repository: owner: owner @@ -2993,18 +2810,24 @@ components: type: object gitProviderConfigId: type: string + id: + type: string image: type: string name: type: string source: $ref: '#/components/schemas/CreateWorkspaceSourceDTO' + targetId: + type: string user: type: string required: - envVars + - id - name - source + - targetId type: object CreateWorkspaceSourceDTO: example: @@ -4084,91 +3907,6 @@ components: targetConfig: targetConfig name: name id: id - workspaces: - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - targetConfig: targetConfig - targetId: targetId - envVars: - key: envVars - name: name - state: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - targetConfig: targetConfig - targetId: targetId - envVars: - key: envVars - name: name - state: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user properties: id: type: string @@ -4176,15 +3914,10 @@ components: type: string targetConfig: type: string - workspaces: - items: - $ref: '#/components/schemas/Workspace' - type: array required: - id - name - targetConfig - - workspaces type: object TargetConfig: example: @@ -4252,105 +3985,9 @@ components: targetConfig: targetConfig name: name id: id - workspaces: - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - targetConfig: targetConfig - targetId: targetId - envVars: - key: envVars - name: name - state: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - targetConfig: targetConfig - targetId: targetId - envVars: - key: envVars - name: name - state: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user info: providerMetadata: providerMetadata name: name - workspaces: - - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name - - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name properties: id: type: string @@ -4360,45 +3997,86 @@ components: type: string targetConfig: type: string - workspaces: - items: - $ref: '#/components/schemas/Workspace' - type: array required: - id - name - targetConfig - - workspaces type: object TargetInfo: example: providerMetadata: providerMetadata name: name - workspaces: - - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name - - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name properties: name: type: string providerMetadata: type: string - workspaces: + required: + - name + type: object + WorkspaceConfig: + example: + prebuilds: + - commitInterval: 0 + id: id + branch: branch + retention: 6 + triggerFiles: + - triggerFiles + - triggerFiles + - commitInterval: 0 + id: id + branch: branch + retention: 6 + triggerFiles: + - triggerFiles + - triggerFiles + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + default: true + envVars: + key: envVars + name: name + user: user + repositoryUrl: repositoryUrl + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + default: + type: boolean + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + prebuilds: items: - $ref: '#/components/schemas/WorkspaceInfo' + $ref: '#/components/schemas/PrebuildConfig' type: array + repositoryUrl: + type: string + user: + type: string required: + - default + - envVars + - image - name - - workspaces + - repositoryUrl + - user type: object - Workspace: + WorkspaceDTO: example: buildConfig: cachedBuild: @@ -4408,11 +4086,12 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image - targetConfig: targetConfig + targetName: targetName targetId: targetId envVars: key: envVars name: name + id: id state: gitStatus: behind: 6 @@ -4442,6 +4121,12 @@ components: sha: sha url: url user: user + info: + providerMetadata: providerMetadata + targetId: targetId + isRunning: true + created: created + name: name properties: buildConfig: $ref: '#/components/schemas/BuildConfig' @@ -4451,89 +4136,32 @@ components: type: object gitProviderConfigId: type: string + id: + type: string image: type: string + info: + $ref: '#/components/schemas/WorkspaceInfo' name: type: string repository: $ref: '#/components/schemas/GitRepository' state: $ref: '#/components/schemas/WorkspaceState' - targetConfig: - type: string targetId: type: string + targetName: + type: string user: type: string required: - envVars + - id - image - name - repository - - targetConfig - targetId - - user - type: object - WorkspaceConfig: - example: - prebuilds: - - commitInterval: 0 - id: id - branch: branch - retention: 6 - triggerFiles: - - triggerFiles - - triggerFiles - - commitInterval: 0 - id: id - branch: branch - retention: 6 - triggerFiles: - - triggerFiles - - triggerFiles - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - default: true - envVars: - key: envVars - name: name - user: user - repositoryUrl: repositoryUrl - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - default: - type: boolean - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - prebuilds: - items: - $ref: '#/components/schemas/PrebuildConfig' - type: array - repositoryUrl: - type: string - user: - type: string - required: - - default - - envVars - - image - - name - - repositoryUrl + - targetName - user type: object WorkspaceDirResponse: @@ -4596,6 +4224,86 @@ components: - updatedAt - uptime type: object + WorkspaceViewDTO: + example: + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + targetName: targetName + targetId: targetId + envVars: + key: envVars + name: name + id: id + state: + gitStatus: + behind: 6 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 0 + branchPublished: true + currentBranch: currentBranch + updatedAt: updatedAt + uptime: 1 + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + user: user + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + id: + type: string + image: + type: string + name: + type: string + repository: + $ref: '#/components/schemas/GitRepository' + state: + $ref: '#/components/schemas/WorkspaceState' + targetId: + type: string + targetName: + type: string + user: + type: string + required: + - envVars + - id + - image + - name + - repository + - targetId + - targetName + - user + type: object apikey.ApiKeyType: enum: - client diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index d91cad7d3e..8588832924 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -516,128 +516,6 @@ func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http. return localVarHTTPResponse, nil } -type ApiSetWorkspaceStateRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - workspaceId string - setState *SetWorkspaceState -} - -// Set State -func (r ApiSetWorkspaceStateRequest) SetState(setState SetWorkspaceState) ApiSetWorkspaceStateRequest { - r.setState = &setState - return r -} - -func (r ApiSetWorkspaceStateRequest) Execute() (*http.Response, error) { - return r.ApiService.SetWorkspaceStateExecute(r) -} - -/* -SetWorkspaceState Set workspace state - -Set workspace state - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param targetId Target ID or Name - @param workspaceId Workspace ID - @return ApiSetWorkspaceStateRequest -*/ -func (a *TargetAPIService) SetWorkspaceState(ctx context.Context, targetId string, workspaceId string) ApiSetWorkspaceStateRequest { - return ApiSetWorkspaceStateRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, - workspaceId: workspaceId, - } -} - -// Execute executes the request -func (a *TargetAPIService) SetWorkspaceStateExecute(r ApiSetWorkspaceStateRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetWorkspaceState") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/target/{targetId}/{workspaceId}/state" - localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - if r.setState == nil { - return nil, reportError("setState is required and must be specified") - } - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - // body params - localVarPostBody = r.setState - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} - type ApiStartTargetRequest struct { ctx context.Context ApiService *TargetAPIService @@ -744,116 +622,6 @@ func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Re return localVarHTTPResponse, nil } -type ApiStartWorkspaceRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - workspaceId string -} - -func (r ApiStartWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.StartWorkspaceExecute(r) -} - -/* -StartWorkspace Start workspace - -Start workspace - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param targetId Target ID or Name - @param workspaceId Workspace ID - @return ApiStartWorkspaceRequest -*/ -func (a *TargetAPIService) StartWorkspace(ctx context.Context, targetId string, workspaceId string) ApiStartWorkspaceRequest { - return ApiStartWorkspaceRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, - workspaceId: workspaceId, - } -} - -// Execute executes the request -func (a *TargetAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartWorkspace") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/target/{targetId}/{workspaceId}/start" - localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} - type ApiStopTargetRequest struct { ctx context.Context ApiService *TargetAPIService @@ -959,113 +727,3 @@ func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Resp return localVarHTTPResponse, nil } - -type ApiStopWorkspaceRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - workspaceId string -} - -func (r ApiStopWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.StopWorkspaceExecute(r) -} - -/* -StopWorkspace Stop workspace - -Stop workspace - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param targetId Target ID or Name - @param workspaceId Workspace ID - @return ApiStopWorkspaceRequest -*/ -func (a *TargetAPIService) StopWorkspace(ctx context.Context, targetId string, workspaceId string) ApiStopWorkspaceRequest { - return ApiStopWorkspaceRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, - workspaceId: workspaceId, - } -} - -// Execute executes the request -func (a *TargetAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopWorkspace") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/target/{targetId}/{workspaceId}/stop" - localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go new file mode 100644 index 0000000000..60a311eec9 --- /dev/null +++ b/pkg/apiclient/api_workspace.go @@ -0,0 +1,847 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// WorkspaceAPIService WorkspaceAPI service +type WorkspaceAPIService service + +type ApiCreateWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspace *CreateWorkspaceDTO +} + +// Create workspace +func (r ApiCreateWorkspaceRequest) Workspace(workspace CreateWorkspaceDTO) ApiCreateWorkspaceRequest { + r.workspace = &workspace + return r +} + +func (r ApiCreateWorkspaceRequest) Execute() (*WorkspaceViewDTO, *http.Response, error) { + return r.ApiService.CreateWorkspaceExecute(r) +} + +/* +CreateWorkspace Create a workspace + +Create a workspace + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateWorkspaceRequest +*/ +func (a *WorkspaceAPIService) CreateWorkspace(ctx context.Context) ApiCreateWorkspaceRequest { + return ApiCreateWorkspaceRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return WorkspaceViewDTO +func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest) (*WorkspaceViewDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *WorkspaceViewDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.CreateWorkspace") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.workspace == nil { + return localVarReturnValue, nil, reportError("workspace is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.workspace + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + verbose *bool +} + +// Verbose +func (r ApiGetWorkspaceRequest) Verbose(verbose bool) ApiGetWorkspaceRequest { + r.verbose = &verbose + return r +} + +func (r ApiGetWorkspaceRequest) Execute() (*WorkspaceDTO, *http.Response, error) { + return r.ApiService.GetWorkspaceExecute(r) +} + +/* +GetWorkspace Get workspace info + +Get workspace info + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID or Name + @return ApiGetWorkspaceRequest +*/ +func (a *WorkspaceAPIService) GetWorkspace(ctx context.Context, workspaceId string) ApiGetWorkspaceRequest { + return ApiGetWorkspaceRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +// +// @return WorkspaceDTO +func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*WorkspaceDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *WorkspaceDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.GetWorkspace") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.verbose != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "verbose", r.verbose, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListWorkspacesRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + verbose *bool +} + +// Verbose +func (r ApiListWorkspacesRequest) Verbose(verbose bool) ApiListWorkspacesRequest { + r.verbose = &verbose + return r +} + +func (r ApiListWorkspacesRequest) Execute() ([]WorkspaceDTO, *http.Response, error) { + return r.ApiService.ListWorkspacesExecute(r) +} + +/* +ListWorkspaces List workspaces + +List workspaces + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListWorkspacesRequest +*/ +func (a *WorkspaceAPIService) ListWorkspaces(ctx context.Context) ApiListWorkspacesRequest { + return ApiListWorkspacesRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []WorkspaceDTO +func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) ([]WorkspaceDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []WorkspaceDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.ListWorkspaces") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.verbose != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "verbose", r.verbose, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiRemoveWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + force *bool +} + +// Force +func (r ApiRemoveWorkspaceRequest) Force(force bool) ApiRemoveWorkspaceRequest { + r.force = &force + return r +} + +func (r ApiRemoveWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.RemoveWorkspaceExecute(r) +} + +/* +RemoveWorkspace Remove workspace + +Remove workspace + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID + @return ApiRemoveWorkspaceRequest +*/ +func (a *WorkspaceAPIService) RemoveWorkspace(ctx context.Context, workspaceId string) ApiRemoveWorkspaceRequest { + return ApiRemoveWorkspaceRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.RemoveWorkspace") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.force != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "force", r.force, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiSetWorkspaceStateRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + setState *SetWorkspaceState +} + +// Set State +func (r ApiSetWorkspaceStateRequest) SetState(setState SetWorkspaceState) ApiSetWorkspaceStateRequest { + r.setState = &setState + return r +} + +func (r ApiSetWorkspaceStateRequest) Execute() (*http.Response, error) { + return r.ApiService.SetWorkspaceStateExecute(r) +} + +/* +SetWorkspaceState Set workspace state + +Set workspace state + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID + @return ApiSetWorkspaceStateRequest +*/ +func (a *WorkspaceAPIService) SetWorkspaceState(ctx context.Context, workspaceId string) ApiSetWorkspaceStateRequest { + return ApiSetWorkspaceStateRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +func (a *WorkspaceAPIService) SetWorkspaceStateExecute(r ApiSetWorkspaceStateRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.SetWorkspaceState") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}/state" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.setState == nil { + return nil, reportError("setState is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.setState + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiStartWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string +} + +func (r ApiStartWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.StartWorkspaceExecute(r) +} + +/* +StartWorkspace Start workspace + +Start workspace + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID or Name + @return ApiStartWorkspaceRequest +*/ +func (a *WorkspaceAPIService) StartWorkspace(ctx context.Context, workspaceId string) ApiStartWorkspaceRequest { + return ApiStartWorkspaceRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +func (a *WorkspaceAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StartWorkspace") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}/start" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiStopWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string +} + +func (r ApiStopWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.StopWorkspaceExecute(r) +} + +/* +StopWorkspace Stop workspace + +Stop workspace + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID or Name + @return ApiStopWorkspaceRequest +*/ +func (a *WorkspaceAPIService) StopWorkspace(ctx context.Context, workspaceId string) ApiStopWorkspaceRequest { + return ApiStopWorkspaceRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StopWorkspace") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}/stop" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/api_workspace_toolbox.go b/pkg/apiclient/api_workspace_toolbox.go index d32eca5ef3..30535b2a27 100644 --- a/pkg/apiclient/api_workspace_toolbox.go +++ b/pkg/apiclient/api_workspace_toolbox.go @@ -27,7 +27,6 @@ type ApiCreateSessionRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *CreateSessionRequest } @@ -48,15 +47,13 @@ Create exec session inside workspace project @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiCreateSessionRequest */ -func (a *WorkspaceToolboxAPIService) CreateSession(ctx context.Context, workspaceId string, projectId string) ApiCreateSessionRequest { +func (a *WorkspaceToolboxAPIService) CreateSession(ctx context.Context, workspaceId string) ApiCreateSessionRequest { return ApiCreateSessionRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -73,9 +70,8 @@ func (a *WorkspaceToolboxAPIService) CreateSessionExecute(r ApiCreateSessionRequ return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/process/session" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -149,7 +145,6 @@ type ApiDeleteSessionRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string sessionId string } @@ -164,16 +159,14 @@ Delete a session inside workspace project @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @param sessionId Session ID @return ApiDeleteSessionRequest */ -func (a *WorkspaceToolboxAPIService) DeleteSession(ctx context.Context, workspaceId string, projectId string, sessionId string) ApiDeleteSessionRequest { +func (a *WorkspaceToolboxAPIService) DeleteSession(ctx context.Context, workspaceId string, sessionId string) ApiDeleteSessionRequest { return ApiDeleteSessionRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, sessionId: sessionId, } } @@ -191,9 +184,8 @@ func (a *WorkspaceToolboxAPIService) DeleteSessionExecute(r ApiDeleteSessionRequ return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"sessionId"+"}", url.PathEscape(parameterValueToString(r.sessionId, "sessionId")), -1) localVarHeaderParams := make(map[string]string) @@ -263,7 +255,6 @@ type ApiFsCreateFolderRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string mode *string } @@ -287,19 +278,17 @@ func (r ApiFsCreateFolderRequest) Execute() (*http.Response, error) { /* FsCreateFolder Create folder -Create folder inside workspace project +Create folder inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsCreateFolderRequest */ -func (a *WorkspaceToolboxAPIService) FsCreateFolder(ctx context.Context, workspaceId string, projectId string) ApiFsCreateFolderRequest { +func (a *WorkspaceToolboxAPIService) FsCreateFolder(ctx context.Context, workspaceId string) ApiFsCreateFolderRequest { return ApiFsCreateFolderRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -316,9 +305,8 @@ func (a *WorkspaceToolboxAPIService) FsCreateFolderExecute(r ApiFsCreateFolderRe return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/folder" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/folder" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -395,7 +383,6 @@ type ApiFsDeleteFileRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -412,19 +399,17 @@ func (r ApiFsDeleteFileRequest) Execute() (*http.Response, error) { /* FsDeleteFile Delete file -Delete file inside workspace project +Delete file inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsDeleteFileRequest */ -func (a *WorkspaceToolboxAPIService) FsDeleteFile(ctx context.Context, workspaceId string, projectId string) ApiFsDeleteFileRequest { +func (a *WorkspaceToolboxAPIService) FsDeleteFile(ctx context.Context, workspaceId string) ApiFsDeleteFileRequest { return ApiFsDeleteFileRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -441,9 +426,8 @@ func (a *WorkspaceToolboxAPIService) FsDeleteFileExecute(r ApiFsDeleteFileReques return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -516,7 +500,6 @@ type ApiFsDownloadFileRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -533,19 +516,17 @@ func (r ApiFsDownloadFileRequest) Execute() (*os.File, *http.Response, error) { /* FsDownloadFile Download file -Download file from workspace project +Download file from a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsDownloadFileRequest */ -func (a *WorkspaceToolboxAPIService) FsDownloadFile(ctx context.Context, workspaceId string, projectId string) ApiFsDownloadFileRequest { +func (a *WorkspaceToolboxAPIService) FsDownloadFile(ctx context.Context, workspaceId string) ApiFsDownloadFileRequest { return ApiFsDownloadFileRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -565,9 +546,8 @@ func (a *WorkspaceToolboxAPIService) FsDownloadFileExecute(r ApiFsDownloadFileRe return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/download" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/download" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -649,7 +629,6 @@ type ApiFsFindInFilesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string pattern *string } @@ -673,19 +652,17 @@ func (r ApiFsFindInFilesRequest) Execute() ([]Match, *http.Response, error) { /* FsFindInFiles Search for text/pattern in files -Search for text/pattern inside workspace project files +Search for text/pattern inside a workspace files @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsFindInFilesRequest */ -func (a *WorkspaceToolboxAPIService) FsFindInFiles(ctx context.Context, workspaceId string, projectId string) ApiFsFindInFilesRequest { +func (a *WorkspaceToolboxAPIService) FsFindInFiles(ctx context.Context, workspaceId string) ApiFsFindInFilesRequest { return ApiFsFindInFilesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -705,9 +682,8 @@ func (a *WorkspaceToolboxAPIService) FsFindInFilesExecute(r ApiFsFindInFilesRequ return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/find" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/find" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -793,7 +769,6 @@ type ApiFsGetFileDetailsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -810,19 +785,17 @@ func (r ApiFsGetFileDetailsRequest) Execute() (*FileInfo, *http.Response, error) /* FsGetFileDetails Get file info -Get file info inside workspace project +Get file info inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsGetFileDetailsRequest */ -func (a *WorkspaceToolboxAPIService) FsGetFileDetails(ctx context.Context, workspaceId string, projectId string) ApiFsGetFileDetailsRequest { +func (a *WorkspaceToolboxAPIService) FsGetFileDetails(ctx context.Context, workspaceId string) ApiFsGetFileDetailsRequest { return ApiFsGetFileDetailsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -842,9 +815,8 @@ func (a *WorkspaceToolboxAPIService) FsGetFileDetailsExecute(r ApiFsGetFileDetai return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/info" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/info" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -926,7 +898,6 @@ type ApiFsListFilesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -943,19 +914,17 @@ func (r ApiFsListFilesRequest) Execute() ([]FileInfo, *http.Response, error) { /* FsListFiles List files -List files inside workspace project +List files inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsListFilesRequest */ -func (a *WorkspaceToolboxAPIService) FsListFiles(ctx context.Context, workspaceId string, projectId string) ApiFsListFilesRequest { +func (a *WorkspaceToolboxAPIService) FsListFiles(ctx context.Context, workspaceId string) ApiFsListFilesRequest { return ApiFsListFilesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -975,9 +944,8 @@ func (a *WorkspaceToolboxAPIService) FsListFilesExecute(r ApiFsListFilesRequest) return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1058,7 +1026,6 @@ type ApiFsMoveFileRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string source *string destination *string } @@ -1082,19 +1049,17 @@ func (r ApiFsMoveFileRequest) Execute() (*http.Response, error) { /* FsMoveFile Create folder -Create folder inside workspace project +Create folder inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsMoveFileRequest */ -func (a *WorkspaceToolboxAPIService) FsMoveFile(ctx context.Context, workspaceId string, projectId string) ApiFsMoveFileRequest { +func (a *WorkspaceToolboxAPIService) FsMoveFile(ctx context.Context, workspaceId string) ApiFsMoveFileRequest { return ApiFsMoveFileRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -1111,9 +1076,8 @@ func (a *WorkspaceToolboxAPIService) FsMoveFileExecute(r ApiFsMoveFileRequest) ( return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/move" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/move" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1190,7 +1154,6 @@ type ApiFsReplaceInFilesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string replace *ReplaceRequest } @@ -1207,19 +1170,17 @@ func (r ApiFsReplaceInFilesRequest) Execute() ([]ReplaceResult, *http.Response, /* FsReplaceInFiles Repleace text/pattern in files -Repleace text/pattern in mutilple files inside workspace project +Repleace text/pattern in mutilple files inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsReplaceInFilesRequest */ -func (a *WorkspaceToolboxAPIService) FsReplaceInFiles(ctx context.Context, workspaceId string, projectId string) ApiFsReplaceInFilesRequest { +func (a *WorkspaceToolboxAPIService) FsReplaceInFiles(ctx context.Context, workspaceId string) ApiFsReplaceInFilesRequest { return ApiFsReplaceInFilesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -1239,9 +1200,8 @@ func (a *WorkspaceToolboxAPIService) FsReplaceInFilesExecute(r ApiFsReplaceInFil return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/replace" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/replace" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1324,7 +1284,6 @@ type ApiFsSearchFilesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string pattern *string } @@ -1348,19 +1307,17 @@ func (r ApiFsSearchFilesRequest) Execute() (*SearchFilesResponse, *http.Response /* FsSearchFiles Search for files -Search for files inside workspace project +Search for files inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsSearchFilesRequest */ -func (a *WorkspaceToolboxAPIService) FsSearchFiles(ctx context.Context, workspaceId string, projectId string) ApiFsSearchFilesRequest { +func (a *WorkspaceToolboxAPIService) FsSearchFiles(ctx context.Context, workspaceId string) ApiFsSearchFilesRequest { return ApiFsSearchFilesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -1380,9 +1337,8 @@ func (a *WorkspaceToolboxAPIService) FsSearchFilesExecute(r ApiFsSearchFilesRequ return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/search" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/search" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1468,7 +1424,6 @@ type ApiFsSetFilePermissionsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string owner *string group *string @@ -1506,19 +1461,17 @@ func (r ApiFsSetFilePermissionsRequest) Execute() (*http.Response, error) { /* FsSetFilePermissions Set file owner/group/permissions -Set file owner/group/permissions inside workspace project +Set file owner/group/permissions inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsSetFilePermissionsRequest */ -func (a *WorkspaceToolboxAPIService) FsSetFilePermissions(ctx context.Context, workspaceId string, projectId string) ApiFsSetFilePermissionsRequest { +func (a *WorkspaceToolboxAPIService) FsSetFilePermissions(ctx context.Context, workspaceId string) ApiFsSetFilePermissionsRequest { return ApiFsSetFilePermissionsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -1535,9 +1488,8 @@ func (a *WorkspaceToolboxAPIService) FsSetFilePermissionsExecute(r ApiFsSetFileP return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/permissions" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/permissions" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1619,7 +1571,6 @@ type ApiFsUploadFileRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string file *os.File } @@ -1643,19 +1594,17 @@ func (r ApiFsUploadFileRequest) Execute() (*http.Response, error) { /* FsUploadFile Upload file -Upload file inside workspace project +Upload file inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiFsUploadFileRequest */ -func (a *WorkspaceToolboxAPIService) FsUploadFile(ctx context.Context, workspaceId string, projectId string) ApiFsUploadFileRequest { +func (a *WorkspaceToolboxAPIService) FsUploadFile(ctx context.Context, workspaceId string) ApiFsUploadFileRequest { return ApiFsUploadFileRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -1672,9 +1621,8 @@ func (a *WorkspaceToolboxAPIService) FsUploadFileExecute(r ApiFsUploadFileReques return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/files/upload" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/files/upload" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -1765,7 +1713,6 @@ type ApiGetSessionCommandLogsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string sessionId string commandId string } @@ -1782,17 +1729,15 @@ Connect with websocket to get a stream of the logs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @param sessionId Session ID @param commandId Command ID @return ApiGetSessionCommandLogsRequest */ -func (a *WorkspaceToolboxAPIService) GetSessionCommandLogs(ctx context.Context, workspaceId string, projectId string, sessionId string, commandId string) ApiGetSessionCommandLogsRequest { +func (a *WorkspaceToolboxAPIService) GetSessionCommandLogs(ctx context.Context, workspaceId string, sessionId string, commandId string) ApiGetSessionCommandLogsRequest { return ApiGetSessionCommandLogsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, sessionId: sessionId, commandId: commandId, } @@ -1814,9 +1759,8 @@ func (a *WorkspaceToolboxAPIService) GetSessionCommandLogsExecute(r ApiGetSessio return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"sessionId"+"}", url.PathEscape(parameterValueToString(r.sessionId, "sessionId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"commandId"+"}", url.PathEscape(parameterValueToString(r.commandId, "commandId")), -1) @@ -1896,7 +1840,6 @@ type ApiGetWorkspaceDirRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string } func (r ApiGetWorkspaceDirRequest) Execute() (*WorkspaceDirResponse, *http.Response, error) { @@ -1910,15 +1853,13 @@ Get workspace directory @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGetWorkspaceDirRequest */ -func (a *WorkspaceToolboxAPIService) GetWorkspaceDir(ctx context.Context, workspaceId string, projectId string) ApiGetWorkspaceDirRequest { +func (a *WorkspaceToolboxAPIService) GetWorkspaceDir(ctx context.Context, workspaceId string) ApiGetWorkspaceDirRequest { return ApiGetWorkspaceDirRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -1938,9 +1879,8 @@ func (a *WorkspaceToolboxAPIService) GetWorkspaceDirExecute(r ApiGetWorkspaceDir return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/workspace-dir" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/workspace-dir" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2018,7 +1958,6 @@ type ApiGitAddFilesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *GitAddRequest } @@ -2039,15 +1978,13 @@ Add files to git commit @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitAddFilesRequest */ -func (a *WorkspaceToolboxAPIService) GitAddFiles(ctx context.Context, workspaceId string, projectId string) ApiGitAddFilesRequest { +func (a *WorkspaceToolboxAPIService) GitAddFiles(ctx context.Context, workspaceId string) ApiGitAddFilesRequest { return ApiGitAddFilesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2064,9 +2001,8 @@ func (a *WorkspaceToolboxAPIService) GitAddFilesExecute(r ApiGitAddFilesRequest) return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/add" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/add" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2140,7 +2076,6 @@ type ApiGitBranchListRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -2157,19 +2092,17 @@ func (r ApiGitBranchListRequest) Execute() (*ListBranchResponse, *http.Response, /* GitBranchList Get branch list -Get branch list from git repository inside workspace project +Get branch list from git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitBranchListRequest */ -func (a *WorkspaceToolboxAPIService) GitBranchList(ctx context.Context, workspaceId string, projectId string) ApiGitBranchListRequest { +func (a *WorkspaceToolboxAPIService) GitBranchList(ctx context.Context, workspaceId string) ApiGitBranchListRequest { return ApiGitBranchListRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2189,9 +2122,8 @@ func (a *WorkspaceToolboxAPIService) GitBranchListExecute(r ApiGitBranchListRequ return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/branches" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/branches" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2273,7 +2205,6 @@ type ApiGitCloneRepositoryRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *GitCloneRequest } @@ -2290,19 +2221,17 @@ func (r ApiGitCloneRepositoryRequest) Execute() (*http.Response, error) { /* GitCloneRepository Clone git repository -Clone git repository inside workspace project +Clone git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitCloneRepositoryRequest */ -func (a *WorkspaceToolboxAPIService) GitCloneRepository(ctx context.Context, workspaceId string, projectId string) ApiGitCloneRepositoryRequest { +func (a *WorkspaceToolboxAPIService) GitCloneRepository(ctx context.Context, workspaceId string) ApiGitCloneRepositoryRequest { return ApiGitCloneRepositoryRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2319,9 +2248,8 @@ func (a *WorkspaceToolboxAPIService) GitCloneRepositoryExecute(r ApiGitCloneRepo return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/clone" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/clone" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2395,7 +2323,6 @@ type ApiGitCommitChangesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *GitCommitRequest } @@ -2412,19 +2339,17 @@ func (r ApiGitCommitChangesRequest) Execute() (*GitCommitResponse, *http.Respons /* GitCommitChanges Commit changes -Commit changes to git repository inside workspace project +Commit changes to git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitCommitChangesRequest */ -func (a *WorkspaceToolboxAPIService) GitCommitChanges(ctx context.Context, workspaceId string, projectId string) ApiGitCommitChangesRequest { +func (a *WorkspaceToolboxAPIService) GitCommitChanges(ctx context.Context, workspaceId string) ApiGitCommitChangesRequest { return ApiGitCommitChangesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2444,9 +2369,8 @@ func (a *WorkspaceToolboxAPIService) GitCommitChangesExecute(r ApiGitCommitChang return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/commit" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/commit" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2529,7 +2453,6 @@ type ApiGitCommitHistoryRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -2546,19 +2469,17 @@ func (r ApiGitCommitHistoryRequest) Execute() ([]GitCommitInfo, *http.Response, /* GitCommitHistory Get commit history -Get commit history from git repository inside workspace project +Get commit history from git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitCommitHistoryRequest */ -func (a *WorkspaceToolboxAPIService) GitCommitHistory(ctx context.Context, workspaceId string, projectId string) ApiGitCommitHistoryRequest { +func (a *WorkspaceToolboxAPIService) GitCommitHistory(ctx context.Context, workspaceId string) ApiGitCommitHistoryRequest { return ApiGitCommitHistoryRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2578,9 +2499,8 @@ func (a *WorkspaceToolboxAPIService) GitCommitHistoryExecute(r ApiGitCommitHisto return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/history" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/history" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2662,7 +2582,6 @@ type ApiGitCreateBranchRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *GitBranchRequest } @@ -2679,19 +2598,17 @@ func (r ApiGitCreateBranchRequest) Execute() (*http.Response, error) { /* GitCreateBranch Create branch -Create branch on git repository inside workspace project +Create branch on git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitCreateBranchRequest */ -func (a *WorkspaceToolboxAPIService) GitCreateBranch(ctx context.Context, workspaceId string, projectId string) ApiGitCreateBranchRequest { +func (a *WorkspaceToolboxAPIService) GitCreateBranch(ctx context.Context, workspaceId string) ApiGitCreateBranchRequest { return ApiGitCreateBranchRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2708,9 +2625,8 @@ func (a *WorkspaceToolboxAPIService) GitCreateBranchExecute(r ApiGitCreateBranch return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/branches" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/branches" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2784,7 +2700,6 @@ type ApiGitGitStatusRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string path *string } @@ -2801,19 +2716,17 @@ func (r ApiGitGitStatusRequest) Execute() (*GitStatus, *http.Response, error) { /* GitGitStatus Get git status -Get status from git repository inside workspace project +Get status from git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitGitStatusRequest */ -func (a *WorkspaceToolboxAPIService) GitGitStatus(ctx context.Context, workspaceId string, projectId string) ApiGitGitStatusRequest { +func (a *WorkspaceToolboxAPIService) GitGitStatus(ctx context.Context, workspaceId string) ApiGitGitStatusRequest { return ApiGitGitStatusRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2833,9 +2746,8 @@ func (a *WorkspaceToolboxAPIService) GitGitStatusExecute(r ApiGitGitStatusReques return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/status" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/status" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -2917,7 +2829,6 @@ type ApiGitPullChangesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *GitRepoRequest } @@ -2934,19 +2845,17 @@ func (r ApiGitPullChangesRequest) Execute() (*http.Response, error) { /* GitPullChanges Pull changes -Pull changes from remote to git repository inside workspace project +Pull changes from remote to git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitPullChangesRequest */ -func (a *WorkspaceToolboxAPIService) GitPullChanges(ctx context.Context, workspaceId string, projectId string) ApiGitPullChangesRequest { +func (a *WorkspaceToolboxAPIService) GitPullChanges(ctx context.Context, workspaceId string) ApiGitPullChangesRequest { return ApiGitPullChangesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -2963,9 +2872,8 @@ func (a *WorkspaceToolboxAPIService) GitPullChangesExecute(r ApiGitPullChangesRe return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/pull" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/pull" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3039,7 +2947,6 @@ type ApiGitPushChangesRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *GitRepoRequest } @@ -3056,19 +2963,17 @@ func (r ApiGitPushChangesRequest) Execute() (*http.Response, error) { /* GitPushChanges Push changes -Push changes to remote from git repository inside workspace project +Push changes to remote from git repository inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiGitPushChangesRequest */ -func (a *WorkspaceToolboxAPIService) GitPushChanges(ctx context.Context, workspaceId string, projectId string) ApiGitPushChangesRequest { +func (a *WorkspaceToolboxAPIService) GitPushChanges(ctx context.Context, workspaceId string) ApiGitPushChangesRequest { return ApiGitPushChangesRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3085,9 +2990,8 @@ func (a *WorkspaceToolboxAPIService) GitPushChangesExecute(r ApiGitPushChangesRe return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/git/push" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/git/push" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3161,7 +3065,6 @@ type ApiListSessionsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string } func (r ApiListSessionsRequest) Execute() ([]Session, *http.Response, error) { @@ -3175,15 +3078,13 @@ List sessions inside workspace project @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiListSessionsRequest */ -func (a *WorkspaceToolboxAPIService) ListSessions(ctx context.Context, workspaceId string, projectId string) ApiListSessionsRequest { +func (a *WorkspaceToolboxAPIService) ListSessions(ctx context.Context, workspaceId string) ApiListSessionsRequest { return ApiListSessionsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3203,9 +3104,8 @@ func (a *WorkspaceToolboxAPIService) ListSessionsExecute(r ApiListSessionsReques return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/process/session" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3283,7 +3183,6 @@ type ApiLspCompletionsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *LspCompletionParams } @@ -3304,15 +3203,13 @@ The Completion request is sent from the client to the server to compute completi @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspCompletionsRequest */ -func (a *WorkspaceToolboxAPIService) LspCompletions(ctx context.Context, workspaceId string, projectId string) ApiLspCompletionsRequest { +func (a *WorkspaceToolboxAPIService) LspCompletions(ctx context.Context, workspaceId string) ApiLspCompletionsRequest { return ApiLspCompletionsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3332,9 +3229,8 @@ func (a *WorkspaceToolboxAPIService) LspCompletionsExecute(r ApiLspCompletionsRe return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/completions" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/completions" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3417,7 +3313,6 @@ type ApiLspDidCloseRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *LspDocumentRequest } @@ -3438,15 +3333,13 @@ The document close notification is sent from the client to the server when the d @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspDidCloseRequest */ -func (a *WorkspaceToolboxAPIService) LspDidClose(ctx context.Context, workspaceId string, projectId string) ApiLspDidCloseRequest { +func (a *WorkspaceToolboxAPIService) LspDidClose(ctx context.Context, workspaceId string) ApiLspDidCloseRequest { return ApiLspDidCloseRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3463,9 +3356,8 @@ func (a *WorkspaceToolboxAPIService) LspDidCloseExecute(r ApiLspDidCloseRequest) return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/did-close" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3539,7 +3431,6 @@ type ApiLspDidOpenRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *LspDocumentRequest } @@ -3560,15 +3451,13 @@ The document open notification is sent from the client to the server to signal n @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspDidOpenRequest */ -func (a *WorkspaceToolboxAPIService) LspDidOpen(ctx context.Context, workspaceId string, projectId string) ApiLspDidOpenRequest { +func (a *WorkspaceToolboxAPIService) LspDidOpen(ctx context.Context, workspaceId string) ApiLspDidOpenRequest { return ApiLspDidOpenRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3585,9 +3474,8 @@ func (a *WorkspaceToolboxAPIService) LspDidOpenExecute(r ApiLspDidOpenRequest) ( return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/did-open" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3661,7 +3549,6 @@ type ApiLspDocumentSymbolsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string languageId *string pathToProject *string uri *string @@ -3696,15 +3583,13 @@ The document symbol request is sent from the client to the server. @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspDocumentSymbolsRequest */ -func (a *WorkspaceToolboxAPIService) LspDocumentSymbols(ctx context.Context, workspaceId string, projectId string) ApiLspDocumentSymbolsRequest { +func (a *WorkspaceToolboxAPIService) LspDocumentSymbols(ctx context.Context, workspaceId string) ApiLspDocumentSymbolsRequest { return ApiLspDocumentSymbolsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3724,9 +3609,8 @@ func (a *WorkspaceToolboxAPIService) LspDocumentSymbolsExecute(r ApiLspDocumentS return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/document-symbols" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3816,7 +3700,6 @@ type ApiLspStartRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *LspServerRequest } @@ -3833,19 +3716,17 @@ func (r ApiLspStartRequest) Execute() (*http.Response, error) { /* LspStart Start Lsp server -Start Lsp server process inside workspace project +Start Lsp server process inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspStartRequest */ -func (a *WorkspaceToolboxAPIService) LspStart(ctx context.Context, workspaceId string, projectId string) ApiLspStartRequest { +func (a *WorkspaceToolboxAPIService) LspStart(ctx context.Context, workspaceId string) ApiLspStartRequest { return ApiLspStartRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3862,9 +3743,8 @@ func (a *WorkspaceToolboxAPIService) LspStartExecute(r ApiLspStartRequest) (*htt return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/start" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/start" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -3938,7 +3818,6 @@ type ApiLspStopRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *LspServerRequest } @@ -3955,19 +3834,17 @@ func (r ApiLspStopRequest) Execute() (*http.Response, error) { /* LspStop Stop Lsp server -Stop Lsp server process inside workspace project +Stop Lsp server process inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspStopRequest */ -func (a *WorkspaceToolboxAPIService) LspStop(ctx context.Context, workspaceId string, projectId string) ApiLspStopRequest { +func (a *WorkspaceToolboxAPIService) LspStop(ctx context.Context, workspaceId string) ApiLspStopRequest { return ApiLspStopRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -3984,9 +3861,8 @@ func (a *WorkspaceToolboxAPIService) LspStopExecute(r ApiLspStopRequest) (*http. return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/stop" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/stop" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -4060,7 +3936,6 @@ type ApiLspWorkspaceSymbolsRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string languageId *string pathToProject *string query *string @@ -4095,15 +3970,13 @@ The workspace symbol request is sent from the client to the server to list proje @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiLspWorkspaceSymbolsRequest */ -func (a *WorkspaceToolboxAPIService) LspWorkspaceSymbols(ctx context.Context, workspaceId string, projectId string) ApiLspWorkspaceSymbolsRequest { +func (a *WorkspaceToolboxAPIService) LspWorkspaceSymbols(ctx context.Context, workspaceId string) ApiLspWorkspaceSymbolsRequest { return ApiLspWorkspaceSymbolsRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -4123,9 +3996,8 @@ func (a *WorkspaceToolboxAPIService) LspWorkspaceSymbolsExecute(r ApiLspWorkspac return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/lsp/workspace-symbols" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -4215,7 +4087,6 @@ type ApiProcessExecuteCommandRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string params *ExecuteRequest } @@ -4232,19 +4103,17 @@ func (r ApiProcessExecuteCommandRequest) Execute() (*ExecuteResponse, *http.Resp /* ProcessExecuteCommand Execute command -Execute command synchronously inside workspace project +Execute command synchronously inside a workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @return ApiProcessExecuteCommandRequest */ -func (a *WorkspaceToolboxAPIService) ProcessExecuteCommand(ctx context.Context, workspaceId string, projectId string) ApiProcessExecuteCommandRequest { +func (a *WorkspaceToolboxAPIService) ProcessExecuteCommand(ctx context.Context, workspaceId string) ApiProcessExecuteCommandRequest { return ApiProcessExecuteCommandRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, } } @@ -4264,9 +4133,8 @@ func (a *WorkspaceToolboxAPIService) ProcessExecuteCommandExecute(r ApiProcessEx return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/execute" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/process/execute" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -4349,7 +4217,6 @@ type ApiSessionExecuteCommandRequest struct { ctx context.Context ApiService *WorkspaceToolboxAPIService workspaceId string - projectId string sessionId string params *SessionExecuteRequest } @@ -4371,16 +4238,14 @@ Execute command inside a session inside workspace project @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @param projectId Project ID @param sessionId Session ID @return ApiSessionExecuteCommandRequest */ -func (a *WorkspaceToolboxAPIService) SessionExecuteCommand(ctx context.Context, workspaceId string, projectId string, sessionId string) ApiSessionExecuteCommandRequest { +func (a *WorkspaceToolboxAPIService) SessionExecuteCommand(ctx context.Context, workspaceId string, sessionId string) ApiSessionExecuteCommandRequest { return ApiSessionExecuteCommandRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, - projectId: projectId, sessionId: sessionId, } } @@ -4401,9 +4266,8 @@ func (a *WorkspaceToolboxAPIService) SessionExecuteCommandExecute(r ApiSessionEx return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec" + localVarPath := localBasePath + "/workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"projectId"+"}", url.PathEscape(parameterValueToString(r.projectId, "projectId")), -1) localVarPath = strings.Replace(localVarPath, "{"+"sessionId"+"}", url.PathEscape(parameterValueToString(r.sessionId, "sessionId")), -1) localVarHeaderParams := make(map[string]string) diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index c4f47e372b..13557afa24 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -72,6 +72,8 @@ type APIClient struct { TargetConfigAPI *TargetConfigAPIService + WorkspaceAPI *WorkspaceAPIService + WorkspaceConfigAPI *WorkspaceConfigAPIService WorkspaceToolboxAPI *WorkspaceToolboxAPIService @@ -105,6 +107,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.ServerAPI = (*ServerAPIService)(&c.common) c.TargetAPI = (*TargetAPIService)(&c.common) c.TargetConfigAPI = (*TargetConfigAPIService)(&c.common) + c.WorkspaceAPI = (*WorkspaceAPIService)(&c.common) c.WorkspaceConfigAPI = (*WorkspaceConfigAPIService)(&c.common) c.WorkspaceToolboxAPI = (*WorkspaceToolboxAPIService)(&c.common) diff --git a/pkg/apiclient/docs/CreateTargetDTO.md b/pkg/apiclient/docs/CreateTargetDTO.md index 1f58d676d7..5a1dc99c0d 100644 --- a/pkg/apiclient/docs/CreateTargetDTO.md +++ b/pkg/apiclient/docs/CreateTargetDTO.md @@ -7,13 +7,12 @@ Name | Type | Description | Notes **Id** | **string** | | **Name** | **string** | | **TargetConfig** | **string** | | -**Workspaces** | [**[]CreateWorkspaceDTO**](CreateWorkspaceDTO.md) | | ## Methods ### NewCreateTargetDTO -`func NewCreateTargetDTO(id string, name string, targetConfig string, workspaces []CreateWorkspaceDTO, ) *CreateTargetDTO` +`func NewCreateTargetDTO(id string, name string, targetConfig string, ) *CreateTargetDTO` NewCreateTargetDTO instantiates a new CreateTargetDTO object This constructor will assign default values to properties that have it defined, @@ -88,26 +87,6 @@ and a boolean to check if the value has been set. SetTargetConfig sets TargetConfig field to given value. -### GetWorkspaces - -`func (o *CreateTargetDTO) GetWorkspaces() []CreateWorkspaceDTO` - -GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. - -### GetWorkspacesOk - -`func (o *CreateTargetDTO) GetWorkspacesOk() (*[]CreateWorkspaceDTO, bool)` - -GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetWorkspaces - -`func (o *CreateTargetDTO) SetWorkspaces(v []CreateWorkspaceDTO)` - -SetWorkspaces sets Workspaces field to given value. - - [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/CreateWorkspaceDTO.md b/pkg/apiclient/docs/CreateWorkspaceDTO.md index f3e6a2b806..20346de368 100644 --- a/pkg/apiclient/docs/CreateWorkspaceDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceDTO.md @@ -7,16 +7,18 @@ Name | Type | Description | Notes **BuildConfig** | Pointer to [**BuildConfig**](BuildConfig.md) | | [optional] **EnvVars** | **map[string]string** | | **GitProviderConfigId** | Pointer to **string** | | [optional] +**Id** | **string** | | **Image** | Pointer to **string** | | [optional] **Name** | **string** | | **Source** | [**CreateWorkspaceSourceDTO**](CreateWorkspaceSourceDTO.md) | | +**TargetId** | **string** | | **User** | Pointer to **string** | | [optional] ## Methods ### NewCreateWorkspaceDTO -`func NewCreateWorkspaceDTO(envVars map[string]string, name string, source CreateWorkspaceSourceDTO, ) *CreateWorkspaceDTO` +`func NewCreateWorkspaceDTO(envVars map[string]string, id string, name string, source CreateWorkspaceSourceDTO, targetId string, ) *CreateWorkspaceDTO` NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -101,6 +103,26 @@ SetGitProviderConfigId sets GitProviderConfigId field to given value. HasGitProviderConfigId returns a boolean if a field has been set. +### GetId + +`func (o *CreateWorkspaceDTO) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *CreateWorkspaceDTO) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *CreateWorkspaceDTO) SetId(v string)` + +SetId sets Id field to given value. + + ### GetImage `func (o *CreateWorkspaceDTO) GetImage() string` @@ -166,6 +188,26 @@ and a boolean to check if the value has been set. SetSource sets Source field to given value. +### GetTargetId + +`func (o *CreateWorkspaceDTO) GetTargetId() string` + +GetTargetId returns the TargetId field if non-nil, zero value otherwise. + +### GetTargetIdOk + +`func (o *CreateWorkspaceDTO) GetTargetIdOk() (*string, bool)` + +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTargetId + +`func (o *CreateWorkspaceDTO) SetTargetId(v string)` + +SetTargetId sets TargetId field to given value. + + ### GetUser `func (o *CreateWorkspaceDTO) GetUser() string` diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index b26c5098bb..0875a578b8 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -7,13 +7,12 @@ Name | Type | Description | Notes **Id** | **string** | | **Name** | **string** | | **TargetConfig** | **string** | | -**Workspaces** | [**[]Workspace**](Workspace.md) | | ## Methods ### NewTarget -`func NewTarget(id string, name string, targetConfig string, workspaces []Workspace, ) *Target` +`func NewTarget(id string, name string, targetConfig string, ) *Target` NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, @@ -88,26 +87,6 @@ and a boolean to check if the value has been set. SetTargetConfig sets TargetConfig field to given value. -### GetWorkspaces - -`func (o *Target) GetWorkspaces() []Workspace` - -GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. - -### GetWorkspacesOk - -`func (o *Target) GetWorkspacesOk() (*[]Workspace, bool)` - -GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetWorkspaces - -`func (o *Target) SetWorkspaces(v []Workspace)` - -SetWorkspaces sets Workspaces field to given value. - - [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index 64fe33c33d..e04e40111c 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -8,11 +8,8 @@ Method | HTTP request | Description [**GetTarget**](TargetAPI.md#GetTarget) | **Get** /target/{targetId} | Get target info [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets [**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target -[**SetWorkspaceState**](TargetAPI.md#SetWorkspaceState) | **Post** /target/{targetId}/{workspaceId}/state | Set workspace state [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target -[**StartWorkspace**](TargetAPI.md#StartWorkspace) | **Post** /target/{targetId}/{workspaceId}/start | Start workspace [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target -[**StopWorkspace**](TargetAPI.md#StopWorkspace) | **Post** /target/{targetId}/{workspaceId}/stop | Stop workspace @@ -37,7 +34,7 @@ import ( ) func main() { - target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfig_example", []openapiclient.CreateWorkspaceDTO{*openapiclient.NewCreateWorkspaceDTO(map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateWorkspaceSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")))}) // CreateTargetDTO | Create target + target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfig_example") // CreateTargetDTO | Create target configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) @@ -290,79 +287,6 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetWorkspaceState - -> SetWorkspaceState(ctx, targetId, workspaceId).SetState(setState).Execute() - -Set workspace state - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - targetId := "targetId_example" // string | Target ID or Name - workspaceId := "workspaceId_example" // string | Workspace ID - setState := *openapiclient.NewSetWorkspaceState(int32(123)) // SetWorkspaceState | Set State - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.SetWorkspaceState(context.Background(), targetId, workspaceId).SetState(setState).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetWorkspaceState``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID or Name | -**workspaceId** | **string** | Workspace ID | - -### Other Parameters - -Other parameters are passed through a pointer to a apiSetWorkspaceStateRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - - **setState** | [**SetWorkspaceState**](SetWorkspaceState.md) | Set State | - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - ## StartTarget > StartTarget(ctx, targetId).Execute() @@ -413,77 +337,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## StartWorkspace - -> StartWorkspace(ctx, targetId, workspaceId).Execute() - -Start workspace - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - targetId := "targetId_example" // string | Target ID or Name - workspaceId := "workspaceId_example" // string | Workspace ID - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StartWorkspace(context.Background(), targetId, workspaceId).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartWorkspace``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID or Name | -**workspaceId** | **string** | Workspace ID | - -### Other Parameters - -Other parameters are passed through a pointer to a apiStartWorkspaceRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - - ### Return type (empty response body) @@ -552,77 +405,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## StopWorkspace - -> StopWorkspace(ctx, targetId, workspaceId).Execute() - -Stop workspace - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - targetId := "targetId_example" // string | Target ID or Name - workspaceId := "workspaceId_example" // string | Workspace ID - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StopWorkspace(context.Background(), targetId, workspaceId).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopWorkspace``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID or Name | -**workspaceId** | **string** | Workspace ID | - -### Other Parameters - -Other parameters are passed through a pointer to a apiStopWorkspaceRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - - ### Return type (empty response body) diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index 6a256f2f7b..c9c6b8742b 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -8,13 +8,12 @@ Name | Type | Description | Notes **Info** | Pointer to [**TargetInfo**](TargetInfo.md) | | [optional] **Name** | **string** | | **TargetConfig** | **string** | | -**Workspaces** | [**[]Workspace**](Workspace.md) | | ## Methods ### NewTargetDTO -`func NewTargetDTO(id string, name string, targetConfig string, workspaces []Workspace, ) *TargetDTO` +`func NewTargetDTO(id string, name string, targetConfig string, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -114,26 +113,6 @@ and a boolean to check if the value has been set. SetTargetConfig sets TargetConfig field to given value. -### GetWorkspaces - -`func (o *TargetDTO) GetWorkspaces() []Workspace` - -GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. - -### GetWorkspacesOk - -`func (o *TargetDTO) GetWorkspacesOk() (*[]Workspace, bool)` - -GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetWorkspaces - -`func (o *TargetDTO) SetWorkspaces(v []Workspace)` - -SetWorkspaces sets Workspaces field to given value. - - [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/TargetInfo.md b/pkg/apiclient/docs/TargetInfo.md index 32363e64e4..c82cdc9401 100644 --- a/pkg/apiclient/docs/TargetInfo.md +++ b/pkg/apiclient/docs/TargetInfo.md @@ -6,13 +6,12 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Name** | **string** | | **ProviderMetadata** | Pointer to **string** | | [optional] -**Workspaces** | [**[]WorkspaceInfo**](WorkspaceInfo.md) | | ## Methods ### NewTargetInfo -`func NewTargetInfo(name string, workspaces []WorkspaceInfo, ) *TargetInfo` +`func NewTargetInfo(name string, ) *TargetInfo` NewTargetInfo instantiates a new TargetInfo object This constructor will assign default values to properties that have it defined, @@ -72,26 +71,6 @@ SetProviderMetadata sets ProviderMetadata field to given value. HasProviderMetadata returns a boolean if a field has been set. -### GetWorkspaces - -`func (o *TargetInfo) GetWorkspaces() []WorkspaceInfo` - -GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. - -### GetWorkspacesOk - -`func (o *TargetInfo) GetWorkspacesOk() (*[]WorkspaceInfo, bool)` - -GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetWorkspaces - -`func (o *TargetInfo) SetWorkspaces(v []WorkspaceInfo)` - -SetWorkspaces sets Workspaces field to given value. - - [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md new file mode 100644 index 0000000000..451a932d25 --- /dev/null +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -0,0 +1,495 @@ +# \WorkspaceAPI + +All URIs are relative to *http://localhost:3986* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**CreateWorkspace**](WorkspaceAPI.md#CreateWorkspace) | **Post** /workspace | Create a workspace +[**GetWorkspace**](WorkspaceAPI.md#GetWorkspace) | **Get** /workspace/{workspaceId} | Get workspace info +[**ListWorkspaces**](WorkspaceAPI.md#ListWorkspaces) | **Get** /workspace | List workspaces +[**RemoveWorkspace**](WorkspaceAPI.md#RemoveWorkspace) | **Delete** /workspace/{workspaceId} | Remove workspace +[**SetWorkspaceState**](WorkspaceAPI.md#SetWorkspaceState) | **Post** /workspace/{workspaceId}/state | Set workspace state +[**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace +[**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace + + + +## CreateWorkspace + +> WorkspaceViewDTO CreateWorkspace(ctx).Workspace(workspace).Execute() + +Create a workspace + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspace := *openapiclient.NewCreateWorkspaceDTO(map[string]string{"key": "Inner_example"}, "Id_example", "Name_example", *openapiclient.NewCreateWorkspaceSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")), "TargetId_example") // CreateWorkspaceDTO | Create workspace + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.WorkspaceAPI.CreateWorkspace(context.Background()).Workspace(workspace).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.CreateWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `CreateWorkspace`: WorkspaceViewDTO + fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.CreateWorkspace`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiCreateWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **workspace** | [**CreateWorkspaceDTO**](CreateWorkspaceDTO.md) | Create workspace | + +### Return type + +[**WorkspaceViewDTO**](WorkspaceViewDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## GetWorkspace + +> WorkspaceDTO GetWorkspace(ctx, workspaceId).Verbose(verbose).Execute() + +Get workspace info + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID or Name + verbose := true // bool | Verbose (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.WorkspaceAPI.GetWorkspace(context.Background(), workspaceId).Verbose(verbose).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.GetWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetWorkspace`: WorkspaceDTO + fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.GetWorkspace`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID or Name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **verbose** | **bool** | Verbose | + +### Return type + +[**WorkspaceDTO**](WorkspaceDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListWorkspaces + +> []WorkspaceDTO ListWorkspaces(ctx).Verbose(verbose).Execute() + +List workspaces + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + verbose := true // bool | Verbose (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Verbose(verbose).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.ListWorkspaces``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListWorkspaces`: []WorkspaceDTO + fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.ListWorkspaces`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiListWorkspacesRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **verbose** | **bool** | Verbose | + +### Return type + +[**[]WorkspaceDTO**](WorkspaceDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## RemoveWorkspace + +> RemoveWorkspace(ctx, workspaceId).Force(force).Execute() + +Remove workspace + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID + force := true // bool | Force (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.WorkspaceAPI.RemoveWorkspace(context.Background(), workspaceId).Force(force).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.RemoveWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiRemoveWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **force** | **bool** | Force | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## SetWorkspaceState + +> SetWorkspaceState(ctx, workspaceId).SetState(setState).Execute() + +Set workspace state + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID + setState := *openapiclient.NewSetWorkspaceState(int32(123)) // SetWorkspaceState | Set State + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.WorkspaceAPI.SetWorkspaceState(context.Background(), workspaceId).SetState(setState).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.SetWorkspaceState``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiSetWorkspaceStateRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **setState** | [**SetWorkspaceState**](SetWorkspaceState.md) | Set State | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## StartWorkspace + +> StartWorkspace(ctx, workspaceId).Execute() + +Start workspace + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID or Name + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.WorkspaceAPI.StartWorkspace(context.Background(), workspaceId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StartWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID or Name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiStartWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## StopWorkspace + +> StopWorkspace(ctx, workspaceId).Execute() + +Stop workspace + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID or Name + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.WorkspaceAPI.StopWorkspace(context.Background(), workspaceId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StopWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID or Name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiStopWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md new file mode 100644 index 0000000000..7f292d664d --- /dev/null +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -0,0 +1,302 @@ +# WorkspaceDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**BuildConfig** | Pointer to [**BuildConfig**](BuildConfig.md) | | [optional] +**EnvVars** | **map[string]string** | | +**GitProviderConfigId** | Pointer to **string** | | [optional] +**Id** | **string** | | +**Image** | **string** | | +**Info** | Pointer to [**WorkspaceInfo**](WorkspaceInfo.md) | | [optional] +**Name** | **string** | | +**Repository** | [**GitRepository**](GitRepository.md) | | +**State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] +**TargetId** | **string** | | +**TargetName** | **string** | | +**User** | **string** | | + +## Methods + +### NewWorkspaceDTO + +`func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string, ) *WorkspaceDTO` + +NewWorkspaceDTO instantiates a new WorkspaceDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewWorkspaceDTOWithDefaults + +`func NewWorkspaceDTOWithDefaults() *WorkspaceDTO` + +NewWorkspaceDTOWithDefaults instantiates a new WorkspaceDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetBuildConfig + +`func (o *WorkspaceDTO) GetBuildConfig() BuildConfig` + +GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. + +### GetBuildConfigOk + +`func (o *WorkspaceDTO) GetBuildConfigOk() (*BuildConfig, bool)` + +GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetBuildConfig + +`func (o *WorkspaceDTO) SetBuildConfig(v BuildConfig)` + +SetBuildConfig sets BuildConfig field to given value. + +### HasBuildConfig + +`func (o *WorkspaceDTO) HasBuildConfig() bool` + +HasBuildConfig returns a boolean if a field has been set. + +### GetEnvVars + +`func (o *WorkspaceDTO) GetEnvVars() map[string]string` + +GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. + +### GetEnvVarsOk + +`func (o *WorkspaceDTO) GetEnvVarsOk() (*map[string]string, bool)` + +GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEnvVars + +`func (o *WorkspaceDTO) SetEnvVars(v map[string]string)` + +SetEnvVars sets EnvVars field to given value. + + +### GetGitProviderConfigId + +`func (o *WorkspaceDTO) GetGitProviderConfigId() string` + +GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. + +### GetGitProviderConfigIdOk + +`func (o *WorkspaceDTO) GetGitProviderConfigIdOk() (*string, bool)` + +GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetGitProviderConfigId + +`func (o *WorkspaceDTO) SetGitProviderConfigId(v string)` + +SetGitProviderConfigId sets GitProviderConfigId field to given value. + +### HasGitProviderConfigId + +`func (o *WorkspaceDTO) HasGitProviderConfigId() bool` + +HasGitProviderConfigId returns a boolean if a field has been set. + +### GetId + +`func (o *WorkspaceDTO) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *WorkspaceDTO) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *WorkspaceDTO) SetId(v string)` + +SetId sets Id field to given value. + + +### GetImage + +`func (o *WorkspaceDTO) GetImage() string` + +GetImage returns the Image field if non-nil, zero value otherwise. + +### GetImageOk + +`func (o *WorkspaceDTO) GetImageOk() (*string, bool)` + +GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetImage + +`func (o *WorkspaceDTO) SetImage(v string)` + +SetImage sets Image field to given value. + + +### GetInfo + +`func (o *WorkspaceDTO) GetInfo() WorkspaceInfo` + +GetInfo returns the Info field if non-nil, zero value otherwise. + +### GetInfoOk + +`func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool)` + +GetInfoOk returns a tuple with the Info field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetInfo + +`func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo)` + +SetInfo sets Info field to given value. + +### HasInfo + +`func (o *WorkspaceDTO) HasInfo() bool` + +HasInfo returns a boolean if a field has been set. + +### GetName + +`func (o *WorkspaceDTO) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *WorkspaceDTO) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *WorkspaceDTO) SetName(v string)` + +SetName sets Name field to given value. + + +### GetRepository + +`func (o *WorkspaceDTO) GetRepository() GitRepository` + +GetRepository returns the Repository field if non-nil, zero value otherwise. + +### GetRepositoryOk + +`func (o *WorkspaceDTO) GetRepositoryOk() (*GitRepository, bool)` + +GetRepositoryOk returns a tuple with the Repository field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRepository + +`func (o *WorkspaceDTO) SetRepository(v GitRepository)` + +SetRepository sets Repository field to given value. + + +### GetState + +`func (o *WorkspaceDTO) GetState() WorkspaceState` + +GetState returns the State field if non-nil, zero value otherwise. + +### GetStateOk + +`func (o *WorkspaceDTO) GetStateOk() (*WorkspaceState, bool)` + +GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetState + +`func (o *WorkspaceDTO) SetState(v WorkspaceState)` + +SetState sets State field to given value. + +### HasState + +`func (o *WorkspaceDTO) HasState() bool` + +HasState returns a boolean if a field has been set. + +### GetTargetId + +`func (o *WorkspaceDTO) GetTargetId() string` + +GetTargetId returns the TargetId field if non-nil, zero value otherwise. + +### GetTargetIdOk + +`func (o *WorkspaceDTO) GetTargetIdOk() (*string, bool)` + +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTargetId + +`func (o *WorkspaceDTO) SetTargetId(v string)` + +SetTargetId sets TargetId field to given value. + + +### GetTargetName + +`func (o *WorkspaceDTO) GetTargetName() string` + +GetTargetName returns the TargetName field if non-nil, zero value otherwise. + +### GetTargetNameOk + +`func (o *WorkspaceDTO) GetTargetNameOk() (*string, bool)` + +GetTargetNameOk returns a tuple with the TargetName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTargetName + +`func (o *WorkspaceDTO) SetTargetName(v string)` + +SetTargetName sets TargetName field to given value. + + +### GetUser + +`func (o *WorkspaceDTO) GetUser() string` + +GetUser returns the User field if non-nil, zero value otherwise. + +### GetUserOk + +`func (o *WorkspaceDTO) GetUserOk() (*string, bool)` + +GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUser + +`func (o *WorkspaceDTO) SetUser(v string)` + +SetUser sets User field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/WorkspaceToolboxAPI.md b/pkg/apiclient/docs/WorkspaceToolboxAPI.md index effaa6c5ef..86974ca868 100644 --- a/pkg/apiclient/docs/WorkspaceToolboxAPI.md +++ b/pkg/apiclient/docs/WorkspaceToolboxAPI.md @@ -4,46 +4,46 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**CreateSession**](WorkspaceToolboxAPI.md#CreateSession) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/session | Create exec session -[**DeleteSession**](WorkspaceToolboxAPI.md#DeleteSession) | **Delete** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId} | Delete session -[**FsCreateFolder**](WorkspaceToolboxAPI.md#FsCreateFolder) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/folder | Create folder -[**FsDeleteFile**](WorkspaceToolboxAPI.md#FsDeleteFile) | **Delete** /workspace/{workspaceId}/{projectId}/toolbox/files | Delete file -[**FsDownloadFile**](WorkspaceToolboxAPI.md#FsDownloadFile) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/download | Download file -[**FsFindInFiles**](WorkspaceToolboxAPI.md#FsFindInFiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/find | Search for text/pattern in files -[**FsGetFileDetails**](WorkspaceToolboxAPI.md#FsGetFileDetails) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/info | Get file info -[**FsListFiles**](WorkspaceToolboxAPI.md#FsListFiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files | List files -[**FsMoveFile**](WorkspaceToolboxAPI.md#FsMoveFile) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/move | Create folder -[**FsReplaceInFiles**](WorkspaceToolboxAPI.md#FsReplaceInFiles) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/replace | Repleace text/pattern in files -[**FsSearchFiles**](WorkspaceToolboxAPI.md#FsSearchFiles) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/files/search | Search for files -[**FsSetFilePermissions**](WorkspaceToolboxAPI.md#FsSetFilePermissions) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/permissions | Set file owner/group/permissions -[**FsUploadFile**](WorkspaceToolboxAPI.md#FsUploadFile) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/files/upload | Upload file -[**GetSessionCommandLogs**](WorkspaceToolboxAPI.md#GetSessionCommandLogs) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/command/{commandId}/logs | Get session command logs -[**GetWorkspaceDir**](WorkspaceToolboxAPI.md#GetWorkspaceDir) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/workspace-dir | Get workspace dir -[**GitAddFiles**](WorkspaceToolboxAPI.md#GitAddFiles) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/add | Add files -[**GitBranchList**](WorkspaceToolboxAPI.md#GitBranchList) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/branches | Get branch list -[**GitCloneRepository**](WorkspaceToolboxAPI.md#GitCloneRepository) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/clone | Clone git repository -[**GitCommitChanges**](WorkspaceToolboxAPI.md#GitCommitChanges) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/commit | Commit changes -[**GitCommitHistory**](WorkspaceToolboxAPI.md#GitCommitHistory) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/history | Get commit history -[**GitCreateBranch**](WorkspaceToolboxAPI.md#GitCreateBranch) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/branches | Create branch -[**GitGitStatus**](WorkspaceToolboxAPI.md#GitGitStatus) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/git/status | Get git status -[**GitPullChanges**](WorkspaceToolboxAPI.md#GitPullChanges) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/pull | Pull changes -[**GitPushChanges**](WorkspaceToolboxAPI.md#GitPushChanges) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/git/push | Push changes -[**ListSessions**](WorkspaceToolboxAPI.md#ListSessions) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/process/session | List sessions -[**LspCompletions**](WorkspaceToolboxAPI.md#LspCompletions) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/completions | Get Lsp Completions -[**LspDidClose**](WorkspaceToolboxAPI.md#LspDidClose) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-close | Call Lsp DidClose -[**LspDidOpen**](WorkspaceToolboxAPI.md#LspDidOpen) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/did-open | Call Lsp DidOpen -[**LspDocumentSymbols**](WorkspaceToolboxAPI.md#LspDocumentSymbols) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/lsp/document-symbols | Call Lsp DocumentSymbols -[**LspStart**](WorkspaceToolboxAPI.md#LspStart) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/start | Start Lsp server -[**LspStop**](WorkspaceToolboxAPI.md#LspStop) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/lsp/stop | Stop Lsp server -[**LspWorkspaceSymbols**](WorkspaceToolboxAPI.md#LspWorkspaceSymbols) | **Get** /workspace/{workspaceId}/{projectId}/toolbox/lsp/workspace-symbols | Call Lsp WorkspaceSymbols -[**ProcessExecuteCommand**](WorkspaceToolboxAPI.md#ProcessExecuteCommand) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/execute | Execute command -[**SessionExecuteCommand**](WorkspaceToolboxAPI.md#SessionExecuteCommand) | **Post** /workspace/{workspaceId}/{projectId}/toolbox/process/session/{sessionId}/exec | Execute command in session +[**CreateSession**](WorkspaceToolboxAPI.md#CreateSession) | **Post** /workspace/{workspaceId}/toolbox/process/session | Create exec session +[**DeleteSession**](WorkspaceToolboxAPI.md#DeleteSession) | **Delete** /workspace/{workspaceId}/toolbox/process/session/{sessionId} | Delete session +[**FsCreateFolder**](WorkspaceToolboxAPI.md#FsCreateFolder) | **Post** /workspace/{workspaceId}/toolbox/files/folder | Create folder +[**FsDeleteFile**](WorkspaceToolboxAPI.md#FsDeleteFile) | **Delete** /workspace/{workspaceId}/toolbox/files | Delete file +[**FsDownloadFile**](WorkspaceToolboxAPI.md#FsDownloadFile) | **Get** /workspace/{workspaceId}/toolbox/files/download | Download file +[**FsFindInFiles**](WorkspaceToolboxAPI.md#FsFindInFiles) | **Get** /workspace/{workspaceId}/toolbox/files/find | Search for text/pattern in files +[**FsGetFileDetails**](WorkspaceToolboxAPI.md#FsGetFileDetails) | **Get** /workspace/{workspaceId}/toolbox/files/info | Get file info +[**FsListFiles**](WorkspaceToolboxAPI.md#FsListFiles) | **Get** /workspace/{workspaceId}/toolbox/files | List files +[**FsMoveFile**](WorkspaceToolboxAPI.md#FsMoveFile) | **Post** /workspace/{workspaceId}/toolbox/files/move | Create folder +[**FsReplaceInFiles**](WorkspaceToolboxAPI.md#FsReplaceInFiles) | **Post** /workspace/{workspaceId}/toolbox/files/replace | Repleace text/pattern in files +[**FsSearchFiles**](WorkspaceToolboxAPI.md#FsSearchFiles) | **Get** /workspace/{workspaceId}/toolbox/files/search | Search for files +[**FsSetFilePermissions**](WorkspaceToolboxAPI.md#FsSetFilePermissions) | **Post** /workspace/{workspaceId}/toolbox/files/permissions | Set file owner/group/permissions +[**FsUploadFile**](WorkspaceToolboxAPI.md#FsUploadFile) | **Post** /workspace/{workspaceId}/toolbox/files/upload | Upload file +[**GetSessionCommandLogs**](WorkspaceToolboxAPI.md#GetSessionCommandLogs) | **Get** /workspace/{workspaceId}/toolbox/process/session/{sessionId}/command/{commandId}/logs | Get session command logs +[**GetWorkspaceDir**](WorkspaceToolboxAPI.md#GetWorkspaceDir) | **Get** /workspace/{workspaceId}/toolbox/workspace-dir | Get workspace dir +[**GitAddFiles**](WorkspaceToolboxAPI.md#GitAddFiles) | **Post** /workspace/{workspaceId}/toolbox/git/add | Add files +[**GitBranchList**](WorkspaceToolboxAPI.md#GitBranchList) | **Get** /workspace/{workspaceId}/toolbox/git/branches | Get branch list +[**GitCloneRepository**](WorkspaceToolboxAPI.md#GitCloneRepository) | **Post** /workspace/{workspaceId}/toolbox/git/clone | Clone git repository +[**GitCommitChanges**](WorkspaceToolboxAPI.md#GitCommitChanges) | **Post** /workspace/{workspaceId}/toolbox/git/commit | Commit changes +[**GitCommitHistory**](WorkspaceToolboxAPI.md#GitCommitHistory) | **Get** /workspace/{workspaceId}/toolbox/git/history | Get commit history +[**GitCreateBranch**](WorkspaceToolboxAPI.md#GitCreateBranch) | **Post** /workspace/{workspaceId}/toolbox/git/branches | Create branch +[**GitGitStatus**](WorkspaceToolboxAPI.md#GitGitStatus) | **Get** /workspace/{workspaceId}/toolbox/git/status | Get git status +[**GitPullChanges**](WorkspaceToolboxAPI.md#GitPullChanges) | **Post** /workspace/{workspaceId}/toolbox/git/pull | Pull changes +[**GitPushChanges**](WorkspaceToolboxAPI.md#GitPushChanges) | **Post** /workspace/{workspaceId}/toolbox/git/push | Push changes +[**ListSessions**](WorkspaceToolboxAPI.md#ListSessions) | **Get** /workspace/{workspaceId}/toolbox/process/session | List sessions +[**LspCompletions**](WorkspaceToolboxAPI.md#LspCompletions) | **Post** /workspace/{workspaceId}/toolbox/lsp/completions | Get Lsp Completions +[**LspDidClose**](WorkspaceToolboxAPI.md#LspDidClose) | **Post** /workspace/{workspaceId}/toolbox/lsp/did-close | Call Lsp DidClose +[**LspDidOpen**](WorkspaceToolboxAPI.md#LspDidOpen) | **Post** /workspace/{workspaceId}/toolbox/lsp/did-open | Call Lsp DidOpen +[**LspDocumentSymbols**](WorkspaceToolboxAPI.md#LspDocumentSymbols) | **Get** /workspace/{workspaceId}/toolbox/lsp/document-symbols | Call Lsp DocumentSymbols +[**LspStart**](WorkspaceToolboxAPI.md#LspStart) | **Post** /workspace/{workspaceId}/toolbox/lsp/start | Start Lsp server +[**LspStop**](WorkspaceToolboxAPI.md#LspStop) | **Post** /workspace/{workspaceId}/toolbox/lsp/stop | Stop Lsp server +[**LspWorkspaceSymbols**](WorkspaceToolboxAPI.md#LspWorkspaceSymbols) | **Get** /workspace/{workspaceId}/toolbox/lsp/workspace-symbols | Call Lsp WorkspaceSymbols +[**ProcessExecuteCommand**](WorkspaceToolboxAPI.md#ProcessExecuteCommand) | **Post** /workspace/{workspaceId}/toolbox/process/execute | Execute command +[**SessionExecuteCommand**](WorkspaceToolboxAPI.md#SessionExecuteCommand) | **Post** /workspace/{workspaceId}/toolbox/process/session/{sessionId}/exec | Execute command in session ## CreateSession -> CreateSession(ctx, workspaceId, projectId).Params(params).Execute() +> CreateSession(ctx, workspaceId).Params(params).Execute() Create exec session @@ -63,12 +63,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewCreateSessionRequest("SessionId_example") // CreateSessionRequest | Create session request configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.CreateSession(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.CreateSession(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.CreateSession``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -83,7 +82,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -93,7 +91,6 @@ Other parameters are passed through a pointer to a apiCreateSessionRequest struc Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**CreateSessionRequest**](CreateSessionRequest.md) | Create session request | ### Return type @@ -116,7 +113,7 @@ Name | Type | Description | Notes ## DeleteSession -> DeleteSession(ctx, workspaceId, projectId, sessionId).Execute() +> DeleteSession(ctx, workspaceId, sessionId).Execute() Delete session @@ -136,12 +133,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID sessionId := "sessionId_example" // string | Session ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.DeleteSession(context.Background(), workspaceId, projectId, sessionId).Execute() + r, err := apiClient.WorkspaceToolboxAPI.DeleteSession(context.Background(), workspaceId, sessionId).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.DeleteSession``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -156,7 +152,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | **sessionId** | **string** | Session ID | ### Other Parameters @@ -169,7 +164,6 @@ Name | Type | Description | Notes - ### Return type (empty response body) @@ -190,7 +184,7 @@ Name | Type | Description | Notes ## FsCreateFolder -> FsCreateFolder(ctx, workspaceId, projectId).Path(path).Mode(mode).Execute() +> FsCreateFolder(ctx, workspaceId).Path(path).Mode(mode).Execute() Create folder @@ -210,13 +204,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path mode := "mode_example" // string | Mode configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.FsCreateFolder(context.Background(), workspaceId, projectId).Path(path).Mode(mode).Execute() + r, err := apiClient.WorkspaceToolboxAPI.FsCreateFolder(context.Background(), workspaceId).Path(path).Mode(mode).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsCreateFolder``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -231,7 +224,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -241,7 +233,6 @@ Other parameters are passed through a pointer to a apiFsCreateFolderRequest stru Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | **mode** | **string** | Mode | @@ -265,7 +256,7 @@ Name | Type | Description | Notes ## FsDeleteFile -> FsDeleteFile(ctx, workspaceId, projectId).Path(path).Execute() +> FsDeleteFile(ctx, workspaceId).Path(path).Execute() Delete file @@ -285,12 +276,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.FsDeleteFile(context.Background(), workspaceId, projectId).Path(path).Execute() + r, err := apiClient.WorkspaceToolboxAPI.FsDeleteFile(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsDeleteFile``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -305,7 +295,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -315,7 +304,6 @@ Other parameters are passed through a pointer to a apiFsDeleteFileRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | ### Return type @@ -338,7 +326,7 @@ Name | Type | Description | Notes ## FsDownloadFile -> *os.File FsDownloadFile(ctx, workspaceId, projectId).Path(path).Execute() +> *os.File FsDownloadFile(ctx, workspaceId).Path(path).Execute() Download file @@ -358,12 +346,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.FsDownloadFile(context.Background(), workspaceId, projectId).Path(path).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.FsDownloadFile(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsDownloadFile``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -380,7 +367,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -390,7 +376,6 @@ Other parameters are passed through a pointer to a apiFsDownloadFileRequest stru Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | ### Return type @@ -413,7 +398,7 @@ Name | Type | Description | Notes ## FsFindInFiles -> []Match FsFindInFiles(ctx, workspaceId, projectId).Path(path).Pattern(pattern).Execute() +> []Match FsFindInFiles(ctx, workspaceId).Path(path).Pattern(pattern).Execute() Search for text/pattern in files @@ -433,13 +418,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path pattern := "pattern_example" // string | Pattern configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.FsFindInFiles(context.Background(), workspaceId, projectId).Path(path).Pattern(pattern).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.FsFindInFiles(context.Background(), workspaceId).Path(path).Pattern(pattern).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsFindInFiles``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -456,7 +440,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -466,7 +449,6 @@ Other parameters are passed through a pointer to a apiFsFindInFilesRequest struc Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | **pattern** | **string** | Pattern | @@ -490,7 +472,7 @@ Name | Type | Description | Notes ## FsGetFileDetails -> FileInfo FsGetFileDetails(ctx, workspaceId, projectId).Path(path).Execute() +> FileInfo FsGetFileDetails(ctx, workspaceId).Path(path).Execute() Get file info @@ -510,12 +492,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.FsGetFileDetails(context.Background(), workspaceId, projectId).Path(path).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.FsGetFileDetails(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsGetFileDetails``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -532,7 +513,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -542,7 +522,6 @@ Other parameters are passed through a pointer to a apiFsGetFileDetailsRequest st Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | ### Return type @@ -565,7 +544,7 @@ Name | Type | Description | Notes ## FsListFiles -> []FileInfo FsListFiles(ctx, workspaceId, projectId).Path(path).Execute() +> []FileInfo FsListFiles(ctx, workspaceId).Path(path).Execute() List files @@ -585,12 +564,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.FsListFiles(context.Background(), workspaceId, projectId).Path(path).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.FsListFiles(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsListFiles``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -607,7 +585,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -617,7 +594,6 @@ Other parameters are passed through a pointer to a apiFsListFilesRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | ### Return type @@ -640,7 +616,7 @@ Name | Type | Description | Notes ## FsMoveFile -> FsMoveFile(ctx, workspaceId, projectId).Source(source).Destination(destination).Execute() +> FsMoveFile(ctx, workspaceId).Source(source).Destination(destination).Execute() Create folder @@ -660,13 +636,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID source := "source_example" // string | Source path destination := "destination_example" // string | Destination path configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.FsMoveFile(context.Background(), workspaceId, projectId).Source(source).Destination(destination).Execute() + r, err := apiClient.WorkspaceToolboxAPI.FsMoveFile(context.Background(), workspaceId).Source(source).Destination(destination).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsMoveFile``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -681,7 +656,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -691,7 +665,6 @@ Other parameters are passed through a pointer to a apiFsMoveFileRequest struct v Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **source** | **string** | Source path | **destination** | **string** | Destination path | @@ -715,7 +688,7 @@ Name | Type | Description | Notes ## FsReplaceInFiles -> []ReplaceResult FsReplaceInFiles(ctx, workspaceId, projectId).Replace(replace).Execute() +> []ReplaceResult FsReplaceInFiles(ctx, workspaceId).Replace(replace).Execute() Repleace text/pattern in files @@ -735,12 +708,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID replace := *openapiclient.NewReplaceRequest([]string{"Files_example"}, "NewValue_example", "Pattern_example") // ReplaceRequest | ReplaceParams configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.FsReplaceInFiles(context.Background(), workspaceId, projectId).Replace(replace).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.FsReplaceInFiles(context.Background(), workspaceId).Replace(replace).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsReplaceInFiles``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -757,7 +729,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -767,7 +738,6 @@ Other parameters are passed through a pointer to a apiFsReplaceInFilesRequest st Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **replace** | [**ReplaceRequest**](ReplaceRequest.md) | ReplaceParams | ### Return type @@ -790,7 +760,7 @@ Name | Type | Description | Notes ## FsSearchFiles -> SearchFilesResponse FsSearchFiles(ctx, workspaceId, projectId).Path(path).Pattern(pattern).Execute() +> SearchFilesResponse FsSearchFiles(ctx, workspaceId).Path(path).Pattern(pattern).Execute() Search for files @@ -810,13 +780,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path pattern := "pattern_example" // string | Pattern configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.FsSearchFiles(context.Background(), workspaceId, projectId).Path(path).Pattern(pattern).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.FsSearchFiles(context.Background(), workspaceId).Path(path).Pattern(pattern).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsSearchFiles``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -833,7 +802,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -843,7 +811,6 @@ Other parameters are passed through a pointer to a apiFsSearchFilesRequest struc Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | **pattern** | **string** | Pattern | @@ -867,7 +834,7 @@ Name | Type | Description | Notes ## FsSetFilePermissions -> FsSetFilePermissions(ctx, workspaceId, projectId).Path(path).Owner(owner).Group(group).Mode(mode).Execute() +> FsSetFilePermissions(ctx, workspaceId).Path(path).Owner(owner).Group(group).Mode(mode).Execute() Set file owner/group/permissions @@ -887,7 +854,6 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path owner := "owner_example" // string | Owner (optional) group := "group_example" // string | Group (optional) @@ -895,7 +861,7 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.FsSetFilePermissions(context.Background(), workspaceId, projectId).Path(path).Owner(owner).Group(group).Mode(mode).Execute() + r, err := apiClient.WorkspaceToolboxAPI.FsSetFilePermissions(context.Background(), workspaceId).Path(path).Owner(owner).Group(group).Mode(mode).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsSetFilePermissions``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -910,7 +876,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -920,7 +885,6 @@ Other parameters are passed through a pointer to a apiFsSetFilePermissionsReques Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | **owner** | **string** | Owner | **group** | **string** | Group | @@ -946,7 +910,7 @@ Name | Type | Description | Notes ## FsUploadFile -> FsUploadFile(ctx, workspaceId, projectId).Path(path).File(file).Execute() +> FsUploadFile(ctx, workspaceId).Path(path).File(file).Execute() Upload file @@ -966,13 +930,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path file := os.NewFile(1234, "some_file") // *os.File | File configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.FsUploadFile(context.Background(), workspaceId, projectId).Path(path).File(file).Execute() + r, err := apiClient.WorkspaceToolboxAPI.FsUploadFile(context.Background(), workspaceId).Path(path).File(file).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.FsUploadFile``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -987,7 +950,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -997,7 +959,6 @@ Other parameters are passed through a pointer to a apiFsUploadFileRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path | **file** | ***os.File** | File | @@ -1021,7 +982,7 @@ Name | Type | Description | Notes ## GetSessionCommandLogs -> string GetSessionCommandLogs(ctx, workspaceId, projectId, sessionId, commandId).Execute() +> string GetSessionCommandLogs(ctx, workspaceId, sessionId, commandId).Execute() Get session command logs @@ -1041,13 +1002,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID sessionId := "sessionId_example" // string | Session ID commandId := "commandId_example" // string | Command ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GetSessionCommandLogs(context.Background(), workspaceId, projectId, sessionId, commandId).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GetSessionCommandLogs(context.Background(), workspaceId, sessionId, commandId).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GetSessionCommandLogs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1064,7 +1024,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | **sessionId** | **string** | Session ID | **commandId** | **string** | Command ID | @@ -1079,7 +1038,6 @@ Name | Type | Description | Notes - ### Return type **string** @@ -1100,7 +1058,7 @@ Name | Type | Description | Notes ## GetWorkspaceDir -> WorkspaceDirResponse GetWorkspaceDir(ctx, workspaceId, projectId).Execute() +> WorkspaceDirResponse GetWorkspaceDir(ctx, workspaceId).Execute() Get workspace dir @@ -1120,11 +1078,10 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GetWorkspaceDir(context.Background(), workspaceId, projectId).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GetWorkspaceDir(context.Background(), workspaceId).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GetWorkspaceDir``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1141,7 +1098,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1152,7 +1108,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - ### Return type [**WorkspaceDirResponse**](WorkspaceDirResponse.md) @@ -1173,7 +1128,7 @@ Name | Type | Description | Notes ## GitAddFiles -> GitAddFiles(ctx, workspaceId, projectId).Params(params).Execute() +> GitAddFiles(ctx, workspaceId).Params(params).Execute() Add files @@ -1193,12 +1148,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewGitAddRequest([]string{"Files_example"}, "Path_example") // GitAddRequest | GitAddRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.GitAddFiles(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.GitAddFiles(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitAddFiles``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1213,7 +1167,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1223,7 +1176,6 @@ Other parameters are passed through a pointer to a apiGitAddFilesRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**GitAddRequest**](GitAddRequest.md) | GitAddRequest | ### Return type @@ -1246,7 +1198,7 @@ Name | Type | Description | Notes ## GitBranchList -> ListBranchResponse GitBranchList(ctx, workspaceId, projectId).Path(path).Execute() +> ListBranchResponse GitBranchList(ctx, workspaceId).Path(path).Execute() Get branch list @@ -1266,12 +1218,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path to git repository configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GitBranchList(context.Background(), workspaceId, projectId).Path(path).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GitBranchList(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitBranchList``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1288,7 +1239,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1298,7 +1248,6 @@ Other parameters are passed through a pointer to a apiGitBranchListRequest struc Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path to git repository | ### Return type @@ -1321,7 +1270,7 @@ Name | Type | Description | Notes ## GitCloneRepository -> GitCloneRepository(ctx, workspaceId, projectId).Params(params).Execute() +> GitCloneRepository(ctx, workspaceId).Params(params).Execute() Clone git repository @@ -1341,12 +1290,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewGitCloneRequest("Path_example", "Url_example") // GitCloneRequest | GitCloneRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.GitCloneRepository(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.GitCloneRepository(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitCloneRepository``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1361,7 +1309,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1371,7 +1318,6 @@ Other parameters are passed through a pointer to a apiGitCloneRepositoryRequest Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**GitCloneRequest**](GitCloneRequest.md) | GitCloneRequest | ### Return type @@ -1394,7 +1340,7 @@ Name | Type | Description | Notes ## GitCommitChanges -> GitCommitResponse GitCommitChanges(ctx, workspaceId, projectId).Params(params).Execute() +> GitCommitResponse GitCommitChanges(ctx, workspaceId).Params(params).Execute() Commit changes @@ -1414,12 +1360,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewGitCommitRequest("Author_example", "Email_example", "Message_example", "Path_example") // GitCommitRequest | GitCommitRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GitCommitChanges(context.Background(), workspaceId, projectId).Params(params).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GitCommitChanges(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitCommitChanges``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1436,7 +1381,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1446,7 +1390,6 @@ Other parameters are passed through a pointer to a apiGitCommitChangesRequest st Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**GitCommitRequest**](GitCommitRequest.md) | GitCommitRequest | ### Return type @@ -1469,7 +1412,7 @@ Name | Type | Description | Notes ## GitCommitHistory -> []GitCommitInfo GitCommitHistory(ctx, workspaceId, projectId).Path(path).Execute() +> []GitCommitInfo GitCommitHistory(ctx, workspaceId).Path(path).Execute() Get commit history @@ -1489,12 +1432,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path to git repository configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GitCommitHistory(context.Background(), workspaceId, projectId).Path(path).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GitCommitHistory(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitCommitHistory``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1511,7 +1453,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1521,7 +1462,6 @@ Other parameters are passed through a pointer to a apiGitCommitHistoryRequest st Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path to git repository | ### Return type @@ -1544,7 +1484,7 @@ Name | Type | Description | Notes ## GitCreateBranch -> GitCreateBranch(ctx, workspaceId, projectId).Params(params).Execute() +> GitCreateBranch(ctx, workspaceId).Params(params).Execute() Create branch @@ -1564,12 +1504,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewGitBranchRequest("Name_example", "Path_example") // GitBranchRequest | GitBranchRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.GitCreateBranch(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.GitCreateBranch(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitCreateBranch``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1584,7 +1523,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1594,7 +1532,6 @@ Other parameters are passed through a pointer to a apiGitCreateBranchRequest str Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**GitBranchRequest**](GitBranchRequest.md) | GitBranchRequest | ### Return type @@ -1617,7 +1554,7 @@ Name | Type | Description | Notes ## GitGitStatus -> GitStatus GitGitStatus(ctx, workspaceId, projectId).Path(path).Execute() +> GitStatus GitGitStatus(ctx, workspaceId).Path(path).Execute() Get git status @@ -1637,12 +1574,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID path := "path_example" // string | Path to git repository configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.GitGitStatus(context.Background(), workspaceId, projectId).Path(path).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.GitGitStatus(context.Background(), workspaceId).Path(path).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitGitStatus``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1659,7 +1595,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1669,7 +1604,6 @@ Other parameters are passed through a pointer to a apiGitGitStatusRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **path** | **string** | Path to git repository | ### Return type @@ -1692,7 +1626,7 @@ Name | Type | Description | Notes ## GitPullChanges -> GitPullChanges(ctx, workspaceId, projectId).Params(params).Execute() +> GitPullChanges(ctx, workspaceId).Params(params).Execute() Pull changes @@ -1712,12 +1646,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewGitRepoRequest("Path_example") // GitRepoRequest | Git pull request configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.GitPullChanges(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.GitPullChanges(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitPullChanges``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1732,7 +1665,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1742,7 +1674,6 @@ Other parameters are passed through a pointer to a apiGitPullChangesRequest stru Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**GitRepoRequest**](GitRepoRequest.md) | Git pull request | ### Return type @@ -1765,7 +1696,7 @@ Name | Type | Description | Notes ## GitPushChanges -> GitPushChanges(ctx, workspaceId, projectId).Params(params).Execute() +> GitPushChanges(ctx, workspaceId).Params(params).Execute() Push changes @@ -1785,12 +1716,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewGitRepoRequest("Path_example") // GitRepoRequest | Git push request configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.GitPushChanges(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.GitPushChanges(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.GitPushChanges``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1805,7 +1735,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1815,7 +1744,6 @@ Other parameters are passed through a pointer to a apiGitPushChangesRequest stru Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**GitRepoRequest**](GitRepoRequest.md) | Git push request | ### Return type @@ -1838,7 +1766,7 @@ Name | Type | Description | Notes ## ListSessions -> []Session ListSessions(ctx, workspaceId, projectId).Execute() +> []Session ListSessions(ctx, workspaceId).Execute() List sessions @@ -1858,11 +1786,10 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.ListSessions(context.Background(), workspaceId, projectId).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.ListSessions(context.Background(), workspaceId).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.ListSessions``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1879,7 +1806,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1890,7 +1816,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - ### Return type [**[]Session**](Session.md) @@ -1911,7 +1836,7 @@ Name | Type | Description | Notes ## LspCompletions -> CompletionList LspCompletions(ctx, workspaceId, projectId).Params(params).Execute() +> CompletionList LspCompletions(ctx, workspaceId).Params(params).Execute() Get Lsp Completions @@ -1931,12 +1856,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewLspCompletionParams("LanguageId_example", "PathToProject_example", *openapiclient.NewPosition(int32(123), int32(123)), "Uri_example") // LspCompletionParams | LspCompletionParams configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.LspCompletions(context.Background(), workspaceId, projectId).Params(params).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.LspCompletions(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspCompletions``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -1953,7 +1877,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -1963,7 +1886,6 @@ Other parameters are passed through a pointer to a apiLspCompletionsRequest stru Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**LspCompletionParams**](LspCompletionParams.md) | LspCompletionParams | ### Return type @@ -1986,7 +1908,7 @@ Name | Type | Description | Notes ## LspDidClose -> LspDidClose(ctx, workspaceId, projectId).Params(params).Execute() +> LspDidClose(ctx, workspaceId).Params(params).Execute() Call Lsp DidClose @@ -2006,12 +1928,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewLspDocumentRequest("LanguageId_example", "PathToProject_example", "Uri_example") // LspDocumentRequest | LspDocumentRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.LspDidClose(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.LspDidClose(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspDidClose``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2026,7 +1947,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2036,7 +1956,6 @@ Other parameters are passed through a pointer to a apiLspDidCloseRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**LspDocumentRequest**](LspDocumentRequest.md) | LspDocumentRequest | ### Return type @@ -2059,7 +1978,7 @@ Name | Type | Description | Notes ## LspDidOpen -> LspDidOpen(ctx, workspaceId, projectId).Params(params).Execute() +> LspDidOpen(ctx, workspaceId).Params(params).Execute() Call Lsp DidOpen @@ -2079,12 +1998,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewLspDocumentRequest("LanguageId_example", "PathToProject_example", "Uri_example") // LspDocumentRequest | LspDocumentRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.LspDidOpen(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.LspDidOpen(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspDidOpen``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2099,7 +2017,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2109,7 +2026,6 @@ Other parameters are passed through a pointer to a apiLspDidOpenRequest struct v Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**LspDocumentRequest**](LspDocumentRequest.md) | LspDocumentRequest | ### Return type @@ -2132,7 +2048,7 @@ Name | Type | Description | Notes ## LspDocumentSymbols -> []LspSymbol LspDocumentSymbols(ctx, workspaceId, projectId).LanguageId(languageId).PathToProject(pathToProject).Uri(uri).Execute() +> []LspSymbol LspDocumentSymbols(ctx, workspaceId).LanguageId(languageId).PathToProject(pathToProject).Uri(uri).Execute() Call Lsp DocumentSymbols @@ -2152,14 +2068,13 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID languageId := "languageId_example" // string | Language ID pathToProject := "pathToProject_example" // string | Path to project uri := "uri_example" // string | Document Uri configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.LspDocumentSymbols(context.Background(), workspaceId, projectId).LanguageId(languageId).PathToProject(pathToProject).Uri(uri).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.LspDocumentSymbols(context.Background(), workspaceId).LanguageId(languageId).PathToProject(pathToProject).Uri(uri).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspDocumentSymbols``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2176,7 +2091,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2186,7 +2100,6 @@ Other parameters are passed through a pointer to a apiLspDocumentSymbolsRequest Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **languageId** | **string** | Language ID | **pathToProject** | **string** | Path to project | **uri** | **string** | Document Uri | @@ -2211,7 +2124,7 @@ Name | Type | Description | Notes ## LspStart -> LspStart(ctx, workspaceId, projectId).Params(params).Execute() +> LspStart(ctx, workspaceId).Params(params).Execute() Start Lsp server @@ -2231,12 +2144,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewLspServerRequest("LanguageId_example", "PathToProject_example") // LspServerRequest | LspServerRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.LspStart(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.LspStart(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspStart``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2251,7 +2163,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2261,7 +2172,6 @@ Other parameters are passed through a pointer to a apiLspStartRequest struct via Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**LspServerRequest**](LspServerRequest.md) | LspServerRequest | ### Return type @@ -2284,7 +2194,7 @@ Name | Type | Description | Notes ## LspStop -> LspStop(ctx, workspaceId, projectId).Params(params).Execute() +> LspStop(ctx, workspaceId).Params(params).Execute() Stop Lsp server @@ -2304,12 +2214,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewLspServerRequest("LanguageId_example", "PathToProject_example") // LspServerRequest | LspServerRequest configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceToolboxAPI.LspStop(context.Background(), workspaceId, projectId).Params(params).Execute() + r, err := apiClient.WorkspaceToolboxAPI.LspStop(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspStop``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2324,7 +2233,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2334,7 +2242,6 @@ Other parameters are passed through a pointer to a apiLspStopRequest struct via Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**LspServerRequest**](LspServerRequest.md) | LspServerRequest | ### Return type @@ -2357,7 +2264,7 @@ Name | Type | Description | Notes ## LspWorkspaceSymbols -> []LspSymbol LspWorkspaceSymbols(ctx, workspaceId, projectId).LanguageId(languageId).PathToProject(pathToProject).Query(query).Execute() +> []LspSymbol LspWorkspaceSymbols(ctx, workspaceId).LanguageId(languageId).PathToProject(pathToProject).Query(query).Execute() Call Lsp WorkspaceSymbols @@ -2377,14 +2284,13 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID languageId := "languageId_example" // string | Language ID pathToProject := "pathToProject_example" // string | Path to project query := "query_example" // string | Symbol Query configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.LspWorkspaceSymbols(context.Background(), workspaceId, projectId).LanguageId(languageId).PathToProject(pathToProject).Query(query).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.LspWorkspaceSymbols(context.Background(), workspaceId).LanguageId(languageId).PathToProject(pathToProject).Query(query).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.LspWorkspaceSymbols``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2401,7 +2307,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2411,7 +2316,6 @@ Other parameters are passed through a pointer to a apiLspWorkspaceSymbolsRequest Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **languageId** | **string** | Language ID | **pathToProject** | **string** | Path to project | **query** | **string** | Symbol Query | @@ -2436,7 +2340,7 @@ Name | Type | Description | Notes ## ProcessExecuteCommand -> ExecuteResponse ProcessExecuteCommand(ctx, workspaceId, projectId).Params(params).Execute() +> ExecuteResponse ProcessExecuteCommand(ctx, workspaceId).Params(params).Execute() Execute command @@ -2456,12 +2360,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID params := *openapiclient.NewExecuteRequest("Command_example") // ExecuteRequest | Execute command request configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.ProcessExecuteCommand(context.Background(), workspaceId, projectId).Params(params).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.ProcessExecuteCommand(context.Background(), workspaceId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.ProcessExecuteCommand``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2478,7 +2381,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | ### Other Parameters @@ -2488,7 +2390,6 @@ Other parameters are passed through a pointer to a apiProcessExecuteCommandReque Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**ExecuteRequest**](ExecuteRequest.md) | Execute command request | ### Return type @@ -2511,7 +2412,7 @@ Name | Type | Description | Notes ## SessionExecuteCommand -> SessionExecuteResponse SessionExecuteCommand(ctx, workspaceId, projectId, sessionId).Params(params).Execute() +> SessionExecuteResponse SessionExecuteCommand(ctx, workspaceId, sessionId).Params(params).Execute() Execute command in session @@ -2531,13 +2432,12 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - projectId := "projectId_example" // string | Project ID sessionId := "sessionId_example" // string | Session ID params := *openapiclient.NewSessionExecuteRequest("Command_example") // SessionExecuteRequest | Execute command request configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceToolboxAPI.SessionExecuteCommand(context.Background(), workspaceId, projectId, sessionId).Params(params).Execute() + resp, r, err := apiClient.WorkspaceToolboxAPI.SessionExecuteCommand(context.Background(), workspaceId, sessionId).Params(params).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceToolboxAPI.SessionExecuteCommand``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -2554,7 +2454,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **workspaceId** | **string** | Workspace ID or Name | -**projectId** | **string** | Project ID | **sessionId** | **string** | Session ID | ### Other Parameters @@ -2566,7 +2465,6 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **params** | [**SessionExecuteRequest**](SessionExecuteRequest.md) | Execute command request | ### Return type diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/WorkspaceViewDTO.md similarity index 58% rename from pkg/apiclient/docs/Workspace.md rename to pkg/apiclient/docs/WorkspaceViewDTO.md index a7f1c89107..098ae0c2c4 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/WorkspaceViewDTO.md @@ -1,4 +1,4 @@ -# Workspace +# WorkspaceViewDTO ## Properties @@ -7,244 +7,265 @@ Name | Type | Description | Notes **BuildConfig** | Pointer to [**BuildConfig**](BuildConfig.md) | | [optional] **EnvVars** | **map[string]string** | | **GitProviderConfigId** | Pointer to **string** | | [optional] +**Id** | **string** | | **Image** | **string** | | **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | **State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] -**TargetConfig** | **string** | | **TargetId** | **string** | | +**TargetName** | **string** | | **User** | **string** | | ## Methods -### NewWorkspace +### NewWorkspaceViewDTO -`func NewWorkspace(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string, ) *Workspace` +`func NewWorkspaceViewDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string, ) *WorkspaceViewDTO` -NewWorkspace instantiates a new Workspace object +NewWorkspaceViewDTO instantiates a new WorkspaceViewDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceWithDefaults +### NewWorkspaceViewDTOWithDefaults -`func NewWorkspaceWithDefaults() *Workspace` +`func NewWorkspaceViewDTOWithDefaults() *WorkspaceViewDTO` -NewWorkspaceWithDefaults instantiates a new Workspace object +NewWorkspaceViewDTOWithDefaults instantiates a new WorkspaceViewDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *Workspace) GetBuildConfig() BuildConfig` +`func (o *WorkspaceViewDTO) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *WorkspaceViewDTO) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *Workspace) SetBuildConfig(v BuildConfig)` +`func (o *WorkspaceViewDTO) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *Workspace) HasBuildConfig() bool` +`func (o *WorkspaceViewDTO) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetEnvVars -`func (o *Workspace) GetEnvVars() map[string]string` +`func (o *WorkspaceViewDTO) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *WorkspaceViewDTO) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *Workspace) SetEnvVars(v map[string]string)` +`func (o *WorkspaceViewDTO) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *Workspace) GetGitProviderConfigId() string` +`func (o *WorkspaceViewDTO) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *WorkspaceViewDTO) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *Workspace) SetGitProviderConfigId(v string)` +`func (o *WorkspaceViewDTO) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *Workspace) HasGitProviderConfigId() bool` +`func (o *WorkspaceViewDTO) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. +### GetId + +`func (o *WorkspaceViewDTO) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *WorkspaceViewDTO) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *WorkspaceViewDTO) SetId(v string)` + +SetId sets Id field to given value. + + ### GetImage -`func (o *Workspace) GetImage() string` +`func (o *WorkspaceViewDTO) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *Workspace) GetImageOk() (*string, bool)` +`func (o *WorkspaceViewDTO) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *Workspace) SetImage(v string)` +`func (o *WorkspaceViewDTO) SetImage(v string)` SetImage sets Image field to given value. ### GetName -`func (o *Workspace) GetName() string` +`func (o *WorkspaceViewDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *Workspace) GetNameOk() (*string, bool)` +`func (o *WorkspaceViewDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *Workspace) SetName(v string)` +`func (o *WorkspaceViewDTO) SetName(v string)` SetName sets Name field to given value. ### GetRepository -`func (o *Workspace) GetRepository() GitRepository` +`func (o *WorkspaceViewDTO) GetRepository() GitRepository` GetRepository returns the Repository field if non-nil, zero value otherwise. ### GetRepositoryOk -`func (o *Workspace) GetRepositoryOk() (*GitRepository, bool)` +`func (o *WorkspaceViewDTO) GetRepositoryOk() (*GitRepository, bool)` GetRepositoryOk returns a tuple with the Repository field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepository -`func (o *Workspace) SetRepository(v GitRepository)` +`func (o *WorkspaceViewDTO) SetRepository(v GitRepository)` SetRepository sets Repository field to given value. ### GetState -`func (o *Workspace) GetState() WorkspaceState` +`func (o *WorkspaceViewDTO) GetState() WorkspaceState` GetState returns the State field if non-nil, zero value otherwise. ### GetStateOk -`func (o *Workspace) GetStateOk() (*WorkspaceState, bool)` +`func (o *WorkspaceViewDTO) GetStateOk() (*WorkspaceState, bool)` GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetState -`func (o *Workspace) SetState(v WorkspaceState)` +`func (o *WorkspaceViewDTO) SetState(v WorkspaceState)` SetState sets State field to given value. ### HasState -`func (o *Workspace) HasState() bool` +`func (o *WorkspaceViewDTO) HasState() bool` HasState returns a boolean if a field has been set. -### GetTargetConfig +### GetTargetId -`func (o *Workspace) GetTargetConfig() string` +`func (o *WorkspaceViewDTO) GetTargetId() string` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetTargetId returns the TargetId field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetTargetIdOk -`func (o *Workspace) GetTargetConfigOk() (*string, bool)` +`func (o *WorkspaceViewDTO) GetTargetIdOk() (*string, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetTargetId -`func (o *Workspace) SetTargetConfig(v string)` +`func (o *WorkspaceViewDTO) SetTargetId(v string)` -SetTargetConfig sets TargetConfig field to given value. +SetTargetId sets TargetId field to given value. -### GetTargetId +### GetTargetName -`func (o *Workspace) GetTargetId() string` +`func (o *WorkspaceViewDTO) GetTargetName() string` -GetTargetId returns the TargetId field if non-nil, zero value otherwise. +GetTargetName returns the TargetName field if non-nil, zero value otherwise. -### GetTargetIdOk +### GetTargetNameOk -`func (o *Workspace) GetTargetIdOk() (*string, bool)` +`func (o *WorkspaceViewDTO) GetTargetNameOk() (*string, bool)` -GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise +GetTargetNameOk returns a tuple with the TargetName field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetId +### SetTargetName -`func (o *Workspace) SetTargetId(v string)` +`func (o *WorkspaceViewDTO) SetTargetName(v string)` -SetTargetId sets TargetId field to given value. +SetTargetName sets TargetName field to given value. ### GetUser -`func (o *Workspace) GetUser() string` +`func (o *WorkspaceViewDTO) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *Workspace) GetUserOk() (*string, bool)` +`func (o *WorkspaceViewDTO) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *Workspace) SetUser(v string)` +`func (o *WorkspaceViewDTO) SetUser(v string)` SetUser sets User field to given value. diff --git a/pkg/apiclient/model_create_target_dto.go b/pkg/apiclient/model_create_target_dto.go index f9da9ea7c8..b4e403a84d 100644 --- a/pkg/apiclient/model_create_target_dto.go +++ b/pkg/apiclient/model_create_target_dto.go @@ -21,10 +21,9 @@ var _ MappedNullable = &CreateTargetDTO{} // CreateTargetDTO struct for CreateTargetDTO type CreateTargetDTO struct { - Id string `json:"id"` - Name string `json:"name"` - TargetConfig string `json:"targetConfig"` - Workspaces []CreateWorkspaceDTO `json:"workspaces"` + Id string `json:"id"` + Name string `json:"name"` + TargetConfig string `json:"targetConfig"` } type _CreateTargetDTO CreateTargetDTO @@ -33,12 +32,11 @@ type _CreateTargetDTO CreateTargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateTargetDTO(id string, name string, targetConfig string, workspaces []CreateWorkspaceDTO) *CreateTargetDTO { +func NewCreateTargetDTO(id string, name string, targetConfig string) *CreateTargetDTO { this := CreateTargetDTO{} this.Id = id this.Name = name this.TargetConfig = targetConfig - this.Workspaces = workspaces return &this } @@ -122,30 +120,6 @@ func (o *CreateTargetDTO) SetTargetConfig(v string) { o.TargetConfig = v } -// GetWorkspaces returns the Workspaces field value -func (o *CreateTargetDTO) GetWorkspaces() []CreateWorkspaceDTO { - if o == nil { - var ret []CreateWorkspaceDTO - return ret - } - - return o.Workspaces -} - -// GetWorkspacesOk returns a tuple with the Workspaces field value -// and a boolean to check if the value has been set. -func (o *CreateTargetDTO) GetWorkspacesOk() ([]CreateWorkspaceDTO, bool) { - if o == nil { - return nil, false - } - return o.Workspaces, true -} - -// SetWorkspaces sets field value -func (o *CreateTargetDTO) SetWorkspaces(v []CreateWorkspaceDTO) { - o.Workspaces = v -} - func (o CreateTargetDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -159,7 +133,6 @@ func (o CreateTargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["id"] = o.Id toSerialize["name"] = o.Name toSerialize["targetConfig"] = o.TargetConfig - toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -171,7 +144,6 @@ func (o *CreateTargetDTO) UnmarshalJSON(data []byte) (err error) { "id", "name", "targetConfig", - "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_create_workspace_dto.go b/pkg/apiclient/model_create_workspace_dto.go index 060e4ac114..dab99f5460 100644 --- a/pkg/apiclient/model_create_workspace_dto.go +++ b/pkg/apiclient/model_create_workspace_dto.go @@ -24,9 +24,11 @@ type CreateWorkspaceDTO struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` + Id string `json:"id"` Image *string `json:"image,omitempty"` Name string `json:"name"` Source CreateWorkspaceSourceDTO `json:"source"` + TargetId string `json:"targetId"` User *string `json:"user,omitempty"` } @@ -36,11 +38,13 @@ type _CreateWorkspaceDTO CreateWorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateWorkspaceDTO(envVars map[string]string, name string, source CreateWorkspaceSourceDTO) *CreateWorkspaceDTO { +func NewCreateWorkspaceDTO(envVars map[string]string, id string, name string, source CreateWorkspaceSourceDTO, targetId string) *CreateWorkspaceDTO { this := CreateWorkspaceDTO{} this.EnvVars = envVars + this.Id = id this.Name = name this.Source = source + this.TargetId = targetId return &this } @@ -140,6 +144,30 @@ func (o *CreateWorkspaceDTO) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } +// GetId returns the Id field value +func (o *CreateWorkspaceDTO) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *CreateWorkspaceDTO) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *CreateWorkspaceDTO) SetId(v string) { + o.Id = v +} + // GetImage returns the Image field value if set, zero value otherwise. func (o *CreateWorkspaceDTO) GetImage() string { if o == nil || IsNil(o.Image) { @@ -220,6 +248,30 @@ func (o *CreateWorkspaceDTO) SetSource(v CreateWorkspaceSourceDTO) { o.Source = v } +// GetTargetId returns the TargetId field value +func (o *CreateWorkspaceDTO) GetTargetId() string { + if o == nil { + var ret string + return ret + } + + return o.TargetId +} + +// GetTargetIdOk returns a tuple with the TargetId field value +// and a boolean to check if the value has been set. +func (o *CreateWorkspaceDTO) GetTargetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.TargetId, true +} + +// SetTargetId sets field value +func (o *CreateWorkspaceDTO) SetTargetId(v string) { + o.TargetId = v +} + // GetUser returns the User field value if set, zero value otherwise. func (o *CreateWorkspaceDTO) GetUser() string { if o == nil || IsNil(o.User) { @@ -269,11 +321,13 @@ func (o CreateWorkspaceDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.GitProviderConfigId) { toSerialize["gitProviderConfigId"] = o.GitProviderConfigId } + toSerialize["id"] = o.Id if !IsNil(o.Image) { toSerialize["image"] = o.Image } toSerialize["name"] = o.Name toSerialize["source"] = o.Source + toSerialize["targetId"] = o.TargetId if !IsNil(o.User) { toSerialize["user"] = o.User } @@ -286,8 +340,10 @@ func (o *CreateWorkspaceDTO) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "envVars", + "id", "name", "source", + "targetId", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index cd132eff46..064753b9f8 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -21,10 +21,9 @@ var _ MappedNullable = &Target{} // Target struct for Target type Target struct { - Id string `json:"id"` - Name string `json:"name"` - TargetConfig string `json:"targetConfig"` - Workspaces []Workspace `json:"workspaces"` + Id string `json:"id"` + Name string `json:"name"` + TargetConfig string `json:"targetConfig"` } type _Target Target @@ -33,12 +32,11 @@ type _Target Target // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTarget(id string, name string, targetConfig string, workspaces []Workspace) *Target { +func NewTarget(id string, name string, targetConfig string) *Target { this := Target{} this.Id = id this.Name = name this.TargetConfig = targetConfig - this.Workspaces = workspaces return &this } @@ -122,30 +120,6 @@ func (o *Target) SetTargetConfig(v string) { o.TargetConfig = v } -// GetWorkspaces returns the Workspaces field value -func (o *Target) GetWorkspaces() []Workspace { - if o == nil { - var ret []Workspace - return ret - } - - return o.Workspaces -} - -// GetWorkspacesOk returns a tuple with the Workspaces field value -// and a boolean to check if the value has been set. -func (o *Target) GetWorkspacesOk() ([]Workspace, bool) { - if o == nil { - return nil, false - } - return o.Workspaces, true -} - -// SetWorkspaces sets field value -func (o *Target) SetWorkspaces(v []Workspace) { - o.Workspaces = v -} - func (o Target) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -159,7 +133,6 @@ func (o Target) ToMap() (map[string]interface{}, error) { toSerialize["id"] = o.Id toSerialize["name"] = o.Name toSerialize["targetConfig"] = o.TargetConfig - toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -171,7 +144,6 @@ func (o *Target) UnmarshalJSON(data []byte) (err error) { "id", "name", "targetConfig", - "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 59cc945b5a..bfaa4c5a09 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -25,7 +25,6 @@ type TargetDTO struct { Info *TargetInfo `json:"info,omitempty"` Name string `json:"name"` TargetConfig string `json:"targetConfig"` - Workspaces []Workspace `json:"workspaces"` } type _TargetDTO TargetDTO @@ -34,12 +33,11 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(id string, name string, targetConfig string, workspaces []Workspace) *TargetDTO { +func NewTargetDTO(id string, name string, targetConfig string) *TargetDTO { this := TargetDTO{} this.Id = id this.Name = name this.TargetConfig = targetConfig - this.Workspaces = workspaces return &this } @@ -155,30 +153,6 @@ func (o *TargetDTO) SetTargetConfig(v string) { o.TargetConfig = v } -// GetWorkspaces returns the Workspaces field value -func (o *TargetDTO) GetWorkspaces() []Workspace { - if o == nil { - var ret []Workspace - return ret - } - - return o.Workspaces -} - -// GetWorkspacesOk returns a tuple with the Workspaces field value -// and a boolean to check if the value has been set. -func (o *TargetDTO) GetWorkspacesOk() ([]Workspace, bool) { - if o == nil { - return nil, false - } - return o.Workspaces, true -} - -// SetWorkspaces sets field value -func (o *TargetDTO) SetWorkspaces(v []Workspace) { - o.Workspaces = v -} - func (o TargetDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -195,7 +169,6 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { } toSerialize["name"] = o.Name toSerialize["targetConfig"] = o.TargetConfig - toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -207,7 +180,6 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { "id", "name", "targetConfig", - "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_info.go b/pkg/apiclient/model_target_info.go index 3e72c92962..834c6a23d9 100644 --- a/pkg/apiclient/model_target_info.go +++ b/pkg/apiclient/model_target_info.go @@ -21,9 +21,8 @@ var _ MappedNullable = &TargetInfo{} // TargetInfo struct for TargetInfo type TargetInfo struct { - Name string `json:"name"` - ProviderMetadata *string `json:"providerMetadata,omitempty"` - Workspaces []WorkspaceInfo `json:"workspaces"` + Name string `json:"name"` + ProviderMetadata *string `json:"providerMetadata,omitempty"` } type _TargetInfo TargetInfo @@ -32,10 +31,9 @@ type _TargetInfo TargetInfo // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetInfo(name string, workspaces []WorkspaceInfo) *TargetInfo { +func NewTargetInfo(name string) *TargetInfo { this := TargetInfo{} this.Name = name - this.Workspaces = workspaces return &this } @@ -103,30 +101,6 @@ func (o *TargetInfo) SetProviderMetadata(v string) { o.ProviderMetadata = &v } -// GetWorkspaces returns the Workspaces field value -func (o *TargetInfo) GetWorkspaces() []WorkspaceInfo { - if o == nil { - var ret []WorkspaceInfo - return ret - } - - return o.Workspaces -} - -// GetWorkspacesOk returns a tuple with the Workspaces field value -// and a boolean to check if the value has been set. -func (o *TargetInfo) GetWorkspacesOk() ([]WorkspaceInfo, bool) { - if o == nil { - return nil, false - } - return o.Workspaces, true -} - -// SetWorkspaces sets field value -func (o *TargetInfo) SetWorkspaces(v []WorkspaceInfo) { - o.Workspaces = v -} - func (o TargetInfo) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -141,7 +115,6 @@ func (o TargetInfo) ToMap() (map[string]interface{}, error) { if !IsNil(o.ProviderMetadata) { toSerialize["providerMetadata"] = o.ProviderMetadata } - toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -151,7 +124,6 @@ func (o *TargetInfo) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "name", - "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go new file mode 100644 index 0000000000..9604431821 --- /dev/null +++ b/pkg/apiclient/model_workspace_dto.go @@ -0,0 +1,496 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the WorkspaceDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceDTO{} + +// WorkspaceDTO struct for WorkspaceDTO +type WorkspaceDTO struct { + BuildConfig *BuildConfig `json:"buildConfig,omitempty"` + EnvVars map[string]string `json:"envVars"` + GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` + Id string `json:"id"` + Image string `json:"image"` + Info *WorkspaceInfo `json:"info,omitempty"` + Name string `json:"name"` + Repository GitRepository `json:"repository"` + State *WorkspaceState `json:"state,omitempty"` + TargetId string `json:"targetId"` + TargetName string `json:"targetName"` + User string `json:"user"` +} + +type _WorkspaceDTO WorkspaceDTO + +// NewWorkspaceDTO instantiates a new WorkspaceDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string) *WorkspaceDTO { + this := WorkspaceDTO{} + this.EnvVars = envVars + this.Id = id + this.Image = image + this.Name = name + this.Repository = repository + this.TargetId = targetId + this.TargetName = targetName + this.User = user + return &this +} + +// NewWorkspaceDTOWithDefaults instantiates a new WorkspaceDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewWorkspaceDTOWithDefaults() *WorkspaceDTO { + this := WorkspaceDTO{} + return &this +} + +// GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetBuildConfig() BuildConfig { + if o == nil || IsNil(o.BuildConfig) { + var ret BuildConfig + return ret + } + return *o.BuildConfig +} + +// GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetBuildConfigOk() (*BuildConfig, bool) { + if o == nil || IsNil(o.BuildConfig) { + return nil, false + } + return o.BuildConfig, true +} + +// HasBuildConfig returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasBuildConfig() bool { + if o != nil && !IsNil(o.BuildConfig) { + return true + } + + return false +} + +// SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. +func (o *WorkspaceDTO) SetBuildConfig(v BuildConfig) { + o.BuildConfig = &v +} + +// GetEnvVars returns the EnvVars field value +func (o *WorkspaceDTO) GetEnvVars() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.EnvVars +} + +// GetEnvVarsOk returns a tuple with the EnvVars field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetEnvVarsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.EnvVars, true +} + +// SetEnvVars sets field value +func (o *WorkspaceDTO) SetEnvVars(v map[string]string) { + o.EnvVars = v +} + +// GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetGitProviderConfigId() string { + if o == nil || IsNil(o.GitProviderConfigId) { + var ret string + return ret + } + return *o.GitProviderConfigId +} + +// GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetGitProviderConfigIdOk() (*string, bool) { + if o == nil || IsNil(o.GitProviderConfigId) { + return nil, false + } + return o.GitProviderConfigId, true +} + +// HasGitProviderConfigId returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasGitProviderConfigId() bool { + if o != nil && !IsNil(o.GitProviderConfigId) { + return true + } + + return false +} + +// SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. +func (o *WorkspaceDTO) SetGitProviderConfigId(v string) { + o.GitProviderConfigId = &v +} + +// GetId returns the Id field value +func (o *WorkspaceDTO) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *WorkspaceDTO) SetId(v string) { + o.Id = v +} + +// GetImage returns the Image field value +func (o *WorkspaceDTO) GetImage() string { + if o == nil { + var ret string + return ret + } + + return o.Image +} + +// GetImageOk returns a tuple with the Image field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetImageOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Image, true +} + +// SetImage sets field value +func (o *WorkspaceDTO) SetImage(v string) { + o.Image = v +} + +// GetInfo returns the Info field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetInfo() WorkspaceInfo { + if o == nil || IsNil(o.Info) { + var ret WorkspaceInfo + return ret + } + return *o.Info +} + +// GetInfoOk returns a tuple with the Info field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool) { + if o == nil || IsNil(o.Info) { + return nil, false + } + return o.Info, true +} + +// HasInfo returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasInfo() bool { + if o != nil && !IsNil(o.Info) { + return true + } + + return false +} + +// SetInfo gets a reference to the given WorkspaceInfo and assigns it to the Info field. +func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo) { + o.Info = &v +} + +// GetName returns the Name field value +func (o *WorkspaceDTO) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *WorkspaceDTO) SetName(v string) { + o.Name = v +} + +// GetRepository returns the Repository field value +func (o *WorkspaceDTO) GetRepository() GitRepository { + if o == nil { + var ret GitRepository + return ret + } + + return o.Repository +} + +// GetRepositoryOk returns a tuple with the Repository field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetRepositoryOk() (*GitRepository, bool) { + if o == nil { + return nil, false + } + return &o.Repository, true +} + +// SetRepository sets field value +func (o *WorkspaceDTO) SetRepository(v GitRepository) { + o.Repository = v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetState() WorkspaceState { + if o == nil || IsNil(o.State) { + var ret WorkspaceState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetStateOk() (*WorkspaceState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given WorkspaceState and assigns it to the State field. +func (o *WorkspaceDTO) SetState(v WorkspaceState) { + o.State = &v +} + +// GetTargetId returns the TargetId field value +func (o *WorkspaceDTO) GetTargetId() string { + if o == nil { + var ret string + return ret + } + + return o.TargetId +} + +// GetTargetIdOk returns a tuple with the TargetId field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetTargetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.TargetId, true +} + +// SetTargetId sets field value +func (o *WorkspaceDTO) SetTargetId(v string) { + o.TargetId = v +} + +// GetTargetName returns the TargetName field value +func (o *WorkspaceDTO) GetTargetName() string { + if o == nil { + var ret string + return ret + } + + return o.TargetName +} + +// GetTargetNameOk returns a tuple with the TargetName field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetTargetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.TargetName, true +} + +// SetTargetName sets field value +func (o *WorkspaceDTO) SetTargetName(v string) { + o.TargetName = v +} + +// GetUser returns the User field value +func (o *WorkspaceDTO) GetUser() string { + if o == nil { + var ret string + return ret + } + + return o.User +} + +// GetUserOk returns a tuple with the User field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetUserOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.User, true +} + +// SetUser sets field value +func (o *WorkspaceDTO) SetUser(v string) { + o.User = v +} + +func (o WorkspaceDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.BuildConfig) { + toSerialize["buildConfig"] = o.BuildConfig + } + toSerialize["envVars"] = o.EnvVars + if !IsNil(o.GitProviderConfigId) { + toSerialize["gitProviderConfigId"] = o.GitProviderConfigId + } + toSerialize["id"] = o.Id + toSerialize["image"] = o.Image + if !IsNil(o.Info) { + toSerialize["info"] = o.Info + } + toSerialize["name"] = o.Name + toSerialize["repository"] = o.Repository + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + toSerialize["targetId"] = o.TargetId + toSerialize["targetName"] = o.TargetName + toSerialize["user"] = o.User + return toSerialize, nil +} + +func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "envVars", + "id", + "image", + "name", + "repository", + "targetId", + "targetName", + "user", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varWorkspaceDTO := _WorkspaceDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varWorkspaceDTO) + + if err != nil { + return err + } + + *o = WorkspaceDTO(varWorkspaceDTO) + + return err +} + +type NullableWorkspaceDTO struct { + value *WorkspaceDTO + isSet bool +} + +func (v NullableWorkspaceDTO) Get() *WorkspaceDTO { + return v.value +} + +func (v *NullableWorkspaceDTO) Set(val *WorkspaceDTO) { + v.value = val + v.isSet = true +} + +func (v NullableWorkspaceDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableWorkspaceDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableWorkspaceDTO(val *WorkspaceDTO) *NullableWorkspaceDTO { + return &NullableWorkspaceDTO{value: val, isSet: true} +} + +func (v NullableWorkspaceDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableWorkspaceDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_workspace_view_dto.go similarity index 62% rename from pkg/apiclient/model_workspace.go rename to pkg/apiclient/model_workspace_view_dto.go index d5035f12cf..6591d6035e 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_workspace_view_dto.go @@ -16,51 +16,53 @@ import ( "fmt" ) -// checks if the Workspace type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &Workspace{} +// checks if the WorkspaceViewDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceViewDTO{} -// Workspace struct for Workspace -type Workspace struct { +// WorkspaceViewDTO struct for WorkspaceViewDTO +type WorkspaceViewDTO struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` + Id string `json:"id"` Image string `json:"image"` Name string `json:"name"` Repository GitRepository `json:"repository"` State *WorkspaceState `json:"state,omitempty"` - TargetConfig string `json:"targetConfig"` TargetId string `json:"targetId"` + TargetName string `json:"targetName"` User string `json:"user"` } -type _Workspace Workspace +type _WorkspaceViewDTO WorkspaceViewDTO -// NewWorkspace instantiates a new Workspace object +// NewWorkspaceViewDTO instantiates a new WorkspaceViewDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspace(envVars map[string]string, image string, name string, repository GitRepository, targetConfig string, targetId string, user string) *Workspace { - this := Workspace{} +func NewWorkspaceViewDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string) *WorkspaceViewDTO { + this := WorkspaceViewDTO{} this.EnvVars = envVars + this.Id = id this.Image = image this.Name = name this.Repository = repository - this.TargetConfig = targetConfig this.TargetId = targetId + this.TargetName = targetName this.User = user return &this } -// NewWorkspaceWithDefaults instantiates a new Workspace object +// NewWorkspaceViewDTOWithDefaults instantiates a new WorkspaceViewDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceWithDefaults() *Workspace { - this := Workspace{} +func NewWorkspaceViewDTOWithDefaults() *WorkspaceViewDTO { + this := WorkspaceViewDTO{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *Workspace) GetBuildConfig() BuildConfig { +func (o *WorkspaceViewDTO) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -70,7 +72,7 @@ func (o *Workspace) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *WorkspaceViewDTO) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -78,7 +80,7 @@ func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *Workspace) HasBuildConfig() bool { +func (o *WorkspaceViewDTO) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -87,12 +89,12 @@ func (o *Workspace) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *Workspace) SetBuildConfig(v BuildConfig) { +func (o *WorkspaceViewDTO) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetEnvVars returns the EnvVars field value -func (o *Workspace) GetEnvVars() map[string]string { +func (o *WorkspaceViewDTO) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -103,7 +105,7 @@ func (o *Workspace) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool) { +func (o *WorkspaceViewDTO) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -111,12 +113,12 @@ func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *Workspace) SetEnvVars(v map[string]string) { +func (o *WorkspaceViewDTO) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *Workspace) GetGitProviderConfigId() string { +func (o *WorkspaceViewDTO) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -126,7 +128,7 @@ func (o *Workspace) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool) { +func (o *WorkspaceViewDTO) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -134,7 +136,7 @@ func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *Workspace) HasGitProviderConfigId() bool { +func (o *WorkspaceViewDTO) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -143,12 +145,36 @@ func (o *Workspace) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *Workspace) SetGitProviderConfigId(v string) { +func (o *WorkspaceViewDTO) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } +// GetId returns the Id field value +func (o *WorkspaceViewDTO) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *WorkspaceViewDTO) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *WorkspaceViewDTO) SetId(v string) { + o.Id = v +} + // GetImage returns the Image field value -func (o *Workspace) GetImage() string { +func (o *WorkspaceViewDTO) GetImage() string { if o == nil { var ret string return ret @@ -159,7 +185,7 @@ func (o *Workspace) GetImage() string { // GetImageOk returns a tuple with the Image field value // and a boolean to check if the value has been set. -func (o *Workspace) GetImageOk() (*string, bool) { +func (o *WorkspaceViewDTO) GetImageOk() (*string, bool) { if o == nil { return nil, false } @@ -167,12 +193,12 @@ func (o *Workspace) GetImageOk() (*string, bool) { } // SetImage sets field value -func (o *Workspace) SetImage(v string) { +func (o *WorkspaceViewDTO) SetImage(v string) { o.Image = v } // GetName returns the Name field value -func (o *Workspace) GetName() string { +func (o *WorkspaceViewDTO) GetName() string { if o == nil { var ret string return ret @@ -183,7 +209,7 @@ func (o *Workspace) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *Workspace) GetNameOk() (*string, bool) { +func (o *WorkspaceViewDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -191,12 +217,12 @@ func (o *Workspace) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *Workspace) SetName(v string) { +func (o *WorkspaceViewDTO) SetName(v string) { o.Name = v } // GetRepository returns the Repository field value -func (o *Workspace) GetRepository() GitRepository { +func (o *WorkspaceViewDTO) GetRepository() GitRepository { if o == nil { var ret GitRepository return ret @@ -207,7 +233,7 @@ func (o *Workspace) GetRepository() GitRepository { // GetRepositoryOk returns a tuple with the Repository field value // and a boolean to check if the value has been set. -func (o *Workspace) GetRepositoryOk() (*GitRepository, bool) { +func (o *WorkspaceViewDTO) GetRepositoryOk() (*GitRepository, bool) { if o == nil { return nil, false } @@ -215,12 +241,12 @@ func (o *Workspace) GetRepositoryOk() (*GitRepository, bool) { } // SetRepository sets field value -func (o *Workspace) SetRepository(v GitRepository) { +func (o *WorkspaceViewDTO) SetRepository(v GitRepository) { o.Repository = v } // GetState returns the State field value if set, zero value otherwise. -func (o *Workspace) GetState() WorkspaceState { +func (o *WorkspaceViewDTO) GetState() WorkspaceState { if o == nil || IsNil(o.State) { var ret WorkspaceState return ret @@ -230,7 +256,7 @@ func (o *Workspace) GetState() WorkspaceState { // GetStateOk returns a tuple with the State field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Workspace) GetStateOk() (*WorkspaceState, bool) { +func (o *WorkspaceViewDTO) GetStateOk() (*WorkspaceState, bool) { if o == nil || IsNil(o.State) { return nil, false } @@ -238,7 +264,7 @@ func (o *Workspace) GetStateOk() (*WorkspaceState, bool) { } // HasState returns a boolean if a field has been set. -func (o *Workspace) HasState() bool { +func (o *WorkspaceViewDTO) HasState() bool { if o != nil && !IsNil(o.State) { return true } @@ -247,60 +273,60 @@ func (o *Workspace) HasState() bool { } // SetState gets a reference to the given WorkspaceState and assigns it to the State field. -func (o *Workspace) SetState(v WorkspaceState) { +func (o *WorkspaceViewDTO) SetState(v WorkspaceState) { o.State = &v } -// GetTargetConfig returns the TargetConfig field value -func (o *Workspace) GetTargetConfig() string { +// GetTargetId returns the TargetId field value +func (o *WorkspaceViewDTO) GetTargetId() string { if o == nil { var ret string return ret } - return o.TargetConfig + return o.TargetId } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *Workspace) GetTargetConfigOk() (*string, bool) { +func (o *WorkspaceViewDTO) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return &o.TargetId, true } -// SetTargetConfig sets field value -func (o *Workspace) SetTargetConfig(v string) { - o.TargetConfig = v +// SetTargetId sets field value +func (o *WorkspaceViewDTO) SetTargetId(v string) { + o.TargetId = v } -// GetTargetId returns the TargetId field value -func (o *Workspace) GetTargetId() string { +// GetTargetName returns the TargetName field value +func (o *WorkspaceViewDTO) GetTargetName() string { if o == nil { var ret string return ret } - return o.TargetId + return o.TargetName } -// GetTargetIdOk returns a tuple with the TargetId field value +// GetTargetNameOk returns a tuple with the TargetName field value // and a boolean to check if the value has been set. -func (o *Workspace) GetTargetIdOk() (*string, bool) { +func (o *WorkspaceViewDTO) GetTargetNameOk() (*string, bool) { if o == nil { return nil, false } - return &o.TargetId, true + return &o.TargetName, true } -// SetTargetId sets field value -func (o *Workspace) SetTargetId(v string) { - o.TargetId = v +// SetTargetName sets field value +func (o *WorkspaceViewDTO) SetTargetName(v string) { + o.TargetName = v } // GetUser returns the User field value -func (o *Workspace) GetUser() string { +func (o *WorkspaceViewDTO) GetUser() string { if o == nil { var ret string return ret @@ -311,7 +337,7 @@ func (o *Workspace) GetUser() string { // GetUserOk returns a tuple with the User field value // and a boolean to check if the value has been set. -func (o *Workspace) GetUserOk() (*string, bool) { +func (o *WorkspaceViewDTO) GetUserOk() (*string, bool) { if o == nil { return nil, false } @@ -319,11 +345,11 @@ func (o *Workspace) GetUserOk() (*string, bool) { } // SetUser sets field value -func (o *Workspace) SetUser(v string) { +func (o *WorkspaceViewDTO) SetUser(v string) { o.User = v } -func (o Workspace) MarshalJSON() ([]byte, error) { +func (o WorkspaceViewDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -331,7 +357,7 @@ func (o Workspace) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o Workspace) ToMap() (map[string]interface{}, error) { +func (o WorkspaceViewDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -340,29 +366,31 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { if !IsNil(o.GitProviderConfigId) { toSerialize["gitProviderConfigId"] = o.GitProviderConfigId } + toSerialize["id"] = o.Id toSerialize["image"] = o.Image toSerialize["name"] = o.Name toSerialize["repository"] = o.Repository if !IsNil(o.State) { toSerialize["state"] = o.State } - toSerialize["targetConfig"] = o.TargetConfig toSerialize["targetId"] = o.TargetId + toSerialize["targetName"] = o.TargetName toSerialize["user"] = o.User return toSerialize, nil } -func (o *Workspace) UnmarshalJSON(data []byte) (err error) { +func (o *WorkspaceViewDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ "envVars", + "id", "image", "name", "repository", - "targetConfig", "targetId", + "targetName", "user", } @@ -380,53 +408,53 @@ func (o *Workspace) UnmarshalJSON(data []byte) (err error) { } } - varWorkspace := _Workspace{} + varWorkspaceViewDTO := _WorkspaceViewDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspace) + err = decoder.Decode(&varWorkspaceViewDTO) if err != nil { return err } - *o = Workspace(varWorkspace) + *o = WorkspaceViewDTO(varWorkspaceViewDTO) return err } -type NullableWorkspace struct { - value *Workspace +type NullableWorkspaceViewDTO struct { + value *WorkspaceViewDTO isSet bool } -func (v NullableWorkspace) Get() *Workspace { +func (v NullableWorkspaceViewDTO) Get() *WorkspaceViewDTO { return v.value } -func (v *NullableWorkspace) Set(val *Workspace) { +func (v *NullableWorkspaceViewDTO) Set(val *WorkspaceViewDTO) { v.value = val v.isSet = true } -func (v NullableWorkspace) IsSet() bool { +func (v NullableWorkspaceViewDTO) IsSet() bool { return v.isSet } -func (v *NullableWorkspace) Unset() { +func (v *NullableWorkspaceViewDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspace(val *Workspace) *NullableWorkspace { - return &NullableWorkspace{value: val, isSet: true} +func NewNullableWorkspaceViewDTO(val *WorkspaceViewDTO) *NullableWorkspaceViewDTO { + return &NullableWorkspaceViewDTO{value: val, isSet: true} } -func (v NullableWorkspace) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceViewDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspace) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceViewDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/build/build.go b/pkg/build/build.go index c0b2ac4c63..de3343e033 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -9,8 +9,8 @@ import ( "time" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/containerconfig" ) type BuildState string diff --git a/pkg/build/detect/detect.go b/pkg/build/detect/detect.go index 1276882eaa..daca0e52ae 100644 --- a/pkg/build/detect/detect.go +++ b/pkg/build/detect/detect.go @@ -9,7 +9,7 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type BuilderType string diff --git a/pkg/build/store.go b/pkg/build/store.go index 7d885f04dd..1b863afa73 100644 --- a/pkg/build/store.go +++ b/pkg/build/store.go @@ -6,7 +6,7 @@ package build import ( "errors" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type Store interface { diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index 5c0966833e..46dfffb4c2 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -6,20 +6,24 @@ package agent import ( + "context" "fmt" "io" "os" "path/filepath" "github.com/daytonaio/daytona/cmd/daytona/config" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/agent" agent_config "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/agent/ssh" "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" ) @@ -42,7 +46,19 @@ var AgentCmd = &cobra.Command{ if err != nil { return err } - c.WorkspaceDir = filepath.Join(os.Getenv("HOME"), c.WorkspaceName) + + telemetryEnabled := os.Getenv("DAYTONA_TELEMETRY_ENABLED") == "true" + + var ws *workspace.Workspace + c.WorkspaceDir = os.Getenv("HOME") + + if agentMode == agent_config.ModeWorkspace { + ws, err = getWorkspace(c, telemetryEnabled) + if err != nil { + return err + } + c.WorkspaceDir = filepath.Join(os.Getenv("HOME"), ws.Name) + } configDir, err := config.GetConfigDir() if err != nil { @@ -82,7 +98,7 @@ var AgentCmd = &cobra.Command{ DefaultWorkspaceDir: os.Getenv("HOME"), } - tailscaleHostname := workspace.GetWorkspaceHostname(c.TargetId, c.WorkspaceName) + tailscaleHostname := workspace.GetWorkspaceHostname(c.WorkspaceId) if hostModeFlag { tailscaleHostname = c.TargetId } @@ -92,8 +108,6 @@ var AgentCmd = &cobra.Command{ ConfigDir: configDir, } - telemetryEnabled := os.Getenv("DAYTONA_TELEMETRY_ENABLED") == "true" - tailscaleServer := &tailscale.Server{ Hostname: tailscaleHostname, Server: c.Server, @@ -109,6 +123,7 @@ var AgentCmd = &cobra.Command{ Tailscale: tailscaleServer, LogWriter: agentLogWriter, TelemetryEnabled: telemetryEnabled, + Workspace: ws, } return agent.Start() @@ -133,3 +148,19 @@ func setLogLevel() { log.SetLevel(log.InfoLevel) } } + +func getWorkspace(c *agent_config.Config, telemetryEnabled bool) (*workspace.Workspace, error) { + ctx := context.Background() + + apiClient, err := apiclient_util.GetAgentApiClient(c.Server.ApiUrl, c.Server.ApiKey, c.ClientId, telemetryEnabled) + if err != nil { + return nil, err + } + + workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, c.WorkspaceId).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + return conversion.ToWorkspace(workspace), nil +} diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go index aeb2c42790..cb01706f8b 100644 --- a/pkg/cmd/agentmode/agent_mode.go +++ b/pkg/cmd/agentmode/agent_mode.go @@ -16,7 +16,7 @@ import ( ) var targetId = "" -var workspaceName = "" +var workspaceId = "" var agentModeRootCmd = &cobra.Command{ Use: "daytona", @@ -65,7 +65,7 @@ func init() { if targetIdEnv := os.Getenv("DAYTONA_TARGET_ID"); targetIdEnv != "" { targetId = targetIdEnv } - if workspaceNameEnv := os.Getenv("DAYTONA_WORKSPACE_NAME"); workspaceNameEnv != "" { - workspaceName = workspaceNameEnv + if workspaceIdEnv := os.Getenv("DAYTONA_WORKSPACE_ID"); workspaceIdEnv != "" { + workspaceId = workspaceIdEnv } } diff --git a/pkg/cmd/agentmode/forward.go b/pkg/cmd/agentmode/forward.go index efb28f0043..2e92e9c665 100644 --- a/pkg/cmd/agentmode/forward.go +++ b/pkg/cmd/agentmode/forward.go @@ -25,7 +25,7 @@ var portForwardCmd = &cobra.Command{ errChan := make(chan error) go func() { - errChan <- defaultPortForwardCmd.ForwardPublicPort(targetId, workspaceName, uint16(port), uint16(port)) + errChan <- defaultPortForwardCmd.ForwardPublicPort(targetId, workspaceId, uint16(port), uint16(port)) }() for { diff --git a/pkg/cmd/agentmode/git_cred.go b/pkg/cmd/agentmode/git_cred.go index 6341fca583..f12dcf51d0 100644 --- a/pkg/cmd/agentmode/git_cred.go +++ b/pkg/cmd/agentmode/git_cred.go @@ -37,22 +37,13 @@ var gitCredCmd = &cobra.Command{ return err } - target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() + workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } - var gitProviderConfigId *string - - for _, workspace := range target.Workspaces { - if workspace.Name == workspaceName { - gitProviderConfigId = workspace.GitProviderConfigId - break - } - } - - if gitProviderConfigId != nil { - gitProvider, _, _ := apiClient.GitProviderAPI.GetGitProvider(ctx, *gitProviderConfigId).Execute() + if workspace.GitProviderConfigId != nil { + gitProvider, _, _ := apiClient.GitProviderAPI.GetGitProvider(ctx, *workspace.GitProviderConfigId).Execute() if gitProvider != nil { fmt.Println("username=" + gitProvider.Username) fmt.Println("password=" + gitProvider.Token) diff --git a/pkg/cmd/agentmode/info.go b/pkg/cmd/agentmode/info.go index d7b6effe9f..dabe68d92a 100644 --- a/pkg/cmd/agentmode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -36,7 +36,7 @@ var infoCmd = &cobra.Command{ return nil } - info.Render(target, "", false) + info.Render(target, false) return nil }, } diff --git a/pkg/cmd/agentmode/restart.go b/pkg/cmd/agentmode/restart.go index 3dc454fa81..8758214f2d 100644 --- a/pkg/cmd/agentmode/restart.go +++ b/pkg/cmd/agentmode/restart.go @@ -4,12 +4,9 @@ package agentmode import ( - "fmt" + "errors" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient" - target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" - "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) @@ -19,21 +16,24 @@ var restartCmd = &cobra.Command{ Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := apiclient.GetApiClient(nil) - if err != nil { - return err - } + return errors.New("not implemented") + }, + // RunE: func(cmd *cobra.Command, args []string) error { + // apiClient, err := apiclient.GetApiClient(nil) + // if err != nil { + // return err + // } - err = target_cmd.RestartTarget(apiClient, targetId, workspaceName) - if err != nil { - return err - } + // err = target_cmd.RestartTarget(apiClient, targetId, workspaceId) + // if err != nil { + // return err + // } - if workspaceName != "" { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully restarted", workspaceName, targetId)) - } else { - views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) - } - return nil - }, + // if workspaceId != "" { + // views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully restarted", workspaceId, targetId)) + // } else { + // views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) + // } + // return nil + // }, } diff --git a/pkg/cmd/agentmode/start.go b/pkg/cmd/agentmode/start.go index 8897f4ccf5..1f64cabc4b 100644 --- a/pkg/cmd/agentmode/start.go +++ b/pkg/cmd/agentmode/start.go @@ -4,10 +4,9 @@ package agentmode import ( + "errors" + "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient" - target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" - "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) @@ -17,17 +16,20 @@ var startCmd = &cobra.Command{ Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := apiclient.GetApiClient(nil) - if err != nil { - return err - } + return errors.New("not implemented") + }, + // RunE: func(cmd *cobra.Command, args []string) error { + // apiClient, err := apiclient.GetApiClient(nil) + // if err != nil { + // return err + // } - err = target_cmd.StartTarget(apiClient, targetId, workspaceName) - if err != nil { - return err - } + // err = target_cmd.StartTarget(apiClient, targetId, workspaceId) + // if err != nil { + // return err + // } - views.RenderInfoMessage("Workspace successfully started") - return nil - }, + // views.RenderInfoMessage("Workspace successfully started") + // return nil + // }, } diff --git a/pkg/cmd/agentmode/stop.go b/pkg/cmd/agentmode/stop.go index 22a058b7ae..b452b4b6d9 100644 --- a/pkg/cmd/agentmode/stop.go +++ b/pkg/cmd/agentmode/stop.go @@ -4,12 +4,9 @@ package agentmode import ( - "fmt" + "errors" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient" - target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" - "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) @@ -19,21 +16,24 @@ var stopCmd = &cobra.Command{ Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := apiclient.GetApiClient(nil) - if err != nil { - return err - } + return errors.New("not implemented") + }, + // RunE: func(cmd *cobra.Command, args []string) error { + // apiClient, err := apiclient.GetApiClient(nil) + // if err != nil { + // return err + // } - err = target_cmd.StopTarget(apiClient, targetId, workspaceName) - if err != nil { - return err - } + // err = target_cmd.StopTarget(apiClient, targetId, workspaceId) + // if err != nil { + // return err + // } - if workspaceName != "" { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully stopped", workspaceName, targetId)) - } else { - views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) - } - return nil - }, + // if workspaceId != "" { + // views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully stopped", workspaceId, targetId)) + // } else { + // views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) + // } + // return nil + // }, } diff --git a/pkg/cmd/build/delete.go b/pkg/cmd/build/delete.go index f9426d8ae6..e9400d1577 100644 --- a/pkg/cmd/build/delete.go +++ b/pkg/cmd/build/delete.go @@ -9,8 +9,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/info.go b/pkg/cmd/build/info.go index 8bbe78687e..7af105a0be 100644 --- a/pkg/cmd/build/info.go +++ b/pkg/cmd/build/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/build/info" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index d4e23ba16f..143b9162b8 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index fdbc53c8ea..5e387c7be3 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -11,9 +11,9 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" + workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) @@ -45,7 +45,7 @@ var buildRunCmd = &cobra.Command{ return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := target_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := workspace_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 369ba39760..7de69fe7ac 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -28,6 +28,7 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/target" . "github.com/daytonaio/daytona/pkg/cmd/targetconfig" . "github.com/daytonaio/daytona/pkg/cmd/telemetry" + . "github.com/daytonaio/daytona/pkg/cmd/workspace" . "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/posthogservice" @@ -74,8 +75,8 @@ func Execute() error { rootCmd.AddCommand(purgeCmd) rootCmd.AddCommand(GitProviderCmd) rootCmd.AddCommand(StartCmd) - rootCmd.AddCommand(StopCmd) - rootCmd.AddCommand(RestartCmd) + // rootCmd.AddCommand(StopCmd) + // rootCmd.AddCommand(RestartCmd) rootCmd.AddCommand(InfoCmd) rootCmd.AddCommand(PrebuildCmd) rootCmd.AddCommand(BuildCmd) @@ -83,6 +84,7 @@ func Execute() error { rootCmd.AddCommand(EnvCmd) rootCmd.AddCommand(TelemetryCmd) rootCmd.AddCommand(updateCmd) + rootCmd.AddCommand(TargetCmd) SetupRootCommand(rootCmd) diff --git a/pkg/cmd/gitprovider/delete.go b/pkg/cmd/gitprovider/delete.go index 433566896c..af357b0db3 100644 --- a/pkg/cmd/gitprovider/delete.go +++ b/pkg/cmd/gitprovider/delete.go @@ -11,8 +11,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/gitprovider/update.go b/pkg/cmd/gitprovider/update.go index fd985318d8..15da83e337 100644 --- a/pkg/cmd/gitprovider/update.go +++ b/pkg/cmd/gitprovider/update.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/logs.go b/pkg/cmd/logs.go index 0c75cd4e72..eace2be835 100644 --- a/pkg/cmd/logs.go +++ b/pkg/cmd/logs.go @@ -4,15 +4,9 @@ package cmd import ( - "context" "errors" - "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" "github.com/spf13/cobra" ) @@ -26,81 +20,84 @@ var logsCmd = &cobra.Command{ GroupID: util.TARGET_GROUP, Aliases: []string{"lg", "log"}, RunE: func(cmd *cobra.Command, args []string) error { - ctx := context.Background() - c, err := config.GetConfig() - if err != nil { - return err - } + return errors.New("not implemented") + }, + // RunE: func(cmd *cobra.Command, args []string) error { + // ctx := context.Background() + // c, err := config.GetConfig() + // if err != nil { + // return err + // } - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } + // activeProfile, err := c.GetActiveProfile() + // if err != nil { + // return err + // } - var target *apiclient.TargetDTO - apiClient, err := apiclient_util.GetApiClient(&activeProfile) - if err != nil { - return err - } + // var target *apiclient.TargetDTO + // apiClient, err := apiclient_util.GetApiClient(&activeProfile) + // if err != nil { + // return err + // } - var ( - showTargetLogs = true - workspaceNames []string - ) + // var ( + // showTargetLogs = true + // workspaceNames []string + // ) - if len(args) == 0 { - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - if len(targetList) == 0 { - views.RenderInfoMessage("The target list is empty. Start off by running 'daytona create'.") - return nil - } - target = selection.GetTargetFromPrompt(targetList, "Get Logs For") - } else { - target, err = apiclient_util.GetTarget(args[0], false) - if err != nil { - return err - } - } + // if len(args) == 0 { + // targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + // if err != nil { + // return apiclient_util.HandleErrorResponse(res, err) + // } + // if len(targetList) == 0 { + // views.RenderInfoMessage("The target list is empty. Start off by running 'daytona create'.") + // return nil + // } + // target = selection.GetTargetFromPrompt(targetList, "Get Logs For") + // } else { + // target, err = apiclient_util.GetTarget(args[0], false) + // if err != nil { + // return err + // } + // } - if target == nil { - return errors.New("target not found") - } else if len(target.Workspaces) == 0 { - return errors.New("no workspaces found in target") - } + // if target == nil { + // return errors.New("target not found") + // } else if len(target.Workspaces) == 0 { + // return errors.New("no workspaces found in target") + // } - if len(args) == 2 { - workspaces := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - return w.Name - }) - var found bool - for _, workspace := range workspaces { - if workspace == args[1] { - found = true - break - } - } - if !found { - return errors.New("workspace not found in target") - } - workspaceNames = append(workspaceNames, args[1]) - if targetFlag { - showTargetLogs = true - } else { - showTargetLogs = false - } - } else if !targetFlag { - workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - return w.Name - }) - } + // if len(args) == 2 { + // workspaces := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + // return w.Name + // }) + // var found bool + // for _, workspace := range workspaces { + // if workspace == args[1] { + // found = true + // break + // } + // } + // if !found { + // return errors.New("workspace not found in target") + // } + // workspaceNames = append(workspaceNames, args[1]) + // if targetFlag { + // showTargetLogs = true + // } else { + // showTargetLogs = false + // } + // } else if !targetFlag { + // workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { + // return w.Name + // }) + // } - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, followFlag, showTargetLogs, nil) + // apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, followFlag, showTargetLogs, nil) - return nil - }, + // return nil + // }, } func init() { diff --git a/pkg/cmd/ports/forward.go b/pkg/cmd/ports/forward.go index 53f54de39b..272ea9e883 100644 --- a/pkg/cmd/ports/forward.go +++ b/pkg/cmd/ports/forward.go @@ -9,15 +9,18 @@ import ( "errors" "fmt" "hash/fnv" + "net/http" "strconv" "time" "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/cmd/tailscale" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/frpc" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" qrcode "github.com/skip2/go-qrcode" "github.com/spf13/cobra" @@ -25,13 +28,13 @@ import ( var publicPreview bool var targetId string -var workspaceName string +var workspaceId string var PortForwardCmd = &cobra.Command{ - Use: "forward [PORT] [TARGET] [WORKSPACE]", + Use: "forward [PORT] [WORKSPACE]", Short: "Forward a port from a workspace to your local machine", GroupID: util.TARGET_GROUP, - Args: cobra.RangeArgs(2, 3), + Args: cobra.RangeArgs(1, 2), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { @@ -46,22 +49,34 @@ var PortForwardCmd = &cobra.Command{ if err != nil { return err } - target, err := apiclient.GetTarget(args[1], true) + + apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } - targetId = target.Id + ctx := context.Background() + + var workspace *apiclient.WorkspaceDTO + var resp *http.Response - if len(args) == 3 { - workspaceName = args[2] + if len(args) == 2 { + workspace, resp, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, args[1]).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(resp, err) + } } else { - workspaceName, err = apiclient.GetFirstWorkspaceName(targetId, workspaceName, nil) + workspaceList, resp, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { - return err + return apiclient_util.HandleErrorResponse(resp, err) + } + + workspace = selection.GetWorkspaceFromPrompt(workspaceList, "Forward") + if workspace == nil { + return nil } } - hostPort, errChan := tailscale.ForwardPort(targetId, workspaceName, uint16(port), activeProfile) + hostPort, errChan := tailscale.ForwardPort(workspace.Id, uint16(port), activeProfile) if hostPort == nil { if err = <-errChan; err != nil { @@ -76,7 +91,7 @@ var PortForwardCmd = &cobra.Command{ if publicPreview { go func() { - errChan <- ForwardPublicPort(targetId, workspaceName, *hostPort, uint16(port)) + errChan <- ForwardPublicPort(targetId, workspaceId, *hostPort, uint16(port)) }() } @@ -93,21 +108,21 @@ func init() { PortForwardCmd.Flags().BoolVar(&publicPreview, "public", false, "Should be port be available publicly via an URL") } -func ForwardPublicPort(targetId, workspaceName string, hostPort, targetPort uint16) error { +func ForwardPublicPort(targetId, workspaceId string, hostPort, targetPort uint16) error { views.RenderInfoMessage("Forwarding port to a public URL...") - apiClient, err := apiclient.GetApiClient(nil) + apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } serverConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() if err != nil { - return apiclient.HandleErrorResponse(res, err) + return apiclient_util.HandleErrorResponse(res, err) } h := fnv.New64() - h.Write([]byte(fmt.Sprintf("%s-%s-%s", targetId, workspaceName, serverConfig.Id))) + h.Write([]byte(fmt.Sprintf("%s-%s-%s", targetId, workspaceId, serverConfig.Id))) subDomain := fmt.Sprintf("%d-%s", targetPort, base64.RawURLEncoding.EncodeToString([]byte(fmt.Sprint(h.Sum64())))) diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/add.go index 496bbd16e0..eaea7c283f 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/add.go @@ -13,11 +13,11 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" + workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" - "github.com/daytonaio/daytona/pkg/views/target/selection" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) @@ -75,7 +75,7 @@ var prebuildAddCmd = &cobra.Command{ return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := target_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := workspace_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index c120da37ee..f27f82e2ae 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -10,8 +10,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index 283e43f55b..7633802ca5 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/prebuild/info" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index df09be4587..061db9238e 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/build" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 706cd9c499..afb8731ad3 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -37,6 +37,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/workspaceconfig" + "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -241,6 +242,10 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } + workspaceStore, err := db.NewWorkspaceStore(dbConnection) + if err != nil { + return nil, err + } headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ ServerId: c.Id, @@ -343,6 +348,19 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }) targetService := targets.NewTargetService(targets.TargetServiceConfig{ + TargetStore: targetStore, + TargetConfigStore: targetConfigStore, + ApiKeyService: apiKeyService, + ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + ServerVersion: version, + ServerUrl: headscaleUrl, + Provisioner: provisioner, + LoggerFactory: loggerFactory, + TelemetryService: telemetryService, + }) + + workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ + WorkspaceStore: workspaceStore, TargetStore: targetStore, TargetConfigStore: targetConfigStore, ApiKeyService: apiKeyService, @@ -373,6 +391,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ContainerRegistryService: containerRegistryService, BuildService: buildService, WorkspaceConfigService: workspaceConfigService, + WorkspaceService: workspaceService, LocalContainerRegistry: localContainerRegistry, ApiKeyService: apiKeyService, TargetService: targetService, diff --git a/pkg/cmd/target/code.go b/pkg/cmd/target/code.go deleted file mode 100644 index aacd7269bf..0000000000 --- a/pkg/cmd/target/code.go +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "context" - "errors" - "fmt" - "net/url" - "strings" - - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/jetbrains" - "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" - "github.com/daytonaio/daytona/pkg/ide" - "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/telemetry" - ide_views "github.com/daytonaio/daytona/pkg/views/ide" - "github.com/daytonaio/daytona/pkg/views/target/selection" - views_util "github.com/daytonaio/daytona/pkg/views/util" - - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var CodeCmd = &cobra.Command{ - Use: "code [TARGET] [WORKSPACE]", - Short: "Open a target in your preferred IDE", - Args: cobra.RangeArgs(0, 2), - Aliases: []string{"open"}, - GroupID: util.TARGET_GROUP, - RunE: func(cmd *cobra.Command, args []string) error { - c, err := config.GetConfig() - if err != nil { - return err - } - - ctx := context.Background() - var targetId string - var workspaceName string - var providerConfigId *string - var ideId string - var target *apiclient.TargetDTO - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - ideId = c.DefaultIdeId - - apiClient, err := apiclient_util.GetApiClient(&activeProfile) - if err != nil { - return err - } - - if len(args) == 0 { - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Verbose(true).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(targetList) == 0 { - views_util.NotifyEmptyTargetList(true) - return nil - } - - target = selection.GetTargetFromPrompt(targetList, "Open") - if target == nil { - return nil - } - targetId = target.Id - } else { - target, err = apiclient_util.GetTarget(url.PathEscape(args[0]), true) - if err != nil { - if strings.Contains(err.Error(), targets.ErrTargetNotFound.Error()) { - log.Debug(err) - return errors.New("target not found. You can see all target names by running the command `daytona list`") - } - return err - } - targetId = target.Id - } - - if len(args) == 0 || len(args) == 1 { - selectedWorkspace, err := selectTargetWorkspace(targetId, &activeProfile) - if err != nil { - return err - } - if selectedWorkspace == nil { - return nil - } - - workspaceName = selectedWorkspace.Name - providerConfigId = selectedWorkspace.GitProviderConfigId - } - - if len(args) == 2 { - workspaceName = args[1] - for _, workspace := range target.Workspaces { - if workspace.Name == workspaceName { - providerConfigId = workspace.GitProviderConfigId - break - } - } - } - - if ideFlag != "" { - ideId = ideFlag - } - - if !target_util.IsWorkspaceRunning(target, workspaceName) { - wsRunningStatus, err := AutoStartTarget(target.Name, workspaceName) - if err != nil { - return err - } - if !wsRunningStatus { - return nil - } - } - - providerMetadata := "" - if ideId != "ssh" { - providerMetadata, err = target_util.GetWorkspaceProviderMetadata(target, workspaceName) - if err != nil { - return err - } - } - - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) - if err != nil { - log.Warn(err) - } - - yesFlag, _ := cmd.Flags().GetBool("yes") - ideList := config.GetIdeList() - ide_views.RenderIdeOpeningMessage(target.Name, workspaceName, ideId, ideList) - return openIDE(ideId, activeProfile, targetId, workspaceName, providerMetadata, yesFlag, gpgKey) - }, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) == 1 { - return getWorkspaceNameCompletions(cmd, args, toComplete) - } - - return getTargetNameCompletions() - }, -} - -func selectTargetWorkspace(targetId string, profile *config.Profile) (*apiclient.Workspace, error) { - ctx := context.Background() - - apiClient, err := apiclient_util.GetApiClient(profile) - if err != nil { - return nil, err - } - - targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - if len(targetInfo.Workspaces) > 1 { - selectedWorkspace := selection.GetWorkspaceFromPrompt(targetInfo.Workspaces, "Open") - if selectedWorkspace == nil { - return nil, nil - } - return selectedWorkspace, nil - } else if len(targetInfo.Workspaces) == 1 { - return &targetInfo.Workspaces[0], nil - } - - return nil, errors.New("no workspaces found in target") -} - -func openIDE(ideId string, activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { - telemetry.AdditionalData["ide"] = ideId - - switch ideId { - case "vscode": - return ide.OpenVSCode(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "code-insiders": - return ide.OpenVSCodeInsiders(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "ssh": - return ide.OpenTerminalSsh(activeProfile, targetId, workspaceName, gpgKey, nil) - case "browser": - return ide.OpenBrowserIDE(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "codium": - return ide.OpenVScodium(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "codium-insiders": - return ide.OpenVScodiumInsiders(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "cursor": - return ide.OpenCursor(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "jupyter": - return ide.OpenJupyterIDE(activeProfile, targetId, workspaceName, workspaceProviderMetadata, yesFlag, gpgKey) - case "fleet": - return ide.OpenFleet(activeProfile, targetId, workspaceName, gpgKey) - case "positron": - return ide.OpenPositron(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - case "zed": - return ide.OpenZed(activeProfile, targetId, workspaceName, gpgKey) - case "windsurf": - return ide.OpenWindsurf(activeProfile, targetId, workspaceName, workspaceProviderMetadata, gpgKey) - default: - _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] - if ok { - return ide.OpenJetbrainsIDE(activeProfile, ideId, targetId, workspaceName, gpgKey) - } - } - - return errors.New("invalid IDE. Please choose one by running `daytona ide`") -} - -var ideFlag string - -func init() { - ideList := config.GetIdeList() - ids := make([]string, len(ideList)) - for i, ide := range ideList { - ids[i] = ide.Id - } - ideListStr := strings.Join(ids, ", ") - CodeCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) - - CodeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") - -} - -func AutoStartTarget(targetId string, workspaceName string) (bool, error) { - if !yesFlag { - if !ide_views.RunStartTargetForm(targetId) { - return false, nil - } - } - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return false, err - } - - err = StartTarget(apiClient, targetId, workspaceName) - if err != nil { - return false, err - } - - return true, nil -} diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index 553535482b..31912bfc8e 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -9,8 +9,6 @@ import ( "strings" "github.com/charmbracelet/huh" - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" @@ -23,10 +21,9 @@ import ( var yesFlag bool var forceFlag bool -var DeleteCmd = &cobra.Command{ +var deleteCmd = &cobra.Command{ Use: "delete [TARGET]", Short: "Delete a target", - GroupID: util.TARGET_GROUP, Aliases: []string{"remove", "rm"}, RunE: func(cmd *cobra.Command, args []string) error { if allFlag { @@ -138,9 +135,9 @@ var DeleteCmd = &cobra.Command{ } func init() { - DeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all targets") - DeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") - DeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a target by force") + deleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all targets") + deleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a target by force") } func DeleteAllTargets(force bool) error { @@ -173,20 +170,7 @@ func RemoveTarget(ctx context.Context, apiClient *apiclient.APIClient, target *a if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - err = config.RemoveTargetSshEntries(activeProfile.Id, target.Id) - if err != nil { - return err - } return nil }) diff --git a/pkg/cmd/target/info.go b/pkg/cmd/target/info.go index da68e06ce8..42b6385be1 100644 --- a/pkg/cmd/target/info.go +++ b/pkg/cmd/target/info.go @@ -6,7 +6,6 @@ package target import ( "context" - "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" @@ -16,12 +15,11 @@ import ( "github.com/spf13/cobra" ) -var InfoCmd = &cobra.Command{ +var infoCmd = &cobra.Command{ Use: "info [TARGET]", Short: "Show target info", Aliases: []string{"view", "inspect"}, Args: cobra.RangeArgs(0, 1), - GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -69,7 +67,7 @@ var InfoCmd = &cobra.Command{ return nil } - info.Render(target, "", false) + info.Render(target, false) return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ -78,5 +76,5 @@ var InfoCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(InfoCmd) + format.RegisterFormatFlag(infoCmd) } diff --git a/pkg/cmd/target/list.go b/pkg/cmd/target/list.go index 1abf11ccf8..ddc23ef838 100644 --- a/pkg/cmd/target/list.go +++ b/pkg/cmd/target/list.go @@ -7,7 +7,6 @@ import ( "context" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" @@ -17,15 +16,13 @@ import ( var verbose bool -var ListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "List targets", Args: cobra.ExactArgs(0), Aliases: []string{"ls"}, - GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - var specifyGitProviders bool apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -38,15 +35,6 @@ var ListCmd = &cobra.Command{ return apiclient.HandleErrorResponse(res, err) } - gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute() - if err != nil { - return apiclient.HandleErrorResponse(res, err) - } - - if len(gitProviders) > 1 { - specifyGitProviders = true - } - if format.FormatFlag != "" { formattedData := format.NewFormatter(targetList) formattedData.Print() @@ -63,13 +51,13 @@ var ListCmd = &cobra.Command{ return err } - list_view.ListTargets(targetList, specifyGitProviders, verbose, activeProfile.Name) + list_view.ListTargets(targetList, verbose, activeProfile.Name) return nil }, } func init() { - ListCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show verbose output") - format.RegisterFormatFlag(ListCmd) + listCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show verbose output") + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index 31b479947c..313d09a2b8 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -7,7 +7,6 @@ import ( "context" "fmt" - "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" @@ -16,13 +15,10 @@ import ( "github.com/spf13/cobra" ) -var restartWorkspaceFlag string - -var RestartCmd = &cobra.Command{ - Use: "restart [TARGET]", - Short: "Restart a target", - Args: cobra.RangeArgs(0, 1), - GroupID: util.TARGET_GROUP, +var restartCmd = &cobra.Command{ + Use: "restart [TARGET]", + Short: "Restart a target", + Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { var targetId string @@ -34,14 +30,6 @@ var RestartCmd = &cobra.Command{ } if len(args) == 0 { - if restartWorkspaceFlag != "" { - err := cmd.Help() - if err != nil { - return err - } - return nil - } - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) @@ -61,30 +49,23 @@ var RestartCmd = &cobra.Command{ targetId = args[0] } - err = RestartTarget(apiClient, targetId, restartWorkspaceFlag) + err = RestartTarget(apiClient, targetId) if err != nil { return err } - if restartWorkspaceFlag != "" { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully restarted", restartWorkspaceFlag, targetId)) - } else { - views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) - } + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) return nil }, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllTargetsByState(TARGET_STATE_RUNNING) - }, -} - -func init() { - RestartCmd.Flags().StringVarP(&restartWorkspaceFlag, "workspace", "w", "", "Restart a single workspace in the target (workspace name)") + // FIXME: add after adding state to targets + // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + // return getAllTargetsByState(TARGET_STATE_RUNNING) + // }, } -func RestartTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) error { - err := StopTarget(apiClient, targetId, workspaceName) +func RestartTarget(apiClient *apiclient.APIClient, targetId string) error { + err := StopTarget(apiClient, targetId) if err != nil { return err } - return StartTarget(apiClient, targetId, workspaceName) + return StartTarget(apiClient, targetId) } diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 7553522f84..01a1356fc0 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -9,12 +9,9 @@ import ( "time" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/views" - ide_views "github.com/daytonaio/daytona/pkg/views/ide" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -29,22 +26,14 @@ const ( TARGET_STATE_STOPPED TargetState = "Unavailable" ) -var startWorkspaceFlag string var allFlag bool -var codeFlag bool -var StartCmd = &cobra.Command{ - Use: "start [TARGET]", - Short: "Start a target", - Args: cobra.RangeArgs(0, 1), - GroupID: util.TARGET_GROUP, +var startCmd = &cobra.Command{ + Use: "start [TARGET]", + Short: "Start a target", + Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { var selectedTargetsNames []string - var activeProfile config.Profile - var ideId string - var ideList []config.Ide - var providerConfigId *string - workspaceProviderMetadata := "" ctx := context.Background() @@ -58,9 +47,6 @@ var StartCmd = &cobra.Command{ } if len(args) == 0 { - if startWorkspaceFlag != "" { - return cmd.Help() - } targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) @@ -80,71 +66,16 @@ var StartCmd = &cobra.Command{ if len(selectedTargetsNames) == 1 { targetName := selectedTargetsNames[0] - var targetId string - if codeFlag { - c, err := config.GetConfig() - if err != nil { - return err - } - activeProfile, err = c.GetActiveProfile() - if err != nil { - return err - } - - ideList = config.GetIdeList() - ideId = c.DefaultIdeId - - targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetName).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - targetId = targetInfo.Id - if startWorkspaceFlag == "" { - startWorkspaceFlag = targetInfo.Workspaces[0].Name - providerConfigId = targetInfo.Workspaces[0].GitProviderConfigId - } else { - for _, workspace := range targetInfo.Workspaces { - if workspace.Name == startWorkspaceFlag { - providerConfigId = workspace.GitProviderConfigId - break - } - } - } - - if ideId != "ssh" { - workspaceProviderMetadata, err = target_util.GetWorkspaceProviderMetadata(targetInfo, targetInfo.Workspaces[0].Name) - if err != nil { - return err - } - } - } - - err = StartTarget(apiClient, targetName, startWorkspaceFlag) + err = StartTarget(apiClient, targetName) if err != nil { return err } - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) - if err != nil { - log.Warn(err) - } - if startWorkspaceFlag == "" { - views.RenderInfoMessage(fmt.Sprintf("Target '%s' started successfully", targetName)) - } else { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' started successfully", startWorkspaceFlag, targetName)) - - if codeFlag { - ide_views.RenderIdeOpeningMessage(targetName, startWorkspaceFlag, ideId, ideList) - err = openIDE(ideId, activeProfile, targetId, startWorkspaceFlag, workspaceProviderMetadata, yesFlag, gpgKey) - if err != nil { - return err - } - } - } + views.RenderInfoMessage(fmt.Sprintf("Target '%s' started successfully", targetName)) } else { for _, target := range selectedTargetsNames { - err := StartTarget(apiClient, target, "") + err := StartTarget(apiClient, target) if err != nil { log.Errorf("Failed to start target %s: %v\n\n", target, err) continue @@ -154,21 +85,15 @@ var StartCmd = &cobra.Command{ } return nil }, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllTargetsByState(TARGET_STATE_STOPPED) - }, + // FIXME: add after adding state to targets + // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + // return getAllTargetsByState(TARGET_STATE_STOPPED) + // }, } func init() { - StartCmd.PersistentFlags().StringVarP(&startWorkspaceFlag, "workspace", "w", "", "Start a single workspace in the target (workspace name)") - StartCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Start all targets") - StartCmd.PersistentFlags().BoolVarP(&codeFlag, "code", "c", false, "Open the target in the IDE after target start") - StartCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") - - err := StartCmd.RegisterFlagCompletionFunc("workspace", getWorkspaceNameCompletions) - if err != nil { - log.Error("failed to register completion function: ", err) - } + startCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Start all targets") + startCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") } func startAllTargets() error { @@ -184,7 +109,7 @@ func startAllTargets() error { } for _, target := range targetList { - err := StartTarget(apiClient, target.Name, "") + err := StartTarget(apiClient, target.Name) if err != nil { log.Errorf("Failed to start target %s: %v\n\n", target.Name, err) continue @@ -195,25 +120,26 @@ func startAllTargets() error { return nil } -func getWorkspaceNameCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return nil, cobra.ShellCompDirectiveDefault - } - - targetId := args[0] - target, _, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() - if err != nil { - return nil, cobra.ShellCompDirectiveDefault - } - - var choices []string - for _, workspace := range target.Workspaces { - choices = append(choices, workspace.Name) - } - return choices, cobra.ShellCompDirectiveDefault -} +// FIXME: add target completions +// func getWorkspaceNameCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { +// ctx := context.Background() +// apiClient, err := apiclient_util.GetApiClient(nil) +// if err != nil { +// return nil, cobra.ShellCompDirectiveDefault +// } + +// targetId := args[0] +// target, _, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() +// if err != nil { +// return nil, cobra.ShellCompDirectiveDefault +// } + +// var choices []string +// for _, workspace := range target.Workspaces { +// choices = append(choices, workspace.Name) +// } +// return choices, cobra.ShellCompDirectiveDefault +// } func getTargetNameCompletions() ([]string, cobra.ShellCompDirective) { ctx := context.Background() @@ -235,41 +161,41 @@ func getTargetNameCompletions() ([]string, cobra.ShellCompDirective) { return choices, cobra.ShellCompDirectiveNoFileComp } -func getAllTargetsByState(state TargetState) ([]string, cobra.ShellCompDirective) { +// FIXME: fix this after adding state to targets +// func getAllTargetsByState(state TargetState) ([]string, cobra.ShellCompDirective) { +// ctx := context.Background() +// apiClient, err := apiclient_util.GetApiClient(nil) +// if err != nil { +// return nil, cobra.ShellCompDirectiveNoFileComp +// } + +// targetList, _, err := apiClient.TargetAPI.ListTargets(ctx).Execute() +// if err != nil { +// return nil, cobra.ShellCompDirectiveNoFileComp +// } + +// var choices []string +// for _, target := range targetList { +// for _, workspace := range target.Workspaces { +// if workspace.State == nil { +// continue +// } +// if state == TARGET_STATE_RUNNING && workspace.State.Uptime != 0 { +// choices = append(choices, target.Name) +// break +// } +// if state == TARGET_STATE_STOPPED && workspace.State.Uptime == 0 { +// choices = append(choices, target.Name) +// break +// } +// } +// } + +// return choices, cobra.ShellCompDirectiveNoFileComp +// } + +func StartTarget(apiClient *apiclient.APIClient, targetId string) error { ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - targetList, _, err := apiClient.TargetAPI.ListTargets(ctx).Execute() - if err != nil { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - var choices []string - for _, target := range targetList { - for _, workspace := range target.Workspaces { - if workspace.State == nil { - continue - } - if state == TARGET_STATE_RUNNING && workspace.State.Uptime != 0 { - choices = append(choices, target.Name) - break - } - if state == TARGET_STATE_STOPPED && workspace.State.Uptime == 0 { - choices = append(choices, target.Name) - break - } - } - } - - return choices, cobra.ShellCompDirectiveNoFileComp -} - -func StartTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) error { - ctx := context.Background() - var workspaceNames []string timeFormat := time.Now().Format("2006-01-02 15:04:05") from, err := time.Parse("2006-01-02 15:04:05", timeFormat) if err != nil { @@ -290,34 +216,15 @@ func StartTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) if err != nil { return err } - if workspaceName != "" { - workspaceNames = append(workspaceNames, workspaceName) - } else { - workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - return w.Name - }) - } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadTargetLogs(logsContext, activeProfile, target.Id, workspaceNames, true, true, &from) - - if workspaceName == "" { - res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() - if err != nil { - stopLogs() - return apiclient_util.HandleErrorResponse(res, err) - } - time.Sleep(100 * time.Millisecond) - stopLogs() - return nil - } else { - res, err := apiClient.TargetAPI.StartWorkspace(ctx, targetId, workspaceName).Execute() - if err != nil { - stopLogs() - return apiclient_util.HandleErrorResponse(res, err) - } - time.Sleep(100 * time.Millisecond) + go apiclient_util.ReadTargetLogs(logsContext, activeProfile, target.Id, true, &from) + res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() + if err != nil { stopLogs() - return nil + return apiclient_util.HandleErrorResponse(res, err) } + time.Sleep(100 * time.Millisecond) + stopLogs() + return nil } diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go index 21cca0a25b..0ecade70df 100644 --- a/pkg/cmd/target/stop.go +++ b/pkg/cmd/target/stop.go @@ -9,7 +9,6 @@ import ( "time" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" @@ -19,13 +18,10 @@ import ( "github.com/spf13/cobra" ) -var stopWorkspaceFlag string - -var StopCmd = &cobra.Command{ - Use: "stop [TARGET]", - Short: "Stop a target", - GroupID: util.TARGET_GROUP, - Args: cobra.RangeArgs(0, 1), +var stopCmd = &cobra.Command{ + Use: "stop [TARGET]", + Short: "Stop a target", + Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { timeFormat := time.Now().Format("2006-01-02 15:04:05") from, err := time.Parse("2006-01-02 15:04:05", timeFormat) @@ -55,9 +51,6 @@ var StopCmd = &cobra.Command{ } if len(args) == 0 { - if stopWorkspaceFlag != "" { - return cmd.Help() - } targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) @@ -71,23 +64,19 @@ var StopCmd = &cobra.Command{ selectedTargets := selection.GetTargetsFromPrompt(targetList, "Stop") for _, target := range selectedTargets { - err := StopTarget(apiClient, target.Name, "") + err := StopTarget(apiClient, target.Name) if err != nil { log.Errorf("Failed to stop target %s: %v\n\n", target.Name, err) continue } - workspaceNames := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - return w.Name - }) - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, false, true, &from) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, false, &from) views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) } } else { targetId := args[0] - var workspaceNames []string - err = StopTarget(apiClient, targetId, stopWorkspaceFlag) + err = StopTarget(apiClient, targetId) if err != nil { return err } @@ -97,32 +86,20 @@ var StopCmd = &cobra.Command{ return err } - if startWorkspaceFlag != "" { - workspaceNames = append(workspaceNames, stopWorkspaceFlag) - } else { - workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - return w.Name - }) - } + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, false, &from) - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, false, true, &from) - - if stopWorkspaceFlag != "" { - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully stopped", stopWorkspaceFlag, targetId)) - } else { - views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) - } + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) } return nil }, - ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllTargetsByState(TARGET_STATE_RUNNING) - }, + // FIXME: add after adding state to targets + // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + // return getAllTargetsByState(TARGET_STATE_RUNNING) + // }, } func init() { - StopCmd.Flags().StringVarP(&stopWorkspaceFlag, "workspace", "w", "", "Stop a single workspace in the target (workspace name)") - StopCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Stop all targets") + stopCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Stop all targets") } func stopAllTargets(activeProfile config.Profile, from time.Time) error { @@ -138,48 +115,28 @@ func stopAllTargets(activeProfile config.Profile, from time.Time) error { } for _, target := range targetList { - err := StopTarget(apiClient, target.Name, "") + err := StopTarget(apiClient, target.Name) if err != nil { log.Errorf("Failed to stop target %s: %v\n\n", target.Name, err) continue } - workspaceNames := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - return w.Name - }) - - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, false, true, &from) + apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, false, &from) views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) } return nil } -func StopTarget(apiClient *apiclient.APIClient, targetId, workspaceName string) error { +func StopTarget(apiClient *apiclient.APIClient, targetId string) error { ctx := context.Background() - var message string - var stopFunc func() error - if workspaceName == "" { - message = fmt.Sprintf("Target '%s' is stopping", targetId) - stopFunc = func() error { - res, err := apiClient.TargetAPI.StopTarget(ctx, targetId).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - return nil - } - } else { - message = fmt.Sprintf("Workspace '%s' from target '%s' is stopping", workspaceName, targetId) - stopFunc = func() error { - res, err := apiClient.TargetAPI.StopWorkspace(ctx, targetId, workspaceName).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - return nil + err := views_util.WithInlineSpinner(fmt.Sprintf("Target '%s' is stopping", targetId), func() error { + res, err := apiClient.TargetAPI.StopTarget(ctx, targetId).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) } - } - - err := views_util.WithInlineSpinner(message, stopFunc) + return nil + }) if err != nil { return err } diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go new file mode 100644 index 0000000000..baec127f32 --- /dev/null +++ b/pkg/cmd/target/target.go @@ -0,0 +1,25 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "github.com/daytonaio/daytona/internal/util" + "github.com/spf13/cobra" +) + +var TargetCmd = &cobra.Command{ + Use: "target", + Aliases: []string{"targets"}, + Short: "Manage targets", + GroupID: util.TARGET_GROUP, +} + +func init() { + TargetCmd.AddCommand(deleteCmd) + TargetCmd.AddCommand(infoCmd) + TargetCmd.AddCommand(restartCmd) + TargetCmd.AddCommand(startCmd) + TargetCmd.AddCommand(stopCmd) + TargetCmd.AddCommand(listCmd) +} diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go new file mode 100644 index 0000000000..95530fd68b --- /dev/null +++ b/pkg/cmd/workspace/code.go @@ -0,0 +1,183 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "errors" + "fmt" + "net/url" + "strings" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/jetbrains" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/ide" + "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/telemetry" + ide_views "github.com/daytonaio/daytona/pkg/views/ide" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var CodeCmd = &cobra.Command{ + Use: "code [WORKSPACE]", + Short: "Open a workspace in your preferred IDE", + Args: cobra.RangeArgs(0, 2), + Aliases: []string{"open"}, + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := config.GetConfig() + if err != nil { + return err + } + + ctx := context.Background() + var providerConfigId *string + var ideId string + var ws *apiclient.WorkspaceDTO + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + ideId = c.DefaultIdeId + + apiClient, err := apiclient_util.GetApiClient(&activeProfile) + if err != nil { + return err + } + + if len(args) == 0 { + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + return errors.New("no workspaces found") + } + + ws = selection.GetWorkspaceFromPrompt(workspaceList, "Open") + if ws == nil { + return nil + } + } else { + ws, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]), true) + if err != nil { + if strings.Contains(err.Error(), workspaces.ErrWorkspaceNotFound.Error()) { + log.Debug(err) + return errors.New("workspace not found. You can see all workspace names by running the command `daytona list`") + } + return err + } + } + if ideFlag != "" { + ideId = ideFlag + } + + if ws.State != nil || ws.State.Uptime < 1 { + wsRunningStatus, err := AutoStartWorkspace(ws.Id) + if err != nil { + return err + } + if !wsRunningStatus { + return nil + } + } + + providerMetadata := *ws.Info.ProviderMetadata + + gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + if err != nil { + log.Warn(err) + } + + yesFlag, _ := cmd.Flags().GetBool("yes") + ideList := config.GetIdeList() + ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList) + return openIDE(ideId, activeProfile, ws.Id, providerMetadata, yesFlag, gpgKey) + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getWorkspaceNameCompletions() + }, +} + +func openIDE(ideId string, activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { + telemetry.AdditionalData["ide"] = ideId + + switch ideId { + case "vscode": + return ide.OpenVSCode(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "code-insiders": + return ide.OpenVSCodeInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "ssh": + return ide.OpenTerminalSsh(activeProfile, workspaceId, gpgKey, nil) + case "browser": + return ide.OpenBrowserIDE(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "codium": + return ide.OpenVScodium(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "codium-insiders": + return ide.OpenVScodiumInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "cursor": + return ide.OpenCursor(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "jupyter": + return ide.OpenJupyterIDE(activeProfile, workspaceId, workspaceProviderMetadata, yesFlag, gpgKey) + case "fleet": + return ide.OpenFleet(activeProfile, workspaceId, gpgKey) + case "positron": + return ide.OpenPositron(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "zed": + return ide.OpenZed(activeProfile, workspaceId, gpgKey) + case "windsurf": + return ide.OpenWindsurf(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + default: + _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] + if ok { + return ide.OpenJetbrainsIDE(activeProfile, ideId, workspaceId, gpgKey) + } + } + + return errors.New("invalid IDE. Please choose one by running `daytona ide`") +} + +var ideFlag string + +func init() { + ideList := config.GetIdeList() + ids := make([]string, len(ideList)) + for i, ide := range ideList { + ids[i] = ide.Id + } + ideListStr := strings.Join(ids, ", ") + CodeCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) + + CodeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") + +} + +func AutoStartWorkspace(workspaceId string) (bool, error) { + if !yesFlag { + if !ide_views.RunStartWorkspaceForm(workspaceId) { + return false, nil + } + } + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return false, err + } + + err = StartWorkspace(apiClient, workspaceId) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/pkg/cmd/target/create.go b/pkg/cmd/workspace/create.go similarity index 83% rename from pkg/cmd/target/create.go rename to pkg/cmd/workspace/create.go index 93086abe8a..92e82bd4f4 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/workspace/create.go @@ -18,17 +18,17 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" + workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/views" logs_view "github.com/daytonaio/daytona/pkg/views/logs" - "github.com/daytonaio/daytona/pkg/views/target/create" - "github.com/daytonaio/daytona/pkg/views/target/info" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" + "github.com/daytonaio/daytona/pkg/views/workspace/info" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/pkg/stringid" log "github.com/sirupsen/logrus" "tailscale.com/tsnet" @@ -100,7 +100,7 @@ var CreateCmd = &cobra.Command{ initialSuggestion := workspaces[0].Name if targetName == "" { - targetName = target_util.GetSuggestedName(initialSuggestion, existingTargetNames) + targetName = workspace_util.GetSuggestedName(initialSuggestion, existingTargetNames) } } @@ -133,7 +133,7 @@ var CreateCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - targetConfig, err := target_util.GetTargetConfig(target_util.GetTargetConfigParams{ + targetConfig, err := workspace_util.GetTargetConfig(workspace_util.GetTargetConfigParams{ Ctx: ctx, ApiClient: apiClient, TargetConfigs: targetConfigs, @@ -148,7 +148,8 @@ var CreateCmd = &cobra.Command{ return err } - logs_view.CalculateLongestPrefixLength(workspaceNames) + names := append(workspaceNames, targetName) + logs_view.CalculateLongestPrefixLength(names) logs_view.DisplayLogEntry(logs.LogEntry{ Msg: "Request submitted\n", @@ -171,16 +172,36 @@ var CreateCmd = &cobra.Command{ id = stringid.TruncateID(id) logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadTargetLogs(logsContext, activeProfile, id, workspaceNames, true, true, nil) + defer stopLogs() + + logs_view.CalculateLongestPrefixLength(names) + + go apiclient_util.ReadTargetLogs(logsContext, activeProfile, id, true, nil) createdTarget, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(apiclient.CreateTargetDTO{ Id: id, Name: targetName, TargetConfig: targetConfig.Name, - Workspaces: workspaces, }).Execute() + + dedupWorkspaceNames(&workspaces) + + for i := range workspaces { + wsId := stringid.GenerateRandomID() + wsId = stringid.TruncateID(wsId) + workspaces[i].Id = wsId + workspaces[i].TargetId = id + ws := workspaces[i] + + go apiclient_util.ReadWorkspaceLogs(logsContext, i, activeProfile, wsId, true, nil) + + _, res, err = apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(ws).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + } + if err != nil { - stopLogs() return apiclient_util.HandleErrorResponse(res, err) } gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, workspaces[0].GitProviderConfigId) @@ -188,9 +209,8 @@ var CreateCmd = &cobra.Command{ log.Warn(err) } - err = waitForDial(createdTarget, &activeProfile, tsConn, gpgKey) + err = waitForDial(createdTarget, workspaces[0].Id, &activeProfile, tsConn, gpgKey) if err != nil { - stopLogs() return err } @@ -199,11 +219,6 @@ var CreateCmd = &cobra.Command{ // Make sure terminal cursor is reset fmt.Print("\033[?25h") - targetInfo, res, err := apiClient.TargetAPI.GetTarget(ctx, targetName).Verbose(true).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - chosenIdeId := c.DefaultIdeId if ideFlag != "" { chosenIdeId = ideFlag @@ -219,7 +234,13 @@ var CreateCmd = &cobra.Command{ } fmt.Println() - info.Render(targetInfo, chosenIde.Name, false) + + ws, err := apiclient_util.GetWorkspace(workspaces[0].Id, true) + if err != nil { + return err + } + + info.Render(ws, chosenIde.Name, false) if noIdeFlag { views.RenderCreationInfoMessage("Run 'daytona code' when you're ready to start developing") @@ -228,13 +249,7 @@ var CreateCmd = &cobra.Command{ views.RenderCreationInfoMessage(fmt.Sprintf("Opening the target in %s ...", chosenIde.Name)) - workspaceName := targetInfo.Workspaces[0].Name - providerMetadata, err := target_util.GetWorkspaceProviderMetadata(targetInfo, workspaceName) - if err != nil { - return err - } - - return openIDE(chosenIdeId, activeProfile, createdTarget.Id, targetInfo.Workspaces[0].Name, providerMetadata, yesFlag, gpgKey) + return openIDE(chosenIdeId, activeProfile, workspaces[0].Name, *ws.Info.ProviderMetadata, yesFlag, gpgKey) }, } @@ -244,7 +259,7 @@ var noIdeFlag bool var blankFlag bool var multiWorkspaceFlag bool -var workspaceConfigurationFlags = target_util.WorkspaceConfigurationFlags{ +var workspaceConfigurationFlags = workspace_util.WorkspaceConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -272,11 +287,11 @@ func init() { CreateCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") CreateCmd.Flags().StringSliceVar(workspaceConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the workspaces") - target_util.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) + workspace_util.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) } func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targetName *string, workspaces *[]apiclient.CreateWorkspaceDTO, targetNames []string) error { - if target_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) || (workspaceConfigurationFlags.Branches != nil && len(*workspaceConfigurationFlags.Branches) > 0) { + if workspace_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) || (workspaceConfigurationFlags.Branches != nil && len(*workspaceConfigurationFlags.Branches) > 0) { return errors.New("please provide the repository URL in order to set up custom workspace details through the CLI") } @@ -302,7 +317,7 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targe DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - *workspaces, err = target_util.GetWorkspacesCreationDataFromPrompt(target_util.WorkspacesDataPromptConfig{ + *workspaces, err = workspace_util.GetWorkspacesCreationDataFromPrompt(workspace_util.WorkspacesDataPromptConfig{ UserGitProviders: gitProviders, WorkspaceConfigs: workspaceConfigs, Manual: *workspaceConfigurationFlags.Manual, @@ -318,7 +333,7 @@ func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targe initialSuggestion := (*workspaces)[0].Name - suggestedName := target_util.GetSuggestedName(initialSuggestion, targetNames) + suggestedName := workspace_util.GetSuggestedName(initialSuggestion, targetNames) dedupWorkspaceNames(workspaces) @@ -345,7 +360,7 @@ func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apic return nil, fmt.Errorf("no repository URLs provided") } - if len(repoUrls) > 1 && target_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { + if len(repoUrls) > 1 && workspace_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { return nil, fmt.Errorf("can't set custom workspace configuration properties for multiple workspaces") } @@ -385,7 +400,7 @@ func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apic return nil, fmt.Errorf("failed to parse the URL or fetch the workspace config for '%s'", repoUrl) } - existingWorkspaceConfigName, err := target_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) + existingWorkspaceConfigName, err := workspace_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) if err != nil { return nil, err } @@ -408,7 +423,7 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API workspaceConfig, res, err := apiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() if err == nil { workspaceConfig.GitProviderConfigId = workspaceConfigurationFlags.GitProviderConfig - return target_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) + return workspace_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) } if res.StatusCode != http.StatusNotFound { @@ -424,12 +439,12 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API return nil, apiclient_util.HandleErrorResponse(res, err) } - workspaceName, err := target_util.GetSanitizedWorkspaceName(repo.Name) + workspaceName, err := workspace_util.GetSanitizedWorkspaceName(repo.Name) if err != nil { return nil, err } - workspaceConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) + workspaceConfigurationFlags.GitProviderConfig, err = workspace_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } @@ -454,7 +469,7 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API } } - workspace, err := target_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) + workspace, err := workspace_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) if err != nil { return nil, err } @@ -469,14 +484,14 @@ func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.API return nil, nil } -func waitForDial(target *apiclient.Target, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { +func waitForDial(target *apiclient.Target, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { if target.TargetConfig == "local" && (activeProfile != nil && activeProfile.Id == "default") { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, target.Id, target.Workspaces[0].Name, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, target.Id, target.Workspaces[0].Name) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) for { sshCommand := exec.Command("ssh", workspaceHostname, "daytona", "version") @@ -499,7 +514,7 @@ func waitForDial(target *apiclient.Target, activeProfile *config.Profile, tsConn go func() { for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(target.Id, target.Workspaces[0].Name), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(workspaceId), ssh_config.SSH_PORT)) if err == nil { connectChan <- dialConn.Close() return diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go new file mode 100644 index 0000000000..b06c306d71 --- /dev/null +++ b/pkg/cmd/workspace/delete.go @@ -0,0 +1,202 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + "strings" + + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var yesFlag bool +var forceFlag bool + +// FIXME: multi-select delete +var DeleteCmd = &cobra.Command{ + Use: "delete [WORKSPACE]", + Short: "Delete a workspace", + GroupID: util.TARGET_GROUP, + Aliases: []string{"remove", "rm"}, + RunE: func(cmd *cobra.Command, args []string) error { + if allFlag { + if yesFlag { + fmt.Println("Deleting all workspaces.") + err := DeleteAllWorkspaces(forceFlag) + if err != nil { + return err + } + } else { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Delete all workspaces?"). + Description("Are you sure you want to delete all workspaces?"). + Value(&yesFlag), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + + if yesFlag { + err := DeleteAllWorkspaces(forceFlag) + if err != nil { + return err + } + } else { + fmt.Println("Operation canceled.") + } + } + return nil + } + + ctx := context.Background() + + var workspaceDeleteList []*apiclient.WorkspaceDTO + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if len(args) == 0 { + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(false) + return nil + } + + workspaceToDelete := selection.GetWorkspaceFromPrompt(workspaceList, "Delete") + if workspaceToDelete == nil { + return nil + } + workspaceDeleteList = append(workspaceDeleteList, workspaceToDelete) + } else { + for _, arg := range args { + workspace, err := apiclient_util.GetWorkspace(arg, false) + if err != nil { + log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) + continue + } + workspaceDeleteList = append(workspaceDeleteList, workspace) + } + } + + if len(workspaceDeleteList) == 0 { + return nil + } + + wsDeleteListNames := util.ArrayMap(workspaceDeleteList, func(w *apiclient.WorkspaceDTO) string { + return w.Name + }) + + if !yesFlag { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title(fmt.Sprintf("Delete workspace(s): [%s]?", strings.Join(wsDeleteListNames, ", "))). + Description(fmt.Sprintf("Are you sure you want to delete the workspace(s): [%s]?", strings.Join(wsDeleteListNames, ", "))). + Value(&yesFlag), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + } + + if !yesFlag { + fmt.Println("Operation canceled.") + } else { + for _, workspace := range workspaceDeleteList { + err := RemoveWorkspace(ctx, apiClient, workspace, forceFlag) + if err != nil { + log.Error(fmt.Sprintf("[ %s ] : %v", workspace.Name, err)) + } + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully deleted", workspace.Name)) + } + } + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getWorkspaceNameCompletions() + }, +} + +func init() { + DeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspaces") + DeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + DeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a workspace by force") +} + +func DeleteAllWorkspaces(force bool) error { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + for _, workspace := range workspaceList { + err := RemoveWorkspace(ctx, apiClient, &workspace, force) + if err != nil { + log.Errorf("Failed to delete workspace %s: %v", workspace.Name, err) + continue + } + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' successfully deleted", workspace.Name)) + } + return nil +} + +func RemoveWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspace *apiclient.WorkspaceDTO, force bool) error { + message := fmt.Sprintf("Deleting workspace %s", workspace.Name) + err := views_util.WithInlineSpinner(message, func() error { + res, err := apiClient.WorkspaceAPI.RemoveWorkspace(ctx, workspace.Id).Force(force).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspace.Id) + if err != nil { + return err + } + return nil + }) + + if err != nil { + return err + } + + return nil +} diff --git a/pkg/cmd/workspace/info.go b/pkg/cmd/workspace/info.go new file mode 100644 index 0000000000..cf183dad6a --- /dev/null +++ b/pkg/cmd/workspace/info.go @@ -0,0 +1,82 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/format" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/info" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/spf13/cobra" +) + +var InfoCmd = &cobra.Command{ + Use: "info [TARGET]", + Short: "Show target info", + Aliases: []string{"view", "inspect"}, + Args: cobra.RangeArgs(0, 1), + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + var ws *apiclient.WorkspaceDTO + + if len(args) == 0 { + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) + return nil + } + + if format.FormatFlag != "" { + format.UnblockStdOut() + } + + ws = selection.GetWorkspaceFromPrompt(workspaceList, "View") + if format.FormatFlag != "" { + format.BlockStdOut() + } + + } else { + ws, err = apiclient_util.GetWorkspace(args[0], true) + if err != nil { + return err + } + } + + if ws == nil { + return nil + } + + if format.FormatFlag != "" { + formattedData := format.NewFormatter(ws) + formattedData.Print() + return nil + } + + info.Render(ws, "", false) + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getWorkspaceNameCompletions() + }, +} + +func init() { + format.RegisterFormatFlag(InfoCmd) +} diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go new file mode 100644 index 0000000000..7839ac82bc --- /dev/null +++ b/pkg/cmd/workspace/list.go @@ -0,0 +1,74 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util/apiclient" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/views/workspace/list" + "github.com/spf13/cobra" +) + +var verbose bool + +var ListCmd = &cobra.Command{ + Use: "list", + Short: "List targets", + Args: cobra.ExactArgs(0), + Aliases: []string{"ls"}, + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + var specifyGitProviders bool + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(verbose).Execute() + + if err != nil { + return apiclient.HandleErrorResponse(res, err) + } + + gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute() + if err != nil { + return apiclient.HandleErrorResponse(res, err) + } + + if len(gitProviders) > 1 { + specifyGitProviders = true + } + + if format.FormatFlag != "" { + formattedData := format.NewFormatter(workspaceList) + formattedData.Print() + return nil + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + list.ListWorkspaces(workspaceList, specifyGitProviders, verbose, activeProfile.Name) + return nil + }, +} + +func init() { + ListCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show verbose output") + format.RegisterFormatFlag(ListCmd) +} diff --git a/pkg/cmd/target/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go similarity index 77% rename from pkg/cmd/target/ssh-proxy.go rename to pkg/cmd/workspace/ssh-proxy.go index c63ff4ee4c..c6bd462c02 100644 --- a/pkg/cmd/target/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -12,11 +12,11 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/cmd/tailscale" - "github.com/daytonaio/daytona/internal/util/apiclient" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" @@ -26,8 +26,8 @@ import ( ) var SshProxyCmd = &cobra.Command{ - Use: "ssh-proxy [PROFILE_ID] [TARGET_ID] [WORKSPACE]", - Args: cobra.RangeArgs(2, 3), + Use: "ssh-proxy [PROFILE_ID] [WORKSPACE]", + Args: cobra.ExactArgs(2), Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() @@ -36,40 +36,25 @@ var SshProxyCmd = &cobra.Command{ } profileId := args[0] - targetId := args[1] - workspaceName := "" + workspaceId := args[1] profile, err := c.GetProfile(profileId) if err != nil { return err } - if len(args) == 3 { - workspaceName = args[2] - } else { - workspaceName, err = apiclient.GetFirstWorkspaceName(targetId, workspaceName, &profile) - if err != nil { - return err - } + ws, err := apiclient_util.GetWorkspace(workspaceId, true) + if err != nil { + return err } - target, err := apiclient.GetTarget(targetId, true) + target, err := apiclient_util.GetTarget(ws.TargetId, true) if err != nil { return err } if target.TargetConfig == "local" && profile.Id == "default" { // If the target is local, we directly access the ssh port through the container - workspace := target.Workspaces[0] - - if workspace.Name != workspaceName { - for _, w := range target.Workspaces { - if w.Name == workspaceName { - workspace = w - break - } - } - } cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { @@ -80,7 +65,7 @@ var SshProxyCmd = &cobra.Command{ ApiClient: cli, }) - containerName := dockerClient.GetWorkspaceContainerName(conversion.ToWorkspace(&workspace)) + containerName := dockerClient.GetWorkspaceContainerName(conversion.ToWorkspace(ws)) ctx := context.Background() @@ -139,7 +124,7 @@ var SshProxyCmd = &cobra.Command{ errChan := make(chan error) - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(targetId, workspaceName), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(ws.Id), ssh_config.SSH_PORT)) if err != nil { return err } diff --git a/pkg/cmd/target/ssh.go b/pkg/cmd/workspace/ssh.go similarity index 68% rename from pkg/cmd/target/ssh.go rename to pkg/cmd/workspace/ssh.go index 4357d11f80..aa693d7efe 100644 --- a/pkg/cmd/target/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -16,11 +16,10 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -31,7 +30,7 @@ var ( ) var SshCmd = &cobra.Command{ - Use: "ssh [TARGET] [WORKSPACE] [CMD...]", + Use: "ssh [WORKSPACE] [CMD...]", Short: "SSH into a workspace using the terminal", Args: cobra.ArbitraryArgs, GroupID: util.TARGET_GROUP, @@ -47,9 +46,7 @@ var SshCmd = &cobra.Command{ } ctx := context.Background() - var target *apiclient.TargetDTO - var workspaceName string - var providerConfigId *string + var ws *apiclient.WorkspaceDTO apiClient, err := apiclient_util.GetApiClient(&activeProfile) if err != nil { @@ -57,87 +54,58 @@ var SshCmd = &cobra.Command{ } if len(args) == 0 { - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(targetList) == 0 { - views_util.NotifyEmptyTargetList(true) + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) return nil } - target = selection.GetTargetFromPrompt(targetList, "SSH Into") - if target == nil { + ws = selection.GetWorkspaceFromPrompt(workspaceList, "SSH Into") + if ws == nil { return nil } } else { - target, err = apiclient_util.GetTarget(args[0], true) + ws, err = apiclient_util.GetWorkspace(args[0], true) if err != nil { return err } } - if len(args) == 0 || len(args) == 1 { - selectedWorkspace, err := selectTargetWorkspace(target.Id, &activeProfile) - if err != nil { - return err - } - if selectedWorkspace == nil { - return nil - } - workspaceName = selectedWorkspace.Name - providerConfigId = selectedWorkspace.GitProviderConfigId - } - - if len(args) >= 2 { - workspaceName = args[1] - for _, workspace := range target.Workspaces { - if workspace.Name == workspaceName { - providerConfigId = workspace.GitProviderConfigId - break - } - } - } - if edit { - err := editSSHConfig(activeProfile, target, workspaceName) + err := editSSHConfig(activeProfile, ws) if err != nil { return err } } - if !target_util.IsWorkspaceRunning(target, workspaceName) { - tgRunningStatus, err := AutoStartTarget(target.Name, workspaceName) + if ws.State == nil || ws.State.Uptime < 1 { + wsRunningStatus, err := AutoStartWorkspace(ws.Id) if err != nil { return err } - if !tgRunningStatus { + if !wsRunningStatus { return nil } } sshArgs := []string{} - if len(args) > 2 { - sshArgs = append(sshArgs, args[2:]...) + if len(args) > 1 { + sshArgs = append(sshArgs, args[1:]...) } - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, ws.GitProviderConfigId) if err != nil { log.Warn(err) } - return ide.OpenTerminalSsh(activeProfile, target.Id, workspaceName, gpgKey, sshOptions, sshArgs...) + return ide.OpenTerminalSsh(activeProfile, ws.Id, gpgKey, sshOptions, sshArgs...) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - if len(args) >= 2 { - return nil, cobra.ShellCompDirectiveNoFileComp - } - if len(args) == 1 { - return getWorkspaceNameCompletions(cmd, args, toComplete) - } - - return getTargetNameCompletions() + return getWorkspaceNameCompletions() }, } @@ -147,7 +115,7 @@ func init() { SshCmd.Flags().StringArrayVarP(&sshOptions, "option", "o", []string{}, "Specify SSH options in KEY=VALUE format.") } -func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, workspaceName string) error { +func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceDTO) error { sshDir := filepath.Join(config.SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") sshConfig, err := config.ReadSshConfig(configPath) @@ -155,11 +123,11 @@ func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, wo return err } - hostLine := fmt.Sprintf("Host %s", config.GetWorkspaceHostname(activeProfile.Id, target.Id, workspaceName)) + hostLine := fmt.Sprintf("Host %s", config.GetWorkspaceHostname(activeProfile.Id, workspace.Id)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(sshConfig) if matchedEntry == "" { - return fmt.Errorf("no SSH entry found for workspace %s", workspaceName) + return fmt.Errorf("no SSH entry found for workspace %s", workspace.Name) } lines := strings.Split(matchedEntry, "\n") @@ -212,11 +180,11 @@ func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, wo } if modifiedContent == "" { - err = config.RemoveTargetSshEntries(activeProfile.Id, target.Id) + err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspace.Id) if err != nil { return err } - views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s removed successfully", workspaceName)) + views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s removed successfully", workspace.Name)) return nil } @@ -236,12 +204,12 @@ func editSSHConfig(activeProfile config.Profile, target *apiclient.TargetDTO, wo modifiedContent += "\n" } - err = config.UpdateWorkspaceSshEntry(activeProfile.Id, target.Id, workspaceName, modifiedContent) + err = config.UpdateWorkspaceSshEntry(activeProfile.Id, workspace.Id, modifiedContent) if err != nil { return err } - views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s updated successfully", workspaceName)) + views.RenderInfoMessage(fmt.Sprintf("SSH configuration for %s updated successfully", workspace.Name)) return nil } diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go new file mode 100644 index 0000000000..2d7b343d7b --- /dev/null +++ b/pkg/cmd/workspace/start.go @@ -0,0 +1,246 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + ide_views "github.com/daytonaio/daytona/pkg/views/ide" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +type WorkspaceState string + +const ( + WORKSPACE_STATE_RUNNING WorkspaceState = "Running" + WORKSPACE_STATE_STOPPED WorkspaceState = "Unavailable" +) + +var allFlag bool +var codeFlag bool + +var StartCmd = &cobra.Command{ + Use: "start [WORKSPACE]", + Short: "Start a workspace", + Args: cobra.RangeArgs(0, 1), + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + var selectedWorkspaceNames []string + var activeProfile config.Profile + var ideId string + var ideList []config.Ide + var providerConfigId *string + workspaceProviderMetadata := "" + + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if allFlag { + return startAllWorkspaces() + } + + if len(args) == 0 { + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) + return nil + } + selectedWorkspace := selection.GetWorkspaceFromPrompt(workspaceList, "Start") + if selectedWorkspace == nil { + return nil + } + selectedWorkspaceNames = append(selectedWorkspaceNames, selectedWorkspace.Name) + } else { + selectedWorkspaceNames = append(selectedWorkspaceNames, args[0]) + } + + if len(selectedWorkspaceNames) == 1 { + var ws *apiclient.WorkspaceDTO + var res *http.Response + workspaceName := selectedWorkspaceNames[0] + if codeFlag { + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err = c.GetActiveProfile() + if err != nil { + return err + } + + ideList = config.GetIdeList() + ideId = c.DefaultIdeId + + ws, res, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceName).Verbose(true).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + if ideId != "ssh" { + workspaceProviderMetadata = *ws.Info.ProviderMetadata + } + } + + err = StartWorkspace(apiClient, workspaceName) + if err != nil { + return err + } + gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + if err != nil { + log.Warn(err) + } + + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' started successfully", workspaceName)) + + if codeFlag { + ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList) + err = openIDE(ideId, activeProfile, ws.Id, workspaceProviderMetadata, yesFlag, gpgKey) + if err != nil { + return err + } + } + } else { + for _, ws := range selectedWorkspaceNames { + err := StartWorkspace(apiClient, ws) + if err != nil { + log.Errorf("Failed to start workspace %s: %v\n\n", ws, err) + continue + } + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", ws)) + } + } + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getAllWorkspacesByState(WORKSPACE_STATE_STOPPED) + }, +} + +func init() { + StartCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Start all targets") + StartCmd.PersistentFlags().BoolVarP(&codeFlag, "code", "c", false, "Open the target in the IDE after target start") + StartCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") +} + +func startAllWorkspaces() error { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + for _, workspace := range workspaceList { + err := StartWorkspace(apiClient, workspace.Id) + if err != nil { + log.Errorf("Failed to start workspace %s: %v\n\n", workspace.Name, err) + continue + } + + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", workspace.Name)) + } + return nil +} + +func getWorkspaceNameCompletions() ([]string, cobra.ShellCompDirective) { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + var choices []string + for _, v := range workspaceList { + choices = append(choices, v.Name) + } + + return choices, cobra.ShellCompDirectiveNoFileComp +} + +func getAllWorkspacesByState(state WorkspaceState) ([]string, cobra.ShellCompDirective) { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + var choices []string + for _, workspace := range workspaceList { + if state == WORKSPACE_STATE_RUNNING && workspace.State.Uptime != 0 { + choices = append(choices, workspace.Name) + break + } + if state == WORKSPACE_STATE_STOPPED && workspace.State.Uptime == 0 { + choices = append(choices, workspace.Name) + break + } + } + + return choices, cobra.ShellCompDirectiveNoFileComp +} + +func StartWorkspace(apiClient *apiclient.APIClient, workspaceId string) error { + ctx := context.Background() + timeFormat := time.Now().Format("2006-01-02 15:04:05") + from, err := time.Parse("2006-01-02 15:04:05", timeFormat) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + logsContext, stopLogs := context.WithCancel(context.Background()) + go apiclient_util.ReadWorkspaceLogs(logsContext, 0, activeProfile, workspaceId, true, &from) + + res, err := apiClient.WorkspaceAPI.StartWorkspace(ctx, workspaceId).Execute() + if err != nil { + stopLogs() + return apiclient_util.HandleErrorResponse(res, err) + } + time.Sleep(100 * time.Millisecond) + stopLogs() + return nil +} diff --git a/pkg/cmd/target/util/add_from_config.go b/pkg/cmd/workspace/util/add_from_config.go similarity index 100% rename from pkg/cmd/target/util/add_from_config.go rename to pkg/cmd/workspace/util/add_from_config.go diff --git a/pkg/cmd/target/util/branch_wizard.go b/pkg/cmd/workspace/util/branch_wizard.go similarity index 99% rename from pkg/cmd/target/util/branch_wizard.go rename to pkg/cmd/workspace/util/branch_wizard.go index c5b4670651..76379930a8 100644 --- a/pkg/cmd/target/util/branch_wizard.go +++ b/pkg/cmd/workspace/util/branch_wizard.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) type BranchWizardConfig struct { diff --git a/pkg/cmd/target/util/creation_data.go b/pkg/cmd/workspace/util/creation_data.go similarity index 98% rename from pkg/cmd/target/util/creation_data.go rename to pkg/cmd/workspace/util/creation_data.go index 11b5a4afdf..d45b21f6d3 100644 --- a/pkg/cmd/target/util/creation_data.go +++ b/pkg/cmd/workspace/util/creation_data.go @@ -17,9 +17,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/views/target/create" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) type WorkspacesDataPromptConfig struct { diff --git a/pkg/cmd/target/util/get_target_config.go b/pkg/cmd/workspace/util/get_target_config.go similarity index 100% rename from pkg/cmd/target/util/get_target_config.go rename to pkg/cmd/workspace/util/get_target_config.go diff --git a/pkg/cmd/target/util/repository_wizard.go b/pkg/cmd/workspace/util/repository_wizard.go similarity index 98% rename from pkg/cmd/target/util/repository_wizard.go rename to pkg/cmd/workspace/util/repository_wizard.go index 5301185f8e..39966c698c 100644 --- a/pkg/cmd/target/util/repository_wizard.go +++ b/pkg/cmd/workspace/util/repository_wizard.go @@ -13,9 +13,9 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" - "github.com/daytonaio/daytona/pkg/views/target/create" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" ) diff --git a/pkg/cmd/target/util/target.go b/pkg/cmd/workspace/util/target.go similarity index 78% rename from pkg/cmd/target/util/target.go rename to pkg/cmd/workspace/util/target.go index de394444e3..9cff8e66d1 100644 --- a/pkg/cmd/target/util/target.go +++ b/pkg/cmd/workspace/util/target.go @@ -4,10 +4,8 @@ package util import ( - "errors" "fmt" - "github.com/daytonaio/daytona/pkg/apiclient" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" ) @@ -50,26 +48,3 @@ func AddWorkspaceConfigurationFlags(cmd *cobra.Command, flags WorkspaceConfigura func CheckAnyWorkspaceConfigurationFlagSet(flags WorkspaceConfigurationFlags) bool { return *flags.GitProviderConfig != "" || *flags.CustomImage != "" || *flags.CustomImageUser != "" || *flags.DevcontainerPath != "" || *flags.Builder != "" || len(*flags.EnvVars) > 0 } - -func IsWorkspaceRunning(target *apiclient.TargetDTO, workspaceName string) bool { - for _, workspace := range target.GetWorkspaces() { - if workspace.GetName() == workspaceName { - return workspace.GetState().Uptime != 0 - } - } - return false -} - -func GetWorkspaceProviderMetadata(target *apiclient.TargetDTO, workspaceName string) (string, error) { - if target.Info != nil { - for _, workspace := range target.Info.Workspaces { - if workspace.Name == workspaceName { - if workspace.ProviderMetadata == nil { - return "", errors.New("workspace provider metadata is missing") - } - return *workspace.ProviderMetadata, nil - } - } - } - return "", nil -} diff --git a/pkg/cmd/workspaceconfig/add.go b/pkg/cmd/workspaceconfig/add.go index 722c3d5db8..e3a4508f46 100644 --- a/pkg/cmd/workspaceconfig/add.go +++ b/pkg/cmd/workspaceconfig/add.go @@ -12,11 +12,11 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - target_util "github.com/daytonaio/daytona/pkg/cmd/target/util" + workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/create" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" "github.com/spf13/cobra" ) @@ -66,7 +66,7 @@ var workspaceConfigAddCmd = &cobra.Command{ } func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.WorkspaceConfig, error) { - if target_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { + if workspace_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { return nil, errors.New("please provide the repository URL in order to set up custom workspace config details through the CLI") } @@ -88,7 +88,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - createDtos, err = target_util.GetWorkspacesCreationDataFromPrompt(target_util.WorkspacesDataPromptConfig{ + createDtos, err = workspace_util.GetWorkspacesCreationDataFromPrompt(workspace_util.WorkspacesDataPromptConfig{ UserGitProviders: gitProviders, Manual: *workspaceConfigurationFlags.Manual, MultiWorkspace: false, @@ -120,7 +120,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap initialSuggestion := createDtos[0].Name - chosenName := target_util.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) + chosenName := workspace_util.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) submissionFormConfig := create.SubmissionFormConfig{ ChosenName: &chosenName, @@ -207,12 +207,12 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con return nil, apiclient_util.HandleErrorResponse(res, err) } - workspaceConfigurationFlags.GitProviderConfig, err = target_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) + workspaceConfigurationFlags.GitProviderConfig, err = workspace_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } - workspace, err := target_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) + workspace, err := workspace_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) if err != nil { return nil, err } @@ -221,8 +221,8 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con if nameFlag != "" { name = nameFlag } else { - workspaceName := target_util.GetWorkspaceNameFromRepo(repoUrl) - name = target_util.GetSuggestedName(workspaceName, existingWorkspaceConfigNames) + workspaceName := workspace_util.GetWorkspaceNameFromRepo(repoUrl) + name = workspace_util.GetSuggestedName(workspaceName, existingWorkspaceConfigNames) } if workspace.GitProviderConfigId == nil || *workspace.GitProviderConfigId == "" { @@ -276,7 +276,7 @@ func getExistingWorkspaceConfigNames(apiClient *apiclient.APIClient) ([]string, var nameFlag string -var workspaceConfigurationFlags = target_util.WorkspaceConfigurationFlags{ +var workspaceConfigurationFlags = workspace_util.WorkspaceConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -289,5 +289,5 @@ var workspaceConfigurationFlags = target_util.WorkspaceConfigurationFlags{ func init() { workspaceConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace config name") - target_util.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) + workspace_util.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) } diff --git a/pkg/cmd/workspaceconfig/delete.go b/pkg/cmd/workspaceconfig/delete.go index fe89f02d58..b7517ac5bd 100644 --- a/pkg/cmd/workspaceconfig/delete.go +++ b/pkg/cmd/workspaceconfig/delete.go @@ -11,8 +11,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/export.go b/pkg/cmd/workspaceconfig/export.go index 647b7604ee..784d36a28c 100644 --- a/pkg/cmd/workspaceconfig/export.go +++ b/pkg/cmd/workspaceconfig/export.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/import.go b/pkg/cmd/workspaceconfig/import.go index 03dda5df5e..388095b4c6 100644 --- a/pkg/cmd/workspaceconfig/import.go +++ b/pkg/cmd/workspaceconfig/import.go @@ -15,9 +15,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/create" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/info.go b/pkg/cmd/workspaceconfig/info.go index 8f9e7d0c36..c4c003bc6d 100644 --- a/pkg/cmd/workspaceconfig/info.go +++ b/pkg/cmd/workspaceconfig/info.go @@ -10,8 +10,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/setdefault.go b/pkg/cmd/workspaceconfig/setdefault.go index 8d1e1b7265..bd55947237 100644 --- a/pkg/cmd/workspaceconfig/setdefault.go +++ b/pkg/cmd/workspaceconfig/setdefault.go @@ -9,8 +9,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/update.go b/pkg/cmd/workspaceconfig/update.go index f8d20944f1..d4c153c6f1 100644 --- a/pkg/cmd/workspaceconfig/update.go +++ b/pkg/cmd/workspaceconfig/update.go @@ -11,9 +11,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/create" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index 7087b7fe90..0440a6aff5 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" "gorm.io/gorm" ) diff --git a/pkg/db/dto/build.go b/pkg/db/dto/build.go index 54ea9b78b5..b74299b9a6 100644 --- a/pkg/db/dto/build.go +++ b/pkg/db/dto/build.go @@ -7,7 +7,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/workspace/containerconfig" ) type BuildDTO struct { diff --git a/pkg/db/dto/target.go b/pkg/db/dto/target.go index f5b4d37267..fe958549ba 100644 --- a/pkg/db/dto/target.go +++ b/pkg/db/dto/target.go @@ -4,27 +4,14 @@ package dto import ( - "errors" - "github.com/daytonaio/daytona/pkg/target" ) type TargetDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name" gorm:"unique"` - TargetConfig string `json:"config"` - ApiKey string `json:"apiKey"` - Workspaces []WorkspaceDTO `gorm:"serializer:json"` -} - -func (w TargetDTO) GetWorkspace(name string) (*WorkspaceDTO, error) { - for _, workspace := range w.Workspaces { - if workspace.Name == name { - return &workspace, nil - } - } - - return nil, errors.New("workspace not found") + Id string `gorm:"primaryKey"` + Name string `json:"name" gorm:"unique"` + TargetConfig string `json:"config"` + ApiKey string `json:"apiKey"` } func ToTargetDTO(target *target.Target) TargetDTO { @@ -35,10 +22,6 @@ func ToTargetDTO(target *target.Target) TargetDTO { ApiKey: target.ApiKey, } - for _, workspace := range target.Workspaces { - targetDTO.Workspaces = append(targetDTO.Workspaces, ToWorkspaceDTO(workspace)) - } - return targetDTO } @@ -50,9 +33,5 @@ func ToTarget(targetDTO TargetDTO) *target.Target { ApiKey: targetDTO.ApiKey, } - for _, workspaceDTO := range targetDTO.Workspaces { - target.Workspaces = append(target.Workspaces, ToWorkspace(workspaceDTO)) - } - return &target } diff --git a/pkg/db/dto/workspace.go b/pkg/db/dto/workspace.go index 552070656e..76d75efa25 100644 --- a/pkg/db/dto/workspace.go +++ b/pkg/db/dto/workspace.go @@ -5,8 +5,8 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type RepositoryDTO struct { @@ -52,13 +52,14 @@ type WorkspaceBuildDTO struct { } type WorkspaceDTO struct { + Id string `gorm:"primaryKey"` Name string `json:"name"` Image string `json:"image"` User string `json:"user"` Build *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` Repository RepositoryDTO `json:"repository" gorm:"serializer:json"` - TargetId string `json:"targetId"` - TargetConfig string `json:"targetConfig"` + TargetId string `json:"targetId" gorm:"foreignKey:TargetId;references:Id"` + Target TargetDTO `gorm:"foreignKey:TargetId"` ApiKey string `json:"apiKey"` State *WorkspaceStateDTO `json:"state,omitempty" gorm:"serializer:json"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` @@ -66,13 +67,13 @@ type WorkspaceDTO struct { func ToWorkspaceDTO(workspace *workspace.Workspace) WorkspaceDTO { return WorkspaceDTO{ + Id: workspace.Id, Name: workspace.Name, Image: workspace.Image, User: workspace.User, Build: ToWorkspaceBuildDTO(workspace.BuildConfig), Repository: ToRepositoryDTO(workspace.Repository), TargetId: workspace.TargetId, - TargetConfig: workspace.TargetConfig, State: ToWorkspaceStateDTO(workspace.State), ApiKey: workspace.ApiKey, GitProviderConfigId: workspace.GitProviderConfigId, @@ -158,13 +159,13 @@ func ToWorkspaceBuildDTO(build *buildconfig.BuildConfig) *WorkspaceBuildDTO { func ToWorkspace(workspaceDTO WorkspaceDTO) *workspace.Workspace { return &workspace.Workspace{ + Id: workspaceDTO.Id, Name: workspaceDTO.Name, Image: workspaceDTO.Image, User: workspaceDTO.User, BuildConfig: ToWorkspaceBuild(workspaceDTO.Build), Repository: ToRepository(workspaceDTO.Repository), TargetId: workspaceDTO.TargetId, - TargetConfig: workspaceDTO.TargetConfig, State: ToWorkspaceState(workspaceDTO.State), ApiKey: workspaceDTO.ApiKey, GitProviderConfigId: workspaceDTO.GitProviderConfigId, @@ -247,3 +248,10 @@ func ToWorkspaceBuild(buildDTO *WorkspaceBuildDTO) *buildconfig.BuildConfig { }, } } + +func ToWorkspaceViewDTO(workspaceDTO WorkspaceDTO) *workspace.WorkspaceViewDTO { + return &workspace.WorkspaceViewDTO{ + Workspace: *ToWorkspace(workspaceDTO), + TargetName: workspaceDTO.Target.Name, + } +} diff --git a/pkg/db/dto/workspace_config.go b/pkg/db/dto/workspace_config.go index 14422b59c2..624b31d3f2 100644 --- a/pkg/db/dto/workspace_config.go +++ b/pkg/db/dto/workspace_config.go @@ -4,7 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" ) type WorkspaceConfigDTO struct { diff --git a/pkg/db/workspace_config_store.go b/pkg/db/workspace_config_store.go index eb2d3edbe1..87a7fb8a0a 100644 --- a/pkg/db/workspace_config_store.go +++ b/pkg/db/workspace_config_store.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" ) type WorkspaceConfigStore struct { diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go new file mode 100644 index 0000000000..ee938e1c16 --- /dev/null +++ b/pkg/db/workspace_store.go @@ -0,0 +1,74 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" + + . "github.com/daytonaio/daytona/pkg/db/dto" + "github.com/daytonaio/daytona/pkg/workspace" +) + +type WorkspaceStore struct { + db *gorm.DB +} + +func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { + err := db.AutoMigrate(&WorkspaceDTO{}) + if err != nil { + return nil, err + } + + return &WorkspaceStore{db: db}, nil +} + +func (store *WorkspaceStore) List() ([]*workspace.WorkspaceViewDTO, error) { + workspaceDTOs := []WorkspaceDTO{} + tx := store.db.Preload(clause.Associations).Find(&workspaceDTOs) + if tx.Error != nil { + return nil, tx.Error + } + + workspaceViewDTOs := []*workspace.WorkspaceViewDTO{} + for _, workspaceDTO := range workspaceDTOs { + workspaceViewDTOs = append(workspaceViewDTOs, ToWorkspaceViewDTO(workspaceDTO)) + } + + return workspaceViewDTOs, nil +} + +func (w *WorkspaceStore) Find(idOrName string) (*workspace.WorkspaceViewDTO, error) { + workspaceDTO := WorkspaceDTO{} + tx := w.db.Preload(clause.Associations).Where("id = ? OR name = ?", idOrName, idOrName).First(&workspaceDTO) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, workspace.ErrWorkspaceNotFound + } + return nil, tx.Error + } + + return ToWorkspaceViewDTO(workspaceDTO), nil +} + +func (w *WorkspaceStore) Save(workspace *workspace.Workspace) error { + tx := w.db.Save(ToWorkspaceDTO(workspace)) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (w *WorkspaceStore) Delete(t *workspace.Workspace) error { + tx := w.db.Delete(ToWorkspaceDTO(t)) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return workspace.ErrWorkspaceNotFound + } + + return nil +} diff --git a/pkg/docker/client.go b/pkg/docker/client.go index ccf99ba066..cc415875f2 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/ssh" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index 93706f61bb..5ee67c14c0 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" "github.com/stretchr/testify/suite" ) @@ -22,20 +22,16 @@ var workspace1 = &workspace.Workspace{ Url: "https://github.com/daytonaio/daytona", Name: "daytona", }, - Image: "test-image:tag", - User: "test-user", - TargetId: "123", - TargetConfig: "local", - BuildConfig: &buildconfig.BuildConfig{}, + Image: "test-image:tag", + User: "test-user", + TargetId: "123", + BuildConfig: &buildconfig.BuildConfig{}, } var target1 = &target.Target{ Id: "123", Name: "test", TargetConfig: "local", - Workspaces: []*workspace.Workspace{ - workspace1, - }, } type DockerClientTestSuiteConfig struct { diff --git a/pkg/docker/create.go b/pkg/docker/create.go index a19de2fb7b..97c2af2176 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -95,7 +95,7 @@ func (d *DockerClient) cloneWorkspaceRepository(opts *CreateWorkspaceOptions) er } gitService := git.Service{ - WorkspaceDir: fmt.Sprintf("/workdir/%s-%s", opts.Workspace.TargetId, opts.Workspace.Name), + WorkspaceDir: fmt.Sprintf("/workdir/%s", opts.Workspace.Name), } cloneCmd := gitService.CloneRepositoryCmd(opts.Workspace.Repository, auth) diff --git a/pkg/docker/create_devcontainer.go b/pkg/docker/create_devcontainer.go index 90dd4342ce..c911bbfeea 100644 --- a/pkg/docker/create_devcontainer.go +++ b/pkg/docker/create_devcontainer.go @@ -21,7 +21,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/mount" diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index 35d1e36205..8d256537af 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -10,7 +10,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/docker/go-connections/nat" @@ -48,7 +48,7 @@ func (d *DockerClient) initWorkspaceContainer(opts *CreateWorkspaceOptions, moun var availablePort *uint16 var portBindings map[nat.Port][]nat.PortBinding - if opts.Workspace.TargetConfig == "local" { + if opts.Workspace.TargetId == "local" { p, err := ports.GetAvailableEphemeralPort() if err != nil { log.Error(err) diff --git a/pkg/docker/destroy.go b/pkg/docker/destroy.go index 6684b04460..4b168c275e 100644 --- a/pkg/docker/destroy.go +++ b/pkg/docker/destroy.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/ssh" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) diff --git a/pkg/docker/info.go b/pkg/docker/info.go index 73783f744b..4b6acb2c2d 100644 --- a/pkg/docker/info.go +++ b/pkg/docker/info.go @@ -9,7 +9,7 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) @@ -23,16 +23,6 @@ func (d *DockerClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, erro ProviderMetadata: fmt.Sprintf(TargetMetadataFormat, t.Id), } - workspaceInfos := []*workspace.WorkspaceInfo{} - for _, workspace := range t.Workspaces { - workspaceInfo, err := d.GetWorkspaceInfo(workspace) - if err != nil { - return nil, err - } - workspaceInfos = append(workspaceInfos, workspaceInfo) - } - targetInfo.Workspaces = workspaceInfos - return targetInfo, nil } diff --git a/pkg/docker/start.go b/pkg/docker/start.go index 2bd5bef1ce..6d91c57666 100644 --- a/pkg/docker/start.go +++ b/pkg/docker/start.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/detect" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" ) diff --git a/pkg/docker/stop.go b/pkg/docker/stop.go index 22c776f2b3..eeb6d8050a 100644 --- a/pkg/docker/stop.go +++ b/pkg/docker/stop.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" ) diff --git a/pkg/git/service.go b/pkg/git/service.go index f30c119275..476ff7d2d1 100644 --- a/pkg/git/service.go +++ b/pkg/git/service.go @@ -9,7 +9,7 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/transport/http" ) diff --git a/pkg/git/status.go b/pkg/git/status.go index 4456ba103f..dc0bafd4ff 100644 --- a/pkg/git/status.go +++ b/pkg/git/status.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/go-git/go-git/v5" ) diff --git a/pkg/ide/browser.go b/pkg/ide/browser.go index b44a535566..5ebb20a8cd 100644 --- a/pkg/ide/browser.go +++ b/pkg/ide/browser.go @@ -23,15 +23,15 @@ import ( const startVSCodeServerCommand = "$HOME/vscode-server/bin/openvscode-server --start-server --port=63000 --host=0.0.0.0 --without-connection-token --disable-workspace-trust --default-folder=" -func OpenBrowserIDE(activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, gpgKey string) error { +func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { // Download and start IDE - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return err } views.RenderInfoMessageBold("Downloading OpenVSCode Server...") - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) installServerCommand := exec.Command("ssh", workspaceHostname, "curl -fsSL https://download.daytona.io/daytona/get-openvscode-server.sh | sh") installServerCommand.Stdout = io.Writer(&util.DebugLogWriter{}) @@ -42,7 +42,7 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, workspaceName return err } - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } @@ -61,7 +61,7 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, workspaceName }() // Forward IDE port - browserPort, errChan := tailscale.ForwardPort(targetId, workspaceName, 63000, activeProfile) + browserPort, errChan := tailscale.ForwardPort(workspaceId, 63000, activeProfile) if browserPort == nil { if err := <-errChan; err != nil { return err @@ -77,7 +77,7 @@ func OpenBrowserIDE(activeProfile config.Profile, targetId string, workspaceName time.Sleep(500 * time.Millisecond) } - views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s IDE port to %s.\nOpening browser...\n", workspaceName, ideURL)) + views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s IDE port to %s.\nOpening browser...\n", workspaceId, ideURL)) err = browser.OpenURL(ideURL) if err != nil { diff --git a/pkg/ide/cursor.go b/pkg/ide/cursor.go index 107207bf27..368cfb2e34 100644 --- a/pkg/ide/cursor.go +++ b/pkg/ide/cursor.go @@ -14,15 +14,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenCursor(activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, gpgkey string) error { +func OpenCursor(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetCursorBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { return err } diff --git a/pkg/ide/fleet.go b/pkg/ide/fleet.go index 3958ed5323..28d7c179a0 100644 --- a/pkg/ide/fleet.go +++ b/pkg/ide/fleet.go @@ -13,13 +13,13 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenFleet(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string) error { +func OpenFleet(activeProfile config.Profile, workspaceId string, gpgKey string) error { if err := CheckFleetInstallation(); err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } diff --git a/pkg/ide/jetbrains.go b/pkg/ide/jetbrains.go index e5c54d0a56..6197f42054 100644 --- a/pkg/ide/jetbrains.go +++ b/pkg/ide/jetbrains.go @@ -23,25 +23,25 @@ import ( "github.com/pkg/browser" ) -func OpenJetbrainsIDE(activeProfile config.Profile, ide, targetId, workspaceName string, gpgKey string) error { +func OpenJetbrainsIDE(activeProfile config.Profile, ide, workspaceId string, gpgKey string) error { err := IsJetBrainsGatewayInstalled() if err != nil { return err } - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) jbIde, ok := jetbrains.GetIdes()[jetbrains.Id(ide)] if !ok { return errors.New("IDE not found") } - home, err := util.GetHomeDir(activeProfile, targetId, workspaceName, gpgKey) + home, err := util.GetHomeDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } diff --git a/pkg/ide/jupyter.go b/pkg/ide/jupyter.go index 512a92394c..88394d50da 100644 --- a/pkg/ide/jupyter.go +++ b/pkg/ide/jupyter.go @@ -26,14 +26,14 @@ import ( const startJupyterCommand = "notebook --no-browser --port=8888 --ip=0.0.0.0 --NotebookApp.token='' --NotebookApp.password=''" // OpenJupyterIDE manages the installation and startup of a Jupyter IDE on a remote target. -func OpenJupyterIDE(activeProfile config.Profile, targetId, workspaceName, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { +func OpenJupyterIDE(activeProfile config.Profile, workspaceId, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { // Ensure SSH config entry is added - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey) + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) // Check and install Python if necessary if err := ensurePythonInstalled(workspaceHostname, yesFlag); err != nil { @@ -51,7 +51,7 @@ func OpenJupyterIDE(activeProfile config.Profile, targetId, workspaceName, works } // Start Jupyter Notebook server - if err := startJupyterServer(workspaceHostname, activeProfile, targetId, workspaceName, gpgKey); err != nil { + if err := startJupyterServer(workspaceHostname, activeProfile, workspaceId, gpgKey); err != nil { return err } @@ -216,8 +216,8 @@ func ensureJupyterInstalled(hostname string) error { } // startJupyterServer starts the Jupyter Notebook server on the remote target. -func startJupyterServer(hostname string, activeProfile config.Profile, targetId, workspaceName string, gpgKey string) error { - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) +func startJupyterServer(hostname string, activeProfile config.Profile, workspaceId string, gpgKey string) error { + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } @@ -235,7 +235,7 @@ func startJupyterServer(hostname string, activeProfile config.Profile, targetId, }() // Forward the IDE port - browserPort, errChan := tailscale.ForwardPort(targetId, workspaceName, 8888, activeProfile) + browserPort, errChan := tailscale.ForwardPort(workspaceId, 8888, activeProfile) if browserPort == nil { if err := <-errChan; err != nil { return err @@ -246,7 +246,7 @@ func startJupyterServer(hostname string, activeProfile config.Profile, targetId, ideURL := fmt.Sprintf("http://localhost:%d", *browserPort) waitForPort(*browserPort) - views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s Jupyter Notebook port to %s.\nOpening browser...\n", workspaceName, ideURL)) + views.RenderInfoMessageBold(fmt.Sprintf("Forwarded %s Jupyter Notebook port to %s.\nOpening browser...\n", workspaceId, ideURL)) if err := browser.OpenURL(ideURL); err != nil { log.Error("Error opening URL: " + err.Error()) diff --git a/pkg/ide/positron.go b/pkg/ide/positron.go index 0842696756..1f1c12df43 100644 --- a/pkg/ide/positron.go +++ b/pkg/ide/positron.go @@ -15,15 +15,15 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenPositron(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenPositron(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetPositronBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { return err } diff --git a/pkg/ide/terminal.go b/pkg/ide/terminal.go index 945bb6c4d3..63c43f4972 100644 --- a/pkg/ide/terminal.go +++ b/pkg/ide/terminal.go @@ -12,8 +12,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func OpenTerminalSsh(activeProfile config.Profile, targetId string, workspaceName string, gpgKey string, sshOptions []string, args ...string) error { - if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, targetId, workspaceName, gpgKey); err != nil { +func OpenTerminalSsh(activeProfile config.Profile, workspaceId string, gpgKey string, sshOptions []string, args ...string) error { + if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey); err != nil { return err } @@ -23,7 +23,7 @@ func OpenTerminalSsh(activeProfile config.Profile, targetId string, workspaceNam return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) cmdArgs := buildCommandArgs(workspaceHostname, parsedOptions, args...) sshCommand := exec.Command("ssh", cmdArgs...) diff --git a/pkg/ide/vscode-insiders.go b/pkg/ide/vscode-insiders.go index f753714aaf..147c1d5615 100644 --- a/pkg/ide/vscode-insiders.go +++ b/pkg/ide/vscode-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { +func OpenVSCodeInsiders(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { path, err := GetVSCodeInsidersBinaryPath() if err != nil { return err @@ -23,9 +23,9 @@ func OpenVSCodeInsiders(activeProfile config.Profile, targetId string, workspace return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } diff --git a/pkg/ide/vscode.go b/pkg/ide/vscode.go index 46aae1fb1d..61fc4f69d4 100644 --- a/pkg/ide/vscode.go +++ b/pkg/ide/vscode.go @@ -19,16 +19,16 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenVSCode(activeProfile config.Profile, targetId string, workspaceName string, workspaceProviderMetadata string, gpgKey string) error { +func OpenVSCode(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { CheckAndAlertVSCodeInstalled() err := installRemoteSSHExtension("code") if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } diff --git a/pkg/ide/vscodium-insiders.go b/pkg/ide/vscodium-insiders.go index 22e727814b..22e008e4b5 100644 --- a/pkg/ide/vscodium-insiders.go +++ b/pkg/ide/vscodium-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenVScodiumInsiders(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetCodiumInsidersBinaryPath() if err != nil { return err @@ -24,9 +24,9 @@ func OpenVScodiumInsiders(activeProfile config.Profile, targetId string, workspa return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { return err } diff --git a/pkg/ide/vscodium.go b/pkg/ide/vscodium.go index b1be03618c..de1354f232 100644 --- a/pkg/ide/vscodium.go +++ b/pkg/ide/vscodium.go @@ -16,7 +16,7 @@ import ( const requiredExtension = "jeanp413.open-remote-ssh" -func OpenVScodium(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenVScodium(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetCodiumBinaryPath() if err != nil { return err @@ -27,9 +27,9 @@ func OpenVScodium(activeProfile config.Profile, targetId string, workspaceId str return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { return err } diff --git a/pkg/ide/windsurf.go b/pkg/ide/windsurf.go index 339e54d0e7..0824f23427 100644 --- a/pkg/ide/windsurf.go +++ b/pkg/ide/windsurf.go @@ -13,15 +13,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenWindsurf(activeProfile config.Profile, targetId string, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenWindsurf(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { path, err := GetWindsurfBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceId) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceId, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { return err } diff --git a/pkg/ide/zed.go b/pkg/ide/zed.go index a8c1d574ac..2b806e35d4 100644 --- a/pkg/ide/zed.go +++ b/pkg/ide/zed.go @@ -14,14 +14,14 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenZed(activeProfile config.Profile, targetId, workspaceName, gpgKey string) error { +func OpenZed(activeProfile config.Profile, workspaceId, gpgKey string) error { path, err := GetZedBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, targetId, workspaceName) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, targetId, workspaceName, gpgKey) + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } diff --git a/pkg/logs/logger.go b/pkg/logs/logger.go index 32118ad848..21aa5334fb 100644 --- a/pkg/logs/logger.go +++ b/pkg/logs/logger.go @@ -24,7 +24,7 @@ const ( type LogEntry struct { Source string `json:"source"` - TargetId *string `json:"targetId,omitempty"` + TargetName *string `json:"targetName,omitempty"` WorkspaceName *string `json:"workspaceName,omitempty"` BuildId *string `json:"buildId,omitempty"` Msg string `json:"msg"` @@ -33,12 +33,14 @@ type LogEntry struct { } type LoggerFactory interface { - CreateTargetLogger(targetId string, source LogSource) Logger - CreateWorkspaceLogger(targetId, workspaceName string, source LogSource) Logger CreateBuildLogger(buildId string, source LogSource) Logger - CreateTargetLogReader(targetId string) (io.Reader, error) - CreateWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) CreateBuildLogReader(buildId string) (io.Reader, error) + + CreateTargetLogger(targetId, targetName string, source LogSource) Logger + CreateTargetLogReader(targetId string) (io.Reader, error) + + CreateWorkspaceLogger(workspaceId, workspaceName string, source LogSource) Logger + CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) } type loggerFactoryImpl struct { diff --git a/pkg/logs/target.go b/pkg/logs/target.go index c5a0d3f392..a13517a7c9 100644 --- a/pkg/logs/target.go +++ b/pkg/logs/target.go @@ -14,11 +14,12 @@ import ( ) type targetLogger struct { - logsDir string - targetId string - logFile *os.File - logger *logrus.Logger - source LogSource + logsDir string + targetId string + targetName string + logFile *os.File + logger *logrus.Logger + source LogSource } func (w *targetLogger) Write(p []byte) (n int, err error) { @@ -39,7 +40,7 @@ func (w *targetLogger) Write(p []byte) (n int, err error) { var entry LogEntry entry.Msg = string(p) entry.Source = string(w.source) - entry.TargetId = &w.targetId + entry.TargetName = &w.targetName entry.Time = time.Now().Format(time.RFC3339) b, err := json.Marshal(entry) @@ -79,14 +80,15 @@ func (w *targetLogger) Cleanup() error { return os.RemoveAll(targetLogsDir) } -func (l *loggerFactoryImpl) CreateTargetLogger(targetId string, source LogSource) Logger { +func (l *loggerFactoryImpl) CreateTargetLogger(targetId, targetName string, source LogSource) Logger { logger := logrus.New() return &targetLogger{ - targetId: targetId, - logsDir: l.targetLogsDir, - logger: logger, - source: source, + targetId: targetId, + targetName: targetName, + logsDir: l.targetLogsDir, + logger: logger, + source: source, } } diff --git a/pkg/logs/workspace.go b/pkg/logs/workspace.go index 06c81b317e..4c4257a689 100644 --- a/pkg/logs/workspace.go +++ b/pkg/logs/workspace.go @@ -15,7 +15,7 @@ import ( type workspaceLogger struct { logsDir string - targetId string + workspaceId string workspaceName string logFile *os.File logger *logrus.Logger @@ -24,7 +24,7 @@ type workspaceLogger struct { func (pl *workspaceLogger) Write(p []byte) (n int, err error) { if pl.logFile == nil { - filePath := filepath.Join(pl.logsDir, pl.targetId, pl.workspaceName, "log") + filePath := filepath.Join(pl.logsDir, pl.workspaceId, "log") err = os.MkdirAll(filepath.Dir(filePath), 0755) if err != nil { return len(p), err @@ -41,7 +41,6 @@ func (pl *workspaceLogger) Write(p []byte) (n int, err error) { var entry LogEntry entry.Msg = string(p) entry.Source = string(pl.source) - entry.TargetId = &pl.targetId entry.WorkspaceName = &pl.workspaceName entry.Time = time.Now().Format(time.RFC3339) @@ -70,7 +69,7 @@ func (pl *workspaceLogger) Close() error { } func (pl *workspaceLogger) Cleanup() error { - workspaceLogsDir := filepath.Join(pl.logsDir, pl.targetId, pl.workspaceName) + workspaceLogsDir := filepath.Join(pl.logsDir, pl.workspaceId) _, err := os.Stat(workspaceLogsDir) if os.IsNotExist(err) { @@ -82,11 +81,11 @@ func (pl *workspaceLogger) Cleanup() error { return os.RemoveAll(workspaceLogsDir) } -func (l *loggerFactoryImpl) CreateWorkspaceLogger(targetId, workspaceName string, source LogSource) Logger { +func (l *loggerFactoryImpl) CreateWorkspaceLogger(workspaceId, workspaceName string, source LogSource) Logger { logger := logrus.New() return &workspaceLogger{ - targetId: targetId, + workspaceId: workspaceId, logsDir: l.targetLogsDir, workspaceName: workspaceName, logger: logger, @@ -94,7 +93,7 @@ func (l *loggerFactoryImpl) CreateWorkspaceLogger(targetId, workspaceName string } } -func (l *loggerFactoryImpl) CreateWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) { - filePath := filepath.Join(l.targetLogsDir, targetId, workspaceName, "log") +func (l *loggerFactoryImpl) CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) { + filePath := filepath.Join(l.targetLogsDir, workspaceId, "log") return os.Open(filePath) } diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 182a538f2b..8fe906112f 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -8,7 +8,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider/util" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" "github.com/hashicorp/go-plugin" ) diff --git a/pkg/provider/rpc_client.go b/pkg/provider/rpc_client.go index bfa5928968..ed2a05f5d5 100644 --- a/pkg/provider/rpc_client.go +++ b/pkg/provider/rpc_client.go @@ -8,7 +8,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider/util" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) type ProviderRPCClient struct { diff --git a/pkg/provider/rpc_server.go b/pkg/provider/rpc_server.go index 54e5d5fc5e..10f1a9b35f 100644 --- a/pkg/provider/rpc_server.go +++ b/pkg/provider/rpc_server.go @@ -6,7 +6,7 @@ package provider import ( "github.com/daytonaio/daytona/pkg/provider/util" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) type ProviderRPCServer struct { diff --git a/pkg/provider/types.go b/pkg/provider/types.go index 6a1f08e1c6..401c9dbd82 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -7,7 +7,7 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) type ProviderInfo struct { diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index 998f52e182..776bb2b94a 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -6,7 +6,7 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) func (p *Provisioner) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error { diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go index 717a6a3f45..d92e8092a1 100644 --- a/pkg/provisioner/info.go +++ b/pkg/provisioner/info.go @@ -8,21 +8,22 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/workspace" ) -type InfoResult struct { +type TargetInfoResult struct { Info *target.TargetInfo Err error } // Gets the target info from the provider - the context is used to cancel the request if it takes too long func (p *Provisioner) GetTargetInfo(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) { - ch := make(chan InfoResult, 1) + ch := make(chan TargetInfoResult, 1) go func() { targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) if err != nil { - ch <- InfoResult{nil, err} + ch <- TargetInfoResult{nil, err} return } @@ -31,7 +32,39 @@ func (p *Provisioner) GetTargetInfo(ctx context.Context, target *target.Target, Target: target, }) - ch <- InfoResult{info, err} + ch <- TargetInfoResult{info, err} + }() + + select { + case <-ctx.Done(): + return nil, ctx.Err() + case data := <-ch: + return data.Info, data.Err + } +} + +type WorkspaceInfoResult struct { + Info *workspace.WorkspaceInfo + Err error +} + +// Gets the workspace info from the provider - the context is used to cancel the request if it takes too long +func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { + ch := make(chan WorkspaceInfoResult, 1) + + go func() { + targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) + if err != nil { + ch <- WorkspaceInfoResult{nil, err} + return + } + + info, err := (*targetProvider).GetWorkspaceInfo(&provider.WorkspaceRequest{ + TargetConfigOptions: targetConfig.Options, + Workspace: workspace, + }) + + ch <- WorkspaceInfoResult{info, err} }() select { diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index 58fdbee3b7..d182c2bdc5 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) type WorkspaceParams struct { @@ -34,6 +34,7 @@ type IProvisioner interface { DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error StartWorkspace(params WorkspaceParams) error StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error + GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) } type ProvisionerConfig struct { diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index cc77456865..a57833e889 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -6,7 +6,7 @@ package provisioner import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" + "github.com/daytonaio/daytona/pkg/workspace" ) func (p *Provisioner) StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error { diff --git a/pkg/server/builds/dto/builds.go b/pkg/server/builds/dto/builds.go index 989b4a7916..7cadf1e552 100644 --- a/pkg/server/builds/dto/builds.go +++ b/pkg/server/builds/dto/builds.go @@ -5,7 +5,7 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type BuildCreationData struct { diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index d140d71fee..b16424eee8 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/workspace/containerconfig" "github.com/docker/docker/pkg/stringid" ) diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 9aaefde7ca..f0608a3434 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/containerconfig" "github.com/stretchr/testify/suite" ) diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index ef716dac60..8d724160a9 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -3,7 +3,7 @@ package gitproviders -import "github.com/daytonaio/daytona/pkg/target/workspace/config" +import "github.com/daytonaio/daytona/pkg/workspace/config" func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { gitProvider, err := s.configStore.Find(gitProviderId) diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index bbec5d149b..efeb647933 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -10,7 +10,7 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" ) type IGitProviderService interface { diff --git a/pkg/server/server.go b/pkg/server/server.go index beba393d27..a139065af3 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -16,6 +16,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/workspaceconfig" + "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/hashicorp/go-plugin" @@ -30,6 +31,7 @@ type ServerInstanceConfig struct { ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService WorkspaceConfigService workspaceconfig.IWorkspaceConfigService + WorkspaceService workspaces.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry TargetService targets.ITargetService ApiKeyService apikeys.IApiKeyService @@ -59,6 +61,7 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { ContainerRegistryService: serverConfig.ContainerRegistryService, BuildService: serverConfig.BuildService, WorkspaceConfigService: serverConfig.WorkspaceConfigService, + WorkspaceService: serverConfig.WorkspaceService, LocalContainerRegistry: serverConfig.LocalContainerRegistry, TargetService: serverConfig.TargetService, ApiKeyService: serverConfig.ApiKeyService, @@ -81,6 +84,7 @@ type Server struct { ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService WorkspaceConfigService workspaceconfig.IWorkspaceConfigService + WorkspaceService workspaces.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry TargetService targets.ITargetService ApiKeyService apikeys.IApiKeyService diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index aba484b1d2..fc762b0b90 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -5,24 +5,14 @@ package targets import ( "context" - "errors" "fmt" - "io" "regexp" - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/apikey" - "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" @@ -56,232 +46,72 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT return nil, ErrInvalidTargetName } - target := &target.Target{ + tg := &target.Target{ Id: req.Id, Name: req.Name, TargetConfig: req.TargetConfig, } - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, target.Id) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &tg.TargetConfig}) if err != nil { - return nil, err - } - target.ApiKey = apiKey - - target.Workspaces = []*workspace.Workspace{} - - for _, workspaceDto := range req.Workspaces { - w := conversion.CreateDtoToWorkspace(workspaceDto) - - isValidWorkspaceName := regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`).MatchString - if !isValidWorkspaceName(w.Name) { - return nil, ErrInvalidWorkspaceName - } - - w.Repository.Url = util.CleanUpRepositoryUrl(w.Repository.Url) - if w.GitProviderConfigId == nil || *w.GitProviderConfigId == "" { - configs, err := s.gitProviderService.ListConfigsForUrl(w.Repository.Url) - if err != nil { - return nil, err - } - - if len(configs) > 1 { - return nil, errors.New("multiple git provider configs found for the repository url") - } - - if len(configs) == 1 { - w.GitProviderConfigId = &configs[0].Id - } - } - - if w.Repository.Sha == "" { - sha, err := s.gitProviderService.GetLastCommitSha(w.Repository) - if err != nil { - return nil, err - } - w.Repository.Sha = sha - } - - if w.BuildConfig != nil { - cachedBuild, err := s.getCachedBuildForWorkspace(w) - if err == nil { - w.BuildConfig.CachedBuild = cachedBuild - } - } - - if w.Image == "" { - w.Image = s.defaultWorkspaceImage - } - - if w.User == "" { - w.User = s.defaultWorkspaceUser - } - - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, fmt.Sprintf("%s/%s", target.Id, w.Name)) - if err != nil { - return nil, err - } - - w.TargetId = target.Id - w.ApiKey = apiKey - w.TargetConfig = target.TargetConfig - target.Workspaces = append(target.Workspaces, w) - } - - err = s.targetStore.Save(target) - if err != nil { - return nil, err + return s.handleCreateError(ctx, nil, err) } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, tg.Id) if err != nil { - return target, err - } - - target, err = s.createTarget(ctx, target, targetConfig) - - if !telemetry.TelemetryEnabled(ctx) { - return target, err - } - - clientId := telemetry.ClientId(ctx) - - telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) - event := telemetry.ServerEventTargetCreated - if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetCreateError - } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) - if telemetryError != nil { - log.Trace(err) + return s.handleCreateError(ctx, nil, err) } + tg.ApiKey = apiKey - return target, err -} - -func (s *TargetService) createWorkspace(w *workspace.Workspace, targetConfig *provider.TargetConfig, logWriter io.Writer) error { - logWriter.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) - - cr, err := s.containerRegistryService.FindByImageName(w.Image) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { - return err - } - - builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { - return err - } - - var gc *gitprovider.GitProviderConfig - - if w.GitProviderConfigId != nil { - gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) - if err != nil && !gitprovider.IsGitProviderNotFound(err) { - return err - } - } - - err = s.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ - Workspace: w, - TargetConfig: targetConfig, - ContainerRegistry: cr, - GitProviderConfig: gc, - BuilderImage: s.builderImage, - BuilderImageContainerRegistry: builderCr, - }) + err = s.targetStore.Save(tg) if err != nil { - return err + return s.handleCreateError(ctx, nil, err) } - logWriter.Write([]byte(fmt.Sprintf("Workspace %s created\n", w.Name))) - - return nil -} - -func (s *TargetService) createTarget(ctx context.Context, t *target.Target, targetConfig *provider.TargetConfig) (*target.Target, error) { - targetLogger := s.loggerFactory.CreateTargetLogger(t.Id, logs.LogSourceServer) + targetLogger := s.loggerFactory.CreateTargetLogger(tg.Id, tg.Name, logs.LogSourceServer) defer targetLogger.Close() - targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", t.Name, t.Id))) + targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", tg.Name, tg.Id))) - t.EnvVars = target.GetTargetEnvVars(t, target.TargetEnvVarParams{ + tg.EnvVars = target.GetTargetEnvVars(tg, target.TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err := s.provisioner.CreateTarget(t, targetConfig) + err = s.provisioner.CreateTarget(tg, targetConfig) if err != nil { return nil, err } - for i, w := range t.Workspaces { - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(t.Id, w.Name, logs.LogSourceServer) - defer workspaceLogger.Close() - - workspaceWithEnv := *w - workspaceWithEnv.EnvVars = workspace.GetWorkspaceEnvVars(w, workspace.WorkspaceEnvVarParams{ - ApiUrl: s.serverApiUrl, - ServerUrl: s.serverUrl, - ServerVersion: s.serverVersion, - ClientId: telemetry.ClientId(ctx), - }, telemetry.TelemetryEnabled(ctx)) - - for k, v := range w.EnvVars { - workspaceWithEnv.EnvVars[k] = v - } - - var err error - - w = &workspaceWithEnv - - t.Workspaces[i] = w - err = s.targetStore.Save(t) - if err != nil { - return nil, err - } - - err = s.createWorkspace(w, targetConfig, workspaceLogger) - if err != nil { - return nil, err - } - } - targetLogger.Write([]byte("Target creation complete. Pending start...\n")) - err = s.startTarget(ctx, t, targetConfig, targetLogger) + err = s.startTarget(tg, targetConfig, targetLogger) if err != nil { - return nil, err + return s.handleCreateError(ctx, tg, err) } - return t, nil + return s.handleCreateError(ctx, tg, err) } -func (s *TargetService) getCachedBuildForWorkspace(w *workspace.Workspace) (*buildconfig.CachedBuild, error) { - validStates := &[]build.BuildState{ - build.BuildState(build.BuildStatePublished), +func (s *TargetService) handleCreateError(ctx context.Context, target *target.Target, err error) (*target.Target, error) { + if !telemetry.TelemetryEnabled(ctx) { + return target, err } - build, err := s.buildService.Find(&build.Filter{ - States: validStates, - RepositoryUrl: &w.Repository.Url, - Branch: &w.Repository.Branch, - EnvVars: &w.EnvVars, - BuildConfig: w.BuildConfig, - GetNewest: util.Pointer(true), - }) + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) + event := telemetry.ServerEventTargetCreated if err != nil { - return nil, err + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventTargetCreateError } - - if build.Image == nil || build.User == nil { - return nil, errors.New("cached build is missing image or user") + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(err) } - return &buildconfig.CachedBuild{ - User: *build.User, - Image: *build.Image, - }, nil + return target, err } diff --git a/pkg/server/targets/dto/target.go b/pkg/server/targets/dto/target.go index f8242b4889..8d0c1689e4 100644 --- a/pkg/server/targets/dto/target.go +++ b/pkg/server/targets/dto/target.go @@ -4,10 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" ) type TargetDTO struct { @@ -15,28 +12,8 @@ type TargetDTO struct { Info *target.TargetInfo `json:"info" validate:"optional"` } // @name TargetDTO -type WorkspaceDTO struct { - workspace.Workspace - Info *workspace.WorkspaceInfo `json:"info" validate:"optional"` -} // @name WorkspaceDTO - type CreateTargetDTO struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - TargetConfig string `json:"targetConfig" validate:"required"` - Workspaces []CreateWorkspaceDTO `json:"workspaces" validate:"required,gt=0,dive"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` } // @name CreateTargetDTO - -type CreateWorkspaceDTO struct { - Name string `json:"name" validate:"required"` - Image *string `json:"image,omitempty" validate:"optional"` - User *string `json:"user,omitempty" validate:"optional"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` - Source CreateWorkspaceSourceDTO `json:"source" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name CreateWorkspaceDTO - -type CreateWorkspaceSourceDTO struct { - Repository *gitprovider.GitRepository `json:"repository" validate:"required"` -} // @name CreateWorkspaceSourceDTO diff --git a/pkg/server/targets/error.go b/pkg/server/targets/error.go index 6bd276f9bc..a0e3b1544b 100644 --- a/pkg/server/targets/error.go +++ b/pkg/server/targets/error.go @@ -8,10 +8,7 @@ import ( ) var ( - ErrTargetAlreadyExists = errors.New("target already exists") - ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") - ErrTargetNotFound = errors.New("target not found") - ErrWorkspaceNotFound = errors.New("workspace not found") - ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") - ErrInvalidWorkspaceConfig = errors.New("workspace config is invalid") + ErrTargetAlreadyExists = errors.New("target already exists") + ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") + ErrTargetNotFound = errors.New("target not found") ) diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 499d4dff4e..648f64f331 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -37,11 +37,11 @@ func (s *TargetService) GetTarget(ctx context.Context, targetId string, verbose ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - resultCh := make(chan provisioner.InfoResult, 1) + resultCh := make(chan provisioner.TargetInfoResult, 1) go func() { targetInfo, err := s.provisioner.GetTargetInfo(ctx, tg, targetConfig) - resultCh <- provisioner.InfoResult{Info: targetInfo, Err: err} + resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} }() select { diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index 1f79c324b2..6abd19ac33 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -44,11 +44,11 @@ func (s *TargetService) ListTargets(ctx context.Context, verbose bool) ([]dto.Ta ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - resultCh := make(chan provisioner.InfoResult, 1) + resultCh := make(chan provisioner.TargetInfoResult, 1) go func() { targetInfo, err := s.provisioner.GetTargetInfo(ctx, t, targetConfig) - resultCh <- provisioner.InfoResult{Info: targetInfo, Err: err} + resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} }() select { diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 08d4746520..6ee3dcb65e 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -5,10 +5,10 @@ package targets import ( "context" - "fmt" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) @@ -16,27 +16,19 @@ import ( func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { target, err := s.targetStore.Find(targetId) if err != nil { - return ErrTargetNotFound + return s.handleRemoveError(ctx, target, ErrTargetNotFound) } log.Infof("Destroying target %s", target.Id) targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) if err != nil { - return err - } - - for _, workspace := range target.Workspaces { - // todo: go routines - err := s.provisioner.DestroyWorkspace(workspace, targetConfig) - if err != nil { - return err - } + return s.handleRemoveError(ctx, target, err) } err = s.provisioner.DestroyTarget(target, targetConfig) if err != nil { - return err + return s.handleRemoveError(ctx, target, err) } // Should not fail the whole operation if the API key cannot be revoked @@ -45,21 +37,7 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error log.Error(err) } - for _, workspace := range target.Workspaces { - err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, workspace.Name)) - if err != nil { - // Should not fail the whole operation if the API key cannot be revoked - log.Error(err) - } - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(target.Id, workspace.Name, logs.LogSourceServer) - err = workspaceLogger.Cleanup() - if err != nil { - // Should not fail the whole operation if the workspace logger cannot be cleaned up - log.Error(err) - } - } - - logger := s.loggerFactory.CreateTargetLogger(target.Id, logs.LogSourceServer) + logger := s.loggerFactory.CreateTargetLogger(target.Id, target.Name, logs.LogSourceServer) err = logger.Cleanup() if err != nil { // Should not fail the whole operation if the target logger cannot be cleaned up @@ -68,45 +46,20 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error err = s.targetStore.Delete(target) - if !telemetry.TelemetryEnabled(ctx) { - return err - } - - clientId := telemetry.ClientId(ctx) - - telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) - event := telemetry.ServerEventTargetDestroyed - if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetDestroyError - } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) - if telemetryError != nil { - log.Trace(telemetryError) - } - - return err + return s.handleRemoveError(ctx, target, err) } // ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { target, err := s.targetStore.Find(targetId) if err != nil { - return ErrTargetNotFound + return s.handleRemoveError(ctx, nil, ErrTargetNotFound) } log.Infof("Destroying target %s", target.Id) targetConfig, _ := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) - for _, workspace := range target.Workspaces { - // todo: go routines - err := s.provisioner.DestroyWorkspace(workspace, targetConfig) - if err != nil { - log.Error(err) - } - } - err = s.provisioner.DestroyTarget(target, targetConfig) if err != nil { log.Error(err) @@ -117,28 +70,19 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) log.Error(err) } - for _, workspace := range target.Workspaces { - err := s.apiKeyService.Revoke(fmt.Sprintf("%s/%s", target.Id, workspace.Name)) - if err != nil { - log.Error(err) - } - - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(target.Id, workspace.Name, logs.LogSourceServer) - err = workspaceLogger.Cleanup() - if err != nil { - log.Error(err) - } - } - err = s.targetStore.Delete(target) + return s.handleRemoveError(ctx, target, err) +} + +func (s *TargetService) handleRemoveError(ctx context.Context, target *target.Target, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) + telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) event := telemetry.ServerEventTargetDestroyed if err != nil { telemetryProps["error"] = err.Error() @@ -146,7 +90,7 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) } telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) if telemetryError != nil { - log.Trace(telemetryError) + log.Trace(err) } return err diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index e2ef76aa6e..6c48213fa1 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -5,20 +5,14 @@ package targets import ( "context" - "errors" "io" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/apikeys" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -31,11 +25,6 @@ type ITargetService interface { StopTarget(ctx context.Context, targetId string) error RemoveTarget(ctx context.Context, targetId string) error ForceRemoveTarget(ctx context.Context, targetId string) error - - GetWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) - SetWorkspaceState(targetId string, workspaceName string, state *workspace.WorkspaceState) (*target.Target, error) - StartWorkspace(ctx context.Context, targetId string, workspaceName string) error - StopWorkspace(ctx context.Context, targetId string, workspaceName string) error } type targetConfigStore interface { @@ -43,84 +32,43 @@ type targetConfigStore interface { } type TargetServiceConfig struct { - TargetStore target.Store - TargetConfigStore targetConfigStore - ContainerRegistryService containerregistries.IContainerRegistryService - BuildService builds.IBuildService - WorkspaceConfigService workspaceconfig.IWorkspaceConfigService - ServerApiUrl string - ServerUrl string - ServerVersion string - Provisioner provisioner.IProvisioner - DefaultWorkspaceImage string - DefaultWorkspaceUser string - BuilderImage string - ApiKeyService apikeys.IApiKeyService - LoggerFactory logs.LoggerFactory - GitProviderService gitproviders.IGitProviderService - TelemetryService telemetry.TelemetryService + TargetStore target.Store + TargetConfigStore targetConfigStore + ServerApiUrl string + ServerUrl string + ServerVersion string + Provisioner provisioner.IProvisioner + ApiKeyService apikeys.IApiKeyService + LoggerFactory logs.LoggerFactory + TelemetryService telemetry.TelemetryService } func NewTargetService(config TargetServiceConfig) ITargetService { return &TargetService{ - targetStore: config.TargetStore, - targetConfigStore: config.TargetConfigStore, - containerRegistryService: config.ContainerRegistryService, - buildService: config.BuildService, - workspaceConfigService: config.WorkspaceConfigService, - serverApiUrl: config.ServerApiUrl, - serverUrl: config.ServerUrl, - serverVersion: config.ServerVersion, - defaultWorkspaceImage: config.DefaultWorkspaceImage, - defaultWorkspaceUser: config.DefaultWorkspaceUser, - provisioner: config.Provisioner, - loggerFactory: config.LoggerFactory, - apiKeyService: config.ApiKeyService, - gitProviderService: config.GitProviderService, - telemetryService: config.TelemetryService, - builderImage: config.BuilderImage, + targetStore: config.TargetStore, + targetConfigStore: config.TargetConfigStore, + serverApiUrl: config.ServerApiUrl, + serverUrl: config.ServerUrl, + serverVersion: config.ServerVersion, + provisioner: config.Provisioner, + loggerFactory: config.LoggerFactory, + apiKeyService: config.ApiKeyService, + telemetryService: config.TelemetryService, } } type TargetService struct { - targetStore target.Store - targetConfigStore targetConfigStore - containerRegistryService containerregistries.IContainerRegistryService - buildService builds.IBuildService - workspaceConfigService workspaceconfig.IWorkspaceConfigService - provisioner provisioner.IProvisioner - apiKeyService apikeys.IApiKeyService - serverApiUrl string - serverUrl string - serverVersion string - defaultWorkspaceImage string - defaultWorkspaceUser string - builderImage string - loggerFactory logs.LoggerFactory - gitProviderService gitproviders.IGitProviderService - telemetryService telemetry.TelemetryService -} - -func (s *TargetService) SetWorkspaceState(targetId, workspaceName string, state *workspace.WorkspaceState) (*target.Target, error) { - tg, err := s.targetStore.Find(targetId) - if err != nil { - return nil, err - } - - for _, workspace := range tg.Workspaces { - if workspace.Name == workspaceName { - workspace.State = state - return tg, s.targetStore.Save(tg) - } - } - - return nil, errors.New("workspace not found") + targetStore target.Store + targetConfigStore targetConfigStore + provisioner provisioner.IProvisioner + apiKeyService apikeys.IApiKeyService + serverApiUrl string + serverUrl string + serverVersion string + loggerFactory logs.LoggerFactory + telemetryService telemetry.TelemetryService } func (s *TargetService) GetTargetLogReader(targetId string) (io.Reader, error) { return s.loggerFactory.CreateTargetLogReader(targetId) } - -func (s *TargetService) GetWorkspaceLogReader(targetId, workspaceName string) (io.Reader, error) { - return s.loggerFactory.CreateWorkspaceLogReader(targetId, workspaceName) -} diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index d305e1bc40..cc9a0cbfab 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -5,24 +5,17 @@ package targets_test import ( "context" - "fmt" "testing" - "time" t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apikey" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -30,9 +23,6 @@ import ( const serverApiUrl = "http://localhost:3986" const serverUrl = "http://localhost:3987" -const serverVersion = "0.0.0-test" -const defaultWorkspaceUser = "daytona" -const defaultWorkspaceImage = "daytonaio/workspace-project:latest" var targetConfig = provider.TargetConfig{ Name: "test-target-config", @@ -42,54 +32,16 @@ var targetConfig = provider.TargetConfig{ }, Options: "test-options", } -var gitProviderConfigId = "github" - -var baseApiUrl = "https://api.github.com" - -var gitProviderConfig = gitprovider.GitProviderConfig{ - Id: "github", - ProviderId: gitProviderConfigId, - Alias: "test-alias", - Username: "test-username", - Token: "test-token", - BaseApiUrl: &baseApiUrl, -} var createTargetDTO = dto.CreateTargetDTO{ Name: "test", Id: "test", TargetConfig: targetConfig.Name, - Workspaces: []dto.CreateWorkspaceDTO{ - { - Name: "workspace1", - GitProviderConfigId: &gitProviderConfig.Id, - Source: dto.CreateWorkspaceSourceDTO{ - Repository: &gitprovider.GitRepository{ - Id: "123", - Url: "https://github.com/daytonaio/daytona", - Name: "daytona", - Branch: "main", - Sha: "sha1", - }, - }, - Image: util.Pointer(defaultWorkspaceImage), - User: util.Pointer(defaultWorkspaceUser), - }, - }, } var targetInfo = target.TargetInfo{ Name: createTargetDTO.Name, ProviderMetadata: "provider-metadata-test", - Workspaces: []*workspace.WorkspaceInfo{ - { - Name: createTargetDTO.Workspaces[0].Name, - Created: "1 min ago", - IsRunning: true, - ProviderMetadata: "provider-metadata-test", - TargetId: createTargetDTO.Id, - }, - }, } func TestTargetService(t *testing.T) { @@ -98,97 +50,38 @@ func TestTargetService(t *testing.T) { targetStore := t_targets.NewInMemoryTargetStore() - containerRegistryService := mocks.NewMockContainerRegistryService() - - workspaceConfigService := mocks.NewMockWorkspaceConfigService() - targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() err := targetConfigStore.Save(&targetConfig) require.Nil(t, err) apiKeyService := mocks.NewMockApiKeyService() - gitProviderService := mocks.NewMockGitProviderService() mockProvisioner := mocks.NewMockProvisioner() tgLogsDir := t.TempDir() buildLogsDir := t.TempDir() service := targets.NewTargetService(targets.TargetServiceConfig{ - TargetStore: targetStore, - TargetConfigStore: targetConfigStore, - ServerApiUrl: serverApiUrl, - ServerUrl: serverUrl, - ServerVersion: serverVersion, - ContainerRegistryService: containerRegistryService, - WorkspaceConfigService: workspaceConfigService, - DefaultWorkspaceImage: defaultWorkspaceImage, - DefaultWorkspaceUser: defaultWorkspaceUser, - ApiKeyService: apiKeyService, - BuilderImage: defaultWorkspaceImage, - Provisioner: mockProvisioner, - LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), - GitProviderService: gitProviderService, + TargetStore: targetStore, + TargetConfigStore: targetConfigStore, + ServerApiUrl: serverApiUrl, + ServerUrl: serverUrl, + ApiKeyService: apiKeyService, + Provisioner: mockProvisioner, + LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), }) t.Run("CreateTarget", func(t *testing.T) { - var containerRegistry *containerregistry.ContainerRegistry - - containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) - mockProvisioner.On("CreateTarget", mock.Anything, &targetConfig).Return(nil) mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Generate", apikey.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) - gitProviderService.On("GetLastCommitSha", createTargetDTO.Workspaces[0].Source.Repository).Return("123", nil) - - for _, workspace := range createTargetDTO.Workspaces { - apiKeyService.On("Generate", apikey.ApiKeyTypeWorkspace, fmt.Sprintf("%s/%s", createTargetDTO.Id, workspace.Name)).Return(workspace.Name, nil) - } - - ws := &workspace.Workspace{ - Name: createTargetDTO.Workspaces[0].Name, - Image: *createTargetDTO.Workspaces[0].Image, - User: *createTargetDTO.Workspaces[0].User, - BuildConfig: createTargetDTO.Workspaces[0].BuildConfig, - Repository: createTargetDTO.Workspaces[0].Source.Repository, - ApiKey: createTargetDTO.Workspaces[0].Name, - GitProviderConfigId: createTargetDTO.Workspaces[0].GitProviderConfigId, - TargetId: createTargetDTO.Id, - TargetConfig: createTargetDTO.TargetConfig, - } - - ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ - ApiUrl: serverApiUrl, - ServerUrl: serverUrl, - ServerVersion: serverVersion, - ClientId: "test", - }, false) - - mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ - Workspace: ws, - TargetConfig: &targetConfig, - ContainerRegistry: containerRegistry, - GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultWorkspaceImage, - BuilderImageContainerRegistry: containerRegistry, - }).Return(nil) - mockProvisioner.On("StartWorkspace", provisioner.WorkspaceParams{ - Workspace: ws, - TargetConfig: &targetConfig, - ContainerRegistry: containerRegistry, - GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultWorkspaceImage, - BuilderImageContainerRegistry: containerRegistry, - }).Return(nil) - - gitProviderService.On("GetConfig", "github").Return(&gitProviderConfig, nil) target, err := service.CreateTarget(ctx, createTargetDTO) require.Nil(t, err) require.NotNil(t, target) - targetEquals(t, createTargetDTO, target, defaultWorkspaceImage) + targetEquals(t, createTargetDTO, target) }) t.Run("CreateTarget fails when target already exists", func(t *testing.T) { @@ -214,7 +107,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, target) - targetDtoEquals(t, createTargetDTO, *target, targetInfo, defaultWorkspaceImage, true) + targetDtoEquals(t, createTargetDTO, *target, targetInfo, true) }) t.Run("GetTarget fails when target not found", func(t *testing.T) { @@ -234,7 +127,7 @@ func TestTargetService(t *testing.T) { target := targets[0] - targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultWorkspaceImage, verbose) + targetDtoEquals(t, createTargetDTO, target, targetInfo, verbose) }) t.Run("ListTargets - verbose", func(t *testing.T) { @@ -248,48 +141,27 @@ func TestTargetService(t *testing.T) { target := targets[0] - targetDtoEquals(t, createTargetDTO, target, targetInfo, defaultWorkspaceImage, verbose) + targetDtoEquals(t, createTargetDTO, target, targetInfo, verbose) }) t.Run("StartTarget", func(t *testing.T) { mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) err := service.StartTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) - t.Run("StartWorkspace", func(t *testing.T) { - mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) - - err := service.StartWorkspace(ctx, createTargetDTO.Id, createTargetDTO.Workspaces[0].Name) - - require.Nil(t, err) - }) - t.Run("StopTarget", func(t *testing.T) { mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) err := service.StopTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) - t.Run("StopWorkspace", func(t *testing.T) { - mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) - - err := service.StopWorkspace(ctx, createTargetDTO.Id, createTargetDTO.Workspaces[0].Name) - - require.Nil(t, err) - }) - t.Run("RemoveTarget", func(t *testing.T) { mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveTarget(ctx, createTargetDTO.Id) @@ -305,7 +177,6 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveTarget(ctx, createTargetDTO.Id) @@ -316,51 +187,21 @@ func TestTargetService(t *testing.T) { require.Equal(t, targets.ErrTargetNotFound, err) }) - t.Run("SetWorkspaceState", func(t *testing.T) { - tg, err := service.CreateTarget(ctx, createTargetDTO) - require.Nil(t, err) - - workspaceName := tg.Workspaces[0].Name - updatedAt := time.Now().Format(time.RFC1123) - res, err := service.SetWorkspaceState(tg.Id, workspaceName, &workspace.WorkspaceState{ - UpdatedAt: updatedAt, - Uptime: 10, - GitStatus: &workspace.GitStatus{ - CurrentBranch: "main", - }, - }) - require.Nil(t, err) - - workspace, err := res.GetWorkspace(workspaceName) - require.Nil(t, err) - require.Equal(t, "main", workspace.State.GitStatus.CurrentBranch) - }) - t.Cleanup(func() { apiKeyService.AssertExpectations(t) mockProvisioner.AssertExpectations(t) }) } -func targetEquals(t *testing.T, req dto.CreateTargetDTO, target *target.Target, workspaceImage string) { +func targetEquals(t *testing.T, req dto.CreateTargetDTO, target *target.Target) { t.Helper() require.Equal(t, req.Id, target.Id) require.Equal(t, req.Name, target.Name) require.Equal(t, req.TargetConfig, target.TargetConfig) - - for i, workspace := range target.Workspaces { - require.Equal(t, req.Workspaces[i].Name, workspace.Name) - require.Equal(t, req.Workspaces[i].Source.Repository.Id, workspace.Repository.Id) - require.Equal(t, req.Workspaces[i].Source.Repository.Url, workspace.Repository.Url) - require.Equal(t, req.Workspaces[i].Source.Repository.Name, workspace.Repository.Name) - require.Equal(t, workspace.ApiKey, workspace.Name) - require.Equal(t, workspace.TargetConfig, req.TargetConfig) - require.Equal(t, workspace.Image, workspaceImage) - } } -func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, workspaceImage string, verbose bool) { +func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, verbose bool) { t.Helper() require.Equal(t, req.Id, target.Id) @@ -373,21 +214,4 @@ func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO } else { require.Nil(t, target.Info) } - - for i, workspace := range target.Workspaces { - require.Equal(t, req.Workspaces[i].Name, workspace.Name) - require.Equal(t, req.Workspaces[i].Source.Repository.Id, workspace.Repository.Id) - require.Equal(t, req.Workspaces[i].Source.Repository.Url, workspace.Repository.Url) - require.Equal(t, req.Workspaces[i].Source.Repository.Name, workspace.Repository.Name) - require.Equal(t, workspace.ApiKey, workspace.Name) - require.Equal(t, workspace.TargetConfig, req.TargetConfig) - require.Equal(t, workspace.Image, workspaceImage) - - if verbose { - require.Equal(t, target.Info.Workspaces[i].Name, targetInfo.Workspaces[i].Name) - require.Equal(t, target.Info.Workspaces[i].Created, targetInfo.Workspaces[i].Created) - require.Equal(t, target.Info.Workspaces[i].IsRunning, targetInfo.Workspaces[i].IsRunning) - require.Equal(t, target.Info.Workspaces[i].ProviderMetadata, targetInfo.Workspaces[i].ProviderMetadata) - } - } } diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index a090ae47be..01d587ce17 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -8,13 +8,9 @@ import ( "fmt" "io" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/workspace" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" @@ -22,67 +18,20 @@ import ( ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { - w, err := s.targetStore.Find(targetId) + t, err := s.targetStore.Find(targetId) if err != nil { - return ErrTargetNotFound + return s.handleStartError(ctx, nil, ErrTargetNotFound) } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &t.TargetConfig}) if err != nil { - return err + return s.handleStartError(ctx, t, err) } - targetLogger := s.loggerFactory.CreateTargetLogger(w.Id, logs.LogSourceServer) + targetLogger := s.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) defer targetLogger.Close() - tgLogWriter := io.MultiWriter(&util.InfoLogWriter{}, targetLogger) - - err = s.startTarget(ctx, w, targetConfig, tgLogWriter) - - if !telemetry.TelemetryEnabled(ctx) { - return err - } - - clientId := telemetry.ClientId(ctx) - - telemetryProps := telemetry.NewTargetEventProps(ctx, w, targetConfig) - event := telemetry.ServerEventTargetStarted - if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetStartError - } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) - if telemetryError != nil { - log.Trace(telemetryError) - } - - return err -} - -func (s *TargetService) StartWorkspace(ctx context.Context, targetId, workspaceName string) error { - w, err := s.targetStore.Find(targetId) - if err != nil { - return ErrTargetNotFound - } - - workspace, err := w.GetWorkspace(workspaceName) - if err != nil { - return ErrWorkspaceNotFound - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) - if err != nil { - return err - } - - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(w.Id, workspace.Name, logs.LogSourceServer) - defer workspaceLogger.Close() - - return s.startWorkspace(ctx, workspace, targetConfig, workspaceLogger) -} - -func (s *TargetService) startTarget(ctx context.Context, t *target.Target, targetConfig *provider.TargetConfig, targetLogger io.Writer) error { - targetLogger.Write([]byte("Starting target\n")) + logger := io.MultiWriter(&util.InfoLogWriter{}, targetLogger) t.EnvVars = target.GetTargetEnvVars(t, target.TargetEnvVarParams{ ApiUrl: s.serverApiUrl, @@ -91,69 +40,44 @@ func (s *TargetService) startTarget(ctx context.Context, t *target.Target, targe ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err := s.provisioner.StartTarget(t, targetConfig) + err = s.startTarget(t, targetConfig, logger) if err != nil { - return err + return s.handleStartError(ctx, t, err) } - for _, workspace := range t.Workspaces { - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(t.Id, workspace.Name, logs.LogSourceServer) - defer workspaceLogger.Close() - - err = s.startWorkspace(ctx, workspace, targetConfig, workspaceLogger) - if err != nil { - return err - } - } - - targetLogger.Write([]byte(fmt.Sprintf("Target %s started\n", t.Name))) - - return nil + return s.handleStartError(ctx, t, err) } -func (s *TargetService) startWorkspace(ctx context.Context, w *workspace.Workspace, targetConfig *provider.TargetConfig, logWriter io.Writer) error { - logWriter.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) - - workspaceToStart := *w - workspaceToStart.EnvVars = workspace.GetWorkspaceEnvVars(w, workspace.WorkspaceEnvVarParams{ - ApiUrl: s.serverApiUrl, - ServerUrl: s.serverUrl, - ServerVersion: s.serverVersion, - ClientId: telemetry.ClientId(ctx), - }, telemetry.TelemetryEnabled(ctx)) +func (s *TargetService) startTarget(target *target.Target, targetConfig *provider.TargetConfig, targetLogger io.Writer) error { + targetLogger.Write([]byte("Starting target\n")) - cr, err := s.containerRegistryService.FindByImageName(w.Image) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + err := s.provisioner.StartTarget(target, targetConfig) + if err != nil { return err } - builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { - return err - } + targetLogger.Write([]byte(fmt.Sprintf("Target %s started\n", target.Name))) - var gc *gitprovider.GitProviderConfig + return err +} - if w.GitProviderConfigId != nil { - gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) - if err != nil && !gitprovider.IsGitProviderNotFound(err) { - return err - } +func (s *TargetService) handleStartError(ctx context.Context, target *target.Target, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err } - err = s.provisioner.StartWorkspace(provisioner.WorkspaceParams{ - Workspace: &workspaceToStart, - TargetConfig: targetConfig, - ContainerRegistry: cr, - GitProviderConfig: gc, - BuilderImage: s.builderImage, - BuilderImageContainerRegistry: builderCr, - }) + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) + event := telemetry.ServerEventTargetStarted if err != nil { - return err + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventTargetStartError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(telemetryError) } - logWriter.Write([]byte(fmt.Sprintf("Workspace %s started\n", w.Name))) - - return nil + return err } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index 06e410dcad..a07d3bf0ff 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -5,9 +5,9 @@ package targets import ( "context" - "time" "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) @@ -15,38 +15,27 @@ import ( func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { target, err := s.targetStore.Find(targetId) if err != nil { - return ErrTargetNotFound + return s.handleStopError(ctx, nil, ErrTargetNotFound) } targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) if err != nil { - return err - } - - for _, workspace := range target.Workspaces { - // todo: go routines - err := s.provisioner.StopWorkspace(workspace, targetConfig) - if err != nil { - return err - } - if workspace.State != nil { - workspace.State.Uptime = 0 - workspace.State.UpdatedAt = time.Now().Format(time.RFC1123) - } + return s.handleStopError(ctx, target, err) } err = s.provisioner.StopTarget(target, targetConfig) - if err == nil { - err = s.targetStore.Save(target) - } + return s.handleStopError(ctx, target, err) +} + +func (s *TargetService) handleStopError(ctx context.Context, target *target.Target, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target, targetConfig) + telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) event := telemetry.ServerEventTargetStopped if err != nil { telemetryProps["error"] = err.Error() @@ -59,32 +48,3 @@ func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { return err } - -func (s *TargetService) StopWorkspace(ctx context.Context, targetId, workspaceName string) error { - w, err := s.targetStore.Find(targetId) - if err != nil { - return ErrTargetNotFound - } - - workspace, err := w.GetWorkspace(workspaceName) - if err != nil { - return ErrWorkspaceNotFound - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &w.TargetConfig}) - if err != nil { - return err - } - - err = s.provisioner.StopWorkspace(workspace, targetConfig) - if err != nil { - return err - } - - if workspace.State != nil { - workspace.State.Uptime = 0 - workspace.State.UpdatedAt = time.Now().Format(time.RFC1123) - } - - return s.targetStore.Save(w) -} diff --git a/pkg/server/workspaceconfig/dto/workspaceconfig.go b/pkg/server/workspaceconfig/dto/workspaceconfig.go index 1a83aceeda..b63c97c266 100644 --- a/pkg/server/workspaceconfig/dto/workspaceconfig.go +++ b/pkg/server/workspaceconfig/dto/workspaceconfig.go @@ -4,7 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type CreateWorkspaceConfigDTO struct { diff --git a/pkg/server/workspaceconfig/prebuild.go b/pkg/server/workspaceconfig/prebuild.go index a5b2a60d58..c4b54c9798 100644 --- a/pkg/server/workspaceconfig/prebuild.go +++ b/pkg/server/workspaceconfig/prebuild.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" - "github.com/daytonaio/daytona/pkg/target/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/containerconfig" log "github.com/sirupsen/logrus" ) diff --git a/pkg/server/workspaceconfig/prebuild_test.go b/pkg/server/workspaceconfig/prebuild_test.go index cddee3a951..a47401fba2 100644 --- a/pkg/server/workspaceconfig/prebuild_test.go +++ b/pkg/server/workspaceconfig/prebuild_test.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" ) var prebuild1 *config.PrebuildConfig = &config.PrebuildConfig{ diff --git a/pkg/server/workspaceconfig/service.go b/pkg/server/workspaceconfig/service.go index 38d2b621fd..803e4e9c25 100644 --- a/pkg/server/workspaceconfig/service.go +++ b/pkg/server/workspaceconfig/service.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" ) type IWorkspaceConfigService interface { diff --git a/pkg/server/workspaceconfig/service_test.go b/pkg/server/workspaceconfig/service_test.go index 3a1768a781..43908653d8 100644 --- a/pkg/server/workspaceconfig/service_test.go +++ b/pkg/server/workspaceconfig/service_test.go @@ -11,7 +11,7 @@ import ( workspaceconfig_internal "github.com/daytonaio/daytona/internal/testing/server/workspaceconfig" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/server/workspaceconfig" - "github.com/daytonaio/daytona/pkg/target/workspace/config" + "github.com/daytonaio/daytona/pkg/workspace/config" "github.com/stretchr/testify/suite" ) diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go new file mode 100644 index 0000000000..3baa8faf30 --- /dev/null +++ b/pkg/server/workspaces/create.go @@ -0,0 +1,229 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "errors" + "fmt" + "regexp" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" + "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + + log "github.com/sirupsen/logrus" +) + +func isValidWorkspaceName(name string) bool { + // The repository name can only contain ASCII letters, digits, and the characters ., -, and _. + var validName = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) + + // Check if the name matches the basic regex + if !validName.MatchString(name) { + return false + } + + // Names starting with a period must have atleast one char appended to it. + if name == "." || name == "" { + return false + } + + return true +} + +func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*workspace.WorkspaceViewDTO, error) { + _, err := s.workspaceStore.Find(req.Name) + if err == nil { + return s.handleCreateError(ctx, nil, ErrWorkspaceAlreadyExists) + } + + target, err := s.targetStore.Find(req.TargetId) + if err != nil { + return s.handleCreateError(ctx, nil, err) + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return s.handleCreateError(ctx, nil, err) + } + + w := conversion.CreateDtoToWorkspace(req) + + if !isValidWorkspaceName(w.Name) { + return s.handleCreateError(ctx, w, ErrInvalidWorkspaceName) + } + + w.Repository.Url = util.CleanUpRepositoryUrl(w.Repository.Url) + if w.GitProviderConfigId == nil || *w.GitProviderConfigId == "" { + configs, err := s.gitProviderService.ListConfigsForUrl(w.Repository.Url) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + + if len(configs) > 1 { + return s.handleCreateError(ctx, w, errors.New("multiple git provider configs found for the repository url")) + } + + if len(configs) == 1 { + w.GitProviderConfigId = &configs[0].Id + } + } + + if w.Repository.Sha == "" { + sha, err := s.gitProviderService.GetLastCommitSha(w.Repository) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + w.Repository.Sha = sha + } + + if w.BuildConfig != nil { + cachedBuild, err := s.getCachedBuildForWorkspace(w) + if err == nil { + w.BuildConfig.CachedBuild = cachedBuild + } + } + + if w.Image == "" { + w.Image = s.defaultWorkspaceImage + } + + if w.User == "" { + w.User = s.defaultWorkspaceUser + } + + apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", w.Id)) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + + w.ApiKey = apiKey + + err = s.workspaceStore.Save(w) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + defer workspaceLogger.Close() + + workspaceWithEnv := *w + workspaceWithEnv.EnvVars = workspace.GetWorkspaceEnvVars(w, workspace.WorkspaceEnvVarParams{ + ApiUrl: s.serverApiUrl, + ServerUrl: s.serverUrl, + ServerVersion: s.serverVersion, + ClientId: telemetry.ClientId(ctx), + }, telemetry.TelemetryEnabled(ctx)) + + for k, v := range w.EnvVars { + workspaceWithEnv.EnvVars[k] = v + } + + w = &workspaceWithEnv + + workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) + + cr, err := s.containerRegistryService.FindByImageName(w.Image) + if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + return s.handleCreateError(ctx, w, err) + } + + builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) + if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + return s.handleCreateError(ctx, w, err) + } + + var gc *gitprovider.GitProviderConfig + + if w.GitProviderConfigId != nil { + gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) + if err != nil && !gitprovider.IsGitProviderNotFound(err) { + return s.handleCreateError(ctx, w, err) + } + } + + err = s.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ + Workspace: w, + TargetConfig: targetConfig, + ContainerRegistry: cr, + GitProviderConfig: gc, + BuilderImage: s.builderImage, + BuilderImageContainerRegistry: builderCr, + }) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + + workspaceLogger.Write([]byte(fmt.Sprintf("Workspace %s created\n", w.Name))) + + err = s.startWorkspace(w, targetConfig, workspaceLogger) + + return s.handleCreateError(ctx, w, err) +} + +func (s *WorkspaceService) handleCreateError(ctx context.Context, w *workspace.Workspace, err error) (*workspace.WorkspaceViewDTO, error) { + if !telemetry.TelemetryEnabled(ctx) { + if w == nil { + return nil, err + } + return &workspace.WorkspaceViewDTO{Workspace: *w}, err + } + + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) + event := telemetry.ServerEventWorkspaceCreated + if err != nil { + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventWorkspaceCreateError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(err) + } + + if w == nil { + return nil, err + } + + return &workspace.WorkspaceViewDTO{Workspace: *w}, err +} + +func (s *WorkspaceService) getCachedBuildForWorkspace(w *workspace.Workspace) (*buildconfig.CachedBuild, error) { + validStates := &[]build.BuildState{ + build.BuildState(build.BuildStatePublished), + } + + build, err := s.buildService.Find(&build.Filter{ + States: validStates, + RepositoryUrl: &w.Repository.Url, + Branch: &w.Repository.Branch, + EnvVars: &w.EnvVars, + BuildConfig: w.BuildConfig, + GetNewest: util.Pointer(true), + }) + if err != nil { + return nil, err + } + + if build.Image == nil || build.User == nil { + return nil, errors.New("cached build is missing image or user") + } + + return &buildconfig.CachedBuild{ + User: *build.User, + Image: *build.Image, + }, nil +} diff --git a/pkg/server/workspaces/dto/workspace.go b/pkg/server/workspaces/dto/workspace.go new file mode 100644 index 0000000000..826812c1fc --- /dev/null +++ b/pkg/server/workspaces/dto/workspace.go @@ -0,0 +1,31 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import ( + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" +) + +type WorkspaceDTO struct { + workspace.WorkspaceViewDTO + Info *workspace.WorkspaceInfo `json:"info" validate:"optional"` +} // @name WorkspaceDTO + +type CreateWorkspaceDTO struct { + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + Image *string `json:"image,omitempty" validate:"optional"` + User *string `json:"user,omitempty" validate:"optional"` + BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` + Source CreateWorkspaceSourceDTO `json:"source" validate:"required"` + EnvVars map[string]string `json:"envVars" validate:"required"` + TargetId string `json:"targetId" validate:"required"` + GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` +} // @name CreateWorkspaceDTO + +type CreateWorkspaceSourceDTO struct { + Repository *gitprovider.GitRepository `json:"repository" validate:"required"` +} // @name CreateWorkspaceSourceDTO diff --git a/pkg/server/workspaces/error.go b/pkg/server/workspaces/error.go new file mode 100644 index 0000000000..68b212eec7 --- /dev/null +++ b/pkg/server/workspaces/error.go @@ -0,0 +1,15 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "errors" +) + +var ( + ErrWorkspaceAlreadyExists = errors.New("workspace already exists") + ErrWorkspaceNotFound = errors.New("workspace not found") + ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") + ErrInvalidWorkspaceConfig = errors.New("workspace config is invalid") +) diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go new file mode 100644 index 0000000000..ce7ee7e0a9 --- /dev/null +++ b/pkg/server/workspaces/get.go @@ -0,0 +1,69 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) { + ws, err := s.workspaceStore.Find(workspaceId) + if err != nil { + return nil, ErrWorkspaceNotFound + } + + response := &dto.WorkspaceDTO{ + WorkspaceViewDTO: *ws, + } + + if !verbose { + return response, nil + } + + target, err := s.targetStore.Find(ws.TargetId) + if err != nil { + return nil, err + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + resultCh := make(chan provisioner.WorkspaceInfoResult, 1) + + go func() { + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, targetConfig) + resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} + }() + + select { + case res := <-resultCh: + if res.Err != nil { + log.Error(fmt.Errorf("failed to get workspace info for %s: %v", ws.Name, res.Err)) + return nil, res.Err + } + + response.Info = res.Info + case <-ctx.Done(): + if errors.Is(ctx.Err(), context.DeadlineExceeded) { + log.Warn(fmt.Sprintf("timeout getting workspace info for %s", ws.Name)) + } else { + log.Warn(fmt.Sprintf("cancelled getting workspace info for %s", ws.Name)) + } + } + + return response, nil +} diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go new file mode 100644 index 0000000000..d02a9a068d --- /dev/null +++ b/pkg/server/workspaces/list.go @@ -0,0 +1,80 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) { + workspaces, err := s.workspaceStore.List() + if err != nil { + return nil, err + } + + var wg sync.WaitGroup + response := []dto.WorkspaceDTO{} + + for i, ws := range workspaces { + response = append(response, dto.WorkspaceDTO{WorkspaceViewDTO: *ws}) + if !verbose { + continue + } + + wg.Add(1) + go func(i int) { + defer wg.Done() + + target, err := s.targetStore.Find(ws.TargetId) + if err != nil { + log.Error(fmt.Errorf("failed to get target for %s", ws.TargetId)) + return + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + log.Error(fmt.Errorf("failed to get target config for %s", target.TargetConfig)) + return + } + + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + resultCh := make(chan provisioner.WorkspaceInfoResult, 1) + + go func() { + targetInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, targetConfig) + resultCh <- provisioner.WorkspaceInfoResult{Info: targetInfo, Err: err} + }() + + select { + case res := <-resultCh: + if res.Err != nil { + log.Error(fmt.Errorf("failed to get target info for %s: %v", ws.Name, res.Err)) + return + } + + response[i].Info = res.Info + case <-ctx.Done(): + if errors.Is(ctx.Err(), context.DeadlineExceeded) { + log.Warn(fmt.Sprintf("timeout getting target info for %s", ws.Name)) + } else { + log.Warn(fmt.Sprintf("cancelled getting target info for %s", ws.Name)) + } + } + }(i) + } + + wg.Wait() + return response, nil +} diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go new file mode 100644 index 0000000000..7ac100e207 --- /dev/null +++ b/pkg/server/workspaces/remove.go @@ -0,0 +1,117 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/workspace" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId string) error { + ws, err := s.workspaceStore.Find(workspaceId) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, ErrWorkspaceNotFound) + } + + log.Infof("Destroying workspace %s", ws.Name) + + target, err := s.targetStore.Find(ws.TargetId) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, err) + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, err) + } + + err = s.provisioner.DestroyWorkspace(&ws.Workspace, targetConfig) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, err) + } + + err = s.apiKeyService.Revoke(fmt.Sprintf("ws-%s", ws.Id)) + if err != nil { + // Should not fail the whole operation if the API key cannot be revoked + log.Error(err) + } + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) + err = workspaceLogger.Cleanup() + if err != nil { + // Should not fail the whole operation if the workspace logger cannot be cleaned up + log.Error(err) + } + + err = s.workspaceStore.Delete(&ws.Workspace) + + return s.handleRemoveError(ctx, &ws.Workspace, err) +} + +// ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. +func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { + ws, err := s.workspaceStore.Find(workspaceId) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, ErrWorkspaceNotFound) + } + + log.Infof("Destroying workspace %s", ws.Name) + + target, err := s.targetStore.Find(ws.TargetId) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, err) + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return s.handleRemoveError(ctx, &ws.Workspace, err) + } + + err = s.provisioner.DestroyWorkspace(&ws.Workspace, targetConfig) + if err != nil { + log.Error(err) + } + + err = s.apiKeyService.Revoke(fmt.Sprintf("ws-%s", ws.Id)) + if err != nil { + // Should not fail the whole operation if the API key cannot be revoked + log.Error(err) + } + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) + err = workspaceLogger.Cleanup() + if err != nil { + // Should not fail the whole operation if the workspace logger cannot be cleaned up + log.Error(err) + } + + err = s.workspaceStore.Delete(&ws.Workspace) + + return s.handleRemoveError(ctx, &ws.Workspace, err) +} + +func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *workspace.Workspace, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) + event := telemetry.ServerEventWorkspaceDestroyed + if err != nil { + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventWorkspaceDestroyError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(err) + } + + return err +} diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go new file mode 100644 index 0000000000..97899ca668 --- /dev/null +++ b/pkg/server/workspaces/service.go @@ -0,0 +1,119 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "io" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/apikeys" + "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/server/workspaceconfig" + "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/workspace" +) + +type IWorkspaceService interface { + CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*workspace.WorkspaceViewDTO, error) + GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) + ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) + StartWorkspace(ctx context.Context, workspaceId string) error + StopWorkspace(ctx context.Context, workspaceId string) error + RemoveWorkspace(ctx context.Context, workspaceId string) error + ForceRemoveWorkspace(ctx context.Context, workspaceId string) error + + GetWorkspaceLogReader(workspaceId string) (io.Reader, error) + SetWorkspaceState(workspaceId string, state *workspace.WorkspaceState) (*workspace.WorkspaceViewDTO, error) +} + +type targetStore interface { + Find(idOrName string) (*target.Target, error) +} + +type targetConfigStore interface { + Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) +} + +type WorkspaceServiceConfig struct { + WorkspaceStore workspace.Store + TargetStore targetStore + TargetConfigStore targetConfigStore + ContainerRegistryService containerregistries.IContainerRegistryService + BuildService builds.IBuildService + WorkspaceConfigService workspaceconfig.IWorkspaceConfigService + ServerApiUrl string + ServerUrl string + ServerVersion string + Provisioner provisioner.IProvisioner + DefaultWorkspaceImage string + DefaultWorkspaceUser string + BuilderImage string + ApiKeyService apikeys.IApiKeyService + LoggerFactory logs.LoggerFactory + GitProviderService gitproviders.IGitProviderService + TelemetryService telemetry.TelemetryService +} + +func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { + return &WorkspaceService{ + workspaceStore: config.WorkspaceStore, + targetStore: config.TargetStore, + targetConfigStore: config.TargetConfigStore, + containerRegistryService: config.ContainerRegistryService, + buildService: config.BuildService, + workspaceConfigService: config.WorkspaceConfigService, + serverApiUrl: config.ServerApiUrl, + serverUrl: config.ServerUrl, + serverVersion: config.ServerVersion, + defaultWorkspaceImage: config.DefaultWorkspaceImage, + defaultWorkspaceUser: config.DefaultWorkspaceUser, + builderImage: config.BuilderImage, + provisioner: config.Provisioner, + loggerFactory: config.LoggerFactory, + apiKeyService: config.ApiKeyService, + gitProviderService: config.GitProviderService, + telemetryService: config.TelemetryService, + } +} + +type WorkspaceService struct { + workspaceStore workspace.Store + targetStore targetStore + targetConfigStore targetConfigStore + containerRegistryService containerregistries.IContainerRegistryService + buildService builds.IBuildService + workspaceConfigService workspaceconfig.IWorkspaceConfigService + provisioner provisioner.IProvisioner + apiKeyService apikeys.IApiKeyService + serverApiUrl string + serverUrl string + serverVersion string + defaultWorkspaceImage string + defaultWorkspaceUser string + builderImage string + loggerFactory logs.LoggerFactory + gitProviderService gitproviders.IGitProviderService + telemetryService telemetry.TelemetryService +} + +func (s *WorkspaceService) SetWorkspaceState(workspaceId string, state *workspace.WorkspaceState) (*workspace.WorkspaceViewDTO, error) { + ws, err := s.workspaceStore.Find(workspaceId) + if err != nil { + return nil, ErrWorkspaceNotFound + } + + ws.State = state + return ws, s.workspaceStore.Save(&ws.Workspace) +} + +func (s *WorkspaceService) GetWorkspaceLogReader(workspaceId string) (io.Reader, error) { + return s.loggerFactory.CreateWorkspaceLogReader(workspaceId) +} diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go new file mode 100644 index 0000000000..64f3d8c5ac --- /dev/null +++ b/pkg/server/workspaces/service_test.go @@ -0,0 +1,353 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces_test + +import ( + "context" + "fmt" + "testing" + "time" + + t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" + t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" + "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" + t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/workspace" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +const serverApiUrl = "http://localhost:3986" +const serverUrl = "http://localhost:3987" +const serverVersion = "0.0.0-test" +const defaultWorkspaceUser = "daytona" +const defaultWorkspaceImage = "daytonaio/workspace-project:latest" + +var targetConfig = provider.TargetConfig{ + Name: "test-target-config", + ProviderInfo: provider.ProviderInfo{ + Name: "test-provider", + Version: "test", + }, + Options: "test-options", +} +var gitProviderConfigId = "github" + +var baseApiUrl = "https://api.github.com" + +var gitProviderConfig = gitprovider.GitProviderConfig{ + Id: "github", + ProviderId: gitProviderConfigId, + Alias: "test-alias", + Username: "test-username", + Token: "test-token", + BaseApiUrl: &baseApiUrl, +} + +var tg = &target.Target{ + Id: "123", + Name: "test", + TargetConfig: targetConfig.Name, +} + +var createWorkspaceDTO = dto.CreateWorkspaceDTO{ + Id: "123", + Name: "workspace1", + GitProviderConfigId: &gitProviderConfig.Id, + Source: dto.CreateWorkspaceSourceDTO{ + Repository: &gitprovider.GitRepository{ + Id: "123", + Url: "https://github.com/daytonaio/daytona", + Name: "daytona", + Branch: "main", + Sha: "sha1", + }, + }, + Image: util.Pointer(defaultWorkspaceImage), + User: util.Pointer(defaultWorkspaceUser), + TargetId: tg.Id, +} + +var workspaceInfo = workspace.WorkspaceInfo{ + Name: createWorkspaceDTO.Name, + Created: "1 min ago", + IsRunning: true, + ProviderMetadata: "provider-metadata-test", + TargetId: "123", +} + +var ws *workspace.Workspace + +func TestTargetService(t *testing.T) { + ctx := context.Background() + ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test") + + targetStore := t_targets.NewInMemoryTargetStore() + err := targetStore.Save(tg) + require.Nil(t, err) + + workspaceStore := t_workspaces.NewInMemoryWorkspaceStore() + + containerRegistryService := mocks.NewMockContainerRegistryService() + + workspaceConfigService := mocks.NewMockWorkspaceConfigService() + + targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() + + err = targetConfigStore.Save(&targetConfig) + require.Nil(t, err) + + apiKeyService := mocks.NewMockApiKeyService() + gitProviderService := mocks.NewMockGitProviderService() + mockProvisioner := mocks.NewMockProvisioner() + + tgLogsDir := t.TempDir() + buildLogsDir := t.TempDir() + + service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ + TargetStore: targetStore, + WorkspaceStore: workspaceStore, + TargetConfigStore: targetConfigStore, + ServerApiUrl: serverApiUrl, + ServerUrl: serverUrl, + ContainerRegistryService: containerRegistryService, + WorkspaceConfigService: workspaceConfigService, + DefaultWorkspaceImage: defaultWorkspaceImage, + DefaultWorkspaceUser: defaultWorkspaceUser, + ApiKeyService: apiKeyService, + Provisioner: mockProvisioner, + LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), + GitProviderService: gitProviderService, + }) + + t.Run("CreateWorkspace", func(t *testing.T) { + var containerRegistry *containerregistry.ContainerRegistry + + containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) + + gitProviderService.On("GetLastCommitSha", createWorkspaceDTO.Source.Repository).Return("123", nil) + + apiKeyService.On("Generate", apikey.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) + + ws := &workspace.Workspace{ + Name: createWorkspaceDTO.Name, + Image: *createWorkspaceDTO.Image, + User: *createWorkspaceDTO.User, + BuildConfig: createWorkspaceDTO.BuildConfig, + Repository: createWorkspaceDTO.Source.Repository, + ApiKey: createWorkspaceDTO.Name, + GitProviderConfigId: createWorkspaceDTO.GitProviderConfigId, + TargetId: createWorkspaceDTO.Id, + } + + ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ + ApiUrl: serverApiUrl, + ServerUrl: serverUrl, + ServerVersion: serverVersion, + ClientId: "test", + }, false) + + mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ + Workspace: ws, + TargetConfig: &targetConfig, + ContainerRegistry: containerRegistry, + GitProviderConfig: &gitProviderConfig, + BuilderImage: defaultWorkspaceImage, + BuilderImageContainerRegistry: containerRegistry, + }).Return(nil) + mockProvisioner.On("StartWorkspace", provisioner.WorkspaceParams{ + Workspace: ws, + TargetConfig: &targetConfig, + ContainerRegistry: containerRegistry, + GitProviderConfig: &gitProviderConfig, + BuilderImage: defaultWorkspaceImage, + BuilderImageContainerRegistry: containerRegistry, + }).Return(nil) + + gitProviderService.On("GetConfig", "github").Return(&gitProviderConfig, nil) + + workspace, err := service.CreateWorkspace(ctx, createWorkspaceDTO) + + require.Nil(t, err) + require.NotNil(t, workspace) + + ws = &workspace.Workspace + ws.EnvVars = nil + + workspaceEquals(t, createWorkspaceDTO, &workspace.Workspace, defaultWorkspaceImage) + }) + + t.Run("CreateWorkspace fails when workspace already exists", func(t *testing.T) { + _, err := service.CreateWorkspace(ctx, createWorkspaceDTO) + require.NotNil(t, err) + require.Equal(t, workspaces.ErrWorkspaceAlreadyExists, err) + }) + + t.Run("CreateWorkspace fails name validation", func(t *testing.T) { + invalidWorkspaceRequest := createWorkspaceDTO + invalidWorkspaceRequest.Name = "invalid name" + + _, err := service.CreateWorkspace(ctx, invalidWorkspaceRequest) + require.NotNil(t, err) + require.Equal(t, workspaces.ErrInvalidWorkspaceName, err) + }) + + t.Run("GetWorkspace", func(t *testing.T) { + mockProvisioner.On("GetWorkspaceInfo", mock.Anything, ws, &targetConfig).Return(&workspaceInfo, nil) + + w, err := service.GetWorkspace(ctx, ws.Id, true) + + require.Nil(t, err) + require.NotNil(t, w) + + workspaceDtoEquals(t, createWorkspaceDTO, *w, workspaceInfo, defaultWorkspaceImage, true) + }) + + t.Run("GetWorkspace fails when workspace not found", func(t *testing.T) { + _, err := service.GetWorkspace(ctx, "invalid-id", true) + require.NotNil(t, err) + require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + }) + + t.Run("ListWorkspaces", func(t *testing.T) { + verbose := false + + workspaces, err := service.ListWorkspaces(ctx, verbose) + + require.Nil(t, err) + require.Len(t, workspaces, 1) + + workspaceDtoEquals(t, createWorkspaceDTO, workspaces[0], workspaceInfo, defaultWorkspaceImage, verbose) + }) + + t.Run("ListWorkspaces - verbose", func(t *testing.T) { + t.Skip("Need to figure out how to test the ListWorkspaces goroutine") + + verbose := true + mockProvisioner.On("GetWorkspaceInfo", mock.Anything, ws, &targetConfig).Return(&workspaceInfo, nil) + + workspaces, err := service.ListWorkspaces(ctx, verbose) + + require.Nil(t, err) + require.Len(t, workspaces, 1) + + workspaceDtoEquals(t, createWorkspaceDTO, workspaces[0], workspaceInfo, defaultWorkspaceImage, verbose) + }) + + t.Run("StartWorkspace", func(t *testing.T) { + mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + + err := service.StartWorkspace(ctx, createWorkspaceDTO.Id) + + require.Nil(t, err) + }) + + t.Run("StopWorkspace", func(t *testing.T) { + mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) + + err := service.StopWorkspace(ctx, createWorkspaceDTO.Id) + + require.Nil(t, err) + }) + + t.Run("RemoveWorkspace", func(t *testing.T) { + mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + apiKeyService.On("Revoke", mock.Anything).Return(nil) + + err := service.RemoveWorkspace(ctx, createWorkspaceDTO.Id) + + require.Nil(t, err) + + _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, true) + require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + }) + + t.Run("ForceRemoveWorkspace", func(t *testing.T) { + err := workspaceStore.Save(ws) + require.Nil(t, err) + + mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + apiKeyService.On("Revoke", mock.Anything).Return(nil) + + err = service.ForceRemoveWorkspace(ctx, createWorkspaceDTO.Id) + + require.Nil(t, err) + + _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, true) + require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + }) + + t.Run("SetWorkspaceState", func(t *testing.T) { + err := workspaceStore.Save(ws) + require.Nil(t, err) + + updatedAt := time.Now().Format(time.RFC1123) + res, err := service.SetWorkspaceState(createWorkspaceDTO.Id, &workspace.WorkspaceState{ + UpdatedAt: updatedAt, + Uptime: 10, + GitStatus: &workspace.GitStatus{ + CurrentBranch: "main", + }, + }) + require.Nil(t, err) + + require.Nil(t, err) + require.Equal(t, "main", res.State.GitStatus.CurrentBranch) + }) + + t.Cleanup(func() { + apiKeyService.AssertExpectations(t) + mockProvisioner.AssertExpectations(t) + }) +} + +func workspaceEquals(t *testing.T, req dto.CreateWorkspaceDTO, ws *workspace.Workspace, workspaceImage string) { + t.Helper() + + // TODO: add more assertions + require.Equal(t, req.Id, ws.Id) + require.Equal(t, req.Name, ws.Name) + require.Equal(t, req.TargetId, ws.TargetId) + require.Equal(t, ws.Image, workspaceImage) + require.Equal(t, ws.User, "daytona") +} + +func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto.WorkspaceDTO, workspaceInfo workspace.WorkspaceInfo, workspaceImage string, verbose bool) { + t.Helper() + + require.Equal(t, req.Id, workspace.Id) + require.Equal(t, req.Name, workspace.Name) + + if verbose { + require.Equal(t, workspace.Info.Name, workspaceInfo.Name) + require.Equal(t, workspace.Info.ProviderMetadata, workspaceInfo.ProviderMetadata) + } else { + require.Nil(t, workspace.Info) + } + + require.Equal(t, req.Name, workspace.Name) + require.Equal(t, req.Source.Repository.Id, workspace.Repository.Id) + require.Equal(t, req.Source.Repository.Url, workspace.Repository.Url) + require.Equal(t, req.Source.Repository.Name, workspace.Repository.Name) + require.Equal(t, workspace.ApiKey, workspace.Name) + require.Equal(t, workspace.Image, workspaceImage) + + if verbose { + require.Equal(t, workspace.Info.Name, workspaceInfo.Name) + require.Equal(t, workspace.Info.Created, workspaceInfo.Created) + require.Equal(t, workspace.Info.IsRunning, workspaceInfo.IsRunning) + require.Equal(t, workspace.Info.ProviderMetadata, workspaceInfo.ProviderMetadata) + } +} diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go new file mode 100644 index 0000000000..44280fbee4 --- /dev/null +++ b/pkg/server/workspaces/start.go @@ -0,0 +1,114 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "fmt" + "io" + + "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/workspace" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { + ws, err := s.workspaceStore.Find(workspaceId) + if err != nil { + return s.handleStartError(ctx, &ws.Workspace, ErrWorkspaceNotFound) + } + + target, err := s.targetStore.Find(ws.TargetId) + if err != nil { + return s.handleStartError(ctx, &ws.Workspace, err) + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return s.handleStartError(ctx, &ws.Workspace, err) + } + + workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) + defer workspaceLogger.Close() + + workspaceToStart := ws.Workspace + workspaceToStart.EnvVars = workspace.GetWorkspaceEnvVars(&ws.Workspace, workspace.WorkspaceEnvVarParams{ + ApiUrl: s.serverApiUrl, + ServerUrl: s.serverUrl, + ServerVersion: s.serverVersion, + ClientId: telemetry.ClientId(ctx), + }, telemetry.TelemetryEnabled(ctx)) + + err = s.startWorkspace(&workspaceToStart, targetConfig, workspaceLogger) + if err != nil { + return s.handleStartError(ctx, &ws.Workspace, err) + } + + return s.handleStartError(ctx, &ws.Workspace, err) +} + +func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, targetConfig *provider.TargetConfig, logger io.Writer) error { + logger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) + + cr, err := s.containerRegistryService.FindByImageName(w.Image) + if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + return err + } + + builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) + if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + return err + } + + var gc *gitprovider.GitProviderConfig + + if w.GitProviderConfigId != nil { + gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) + if err != nil && !gitprovider.IsGitProviderNotFound(err) { + return err + } + } + + err = s.provisioner.StartWorkspace(provisioner.WorkspaceParams{ + Workspace: w, + TargetConfig: targetConfig, + ContainerRegistry: cr, + GitProviderConfig: gc, + BuilderImage: s.builderImage, + BuilderImageContainerRegistry: builderCr, + }) + if err != nil { + return err + } + + logger.Write([]byte(fmt.Sprintf("Workspace %s started\n", w.Name))) + + return nil +} + +func (s *WorkspaceService) handleStartError(ctx context.Context, w *workspace.Workspace, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) + event := telemetry.ServerEventWorkspaceStarted + if err != nil { + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventWorkspaceStartError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(err) + } + + return err +} diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go new file mode 100644 index 0000000000..e0def5ba99 --- /dev/null +++ b/pkg/server/workspaces/stop.go @@ -0,0 +1,66 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + "time" + + "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/workspace" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { + ws, err := s.workspaceStore.Find(workspaceId) + if err != nil { + return s.handleStopError(ctx, &ws.Workspace, ErrWorkspaceNotFound) + } + + target, err := s.targetStore.Find(ws.TargetId) + if err != nil { + return s.handleStopError(ctx, &ws.Workspace, err) + } + + targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + if err != nil { + return s.handleStopError(ctx, &ws.Workspace, err) + } + + // todo: go routines + err = s.provisioner.StopWorkspace(&ws.Workspace, targetConfig) + if err != nil { + return s.handleStopError(ctx, &ws.Workspace, err) + } + if ws.State != nil { + ws.State.Uptime = 0 + ws.State.UpdatedAt = time.Now().Format(time.RFC1123) + } + + err = s.workspaceStore.Save(&ws.Workspace) + + return s.handleStopError(ctx, &ws.Workspace, err) +} + +func (s *WorkspaceService) handleStopError(ctx context.Context, w *workspace.Workspace, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) + event := telemetry.ServerEventWorkspaceStopped + if err != nil { + telemetryProps["error"] = err.Error() + event = telemetry.ServerEventWorkspaceStopError + } + telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + if telemetryError != nil { + log.Trace(err) + } + + return err +} diff --git a/pkg/target/target.go b/pkg/target/target.go index f31cdfd00f..33dfd9a682 100644 --- a/pkg/target/target.go +++ b/pkg/target/target.go @@ -3,36 +3,19 @@ package target -import ( - "errors" - - "github.com/daytonaio/daytona/pkg/target/workspace" -) - type Target struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - Workspaces []*workspace.Workspace `json:"workspaces" validate:"required"` - TargetConfig string `json:"targetConfig" validate:"required"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"-"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfig string `json:"targetConfig" validate:"required"` + ApiKey string `json:"-"` + EnvVars map[string]string `json:"-"` } // @name Target type TargetInfo struct { - Name string `json:"name" validate:"required"` - Workspaces []*workspace.WorkspaceInfo `json:"workspaces" validate:"required"` - ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` + Name string `json:"name" validate:"required"` + ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` } // @name TargetInfo -func (t *Target) GetWorkspace(workspaceName string) (*workspace.Workspace, error) { - for _, workspace := range t.Workspaces { - if workspace.Name == workspaceName { - return workspace, nil - } - } - return nil, errors.New("workspace not found") -} - type TargetEnvVarParams struct { ApiUrl string ServerUrl string diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index c9e9074ec1..8ff064ef5e 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -11,6 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/workspace" ) type ServerEvent string @@ -31,6 +32,16 @@ const ( ServerEventTargetDestroyError ServerEvent = "server_target_destroyed_error" ServerEventTargetStartError ServerEvent = "server_target_started_error" ServerEventTargetStopError ServerEvent = "server_target_stopped_error" + + // Workspace events + ServerEventWorkspaceCreated ServerEvent = "server_workspace_created" + ServerEventWorkspaceDestroyed ServerEvent = "server_workspace_destroyed" + ServerEventWorkspaceStarted ServerEvent = "server_workspace_started" + ServerEventWorkspaceStopped ServerEvent = "server_workspace_stopped" + ServerEventWorkspaceCreateError ServerEvent = "server_workspace_created_error" + ServerEventWorkspaceDestroyError ServerEvent = "server_workspace_destroyed_error" + ServerEventWorkspaceStartError ServerEvent = "server_workspace_started_error" + ServerEventWorkspaceStopError ServerEvent = "server_workspace_stopped_error" ) func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) map[string]interface{} { @@ -44,30 +55,6 @@ func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfi if target != nil { props["target_id"] = target.Id - props["target_n_workspaces"] = len(target.Workspaces) - publicRepos := []string{} - publicImages := []string{} - builders := map[string]int{} - - for _, workspace := range target.Workspaces { - if isImagePublic(workspace.Image) { - publicImages = append(publicImages, workspace.Image) - } - if workspace.Repository != nil && isPublic(workspace.Repository.Url) { - publicRepos = append(publicRepos, workspace.Repository.Url) - } - if workspace.BuildConfig == nil { - builders["none"]++ - } else if workspace.BuildConfig.Devcontainer != nil { - builders["devcontainer"]++ - } else { - builders["automatic"]++ - } - } - - props["target_public_repos"] = publicRepos - props["target_public_images"] = publicImages - props["target_builders"] = builders } if targetConfig != nil { @@ -79,6 +66,31 @@ func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfi return props } +func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace) map[string]interface{} { + props := map[string]interface{}{} + + if workspace == nil { + return props + } + + if isImagePublic(workspace.Image) { + props["workspace_image"] = workspace.Image + } + if workspace.Repository != nil && isPublic(workspace.Repository.Url) { + props["workspace_repository"] = workspace.Repository.Url + } + + if workspace.BuildConfig == nil { + props["workspace_builder"] = "none" + } else if workspace.BuildConfig.Devcontainer != nil { + props["workspace_builder"] = "devcontainer" + } else { + props["workspace_builder"] = "automatic" + } + + return props +} + func isImagePublic(imageName string) bool { if strings.Count(imageName, "/") < 2 { if strings.Count(imageName, "/") == 0 { diff --git a/pkg/views/ide/start_target.go b/pkg/views/ide/start_target.go index 140e5800ec..92d56004f7 100644 --- a/pkg/views/ide/start_target.go +++ b/pkg/views/ide/start_target.go @@ -11,13 +11,13 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func RunStartTargetForm(targetName string) bool { +func RunStartWorkspaceForm(workspaceName string) bool { confirmCheck := true form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title(fmt.Sprintf("The target %s is stopped, would you like to start it?", targetName)). + Title(fmt.Sprintf("The workspace %s is stopped, would you like to start it?", workspaceName)). Value(&confirmCheck), ), ).WithTheme(views.GetCustomTheme()) diff --git a/pkg/views/logs/display.go b/pkg/views/logs/display.go index bd4d6d456b..7ff17eea64 100644 --- a/pkg/views/logs/display.go +++ b/pkg/views/logs/display.go @@ -12,15 +12,16 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -var FIRST_WORKSPACE_INDEX = 0 -var STATIC_INDEX = -1 -var TARGET_PREFIX = "TARGET" -var PROVIDER_PREFIX = "PROVIDER" +const FIRST_WORKSPACE_INDEX = 0 +const STATIC_INDEX = -1 +const TARGET_PREFIX = "TARGET" +const PROVIDER_PREFIX = "PROVIDER" var longestPrefixLength = len(TARGET_PREFIX) -var maxPrefixLength = 20 -var prefixDelimiter = " | " -var prefixPadding = " " + +const maxPrefixLength = 20 +const prefixDelimiter = " | " +const prefixPadding = " " func DisplayLogs(logEntriesChan <-chan logs.LogEntry, index int) { for logEntry := range logEntriesChan { @@ -36,13 +37,13 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { if logEntry.WorkspaceName != nil { prefixText = *logEntry.WorkspaceName - } - - if logEntry.BuildId != nil { + } else if logEntry.BuildId != nil { prefixText = *logEntry.BuildId + } else if logEntry.TargetName != nil { + prefixText = *logEntry.TargetName } - if index == STATIC_INDEX { + if index == STATIC_INDEX && prefixText == "" { if logEntry.Source == string(logs.LogSourceProvider) { prefixText = PROVIDER_PREFIX } else { @@ -53,7 +54,7 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { prefix := lipgloss.NewStyle().Foreground(prefixColor).Bold(true).Render(formatPrefixText(prefixText)) if index == STATIC_INDEX { - if logEntry.Source == string(logs.LogSourceProvider) { + if logEntry.Source == string(logs.LogSourceProvider) && prefixText == PROVIDER_PREFIX { line = fmt.Sprintf("%s%s\033[1m%s\033[0m", prefixPadding, prefix, line) } else { line = fmt.Sprintf("%s%s%s \033[1m%s\033[0m", prefixPadding, prefix, views.CheckmarkSymbol, line) diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index 45ea1de940..9d53b742e3 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -6,7 +6,6 @@ package info import ( "fmt" "os" - "strings" "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/pkg/apiclient" @@ -23,34 +22,15 @@ var propertyValueStyle = lipgloss.NewStyle(). Foreground(views.Light). Bold(true) -func Render(target *apiclient.TargetDTO, ide string, forceUnstyled bool) { - var isCreationView bool +func Render(target *apiclient.TargetDTO, forceUnstyled bool) { var output string nameLabel := "Name" - if ide != "" { - isCreationView = true - } - - if isCreationView { - nameLabel = "Target" - } - output += "\n" output += getInfoLine(nameLabel, target.Name) + "\n" output += getInfoLine("ID", target.Id) + "\n" - if isCreationView { - output += getInfoLine("Editor", ide) + "\n" - } - - if len(target.Workspaces) == 1 { - output += getSingleWorkspaceOutput(&target.Workspaces[0], isCreationView) - } else { - output += getWorkspacesOutputs(target.Workspaces, isCreationView) - } - terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) if err != nil { fmt.Println(output) @@ -61,152 +41,23 @@ func Render(target *apiclient.TargetDTO, ide string, forceUnstyled bool) { return } - if !isCreationView { - output = views.GetStyledMainTitle("Target Info") + "\n" + output - } - - renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth), isCreationView) + renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth)) } func renderUnstyledInfo(output string) { fmt.Println(output) } -func renderTUIView(output string, width int, isCreationView bool) { +func renderTUIView(output string, width int) { output = lipgloss.NewStyle().PaddingLeft(3).Render(output) content := lipgloss. NewStyle().Width(width). Render(output) - if !isCreationView { - content = lipgloss.NewStyle().Margin(1, 0).Render(content) - } - fmt.Println(content) } -func getSingleWorkspaceOutput(workspace *apiclient.Workspace, isCreationView bool) string { - var output string - var repositoryUrl string - - repositoryUrl = workspace.Repository.Url - repositoryUrl = strings.TrimPrefix(repositoryUrl, "https://") - repositoryUrl = strings.TrimPrefix(repositoryUrl, "http://") - - if workspace.State != nil { - output += getInfoLineState("State", workspace.State) + "\n" - output += getInfoLineGitStatus("Branch", workspace.State.GitStatus) + "\n" - } - - output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) - - if !isCreationView { - output += getInfoLine("Target Config", workspace.TargetConfig) + "\n" - } - output += getInfoLine("Repository", repositoryUrl) - - if !isCreationView { - output += "\n" - output += getInfoLine("Workspace", workspace.Name) - } - - return output -} - -func getWorkspacesOutputs(workspaces []apiclient.Workspace, isCreationView bool) string { - var output string - for i, workspace := range workspaces { - output += getInfoLine(fmt.Sprintf("Workspace #%d", i+1), workspace.Name) - output += getInfoLineState("State", workspace.State) - if workspace.State != nil { - output += getInfoLineGitStatus("Branch", workspace.State.GitStatus) - } - output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) - - if !isCreationView { - output += getInfoLine("Target Config", workspace.TargetConfig) - } - output += getInfoLine("Repository", workspace.Repository.Url) - if workspace.Name != workspaces[len(workspaces)-1].Name { - output += "\n" - } - } - return output -} - func getInfoLine(key, value string) string { return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + propertyValueStyle.Render(value) + "\n" } - -func getInfoLineState(key string, state *apiclient.WorkspaceState) string { - var uptime int - var stateProperty string - - if state == nil { - uptime = 0 - } else { - uptime = int(state.Uptime) - } - - if uptime == 0 { - stateProperty = propertyValueStyle.Foreground(views.Gray).Render("STOPPED") - } else { - stateProperty = propertyValueStyle.Foreground(views.Green).Render("RUNNING") - } - - return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + stateProperty + propertyValueStyle.Foreground(views.Light).Render("\n") -} - -func getInfoLineGitStatus(key string, status *apiclient.GitStatus) string { - if status == nil { - return "" - } - - output := propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) - output += propertyNameStyle.Foreground(views.Gray).Render(fmt.Sprintf("%-*s", propertyNameWidth, status.CurrentBranch)) - - changesOutput := "" - if status.FileStatus != nil { - filesNum := len(status.FileStatus) - if filesNum == 1 { - changesOutput = " (1 uncommitted change)" - } else if filesNum > 1 { - changesOutput = fmt.Sprintf(" (%d uncommitted changes)", filesNum) - } - } - - unpushedOutput := "" - - if status.Ahead != nil && *status.Ahead > 0 { - if *status.Ahead == 1 { - unpushedOutput += " (1 commit ahead)" - } else { - unpushedOutput += fmt.Sprintf(" (%d commits ahead)", *status.Ahead) - } - } - - if status.Behind != nil && *status.Behind > 0 { - if *status.Behind == 1 { - unpushedOutput += " (1 commit behind)" - } else { - unpushedOutput += fmt.Sprintf(" (%d commits behind)", *status.Behind) - } - } - - branchPublishedOutput := "" - if !*status.BranchPublished { - branchPublishedOutput = " (branch not published)" - } - - output += changesOutput + unpushedOutput + branchPublishedOutput + propertyValueStyle.Foreground(views.Light).Render("\n") - - return output -} - -func getInfoLinePrNumber(PrNumber *int32, repo apiclient.GitRepository, state *apiclient.WorkspaceState) string { - if PrNumber != nil && (state == nil || state.GitStatus.CurrentBranch == repo.Branch) { - return getInfoLine("PR Number", fmt.Sprintf("#%d", *PrNumber)) + "\n" - } - return "" -} diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index 1bf11590b4..8dbf1b3951 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -5,7 +5,6 @@ package list import ( "fmt" - "sort" "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/internal/util" @@ -17,59 +16,20 @@ import ( type RowData struct { Name string - Repository string TargetConfig string - Status string - Created string - Branch string } -func ListTargets(targetList []apiclient.TargetDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { +func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileName string) { if len(targetList) == 0 { views_util.NotifyEmptyTargetList(true) return } - SortTargets(&targetList, verbose) + headers := []string{"Target", "Target Config"} - headers := []string{"Target", "Repository", "Target Config", "Status", "Created", "Branch"} - - data := [][]string{} - - for _, target := range targetList { - var rowData *RowData - var row []string - - if len(target.Workspaces) == 1 { - rowData = getTargetTableRowData(target, specifyGitProviders) - row = getRowFromRowData(*rowData, false) - data = append(data, row) - } else { - row = getRowFromRowData(RowData{Name: target.Name}, true) - data = append(data, row) - for _, workspace := range target.Workspaces { - rowData = getWorkspaceTableRowData(target, workspace, specifyGitProviders) - if rowData == nil { - continue - } - row = getRowFromRowData(*rowData, false) - data = append(data, row) - } - } - } - - if !verbose { - headers = headers[:len(headers)-2] - for value := range data { - data[value] = data[value][:len(data[value])-2] - } - } else { - // Temporarily hiding the branch column - headers = headers[:len(headers)-1] - for value := range data { - data[value] = data[value][:len(data[value])-1] - } - } + data := util.ArrayMap(targetList, func(target apiclient.TargetDTO) []string { + return getRowFromRowData(RowData{Name: target.Name, TargetConfig: target.TargetConfig}) + }) footer := lipgloss.NewStyle().Foreground(views.LightGray).Render(views.GetListFooter(activeProfileName, &views.Padding{})) @@ -82,112 +42,17 @@ func ListTargets(targetList []apiclient.TargetDTO, specifyGitProviders bool, ver func renderUnstyledList(targetList []apiclient.TargetDTO) { for _, target := range targetList { - info_view.Render(&target, "", true) + info_view.Render(&target, true) if target.Id != targetList[len(targetList)-1].Id { fmt.Printf("\n%s\n\n", views.SeparatorString) } - } } -func getRowFromRowData(rowData RowData, isMultiWorkspaceAccordion bool) []string { - var state string - if rowData.Status == "" { - state = views.InactiveStyle.Render("STOPPED") - } else { - state = views.ActiveStyle.Render("RUNNING") - } - - if isMultiWorkspaceAccordion { - return []string{rowData.Name, "", "", "", "", ""} - } - - row := []string{ +func getRowFromRowData(rowData RowData) []string { + return []string{ views.NameStyle.Render(rowData.Name), - views.DefaultRowDataStyle.Render(rowData.Repository), views.DefaultRowDataStyle.Render(rowData.TargetConfig), - state, - views.DefaultRowDataStyle.Render(rowData.Created), - views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(rowData.Branch)), - } - - if rowData.Status != "" { - row[3] = fmt.Sprintf("%s %s", state, views.DefaultRowDataStyle.Render(fmt.Sprintf("(%s)", rowData.Status))) - } - - return row -} - -func SortTargets(targetList *[]apiclient.TargetDTO, verbose bool) { - if verbose { - sort.Slice(*targetList, func(i, j int) bool { - t1 := (*targetList)[i] - t2 := (*targetList)[j] - if t1.Info == nil || t2.Info == nil || t1.Info.Workspaces == nil || t2.Info.Workspaces == nil { - return true - } - if len(t1.Info.Workspaces) == 0 || len(t2.Info.Workspaces) == 0 { - return true - } - return t1.Info.Workspaces[0].Created > t2.Info.Workspaces[0].Created - }) - return } - - sort.Slice(*targetList, func(i, j int) bool { - t1 := (*targetList)[i] - t2 := (*targetList)[j] - if len(t1.Workspaces) == 0 || len(t2.Workspaces) == 0 || t1.Workspaces[0].State == nil || t2.Workspaces[0].State == nil { - return true - } - return t1.Workspaces[0].State.Uptime < t2.Workspaces[0].State.Uptime - }) - -} - -func getTargetTableRowData(target apiclient.TargetDTO, specifyGitProviders bool) *RowData { - rowData := RowData{"", "", "", "", "", ""} - rowData.Name = target.Name + views_util.AdditionalPropertyPadding - if len(target.Workspaces) > 0 { - rowData.Repository = util.GetRepositorySlugFromUrl(target.Workspaces[0].Repository.Url, specifyGitProviders) - rowData.Branch = target.Workspaces[0].Repository.Branch - } - - rowData.TargetConfig = target.TargetConfig + views_util.AdditionalPropertyPadding - - if target.Info != nil && target.Info.Workspaces != nil && len(target.Info.Workspaces) > 0 { - rowData.Created = util.FormatTimestamp(target.Info.Workspaces[0].Created) - } - if len(target.Workspaces) > 0 && target.Workspaces[0].State != nil && target.Workspaces[0].State.Uptime > 0 { - rowData.Status = util.FormatUptime(target.Workspaces[0].State.Uptime) - } - return &rowData -} - -func getWorkspaceTableRowData(targetDTO apiclient.TargetDTO, workspace apiclient.Workspace, specifyGitProviders bool) *RowData { - rowData := RowData{"", "", "", "", "", ""} - rowData.Name = " └ " + workspace.Name - - rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) - rowData.Branch = workspace.Repository.Branch - - rowData.TargetConfig = workspace.TargetConfig + views_util.AdditionalPropertyPadding - - if workspace.State != nil && workspace.State.Uptime > 0 { - rowData.Status = util.FormatUptime(workspace.State.Uptime) - } - - if targetDTO.Info == nil || targetDTO.Info.Workspaces == nil { - return &rowData - } - - for _, workspaceInfo := range targetDTO.Info.Workspaces { - if workspaceInfo.Name == workspace.Name { - rowData.Created = util.FormatTimestamp(workspaceInfo.Created) - break - } - } - - return &rowData } diff --git a/pkg/views/target/selection/target.go b/pkg/views/target/selection/target.go index e8227e9869..1fa697cabc 100644 --- a/pkg/views/target/selection/target.go +++ b/pkg/views/target/selection/target.go @@ -11,10 +11,8 @@ import ( "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" - list_view "github.com/daytonaio/daytona/pkg/views/target/list" ) func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, action string) []list.Item { @@ -26,38 +24,10 @@ func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, ac for _, target := range targets { var workspacesInfo []string - if len(target.Workspaces) == 0 { - continue - } - - if len(target.Workspaces) == 1 { - workspacesInfo = append(workspacesInfo, util.GetRepositorySlugFromUrl(target.Workspaces[0].Repository.Url, true)) - } else { - for _, workspace := range target.Workspaces { - workspacesInfo = append(workspacesInfo, workspace.Name) - } - } - - // Get the time if available - uptime := "" - createdTime := "" - if target.Info != nil && target.Info.Workspaces != nil && len(target.Info.Workspaces) > 0 { - createdTime = util.FormatTimestamp(target.Info.Workspaces[0].Created) - } - if len(target.Workspaces) > 0 && target.Workspaces[0].State != nil { - if target.Workspaces[0].State.Uptime == 0 { - uptime = "STOPPED" - } else { - uptime = fmt.Sprintf("up %s", util.FormatUptime(target.Workspaces[0].State.Uptime)) - } - } - newItem := item[apiclient.TargetDTO]{ title: target.Name, id: target.Id, desc: strings.Join(workspacesInfo, ", "), - createdTime: createdTime, - uptime: uptime, targetConfig: target.TargetConfig, choiceProperty: target, } @@ -104,8 +74,6 @@ func getTargetProgramEssentials(modelTitle string, actionVerb string, targets [] } func selectTargetPrompt(targets []apiclient.TargetDTO, actionVerb string, choiceChan chan<- *apiclient.TargetDTO) { - list_view.SortTargets(&targets, true) - p := getTargetProgramEssentials("Select a Target To ", actionVerb, targets, "", false) if m, ok := p.(model[apiclient.TargetDTO]); ok && m.choice != nil { choiceChan <- m.choice @@ -123,8 +91,6 @@ func GetTargetFromPrompt(targets []apiclient.TargetDTO, actionVerb string) *apic } func selectTargetsFromPrompt(targets []apiclient.TargetDTO, actionVerb string, choiceChan chan<- []*apiclient.TargetDTO) { - list_view.SortTargets(&targets, true) - footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark target.\nPress 'enter' to %s the current/marked targets.", actionVerb)) p := getTargetProgramEssentials("Select Targets To ", actionVerb, targets, footerText, true) diff --git a/pkg/views/target/selection/view.go b/pkg/views/target/selection/view.go index 23b6464407..886c4ff8a5 100644 --- a/pkg/views/target/selection/view.go +++ b/pkg/views/target/selection/view.go @@ -19,10 +19,6 @@ import ( "golang.org/x/term" ) -var CustomRepoIdentifier = "" - -const CREATE_FROM_SAMPLE = "" - var selectedStyles = lipgloss.NewStyle(). Border(lipgloss.NormalBorder(), false, false, false, true). BorderForeground(views.Green). @@ -38,19 +34,17 @@ var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). Render type item[T any] struct { - id, title, desc, createdTime, uptime, targetConfig string - choiceProperty T - isMarked bool - isMultipleSelect bool - action string + id, title, desc, targetConfig string + choiceProperty T + isMarked bool + isMultipleSelect bool + action string } func (i item[T]) Title() string { return i.title } func (i item[T]) Id() string { return i.id } func (i item[T]) Description() string { return i.desc } func (i item[T]) FilterValue() string { return i.title } -func (i item[T]) CreatedTime() string { return i.createdTime } -func (i item[T]) Uptime() string { return i.uptime } func (i item[T]) TargetConfig() string { return i.targetConfig } type model[T any] struct { @@ -159,11 +153,6 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l Align(lipgloss.Right). Width(timeWidth) timeString := timeStyles.Render("") - if i.Uptime() != "" { - timeString = timeStyles.Render(i.Uptime()) - } else if i.CreatedTime() != "" { - timeString = timeStyles.Render(fmt.Sprintf("created %s", i.CreatedTime())) - } // Adjust styles as the user moves through the menu if isSelected { diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index a8707a5405..808b16b8b8 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -40,6 +40,13 @@ func NotifyEmptyTargetList(tip bool) { } } +func NotifyEmptyWorkspaceList(tip bool) { + views.RenderInfoMessageBold("No workspaces found") + if tip { + views.RenderTip("Use 'daytona create' to create a target") + } +} + func NotifyEmptyContainerRegistryList(tip bool) { views.RenderInfoMessageBold("No container registries found") if tip { diff --git a/pkg/views/target/create/configuration.go b/pkg/views/workspace/create/configuration.go similarity index 99% rename from pkg/views/target/create/configuration.go rename to pkg/views/workspace/create/configuration.go index 08795f987b..0048ac7340 100644 --- a/pkg/views/target/create/configuration.go +++ b/pkg/views/workspace/create/configuration.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) const ( diff --git a/pkg/views/target/create/summary.go b/pkg/views/workspace/create/summary.go similarity index 100% rename from pkg/views/target/create/summary.go rename to pkg/views/workspace/create/summary.go diff --git a/pkg/views/target/create/view.go b/pkg/views/workspace/create/view.go similarity index 100% rename from pkg/views/target/create/view.go rename to pkg/views/workspace/create/view.go diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go new file mode 100644 index 0000000000..d8880b5df8 --- /dev/null +++ b/pkg/views/workspace/info/view.go @@ -0,0 +1,184 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package info + +import ( + "fmt" + "os" + "strings" + + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +const propertyNameWidth = 16 + +var propertyNameStyle = lipgloss.NewStyle(). + Foreground(views.LightGray) + +var propertyValueStyle = lipgloss.NewStyle(). + Foreground(views.Light). + Bold(true) + +func Render(workspace *apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { + var isCreationView bool + var output string + nameLabel := "Name" + + if ide != "" { + isCreationView = true + } + + if isCreationView { + nameLabel = "Workspace" + } + + output += "\n" + output += getInfoLine(nameLabel, workspace.Name) + "\n" + + output += getInfoLine("ID", workspace.Id) + "\n" + + if isCreationView { + output += getInfoLine("Editor", ide) + "\n" + } + + terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + fmt.Println(output) + return + } + if terminalWidth < views.TUITableMinimumWidth || forceUnstyled { + renderUnstyledInfo(output) + return + } + + output += getSingleWorkspaceOutput(workspace, isCreationView) + + if !isCreationView { + output = views.GetStyledMainTitle("Workspace Info") + "\n" + output + } + + renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth), isCreationView) +} + +func renderUnstyledInfo(output string) { + fmt.Println(output) +} + +func renderTUIView(output string, width int, isCreationView bool) { + output = lipgloss.NewStyle().PaddingLeft(3).Render(output) + + content := lipgloss. + NewStyle().Width(width). + Render(output) + + if !isCreationView { + content = lipgloss.NewStyle().Margin(1, 0).Render(content) + } + + fmt.Println(content) +} + +func getSingleWorkspaceOutput(workspace *apiclient.WorkspaceDTO, isCreationView bool) string { + var output string + var repositoryUrl string + + repositoryUrl = workspace.Repository.Url + repositoryUrl = strings.TrimPrefix(repositoryUrl, "https://") + repositoryUrl = strings.TrimPrefix(repositoryUrl, "http://") + + if workspace.State != nil { + output += getInfoLineState("State", workspace.State) + "\n" + output += getInfoLineGitStatus("Branch", workspace.State.GitStatus) + "\n" + } + + output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) + + if !isCreationView { + output += getInfoLine("Target ID", workspace.TargetId) + "\n" + } + + output += getInfoLine("Repository", repositoryUrl) + + if !isCreationView { + output += "\n" + output += getInfoLine("Workspace", workspace.Name) + } + + return output +} + +func getInfoLine(key, value string) string { + return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + propertyValueStyle.Render(value) + "\n" +} + +func getInfoLineState(key string, state *apiclient.WorkspaceState) string { + var uptime int + var stateProperty string + + if state == nil { + uptime = 0 + } else { + uptime = int(state.Uptime) + } + + if uptime == 0 { + stateProperty = propertyValueStyle.Foreground(views.Gray).Render("STOPPED") + } else { + stateProperty = propertyValueStyle.Foreground(views.Green).Render("RUNNING") + } + + return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + stateProperty + propertyValueStyle.Foreground(views.Light).Render("\n") +} + +func getInfoLineGitStatus(key string, status *apiclient.GitStatus) string { + output := propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + output += propertyNameStyle.Foreground(views.Gray).Render(fmt.Sprintf("%-*s", propertyNameWidth, status.CurrentBranch)) + + changesOutput := "" + if status.FileStatus != nil { + filesNum := len(status.FileStatus) + if filesNum == 1 { + changesOutput = " (1 uncommitted change)" + } else if filesNum > 1 { + changesOutput = fmt.Sprintf(" (%d uncommitted changes)", filesNum) + } + } + + unpushedOutput := "" + + if status.Ahead != nil && *status.Ahead > 0 { + if *status.Ahead == 1 { + unpushedOutput += " (1 commit ahead)" + } else { + unpushedOutput += fmt.Sprintf(" (%d commits ahead)", *status.Ahead) + } + } + + if status.Behind != nil && *status.Behind > 0 { + if *status.Behind == 1 { + unpushedOutput += " (1 commit behind)" + } else { + unpushedOutput += fmt.Sprintf(" (%d commits behind)", *status.Behind) + } + } + + branchPublishedOutput := "" + if !*status.BranchPublished { + branchPublishedOutput = " (branch not published)" + } + + output += changesOutput + unpushedOutput + branchPublishedOutput + propertyValueStyle.Foreground(views.Light).Render("\n") + + return output +} + +func getInfoLinePrNumber(PrNumber *int32, repo apiclient.GitRepository, state *apiclient.WorkspaceState) string { + if PrNumber != nil && (state == nil || state.GitStatus.CurrentBranch == repo.Branch) { + return getInfoLine("PR Number", fmt.Sprintf("#%d", *PrNumber)) + "\n" + } + return "" +} diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go new file mode 100644 index 0000000000..a7d1122979 --- /dev/null +++ b/pkg/views/workspace/list/view.go @@ -0,0 +1,148 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package list + +import ( + "fmt" + "sort" + + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" + info_view "github.com/daytonaio/daytona/pkg/views/workspace/info" +) + +type RowData struct { + Name string + Repository string + TargetName string + Status string + Created string + Branch string +} + +func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { + if len(workspaceList) == 0 { + views_util.NotifyEmptyTargetList(true) + return + } + + SortWorkspaces(&workspaceList, verbose) + + headers := []string{"Workspace", "Repository", "Target", "Status", "Created", "Branch"} + + data := [][]string{} + + for _, target := range workspaceList { + var rowData *RowData + var row []string + + rowData = getTableRowData(target, specifyGitProviders) + row = getRowFromRowData(*rowData, false) + data = append(data, row) + } + + if !verbose { + headers = headers[:len(headers)-2] + for value := range data { + data[value] = data[value][:len(data[value])-2] + } + } else { + // Temporarily hiding the branch column + headers = headers[:len(headers)-1] + for value := range data { + data[value] = data[value][:len(data[value])-1] + } + } + + footer := lipgloss.NewStyle().Foreground(views.LightGray).Render(views.GetListFooter(activeProfileName, &views.Padding{})) + + table := views_util.GetTableView(data, headers, &footer, func() { + renderUnstyledList(workspaceList) + }) + + fmt.Println(table) +} + +func renderUnstyledList(workspaceList []apiclient.WorkspaceDTO) { + for _, target := range workspaceList { + info_view.Render(&target, "", true) + + if target.Id != workspaceList[len(workspaceList)-1].Id { + fmt.Printf("\n%s\n\n", views.SeparatorString) + } + + } +} + +func getRowFromRowData(rowData RowData, isMultiWorkspaceAccordion bool) []string { + var state string + if rowData.Status == "" { + state = views.InactiveStyle.Render("STOPPED") + } else { + state = views.ActiveStyle.Render("RUNNING") + } + + if isMultiWorkspaceAccordion { + return []string{rowData.Name, "", "", "", "", ""} + } + + row := []string{ + views.NameStyle.Render(rowData.Name), + views.DefaultRowDataStyle.Render(rowData.Repository), + views.DefaultRowDataStyle.Render(rowData.TargetName), + state, + views.DefaultRowDataStyle.Render(rowData.Created), + views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(rowData.Branch)), + } + + if rowData.Status != "" { + row[3] = fmt.Sprintf("%s %s", state, views.DefaultRowDataStyle.Render(fmt.Sprintf("(%s)", rowData.Status))) + } + + return row +} + +func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { + if verbose { + sort.Slice(*workspaceList, func(i, j int) bool { + w1 := (*workspaceList)[i] + w2 := (*workspaceList)[j] + if w1.Info == nil || w2.Info == nil { + return true + } + return w1.Info.Created > w2.Info.Created + }) + return + } + + sort.Slice(*workspaceList, func(i, j int) bool { + w1 := (*workspaceList)[i] + w2 := (*workspaceList)[j] + if w1.State == nil || w2.State == nil { + return true + } + return w1.State.Uptime < w2.State.Uptime + }) + +} + +func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) *RowData { + rowData := RowData{"", "", "", "", "", ""} + rowData.Name = workspace.Name + views_util.AdditionalPropertyPadding + rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) + rowData.Branch = workspace.Repository.Branch + + rowData.TargetName = workspace.TargetName + views_util.AdditionalPropertyPadding + + if workspace.Info != nil { + rowData.Created = util.FormatTimestamp(workspace.Info.Created) + } + if workspace.State != nil && workspace.State.Uptime > 0 { + rowData.Status = util.FormatUptime(workspace.State.Uptime) + } + return &rowData +} diff --git a/pkg/views/target/selection/branch.go b/pkg/views/workspace/selection/branch.go similarity index 100% rename from pkg/views/target/selection/branch.go rename to pkg/views/workspace/selection/branch.go diff --git a/pkg/views/target/selection/build.go b/pkg/views/workspace/selection/build.go similarity index 100% rename from pkg/views/target/selection/build.go rename to pkg/views/workspace/selection/build.go diff --git a/pkg/views/target/selection/checkout.go b/pkg/views/workspace/selection/checkout.go similarity index 100% rename from pkg/views/target/selection/checkout.go rename to pkg/views/workspace/selection/checkout.go diff --git a/pkg/views/target/selection/common.go b/pkg/views/workspace/selection/common.go similarity index 100% rename from pkg/views/target/selection/common.go rename to pkg/views/workspace/selection/common.go diff --git a/pkg/views/target/selection/gitprovider.go b/pkg/views/workspace/selection/gitprovider.go similarity index 100% rename from pkg/views/target/selection/gitprovider.go rename to pkg/views/workspace/selection/gitprovider.go diff --git a/pkg/views/target/selection/gitproviderconfig.go b/pkg/views/workspace/selection/gitproviderconfig.go similarity index 100% rename from pkg/views/target/selection/gitproviderconfig.go rename to pkg/views/workspace/selection/gitproviderconfig.go diff --git a/pkg/views/target/selection/namespace.go b/pkg/views/workspace/selection/namespace.go similarity index 100% rename from pkg/views/target/selection/namespace.go rename to pkg/views/workspace/selection/namespace.go diff --git a/pkg/views/target/selection/prebuild.go b/pkg/views/workspace/selection/prebuild.go similarity index 100% rename from pkg/views/target/selection/prebuild.go rename to pkg/views/workspace/selection/prebuild.go diff --git a/pkg/views/target/selection/pullrequest.go b/pkg/views/workspace/selection/pullrequest.go similarity index 100% rename from pkg/views/target/selection/pullrequest.go rename to pkg/views/workspace/selection/pullrequest.go diff --git a/pkg/views/target/selection/repository.go b/pkg/views/workspace/selection/repository.go similarity index 100% rename from pkg/views/target/selection/repository.go rename to pkg/views/workspace/selection/repository.go diff --git a/pkg/views/target/selection/sample.go b/pkg/views/workspace/selection/sample.go similarity index 100% rename from pkg/views/target/selection/sample.go rename to pkg/views/workspace/selection/sample.go diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/workspace/selection/view.go new file mode 100644 index 0000000000..23b6464407 --- /dev/null +++ b/pkg/views/workspace/selection/view.go @@ -0,0 +1,227 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package selection + +import ( + "fmt" + "io" + "log" + "os" + "strings" + "time" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +var CustomRepoIdentifier = "" + +const CREATE_FROM_SAMPLE = "" + +var selectedStyles = lipgloss.NewStyle(). + Border(lipgloss.NormalBorder(), false, false, false, true). + BorderForeground(views.Green). + Bold(true). + Padding(0, 0, 0, 1) + +var statusMessageGreenStyle = lipgloss.NewStyle().Bold(true). + Foreground(lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#04B575"}). + Render + +var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). + Foreground(lipgloss.AdaptiveColor{Light: "#FF474C", Dark: "#FF474C"}). + Render + +type item[T any] struct { + id, title, desc, createdTime, uptime, targetConfig string + choiceProperty T + isMarked bool + isMultipleSelect bool + action string +} + +func (i item[T]) Title() string { return i.title } +func (i item[T]) Id() string { return i.id } +func (i item[T]) Description() string { return i.desc } +func (i item[T]) FilterValue() string { return i.title } +func (i item[T]) CreatedTime() string { return i.createdTime } +func (i item[T]) Uptime() string { return i.uptime } +func (i item[T]) TargetConfig() string { return i.targetConfig } + +type model[T any] struct { + list list.Model + choice *T + choices []*T + footer string + initialWidthSet bool +} + +func (m model[T]) Init() tea.Cmd { + return nil +} + +func (m model[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + if !m.initialWidthSet { + _, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + m.list.SetWidth(150) + } + } + + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "ctrl+c": + return m, tea.Quit + + case "enter": + i, ok := m.list.SelectedItem().(item[T]) + if ok { + m.choice = &i.choiceProperty + } + targetList := m.list.Items() + var choices []*T + for _, target := range targetList { + if target.(item[T]).isMarked { + targetItem, ok := target.(item[T]) + if !ok { + continue + } + choices = append(choices, &targetItem.choiceProperty) + } + + } + m.choices = choices + return m, tea.Quit + } + + case tea.WindowSizeMsg: + h, v := views.DocStyle.GetFrameSize() + m.list.SetSize(msg.Width-h, msg.Height-v) + } + + var cmd tea.Cmd + m.list, cmd = m.list.Update(msg) + return m, cmd +} + +func (m model[T]) View() string { + if m.footer == "" { + c, err := config.GetConfig() + if err != nil { + log.Fatal(err) + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + log.Fatal(err) + } + + m.footer = views.GetListFooter(activeProfile.Name, views.DefaultListFooterPadding) + } + + terminalWidth, terminalHeight, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + return "" + } + + if m.list.FilterState() == list.Filtering { + return views.DocStyle.MaxWidth(terminalWidth - 4).MaxHeight(terminalHeight - 4).Render(m.list.View() + m.footer) + } + + return views.DocStyle.MaxWidth(terminalWidth - 4).Height(terminalHeight - 2).Render(m.list.View() + m.footer) +} + +type ItemDelegate[T any] struct { +} + +func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem list.Item) { + i, _ := listItem.(item[T]) // Cast the listItem to your custom item type + s := strings.Builder{} + + var isSelected = index == m.Index() + + baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) + + title := baseStyles.Render(i.Title()) + idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetConfig()) + idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + description := baseStyles.Render(i.Description()) + + // Add the created/updated time if it's available + timeWidth := m.Width() - baseStyles.GetHorizontalFrameSize() - lipgloss.Width(title) + timeStyles := lipgloss.NewStyle(). + Align(lipgloss.Right). + Width(timeWidth) + timeString := timeStyles.Render("") + if i.Uptime() != "" { + timeString = timeStyles.Render(i.Uptime()) + } else if i.CreatedTime() != "" { + timeString = timeStyles.Render(fmt.Sprintf("created %s", i.CreatedTime())) + } + + // Adjust styles as the user moves through the menu + if isSelected { + title = selectedStyles.Foreground(views.Green).Render(i.Title()) + idWithTargetConfig = selectedStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) + timeString = timeStyles.Foreground(views.DimmedGreen).Render(timeString) + } + + // Render to the terminal + s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, timeString)) + s.WriteRune('\n') + s.WriteString(idWithTargetConfig) + s.WriteRune('\n') + s.WriteString(description) + s.WriteRune('\n') + + fmt.Fprint(w, s.String()) +} + +func (d ItemDelegate[T]) Height() int { + height := lipgloss.NewStyle().GetVerticalFrameSize() + 4 + return height +} + +func (d ItemDelegate[T]) Spacing() int { + return 0 +} + +func (d ItemDelegate[T]) Update(msg tea.Msg, m *list.Model) tea.Cmd { + i, ok := m.SelectedItem().(item[T]) + if !ok { + return nil + } + + m.StatusMessageLifetime = time.Millisecond * 2000 + + var title string + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "x": + if !i.isMultipleSelect { + return nil + } + if i.isMarked { + i.title = strings.TrimPrefix(i.title, statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action))) + i.isMarked = false + m.SetItem(m.Index(), i) + return m.NewStatusMessage(statusMessageGreenStyle("Removed target from list: ") + statusMessageGreenStyle(i.title)) + } + + title = i.title + i.title = statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action)) + statusMessageGreenStyle(i.title) + i.isMarked = true + m.SetItem(m.Index(), i) + return m.NewStatusMessage(statusMessageDangerStyle("Added target to list: ") + statusMessageGreenStyle(title)) + } + } + return nil +} diff --git a/pkg/views/target/selection/workspace.go b/pkg/views/workspace/selection/workspace.go similarity index 76% rename from pkg/views/target/selection/workspace.go rename to pkg/views/workspace/selection/workspace.go index 5e98459f08..b78d5e3bfd 100644 --- a/pkg/views/target/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -15,13 +15,13 @@ import ( "github.com/charmbracelet/lipgloss" ) -func GetWorkspaceFromPrompt(workspaces []apiclient.Workspace, actionVerb string) *apiclient.Workspace { - choiceChan := make(chan *apiclient.Workspace) +func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) *apiclient.WorkspaceDTO { + choiceChan := make(chan *apiclient.WorkspaceDTO) go selectWorkspacePrompt(workspaces, actionVerb, choiceChan) return <-choiceChan } -func selectWorkspacePrompt(workspaces []apiclient.Workspace, actionVerb string, choiceChan chan<- *apiclient.Workspace) { +func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- *apiclient.WorkspaceDTO) { items := []list.Item{} for _, workspace := range workspaces { @@ -30,7 +30,7 @@ func selectWorkspacePrompt(workspaces []apiclient.Workspace, actionVerb string, workspaceName = "Unnamed Workspace" } - newItem := item[apiclient.Workspace]{title: workspaceName, desc: "", choiceProperty: workspace} + newItem := item[apiclient.WorkspaceDTO]{title: workspaceName, desc: "", choiceProperty: workspace} items = append(items, newItem) } @@ -53,7 +53,7 @@ func selectWorkspacePrompt(workspaces []apiclient.Workspace, actionVerb string, l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) - m := model[apiclient.Workspace]{list: l} + m := model[apiclient.WorkspaceDTO]{list: l} m.list.Title = views.GetStyledMainTitle("Select a Workspace To " + actionVerb) m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) @@ -64,7 +64,7 @@ func selectWorkspacePrompt(workspaces []apiclient.Workspace, actionVerb string, os.Exit(1) } - if m, ok := p.(model[apiclient.Workspace]); ok && m.choice != nil { + if m, ok := p.(model[apiclient.WorkspaceDTO]); ok && m.choice != nil { choiceChan <- m.choice } else { choiceChan <- nil diff --git a/pkg/views/target/selection/workspaceconfig.go b/pkg/views/workspace/selection/workspaceconfig.go similarity index 100% rename from pkg/views/target/selection/workspaceconfig.go rename to pkg/views/workspace/selection/workspaceconfig.go diff --git a/pkg/views/target/selection/workspacerequest.go b/pkg/views/workspace/selection/workspacerequest.go similarity index 100% rename from pkg/views/target/selection/workspacerequest.go rename to pkg/views/workspace/selection/workspacerequest.go diff --git a/pkg/target/workspace/buildconfig/config.go b/pkg/workspace/buildconfig/config.go similarity index 100% rename from pkg/target/workspace/buildconfig/config.go rename to pkg/workspace/buildconfig/config.go diff --git a/pkg/target/workspace/config/config.go b/pkg/workspace/config/config.go similarity index 97% rename from pkg/target/workspace/config/config.go rename to pkg/workspace/config/config.go index 1193430b45..6321d0963e 100644 --- a/pkg/target/workspace/config/config.go +++ b/pkg/workspace/config/config.go @@ -6,7 +6,7 @@ package config import ( "errors" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type WorkspaceConfig struct { diff --git a/pkg/target/workspace/config/prebuild.go b/pkg/workspace/config/prebuild.go similarity index 100% rename from pkg/target/workspace/config/prebuild.go rename to pkg/workspace/config/prebuild.go diff --git a/pkg/target/workspace/config/store.go b/pkg/workspace/config/store.go similarity index 100% rename from pkg/target/workspace/config/store.go rename to pkg/workspace/config/store.go diff --git a/pkg/target/workspace/containerconfig/config.go b/pkg/workspace/containerconfig/config.go similarity index 100% rename from pkg/target/workspace/containerconfig/config.go rename to pkg/workspace/containerconfig/config.go diff --git a/pkg/workspace/store.go b/pkg/workspace/store.go new file mode 100644 index 0000000000..c436f15297 --- /dev/null +++ b/pkg/workspace/store.go @@ -0,0 +1,26 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import "errors" + +type Store interface { + List() ([]*WorkspaceViewDTO, error) + Find(idOrName string) (*WorkspaceViewDTO, error) + Save(workspace *Workspace) error + Delete(workspace *Workspace) error +} + +type WorkspaceViewDTO struct { + Workspace + TargetName string `json:"targetName" validate:"required"` +} // @name WorkspaceViewDTO + +var ( + ErrWorkspaceNotFound = errors.New("workspace not found") +) + +func IsWorkspaceNotFound(err error) bool { + return err.Error() == ErrWorkspaceNotFound.Error() +} diff --git a/pkg/target/workspace/workspace.go b/pkg/workspace/workspace.go similarity index 88% rename from pkg/target/workspace/workspace.go rename to pkg/workspace/workspace.go index 450ba5b3fd..b38838fdd7 100644 --- a/pkg/target/workspace/workspace.go +++ b/pkg/workspace/workspace.go @@ -8,10 +8,11 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type Workspace struct { + Id string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` @@ -20,7 +21,6 @@ type Workspace struct { EnvVars map[string]string `json:"envVars" validate:"required"` TargetId string `json:"targetId" validate:"required"` ApiKey string `json:"-"` - TargetConfig string `json:"targetConfig" validate:"required"` State *WorkspaceState `json:"state,omitempty" validate:"optional"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` } // @name Workspace @@ -78,7 +78,7 @@ type WorkspaceEnvVarParams struct { func GetWorkspaceEnvVars(workspace *Workspace, params WorkspaceEnvVarParams, telemetryEnabled bool) map[string]string { envVars := map[string]string{ "DAYTONA_TARGET_ID": workspace.TargetId, - "DAYTONA_WORKSPACE_NAME": workspace.Name, + "DAYTONA_WORKSPACE_ID": workspace.Id, "DAYTONA_WORKSPACE_REPOSITORY_URL": workspace.Repository.Url, "DAYTONA_SERVER_API_KEY": workspace.ApiKey, "DAYTONA_SERVER_VERSION": params.ServerVersion, @@ -96,14 +96,14 @@ func GetWorkspaceEnvVars(workspace *Workspace, params WorkspaceEnvVarParams, tel return envVars } -func GetWorkspaceHostname(targetId string, workspaceName string) string { +func GetWorkspaceHostname(workspaceId string) string { // Replace special chars with hyphen to form valid hostname // String resulting in consecutive hyphens is also valid - workspaceName = strings.ReplaceAll(workspaceName, "_", "-") - workspaceName = strings.ReplaceAll(workspaceName, "*", "-") - workspaceName = strings.ReplaceAll(workspaceName, ".", "-") + workspaceId = strings.ReplaceAll(workspaceId, "_", "-") + workspaceId = strings.ReplaceAll(workspaceId, "*", "-") + workspaceId = strings.ReplaceAll(workspaceId, ".", "-") - hostname := fmt.Sprintf("%s-%s", targetId, workspaceName) + hostname := fmt.Sprintf("ws-%s", workspaceId) if len(hostname) > 63 { return hostname[:63] From 7a48032c0796341fc24d3c6a1491f49ee7bc9656 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Wed, 6 Nov 2024 16:57:38 +0100 Subject: [PATCH 05/76] feat: target & target config rework - targets no longer have a relation to a target configs - workspaces can be managed on already created targets - targets can not be removed if a workspace is attached to it BREAKING CHANGE: - target config - target relation Signed-off-by: Ivan Dagelic --- docs/agent_mode/daytona.md | 4 +- docs/agent_mode/daytona_list.md | 2 +- docs/agent_mode/daytona_logs.md | 11 +- docs/daytona.md | 10 +- docs/daytona_create.md | 3 +- docs/daytona_info.md | 4 +- docs/daytona_list.md | 2 +- docs/daytona_logs.md | 5 +- docs/daytona_restart.md | 18 + docs/daytona_stop.md | 25 + docs/daytona_target-config.md | 1 - docs/daytona_target-config_set-default.md | 18 - docs/daytona_target.md | 3 + docs/daytona_target_create.md | 18 + docs/daytona_target_logs.md | 24 + docs/daytona_target_set-default.md | 18 + hack/docs/agent_mode/daytona.yaml | 4 +- hack/docs/agent_mode/daytona_list.yaml | 2 +- hack/docs/agent_mode/daytona_logs.yaml | 13 +- hack/docs/daytona.yaml | 10 +- hack/docs/daytona_create.yaml | 4 +- hack/docs/daytona_info.yaml | 4 +- hack/docs/daytona_list.yaml | 2 +- hack/docs/daytona_logs.yaml | 8 +- hack/docs/daytona_restart.yaml | 9 + hack/docs/daytona_stop.yaml | 18 + hack/docs/daytona_target-config.yaml | 1 - .../daytona_target-config_set-default.yaml | 9 - hack/docs/daytona_target.yaml | 3 + hack/docs/daytona_target_create.yaml | 9 + hack/docs/daytona_target_logs.yaml | 14 + hack/docs/daytona_target_set-default.yaml | 9 + .../testing/provider/targetconfigs/store.go | 35 +- .../testing/server/targetconfigs/store.go | 71 +++ .../server/targets/mocks/provisioner.go | 33 +- internal/testing/server/targets/store.go | 72 ++- .../apiclient/conversion/target_config.go | 6 +- .../util/apiclient/websocket_log_reader.go | 59 +- pkg/agent/agent_test.go | 10 +- pkg/api/controllers/target/create.go | 12 +- pkg/api/controllers/target/remove.go | 55 ++ pkg/api/controllers/target/set_default.go | 36 ++ pkg/api/controllers/target/target.go | 58 +- pkg/api/controllers/targetconfig/list.go | 31 +- pkg/api/controllers/targetconfig/remove.go | 4 +- pkg/api/controllers/targetconfig/set.go | 41 +- pkg/api/docs/docs.go | 133 ++-- pkg/api/docs/swagger.json | 133 ++-- pkg/api/docs/swagger.yaml | 98 +-- pkg/api/server.go | 2 +- pkg/api/util/mask-options.go | 41 ++ pkg/apiclient/README.md | 4 +- pkg/apiclient/api/openapi.yaml | 131 ++-- pkg/apiclient/api_target.go | 106 ++++ pkg/apiclient/api_target_config.go | 144 +---- pkg/apiclient/docs/CreateTargetConfigDTO.md | 10 +- pkg/apiclient/docs/CreateTargetDTO.md | 22 +- pkg/apiclient/docs/Target.md | 64 +- pkg/apiclient/docs/TargetAPI.md | 71 ++- pkg/apiclient/docs/TargetConfig.md | 31 +- pkg/apiclient/docs/TargetConfigAPI.md | 81 +-- pkg/apiclient/docs/TargetDTO.md | 85 ++- ...rProviderInfo.md => TargetProviderInfo.md} | 34 +- .../model_create_target_config_dto.go | 16 +- pkg/apiclient/model_create_target_dto.go | 32 +- pkg/apiclient/model_target.go | 89 ++- pkg/apiclient/model_target_config.go | 44 +- pkg/apiclient/model_target_dto.go | 119 +++- ..._info.go => model_target_provider_info.go} | 74 +-- pkg/build/devcontainer.go | 2 +- pkg/cmd/agent/agent.go | 8 +- pkg/cmd/agentmode/agent_mode.go | 1 + pkg/cmd/agentmode/logs.go | 22 + pkg/cmd/build/logs.go | 6 +- pkg/cmd/build/run.go | 4 +- pkg/cmd/cmd.go | 7 +- pkg/cmd/logs.go | 106 ---- pkg/cmd/prebuild/add.go | 4 +- pkg/cmd/provider/install.go | 26 +- pkg/cmd/purge.go | 8 +- pkg/cmd/server/serve.go | 2 - pkg/cmd/target/create.go | 158 +++++ pkg/cmd/target/delete.go | 45 +- pkg/cmd/target/info.go | 2 +- pkg/cmd/target/list.go | 1 - pkg/cmd/target/logs.go | 79 +++ pkg/cmd/target/restart.go | 2 +- pkg/cmd/target/setdefault.go | 66 ++ pkg/cmd/target/start.go | 9 +- pkg/cmd/target/stop.go | 33 +- pkg/cmd/target/target.go | 3 + pkg/cmd/targetconfig/remove.go | 82 --- pkg/cmd/targetconfig/set.go | 205 +++--- pkg/cmd/targetconfig/setdefault.go | 79 --- pkg/cmd/targetconfig/target_config.go | 1 - pkg/cmd/workspace/code.go | 68 +- .../configuration_flags.go} | 2 +- pkg/cmd/workspace/common/get_gpg_key.go | 42 ++ pkg/cmd/workspace/common/open_ide.go | 51 ++ .../common/workspace_autocompletion.go | 65 ++ pkg/cmd/workspace/create.go | 583 ------------------ .../{util => create}/add_from_config.go | 2 +- .../{util => create}/branch_wizard.go | 118 ++-- pkg/cmd/workspace/create/cmd.go | 373 +++++++++++ .../{util => create}/creation_data.go | 37 +- pkg/cmd/workspace/create/get_target.go | 76 +++ .../workspace/create/process_cmd_arguments.go | 174 ++++++ pkg/cmd/workspace/create/process_prompting.go | 89 +++ .../{util => create}/repository_wizard.go | 2 +- pkg/cmd/workspace/delete.go | 5 +- pkg/cmd/workspace/info.go | 9 +- pkg/cmd/workspace/list.go | 4 +- pkg/cmd/workspace/logs.go | 95 +++ pkg/cmd/workspace/restart.go | 78 +++ pkg/cmd/workspace/ssh-proxy.go | 5 +- pkg/cmd/workspace/ssh.go | 10 +- pkg/cmd/workspace/start.go | 109 ++-- pkg/cmd/workspace/stop.go | 158 +++++ pkg/cmd/workspace/util/get_target_config.go | 122 ---- pkg/cmd/workspaceconfig/add.go | 35 +- pkg/cmd/workspaceconfig/import.go | 19 +- pkg/db/dto/target.go | 52 +- pkg/db/dto/target_config.go | 44 +- pkg/db/target_config_store.go | 21 +- pkg/db/target_store.go | 52 +- pkg/docker/client_test.go | 10 +- pkg/docker/create.go | 4 +- pkg/docker/create_devcontainer.go | 6 +- pkg/docker/create_image.go | 2 +- pkg/docker/create_test.go | 2 +- pkg/docker/info_test.go | 10 +- pkg/docker/pull_image.go | 3 +- pkg/provider/manager/manager.go | 17 +- pkg/provider/provider.go | 6 + pkg/provider/types.go | 19 +- pkg/provisioner/create.go | 11 +- pkg/provisioner/destroy.go | 15 +- pkg/provisioner/info.go | 15 +- pkg/provisioner/provisioner.go | 19 +- pkg/provisioner/start.go | 11 +- pkg/provisioner/stop.go | 15 +- pkg/server/purge.go | 2 +- pkg/server/targetconfigs/dto/target_config.go | 8 +- pkg/server/targetconfigs/service.go | 64 +- pkg/server/targetconfigs/service_test.go | 47 +- pkg/server/targets/create.go | 40 +- pkg/server/targets/dto/target.go | 8 +- pkg/server/targets/get.go | 15 +- pkg/server/targets/list.go | 16 +- pkg/server/targets/remove.go | 30 +- pkg/server/targets/service.go | 9 +- pkg/server/targets/service_test.go | 116 ++-- pkg/server/targets/set-default.go | 49 ++ pkg/server/targets/start.go | 25 +- pkg/server/targets/stop.go | 14 +- pkg/server/workspaceconfig/service.go | 2 +- pkg/server/workspaces/create.go | 16 +- pkg/server/workspaces/get.go | 11 +- pkg/server/workspaces/list.go | 20 +- pkg/server/workspaces/remove.go | 20 +- pkg/server/workspaces/service.go | 14 +- pkg/server/workspaces/service_test.go | 92 +-- pkg/server/workspaces/start.go | 18 +- pkg/server/workspaces/stop.go | 11 +- pkg/tailscale/forward_unix.go | 5 +- pkg/target/config/config.go | 13 + pkg/{provider => target/config}/store.go | 5 +- pkg/target/store.go | 14 +- pkg/target/target.go | 19 +- pkg/telemetry/server_events.go | 12 +- pkg/views/common.go | 7 +- pkg/views/logs/display.go | 18 +- pkg/views/target/info/view.go | 17 + pkg/views/target/list/view.go | 46 +- pkg/views/target/name.go | 38 ++ pkg/views/target/selection/target.go | 47 +- pkg/views/target/selection/view.go | 35 +- pkg/views/targetconfig/list.go | 18 +- pkg/views/targetconfig/select.go | 9 +- pkg/views/targetconfig/set.go | 2 +- pkg/views/targetconfig/view.go | 14 +- pkg/views/util/empty_list.go | 2 +- pkg/views/util/table.go | 17 +- pkg/views/workspace/create/configuration.go | 64 +- pkg/views/workspace/create/summary.go | 78 ++- pkg/views/workspace/list/view.go | 3 +- pkg/workspace/workspace.go | 7 + 187 files changed, 4295 insertions(+), 2840 deletions(-) create mode 100644 docs/daytona_restart.md create mode 100644 docs/daytona_stop.md delete mode 100644 docs/daytona_target-config_set-default.md create mode 100644 docs/daytona_target_create.md create mode 100644 docs/daytona_target_logs.md create mode 100644 docs/daytona_target_set-default.md create mode 100644 hack/docs/daytona_restart.yaml create mode 100644 hack/docs/daytona_stop.yaml delete mode 100644 hack/docs/daytona_target-config_set-default.yaml create mode 100644 hack/docs/daytona_target_create.yaml create mode 100644 hack/docs/daytona_target_logs.yaml create mode 100644 hack/docs/daytona_target_set-default.yaml create mode 100644 internal/testing/server/targetconfigs/store.go create mode 100644 pkg/api/controllers/target/remove.go create mode 100644 pkg/api/controllers/target/set_default.go create mode 100644 pkg/api/util/mask-options.go rename pkg/apiclient/docs/{ProviderProviderInfo.md => TargetProviderInfo.md} (64%) rename pkg/apiclient/{model_provider_provider_info.go => model_target_provider_info.go} (60%) create mode 100644 pkg/cmd/agentmode/logs.go delete mode 100644 pkg/cmd/logs.go create mode 100644 pkg/cmd/target/create.go create mode 100644 pkg/cmd/target/logs.go create mode 100644 pkg/cmd/target/setdefault.go delete mode 100644 pkg/cmd/targetconfig/setdefault.go rename pkg/cmd/workspace/{util/target.go => common/configuration_flags.go} (99%) create mode 100644 pkg/cmd/workspace/common/get_gpg_key.go create mode 100644 pkg/cmd/workspace/common/open_ide.go create mode 100644 pkg/cmd/workspace/common/workspace_autocompletion.go delete mode 100644 pkg/cmd/workspace/create.go rename pkg/cmd/workspace/{util => create}/add_from_config.go (99%) rename pkg/cmd/workspace/{util => create}/branch_wizard.go (99%) create mode 100644 pkg/cmd/workspace/create/cmd.go rename pkg/cmd/workspace/{util => create}/creation_data.go (91%) create mode 100644 pkg/cmd/workspace/create/get_target.go create mode 100644 pkg/cmd/workspace/create/process_cmd_arguments.go create mode 100644 pkg/cmd/workspace/create/process_prompting.go rename pkg/cmd/workspace/{util => create}/repository_wizard.go (99%) create mode 100644 pkg/cmd/workspace/logs.go create mode 100644 pkg/cmd/workspace/restart.go create mode 100644 pkg/cmd/workspace/stop.go delete mode 100644 pkg/cmd/workspace/util/get_target_config.go create mode 100644 pkg/server/targets/set-default.go create mode 100644 pkg/target/config/config.go rename pkg/{provider => target/config}/store.go (91%) create mode 100644 pkg/views/target/name.go diff --git a/docs/agent_mode/daytona.md b/docs/agent_mode/daytona.md index e6bc63f1ca..0238291882 100644 --- a/docs/agent_mode/daytona.md +++ b/docs/agent_mode/daytona.md @@ -25,8 +25,8 @@ daytona [flags] * [daytona expose](daytona_expose.md) - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace * [daytona forward](daytona_forward.md) - Forward a port publicly via an URL * [daytona info](daytona_info.md) - Show workspace info -* [daytona list](daytona_list.md) - List targets -* [daytona logs](daytona_logs.md) - View logs for a target/workspace +* [daytona list](daytona_list.md) - List workspaces +* [daytona logs](daytona_logs.md) - View logs for the workspace * [daytona restart](daytona_restart.md) - Restart the workspace * [daytona start](daytona_start.md) - Start the workspace * [daytona stop](daytona_stop.md) - Stop the workspace diff --git a/docs/agent_mode/daytona_list.md b/docs/agent_mode/daytona_list.md index 9bf836328a..ea33021b05 100644 --- a/docs/agent_mode/daytona_list.md +++ b/docs/agent_mode/daytona_list.md @@ -1,6 +1,6 @@ ## daytona list -List targets +List workspaces ``` daytona list [flags] diff --git a/docs/agent_mode/daytona_logs.md b/docs/agent_mode/daytona_logs.md index d29fc8990a..01523f908f 100644 --- a/docs/agent_mode/daytona_logs.md +++ b/docs/agent_mode/daytona_logs.md @@ -1,16 +1,9 @@ ## daytona logs -View logs for a target/workspace +View logs for the workspace ``` -daytona logs [TARGET] [WORKSPACE_NAME] [flags] -``` - -### Options - -``` - -f, --follow Follow logs - -w, --target View target logs +daytona logs [flags] ``` ### Options inherited from parent commands diff --git a/docs/daytona.md b/docs/daytona.md index 5ca9b7228f..ba2b8af73d 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -25,24 +25,26 @@ daytona [flags] * [daytona code](daytona_code.md) - Open a workspace in your preferred IDE * [daytona config](daytona_config.md) - Output Daytona configuration * [daytona container-registry](daytona_container-registry.md) - Manage container registries -* [daytona create](daytona_create.md) - Create a target +* [daytona create](daytona_create.md) - Create a workspace * [daytona delete](daytona_delete.md) - Delete a workspace * [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. * [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces * [daytona forward](daytona_forward.md) - Forward a port from a workspace to your local machine * [daytona git-providers](daytona_git-providers.md) - Manage Git providers * [daytona ide](daytona_ide.md) - Choose the default IDE -* [daytona info](daytona_info.md) - Show target info -* [daytona list](daytona_list.md) - List targets -* [daytona logs](daytona_logs.md) - View logs for a target/workspace +* [daytona info](daytona_info.md) - Show workspace info +* [daytona list](daytona_list.md) - List workspaces +* [daytona logs](daytona_logs.md) - View the logs of a workspace * [daytona prebuild](daytona_prebuild.md) - Manage prebuilds * [daytona profile](daytona_profile.md) - Manage profiles * [daytona provider](daytona_provider.md) - Manage providers * [daytona purge](daytona_purge.md) - Purges all Daytona data from the current device +* [daytona restart](daytona_restart.md) - Restart a workspace * [daytona serve](daytona_serve.md) - Run the server process in the current terminal session * [daytona server](daytona_server.md) - Start the server process in daemon mode * [daytona ssh](daytona_ssh.md) - SSH into a workspace using the terminal * [daytona start](daytona_start.md) - Start a workspace +* [daytona stop](daytona_stop.md) - Stop a workspace * [daytona target](daytona_target.md) - Manage targets * [daytona target-config](daytona_target-config.md) - Manage target configs * [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection diff --git a/docs/daytona_create.md b/docs/daytona_create.md index 0618c04375..88850a9655 100644 --- a/docs/daytona_create.md +++ b/docs/daytona_create.md @@ -1,6 +1,6 @@ ## daytona create -Create a target +Create a workspace ``` daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] @@ -20,7 +20,6 @@ daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] -i, --ide string Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) --manual Manually enter the Git repository --multi-workspace Target with multiple workspaces/repos - --name string Specify the target name -n, --no-ide Do not open the target in the IDE after target creation -t, --target string Specify the target (e.g. 'local') -y, --yes Automatically confirm any prompts diff --git a/docs/daytona_info.md b/docs/daytona_info.md index 8ae541bb98..1d699e24a0 100644 --- a/docs/daytona_info.md +++ b/docs/daytona_info.md @@ -1,9 +1,9 @@ ## daytona info -Show target info +Show workspace info ``` -daytona info [TARGET] [flags] +daytona info [WORKSPACE] [flags] ``` ### Options diff --git a/docs/daytona_list.md b/docs/daytona_list.md index 9bf836328a..ea33021b05 100644 --- a/docs/daytona_list.md +++ b/docs/daytona_list.md @@ -1,6 +1,6 @@ ## daytona list -List targets +List workspaces ``` daytona list [flags] diff --git a/docs/daytona_logs.md b/docs/daytona_logs.md index d29fc8990a..4826bdd139 100644 --- a/docs/daytona_logs.md +++ b/docs/daytona_logs.md @@ -1,16 +1,15 @@ ## daytona logs -View logs for a target/workspace +View the logs of a workspace ``` -daytona logs [TARGET] [WORKSPACE_NAME] [flags] +daytona logs [WORKSPACE] [flags] ``` ### Options ``` -f, --follow Follow logs - -w, --target View target logs ``` ### Options inherited from parent commands diff --git a/docs/daytona_restart.md b/docs/daytona_restart.md new file mode 100644 index 0000000000..98ff4b8092 --- /dev/null +++ b/docs/daytona_restart.md @@ -0,0 +1,18 @@ +## daytona restart + +Restart a workspace + +``` +daytona restart [WORKSPACE] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_stop.md b/docs/daytona_stop.md new file mode 100644 index 0000000000..868b1b037c --- /dev/null +++ b/docs/daytona_stop.md @@ -0,0 +1,25 @@ +## daytona stop + +Stop a workspace + +``` +daytona stop [WORKSPACE] [flags] +``` + +### Options + +``` + -a, --all Stop all targets + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager + diff --git a/docs/daytona_target-config.md b/docs/daytona_target-config.md index 3effd3ca45..36cfd077a5 100644 --- a/docs/daytona_target-config.md +++ b/docs/daytona_target-config.md @@ -14,5 +14,4 @@ Manage target configs * [daytona target-config list](daytona_target-config_list.md) - List target configs * [daytona target-config remove](daytona_target-config_remove.md) - Remove target config * [daytona target-config set](daytona_target-config_set.md) - Set target config -* [daytona target-config set-default](daytona_target-config_set-default.md) - Set default target config diff --git a/docs/daytona_target-config_set-default.md b/docs/daytona_target-config_set-default.md deleted file mode 100644 index 60aa9b6f7c..0000000000 --- a/docs/daytona_target-config_set-default.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona target-config set-default - -Set default target config - -``` -daytona target-config set-default [CONFIG_NAME] [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona target-config](daytona_target-config.md) - Manage target configs - diff --git a/docs/daytona_target.md b/docs/daytona_target.md index 4b68b6dcd7..6a3790a81d 100644 --- a/docs/daytona_target.md +++ b/docs/daytona_target.md @@ -11,10 +11,13 @@ Manage targets ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona target create](daytona_target_create.md) - Create a target * [daytona target delete](daytona_target_delete.md) - Delete a target * [daytona target info](daytona_target_info.md) - Show target info * [daytona target list](daytona_target_list.md) - List targets +* [daytona target logs](daytona_target_logs.md) - View the logs of a target * [daytona target restart](daytona_target_restart.md) - Restart a target +* [daytona target set-default](daytona_target_set-default.md) - Set default target * [daytona target start](daytona_target_start.md) - Start a target * [daytona target stop](daytona_target_stop.md) - Stop a target diff --git a/docs/daytona_target_create.md b/docs/daytona_target_create.md new file mode 100644 index 0000000000..68129d015d --- /dev/null +++ b/docs/daytona_target_create.md @@ -0,0 +1,18 @@ +## daytona target create + +Create a target + +``` +daytona target create [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_logs.md b/docs/daytona_target_logs.md new file mode 100644 index 0000000000..68fc5f8f49 --- /dev/null +++ b/docs/daytona_target_logs.md @@ -0,0 +1,24 @@ +## daytona target logs + +View the logs of a target + +``` +daytona target logs [TARGET] [flags] +``` + +### Options + +``` + -f, --follow Follow logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/docs/daytona_target_set-default.md b/docs/daytona_target_set-default.md new file mode 100644 index 0000000000..b6ad2fea8a --- /dev/null +++ b/docs/daytona_target_set-default.md @@ -0,0 +1,18 @@ +## daytona target set-default + +Set default target + +``` +daytona target set-default [TARGET] [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/hack/docs/agent_mode/daytona.yaml b/hack/docs/agent_mode/daytona.yaml index be0c604e58..dd4e6664e7 100644 --- a/hack/docs/agent_mode/daytona.yaml +++ b/hack/docs/agent_mode/daytona.yaml @@ -17,8 +17,8 @@ see_also: - daytona expose - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace - daytona forward - Forward a port publicly via an URL - daytona info - Show workspace info - - daytona list - List targets - - daytona logs - View logs for a target/workspace + - daytona list - List workspaces + - daytona logs - View logs for the workspace - daytona restart - Restart the workspace - daytona start - Start the workspace - daytona stop - Stop the workspace diff --git a/hack/docs/agent_mode/daytona_list.yaml b/hack/docs/agent_mode/daytona_list.yaml index 08be0d7c58..e4efaaea82 100644 --- a/hack/docs/agent_mode/daytona_list.yaml +++ b/hack/docs/agent_mode/daytona_list.yaml @@ -1,5 +1,5 @@ name: daytona list -synopsis: List targets +synopsis: List workspaces usage: daytona list [flags] options: - name: format diff --git a/hack/docs/agent_mode/daytona_logs.yaml b/hack/docs/agent_mode/daytona_logs.yaml index 5ae83c6de5..70a97d203c 100644 --- a/hack/docs/agent_mode/daytona_logs.yaml +++ b/hack/docs/agent_mode/daytona_logs.yaml @@ -1,15 +1,6 @@ name: daytona logs -synopsis: View logs for a target/workspace -usage: daytona logs [TARGET] [WORKSPACE_NAME] [flags] -options: - - name: follow - shorthand: f - default_value: "false" - usage: Follow logs - - name: target - shorthand: w - default_value: "false" - usage: View target logs +synopsis: View logs for the workspace +usage: daytona logs [flags] inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 293b544fed..b919bbcef9 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -17,24 +17,26 @@ see_also: - daytona code - Open a workspace in your preferred IDE - daytona config - Output Daytona configuration - daytona container-registry - Manage container registries - - daytona create - Create a target + - daytona create - Create a workspace - daytona delete - Delete a workspace - daytona docs - Opens the Daytona documentation in your default browser. - daytona env - Manage profile environment variables that are added to all targets and workspaces - daytona forward - Forward a port from a workspace to your local machine - daytona git-providers - Manage Git providers - daytona ide - Choose the default IDE - - daytona info - Show target info - - daytona list - List targets - - daytona logs - View logs for a target/workspace + - daytona info - Show workspace info + - daytona list - List workspaces + - daytona logs - View the logs of a workspace - daytona prebuild - Manage prebuilds - daytona profile - Manage profiles - daytona provider - Manage providers - daytona purge - Purges all Daytona data from the current device + - daytona restart - Restart a workspace - daytona serve - Run the server process in the current terminal session - daytona server - Start the server process in daemon mode - daytona ssh - SSH into a workspace using the terminal - daytona start - Start a workspace + - daytona stop - Stop a workspace - daytona target - Manage targets - daytona target-config - Manage target configs - daytona telemetry - Manage telemetry collection diff --git a/hack/docs/daytona_create.yaml b/hack/docs/daytona_create.yaml index 45329bd8e9..bc3a691be4 100644 --- a/hack/docs/daytona_create.yaml +++ b/hack/docs/daytona_create.yaml @@ -1,5 +1,5 @@ name: daytona create -synopsis: Create a target +synopsis: Create a workspace usage: daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] options: - name: blank @@ -36,8 +36,6 @@ options: - name: multi-workspace default_value: "false" usage: Target with multiple workspaces/repos - - name: name - usage: Specify the target name - name: no-ide shorthand: "n" default_value: "false" diff --git a/hack/docs/daytona_info.yaml b/hack/docs/daytona_info.yaml index 6c96f1013e..e638f0b36b 100644 --- a/hack/docs/daytona_info.yaml +++ b/hack/docs/daytona_info.yaml @@ -1,6 +1,6 @@ name: daytona info -synopsis: Show target info -usage: daytona info [TARGET] [flags] +synopsis: Show workspace info +usage: daytona info [WORKSPACE] [flags] options: - name: format shorthand: f diff --git a/hack/docs/daytona_list.yaml b/hack/docs/daytona_list.yaml index 08be0d7c58..e4efaaea82 100644 --- a/hack/docs/daytona_list.yaml +++ b/hack/docs/daytona_list.yaml @@ -1,5 +1,5 @@ name: daytona list -synopsis: List targets +synopsis: List workspaces usage: daytona list [flags] options: - name: format diff --git a/hack/docs/daytona_logs.yaml b/hack/docs/daytona_logs.yaml index 5ae83c6de5..d3d06469a3 100644 --- a/hack/docs/daytona_logs.yaml +++ b/hack/docs/daytona_logs.yaml @@ -1,15 +1,11 @@ name: daytona logs -synopsis: View logs for a target/workspace -usage: daytona logs [TARGET] [WORKSPACE_NAME] [flags] +synopsis: View the logs of a workspace +usage: daytona logs [WORKSPACE] [flags] options: - name: follow shorthand: f default_value: "false" usage: Follow logs - - name: target - shorthand: w - default_value: "false" - usage: View target logs inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_restart.yaml b/hack/docs/daytona_restart.yaml new file mode 100644 index 0000000000..db758636a6 --- /dev/null +++ b/hack/docs/daytona_restart.yaml @@ -0,0 +1,9 @@ +name: daytona restart +synopsis: Restart a workspace +usage: daytona restart [WORKSPACE] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_stop.yaml b/hack/docs/daytona_stop.yaml new file mode 100644 index 0000000000..d9c14e0d03 --- /dev/null +++ b/hack/docs/daytona_stop.yaml @@ -0,0 +1,18 @@ +name: daytona stop +synopsis: Stop a workspace +usage: daytona stop [WORKSPACE] [flags] +options: + - name: all + shorthand: a + default_value: "false" + usage: Stop all targets + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/daytona_target-config.yaml b/hack/docs/daytona_target-config.yaml index 60577252ee..cbbecaca5b 100644 --- a/hack/docs/daytona_target-config.yaml +++ b/hack/docs/daytona_target-config.yaml @@ -9,4 +9,3 @@ see_also: - daytona target-config list - List target configs - daytona target-config remove - Remove target config - daytona target-config set - Set target config - - daytona target-config set-default - Set default target config diff --git a/hack/docs/daytona_target-config_set-default.yaml b/hack/docs/daytona_target-config_set-default.yaml deleted file mode 100644 index dc6fe9e01e..0000000000 --- a/hack/docs/daytona_target-config_set-default.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona target-config set-default -synopsis: Set default target config -usage: daytona target-config set-default [CONFIG_NAME] [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona target-config - Manage target configs diff --git a/hack/docs/daytona_target.yaml b/hack/docs/daytona_target.yaml index efa976f7e0..0ffef0f381 100644 --- a/hack/docs/daytona_target.yaml +++ b/hack/docs/daytona_target.yaml @@ -6,9 +6,12 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager + - daytona target create - Create a target - daytona target delete - Delete a target - daytona target info - Show target info - daytona target list - List targets + - daytona target logs - View the logs of a target - daytona target restart - Restart a target + - daytona target set-default - Set default target - daytona target start - Start a target - daytona target stop - Stop a target diff --git a/hack/docs/daytona_target_create.yaml b/hack/docs/daytona_target_create.yaml new file mode 100644 index 0000000000..dae63af760 --- /dev/null +++ b/hack/docs/daytona_target_create.yaml @@ -0,0 +1,9 @@ +name: daytona target create +synopsis: Create a target +usage: daytona target create [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_logs.yaml b/hack/docs/daytona_target_logs.yaml new file mode 100644 index 0000000000..17e1a8fde3 --- /dev/null +++ b/hack/docs/daytona_target_logs.yaml @@ -0,0 +1,14 @@ +name: daytona target logs +synopsis: View the logs of a target +usage: daytona target logs [TARGET] [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/hack/docs/daytona_target_set-default.yaml b/hack/docs/daytona_target_set-default.yaml new file mode 100644 index 0000000000..cc0f9747e6 --- /dev/null +++ b/hack/docs/daytona_target_set-default.yaml @@ -0,0 +1,9 @@ +name: daytona target set-default +synopsis: Set default target +usage: daytona target set-default [TARGET] [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/internal/testing/provider/targetconfigs/store.go b/internal/testing/provider/targetconfigs/store.go index 9c40b2be58..a047dc16db 100644 --- a/internal/testing/provider/targetconfigs/store.go +++ b/internal/testing/provider/targetconfigs/store.go @@ -8,48 +8,48 @@ package targetconfigs import ( "fmt" - "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target/config" ) type InMemoryTargetConfigStore struct { - targetConfigs map[string]*provider.TargetConfig + targetConfigs map[string]*config.TargetConfig } -func NewInMemoryTargetConfigStore() provider.TargetConfigStore { +func NewInMemoryTargetConfigStore() config.TargetConfigStore { return &InMemoryTargetConfigStore{ - targetConfigs: make(map[string]*provider.TargetConfig), + targetConfigs: make(map[string]*config.TargetConfig), } } -func (s *InMemoryTargetConfigStore) List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { return s.processFilters(filter) } -func (s *InMemoryTargetConfigStore) Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { targetConfigs, err := s.processFilters(filter) if err != nil { return nil, err } if len(targetConfigs) == 0 { - return nil, provider.ErrTargetConfigNotFound + return nil, config.ErrTargetConfigNotFound } return targetConfigs[0], nil } -func (s *InMemoryTargetConfigStore) Save(targetConfig *provider.TargetConfig) error { +func (s *InMemoryTargetConfigStore) Save(targetConfig *config.TargetConfig) error { s.targetConfigs[targetConfig.Name] = targetConfig return nil } -func (s *InMemoryTargetConfigStore) Delete(targetConfig *provider.TargetConfig) error { +func (s *InMemoryTargetConfigStore) Delete(targetConfig *config.TargetConfig) error { delete(s.targetConfigs, targetConfig.Name) return nil } -func (s *InMemoryTargetConfigStore) processFilters(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { - var result []*provider.TargetConfig - targetConfigs := make(map[string]*provider.TargetConfig) +func (s *InMemoryTargetConfigStore) processFilters(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { + var result []*config.TargetConfig + targetConfigs := make(map[string]*config.TargetConfig) for k, v := range s.targetConfigs { targetConfigs[k] = v } @@ -58,16 +58,9 @@ func (s *InMemoryTargetConfigStore) processFilters(filter *provider.TargetConfig if filter.Name != nil { targetConfig, ok := s.targetConfigs[*filter.Name] if ok { - return []*provider.TargetConfig{targetConfig}, nil + return []*config.TargetConfig{targetConfig}, nil } else { - return []*provider.TargetConfig{}, fmt.Errorf("target config with name %s not found", *filter.Name) - } - } - if filter.Default != nil { - for _, targetConfig := range targetConfigs { - if targetConfig.IsDefault != *filter.Default { - delete(targetConfigs, targetConfig.Name) - } + return []*config.TargetConfig{}, fmt.Errorf("target config with name %s not found", *filter.Name) } } } diff --git a/internal/testing/server/targetconfigs/store.go b/internal/testing/server/targetconfigs/store.go new file mode 100644 index 0000000000..8bd545b2ad --- /dev/null +++ b/internal/testing/server/targetconfigs/store.go @@ -0,0 +1,71 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targetconfigs + +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" +) + +type InMemoryTargetConfigStore struct { + targetConfigs map[string]*config.TargetConfig +} + +func NewInMemoryTargetConfigStore() config.TargetConfigStore { + return &InMemoryTargetConfigStore{ + targetConfigs: make(map[string]*config.TargetConfig), + } +} + +func (s *InMemoryTargetConfigStore) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { + return s.processFilters(filter) +} + +func (s *InMemoryTargetConfigStore) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { + targets, err := s.processFilters(filter) + if err != nil { + return nil, err + } + + if len(targets) == 0 { + return nil, target.ErrTargetNotFound + } + + return targets[0], nil +} + +func (s *InMemoryTargetConfigStore) Save(targetConfig *config.TargetConfig) error { + s.targetConfigs[targetConfig.Name] = targetConfig + return nil +} + +func (s *InMemoryTargetConfigStore) Delete(targetConfig *config.TargetConfig) error { + delete(s.targetConfigs, targetConfig.Name) + return nil +} + +func (s *InMemoryTargetConfigStore) processFilters(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { + var result []*config.TargetConfig + + if filter != nil { + if filter.Name != nil { + t, ok := s.targetConfigs[*filter.Name] + if ok { + return []*config.TargetConfig{t}, nil + } else { + return nil, fmt.Errorf("target config with id or name %s not found", *filter.Name) + } + } + } + + for _, targetConfig := range s.targetConfigs { + result = append(result, targetConfig) + } + + return result, nil +} diff --git a/internal/testing/server/targets/mocks/provisioner.go b/internal/testing/server/targets/mocks/provisioner.go index 5815acf5a8..743f3cf5aa 100644 --- a/internal/testing/server/targets/mocks/provisioner.go +++ b/internal/testing/server/targets/mocks/provisioner.go @@ -8,7 +8,6 @@ package mocks import ( "context" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/workspace" @@ -28,23 +27,23 @@ func (p *mockProvisioner) CreateWorkspace(params provisioner.WorkspaceParams) er return args.Error(0) } -func (p *mockProvisioner) CreateTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - args := p.Called(target, targetConfig) +func (p *mockProvisioner) CreateTarget(t *target.Target) error { + args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) DestroyWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { - args := p.Called(ws, targetConfig) +func (p *mockProvisioner) DestroyWorkspace(ws *workspace.Workspace, t *target.Target) error { + args := p.Called(ws, t) return args.Error(0) } -func (p *mockProvisioner) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - args := p.Called(target, targetConfig) +func (p *mockProvisioner) DestroyTarget(t *target.Target) error { + args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) GetTargetInfo(ctx context.Context, w *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) { - args := p.Called(ctx, w, targetConfig) +func (p *mockProvisioner) GetTargetInfo(ctx context.Context, t *target.Target) (*target.TargetInfo, error) { + args := p.Called(ctx, t) return args.Get(0).(*target.TargetInfo), args.Error(1) } @@ -53,22 +52,22 @@ func (p *mockProvisioner) StartWorkspace(params provisioner.WorkspaceParams) err return args.Error(0) } -func (p *mockProvisioner) StartTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - args := p.Called(target, targetConfig) +func (p *mockProvisioner) StartTarget(t *target.Target) error { + args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) StopWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { - args := p.Called(ws, targetConfig) +func (p *mockProvisioner) StopWorkspace(ws *workspace.Workspace, t *target.Target) error { + args := p.Called(ws, t) return args.Error(0) } -func (p *mockProvisioner) StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - args := p.Called(target, targetConfig) +func (p *mockProvisioner) StopTarget(t *target.Target) error { + args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { - args := p.Called(ctx, w, targetConfig) +func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, t *target.Target) (*workspace.WorkspaceInfo, error) { + args := p.Called(ctx, w, t) return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) } diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go index f835a7e988..4bdea399f2 100644 --- a/internal/testing/server/targets/store.go +++ b/internal/testing/server/targets/store.go @@ -5,7 +5,11 @@ package targets -import "github.com/daytonaio/daytona/pkg/target" +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/target" +) type InMemoryTargetStore struct { targets map[string]*target.Target @@ -17,31 +21,29 @@ func NewInMemoryTargetStore() target.Store { } } -func (s *InMemoryTargetStore) List() ([]*target.Target, error) { - targets := []*target.Target{} - for _, t := range s.targets { - targets = append(targets, t) - } - - return targets, nil +func (s *InMemoryTargetStore) List(filter *target.TargetFilter) ([]*target.TargetViewDTO, error) { + return s.processFilters(filter) } -func (s *InMemoryTargetStore) Find(idOrName string) (*target.Target, error) { - t, ok := s.targets[idOrName] - if !ok { - for _, w := range s.targets { - if w.Name == idOrName { - return w, nil - } - } +func (s *InMemoryTargetStore) Find(filter *target.TargetFilter) (*target.TargetViewDTO, error) { + targets, err := s.processFilters(filter) + if err != nil { + return nil, err + } + + if len(targets) == 0 { return nil, target.ErrTargetNotFound } - return t, nil + return targets[0], nil } func (s *InMemoryTargetStore) Save(target *target.Target) error { - s.targets[target.Id] = target + tg := *target + tg.EnvVars = nil + tg.ApiKey = "" + + s.targets[target.Id] = &tg return nil } @@ -49,3 +51,37 @@ func (s *InMemoryTargetStore) Delete(target *target.Target) error { delete(s.targets, target.Id) return nil } + +func (s *InMemoryTargetStore) processFilters(filter *target.TargetFilter) ([]*target.TargetViewDTO, error) { + var result []*target.TargetViewDTO + filteredTargets := make(map[string]*target.TargetViewDTO) + for k, v := range s.targets { + filteredTargets[k] = &target.TargetViewDTO{ + Target: *v, + } + } + + if filter != nil { + if filter.IdOrName != nil { + t, ok := s.targets[*filter.IdOrName] + if ok { + return []*target.TargetViewDTO{{Target: *t}}, nil + } else { + return []*target.TargetViewDTO{}, fmt.Errorf("target with id or name %s not found", *filter.IdOrName) + } + } + if filter.Default != nil { + for _, targetConfig := range filteredTargets { + if targetConfig.IsDefault != *filter.Default { + delete(filteredTargets, targetConfig.Name) + } + } + } + } + + for _, targetConfig := range filteredTargets { + result = append(result, targetConfig) + } + + return result, nil +} diff --git a/internal/util/apiclient/conversion/target_config.go b/internal/util/apiclient/conversion/target_config.go index cf7f646de0..40a9fcee15 100644 --- a/internal/util/apiclient/conversion/target_config.go +++ b/internal/util/apiclient/conversion/target_config.go @@ -4,12 +4,12 @@ package conversion import ( - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" + "github.com/daytonaio/daytona/pkg/target/config" ) -func ToTargetConfig(createTargetConfigDto dto.CreateTargetConfigDTO) *provider.TargetConfig { - return &provider.TargetConfig{ +func ToTargetConfig(createTargetConfigDto dto.CreateTargetConfigDTO) *config.TargetConfig { + return &config.TargetConfig{ Name: createTargetConfigDto.Name, ProviderInfo: createTargetConfigDto.ProviderInfo, Options: createTargetConfigDto.Options, diff --git a/internal/util/apiclient/websocket_log_reader.go b/internal/util/apiclient/websocket_log_reader.go index ba9989a66c..92c15289e3 100644 --- a/internal/util/apiclient/websocket_log_reader.go +++ b/internal/util/apiclient/websocket_log_reader.go @@ -15,16 +15,29 @@ import ( log "github.com/sirupsen/logrus" ) +type ReadLogParams struct { + Id string + Label *string + ActiveProfile config.Profile + SkipPrefixLengthSetup bool + Index *int + Follow *bool + Query *string + From *time.Time +} + var targetLogsStarted bool -func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId string, follow bool, from *time.Time) { +func ReadTargetLogs(ctx context.Context, params ReadLogParams) { + checkAndSetupLongestPrefixLength(params.SkipPrefixLengthSetup, params.Id, params.Label) + query := "" - if follow { + if params.Follow != nil && *params.Follow { query = "follow=true" } for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", targetId), &activeProfile, &query) + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", params.Id), ¶ms.ActiveProfile, &query) // We want to retry getting the logs if it fails if err != nil { log.Trace(HandleErrorResponse(res, err)) @@ -32,20 +45,22 @@ func ReadTargetLogs(ctx context.Context, activeProfile config.Profile, targetId continue } - readJSONLog(ctx, ws, logs_view.STATIC_INDEX, from) + readJSONLog(ctx, ws, logs_view.STATIC_INDEX, params.From) ws.Close() break } } -func ReadWorkspaceLogs(ctx context.Context, index int, activeProfile config.Profile, workspaceId string, follow bool, from *time.Time) { +func ReadWorkspaceLogs(ctx context.Context, params ReadLogParams) { + checkAndSetupLongestPrefixLength(params.SkipPrefixLengthSetup, params.Id, params.Label) + query := "" - if follow { + if params.Follow != nil && *params.Follow { query = "follow=true" } for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s", workspaceId), &activeProfile, &query) + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s", params.Id), ¶ms.ActiveProfile, &query) // We want to retry getting the logs if it fails if err != nil { log.Trace(HandleErrorResponse(res, err)) @@ -53,17 +68,27 @@ func ReadWorkspaceLogs(ctx context.Context, index int, activeProfile config.Prof continue } - readJSONLog(ctx, ws, index, from) + index := 0 + if params.Index != nil { + index = *params.Index + } + + readJSONLog(ctx, ws, index, params.From) ws.Close() break } } -func ReadBuildLogs(ctx context.Context, activeProfile config.Profile, buildId string, query string) { - logs_view.CalculateLongestPrefixLength([]string{buildId}) +func ReadBuildLogs(ctx context.Context, params ReadLogParams) { + checkAndSetupLongestPrefixLength(params.SkipPrefixLengthSetup, params.Id, params.Label) for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/build/%s", buildId), &activeProfile, &query) + var query string + if params.Query != nil { + query = *params.Query + } + + ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/build/%s", params.Id), ¶ms.ActiveProfile, &query) // We want to retry getting the logs if it fails if err != nil { log.Trace(HandleErrorResponse(res, err)) @@ -136,3 +161,15 @@ func readJSONLog(ctx context.Context, ws *websocket.Conn, index int, from *time. } } } + +func checkAndSetupLongestPrefixLength(skipSetup bool, id string, label *string) { + if skipSetup { + return + } + + name := id + if label != nil { + name = *label + } + logs_view.SetupLongestPrefixLength([]string{name}) +} diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index c603e5d727..0a0b8e5021 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -37,9 +37,13 @@ var workspace1 = &workspace.Workspace{ } var target1 = &target.Target{ - Id: "123", - Name: "test", - TargetConfig: "local", + Id: "123", + Name: "test", + ProviderInfo: target.ProviderInfo{ + Name: "test-provider", + Version: "test", + }, + Options: "test-options", } var gitStatus1 = &workspace.GitStatus{ diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go index 75f943edd6..e66e59e04d 100644 --- a/pkg/api/controllers/target/create.go +++ b/pkg/api/controllers/target/create.go @@ -8,6 +8,7 @@ import ( "fmt" "net/http" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" @@ -35,7 +36,7 @@ func CreateTarget(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.TargetService.CreateTarget(ctx.Request.Context(), createTargetReq) + t, err := server.TargetService.CreateTarget(ctx.Request.Context(), createTargetReq) if err != nil { if errors.Is(err, targets.ErrTargetAlreadyExists) { ctx.AbortWithError(http.StatusConflict, fmt.Errorf("target already exists: %w", err)) @@ -45,5 +46,12 @@ func CreateTarget(ctx *gin.Context) { return } - ctx.JSON(200, w) + maskedOptions, err := util.GetMaskedOptions(server, t.ProviderInfo.Name, t.Options) + if err != nil { + t.Options = fmt.Sprintf("Error: %s", err.Error()) + } else { + t.Options = maskedOptions + } + + ctx.JSON(200, t) } diff --git a/pkg/api/controllers/target/remove.go b/pkg/api/controllers/target/remove.go new file mode 100644 index 0000000000..632ed4cc22 --- /dev/null +++ b/pkg/api/controllers/target/remove.go @@ -0,0 +1,55 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "errors" + "fmt" + "net/http" + "strconv" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// RemoveTarget godoc +// +// @Tags target +// @Summary Remove target +// @Description Remove target +// @Param targetId path string true "Target ID" +// @Param force query bool false "Force" +// @Success 200 +// @Router /target/{targetId} [delete] +// +// @id RemoveTarget +func RemoveTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") + forceQuery := ctx.Query("force") + var err error + force := false + + if forceQuery != "" { + force, err = strconv.ParseBool(forceQuery) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) + return + } + } + + server := server.GetInstance(nil) + + if force { + err = server.TargetService.ForceRemoveTarget(ctx.Request.Context(), targetId) + } else { + err = server.TargetService.RemoveTarget(ctx.Request.Context(), targetId) + } + + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target: %w", err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/target/set_default.go b/pkg/api/controllers/target/set_default.go new file mode 100644 index 0000000000..7c2a476119 --- /dev/null +++ b/pkg/api/controllers/target/set_default.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// SetDefaultTarget godoc +// +// @Tags target +// @Summary Set target to be used by default +// @Description Set target to be used by default +// @Param targetId path string true "Target ID or name" +// @Success 200 +// @Router /target/{targetId}/set-default [patch] +// +// @id SetDefaultTarget +func SetDefaultTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") + + server := server.GetInstance(nil) + + err := server.TargetService.SetDefault(ctx.Request.Context(), targetId) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set target to default: %s", err.Error())) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index c69e479bbf..75741efca8 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -9,7 +9,9 @@ import ( "net/http" "strconv" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/target" "github.com/gin-gonic/gin" ) @@ -41,13 +43,20 @@ func GetTarget(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.TargetService.GetTarget(ctx.Request.Context(), targetId, verbose) + t, err := server.TargetService.GetTarget(ctx.Request.Context(), &target.TargetFilter{IdOrName: &targetId}, verbose) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get target: %w", err)) return } - ctx.JSON(200, w) + maskedOptions, err := util.GetMaskedOptions(server, t.ProviderInfo.Name, t.Options) + if err != nil { + t.Options = fmt.Sprintf("Error: %s", err.Error()) + } else { + t.Options = maskedOptions + } + + ctx.JSON(200, t) } // ListTargets godoc @@ -76,52 +85,21 @@ func ListTargets(ctx *gin.Context) { server := server.GetInstance(nil) - targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), verbose) + targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), nil, verbose) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list targets: %w", err)) return } - ctx.JSON(200, targetList) -} - -// RemoveTarget godoc -// -// @Tags target -// @Summary Remove target -// @Description Remove target -// @Param targetId path string true "Target ID" -// @Param force query bool false "Force" -// @Success 200 -// @Router /target/{targetId} [delete] -// -// @id RemoveTarget -func RemoveTarget(ctx *gin.Context) { - targetId := ctx.Param("targetId") - forceQuery := ctx.Query("force") - var err error - force := false - - if forceQuery != "" { - force, err = strconv.ParseBool(forceQuery) + for i, t := range targetList { + maskedOptions, err := util.GetMaskedOptions(server, t.ProviderInfo.Name, t.Options) if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) - return + targetList[i].Options = fmt.Sprintf("Error: %s", err.Error()) + continue } - } - server := server.GetInstance(nil) - - if force { - err = server.TargetService.ForceRemoveTarget(ctx.Request.Context(), targetId) - } else { - err = server.TargetService.RemoveTarget(ctx.Request.Context(), targetId) + targetList[i].Options = maskedOptions } - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target: %w", err)) - return - } - - ctx.Status(200) + ctx.JSON(200, targetList) } diff --git a/pkg/api/controllers/targetconfig/list.go b/pkg/api/controllers/targetconfig/list.go index 86bbdd063e..17ac7c471a 100644 --- a/pkg/api/controllers/targetconfig/list.go +++ b/pkg/api/controllers/targetconfig/list.go @@ -4,10 +4,10 @@ package targetconfig import ( - "encoding/json" "fmt" "net/http" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -32,38 +32,13 @@ func ListTargetConfigs(ctx *gin.Context) { } for _, targetConfig := range targetConfigs { - p, err := server.ProviderManager.GetProvider(targetConfig.ProviderInfo.Name) + maskedOptions, err := util.GetMaskedOptions(server, targetConfig.ProviderInfo.Name, targetConfig.Options) if err != nil { targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) continue } - manifest, err := (*p).GetTargetConfigManifest() - if err != nil { - targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - var opts map[string]interface{} - err = json.Unmarshal([]byte(targetConfig.Options), &opts) - if err != nil { - targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - for name, property := range *manifest { - if property.InputMasked { - delete(opts, name) - } - } - - updatedOptions, err := json.MarshalIndent(opts, "", " ") - if err != nil { - targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - continue - } - - targetConfig.Options = string(updatedOptions) + targetConfig.Options = maskedOptions } ctx.JSON(200, targetConfigs) diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/remove.go index bd00fba0a2..d38c41ef1d 100644 --- a/pkg/api/controllers/targetconfig/remove.go +++ b/pkg/api/controllers/targetconfig/remove.go @@ -7,8 +7,8 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/target/config" "github.com/gin-gonic/gin" ) @@ -27,7 +27,7 @@ func RemoveTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfig, err := server.TargetConfigService.Find(&provider.TargetConfigFilter{ + targetConfig, err := server.TargetConfigService.Find(&config.TargetConfigFilter{ Name: &configName, }) if err != nil { diff --git a/pkg/api/controllers/targetconfig/set.go b/pkg/api/controllers/targetconfig/set.go index 063cdeed9f..a58fff534c 100644 --- a/pkg/api/controllers/targetconfig/set.go +++ b/pkg/api/controllers/targetconfig/set.go @@ -8,7 +8,7 @@ import ( "net/http" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" - "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" "github.com/gin-gonic/gin" @@ -19,8 +19,8 @@ import ( // @Tags target-config // @Summary Set a target config // @Description Set a target config -// @Param targetConfig body CreateTargetConfigDTO true "Target config to set" -// @Success 201 +// @Param targetConfig body CreateTargetConfigDTO true "Target config to set" +// @Success 200 {object} TargetConfig // @Router /target-config [put] // // @id SetTargetConfig @@ -42,37 +42,12 @@ func SetTargetConfig(ctx *gin.Context) { return } - ctx.Status(201) -} - -// SetDefaultTargetConfig godoc -// -// @Tags target-config -// @Summary Set target config to default -// @Description Set target config to default -// @Param configName path string true "Target config name" -// @Success 200 -// @Router /target-config/{configName}/set-default [patch] -// -// @id SetDefaultTargetConfig -func SetDefaultTargetConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - - server := server.GetInstance(nil) - - targetConfig, err := server.TargetConfigService.Find(&provider.TargetConfigFilter{ - Name: &configName, - }) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find target config: %w", err)) - return - } - - err = server.TargetConfigService.SetDefault(targetConfig) + maskedOptions, err := util.GetMaskedOptions(server, targetConfig.ProviderInfo.Name, targetConfig.Options) if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set target config to default: %s", err.Error())) - return + targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) + } else { + targetConfig.Options = maskedOptions } - ctx.Status(200) + ctx.JSON(200, targetConfig) } diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 9e3acd4e37..b36993c22a 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1255,8 +1255,11 @@ const docTemplate = `{ } ], "responses": { - "201": { - "description": "Created" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/TargetConfig" + } } } } @@ -1285,30 +1288,6 @@ const docTemplate = `{ } } }, - "/target-config/{configName}/set-default": { - "patch": { - "description": "Set target config to default", - "tags": [ - "target-config" - ], - "summary": "Set target config to default", - "operationId": "SetDefaultTargetConfig", - "parameters": [ - { - "type": "string", - "description": "Target config name", - "name": "configName", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, "/target/{targetId}": { "get": { "description": "Get target info", @@ -1373,6 +1352,30 @@ const docTemplate = `{ } } }, + "/target/{targetId}/set-default": { + "patch": { + "description": "Set target to be used by default", + "tags": [ + "target" + ], + "summary": "Set target to be used by default", + "operationId": "SetDefaultTarget", + "parameters": [ + { + "type": "string", + "description": "Target ID or name", + "name": "targetId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/start": { "post": { "description": "Start target", @@ -3616,7 +3619,7 @@ const docTemplate = `{ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" + "$ref": "#/definitions/TargetProviderInfo" } } }, @@ -3625,7 +3628,7 @@ const docTemplate = `{ "required": [ "id", "name", - "targetConfig" + "targetConfigName" ], "properties": { "id": { @@ -3634,7 +3637,7 @@ const docTemplate = `{ "name": { "type": "string" }, - "targetConfig": { + "targetConfigName": { "type": "string" } } @@ -4823,34 +4826,39 @@ const docTemplate = `{ "Target": { "type": "object", "required": [ + "default", "id", "name", - "targetConfig" + "options", + "providerInfo" ], "properties": { + "default": { + "type": "boolean" + }, "id": { "type": "string" }, "name": { "type": "string" }, - "targetConfig": { + "options": { + "description": "JSON encoded map of options", "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/TargetProviderInfo" } } }, "TargetConfig": { "type": "object", "required": [ - "isDefault", "name", "options", "providerInfo" ], "properties": { - "isDefault": { - "type": "boolean" - }, "name": { "type": "string" }, @@ -4859,7 +4867,7 @@ const docTemplate = `{ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" + "$ref": "#/definitions/TargetProviderInfo" } } }, @@ -4909,11 +4917,17 @@ const docTemplate = `{ "TargetDTO": { "type": "object", "required": [ + "default", "id", "name", - "targetConfig" + "options", + "providerInfo", + "workspaceCount" ], "properties": { + "default": { + "type": "boolean" + }, "id": { "type": "string" }, @@ -4923,8 +4937,15 @@ const docTemplate = `{ "name": { "type": "string" }, - "targetConfig": { + "options": { + "description": "JSON encoded map of options", "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/TargetProviderInfo" + }, + "workspaceCount": { + "type": "integer" } } }, @@ -4942,6 +4963,24 @@ const docTemplate = `{ } } }, + "TargetProviderInfo": { + "type": "object", + "required": [ + "name", + "version" + ], + "properties": { + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "WorkspaceConfig": { "type": "object", "required": [ @@ -5181,24 +5220,6 @@ const docTemplate = `{ "BuildStateDeleting" ] }, - "provider.ProviderInfo": { - "type": "object", - "required": [ - "name", - "version" - ], - "properties": { - "label": { - "type": "string" - }, - "name": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, "provider.TargetConfigPropertyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 20b0ca1487..eb26c4ed7e 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1252,8 +1252,11 @@ } ], "responses": { - "201": { - "description": "Created" + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/TargetConfig" + } } } } @@ -1282,30 +1285,6 @@ } } }, - "/target-config/{configName}/set-default": { - "patch": { - "description": "Set target config to default", - "tags": [ - "target-config" - ], - "summary": "Set target config to default", - "operationId": "SetDefaultTargetConfig", - "parameters": [ - { - "type": "string", - "description": "Target config name", - "name": "configName", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, "/target/{targetId}": { "get": { "description": "Get target info", @@ -1370,6 +1349,30 @@ } } }, + "/target/{targetId}/set-default": { + "patch": { + "description": "Set target to be used by default", + "tags": [ + "target" + ], + "summary": "Set target to be used by default", + "operationId": "SetDefaultTarget", + "parameters": [ + { + "type": "string", + "description": "Target ID or name", + "name": "targetId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/start": { "post": { "description": "Start target", @@ -3613,7 +3616,7 @@ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" + "$ref": "#/definitions/TargetProviderInfo" } } }, @@ -3622,7 +3625,7 @@ "required": [ "id", "name", - "targetConfig" + "targetConfigName" ], "properties": { "id": { @@ -3631,7 +3634,7 @@ "name": { "type": "string" }, - "targetConfig": { + "targetConfigName": { "type": "string" } } @@ -4820,34 +4823,39 @@ "Target": { "type": "object", "required": [ + "default", "id", "name", - "targetConfig" + "options", + "providerInfo" ], "properties": { + "default": { + "type": "boolean" + }, "id": { "type": "string" }, "name": { "type": "string" }, - "targetConfig": { + "options": { + "description": "JSON encoded map of options", "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/TargetProviderInfo" } } }, "TargetConfig": { "type": "object", "required": [ - "isDefault", "name", "options", "providerInfo" ], "properties": { - "isDefault": { - "type": "boolean" - }, "name": { "type": "string" }, @@ -4856,7 +4864,7 @@ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/provider.ProviderInfo" + "$ref": "#/definitions/TargetProviderInfo" } } }, @@ -4906,11 +4914,17 @@ "TargetDTO": { "type": "object", "required": [ + "default", "id", "name", - "targetConfig" + "options", + "providerInfo", + "workspaceCount" ], "properties": { + "default": { + "type": "boolean" + }, "id": { "type": "string" }, @@ -4920,8 +4934,15 @@ "name": { "type": "string" }, - "targetConfig": { + "options": { + "description": "JSON encoded map of options", "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/TargetProviderInfo" + }, + "workspaceCount": { + "type": "integer" } } }, @@ -4939,6 +4960,24 @@ } } }, + "TargetProviderInfo": { + "type": "object", + "required": [ + "name", + "version" + ], + "properties": { + "label": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "WorkspaceConfig": { "type": "object", "required": [ @@ -5178,24 +5217,6 @@ "BuildStateDeleting" ] }, - "provider.ProviderInfo": { - "type": "object", - "required": [ - "name", - "version" - ], - "properties": { - "label": { - "type": "string" - }, - "name": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, "provider.TargetConfigPropertyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index f78b6104eb..b0d9c48adc 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -197,7 +197,7 @@ definitions: options: type: string providerInfo: - $ref: '#/definitions/provider.ProviderInfo' + $ref: '#/definitions/TargetProviderInfo' required: - name - options @@ -209,12 +209,12 @@ definitions: type: string name: type: string - targetConfig: + targetConfigName: type: string required: - id - name - - targetConfig + - targetConfigName type: object CreateWorkspaceConfigDTO: properties: @@ -1026,30 +1026,34 @@ definitions: - UpdatedButUnmerged Target: properties: + default: + type: boolean id: type: string name: type: string - targetConfig: + options: + description: JSON encoded map of options type: string + providerInfo: + $ref: '#/definitions/TargetProviderInfo' required: + - default - id - name - - targetConfig + - options + - providerInfo type: object TargetConfig: properties: - isDefault: - type: boolean name: type: string options: description: JSON encoded map of options type: string providerInfo: - $ref: '#/definitions/provider.ProviderInfo' + $ref: '#/definitions/TargetProviderInfo' required: - - isDefault - name - options - providerInfo @@ -1092,18 +1096,28 @@ definitions: type: object TargetDTO: properties: + default: + type: boolean id: type: string info: $ref: '#/definitions/TargetInfo' name: type: string - targetConfig: + options: + description: JSON encoded map of options type: string + providerInfo: + $ref: '#/definitions/TargetProviderInfo' + workspaceCount: + type: integer required: + - default - id - name - - targetConfig + - options + - providerInfo + - workspaceCount type: object TargetInfo: properties: @@ -1114,6 +1128,18 @@ definitions: required: - name type: object + TargetProviderInfo: + properties: + label: + type: string + name: + type: string + version: + type: string + required: + - name + - version + type: object WorkspaceConfig: properties: buildConfig: @@ -1285,18 +1311,6 @@ definitions: - BuildStatePendingDelete - BuildStatePendingForcedDelete - BuildStateDeleting - provider.ProviderInfo: - properties: - label: - type: string - name: - type: string - version: - type: string - required: - - name - - version - type: object provider.TargetConfigPropertyType: enum: - string @@ -2148,8 +2162,10 @@ paths: schema: $ref: '#/definitions/CreateTargetConfigDTO' responses: - "201": - description: Created + "200": + description: OK + schema: + $ref: '#/definitions/TargetConfig' summary: Set a target config tags: - target-config @@ -2169,22 +2185,6 @@ paths: summary: Remove a target config tags: - target-config - /target-config/{configName}/set-default: - patch: - description: Set target config to default - operationId: SetDefaultTargetConfig - parameters: - - description: Target config name - in: path - name: configName - required: true - type: string - responses: - "200": - description: OK - summary: Set target config to default - tags: - - target-config /target/{targetId}: delete: description: Remove target @@ -2228,6 +2228,22 @@ paths: summary: Get target info tags: - target + /target/{targetId}/set-default: + patch: + description: Set target to be used by default + operationId: SetDefaultTarget + parameters: + - description: Target ID or name + in: path + name: targetId + required: true + type: string + responses: + "200": + description: OK + summary: Set target to be used by default + tags: + - target /target/{targetId}/start: post: description: Start target diff --git a/pkg/api/server.go b/pkg/api/server.go index 5fa8554437..25f49bb374 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -148,6 +148,7 @@ func (a *ApiServer) Start() error { targetController.POST("", target.CreateTarget) targetController.POST("/:targetId/start", target.StartTarget) targetController.POST("/:targetId/stop", target.StopTarget) + targetController.PATCH("/:targetId/set-default", target.SetDefaultTarget) targetController.DELETE("/:targetId", target.RemoveTarget) } @@ -281,7 +282,6 @@ func (a *ApiServer) Start() error { { targetConfigController.GET("", targetconfig.ListTargetConfigs) targetConfigController.PUT("", targetconfig.SetTargetConfig) - targetConfigController.PATCH("/:configName/set-default", targetconfig.SetDefaultTargetConfig) targetConfigController.DELETE("/:configName", targetconfig.RemoveTargetConfig) } diff --git a/pkg/api/util/mask-options.go b/pkg/api/util/mask-options.go new file mode 100644 index 0000000000..42f6f7178d --- /dev/null +++ b/pkg/api/util/mask-options.go @@ -0,0 +1,41 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "encoding/json" + + "github.com/daytonaio/daytona/pkg/server" +) + +func GetMaskedOptions(server *server.Server, providerName, options string) (string, error) { + p, err := server.ProviderManager.GetProvider(providerName) + if err != nil { + return "", err + } + + manifest, err := (*p).GetTargetConfigManifest() + if err != nil { + return "", err + } + + var opts map[string]interface{} + err = json.Unmarshal([]byte(options), &opts) + if err != nil { + return "", err + } + + for name, property := range *manifest { + if property.InputMasked { + delete(opts, name) + } + } + + updatedOptions, err := json.MarshalIndent(opts, "", " ") + if err != nil { + return "", err + } + + return string(updatedOptions), nil +} diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index e9e8cf712d..42388bf53f 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -126,11 +126,11 @@ Class | Method | HTTP request | Description *TargetAPI* | [**GetTarget**](docs/TargetAPI.md#gettarget) | **Get** /target/{targetId} | Get target info *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets *TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target +*TargetAPI* | [**SetDefaultTarget**](docs/TargetAPI.md#setdefaulttarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs *TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configName} | Remove a target config -*TargetConfigAPI* | [**SetDefaultTargetConfig**](docs/TargetConfigAPI.md#setdefaulttargetconfig) | **Patch** /target-config/{configName}/set-default | Set target config to default *TargetConfigAPI* | [**SetTargetConfig**](docs/TargetConfigAPI.md#settargetconfig) | **Put** /target-config | Set a target config *WorkspaceAPI* | [**CreateWorkspace**](docs/WorkspaceAPI.md#createworkspace) | **Post** /workspace | Create a workspace *WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info @@ -242,7 +242,6 @@ Class | Method | HTTP request | Description - [PrebuildDTO](docs/PrebuildDTO.md) - [ProfileData](docs/ProfileData.md) - [Provider](docs/Provider.md) - - [ProviderProviderInfo](docs/ProviderProviderInfo.md) - [ProviderTargetConfigPropertyType](docs/ProviderTargetConfigPropertyType.md) - [ReplaceRequest](docs/ReplaceRequest.md) - [ReplaceResult](docs/ReplaceResult.md) @@ -262,6 +261,7 @@ Class | Method | HTTP request | Description - [TargetConfigProperty](docs/TargetConfigProperty.md) - [TargetDTO](docs/TargetDTO.md) - [TargetInfo](docs/TargetInfo.md) + - [TargetProviderInfo](docs/TargetProviderInfo.md) - [WorkspaceConfig](docs/WorkspaceConfig.md) - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 66b87565ef..c41c44a1ff 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -885,9 +885,12 @@ paths: description: Target config to set required: true responses: - "201": - content: {} - description: Created + "200": + content: + '*/*': + schema: + $ref: '#/components/schemas/TargetConfig' + description: OK summary: Set a target config tags: - target-config @@ -910,24 +913,6 @@ paths: summary: Remove a target config tags: - target-config - /target-config/{configName}/set-default: - patch: - description: Set target config to default - operationId: SetDefaultTargetConfig - parameters: - - description: Target config name - in: path - name: configName - required: true - schema: - type: string - responses: - "200": - content: {} - description: OK - summary: Set target config to default - tags: - - target-config /target/{targetId}: delete: description: Remove target @@ -976,6 +961,24 @@ paths: summary: Get target info tags: - target + /target/{targetId}/set-default: + patch: + description: Set target to be used by default + operationId: SetDefaultTarget + parameters: + - description: Target ID or name + in: path + name: targetId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Set target to be used by default + tags: + - target /target/{targetId}/start: post: description: Start target @@ -2713,7 +2716,7 @@ components: options: type: string providerInfo: - $ref: '#/components/schemas/provider.ProviderInfo' + $ref: '#/components/schemas/TargetProviderInfo' required: - name - options @@ -2721,7 +2724,7 @@ components: type: object CreateTargetDTO: example: - targetConfig: targetConfig + targetConfigName: targetConfigName name: name id: id properties: @@ -2729,12 +2732,12 @@ components: type: string name: type: string - targetConfig: + targetConfigName: type: string required: - id - name - - targetConfig + - targetConfigName type: object CreateWorkspaceConfigDTO: example: @@ -3904,24 +3907,35 @@ components: - UpdatedButUnmerged Target: example: - targetConfig: targetConfig + default: true name: name + options: options id: id + providerInfo: + name: name + label: label + version: version properties: + default: + type: boolean id: type: string name: type: string - targetConfig: + options: + description: JSON encoded map of options type: string + providerInfo: + $ref: '#/components/schemas/TargetProviderInfo' required: + - default - id - name - - targetConfig + - options + - providerInfo type: object TargetConfig: example: - isDefault: true name: name options: options providerInfo: @@ -3929,17 +3943,14 @@ components: label: label version: version properties: - isDefault: - type: boolean name: type: string options: description: JSON encoded map of options type: string providerInfo: - $ref: '#/components/schemas/provider.ProviderInfo' + $ref: '#/components/schemas/TargetProviderInfo' required: - - isDefault - name - options - providerInfo @@ -3982,25 +3993,41 @@ components: type: object TargetDTO: example: - targetConfig: targetConfig + default: true name: name + options: options + workspaceCount: 0 id: id info: providerMetadata: providerMetadata name: name + providerInfo: + name: name + label: label + version: version properties: + default: + type: boolean id: type: string info: $ref: '#/components/schemas/TargetInfo' name: type: string - targetConfig: + options: + description: JSON encoded map of options type: string + providerInfo: + $ref: '#/components/schemas/TargetProviderInfo' + workspaceCount: + type: integer required: + - default - id - name - - targetConfig + - options + - providerInfo + - workspaceCount type: object TargetInfo: example: @@ -4014,6 +4041,22 @@ components: required: - name type: object + TargetProviderInfo: + example: + name: name + label: label + version: version + properties: + label: + type: string + name: + type: string + version: + type: string + required: + - name + - version + type: object WorkspaceConfig: example: prebuilds: @@ -4334,22 +4377,6 @@ components: - BuildStatePendingDelete - BuildStatePendingForcedDelete - BuildStateDeleting - provider.ProviderInfo: - example: - name: name - label: label - version: version - properties: - label: - type: string - name: - type: string - version: - type: string - required: - - name - - version - type: object provider.TargetConfigPropertyType: enum: - string diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index 8588832924..3d096b0db0 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -516,6 +516,112 @@ func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http. return localVarHTTPResponse, nil } +type ApiSetDefaultTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string +} + +func (r ApiSetDefaultTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.SetDefaultTargetExecute(r) +} + +/* +SetDefaultTarget Set target to be used by default + +Set target to be used by default + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param targetId Target ID or name + @return ApiSetDefaultTargetRequest +*/ +func (a *TargetAPIService) SetDefaultTarget(ctx context.Context, targetId string) ApiSetDefaultTargetRequest { + return ApiSetDefaultTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + } +} + +// Execute executes the request +func (a *TargetAPIService) SetDefaultTargetExecute(r ApiSetDefaultTargetRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetDefaultTarget") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/target/{targetId}/set-default" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + type ApiStartTargetRequest struct { ctx context.Context ApiService *TargetAPIService diff --git a/pkg/apiclient/api_target_config.go b/pkg/apiclient/api_target_config.go index ea4adf6662..b2555ee5e0 100644 --- a/pkg/apiclient/api_target_config.go +++ b/pkg/apiclient/api_target_config.go @@ -242,112 +242,6 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf return localVarHTTPResponse, nil } -type ApiSetDefaultTargetConfigRequest struct { - ctx context.Context - ApiService *TargetConfigAPIService - configName string -} - -func (r ApiSetDefaultTargetConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.SetDefaultTargetConfigExecute(r) -} - -/* -SetDefaultTargetConfig Set target config to default - -Set target config to default - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Target config name - @return ApiSetDefaultTargetConfigRequest -*/ -func (a *TargetConfigAPIService) SetDefaultTargetConfig(ctx context.Context, configName string) ApiSetDefaultTargetConfigRequest { - return ApiSetDefaultTargetConfigRequest{ - ApiService: a, - ctx: ctx, - configName: configName, - } -} - -// Execute executes the request -func (a *TargetConfigAPIService) SetDefaultTargetConfigExecute(r ApiSetDefaultTargetConfigRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodPatch - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.SetDefaultTargetConfig") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/target-config/{configName}/set-default" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} - type ApiSetTargetConfigRequest struct { ctx context.Context ApiService *TargetConfigAPIService @@ -360,7 +254,7 @@ func (r ApiSetTargetConfigRequest) TargetConfig(targetConfig CreateTargetConfigD return r } -func (r ApiSetTargetConfigRequest) Execute() (*http.Response, error) { +func (r ApiSetTargetConfigRequest) Execute() (*TargetConfig, *http.Response, error) { return r.ApiService.SetTargetConfigExecute(r) } @@ -380,16 +274,19 @@ func (a *TargetConfigAPIService) SetTargetConfig(ctx context.Context) ApiSetTarg } // Execute executes the request -func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequest) (*http.Response, error) { +// +// @return TargetConfig +func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequest) (*TargetConfig, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodPut + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *TargetConfig ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.SetTargetConfig") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } localVarPath := localBasePath + "/target-config" @@ -398,7 +295,7 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ localVarQueryParams := url.Values{} localVarFormParams := url.Values{} if r.targetConfig == nil { - return nil, reportError("targetConfig is required and must be specified") + return localVarReturnValue, nil, reportError("targetConfig is required and must be specified") } // to determine the Content-Type header @@ -411,7 +308,7 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"*/*"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -436,19 +333,19 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -456,8 +353,17 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil } diff --git a/pkg/apiclient/docs/CreateTargetConfigDTO.md b/pkg/apiclient/docs/CreateTargetConfigDTO.md index d657ad325f..0d4e7d7c65 100644 --- a/pkg/apiclient/docs/CreateTargetConfigDTO.md +++ b/pkg/apiclient/docs/CreateTargetConfigDTO.md @@ -6,13 +6,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Name** | **string** | | **Options** | **string** | | -**ProviderInfo** | [**ProviderProviderInfo**](ProviderProviderInfo.md) | | +**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | ## Methods ### NewCreateTargetConfigDTO -`func NewCreateTargetConfigDTO(name string, options string, providerInfo ProviderProviderInfo, ) *CreateTargetConfigDTO` +`func NewCreateTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo, ) *CreateTargetConfigDTO` NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object This constructor will assign default values to properties that have it defined, @@ -69,20 +69,20 @@ SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderProviderInfo` +`func (o *CreateTargetConfigDTO) GetProviderInfo() TargetProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool)` +`func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *CreateTargetConfigDTO) SetProviderInfo(v ProviderProviderInfo)` +`func (o *CreateTargetConfigDTO) SetProviderInfo(v TargetProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/CreateTargetDTO.md b/pkg/apiclient/docs/CreateTargetDTO.md index 5a1dc99c0d..e1b5229371 100644 --- a/pkg/apiclient/docs/CreateTargetDTO.md +++ b/pkg/apiclient/docs/CreateTargetDTO.md @@ -6,13 +6,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Id** | **string** | | **Name** | **string** | | -**TargetConfig** | **string** | | +**TargetConfigName** | **string** | | ## Methods ### NewCreateTargetDTO -`func NewCreateTargetDTO(id string, name string, targetConfig string, ) *CreateTargetDTO` +`func NewCreateTargetDTO(id string, name string, targetConfigName string, ) *CreateTargetDTO` NewCreateTargetDTO instantiates a new CreateTargetDTO object This constructor will assign default values to properties that have it defined, @@ -67,24 +67,24 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetTargetConfig +### GetTargetConfigName -`func (o *CreateTargetDTO) GetTargetConfig() string` +`func (o *CreateTargetDTO) GetTargetConfigName() string` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetTargetConfigName returns the TargetConfigName field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetTargetConfigNameOk -`func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool)` +`func (o *CreateTargetDTO) GetTargetConfigNameOk() (*string, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetTargetConfigNameOk returns a tuple with the TargetConfigName field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetTargetConfigName -`func (o *CreateTargetDTO) SetTargetConfig(v string)` +`func (o *CreateTargetDTO) SetTargetConfigName(v string)` -SetTargetConfig sets TargetConfig field to given value. +SetTargetConfigName sets TargetConfigName field to given value. diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index 0875a578b8..0b847f6831 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -4,15 +4,17 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**Default** | **bool** | | **Id** | **string** | | **Name** | **string** | | -**TargetConfig** | **string** | | +**Options** | **string** | JSON encoded map of options | +**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | ## Methods ### NewTarget -`func NewTarget(id string, name string, targetConfig string, ) *Target` +`func NewTarget(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, ) *Target` NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, @@ -27,6 +29,26 @@ NewTargetWithDefaults instantiates a new Target object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set +### GetDefault + +`func (o *Target) GetDefault() bool` + +GetDefault returns the Default field if non-nil, zero value otherwise. + +### GetDefaultOk + +`func (o *Target) GetDefaultOk() (*bool, bool)` + +GetDefaultOk returns a tuple with the Default field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDefault + +`func (o *Target) SetDefault(v bool)` + +SetDefault sets Default field to given value. + + ### GetId `func (o *Target) GetId() string` @@ -67,24 +89,44 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetTargetConfig +### GetOptions + +`func (o *Target) GetOptions() string` + +GetOptions returns the Options field if non-nil, zero value otherwise. + +### GetOptionsOk + +`func (o *Target) GetOptionsOk() (*string, bool)` + +GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOptions + +`func (o *Target) SetOptions(v string)` + +SetOptions sets Options field to given value. + + +### GetProviderInfo -`func (o *Target) GetTargetConfig() string` +`func (o *Target) GetProviderInfo() TargetProviderInfo` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetProviderInfoOk -`func (o *Target) GetTargetConfigOk() (*string, bool)` +`func (o *Target) GetProviderInfoOk() (*TargetProviderInfo, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetProviderInfo -`func (o *Target) SetTargetConfig(v string)` +`func (o *Target) SetProviderInfo(v TargetProviderInfo)` -SetTargetConfig sets TargetConfig field to given value. +SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index e04e40111c..bacbdd15ef 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -8,6 +8,7 @@ Method | HTTP request | Description [**GetTarget**](TargetAPI.md#GetTarget) | **Get** /target/{targetId} | Get target info [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets [**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target +[**SetDefaultTarget**](TargetAPI.md#SetDefaultTarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target @@ -34,7 +35,7 @@ import ( ) func main() { - target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfig_example") // CreateTargetDTO | Create target + target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfigName_example") // CreateTargetDTO | Create target configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) @@ -287,6 +288,74 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## SetDefaultTarget + +> SetDefaultTarget(ctx, targetId).Execute() + +Set target to be used by default + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + targetId := "targetId_example" // string | Target ID or name + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.TargetAPI.SetDefaultTarget(context.Background(), targetId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetDefaultTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**targetId** | **string** | Target ID or name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiSetDefaultTargetRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## StartTarget > StartTarget(ctx, targetId).Execute() diff --git a/pkg/apiclient/docs/TargetConfig.md b/pkg/apiclient/docs/TargetConfig.md index e11cb57344..07dab01561 100644 --- a/pkg/apiclient/docs/TargetConfig.md +++ b/pkg/apiclient/docs/TargetConfig.md @@ -4,16 +4,15 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**IsDefault** | **bool** | | **Name** | **string** | | **Options** | **string** | JSON encoded map of options | -**ProviderInfo** | [**ProviderProviderInfo**](ProviderProviderInfo.md) | | +**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | ## Methods ### NewTargetConfig -`func NewTargetConfig(isDefault bool, name string, options string, providerInfo ProviderProviderInfo, ) *TargetConfig` +`func NewTargetConfig(name string, options string, providerInfo TargetProviderInfo, ) *TargetConfig` NewTargetConfig instantiates a new TargetConfig object This constructor will assign default values to properties that have it defined, @@ -28,26 +27,6 @@ NewTargetConfigWithDefaults instantiates a new TargetConfig object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set -### GetIsDefault - -`func (o *TargetConfig) GetIsDefault() bool` - -GetIsDefault returns the IsDefault field if non-nil, zero value otherwise. - -### GetIsDefaultOk - -`func (o *TargetConfig) GetIsDefaultOk() (*bool, bool)` - -GetIsDefaultOk returns a tuple with the IsDefault field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetIsDefault - -`func (o *TargetConfig) SetIsDefault(v bool)` - -SetIsDefault sets IsDefault field to given value. - - ### GetName `func (o *TargetConfig) GetName() string` @@ -90,20 +69,20 @@ SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *TargetConfig) GetProviderInfo() ProviderProviderInfo` +`func (o *TargetConfig) GetProviderInfo() TargetProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *TargetConfig) GetProviderInfoOk() (*ProviderProviderInfo, bool)` +`func (o *TargetConfig) GetProviderInfoOk() (*TargetProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *TargetConfig) SetProviderInfo(v ProviderProviderInfo)` +`func (o *TargetConfig) SetProviderInfo(v TargetProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/TargetConfigAPI.md b/pkg/apiclient/docs/TargetConfigAPI.md index 0092483e2e..52bf66380c 100644 --- a/pkg/apiclient/docs/TargetConfigAPI.md +++ b/pkg/apiclient/docs/TargetConfigAPI.md @@ -6,7 +6,6 @@ Method | HTTP request | Description ------------- | ------------- | ------------- [**ListTargetConfigs**](TargetConfigAPI.md#ListTargetConfigs) | **Get** /target-config | List target configs [**RemoveTargetConfig**](TargetConfigAPI.md#RemoveTargetConfig) | **Delete** /target-config/{configName} | Remove a target config -[**SetDefaultTargetConfig**](TargetConfigAPI.md#SetDefaultTargetConfig) | **Patch** /target-config/{configName}/set-default | Set target config to default [**SetTargetConfig**](TargetConfigAPI.md#SetTargetConfig) | **Put** /target-config | Set a target config @@ -140,77 +139,9 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetDefaultTargetConfig - -> SetDefaultTargetConfig(ctx, configName).Execute() - -Set target config to default - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - configName := "configName_example" // string | Target config name - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetConfigAPI.SetDefaultTargetConfig(context.Background(), configName).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.SetDefaultTargetConfig``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Target config name | - -### Other Parameters - -Other parameters are passed through a pointer to a apiSetDefaultTargetConfigRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - ## SetTargetConfig -> SetTargetConfig(ctx).TargetConfig(targetConfig).Execute() +> TargetConfig SetTargetConfig(ctx).TargetConfig(targetConfig).Execute() Set a target config @@ -229,15 +160,17 @@ import ( ) func main() { - targetConfig := *openapiclient.NewCreateTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewProviderProviderInfo("Name_example", "Version_example")) // CreateTargetConfigDTO | Target config to set + targetConfig := *openapiclient.NewCreateTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewTargetProviderInfo("Name_example", "Version_example")) // CreateTargetConfigDTO | Target config to set configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfig).Execute() + resp, r, err := apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfig).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.SetTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `SetTargetConfig`: TargetConfig + fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.SetTargetConfig`: %v\n", resp) } ``` @@ -256,7 +189,7 @@ Name | Type | Description | Notes ### Return type - (empty response body) +[**TargetConfig**](TargetConfig.md) ### Authorization @@ -265,7 +198,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: */* [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index c9c6b8742b..33e2f59480 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -4,16 +4,19 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**Default** | **bool** | | **Id** | **string** | | **Info** | Pointer to [**TargetInfo**](TargetInfo.md) | | [optional] **Name** | **string** | | -**TargetConfig** | **string** | | +**Options** | **string** | JSON encoded map of options | +**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | +**WorkspaceCount** | **int32** | | ## Methods ### NewTargetDTO -`func NewTargetDTO(id string, name string, targetConfig string, ) *TargetDTO` +`func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, workspaceCount int32, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -28,6 +31,26 @@ NewTargetDTOWithDefaults instantiates a new TargetDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set +### GetDefault + +`func (o *TargetDTO) GetDefault() bool` + +GetDefault returns the Default field if non-nil, zero value otherwise. + +### GetDefaultOk + +`func (o *TargetDTO) GetDefaultOk() (*bool, bool)` + +GetDefaultOk returns a tuple with the Default field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDefault + +`func (o *TargetDTO) SetDefault(v bool)` + +SetDefault sets Default field to given value. + + ### GetId `func (o *TargetDTO) GetId() string` @@ -93,24 +116,64 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetTargetConfig +### GetOptions + +`func (o *TargetDTO) GetOptions() string` + +GetOptions returns the Options field if non-nil, zero value otherwise. + +### GetOptionsOk + +`func (o *TargetDTO) GetOptionsOk() (*string, bool)` + +GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetOptions + +`func (o *TargetDTO) SetOptions(v string)` + +SetOptions sets Options field to given value. + + +### GetProviderInfo + +`func (o *TargetDTO) GetProviderInfo() TargetProviderInfo` + +GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. + +### GetProviderInfoOk + +`func (o *TargetDTO) GetProviderInfoOk() (*TargetProviderInfo, bool)` + +GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviderInfo + +`func (o *TargetDTO) SetProviderInfo(v TargetProviderInfo)` + +SetProviderInfo sets ProviderInfo field to given value. + + +### GetWorkspaceCount -`func (o *TargetDTO) GetTargetConfig() string` +`func (o *TargetDTO) GetWorkspaceCount() int32` -GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. +GetWorkspaceCount returns the WorkspaceCount field if non-nil, zero value otherwise. -### GetTargetConfigOk +### GetWorkspaceCountOk -`func (o *TargetDTO) GetTargetConfigOk() (*string, bool)` +`func (o *TargetDTO) GetWorkspaceCountOk() (*int32, bool)` -GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise +GetWorkspaceCountOk returns a tuple with the WorkspaceCount field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfig +### SetWorkspaceCount -`func (o *TargetDTO) SetTargetConfig(v string)` +`func (o *TargetDTO) SetWorkspaceCount(v int32)` -SetTargetConfig sets TargetConfig field to given value. +SetWorkspaceCount sets WorkspaceCount field to given value. diff --git a/pkg/apiclient/docs/ProviderProviderInfo.md b/pkg/apiclient/docs/TargetProviderInfo.md similarity index 64% rename from pkg/apiclient/docs/ProviderProviderInfo.md rename to pkg/apiclient/docs/TargetProviderInfo.md index a20bd6d5a0..22bcc30ffa 100644 --- a/pkg/apiclient/docs/ProviderProviderInfo.md +++ b/pkg/apiclient/docs/TargetProviderInfo.md @@ -1,4 +1,4 @@ -# ProviderProviderInfo +# TargetProviderInfo ## Properties @@ -10,84 +10,84 @@ Name | Type | Description | Notes ## Methods -### NewProviderProviderInfo +### NewTargetProviderInfo -`func NewProviderProviderInfo(name string, version string, ) *ProviderProviderInfo` +`func NewTargetProviderInfo(name string, version string, ) *TargetProviderInfo` -NewProviderProviderInfo instantiates a new ProviderProviderInfo object +NewTargetProviderInfo instantiates a new TargetProviderInfo object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewProviderProviderInfoWithDefaults +### NewTargetProviderInfoWithDefaults -`func NewProviderProviderInfoWithDefaults() *ProviderProviderInfo` +`func NewTargetProviderInfoWithDefaults() *TargetProviderInfo` -NewProviderProviderInfoWithDefaults instantiates a new ProviderProviderInfo object +NewTargetProviderInfoWithDefaults instantiates a new TargetProviderInfo object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetLabel -`func (o *ProviderProviderInfo) GetLabel() string` +`func (o *TargetProviderInfo) GetLabel() string` GetLabel returns the Label field if non-nil, zero value otherwise. ### GetLabelOk -`func (o *ProviderProviderInfo) GetLabelOk() (*string, bool)` +`func (o *TargetProviderInfo) GetLabelOk() (*string, bool)` GetLabelOk returns a tuple with the Label field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetLabel -`func (o *ProviderProviderInfo) SetLabel(v string)` +`func (o *TargetProviderInfo) SetLabel(v string)` SetLabel sets Label field to given value. ### HasLabel -`func (o *ProviderProviderInfo) HasLabel() bool` +`func (o *TargetProviderInfo) HasLabel() bool` HasLabel returns a boolean if a field has been set. ### GetName -`func (o *ProviderProviderInfo) GetName() string` +`func (o *TargetProviderInfo) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *ProviderProviderInfo) GetNameOk() (*string, bool)` +`func (o *TargetProviderInfo) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *ProviderProviderInfo) SetName(v string)` +`func (o *TargetProviderInfo) SetName(v string)` SetName sets Name field to given value. ### GetVersion -`func (o *ProviderProviderInfo) GetVersion() string` +`func (o *TargetProviderInfo) GetVersion() string` GetVersion returns the Version field if non-nil, zero value otherwise. ### GetVersionOk -`func (o *ProviderProviderInfo) GetVersionOk() (*string, bool)` +`func (o *TargetProviderInfo) GetVersionOk() (*string, bool)` GetVersionOk returns a tuple with the Version field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetVersion -`func (o *ProviderProviderInfo) SetVersion(v string)` +`func (o *TargetProviderInfo) SetVersion(v string)` SetVersion sets Version field to given value. diff --git a/pkg/apiclient/model_create_target_config_dto.go b/pkg/apiclient/model_create_target_config_dto.go index 03616bf004..27d4617618 100644 --- a/pkg/apiclient/model_create_target_config_dto.go +++ b/pkg/apiclient/model_create_target_config_dto.go @@ -21,9 +21,9 @@ var _ MappedNullable = &CreateTargetConfigDTO{} // CreateTargetConfigDTO struct for CreateTargetConfigDTO type CreateTargetConfigDTO struct { - Name string `json:"name"` - Options string `json:"options"` - ProviderInfo ProviderProviderInfo `json:"providerInfo"` + Name string `json:"name"` + Options string `json:"options"` + ProviderInfo TargetProviderInfo `json:"providerInfo"` } type _CreateTargetConfigDTO CreateTargetConfigDTO @@ -32,7 +32,7 @@ type _CreateTargetConfigDTO CreateTargetConfigDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateTargetConfigDTO(name string, options string, providerInfo ProviderProviderInfo) *CreateTargetConfigDTO { +func NewCreateTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo) *CreateTargetConfigDTO { this := CreateTargetConfigDTO{} this.Name = name this.Options = options @@ -97,9 +97,9 @@ func (o *CreateTargetConfigDTO) SetOptions(v string) { } // GetProviderInfo returns the ProviderInfo field value -func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderProviderInfo { +func (o *CreateTargetConfigDTO) GetProviderInfo() TargetProviderInfo { if o == nil { - var ret ProviderProviderInfo + var ret TargetProviderInfo return ret } @@ -108,7 +108,7 @@ func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool) { +func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { if o == nil { return nil, false } @@ -116,7 +116,7 @@ func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderProviderInfo, bool } // SetProviderInfo sets field value -func (o *CreateTargetConfigDTO) SetProviderInfo(v ProviderProviderInfo) { +func (o *CreateTargetConfigDTO) SetProviderInfo(v TargetProviderInfo) { o.ProviderInfo = v } diff --git a/pkg/apiclient/model_create_target_dto.go b/pkg/apiclient/model_create_target_dto.go index b4e403a84d..c38a711e60 100644 --- a/pkg/apiclient/model_create_target_dto.go +++ b/pkg/apiclient/model_create_target_dto.go @@ -21,9 +21,9 @@ var _ MappedNullable = &CreateTargetDTO{} // CreateTargetDTO struct for CreateTargetDTO type CreateTargetDTO struct { - Id string `json:"id"` - Name string `json:"name"` - TargetConfig string `json:"targetConfig"` + Id string `json:"id"` + Name string `json:"name"` + TargetConfigName string `json:"targetConfigName"` } type _CreateTargetDTO CreateTargetDTO @@ -32,11 +32,11 @@ type _CreateTargetDTO CreateTargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateTargetDTO(id string, name string, targetConfig string) *CreateTargetDTO { +func NewCreateTargetDTO(id string, name string, targetConfigName string) *CreateTargetDTO { this := CreateTargetDTO{} this.Id = id this.Name = name - this.TargetConfig = targetConfig + this.TargetConfigName = targetConfigName return &this } @@ -96,28 +96,28 @@ func (o *CreateTargetDTO) SetName(v string) { o.Name = v } -// GetTargetConfig returns the TargetConfig field value -func (o *CreateTargetDTO) GetTargetConfig() string { +// GetTargetConfigName returns the TargetConfigName field value +func (o *CreateTargetDTO) GetTargetConfigName() string { if o == nil { var ret string return ret } - return o.TargetConfig + return o.TargetConfigName } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetTargetConfigNameOk returns a tuple with the TargetConfigName field value // and a boolean to check if the value has been set. -func (o *CreateTargetDTO) GetTargetConfigOk() (*string, bool) { +func (o *CreateTargetDTO) GetTargetConfigNameOk() (*string, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return &o.TargetConfigName, true } -// SetTargetConfig sets field value -func (o *CreateTargetDTO) SetTargetConfig(v string) { - o.TargetConfig = v +// SetTargetConfigName sets field value +func (o *CreateTargetDTO) SetTargetConfigName(v string) { + o.TargetConfigName = v } func (o CreateTargetDTO) MarshalJSON() ([]byte, error) { @@ -132,7 +132,7 @@ func (o CreateTargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name - toSerialize["targetConfig"] = o.TargetConfig + toSerialize["targetConfigName"] = o.TargetConfigName return toSerialize, nil } @@ -143,7 +143,7 @@ func (o *CreateTargetDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "id", "name", - "targetConfig", + "targetConfigName", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index 064753b9f8..8828ee4b68 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -21,9 +21,12 @@ var _ MappedNullable = &Target{} // Target struct for Target type Target struct { - Id string `json:"id"` - Name string `json:"name"` - TargetConfig string `json:"targetConfig"` + Default bool `json:"default"` + Id string `json:"id"` + Name string `json:"name"` + // JSON encoded map of options + Options string `json:"options"` + ProviderInfo TargetProviderInfo `json:"providerInfo"` } type _Target Target @@ -32,11 +35,13 @@ type _Target Target // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTarget(id string, name string, targetConfig string) *Target { +func NewTarget(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo) *Target { this := Target{} + this.Default = default_ this.Id = id this.Name = name - this.TargetConfig = targetConfig + this.Options = options + this.ProviderInfo = providerInfo return &this } @@ -48,6 +53,30 @@ func NewTargetWithDefaults() *Target { return &this } +// GetDefault returns the Default field value +func (o *Target) GetDefault() bool { + if o == nil { + var ret bool + return ret + } + + return o.Default +} + +// GetDefaultOk returns a tuple with the Default field value +// and a boolean to check if the value has been set. +func (o *Target) GetDefaultOk() (*bool, bool) { + if o == nil { + return nil, false + } + return &o.Default, true +} + +// SetDefault sets field value +func (o *Target) SetDefault(v bool) { + o.Default = v +} + // GetId returns the Id field value func (o *Target) GetId() string { if o == nil { @@ -96,28 +125,52 @@ func (o *Target) SetName(v string) { o.Name = v } -// GetTargetConfig returns the TargetConfig field value -func (o *Target) GetTargetConfig() string { +// GetOptions returns the Options field value +func (o *Target) GetOptions() string { if o == nil { var ret string return ret } - return o.TargetConfig + return o.Options +} + +// GetOptionsOk returns a tuple with the Options field value +// and a boolean to check if the value has been set. +func (o *Target) GetOptionsOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Options, true +} + +// SetOptions sets field value +func (o *Target) SetOptions(v string) { + o.Options = v +} + +// GetProviderInfo returns the ProviderInfo field value +func (o *Target) GetProviderInfo() TargetProviderInfo { + if o == nil { + var ret TargetProviderInfo + return ret + } + + return o.ProviderInfo } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *Target) GetTargetConfigOk() (*string, bool) { +func (o *Target) GetProviderInfoOk() (*TargetProviderInfo, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return &o.ProviderInfo, true } -// SetTargetConfig sets field value -func (o *Target) SetTargetConfig(v string) { - o.TargetConfig = v +// SetProviderInfo sets field value +func (o *Target) SetProviderInfo(v TargetProviderInfo) { + o.ProviderInfo = v } func (o Target) MarshalJSON() ([]byte, error) { @@ -130,9 +183,11 @@ func (o Target) MarshalJSON() ([]byte, error) { func (o Target) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} + toSerialize["default"] = o.Default toSerialize["id"] = o.Id toSerialize["name"] = o.Name - toSerialize["targetConfig"] = o.TargetConfig + toSerialize["options"] = o.Options + toSerialize["providerInfo"] = o.ProviderInfo return toSerialize, nil } @@ -141,9 +196,11 @@ func (o *Target) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ + "default", "id", "name", - "targetConfig", + "options", + "providerInfo", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_config.go b/pkg/apiclient/model_target_config.go index faf208fb39..3a0f45f701 100644 --- a/pkg/apiclient/model_target_config.go +++ b/pkg/apiclient/model_target_config.go @@ -21,11 +21,10 @@ var _ MappedNullable = &TargetConfig{} // TargetConfig struct for TargetConfig type TargetConfig struct { - IsDefault bool `json:"isDefault"` - Name string `json:"name"` + Name string `json:"name"` // JSON encoded map of options - Options string `json:"options"` - ProviderInfo ProviderProviderInfo `json:"providerInfo"` + Options string `json:"options"` + ProviderInfo TargetProviderInfo `json:"providerInfo"` } type _TargetConfig TargetConfig @@ -34,9 +33,8 @@ type _TargetConfig TargetConfig // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetConfig(isDefault bool, name string, options string, providerInfo ProviderProviderInfo) *TargetConfig { +func NewTargetConfig(name string, options string, providerInfo TargetProviderInfo) *TargetConfig { this := TargetConfig{} - this.IsDefault = isDefault this.Name = name this.Options = options this.ProviderInfo = providerInfo @@ -51,30 +49,6 @@ func NewTargetConfigWithDefaults() *TargetConfig { return &this } -// GetIsDefault returns the IsDefault field value -func (o *TargetConfig) GetIsDefault() bool { - if o == nil { - var ret bool - return ret - } - - return o.IsDefault -} - -// GetIsDefaultOk returns a tuple with the IsDefault field value -// and a boolean to check if the value has been set. -func (o *TargetConfig) GetIsDefaultOk() (*bool, bool) { - if o == nil { - return nil, false - } - return &o.IsDefault, true -} - -// SetIsDefault sets field value -func (o *TargetConfig) SetIsDefault(v bool) { - o.IsDefault = v -} - // GetName returns the Name field value func (o *TargetConfig) GetName() string { if o == nil { @@ -124,9 +98,9 @@ func (o *TargetConfig) SetOptions(v string) { } // GetProviderInfo returns the ProviderInfo field value -func (o *TargetConfig) GetProviderInfo() ProviderProviderInfo { +func (o *TargetConfig) GetProviderInfo() TargetProviderInfo { if o == nil { - var ret ProviderProviderInfo + var ret TargetProviderInfo return ret } @@ -135,7 +109,7 @@ func (o *TargetConfig) GetProviderInfo() ProviderProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *TargetConfig) GetProviderInfoOk() (*ProviderProviderInfo, bool) { +func (o *TargetConfig) GetProviderInfoOk() (*TargetProviderInfo, bool) { if o == nil { return nil, false } @@ -143,7 +117,7 @@ func (o *TargetConfig) GetProviderInfoOk() (*ProviderProviderInfo, bool) { } // SetProviderInfo sets field value -func (o *TargetConfig) SetProviderInfo(v ProviderProviderInfo) { +func (o *TargetConfig) SetProviderInfo(v TargetProviderInfo) { o.ProviderInfo = v } @@ -157,7 +131,6 @@ func (o TargetConfig) MarshalJSON() ([]byte, error) { func (o TargetConfig) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} - toSerialize["isDefault"] = o.IsDefault toSerialize["name"] = o.Name toSerialize["options"] = o.Options toSerialize["providerInfo"] = o.ProviderInfo @@ -169,7 +142,6 @@ func (o *TargetConfig) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ - "isDefault", "name", "options", "providerInfo", diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index bfaa4c5a09..2808022c4a 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -21,10 +21,14 @@ var _ MappedNullable = &TargetDTO{} // TargetDTO struct for TargetDTO type TargetDTO struct { - Id string `json:"id"` - Info *TargetInfo `json:"info,omitempty"` - Name string `json:"name"` - TargetConfig string `json:"targetConfig"` + Default bool `json:"default"` + Id string `json:"id"` + Info *TargetInfo `json:"info,omitempty"` + Name string `json:"name"` + // JSON encoded map of options + Options string `json:"options"` + ProviderInfo TargetProviderInfo `json:"providerInfo"` + WorkspaceCount int32 `json:"workspaceCount"` } type _TargetDTO TargetDTO @@ -33,11 +37,14 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(id string, name string, targetConfig string) *TargetDTO { +func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, workspaceCount int32) *TargetDTO { this := TargetDTO{} + this.Default = default_ this.Id = id this.Name = name - this.TargetConfig = targetConfig + this.Options = options + this.ProviderInfo = providerInfo + this.WorkspaceCount = workspaceCount return &this } @@ -49,6 +56,30 @@ func NewTargetDTOWithDefaults() *TargetDTO { return &this } +// GetDefault returns the Default field value +func (o *TargetDTO) GetDefault() bool { + if o == nil { + var ret bool + return ret + } + + return o.Default +} + +// GetDefaultOk returns a tuple with the Default field value +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetDefaultOk() (*bool, bool) { + if o == nil { + return nil, false + } + return &o.Default, true +} + +// SetDefault sets field value +func (o *TargetDTO) SetDefault(v bool) { + o.Default = v +} + // GetId returns the Id field value func (o *TargetDTO) GetId() string { if o == nil { @@ -129,28 +160,76 @@ func (o *TargetDTO) SetName(v string) { o.Name = v } -// GetTargetConfig returns the TargetConfig field value -func (o *TargetDTO) GetTargetConfig() string { +// GetOptions returns the Options field value +func (o *TargetDTO) GetOptions() string { if o == nil { var ret string return ret } - return o.TargetConfig + return o.Options +} + +// GetOptionsOk returns a tuple with the Options field value +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetOptionsOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Options, true +} + +// SetOptions sets field value +func (o *TargetDTO) SetOptions(v string) { + o.Options = v +} + +// GetProviderInfo returns the ProviderInfo field value +func (o *TargetDTO) GetProviderInfo() TargetProviderInfo { + if o == nil { + var ret TargetProviderInfo + return ret + } + + return o.ProviderInfo +} + +// GetProviderInfoOk returns a tuple with the ProviderInfo field value +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { + if o == nil { + return nil, false + } + return &o.ProviderInfo, true +} + +// SetProviderInfo sets field value +func (o *TargetDTO) SetProviderInfo(v TargetProviderInfo) { + o.ProviderInfo = v +} + +// GetWorkspaceCount returns the WorkspaceCount field value +func (o *TargetDTO) GetWorkspaceCount() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.WorkspaceCount } -// GetTargetConfigOk returns a tuple with the TargetConfig field value +// GetWorkspaceCountOk returns a tuple with the WorkspaceCount field value // and a boolean to check if the value has been set. -func (o *TargetDTO) GetTargetConfigOk() (*string, bool) { +func (o *TargetDTO) GetWorkspaceCountOk() (*int32, bool) { if o == nil { return nil, false } - return &o.TargetConfig, true + return &o.WorkspaceCount, true } -// SetTargetConfig sets field value -func (o *TargetDTO) SetTargetConfig(v string) { - o.TargetConfig = v +// SetWorkspaceCount sets field value +func (o *TargetDTO) SetWorkspaceCount(v int32) { + o.WorkspaceCount = v } func (o TargetDTO) MarshalJSON() ([]byte, error) { @@ -163,12 +242,15 @@ func (o TargetDTO) MarshalJSON() ([]byte, error) { func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} + toSerialize["default"] = o.Default toSerialize["id"] = o.Id if !IsNil(o.Info) { toSerialize["info"] = o.Info } toSerialize["name"] = o.Name - toSerialize["targetConfig"] = o.TargetConfig + toSerialize["options"] = o.Options + toSerialize["providerInfo"] = o.ProviderInfo + toSerialize["workspaceCount"] = o.WorkspaceCount return toSerialize, nil } @@ -177,9 +259,12 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ + "default", "id", "name", - "targetConfig", + "options", + "providerInfo", + "workspaceCount", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_provider_provider_info.go b/pkg/apiclient/model_target_provider_info.go similarity index 60% rename from pkg/apiclient/model_provider_provider_info.go rename to pkg/apiclient/model_target_provider_info.go index 070852d9c1..8209f2b62a 100644 --- a/pkg/apiclient/model_provider_provider_info.go +++ b/pkg/apiclient/model_target_provider_info.go @@ -16,39 +16,39 @@ import ( "fmt" ) -// checks if the ProviderProviderInfo type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProviderProviderInfo{} +// checks if the TargetProviderInfo type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TargetProviderInfo{} -// ProviderProviderInfo struct for ProviderProviderInfo -type ProviderProviderInfo struct { +// TargetProviderInfo struct for TargetProviderInfo +type TargetProviderInfo struct { Label *string `json:"label,omitempty"` Name string `json:"name"` Version string `json:"version"` } -type _ProviderProviderInfo ProviderProviderInfo +type _TargetProviderInfo TargetProviderInfo -// NewProviderProviderInfo instantiates a new ProviderProviderInfo object +// NewTargetProviderInfo instantiates a new TargetProviderInfo object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProviderProviderInfo(name string, version string) *ProviderProviderInfo { - this := ProviderProviderInfo{} +func NewTargetProviderInfo(name string, version string) *TargetProviderInfo { + this := TargetProviderInfo{} this.Name = name this.Version = version return &this } -// NewProviderProviderInfoWithDefaults instantiates a new ProviderProviderInfo object +// NewTargetProviderInfoWithDefaults instantiates a new TargetProviderInfo object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewProviderProviderInfoWithDefaults() *ProviderProviderInfo { - this := ProviderProviderInfo{} +func NewTargetProviderInfoWithDefaults() *TargetProviderInfo { + this := TargetProviderInfo{} return &this } // GetLabel returns the Label field value if set, zero value otherwise. -func (o *ProviderProviderInfo) GetLabel() string { +func (o *TargetProviderInfo) GetLabel() string { if o == nil || IsNil(o.Label) { var ret string return ret @@ -58,7 +58,7 @@ func (o *ProviderProviderInfo) GetLabel() string { // GetLabelOk returns a tuple with the Label field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ProviderProviderInfo) GetLabelOk() (*string, bool) { +func (o *TargetProviderInfo) GetLabelOk() (*string, bool) { if o == nil || IsNil(o.Label) { return nil, false } @@ -66,7 +66,7 @@ func (o *ProviderProviderInfo) GetLabelOk() (*string, bool) { } // HasLabel returns a boolean if a field has been set. -func (o *ProviderProviderInfo) HasLabel() bool { +func (o *TargetProviderInfo) HasLabel() bool { if o != nil && !IsNil(o.Label) { return true } @@ -75,12 +75,12 @@ func (o *ProviderProviderInfo) HasLabel() bool { } // SetLabel gets a reference to the given string and assigns it to the Label field. -func (o *ProviderProviderInfo) SetLabel(v string) { +func (o *TargetProviderInfo) SetLabel(v string) { o.Label = &v } // GetName returns the Name field value -func (o *ProviderProviderInfo) GetName() string { +func (o *TargetProviderInfo) GetName() string { if o == nil { var ret string return ret @@ -91,7 +91,7 @@ func (o *ProviderProviderInfo) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *ProviderProviderInfo) GetNameOk() (*string, bool) { +func (o *TargetProviderInfo) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -99,12 +99,12 @@ func (o *ProviderProviderInfo) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *ProviderProviderInfo) SetName(v string) { +func (o *TargetProviderInfo) SetName(v string) { o.Name = v } // GetVersion returns the Version field value -func (o *ProviderProviderInfo) GetVersion() string { +func (o *TargetProviderInfo) GetVersion() string { if o == nil { var ret string return ret @@ -115,7 +115,7 @@ func (o *ProviderProviderInfo) GetVersion() string { // GetVersionOk returns a tuple with the Version field value // and a boolean to check if the value has been set. -func (o *ProviderProviderInfo) GetVersionOk() (*string, bool) { +func (o *TargetProviderInfo) GetVersionOk() (*string, bool) { if o == nil { return nil, false } @@ -123,11 +123,11 @@ func (o *ProviderProviderInfo) GetVersionOk() (*string, bool) { } // SetVersion sets field value -func (o *ProviderProviderInfo) SetVersion(v string) { +func (o *TargetProviderInfo) SetVersion(v string) { o.Version = v } -func (o ProviderProviderInfo) MarshalJSON() ([]byte, error) { +func (o TargetProviderInfo) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -135,7 +135,7 @@ func (o ProviderProviderInfo) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ProviderProviderInfo) ToMap() (map[string]interface{}, error) { +func (o TargetProviderInfo) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.Label) { toSerialize["label"] = o.Label @@ -145,7 +145,7 @@ func (o ProviderProviderInfo) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *ProviderProviderInfo) UnmarshalJSON(data []byte) (err error) { +func (o *TargetProviderInfo) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -168,53 +168,53 @@ func (o *ProviderProviderInfo) UnmarshalJSON(data []byte) (err error) { } } - varProviderProviderInfo := _ProviderProviderInfo{} + varTargetProviderInfo := _TargetProviderInfo{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varProviderProviderInfo) + err = decoder.Decode(&varTargetProviderInfo) if err != nil { return err } - *o = ProviderProviderInfo(varProviderProviderInfo) + *o = TargetProviderInfo(varTargetProviderInfo) return err } -type NullableProviderProviderInfo struct { - value *ProviderProviderInfo +type NullableTargetProviderInfo struct { + value *TargetProviderInfo isSet bool } -func (v NullableProviderProviderInfo) Get() *ProviderProviderInfo { +func (v NullableTargetProviderInfo) Get() *TargetProviderInfo { return v.value } -func (v *NullableProviderProviderInfo) Set(val *ProviderProviderInfo) { +func (v *NullableTargetProviderInfo) Set(val *TargetProviderInfo) { v.value = val v.isSet = true } -func (v NullableProviderProviderInfo) IsSet() bool { +func (v NullableTargetProviderInfo) IsSet() bool { return v.isSet } -func (v *NullableProviderProviderInfo) Unset() { +func (v *NullableTargetProviderInfo) Unset() { v.value = nil v.isSet = false } -func NewNullableProviderProviderInfo(val *ProviderProviderInfo) *NullableProviderProviderInfo { - return &NullableProviderProviderInfo{value: val, isSet: true} +func NewNullableTargetProviderInfo(val *TargetProviderInfo) *NullableTargetProviderInfo { + return &NullableTargetProviderInfo{value: val, isSet: true} } -func (v NullableProviderProviderInfo) MarshalJSON() ([]byte, error) { +func (v NullableTargetProviderInfo) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableProviderProviderInfo) UnmarshalJSON(src []byte) error { +func (v *NullableTargetProviderInfo) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/build/devcontainer.go b/pkg/build/devcontainer.go index 9aa87f85a6..7db816de04 100644 --- a/pkg/build/devcontainer.go +++ b/pkg/build/devcontainer.go @@ -84,7 +84,7 @@ func (b *DevcontainerBuilder) buildDevcontainer(build Build) (string, string, er containerId, remoteUser, err := dockerClient.CreateFromDevcontainer(docker.CreateDevcontainerOptions{ BuildConfig: build.BuildConfig, - WorkspaceName: build.Id, + WorkspaceFolderName: build.Id, ContainerRegistry: b.buildImageContainerRegistry, BuilderImage: b.image, BuilderContainerRegistry: b.containerRegistry, diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index 46dfffb4c2..ee1ebf21bf 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -57,7 +57,7 @@ var AgentCmd = &cobra.Command{ if err != nil { return err } - c.WorkspaceDir = filepath.Join(os.Getenv("HOME"), ws.Name) + c.WorkspaceDir = filepath.Join(os.Getenv("HOME"), ws.WorkspaceFolderName()) } configDir, err := config.GetConfigDir() @@ -98,9 +98,9 @@ var AgentCmd = &cobra.Command{ DefaultWorkspaceDir: os.Getenv("HOME"), } - tailscaleHostname := workspace.GetWorkspaceHostname(c.WorkspaceId) - if hostModeFlag { - tailscaleHostname = c.TargetId + tailscaleHostname := c.TargetId + if agentMode == agent_config.ModeWorkspace { + tailscaleHostname = workspace.GetWorkspaceHostname(c.WorkspaceId) } toolBoxServer := &toolbox.Server{ diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go index cb01706f8b..369b5106f5 100644 --- a/pkg/cmd/agentmode/agent_mode.go +++ b/pkg/cmd/agentmode/agent_mode.go @@ -41,6 +41,7 @@ func Execute() error { agentModeRootCmd.AddCommand(infoCmd) agentModeRootCmd.AddCommand(portForwardCmd) agentModeRootCmd.AddCommand(exposeCmd) + agentModeRootCmd.AddCommand(logsCmd) clientId := config.GetClientId() telemetryEnabled := config.TelemetryEnabled() diff --git a/pkg/cmd/agentmode/logs.go b/pkg/cmd/agentmode/logs.go new file mode 100644 index 0000000000..0f41b852d7 --- /dev/null +++ b/pkg/cmd/agentmode/logs.go @@ -0,0 +1,22 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package agentmode + +import ( + "errors" + + "github.com/daytonaio/daytona/internal/util" + "github.com/spf13/cobra" +) + +var logsCmd = &cobra.Command{ + Use: "logs", + Short: "View logs for the workspace", + Args: cobra.NoArgs, + GroupID: util.TARGET_GROUP, + Aliases: []string{"lg", "log"}, + RunE: func(cmd *cobra.Command, args []string) error { + return errors.New("not implemented") + }, +} diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index 143b9162b8..d9df00bf35 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -68,7 +68,11 @@ var buildLogsCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(nil, err) } - apiclient_util.ReadBuildLogs(ctx, activeProfile, buildId, query) + apiclient_util.ReadBuildLogs(ctx, apiclient_util.ReadLogParams{ + Id: buildId, + ActiveProfile: activeProfile, + Query: &query, + }) // Make sure the terminal cursor is reset fmt.Print("\033[?25h") diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index 5e387c7be3..774a76c747 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" @@ -45,7 +45,7 @@ var buildRunCmd = &cobra.Command{ return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := workspace_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := create.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 7de69fe7ac..e934d03147 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -29,6 +29,7 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/targetconfig" . "github.com/daytonaio/daytona/pkg/cmd/telemetry" . "github.com/daytonaio/daytona/pkg/cmd/workspace" + . "github.com/daytonaio/daytona/pkg/cmd/workspace/create" . "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/posthogservice" @@ -75,8 +76,9 @@ func Execute() error { rootCmd.AddCommand(purgeCmd) rootCmd.AddCommand(GitProviderCmd) rootCmd.AddCommand(StartCmd) - // rootCmd.AddCommand(StopCmd) - // rootCmd.AddCommand(RestartCmd) + rootCmd.AddCommand(StopCmd) + rootCmd.AddCommand(RestartCmd) + rootCmd.AddCommand(LogsCmd) rootCmd.AddCommand(InfoCmd) rootCmd.AddCommand(PrebuildCmd) rootCmd.AddCommand(BuildCmd) @@ -155,7 +157,6 @@ func SetupRootCommand(cmd *cobra.Command) { cmd.AddCommand(ListCmd) cmd.AddCommand(generateDocsCmd) cmd.AddCommand(DocsCmd) - cmd.AddCommand(logsCmd) cmd.CompletionOptions.HiddenDefaultCmd = true cmd.PersistentFlags().BoolP("help", "", false, "help for daytona") diff --git a/pkg/cmd/logs.go b/pkg/cmd/logs.go deleted file mode 100644 index eace2be835..0000000000 --- a/pkg/cmd/logs.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package cmd - -import ( - "errors" - - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var followFlag bool -var targetFlag bool - -var logsCmd = &cobra.Command{ - Use: "logs [TARGET] [WORKSPACE_NAME]", - Short: "View logs for a target/workspace", - Args: cobra.RangeArgs(0, 2), - GroupID: util.TARGET_GROUP, - Aliases: []string{"lg", "log"}, - RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") - }, - // RunE: func(cmd *cobra.Command, args []string) error { - // ctx := context.Background() - // c, err := config.GetConfig() - // if err != nil { - // return err - // } - - // activeProfile, err := c.GetActiveProfile() - // if err != nil { - // return err - // } - - // var target *apiclient.TargetDTO - // apiClient, err := apiclient_util.GetApiClient(&activeProfile) - // if err != nil { - // return err - // } - - // var ( - // showTargetLogs = true - // workspaceNames []string - // ) - - // if len(args) == 0 { - // targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() - // if err != nil { - // return apiclient_util.HandleErrorResponse(res, err) - // } - // if len(targetList) == 0 { - // views.RenderInfoMessage("The target list is empty. Start off by running 'daytona create'.") - // return nil - // } - // target = selection.GetTargetFromPrompt(targetList, "Get Logs For") - // } else { - // target, err = apiclient_util.GetTarget(args[0], false) - // if err != nil { - // return err - // } - // } - - // if target == nil { - // return errors.New("target not found") - // } else if len(target.Workspaces) == 0 { - // return errors.New("no workspaces found in target") - // } - - // if len(args) == 2 { - // workspaces := util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - // return w.Name - // }) - // var found bool - // for _, workspace := range workspaces { - // if workspace == args[1] { - // found = true - // break - // } - // } - // if !found { - // return errors.New("workspace not found in target") - // } - // workspaceNames = append(workspaceNames, args[1]) - // if targetFlag { - // showTargetLogs = true - // } else { - // showTargetLogs = false - // } - // } else if !targetFlag { - // workspaceNames = util.ArrayMap(target.Workspaces, func(w apiclient.Workspace) string { - // return w.Name - // }) - // } - - // apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, workspaceNames, followFlag, showTargetLogs, nil) - - // return nil - // }, -} - -func init() { - logsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") - logsCmd.Flags().BoolVarP(&targetFlag, "target", "w", false, "View target logs") -} diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/add.go index eaea7c283f..1058988332 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/add.go @@ -13,7 +13,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" @@ -75,7 +75,7 @@ var prebuildAddCmd = &cobra.Command{ return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := workspace_util.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := create.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index 5c3c886c24..6b3991906c 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -21,6 +21,7 @@ import ( provider_view "github.com/daytonaio/daytona/pkg/views/provider" "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/docker/docker/pkg/stringid" "github.com/spf13/cobra" ) @@ -100,12 +101,12 @@ var providerInstallCmd = &cobra.Command{ views.RenderInfoMessageBold(fmt.Sprintf("Provider %s has been successfully installed", providerToInstall.Name)) - targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).Execute() + targets, res, err := apiClient.TargetAPI.ListTargets(context.Background()).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if slices.ContainsFunc(targetConfigs, func(t apiclient.TargetConfig) bool { + if slices.ContainsFunc(targets, func(t apiclient.TargetDTO) bool { return t.ProviderInfo.Name == providerToInstall.Name }) { return nil @@ -115,7 +116,7 @@ var providerInstallCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title("Add a Target Config?"). + Title("Add a Target?"). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -137,6 +138,7 @@ var providerInstallCmd = &cobra.Command{ ProviderInfo: targetconfig.ProviderInfo{ Name: providerToInstall.Name, Version: providerToInstall.Version, + Label: providerToInstall.Label, }, } @@ -150,16 +152,16 @@ var providerInstallCmd = &cobra.Command{ return err } - targetConfigData := apiclient.CreateTargetConfigDTO{ - Name: targetConfigToSet.Name, - Options: targetConfigToSet.Options, - ProviderInfo: apiclient.ProviderProviderInfo{ - Name: targetConfigToSet.ProviderInfo.Name, - Version: targetConfigToSet.ProviderInfo.Version, - }, + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + + targetData := apiclient.CreateTargetDTO{ + Id: id, + Name: targetConfigToSet.Name, + TargetConfigName: targetConfigToSet.Name, } - res, err = apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() + _, res, err = apiClient.TargetAPI.CreateTarget(context.Background()).Target(targetData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -167,7 +169,7 @@ var providerInstallCmd = &cobra.Command{ return err } - views.RenderInfoMessage("Target Config set successfully") + views.RenderInfoMessage("Target set successfully") } return nil }, diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 0fb30e3986..7ea4d5d38c 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -14,6 +14,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/build" server_cmd "github.com/daytonaio/daytona/pkg/cmd/server" + "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/telemetry" @@ -23,7 +24,6 @@ import ( "github.com/spf13/cobra" ) -var yesFlag bool var forceFlag bool var purgeCmd = &cobra.Command{ @@ -57,7 +57,7 @@ var purgeCmd = &cobra.Command{ } if c.ActiveProfileId != "default" { - if !yesFlag { + if !create.YesFlag { view.DefaultProfileNoticePrompt(&defaultProfileNoticeConfirm) if !defaultProfileNoticeConfirm { fmt.Println("Operation cancelled.") @@ -90,7 +90,7 @@ var purgeCmd = &cobra.Command{ } } - if !yesFlag { + if !create.YesFlag { view.ConfirmPrompt(&confirmCheck) if !confirmCheck { fmt.Println("Operation cancelled.") @@ -240,6 +240,6 @@ var purgeCmd = &cobra.Command{ } func init() { - purgeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Execute purge without prompt") + purgeCmd.Flags().BoolVarP(&create.YesFlag, "yes", "y", false, "Execute purge without prompt") purgeCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete all targets by force") } diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index afb8731ad3..971f3341bf 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -362,13 +362,11 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ WorkspaceStore: workspaceStore, TargetStore: targetStore, - TargetConfigStore: targetConfigStore, ApiKeyService: apiKeyService, GitProviderService: gitProviderService, ContainerRegistryService: containerRegistryService, BuilderImage: c.BuilderImage, BuildService: buildService, - WorkspaceConfigService: workspaceConfigService, ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), ServerVersion: version, ServerUrl: headscaleUrl, diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go new file mode 100644 index 0000000000..ea563cfec4 --- /dev/null +++ b/pkg/cmd/target/create.go @@ -0,0 +1,158 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/cmd/targetconfig" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/views" + logs_view "github.com/daytonaio/daytona/pkg/views/logs" + target_view "github.com/daytonaio/daytona/pkg/views/target" + targetconfig_view "github.com/daytonaio/daytona/pkg/views/targetconfig" + "github.com/docker/docker/pkg/stringid" + "github.com/spf13/cobra" +) + +var targetCreateCmd = &cobra.Command{ + Use: "create", + Short: "Create a target", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + createTargetDto, err := CreateTargetDtoFlow(ctx, TargetCreationParams{ + ApiClient: apiClient, + ActiveProfileName: activeProfile.Name, + }) + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + + logsContext, stopLogs := context.WithCancel(context.Background()) + defer stopLogs() + + logs_view.SetupLongestPrefixLength([]string{createTargetDto.Name}) + + logs_view.DisplayLogEntry(logs.LogEntry{ + TargetName: &createTargetDto.Name, + Msg: views.GetPrettyLogLine("Request submitted"), + }, logs_view.STATIC_INDEX) + + go apiclient_util.ReadTargetLogs(logsContext, apiclient_util.ReadLogParams{ + Id: createTargetDto.Id, + Label: &createTargetDto.Name, + ActiveProfile: activeProfile, + Follow: util.Pointer(true), + SkipPrefixLengthSetup: true, + }) + + _, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(*createTargetDto).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + views.RenderInfoMessage(fmt.Sprintf("Target '%s' set successfully and will be used by default", createTargetDto.Name)) + return nil + }, +} + +type TargetCreationParams struct { + ApiClient *apiclient.APIClient + ActiveProfileName string +} + +func CreateTargetDtoFlow(ctx context.Context, params TargetCreationParams) (*apiclient.CreateTargetDTO, error) { + var targetConfigView *targetconfig_view.TargetConfigView + + targetConfigList, res, err := params.ApiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + if len(targetConfigList) == 0 { + targetConfigView, err = targetconfig.TargetConfigCreationFlow(ctx, params.ApiClient, params.ActiveProfileName, false) + if err != nil { + return nil, err + } + + if targetConfigView == nil { + return nil, common.ErrCtrlCAbort + } + } else { + targetConfigView, err = targetconfig_view.GetTargetConfigFromPrompt(targetConfigList, params.ActiveProfileName, nil, true, "Use") + if err != nil { + return nil, err + } + + if targetConfigView == nil { + return nil, common.ErrCtrlCAbort + } + + if targetConfigView.Name == targetconfig_view.NewTargetConfigName { + targetConfigView, err = targetconfig.TargetConfigCreationFlow(ctx, params.ApiClient, params.ActiveProfileName, false) + if err != nil { + return nil, err + } + + if targetConfigView == nil { + return nil, common.ErrCtrlCAbort + } + } + } + + if format.FormatFlag != "" { + format.UnblockStdOut() + } + + targetList, res, err := params.ApiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + var targetName string + if targetConfigView != nil { + targetName = targetConfigView.Name + } + + target_view.SetTargetNameView(&targetName, util.ArrayMap(targetList, func(t apiclient.TargetDTO) string { + return t.Name + })) + + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + + return &apiclient.CreateTargetDTO{ + Id: id, + Name: targetName, + TargetConfigName: targetConfigView.Name, + }, nil +} diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index 31912bfc8e..1c5feac199 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -26,10 +26,25 @@ var deleteCmd = &cobra.Command{ Short: "Delete a target", Aliases: []string{"remove", "rm"}, RunE: func(cmd *cobra.Command, args []string) error { + + ctx := context.Background() + + var targetDeleteList = []*apiclient.TargetDTO{} + var targetDeleteListNames = []string{} + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + if allFlag { if yesFlag { fmt.Println("Deleting all targets.") - err := DeleteAllTargets(forceFlag) + err := DeleteAllTargets(workspaceList, forceFlag) if err != nil { return err } @@ -49,7 +64,7 @@ var deleteCmd = &cobra.Command{ } if yesFlag { - err := DeleteAllTargets(forceFlag) + err := DeleteAllTargets(workspaceList, forceFlag) if err != nil { return err } @@ -60,15 +75,6 @@ var deleteCmd = &cobra.Command{ return nil } - ctx := context.Background() - - var targetDeleteList = []*apiclient.TargetDTO{} - var targetDeleteListNames = []string{} - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - if len(args) == 0 { targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { @@ -120,11 +126,12 @@ var deleteCmd = &cobra.Command{ fmt.Println("Operation canceled.") } else { for _, target := range targetDeleteList { - err := RemoveTarget(ctx, apiClient, target, forceFlag) + err := RemoveTarget(ctx, apiClient, target, workspaceList, forceFlag) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", target.Name, err)) + } else { + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully deleted", target.Name)) } - views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully deleted", target.Name)) } } return nil @@ -140,7 +147,7 @@ func init() { deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a target by force") } -func DeleteAllTargets(force bool) error { +func DeleteAllTargets(workspaceList []apiclient.WorkspaceDTO, force bool) error { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -153,7 +160,7 @@ func DeleteAllTargets(force bool) error { } for _, target := range targetList { - err := RemoveTarget(ctx, apiClient, &target, force) + err := RemoveTarget(ctx, apiClient, &target, workspaceList, force) if err != nil { log.Errorf("Failed to delete target %s: %v", target.Name, err) continue @@ -163,7 +170,13 @@ func DeleteAllTargets(force bool) error { return nil } -func RemoveTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO, force bool) error { +func RemoveTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO, workspaceList []apiclient.WorkspaceDTO, force bool) error { + for _, workspace := range workspaceList { + if workspace.TargetId == target.Id { + return fmt.Errorf("target '%s' is in use by workspace '%s', please remove workspaces before deleting their target", target.Name, workspace.Name) + } + } + message := fmt.Sprintf("Deleting target %s", target.Name) err := views_util.WithInlineSpinner(message, func() error { res, err := apiClient.TargetAPI.RemoveTarget(ctx, target.Id).Force(force).Execute() diff --git a/pkg/cmd/target/info.go b/pkg/cmd/target/info.go index 42b6385be1..51c6442c95 100644 --- a/pkg/cmd/target/info.go +++ b/pkg/cmd/target/info.go @@ -45,7 +45,7 @@ var infoCmd = &cobra.Command{ format.UnblockStdOut() } - target = selection.GetTargetFromPrompt(targetList, "View") + target = selection.GetTargetFromPrompt(targetList, false, "View") if format.FormatFlag != "" { format.BlockStdOut() } diff --git a/pkg/cmd/target/list.go b/pkg/cmd/target/list.go index ddc23ef838..b2b2662393 100644 --- a/pkg/cmd/target/list.go +++ b/pkg/cmd/target/list.go @@ -52,7 +52,6 @@ var listCmd = &cobra.Command{ } list_view.ListTargets(targetList, verbose, activeProfile.Name) - return nil }, } diff --git a/pkg/cmd/target/logs.go b/pkg/cmd/target/logs.go new file mode 100644 index 0000000000..593d46ab04 --- /dev/null +++ b/pkg/cmd/target/logs.go @@ -0,0 +1,79 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + + "github.com/daytonaio/daytona/cmd/daytona/config" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views/target/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/spf13/cobra" +) + +var logsCmd = &cobra.Command{ + Use: "logs [TARGET]", + Short: "View the logs of a target", + Args: cobra.RangeArgs(0, 2), + Aliases: []string{"lg", "log"}, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + var target *apiclient.TargetDTO + apiClient, err := apiclient_util.GetApiClient(&activeProfile) + if err != nil { + return err + } + + if len(args) == 0 { + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) + return nil + } + target = selection.GetTargetFromPrompt(targetList, false, "Get Logs For") + if target == nil { + return nil + } + } else { + target, err = apiclient_util.GetTarget(args[0], false) + if err != nil { + return err + } + } + + apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ActiveProfile: activeProfile, + Follow: &followFlag, + }) + + return nil + }, + // FIXME: add after adding state to targets + // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + // return getAllTargetsByState(TARGET_STATE_RUNNING) + // }, +} + +var followFlag bool + +func init() { + logsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") +} diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index 313d09a2b8..2695d9e8bf 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -40,7 +40,7 @@ var restartCmd = &cobra.Command{ return nil } - target := selection.GetTargetFromPrompt(targetList, "Restart") + target := selection.GetTargetFromPrompt(targetList, false, "Restart") if target == nil { return nil } diff --git a/pkg/cmd/target/setdefault.go b/pkg/cmd/target/setdefault.go new file mode 100644 index 0000000000..f4d709c5f7 --- /dev/null +++ b/pkg/cmd/target/setdefault.go @@ -0,0 +1,66 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/target/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/spf13/cobra" +) + +var setDefaultCmd = &cobra.Command{ + Use: "set-default [TARGET]", + Short: "Set default target", + Args: cobra.RangeArgs(0, 1), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + var target *apiclient.TargetDTO + + if len(args) == 0 { + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(targetList) == 0 { + views_util.NotifyEmptyTargetList(true) + return nil + } + + target = selection.GetTargetFromPrompt(targetList, false, "Set As Default") + } else { + target, err = apiclient_util.GetTarget(args[0], true) + if err != nil { + return err + } + } + + if target == nil { + return nil + } + + res, err := apiClient.TargetAPI.SetDefaultTarget(ctx, target.Id).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + views.RenderInfoMessage(fmt.Sprintf("Target '%s' set as default", target.Name)) + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getTargetNameCompletions() + }, +} diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 01a1356fc0..955f787cfe 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -9,6 +9,7 @@ import ( "time" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" @@ -218,7 +219,13 @@ func StartTarget(apiClient *apiclient.APIClient, targetId string) error { } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadTargetLogs(logsContext, activeProfile, target.Id, true, &from) + go apiclient_util.ReadTargetLogs(logsContext, apiclient_util.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ActiveProfile: activeProfile, + Follow: util.Pointer(true), + From: &from, + }) res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() if err != nil { stopLogs() diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go index 0ecade70df..3eee98a020 100644 --- a/pkg/cmd/target/stop.go +++ b/pkg/cmd/target/stop.go @@ -9,9 +9,11 @@ import ( "time" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + logs_view "github.com/daytonaio/daytona/pkg/views/logs" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" log "github.com/sirupsen/logrus" @@ -70,7 +72,17 @@ var stopCmd = &cobra.Command{ continue } - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, false, &from) + logs_view.SetupLongestPrefixLength(util.ArrayMap(targetList, func(t apiclient.TargetDTO) string { + return t.Name + })) + + apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ActiveProfile: activeProfile, + From: &from, + SkipPrefixLengthSetup: true, + }) views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) } } else { @@ -86,7 +98,12 @@ var stopCmd = &cobra.Command{ return err } - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, false, &from) + apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ActiveProfile: activeProfile, + From: &from, + }) views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) } @@ -121,7 +138,17 @@ func stopAllTargets(activeProfile config.Profile, from time.Time) error { continue } - apiclient_util.ReadTargetLogs(ctx, activeProfile, target.Id, false, &from) + logs_view.SetupLongestPrefixLength(util.ArrayMap(targetList, func(t apiclient.TargetDTO) string { + return t.Name + })) + + apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ActiveProfile: activeProfile, + From: &from, + SkipPrefixLengthSetup: true, + }) views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully stopped", target.Name)) } return nil diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go index baec127f32..de6cf5c8b3 100644 --- a/pkg/cmd/target/target.go +++ b/pkg/cmd/target/target.go @@ -16,10 +16,13 @@ var TargetCmd = &cobra.Command{ } func init() { + TargetCmd.AddCommand(targetCreateCmd) TargetCmd.AddCommand(deleteCmd) TargetCmd.AddCommand(infoCmd) TargetCmd.AddCommand(restartCmd) TargetCmd.AddCommand(startCmd) TargetCmd.AddCommand(stopCmd) + TargetCmd.AddCommand(logsCmd) TargetCmd.AddCommand(listCmd) + TargetCmd.AddCommand(setDefaultCmd) } diff --git a/pkg/cmd/targetconfig/remove.go b/pkg/cmd/targetconfig/remove.go index 4cf7907cad..1c0f5b2886 100644 --- a/pkg/cmd/targetconfig/remove.go +++ b/pkg/cmd/targetconfig/remove.go @@ -7,18 +7,13 @@ import ( "context" "fmt" - "github.com/charmbracelet/huh" "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - target_cmd "github.com/daytonaio/daytona/pkg/cmd/target" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" - - log "github.com/sirupsen/logrus" ) var yesFlag bool @@ -72,61 +67,6 @@ var removeCmd = &cobra.Command{ selectedConfigName = args[0] } - if yesFlag { - fmt.Println("Deleting all targets.") - err := RemoveTargetConfigTargets(ctx, apiClient, selectedConfigName) - - if err != nil { - return err - } - } else { - var configTargetCount int - - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - for _, target := range targetList { - if target.TargetConfig == selectedConfigName { - configTargetCount++ - } - } - - if configTargetCount > 0 { - title := fmt.Sprintf("Delete %d targets within %s?", configTargetCount, selectedConfigName) - description := "You might not be able to easily remove these targets later." - - if configTargetCount == 1 { - title = fmt.Sprintf("Delete 1 target within %s?", selectedConfigName) - description = "You might not be able to easily remove this target later." - } - - form := huh.NewForm( - huh.NewGroup( - huh.NewConfirm(). - Title(title). - Description(description). - Value(&yesFlag), - ), - ).WithTheme(views.GetCustomTheme()) - - err := form.Run() - if err != nil { - return err - } - - if yesFlag { - err := RemoveTargetConfigTargets(ctx, apiClient, selectedConfigName) - if err != nil { - return err - } - } else { - fmt.Println("Proceeding with target config removal without deleting targets.") - } - } - } - res, err := apiClient.TargetConfigAPI.RemoveTargetConfig(ctx, selectedConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) @@ -140,25 +80,3 @@ var removeCmd = &cobra.Command{ func init() { removeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all targets without prompt") } - -func RemoveTargetConfigTargets(ctx context.Context, client *apiclient.APIClient, targetConfig string) error { - targetList, res, err := client.TargetAPI.ListTargets(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - for _, target := range targetList { - if target.TargetConfig != targetConfig { - continue - } - err := target_cmd.RemoveTarget(ctx, client, &target, false) - if err != nil { - log.Errorf("Failed to delete target %s: %v", target.Name, err) - continue - } - - views.RenderInfoMessage(fmt.Sprintf("- Target '%s' successfully deleted", target.Name)) - } - - return nil -} diff --git a/pkg/cmd/targetconfig/set.go b/pkg/cmd/targetconfig/set.go index 88bfe7fe36..cbb7205a4e 100644 --- a/pkg/cmd/targetconfig/set.go +++ b/pkg/cmd/targetconfig/set.go @@ -34,10 +34,9 @@ var TargetConfigSetCmd = &cobra.Command{ Use: "set", Short: "Set target config", Args: cobra.NoArgs, - Aliases: []string{"s", "add", "update", "register", "edit"}, + Aliases: []string{"s", "add", "update", "register", "edit", "new", "create"}, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - var isNewProvider bool var input []byte var err error @@ -46,13 +45,13 @@ var TargetConfigSetCmd = &cobra.Command{ if err != nil { return fmt.Errorf("failed to read from stdin: %w", err) } - return handleTargetJSON(input) + return handleTargetConfigJSON(input) } else if pipeFile != "" { input, err = os.ReadFile(pipeFile) if err != nil { return fmt.Errorf("failed to read file %s: %w", pipeFile, err) } - return handleTargetJSON(input) + return handleTargetConfigJSON(input) } apiClient, err := apiclient_util.GetApiClient(nil) @@ -70,64 +69,92 @@ var TargetConfigSetCmd = &cobra.Command{ return err } - serverConfig, res, err := apiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) + targetConfig, err := TargetConfigCreationFlow(ctx, apiClient, activeProfile.Name, true) if err != nil { - return apiclient_util.HandleErrorResponse(res, err) + return err } - providersManifest, err := manager.NewProviderManager(manager.ProviderManagerConfig{ - RegistryUrl: serverConfig.RegistryUrl, - }).GetProvidersManifest() - if err != nil { - log.Error(err) + if targetConfig == nil { + return nil } - var latestProviders []apiclient.Provider - if providersManifest != nil { - providersManifestLatest := providersManifest.GetLatestVersions() - if providersManifestLatest == nil { - return errors.New("could not get latest provider versions") - } + views.RenderInfoMessage(fmt.Sprintf("Target config '%s' set successfully", targetConfig.Name)) + return nil + }, +} - latestProviders = provider.GetProviderListFromManifest(providersManifestLatest) - } else { - fmt.Println("Could not get provider manifest. Can't check for new providers to install") - } +func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClient, activeProfileName string, allowUpdating bool) (*targetconfig.TargetConfigView, error) { + var isNewProvider bool - providerViewList, err := provider.GetProviderViewOptions(apiClient, latestProviders, ctx) - if err != nil { - return err - } + serverConfig, res, err := apiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } - selectedProvider, err := provider_view.GetProviderFromPrompt(providerViewList, "Choose a Provider", false) - if err != nil { - if common.IsCtrlCAbort(err) { - return nil - } else { - return err - } - } + providersManifest, err := manager.NewProviderManager(manager.ProviderManagerConfig{ + RegistryUrl: serverConfig.RegistryUrl, + }).GetProvidersManifest() + if err != nil { + log.Error(err) + } - if selectedProvider == nil { - return nil + var latestProviders []apiclient.Provider + if providersManifest != nil { + providersManifestLatest := providersManifest.GetLatestVersions() + if providersManifestLatest == nil { + return nil, errors.New("could not get latest provider versions") } - if selectedProvider.Installed != nil && !*selectedProvider.Installed { - if providersManifest == nil { - return errors.New("could not get providers manifest") - } - err = provider.InstallProvider(apiClient, *selectedProvider, providersManifest) - if err != nil { - return err - } - isNewProvider = true + latestProviders = provider.GetProviderListFromManifest(providersManifestLatest) + } else { + fmt.Println("Could not get provider manifest. Can't check for new providers to install") + } + + providerViewList, err := provider.GetProviderViewOptions(apiClient, latestProviders, ctx) + if err != nil { + return nil, err + } + + selectedProvider, err := provider_view.GetProviderFromPrompt(providerViewList, "Choose a Provider", false) + if err != nil { + if common.IsCtrlCAbort(err) { + return nil, nil + } else { + return nil, err } + } - targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() + if selectedProvider == nil { + return nil, nil + } + + if selectedProvider.Installed != nil && !*selectedProvider.Installed { + if providersManifest == nil { + return nil, errors.New("could not get providers manifest") + } + err = provider.InstallProvider(apiClient, *selectedProvider, providersManifest) if err != nil { - return apiclient_util.HandleErrorResponse(res, err) + return nil, err } + isNewProvider = true + } + selectedTargetConfig := &targetconfig.TargetConfigView{ + Name: "", + Options: "{}", + ProviderInfo: targetconfig.ProviderInfo{ + Name: selectedProvider.Name, + Version: selectedProvider.Version, + Label: selectedProvider.Label, + }, + } + + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + if allowUpdating { filteredConfigs := []apiclient.TargetConfig{} for _, t := range targetConfigs { if t.ProviderInfo.Name == selectedProvider.Name { @@ -135,15 +162,13 @@ var TargetConfigSetCmd = &cobra.Command{ } } - var selectedTargetConfig *targetconfig.TargetConfigView - if !isNewProvider || len(filteredConfigs) > 0 { - selectedTargetConfig, err = targetconfig.GetTargetConfigFromPrompt(filteredConfigs, activeProfile.Name, nil, true, "Set") + selectedTargetConfig, err = targetconfig.GetTargetConfigFromPrompt(filteredConfigs, activeProfileName, nil, true, "Set") if err != nil { if common.IsCtrlCAbort(err) { - return nil + return nil, nil } else { - return err + return nil, err } } } else { @@ -152,47 +177,55 @@ var TargetConfigSetCmd = &cobra.Command{ Options: "{}", } } + } - if selectedTargetConfig.Name == targetconfig.NewTargetConfigName { - selectedTargetConfig.Name = "" - err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, internal_util.ArrayMap(targetConfigs, func(t apiclient.TargetConfig) string { - return t.Name - })) - if err != nil { - return err - } - } - - targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedProvider.Name).Execute() + if !allowUpdating || selectedTargetConfig.Name == targetconfig.NewTargetConfigName { + selectedTargetConfig.Name = "" + err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, internal_util.ArrayMap(targetConfigs, func(t apiclient.TargetConfig) string { + return t.Name + })) if err != nil { - return apiclient_util.HandleErrorResponse(res, err) + return nil, err } + } - err = targetconfig.SetTargetConfigForm(selectedTargetConfig, *targetConfigManifest) - if err != nil { - return err - } + targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedProvider.Name).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } - targetConfigData := apiclient.CreateTargetConfigDTO{ - Name: selectedTargetConfig.Name, - Options: selectedTargetConfig.Options, - ProviderInfo: apiclient.ProviderProviderInfo{ - Name: selectedProvider.Name, - Version: selectedProvider.Version, - }, - } + err = targetconfig.SetTargetConfigForm(selectedTargetConfig, *targetConfigManifest) + if err != nil { + return nil, err + } - res, err = apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } + targetConfigData := apiclient.CreateTargetConfigDTO{ + Name: selectedTargetConfig.Name, + Options: selectedTargetConfig.Options, + ProviderInfo: apiclient.TargetProviderInfo{ + Name: selectedProvider.Name, + Version: selectedProvider.Version, + Label: selectedProvider.Label, + }, + } - views.RenderInfoMessage("Target config set successfully and will be used by default") - return nil - }, + targetConfig, res, err := apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + return &targetconfig.TargetConfigView{ + Name: targetConfig.Name, + Options: targetConfig.Options, + ProviderInfo: targetconfig.ProviderInfo{ + Name: targetConfig.ProviderInfo.Name, + Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, + }, + }, nil } -func handleTargetJSON(data []byte) error { +func handleTargetConfigJSON(data []byte) error { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -209,7 +242,7 @@ func handleTargetJSON(data []byte) error { return errors.New("invalid input: 'name' field is required") } if selectedTargetConfig.Options == "" { - return errors.New("option fields are required to setup your target") + return errors.New("option fields are required to setup your target config") } targetManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(ctx, selectedTargetConfig.ProviderInfo.Name).Execute() if err != nil { @@ -222,12 +255,12 @@ func handleTargetJSON(data []byte) error { targetConfigData := apiclient.CreateTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, - ProviderInfo: apiclient.ProviderProviderInfo{ + ProviderInfo: apiclient.TargetProviderInfo{ Name: selectedTargetConfig.ProviderInfo.Name, Version: selectedTargetConfig.ProviderInfo.Version, }, } - res, err = apiClient.TargetConfigAPI.SetTargetConfig(ctx).TargetConfig(targetConfigData).Execute() + _, res, err = apiClient.TargetConfigAPI.SetTargetConfig(ctx).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/targetconfig/setdefault.go b/pkg/cmd/targetconfig/setdefault.go deleted file mode 100644 index c5d520653c..0000000000 --- a/pkg/cmd/targetconfig/setdefault.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package targetconfig - -import ( - "context" - "fmt" - - "github.com/daytonaio/daytona/cmd/daytona/config" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/targetconfig" - views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/spf13/cobra" -) - -var setDefaultCmd = &cobra.Command{ - Use: "set-default [CONFIG_NAME]", - Short: "Set default target config", - Args: cobra.RangeArgs(0, 1), - RunE: func(cmd *cobra.Command, args []string) error { - var configName string - ctx := context.Background() - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - if len(args) == 0 { - targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(targetConfigs) == 0 { - views_util.NotifyEmptyTargetConfigList(true) - return nil - } - - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(targetConfigs, activeProfile.Name, nil, false, "Make Default") - if err != nil { - if common.IsCtrlCAbort(err) { - return nil - } else { - return err - } - } - - if selectedTargetConfig == nil { - return nil - } - - configName = selectedTargetConfig.Name - } else { - configName = args[0] - } - - res, err := apiClient.TargetConfigAPI.SetDefaultTargetConfig(ctx, configName).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - views.RenderInfoMessage(fmt.Sprintf("Target config '%s' set as default", configName)) - return nil - }, -} diff --git a/pkg/cmd/targetconfig/target_config.go b/pkg/cmd/targetconfig/target_config.go index a23abba3ce..827bf9a098 100644 --- a/pkg/cmd/targetconfig/target_config.go +++ b/pkg/cmd/targetconfig/target_config.go @@ -19,5 +19,4 @@ func init() { TargetConfigCmd.AddCommand(listCmd) TargetConfigCmd.AddCommand(TargetConfigSetCmd) TargetConfigCmd.AddCommand(removeCmd) - TargetConfigCmd.AddCommand(setDefaultCmd) } diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go index 95530fd68b..5ff380e61b 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/workspace/code.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -11,13 +11,13 @@ import ( "strings" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/jetbrains" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/ide" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/telemetry" ide_views "github.com/daytonaio/daytona/pkg/views/ide" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -78,12 +78,12 @@ var CodeCmd = &cobra.Command{ return err } } - if ideFlag != "" { - ideId = ideFlag + if create.IdeFlag != "" { + ideId = create.IdeFlag } if ws.State != nil || ws.State.Uptime < 1 { - wsRunningStatus, err := AutoStartWorkspace(ws.Id) + wsRunningStatus, err := AutoStartWorkspace(*ws) if err != nil { return err } @@ -94,7 +94,7 @@ var CodeCmd = &cobra.Command{ providerMetadata := *ws.Info.ProviderMetadata - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) if err != nil { log.Warn(err) } @@ -102,53 +102,13 @@ var CodeCmd = &cobra.Command{ yesFlag, _ := cmd.Flags().GetBool("yes") ideList := config.GetIdeList() ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList) - return openIDE(ideId, activeProfile, ws.Id, providerMetadata, yesFlag, gpgKey) + return workspace_common.OpenIDE(ideId, activeProfile, ws.Id, providerMetadata, yesFlag, gpgKey) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getWorkspaceNameCompletions() + return common.GetWorkspaceNameCompletions() }, } -func openIDE(ideId string, activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { - telemetry.AdditionalData["ide"] = ideId - - switch ideId { - case "vscode": - return ide.OpenVSCode(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "code-insiders": - return ide.OpenVSCodeInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "ssh": - return ide.OpenTerminalSsh(activeProfile, workspaceId, gpgKey, nil) - case "browser": - return ide.OpenBrowserIDE(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "codium": - return ide.OpenVScodium(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "codium-insiders": - return ide.OpenVScodiumInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "cursor": - return ide.OpenCursor(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "jupyter": - return ide.OpenJupyterIDE(activeProfile, workspaceId, workspaceProviderMetadata, yesFlag, gpgKey) - case "fleet": - return ide.OpenFleet(activeProfile, workspaceId, gpgKey) - case "positron": - return ide.OpenPositron(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - case "zed": - return ide.OpenZed(activeProfile, workspaceId, gpgKey) - case "windsurf": - return ide.OpenWindsurf(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) - default: - _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] - if ok { - return ide.OpenJetbrainsIDE(activeProfile, ideId, workspaceId, gpgKey) - } - } - - return errors.New("invalid IDE. Please choose one by running `daytona ide`") -} - -var ideFlag string - func init() { ideList := config.GetIdeList() ids := make([]string, len(ideList)) @@ -156,15 +116,15 @@ func init() { ids[i] = ide.Id } ideListStr := strings.Join(ids, ", ") - CodeCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) + CodeCmd.Flags().StringVarP(&create.IdeFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) CodeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") } -func AutoStartWorkspace(workspaceId string) (bool, error) { +func AutoStartWorkspace(workspace apiclient.WorkspaceDTO) (bool, error) { if !yesFlag { - if !ide_views.RunStartWorkspaceForm(workspaceId) { + if !ide_views.RunStartWorkspaceForm(workspace.Id) { return false, nil } } @@ -174,7 +134,7 @@ func AutoStartWorkspace(workspaceId string) (bool, error) { return false, err } - err = StartWorkspace(apiClient, workspaceId) + err = StartWorkspace(apiClient, workspace) if err != nil { return false, err } diff --git a/pkg/cmd/workspace/util/target.go b/pkg/cmd/workspace/common/configuration_flags.go similarity index 99% rename from pkg/cmd/workspace/util/target.go rename to pkg/cmd/workspace/common/configuration_flags.go index 9cff8e66d1..aabf4588ad 100644 --- a/pkg/cmd/workspace/util/target.go +++ b/pkg/cmd/workspace/common/configuration_flags.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package util +package common import ( "fmt" diff --git a/pkg/cmd/workspace/common/get_gpg_key.go b/pkg/cmd/workspace/common/get_gpg_key.go new file mode 100644 index 0000000000..516c13d7aa --- /dev/null +++ b/pkg/cmd/workspace/common/get_gpg_key.go @@ -0,0 +1,42 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "context" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/gitprovider" +) + +func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (string, error) { + if providerConfigId == nil || *providerConfigId == "" { + return "", nil + } + + var providerConfig *gitprovider.GitProviderConfig + var gpgKey string + + gitProvider, res, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *providerConfigId).Execute() + if err != nil { + return "", apiclient_util.HandleErrorResponse(res, err) + } + + // Extract GPG key if present + if gitProvider != nil { + providerConfig = &gitprovider.GitProviderConfig{ + SigningMethod: (*gitprovider.SigningMethod)(gitProvider.SigningMethod), + SigningKey: gitProvider.SigningKey, + } + + if providerConfig.SigningMethod != nil && providerConfig.SigningKey != nil { + if *providerConfig.SigningMethod == gitprovider.SigningMethodGPG { + gpgKey = *providerConfig.SigningKey + } + } + } + + return gpgKey, nil +} diff --git a/pkg/cmd/workspace/common/open_ide.go b/pkg/cmd/workspace/common/open_ide.go new file mode 100644 index 0000000000..bebe9bbcf7 --- /dev/null +++ b/pkg/cmd/workspace/common/open_ide.go @@ -0,0 +1,51 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "errors" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/jetbrains" + "github.com/daytonaio/daytona/pkg/ide" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +func OpenIDE(ideId string, activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { + telemetry.AdditionalData["ide"] = ideId + + switch ideId { + case "vscode": + return ide.OpenVSCode(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "code-insiders": + return ide.OpenVSCodeInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "ssh": + return ide.OpenTerminalSsh(activeProfile, workspaceId, gpgKey, nil) + case "browser": + return ide.OpenBrowserIDE(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "codium": + return ide.OpenVScodium(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "codium-insiders": + return ide.OpenVScodiumInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "cursor": + return ide.OpenCursor(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "jupyter": + return ide.OpenJupyterIDE(activeProfile, workspaceId, workspaceProviderMetadata, yesFlag, gpgKey) + case "fleet": + return ide.OpenFleet(activeProfile, workspaceId, gpgKey) + case "positron": + return ide.OpenPositron(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + case "zed": + return ide.OpenZed(activeProfile, workspaceId, gpgKey) + case "windsurf": + return ide.OpenWindsurf(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + default: + _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] + if ok { + return ide.OpenJetbrainsIDE(activeProfile, ideId, workspaceId, gpgKey) + } + } + + return errors.New("invalid IDE. Please choose one by running `daytona ide`") +} diff --git a/pkg/cmd/workspace/common/workspace_autocompletion.go b/pkg/cmd/workspace/common/workspace_autocompletion.go new file mode 100644 index 0000000000..a2ea1aaea1 --- /dev/null +++ b/pkg/cmd/workspace/common/workspace_autocompletion.go @@ -0,0 +1,65 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "context" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/spf13/cobra" +) + +type workspaceState string + +const ( + WORKSPACE_STATE_RUNNING workspaceState = "Running" + WORKSPACE_STATE_STOPPED workspaceState = "Unavailable" +) + +func GetWorkspaceNameCompletions() ([]string, cobra.ShellCompDirective) { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + var choices []string + for _, v := range workspaceList { + choices = append(choices, v.Name) + } + + return choices, cobra.ShellCompDirectiveNoFileComp +} + +func GetAllWorkspacesByState(state workspaceState) ([]string, cobra.ShellCompDirective) { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + var choices []string + for _, workspace := range workspaceList { + if state == WORKSPACE_STATE_RUNNING && workspace.State.Uptime != 0 { + choices = append(choices, workspace.Name) + break + } + if state == WORKSPACE_STATE_STOPPED && workspace.State.Uptime == 0 { + choices = append(choices, workspace.Name) + break + } + } + + return choices, cobra.ShellCompDirectiveNoFileComp +} diff --git a/pkg/cmd/workspace/create.go b/pkg/cmd/workspace/create.go deleted file mode 100644 index 92e82bd4f4..0000000000 --- a/pkg/cmd/workspace/create.go +++ /dev/null @@ -1,583 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import ( - "context" - "errors" - "fmt" - "net/http" - "net/url" - "os/exec" - "strings" - "time" - - "github.com/daytonaio/daytona/internal/cmd/tailscale" - "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" - "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/views" - logs_view "github.com/daytonaio/daytona/pkg/views/logs" - views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/info" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/docker/docker/pkg/stringid" - log "github.com/sirupsen/logrus" - "tailscale.com/tsnet" - - "github.com/spf13/cobra" - - "github.com/daytonaio/daytona/cmd/daytona/config" -) - -var CreateCmd = &cobra.Command{ - Use: "create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]...", - Short: "Create a target", - GroupID: util.TARGET_GROUP, - RunE: func(cmd *cobra.Command, args []string) error { - ctx := context.Background() - var workspaces []apiclient.CreateWorkspaceDTO - var targetName string - var existingTargetNames []string - var existingWorkspaceConfigNames []string - promptUsingTUI := len(args) == 0 - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if nameFlag != "" { - targetName = nameFlag - } - - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - for _, targetInfo := range targetList { - existingTargetNames = append(existingTargetNames, targetInfo.Name) - } - - if promptUsingTUI { - err = processPrompting(ctx, apiClient, &targetName, &workspaces, existingTargetNames) - if err != nil { - if common.IsCtrlCAbort(err) { - return nil - } else { - return err - } - } - } else { - existingWorkspaceConfigNames, err = processCmdArguments(ctx, args, apiClient, &workspaces) - if err != nil { - return err - } - - initialSuggestion := workspaces[0].Name - - if targetName == "" { - targetName = workspace_util.GetSuggestedName(initialSuggestion, existingTargetNames) - } - } - - if targetName == "" || len(workspaces) == 0 { - return errors.New("target name and repository urls are required") - } - - workspaceNames := []string{} - for i := range workspaces { - if profileData != nil && profileData.EnvVars != nil { - workspaces[i].EnvVars = util.MergeEnvVars(profileData.EnvVars, workspaces[i].EnvVars) - } else { - workspaces[i].EnvVars = util.MergeEnvVars(workspaces[i].EnvVars) - } - workspaceNames = append(workspaceNames, workspaces[i].Name) - } - - for i, workspaceConfigName := range existingWorkspaceConfigNames { - if workspaceConfigName == "" { - continue - } - logs_view.DisplayLogEntry(logs.LogEntry{ - WorkspaceName: &workspaces[i].Name, - Msg: fmt.Sprintf("Using detected workspace config '%s'\n", workspaceConfigName), - }, i) - } - - targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - targetConfig, err := workspace_util.GetTargetConfig(workspace_util.GetTargetConfigParams{ - Ctx: ctx, - ApiClient: apiClient, - TargetConfigs: targetConfigs, - ActiveProfileName: activeProfile.Name, - TargetConfigNameFlag: targetConfigNameFlag, - PromptUsingTUI: promptUsingTUI, - }) - if err != nil { - if common.IsCtrlCAbort(err) { - return nil - } - return err - } - - names := append(workspaceNames, targetName) - logs_view.CalculateLongestPrefixLength(names) - - logs_view.DisplayLogEntry(logs.LogEntry{ - Msg: "Request submitted\n", - }, logs_view.STATIC_INDEX) - - activeProfile, err = c.GetActiveProfile() - if err != nil { - return err - } - - var tsConn *tsnet.Server - if targetConfig.Name != "local" || activeProfile.Id != "default" { - tsConn, err = tailscale.GetConnection(&activeProfile) - if err != nil { - return err - } - } - - id := stringid.GenerateRandomID() - id = stringid.TruncateID(id) - - logsContext, stopLogs := context.WithCancel(context.Background()) - defer stopLogs() - - logs_view.CalculateLongestPrefixLength(names) - - go apiclient_util.ReadTargetLogs(logsContext, activeProfile, id, true, nil) - - createdTarget, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(apiclient.CreateTargetDTO{ - Id: id, - Name: targetName, - TargetConfig: targetConfig.Name, - }).Execute() - - dedupWorkspaceNames(&workspaces) - - for i := range workspaces { - wsId := stringid.GenerateRandomID() - wsId = stringid.TruncateID(wsId) - workspaces[i].Id = wsId - workspaces[i].TargetId = id - ws := workspaces[i] - - go apiclient_util.ReadWorkspaceLogs(logsContext, i, activeProfile, wsId, true, nil) - - _, res, err = apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(ws).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - } - - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, workspaces[0].GitProviderConfigId) - if err != nil { - log.Warn(err) - } - - err = waitForDial(createdTarget, workspaces[0].Id, &activeProfile, tsConn, gpgKey) - if err != nil { - return err - } - - stopLogs() - - // Make sure terminal cursor is reset - fmt.Print("\033[?25h") - - chosenIdeId := c.DefaultIdeId - if ideFlag != "" { - chosenIdeId = ideFlag - } - - ideList := config.GetIdeList() - var chosenIde config.Ide - - for _, ide := range ideList { - if ide.Id == chosenIdeId { - chosenIde = ide - } - } - - fmt.Println() - - ws, err := apiclient_util.GetWorkspace(workspaces[0].Id, true) - if err != nil { - return err - } - - info.Render(ws, chosenIde.Name, false) - - if noIdeFlag { - views.RenderCreationInfoMessage("Run 'daytona code' when you're ready to start developing") - return nil - } - - views.RenderCreationInfoMessage(fmt.Sprintf("Opening the target in %s ...", chosenIde.Name)) - - return openIDE(chosenIdeId, activeProfile, workspaces[0].Name, *ws.Info.ProviderMetadata, yesFlag, gpgKey) - }, -} - -var nameFlag string -var targetConfigNameFlag string -var noIdeFlag bool -var blankFlag bool -var multiWorkspaceFlag bool - -var workspaceConfigurationFlags = workspace_util.WorkspaceConfigurationFlags{ - Builder: new(views_util.BuildChoice), - CustomImage: new(string), - CustomImageUser: new(string), - Branches: new([]string), - DevcontainerPath: new(string), - EnvVars: new([]string), - Manual: new(bool), - GitProviderConfig: new(string), -} - -func init() { - ideList := config.GetIdeList() - ids := make([]string, len(ideList)) - for i, ide := range ideList { - ids[i] = ide.Id - } - ideListStr := strings.Join(ids, ", ") - - CreateCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the target name") - CreateCmd.Flags().StringVarP(&ideFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) - CreateCmd.Flags().StringVarP(&targetConfigNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") - CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank workspace without using existing configurations") - CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the target in the IDE after target creation") - CreateCmd.Flags().BoolVar(&multiWorkspaceFlag, "multi-workspace", false, "Target with multiple workspaces/repos") - CreateCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") - CreateCmd.Flags().StringSliceVar(workspaceConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the workspaces") - - workspace_util.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) -} - -func processPrompting(ctx context.Context, apiClient *apiclient.APIClient, targetName *string, workspaces *[]apiclient.CreateWorkspaceDTO, targetNames []string) error { - if workspace_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) || (workspaceConfigurationFlags.Branches != nil && len(*workspaceConfigurationFlags.Branches) > 0) { - return errors.New("please provide the repository URL in order to set up custom workspace details through the CLI") - } - - gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - apiServerConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ - BuildChoice: views_util.AUTOMATIC, - Image: &apiServerConfig.DefaultWorkspaceImage, - ImageUser: &apiServerConfig.DefaultWorkspaceUser, - DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, - } - - *workspaces, err = workspace_util.GetWorkspacesCreationDataFromPrompt(workspace_util.WorkspacesDataPromptConfig{ - UserGitProviders: gitProviders, - WorkspaceConfigs: workspaceConfigs, - Manual: *workspaceConfigurationFlags.Manual, - MultiWorkspace: multiWorkspaceFlag, - BlankWorkspace: blankFlag, - ApiClient: apiClient, - Defaults: workspaceDefaults, - }) - - if err != nil { - return err - } - - initialSuggestion := (*workspaces)[0].Name - - suggestedName := workspace_util.GetSuggestedName(initialSuggestion, targetNames) - - dedupWorkspaceNames(workspaces) - - submissionFormConfig := create.SubmissionFormConfig{ - ChosenName: targetName, - SuggestedName: suggestedName, - ExistingNames: targetNames, - WorkspaceList: workspaces, - NameLabel: "Target", - Defaults: workspaceDefaults, - } - - pcImportFlag := false - err = create.RunSubmissionForm(submissionFormConfig, &pcImportFlag) - if err != nil { - return err - } - - return nil -} - -func processCmdArguments(ctx context.Context, repoUrls []string, apiClient *apiclient.APIClient, workspaces *[]apiclient.CreateWorkspaceDTO) ([]string, error) { - if len(repoUrls) == 0 { - return nil, fmt.Errorf("no repository URLs provided") - } - - if len(repoUrls) > 1 && workspace_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { - return nil, fmt.Errorf("can't set custom workspace configuration properties for multiple workspaces") - } - - if *workspaceConfigurationFlags.Builder != "" && *workspaceConfigurationFlags.Builder != views_util.DEVCONTAINER && *workspaceConfigurationFlags.DevcontainerPath != "" { - return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) - } - - var workspaceConfig *apiclient.WorkspaceConfig - - existingWorkspaceConfigNames := []string{} - - for i, repoUrl := range repoUrls { - var branch *string - if len(*workspaceConfigurationFlags.Branches) > i { - branch = &(*workspaceConfigurationFlags.Branches)[i] - } - - validatedUrl, err := util.GetValidatedUrl(repoUrl) - if err == nil { - // The argument is a Git URL - existingWorkspaceConfigName, err := processGitURL(ctx, validatedUrl, apiClient, workspaces, branch) - if err != nil { - return nil, err - } - if existingWorkspaceConfigName != nil { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) - } else { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") - } - - continue - } - - // The argument is not a Git URL - try getting the workspace config - workspaceConfig, _, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, repoUrl).Execute() - if err != nil { - return nil, fmt.Errorf("failed to parse the URL or fetch the workspace config for '%s'", repoUrl) - } - - existingWorkspaceConfigName, err := workspace_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) - if err != nil { - return nil, err - } - if existingWorkspaceConfigName != nil { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) - } else { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") - } - } - - dedupWorkspaceNames(workspaces) - - return existingWorkspaceConfigNames, nil -} - -func processGitURL(ctx context.Context, repoUrl string, apiClient *apiclient.APIClient, workspaces *[]apiclient.CreateWorkspaceDTO, branch *string) (*string, error) { - encodedURLParam := url.QueryEscape(repoUrl) - - if !blankFlag { - workspaceConfig, res, err := apiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() - if err == nil { - workspaceConfig.GitProviderConfigId = workspaceConfigurationFlags.GitProviderConfig - return workspace_util.AddWorkspaceFromConfig(workspaceConfig, apiClient, workspaces, branch) - } - - if res.StatusCode != http.StatusNotFound { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - } - - repo, res, err := apiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: repoUrl, - Branch: branch, - }).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - workspaceName, err := workspace_util.GetSanitizedWorkspaceName(repo.Name) - if err != nil { - return nil, err - } - - workspaceConfigurationFlags.GitProviderConfig, err = workspace_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) - if err != nil { - return nil, err - } - - if workspaceConfigurationFlags.GitProviderConfig == nil || *workspaceConfigurationFlags.GitProviderConfig == "" { - gitProviderConfigs, res, err := apiClient.GitProviderAPI.ListGitProvidersForUrl(context.Background(), url.QueryEscape(repoUrl)).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - if len(gitProviderConfigs) == 1 { - workspaceConfigurationFlags.GitProviderConfig = &gitProviderConfigs[0].Id - } else if len(gitProviderConfigs) > 1 { - gp := selection.GetGitProviderConfigFromPrompt(selection.GetGitProviderConfigParams{ - GitProviderConfigs: gitProviderConfigs, - ActionVerb: "Use", - }) - if gp == nil { - return nil, common.ErrCtrlCAbort - } - workspaceConfigurationFlags.GitProviderConfig = &gp.Id - } - } - - workspace, err := workspace_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) - if err != nil { - return nil, err - } - - workspace.Name = workspaceName - workspace.Source = apiclient.CreateWorkspaceSourceDTO{ - Repository: *repo, - } - - *workspaces = append(*workspaces, *workspace) - - return nil, nil -} - -func waitForDial(target *apiclient.Target, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { - if target.TargetConfig == "local" && (activeProfile != nil && activeProfile.Id == "default") { - err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) - if err != nil { - return err - } - - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - - for { - sshCommand := exec.Command("ssh", workspaceHostname, "daytona", "version") - sshCommand.Stdin = nil - sshCommand.Stdout = nil - sshCommand.Stderr = &util.TraceLogWriter{} - - err = sshCommand.Run() - if err == nil { - return nil - } - - time.Sleep(100 * time.Millisecond) - } - } - - connectChan := make(chan error) - spinner := time.After(15 * time.Second) - timeout := time.After(2 * time.Minute) - - go func() { - for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(workspaceId), ssh_config.SSH_PORT)) - if err == nil { - connectChan <- dialConn.Close() - return - } - time.Sleep(100 * time.Millisecond) - } - }() - - select { - case err := <-connectChan: - return err - case <-spinner: - err := views_util.WithInlineSpinner("Connection to tailscale is taking longer than usual", func() error { - select { - case err := <-connectChan: - return err - case <-timeout: - return errors.New("secure connection to the Daytona Server could not be established. Please check your internet connection or Tailscale availability") - } - }) - return err - } -} - -func dedupWorkspaceNames(workspaces *[]apiclient.CreateWorkspaceDTO) { - workspaceNames := map[string]int{} - - for i, workspace := range *workspaces { - if _, ok := workspaceNames[workspace.Name]; ok { - (*workspaces)[i].Name = fmt.Sprintf("%s-%d", workspace.Name, workspaceNames[workspace.Name]) - workspaceNames[workspace.Name]++ - } else { - workspaceNames[workspace.Name] = 2 - } - } -} - -func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (string, error) { - if providerConfigId == nil || *providerConfigId == "" { - return "", nil - } - - var providerConfig *gitprovider.GitProviderConfig - var gpgKey string - - gitProvider, res, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *providerConfigId).Execute() - if err != nil { - return "", apiclient_util.HandleErrorResponse(res, err) - } - - // Extract GPG key if present - if gitProvider != nil { - providerConfig = &gitprovider.GitProviderConfig{ - SigningMethod: (*gitprovider.SigningMethod)(gitProvider.SigningMethod), - SigningKey: gitProvider.SigningKey, - } - - if providerConfig.SigningMethod != nil && providerConfig.SigningKey != nil { - if *providerConfig.SigningMethod == gitprovider.SigningMethodGPG { - gpgKey = *providerConfig.SigningKey - } - } - } - - return gpgKey, nil -} diff --git a/pkg/cmd/workspace/util/add_from_config.go b/pkg/cmd/workspace/create/add_from_config.go similarity index 99% rename from pkg/cmd/workspace/util/add_from_config.go rename to pkg/cmd/workspace/create/add_from_config.go index 18e558fb9e..37d98a2bf1 100644 --- a/pkg/cmd/workspace/util/add_from_config.go +++ b/pkg/cmd/workspace/create/add_from_config.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package util +package create import ( "context" diff --git a/pkg/cmd/workspace/util/branch_wizard.go b/pkg/cmd/workspace/create/branch_wizard.go similarity index 99% rename from pkg/cmd/workspace/util/branch_wizard.go rename to pkg/cmd/workspace/create/branch_wizard.go index 76379930a8..f3c13571cc 100644 --- a/pkg/cmd/workspace/util/branch_wizard.go +++ b/pkg/cmd/workspace/create/branch_wizard.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package util +package create import ( "context" @@ -27,64 +27,6 @@ type BranchWizardConfig struct { ProviderId string } -func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWizardConfig, parentIdentifier string, page, perPage int32) (*apiclient.GitRepository, error) { - var branchList []apiclient.GitBranch - disablePagination := false - curPageItemsNum := 0 - selectionListCursorIdx := 0 - var selectionListOptions views.SelectionListOptions - var err error - - for { - err = views_util.WithSpinner("Loading Branches", func() error { - branches, _, err := config.ApiClient.GitProviderAPI.GetRepoBranches(ctx, config.GitProviderConfigId, url.QueryEscape(config.NamespaceId), url.QueryEscape(config.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() - if err != nil { - return err - } - - curPageItemsNum = len(branches) - branchList = append(branchList, branches...) - return nil - }) - - if err != nil { - return nil, err - } - - // Check first if the git provider supports pagination - if isGitProviderWithUnsupportedPagination(config.GitProviderConfigId) { - disablePagination = true - } else { - // Check if we have reached the end of the list - disablePagination = int32(curPageItemsNum) < perPage - } - - selectionListCursorIdx = (int)(page-1) * int(perPage) - selectionListOptions = views.SelectionListOptions{ - ParentIdentifier: parentIdentifier, - IsPaginationDisabled: disablePagination, - CursorIndex: selectionListCursorIdx, - } - - // User will either choose a branch or navigate the pages - branch, navigate := selection.GetBranchFromPrompt(branchList, config.WorkspaceOrder, selectionListOptions) - if !disablePagination && navigate != "" { - if navigate == views.ListNavigationText { - page++ - continue // Fetch the next page of branches - } - } else if branch != nil { - config.ChosenRepo.Branch = branch.Name - config.ChosenRepo.Sha = branch.Sha - - return config.ChosenRepo, nil - } else { - // If user aborts or there's no selection - return nil, errors.New("must select a branch") - } - } -} - func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, error) { var branchList []apiclient.GitBranch var checkoutOptions []selection.CheckoutOption @@ -237,3 +179,61 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e return config.ChosenRepo, nil } + +func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWizardConfig, parentIdentifier string, page, perPage int32) (*apiclient.GitRepository, error) { + var branchList []apiclient.GitBranch + disablePagination := false + curPageItemsNum := 0 + selectionListCursorIdx := 0 + var selectionListOptions views.SelectionListOptions + var err error + + for { + err = views_util.WithSpinner("Loading Branches", func() error { + branches, _, err := config.ApiClient.GitProviderAPI.GetRepoBranches(ctx, config.GitProviderConfigId, url.QueryEscape(config.NamespaceId), url.QueryEscape(config.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() + if err != nil { + return err + } + + curPageItemsNum = len(branches) + branchList = append(branchList, branches...) + return nil + }) + + if err != nil { + return nil, err + } + + // Check first if the git provider supports pagination + if isGitProviderWithUnsupportedPagination(config.GitProviderConfigId) { + disablePagination = true + } else { + // Check if we have reached the end of the list + disablePagination = int32(curPageItemsNum) < perPage + } + + selectionListCursorIdx = (int)(page-1) * int(perPage) + selectionListOptions = views.SelectionListOptions{ + ParentIdentifier: parentIdentifier, + IsPaginationDisabled: disablePagination, + CursorIndex: selectionListCursorIdx, + } + + // User will either choose a branch or navigate the pages + branch, navigate := selection.GetBranchFromPrompt(branchList, config.WorkspaceOrder, selectionListOptions) + if !disablePagination && navigate != "" { + if navigate == views.ListNavigationText { + page++ + continue // Fetch the next page of branches + } + } else if branch != nil { + config.ChosenRepo.Branch = branch.Name + config.ChosenRepo.Sha = branch.Sha + + return config.ChosenRepo, nil + } else { + // If user aborts or there's no selection + return nil, errors.New("must select a branch") + } + } +} diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go new file mode 100644 index 0000000000..0f7ecc5417 --- /dev/null +++ b/pkg/cmd/workspace/create/cmd.go @@ -0,0 +1,373 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package create + +import ( + "context" + "errors" + "fmt" + "os/exec" + "strings" + "time" + + "github.com/daytonaio/daytona/internal/cmd/tailscale" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" + "github.com/daytonaio/daytona/pkg/apiclient" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/views" + logs_view "github.com/daytonaio/daytona/pkg/views/logs" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/info" + "github.com/daytonaio/daytona/pkg/workspace" + log "github.com/sirupsen/logrus" + "tailscale.com/tsnet" + + "github.com/spf13/cobra" + + "github.com/daytonaio/daytona/cmd/daytona/config" +) + +var CreateCmd = &cobra.Command{ + Use: "create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]...", + Short: "Create a workspace", + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + var createWorkspaceDtos []apiclient.CreateWorkspaceDTO + var existingWorkspaceConfigNames []string + var targetId string + promptUsingTUI := len(args) == 0 + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + target, createTargetDto, err := GetTarget(ctx, GetTargetConfigParams{ + ApiClient: apiClient, + ActiveProfileName: activeProfile.Name, + TargetNameFlag: targetNameFlag, + PromptUsingTUI: promptUsingTUI, + }) + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } + return err + } + + targetName := "" + if target != nil { + targetName = target.Name + } else if createTargetDto != nil { + targetName = createTargetDto.Name + } + + existingWorkspaces, res, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if promptUsingTUI { + err = ProcessPrompting(ctx, ProcessPromptingConfig{ + ApiClient: apiClient, + CreateWorkspaceDtos: &createWorkspaceDtos, + ExistingWorkspaces: &existingWorkspaces, + WorkspaceConfigurationFlags: workspaceConfigurationFlags, + MultiWorkspaceFlag: multiWorkspaceFlag, + BlankFlag: blankFlag, + TargetName: targetName, + }) + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + } else { + existingWorkspaceConfigNames, err = ProcessCmdArguments(ctx, ProcessCmdArgumentsConfig{ + ApiClient: apiClient, + RepoUrls: args, + CreateWorkspaceDtos: &createWorkspaceDtos, + ExistingWorkspaces: &existingWorkspaces, + WorkspaceConfigurationFlags: workspaceConfigurationFlags, + BlankFlag: blankFlag, + }) + if err != nil { + return err + } + } + + workspaceNames := []string{} + for i := range createWorkspaceDtos { + if profileData != nil && profileData.EnvVars != nil { + createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(profileData.EnvVars, createWorkspaceDtos[i].EnvVars) + } else { + createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(createWorkspaceDtos[i].EnvVars) + } + workspaceNames = append(workspaceNames, createWorkspaceDtos[i].Name) + } + + names := append(workspaceNames, targetName) + + logs_view.SetupLongestPrefixLength(names) + + for i, workspaceConfigName := range existingWorkspaceConfigNames { + if workspaceConfigName == "" { + continue + } + logs_view.DisplayLogEntry(logs.LogEntry{ + WorkspaceName: &createWorkspaceDtos[i].Name, + Msg: fmt.Sprintf("Using detected workspace config '%s'\n", workspaceConfigName), + }, i) + } + + requestLogEntry := logs.LogEntry{ + Msg: views.GetPrettyLogLine("Request submitted"), + } + + if target != nil { + requestLogEntry.TargetName = &target.Name + } else if createTargetDto != nil { + requestLogEntry.TargetName = &createTargetDto.Name + } + + logs_view.DisplayLogEntry(requestLogEntry, logs_view.STATIC_INDEX) + + activeProfile, err = c.GetActiveProfile() + if err != nil { + return err + } + + if target != nil { + targetId = target.Id + } else if createTargetDto != nil { + targetId = createTargetDto.Id + } + + logsContext, stopLogs := context.WithCancel(context.Background()) + defer stopLogs() + + if createTargetDto != nil { + go apiclient_util.ReadTargetLogs(logsContext, apiclient_util.ReadLogParams{ + Id: targetId, + Label: &createTargetDto.Name, + ActiveProfile: activeProfile, + Follow: util.Pointer(true), + SkipPrefixLengthSetup: true, + }) + + t, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(apiclient.CreateTargetDTO{ + Id: createTargetDto.Id, + Name: createTargetDto.Name, + TargetConfigName: createTargetDto.TargetConfigName, + }).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + target = &apiclient.TargetDTO{ + Id: t.Id, + Name: t.Name, + Options: t.Options, + ProviderInfo: t.ProviderInfo, + Default: t.Default, + } + } + + var tsConn *tsnet.Server + if !IsLocalDockerTarget(target) || activeProfile.Id != "default" { + tsConn, err = tailscale.GetConnection(&activeProfile) + if err != nil { + return err + } + } + + for i := range createWorkspaceDtos { + createWorkspaceDtos[i].TargetId = targetId + go apiclient_util.ReadWorkspaceLogs(logsContext, apiclient_util.ReadLogParams{ + Id: createWorkspaceDtos[i].Id, + Label: &createWorkspaceDtos[i].Name, + ActiveProfile: activeProfile, + Index: util.Pointer(i), + Follow: util.Pointer(true), + SkipPrefixLengthSetup: true, + }) + + _, res, err = apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(createWorkspaceDtos[i]).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + } + + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, createWorkspaceDtos[0].GitProviderConfigId) + if err != nil { + log.Warn(err) + } + + err = waitForDial(target, createWorkspaceDtos[0].Id, &activeProfile, tsConn, gpgKey) + if err != nil { + return err + } + + stopLogs() + + // Make sure terminal cursor is reset + fmt.Print("\033[?25h") + + chosenIdeId := c.DefaultIdeId + if IdeFlag != "" { + chosenIdeId = IdeFlag + } + + ideList := config.GetIdeList() + var chosenIde config.Ide + + for _, ide := range ideList { + if ide.Id == chosenIdeId { + chosenIde = ide + } + } + + fmt.Println() + + ws, err := apiclient_util.GetWorkspace(createWorkspaceDtos[0].Id, true) + if err != nil { + return err + } + + info.Render(ws, chosenIde.Name, false) + + if noIdeFlag { + views.RenderCreationInfoMessage("Run 'daytona code' when you're ready to start developing") + return nil + } + + views.RenderCreationInfoMessage(fmt.Sprintf("Opening the workspace in %s ...", chosenIde.Name)) + + return workspace_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *ws.Info.ProviderMetadata, YesFlag, gpgKey) + }, +} + +var YesFlag bool +var targetNameFlag string +var IdeFlag string +var noIdeFlag bool +var blankFlag bool +var multiWorkspaceFlag bool + +var workspaceConfigurationFlags = workspace_common.WorkspaceConfigurationFlags{ + Builder: new(views_util.BuildChoice), + CustomImage: new(string), + CustomImageUser: new(string), + Branches: new([]string), + DevcontainerPath: new(string), + EnvVars: new([]string), + Manual: new(bool), + GitProviderConfig: new(string), +} + +func init() { + ideList := config.GetIdeList() + ids := make([]string, len(ideList)) + for i, ide := range ideList { + ids[i] = ide.Id + } + ideListStr := strings.Join(ids, ", ") + + CreateCmd.Flags().StringVarP(&IdeFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) + CreateCmd.Flags().StringVarP(&targetNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") + CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank workspace without using existing configurations") + CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the target in the IDE after target creation") + CreateCmd.Flags().BoolVar(&multiWorkspaceFlag, "multi-workspace", false, "Target with multiple workspaces/repos") + CreateCmd.Flags().BoolVarP(&YesFlag, "yes", "y", false, "Automatically confirm any prompts") + CreateCmd.Flags().StringSliceVar(workspaceConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the workspaces") + + workspace_common.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) +} + +func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { + if IsLocalDockerTarget(target) && (activeProfile != nil && activeProfile.Id == "default") { + err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) + if err != nil { + return err + } + + workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + + for { + sshCommand := exec.Command("ssh", workspaceHostname, "daytona", "version") + sshCommand.Stdin = nil + sshCommand.Stdout = nil + sshCommand.Stderr = &util.TraceLogWriter{} + + err = sshCommand.Run() + if err == nil { + return nil + } + + time.Sleep(100 * time.Millisecond) + } + } + + connectChan := make(chan error) + spinner := time.After(15 * time.Second) + timeout := time.After(2 * time.Minute) + + go func() { + for { + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(workspaceId), ssh_config.SSH_PORT)) + if err == nil { + connectChan <- dialConn.Close() + return + } + time.Sleep(100 * time.Millisecond) + } + }() + + select { + case err := <-connectChan: + return err + case <-spinner: + err := views_util.WithInlineSpinner("Connection to tailscale is taking longer than usual", func() error { + select { + case err := <-connectChan: + return err + case <-timeout: + return errors.New("secure connection to the Daytona Server could not be established. Please check your internet connection or Tailscale availability") + } + }) + return err + } +} + +func IsLocalDockerTarget(target *apiclient.TargetDTO) bool { + if target.ProviderInfo.Name != "docker-provider" { + return false + } + + return !strings.Contains(target.Options, "Remote Hostname") +} diff --git a/pkg/cmd/workspace/util/creation_data.go b/pkg/cmd/workspace/create/creation_data.go similarity index 91% rename from pkg/cmd/workspace/util/creation_data.go rename to pkg/cmd/workspace/create/creation_data.go index d45b21f6d3..580a8a3f3e 100644 --- a/pkg/cmd/workspace/util/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package util +package create import ( "context" @@ -16,10 +16,12 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/common" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/create" "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/docker/docker/pkg/stringid" ) type WorkspacesDataPromptConfig struct { @@ -250,7 +252,7 @@ func GetBranchFromWorkspaceConfig(workspaceConfig *apiclient.WorkspaceConfig, ap }, nil } -func GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags WorkspaceConfigurationFlags) (*apiclient.CreateWorkspaceDTO, error) { +func GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags) (*apiclient.CreateWorkspaceDTO, error) { workspace := &apiclient.CreateWorkspaceDTO{ GitProviderConfigId: workspaceConfigurationFlags.GitProviderConfig, BuildConfig: &apiclient.BuildConfig{}, @@ -346,3 +348,34 @@ func createGetRepoContextFromRepository(providerRepo *apiclient.GitRepository) a return result } + +func setInitialWorkspaceNames(createWorkspaceDtos *[]apiclient.CreateWorkspaceDTO, existingWorkspaces []apiclient.WorkspaceDTO) { + existingNames := make(map[string]bool) + for _, workspace := range existingWorkspaces { + existingNames[workspace.Name] = true + } + + for i := range *createWorkspaceDtos { + originalName := (*createWorkspaceDtos)[i].Name + newName := originalName + counter := 2 + + for existingNames[newName] { + newName = fmt.Sprintf("%s%d", originalName, counter) + counter++ + } + + (*createWorkspaceDtos)[i].Name = newName + existingNames[newName] = true + } +} + +func generateWorkspaceIds(createWorkspaceDtos *[]apiclient.CreateWorkspaceDTO) []string { + for i := range *createWorkspaceDtos { + wsId := stringid.GenerateRandomID() + wsId = stringid.TruncateID(wsId) + (*createWorkspaceDtos)[i].Id = wsId + } + + return nil +} diff --git a/pkg/cmd/workspace/create/get_target.go b/pkg/cmd/workspace/create/get_target.go new file mode 100644 index 0000000000..c1cb367e2c --- /dev/null +++ b/pkg/cmd/workspace/create/get_target.go @@ -0,0 +1,76 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package create + +import ( + "context" + "fmt" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/target" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views/target/selection" +) + +type GetTargetConfigParams struct { + ApiClient *apiclient.APIClient + ActiveProfileName string + TargetNameFlag string + PromptUsingTUI bool +} + +func GetTarget(ctx context.Context, params GetTargetConfigParams) (t *apiclient.TargetDTO, createTargetDto *apiclient.CreateTargetDTO, err error) { + targetList, res, err := params.ApiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return nil, nil, apiclient_util.HandleErrorResponse(res, err) + } + + if params.TargetNameFlag != "" { + for _, t := range targetList { + if t.Name == params.TargetNameFlag { + return &t, nil, nil + } + } + return nil, nil, fmt.Errorf("target '%s' not found", params.TargetNameFlag) + } + + if !params.PromptUsingTUI { + for _, t := range targetList { + if t.Default { + return &t, nil, nil + } + } + } + + if len(targetList) == 0 { + createTargetDto, err := target.CreateTargetDtoFlow(ctx, target.TargetCreationParams{ + ApiClient: params.ApiClient, + ActiveProfileName: params.ActiveProfileName, + }) + if err != nil { + return nil, nil, err + } + return nil, createTargetDto, nil + } + + selectedTarget := selection.GetTargetFromPrompt(targetList, true, "Use") + + if selectedTarget == nil { + return nil, nil, common.ErrCtrlCAbort + } + + if selectedTarget.Name == selection.NewTargetIdentifier { + createTargetDto, err := target.CreateTargetDtoFlow(ctx, target.TargetCreationParams{ + ApiClient: params.ApiClient, + ActiveProfileName: params.ActiveProfileName, + }) + if err != nil { + return nil, createTargetDto, err + } + return nil, createTargetDto, nil + } + + return selectedTarget, nil, nil +} diff --git a/pkg/cmd/workspace/create/process_cmd_arguments.go b/pkg/cmd/workspace/create/process_cmd_arguments.go new file mode 100644 index 0000000000..7f4a569969 --- /dev/null +++ b/pkg/cmd/workspace/create/process_cmd_arguments.go @@ -0,0 +1,174 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package create + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/common" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" +) + +type ProcessCmdArgumentsConfig struct { + ApiClient *apiclient.APIClient + RepoUrls []string + CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO + ExistingWorkspaces *[]apiclient.WorkspaceDTO + WorkspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags + BlankFlag bool +} + +type ProcessGitUrlConfig struct { + ApiClient *apiclient.APIClient + RepoUrl string + CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO + WorkspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags + Branch *string + BlankFlag bool +} + +func ProcessCmdArguments(ctx context.Context, config ProcessCmdArgumentsConfig) ([]string, error) { + if len(config.RepoUrls) == 0 { + return nil, fmt.Errorf("no repository URLs provided") + } + + if len(config.RepoUrls) > 1 && workspace_common.CheckAnyWorkspaceConfigurationFlagSet(config.WorkspaceConfigurationFlags) { + return nil, fmt.Errorf("can't set custom workspace configuration properties for multiple workspaces") + } + + if *config.WorkspaceConfigurationFlags.Builder != "" && *config.WorkspaceConfigurationFlags.Builder != views_util.DEVCONTAINER && *config.WorkspaceConfigurationFlags.DevcontainerPath != "" { + return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) + } + + var workspaceConfig *apiclient.WorkspaceConfig + + existingWorkspaceConfigNames := []string{} + + for i, repoUrl := range config.RepoUrls { + var branch *string + if len(*config.WorkspaceConfigurationFlags.Branches) > i { + branch = &(*config.WorkspaceConfigurationFlags.Branches)[i] + } + + validatedUrl, err := util.GetValidatedUrl(repoUrl) + if err == nil { + // The argument is a Git URL + existingWorkspaceConfigName, err := processGitURL(ctx, ProcessGitUrlConfig{ + ApiClient: config.ApiClient, + RepoUrl: validatedUrl, + CreateWorkspaceDtos: config.CreateWorkspaceDtos, + WorkspaceConfigurationFlags: config.WorkspaceConfigurationFlags, + Branch: branch, + BlankFlag: config.BlankFlag, + }) + if err != nil { + return nil, err + } + if existingWorkspaceConfigName != nil { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) + } else { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") + } + + continue + } + + // The argument is not a Git URL - try getting the workspace config + workspaceConfig, _, err = config.ApiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, repoUrl).Execute() + if err != nil { + return nil, fmt.Errorf("failed to parse the URL or fetch the workspace config for '%s'", repoUrl) + } + + existingWorkspaceConfigName, err := AddWorkspaceFromConfig(workspaceConfig, config.ApiClient, config.CreateWorkspaceDtos, branch) + if err != nil { + return nil, err + } + if existingWorkspaceConfigName != nil { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) + } else { + existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") + } + } + + generateWorkspaceIds(config.CreateWorkspaceDtos) + setInitialWorkspaceNames(config.CreateWorkspaceDtos, *config.ExistingWorkspaces) + + return existingWorkspaceConfigNames, nil +} + +func processGitURL(ctx context.Context, config ProcessGitUrlConfig) (*string, error) { + encodedURLParam := url.QueryEscape(config.RepoUrl) + + if !config.BlankFlag { + workspaceConfig, res, err := config.ApiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() + if err == nil { + workspaceConfig.GitProviderConfigId = config.WorkspaceConfigurationFlags.GitProviderConfig + return AddWorkspaceFromConfig(workspaceConfig, config.ApiClient, config.CreateWorkspaceDtos, config.Branch) + } + + if res.StatusCode != http.StatusNotFound { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + } + + repo, res, err := config.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + Url: config.RepoUrl, + Branch: config.Branch, + }).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + workspaceName, err := GetSanitizedWorkspaceName(repo.Name) + if err != nil { + return nil, err + } + + config.WorkspaceConfigurationFlags.GitProviderConfig, err = GetGitProviderConfigIdFromFlag(ctx, config.ApiClient, config.WorkspaceConfigurationFlags.GitProviderConfig) + if err != nil { + return nil, err + } + + if config.WorkspaceConfigurationFlags.GitProviderConfig == nil || *config.WorkspaceConfigurationFlags.GitProviderConfig == "" { + gitProviderConfigs, res, err := config.ApiClient.GitProviderAPI.ListGitProvidersForUrl(context.Background(), url.QueryEscape(config.RepoUrl)).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + if len(gitProviderConfigs) == 1 { + config.WorkspaceConfigurationFlags.GitProviderConfig = &gitProviderConfigs[0].Id + } else if len(gitProviderConfigs) > 1 { + gp := selection.GetGitProviderConfigFromPrompt(selection.GetGitProviderConfigParams{ + GitProviderConfigs: gitProviderConfigs, + ActionVerb: "Use", + }) + if gp == nil { + return nil, common.ErrCtrlCAbort + } + config.WorkspaceConfigurationFlags.GitProviderConfig = &gp.Id + } + } + + workspace, err := GetCreateWorkspaceDtoFromFlags(config.WorkspaceConfigurationFlags) + if err != nil { + return nil, err + } + + workspace.Name = workspaceName + workspace.Source = apiclient.CreateWorkspaceSourceDTO{ + Repository: *repo, + } + + *config.CreateWorkspaceDtos = append(*config.CreateWorkspaceDtos, *workspace) + + return nil, nil +} diff --git a/pkg/cmd/workspace/create/process_prompting.go b/pkg/cmd/workspace/create/process_prompting.go new file mode 100644 index 0000000000..61bf818c45 --- /dev/null +++ b/pkg/cmd/workspace/create/process_prompting.go @@ -0,0 +1,89 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package create + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/create" +) + +type ProcessPromptingConfig struct { + ApiClient *apiclient.APIClient + CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO + ExistingWorkspaces *[]apiclient.WorkspaceDTO + WorkspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags + MultiWorkspaceFlag bool + BlankFlag bool + TargetName string + IsImporting *bool +} + +func ProcessPrompting(ctx context.Context, config ProcessPromptingConfig) error { + if workspace_common.CheckAnyWorkspaceConfigurationFlagSet(config.WorkspaceConfigurationFlags) || (config.WorkspaceConfigurationFlags.Branches != nil && len(*config.WorkspaceConfigurationFlags.Branches) > 0) { + return errors.New("please provide the repository URL in order to set up custom workspace details through the CLI") + } + + gitProviders, res, err := config.ApiClient.GitProviderAPI.ListGitProviders(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + workspaceConfigs, res, err := config.ApiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + apiServerConfig, res, err := config.ApiClient.ServerAPI.GetConfig(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + BuildChoice: views_util.AUTOMATIC, + Image: &apiServerConfig.DefaultWorkspaceImage, + ImageUser: &apiServerConfig.DefaultWorkspaceUser, + DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, + } + + *config.CreateWorkspaceDtos, err = GetWorkspacesCreationDataFromPrompt(WorkspacesDataPromptConfig{ + UserGitProviders: gitProviders, + WorkspaceConfigs: workspaceConfigs, + Manual: *config.WorkspaceConfigurationFlags.Manual, + MultiWorkspace: config.MultiWorkspaceFlag, + BlankWorkspace: config.BlankFlag, + ApiClient: config.ApiClient, + Defaults: workspaceDefaults, + }) + + if err != nil { + return err + } + + generateWorkspaceIds(config.CreateWorkspaceDtos) + setInitialWorkspaceNames(config.CreateWorkspaceDtos, *config.ExistingWorkspaces) + + submissionFormConfig := create.SubmissionFormConfig{ + ChosenName: &config.TargetName, + WorkspaceList: config.CreateWorkspaceDtos, + NameLabel: config.TargetName, + Defaults: workspaceDefaults, + ExistingWorkspaceNames: util.ArrayMap(*config.ExistingWorkspaces, func(w apiclient.WorkspaceDTO) string { + return w.Name + }), + } + + err = create.RunSubmissionForm(submissionFormConfig) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/cmd/workspace/util/repository_wizard.go b/pkg/cmd/workspace/create/repository_wizard.go similarity index 99% rename from pkg/cmd/workspace/util/repository_wizard.go rename to pkg/cmd/workspace/create/repository_wizard.go index 39966c698c..fc9979a441 100644 --- a/pkg/cmd/workspace/util/repository_wizard.go +++ b/pkg/cmd/workspace/create/repository_wizard.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package util +package create import ( "context" diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index b06c306d71..4efbba1aa9 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -13,6 +13,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -137,7 +138,7 @@ var DeleteCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getWorkspaceNameCompletions() + return common.GetWorkspaceNameCompletions() }, } diff --git a/pkg/cmd/workspace/info.go b/pkg/cmd/workspace/info.go index cf183dad6a..ccfbdf07da 100644 --- a/pkg/cmd/workspace/info.go +++ b/pkg/cmd/workspace/info.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -10,6 +10,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/info" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -17,8 +18,8 @@ import ( ) var InfoCmd = &cobra.Command{ - Use: "info [TARGET]", - Short: "Show target info", + Use: "info [WORKSPACE]", + Short: "Show workspace info", Aliases: []string{"view", "inspect"}, Args: cobra.RangeArgs(0, 1), GroupID: util.TARGET_GROUP, @@ -73,7 +74,7 @@ var InfoCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getWorkspaceNameCompletions() + return common.GetWorkspaceNameCompletions() }, } diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 7839ac82bc..785cd8e5ad 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -19,7 +19,7 @@ var verbose bool var ListCmd = &cobra.Command{ Use: "list", - Short: "List targets", + Short: "List workspaces", Args: cobra.ExactArgs(0), Aliases: []string{"ls"}, GroupID: util.TARGET_GROUP, diff --git a/pkg/cmd/workspace/logs.go b/pkg/cmd/workspace/logs.go new file mode 100644 index 0000000000..1ae7e2f3e7 --- /dev/null +++ b/pkg/cmd/workspace/logs.go @@ -0,0 +1,95 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/spf13/cobra" +) + +var followFlag bool + +var LogsCmd = &cobra.Command{ + Use: "logs [WORKSPACE]", + Short: "View the logs of a workspace", + Args: cobra.RangeArgs(0, 2), + GroupID: util.TARGET_GROUP, + Aliases: []string{"lg", "log"}, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + var ws *apiclient.WorkspaceDTO + + if len(args) == 0 { + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) + return nil + } + + if format.FormatFlag != "" { + format.UnblockStdOut() + } + + ws = selection.GetWorkspaceFromPrompt(workspaceList, "View Logs For") + if format.FormatFlag != "" { + format.BlockStdOut() + } + + } else { + ws, err = apiclient_util.GetWorkspace(args[0], true) + if err != nil { + return err + } + } + + if ws == nil { + return nil + } + + apiclient_util.ReadWorkspaceLogs(ctx, apiclient_util.ReadLogParams{ + Id: ws.Id, + Label: &ws.Name, + ActiveProfile: activeProfile, + Index: util.Pointer(0), + Follow: &followFlag, + }) + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return common.GetWorkspaceNameCompletions() + }, +} + +func init() { + LogsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") +} diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/workspace/restart.go new file mode 100644 index 0000000000..6ef66626af --- /dev/null +++ b/pkg/cmd/workspace/restart.go @@ -0,0 +1,78 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + + "github.com/spf13/cobra" +) + +var RestartCmd = &cobra.Command{ + Use: "restart [WORKSPACE]", + Short: "Restart a workspace", + Args: cobra.RangeArgs(0, 1), + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + var workspace *apiclient.WorkspaceDTO + + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) + return nil + } + + if len(args) == 0 { + workspace := selection.GetWorkspaceFromPrompt(workspaceList, "Restart") + if workspace == nil { + return nil + } + } else { + workspace, err = apiclient_util.GetWorkspace(args[0], false) + if err != nil { + return err + } + } + + err = RestartWorkspace(apiClient, *workspace) + if err != nil { + return err + } + + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' restarted successfully", workspace.Name)) + + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return common.GetAllWorkspacesByState(common.WORKSPACE_STATE_RUNNING) + }, +} + +func RestartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO) error { + err := StopWorkspace(apiClient, workspace) + if err != nil { + return err + } + return StartWorkspace(apiClient, workspace) +} diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index c6bd462c02..05b45d2419 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -15,6 +15,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" + "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" @@ -53,7 +54,7 @@ var SshProxyCmd = &cobra.Command{ return err } - if target.TargetConfig == "local" && profile.Id == "default" { + if create.IsLocalDockerTarget(target) && profile.Id == "default" { // If the target is local, we directly access the ssh port through the container cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index aa693d7efe..f068b4c2d9 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -16,6 +16,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -83,7 +85,7 @@ var SshCmd = &cobra.Command{ } if ws.State == nil || ws.State.Uptime < 1 { - wsRunningStatus, err := AutoStartWorkspace(ws.Id) + wsRunningStatus, err := AutoStartWorkspace(*ws) if err != nil { return err } @@ -97,7 +99,7 @@ var SshCmd = &cobra.Command{ sshArgs = append(sshArgs, args[1:]...) } - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, ws.GitProviderConfigId) + gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, ws.GitProviderConfigId) if err != nil { log.Warn(err) } @@ -105,7 +107,7 @@ var SshCmd = &cobra.Command{ return ide.OpenTerminalSsh(activeProfile, ws.Id, gpgKey, sshOptions, sshArgs...) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getWorkspaceNameCompletions() + return common.GetWorkspaceNameCompletions() }, } diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index 2d7b343d7b..cbe9b091e5 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package target +package workspace import ( "context" @@ -13,6 +13,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/views" ide_views "github.com/daytonaio/daytona/pkg/views/ide" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -22,13 +24,6 @@ import ( "github.com/spf13/cobra" ) -type WorkspaceState string - -const ( - WORKSPACE_STATE_RUNNING WorkspaceState = "Running" - WORKSPACE_STATE_STOPPED WorkspaceState = "Unavailable" -) - var allFlag bool var codeFlag bool @@ -38,7 +33,7 @@ var StartCmd = &cobra.Command{ Args: cobra.RangeArgs(0, 1), GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var selectedWorkspaceNames []string + var selectedWorkspaces []apiclient.WorkspaceDTO var activeProfile config.Profile var ideId string var ideList []config.Ide @@ -66,19 +61,25 @@ var StartCmd = &cobra.Command{ views_util.NotifyEmptyWorkspaceList(true) return nil } + selectedWorkspace := selection.GetWorkspaceFromPrompt(workspaceList, "Start") if selectedWorkspace == nil { return nil } - selectedWorkspaceNames = append(selectedWorkspaceNames, selectedWorkspace.Name) + selectedWorkspaces = append(selectedWorkspaces, *selectedWorkspace) } else { - selectedWorkspaceNames = append(selectedWorkspaceNames, args[0]) + workspace, err := apiclient_util.GetWorkspace(args[0], true) + if err != nil { + return err + } + + selectedWorkspaces = append(selectedWorkspaces, *workspace) } - if len(selectedWorkspaceNames) == 1 { + if len(selectedWorkspaces) == 1 { var ws *apiclient.WorkspaceDTO var res *http.Response - workspaceName := selectedWorkspaceNames[0] + workspace := selectedWorkspaces[0] if codeFlag { c, err := config.GetConfig() if err != nil { @@ -93,7 +94,7 @@ var StartCmd = &cobra.Command{ ideList = config.GetIdeList() ideId = c.DefaultIdeId - ws, res, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceName).Verbose(true).Execute() + ws, res, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, workspace.Id).Verbose(true).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -102,38 +103,38 @@ var StartCmd = &cobra.Command{ } } - err = StartWorkspace(apiClient, workspaceName) + err = StartWorkspace(apiClient, workspace) if err != nil { return err } - gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) if err != nil { log.Warn(err) } - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' started successfully", workspaceName)) + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' started successfully", workspace.Name)) if codeFlag { ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList) - err = openIDE(ideId, activeProfile, ws.Id, workspaceProviderMetadata, yesFlag, gpgKey) + err = workspace_common.OpenIDE(ideId, activeProfile, ws.Id, workspaceProviderMetadata, yesFlag, gpgKey) if err != nil { return err } } } else { - for _, ws := range selectedWorkspaceNames { + for _, ws := range selectedWorkspaces { err := StartWorkspace(apiClient, ws) if err != nil { - log.Errorf("Failed to start workspace %s: %v\n\n", ws, err) + log.Errorf("Failed to start workspace %s: %v\n\n", ws.Name, err) continue } - views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", ws)) + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", ws.Name)) } } return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getAllWorkspacesByState(WORKSPACE_STATE_STOPPED) + return common.GetAllWorkspacesByState(common.WORKSPACE_STATE_STOPPED) }, } @@ -156,7 +157,7 @@ func startAllWorkspaces() error { } for _, workspace := range workspaceList { - err := StartWorkspace(apiClient, workspace.Id) + err := StartWorkspace(apiClient, workspace) if err != nil { log.Errorf("Failed to start workspace %s: %v\n\n", workspace.Name, err) continue @@ -167,54 +168,7 @@ func startAllWorkspaces() error { return nil } -func getWorkspaceNameCompletions() ([]string, cobra.ShellCompDirective) { - ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() - if err != nil { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - var choices []string - for _, v := range workspaceList { - choices = append(choices, v.Name) - } - - return choices, cobra.ShellCompDirectiveNoFileComp -} - -func getAllWorkspacesByState(state WorkspaceState) ([]string, cobra.ShellCompDirective) { - ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - workspaceList, _, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() - if err != nil { - return nil, cobra.ShellCompDirectiveNoFileComp - } - - var choices []string - for _, workspace := range workspaceList { - if state == WORKSPACE_STATE_RUNNING && workspace.State.Uptime != 0 { - choices = append(choices, workspace.Name) - break - } - if state == WORKSPACE_STATE_STOPPED && workspace.State.Uptime == 0 { - choices = append(choices, workspace.Name) - break - } - } - - return choices, cobra.ShellCompDirectiveNoFileComp -} - -func StartWorkspace(apiClient *apiclient.APIClient, workspaceId string) error { +func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO) error { ctx := context.Background() timeFormat := time.Now().Format("2006-01-02 15:04:05") from, err := time.Parse("2006-01-02 15:04:05", timeFormat) @@ -233,9 +187,16 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspaceId string) error { } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadWorkspaceLogs(logsContext, 0, activeProfile, workspaceId, true, &from) - - res, err := apiClient.WorkspaceAPI.StartWorkspace(ctx, workspaceId).Execute() + go apiclient_util.ReadWorkspaceLogs(logsContext, apiclient_util.ReadLogParams{ + Id: workspace.Id, + Label: &workspace.Name, + ActiveProfile: activeProfile, + Index: util.Pointer(0), + Follow: util.Pointer(true), + From: &from, + }) + + res, err := apiClient.WorkspaceAPI.StartWorkspace(ctx, workspace.Id).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go new file mode 100644 index 0000000000..76f3dbbd9f --- /dev/null +++ b/pkg/cmd/workspace/stop.go @@ -0,0 +1,158 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "fmt" + "time" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/daytonaio/daytona/pkg/views/workspace/selection" + + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var StopCmd = &cobra.Command{ + Use: "stop [WORKSPACE]", + Short: "Stop a workspace", + Args: cobra.RangeArgs(0, 1), + GroupID: util.TARGET_GROUP, + RunE: func(cmd *cobra.Command, args []string) error { + var selectedWorkspaces []apiclient.WorkspaceDTO + + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if allFlag { + return stopAllWorkspaces() + } + + if len(args) == 0 { + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) + return nil + } + selectedWorkspace := selection.GetWorkspaceFromPrompt(workspaceList, "Stop") + if selectedWorkspace == nil { + return nil + } + selectedWorkspaces = append(selectedWorkspaces, *selectedWorkspace) + } else { + workspace, err := apiclient_util.GetWorkspace(args[0], true) + if err != nil { + return err + } + + selectedWorkspaces = append(selectedWorkspaces, *workspace) + } + + if len(selectedWorkspaces) == 1 { + workspace := selectedWorkspaces[0] + + err = StopWorkspace(apiClient, workspace) + if err != nil { + return err + } + + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' stopped successfully", workspace.Name)) + } else { + for _, ws := range selectedWorkspaces { + err := StopWorkspace(apiClient, ws) + if err != nil { + log.Errorf("Failed to stop workspace %s: %v\n\n", ws.Name, err) + continue + } + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' stopped successfully", ws.Name)) + } + } + return nil + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return common.GetAllWorkspacesByState(common.WORKSPACE_STATE_RUNNING) + }, +} + +func init() { + StopCmd.PersistentFlags().BoolVarP(&allFlag, "all", "a", false, "Stop all targets") + StopCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") +} + +func stopAllWorkspaces() error { + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + for _, workspace := range workspaceList { + err := StopWorkspace(apiClient, workspace) + if err != nil { + log.Errorf("Failed to stop workspace %s: %v\n\n", workspace.Name, err) + continue + } + + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' stopped successfully", workspace.Name)) + } + return nil +} + +func StopWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO) error { + ctx := context.Background() + timeFormat := time.Now().Format("2006-01-02 15:04:05") + from, err := time.Parse("2006-01-02 15:04:05", timeFormat) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + logsContext, stopLogs := context.WithCancel(context.Background()) + go apiclient_util.ReadWorkspaceLogs(logsContext, apiclient_util.ReadLogParams{ + Id: workspace.Id, + Label: &workspace.Name, + ActiveProfile: activeProfile, + Index: util.Pointer(0), + Follow: util.Pointer(true), + From: &from, + }) + + res, err := apiClient.WorkspaceAPI.StopWorkspace(ctx, workspace.Id).Execute() + if err != nil { + stopLogs() + return apiclient_util.HandleErrorResponse(res, err) + } + time.Sleep(100 * time.Millisecond) + stopLogs() + return nil +} diff --git a/pkg/cmd/workspace/util/get_target_config.go b/pkg/cmd/workspace/util/get_target_config.go deleted file mode 100644 index 1314a74d28..0000000000 --- a/pkg/cmd/workspace/util/get_target_config.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package util - -import ( - "context" - "errors" - "fmt" - - "github.com/daytonaio/daytona/internal/util" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/provider" - "github.com/daytonaio/daytona/pkg/provider/manager" - provider_view "github.com/daytonaio/daytona/pkg/views/provider" - "github.com/daytonaio/daytona/pkg/views/targetconfig" -) - -type GetTargetConfigParams struct { - Ctx context.Context - ApiClient *apiclient.APIClient - TargetConfigs []apiclient.TargetConfig - ActiveProfileName string - TargetConfigNameFlag string - PromptUsingTUI bool -} - -func GetTargetConfig(params GetTargetConfigParams) (*targetconfig.TargetConfigView, error) { - if params.TargetConfigNameFlag != "" { - for _, t := range params.TargetConfigs { - if t.Name == params.TargetConfigNameFlag { - return util.Pointer(targetconfig.ToTargetConfigView(t)), nil - } - } - return nil, fmt.Errorf("target config '%s' not found", params.TargetConfigNameFlag) - } - - if !params.PromptUsingTUI { - for _, t := range params.TargetConfigs { - if t.IsDefault { - return util.Pointer(targetconfig.ToTargetConfigView(t)), nil - } - } - } - - serverConfig, res, err := params.ApiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - providersManifest, err := manager.NewProviderManager(manager.ProviderManagerConfig{ - RegistryUrl: serverConfig.RegistryUrl, - }).GetProvidersManifest() - if err != nil { - return nil, err - } - - var providerViewList []provider_view.ProviderView - if providersManifest != nil { - providersManifestLatest := providersManifest.GetLatestVersions() - if providersManifestLatest == nil { - return nil, errors.New("could not get latest provider versions") - } - - latestProviders := provider.GetProviderListFromManifest(providersManifestLatest) - - providerViewList, err = provider.GetProviderViewOptions(params.ApiClient, latestProviders, params.Ctx) - if err != nil { - return nil, err - } - } - - selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(params.TargetConfigs, params.ActiveProfileName, &providerViewList, false, "Use") - if err != nil { - return nil, err - } - - if selectedTargetConfig.ProviderInfo.Installed == nil || *selectedTargetConfig.ProviderInfo.Installed || selectedTargetConfig == nil { - return selectedTargetConfig, nil - } - - err = provider.InstallProvider(params.ApiClient, provider_view.ProviderView{ - Name: selectedTargetConfig.ProviderInfo.Name, - Version: selectedTargetConfig.ProviderInfo.Version, - }, providersManifest) - if err != nil { - return nil, err - } - - targetConfigManifest, res, err := params.ApiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedTargetConfig.ProviderInfo.Name).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - selectedTargetConfig.Name = "" - err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, util.ArrayMap(params.TargetConfigs, func(t apiclient.TargetConfig) string { - return t.Name - })) - if err != nil { - return nil, err - } - - err = targetconfig.SetTargetConfigForm(selectedTargetConfig, *targetConfigManifest) - if err != nil { - return nil, err - } - - res, err = params.ApiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(apiclient.CreateTargetConfigDTO{ - Name: selectedTargetConfig.Name, - Options: selectedTargetConfig.Options, - ProviderInfo: apiclient.ProviderProviderInfo{ - Name: selectedTargetConfig.ProviderInfo.Name, - Version: selectedTargetConfig.ProviderInfo.Version, - }, - }).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - return selectedTargetConfig, nil -} diff --git a/pkg/cmd/workspaceconfig/add.go b/pkg/cmd/workspaceconfig/add.go index e3a4508f46..b4a0185119 100644 --- a/pkg/cmd/workspaceconfig/add.go +++ b/pkg/cmd/workspaceconfig/add.go @@ -12,7 +12,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_util "github.com/daytonaio/daytona/pkg/cmd/workspace/util" + workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + create_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -66,7 +67,7 @@ var workspaceConfigAddCmd = &cobra.Command{ } func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.WorkspaceConfig, error) { - if workspace_util.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { + if workspace_common.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { return nil, errors.New("please provide the repository URL in order to set up custom workspace config details through the CLI") } @@ -88,7 +89,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - createDtos, err = workspace_util.GetWorkspacesCreationDataFromPrompt(workspace_util.WorkspacesDataPromptConfig{ + createDtos, err = create_cmd.GetWorkspacesCreationDataFromPrompt(create_cmd.WorkspacesDataPromptConfig{ UserGitProviders: gitProviders, Manual: *workspaceConfigurationFlags.Manual, MultiWorkspace: false, @@ -120,18 +121,18 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap initialSuggestion := createDtos[0].Name - chosenName := workspace_util.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) + chosenName := create_cmd.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) submissionFormConfig := create.SubmissionFormConfig{ - ChosenName: &chosenName, - SuggestedName: chosenName, - ExistingNames: existingWorkspaceConfigNames, - WorkspaceList: &createDtos, - NameLabel: "Workspace config", - Defaults: workspaceDefaults, + ChosenName: &chosenName, + SuggestedName: chosenName, + ExistingWorkspaceNames: existingWorkspaceConfigNames, + WorkspaceList: &createDtos, + NameLabel: "Workspace config", + Defaults: workspaceDefaults, } - err = create.RunSubmissionForm(submissionFormConfig, nil) + err = create.RunSubmissionForm(submissionFormConfig) if err != nil { return nil, err } @@ -207,12 +208,12 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con return nil, apiclient_util.HandleErrorResponse(res, err) } - workspaceConfigurationFlags.GitProviderConfig, err = workspace_util.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) + workspaceConfigurationFlags.GitProviderConfig, err = create_cmd.GetGitProviderConfigIdFromFlag(ctx, apiClient, workspaceConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } - workspace, err := workspace_util.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) + workspace, err := create_cmd.GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags) if err != nil { return nil, err } @@ -221,8 +222,8 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con if nameFlag != "" { name = nameFlag } else { - workspaceName := workspace_util.GetWorkspaceNameFromRepo(repoUrl) - name = workspace_util.GetSuggestedName(workspaceName, existingWorkspaceConfigNames) + workspaceName := create_cmd.GetWorkspaceNameFromRepo(repoUrl) + name = create_cmd.GetSuggestedName(workspaceName, existingWorkspaceConfigNames) } if workspace.GitProviderConfigId == nil || *workspace.GitProviderConfigId == "" { @@ -276,7 +277,7 @@ func getExistingWorkspaceConfigNames(apiClient *apiclient.APIClient) ([]string, var nameFlag string -var workspaceConfigurationFlags = workspace_util.WorkspaceConfigurationFlags{ +var workspaceConfigurationFlags = workspace_common.WorkspaceConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -289,5 +290,5 @@ var workspaceConfigurationFlags = workspace_util.WorkspaceConfigurationFlags{ func init() { workspaceConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace config name") - workspace_util.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) + workspace_common.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) } diff --git a/pkg/cmd/workspaceconfig/import.go b/pkg/cmd/workspaceconfig/import.go index 388095b4c6..7c0cce2f58 100644 --- a/pkg/cmd/workspaceconfig/import.go +++ b/pkg/cmd/workspaceconfig/import.go @@ -12,6 +12,7 @@ import ( "os" "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" @@ -212,21 +213,21 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, } submissionFormConfig := create.SubmissionFormConfig{ - ChosenName: &config.Name, - SuggestedName: config.Name, - ExistingNames: existingWorkspaceConfigNames, - WorkspaceList: &createDto, - NameLabel: "Workspace config", - Defaults: workspaceDefaults, + ChosenName: &config.Name, + SuggestedName: config.Name, + ExistingWorkspaceNames: existingWorkspaceConfigNames, + WorkspaceList: &createDto, + NameLabel: "Workspace config", + Defaults: workspaceDefaults, + ImportConfirmation: util.Pointer(true), } - confirmation := true - err = create.RunSubmissionForm(submissionFormConfig, &confirmation) + err = create.RunSubmissionForm(submissionFormConfig) if err != nil { return err } - if confirmation { + if submissionFormConfig.ImportConfirmation != nil && *submissionFormConfig.ImportConfirmation { res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/db/dto/target.go b/pkg/db/dto/target.go index fe958549ba..028d91b3d3 100644 --- a/pkg/db/dto/target.go +++ b/pkg/db/dto/target.go @@ -8,18 +8,33 @@ import ( ) type TargetDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name" gorm:"unique"` - TargetConfig string `json:"config"` - ApiKey string `json:"apiKey"` + Id string `gorm:"primaryKey"` + Name string `json:"name" gorm:"unique"` + ProviderInfo ProviderInfoDTO `json:"providerInfo" gorm:"serializer:json"` + Options string `json:"options"` + ApiKey string `json:"apiKey"` + IsDefault bool `json:"isDefault"` + Workspaces []WorkspaceDTO `gorm:"foreignKey:TargetId;references:Id"` +} + +type ProviderInfoDTO struct { + Name string `json:"name" validate:"required"` + Version string `json:"version" validate:"required"` + Label *string `json:"label" validate:"optional"` } func ToTargetDTO(target *target.Target) TargetDTO { targetDTO := TargetDTO{ - Id: target.Id, - Name: target.Name, - TargetConfig: target.TargetConfig, - ApiKey: target.ApiKey, + Id: target.Id, + Name: target.Name, + ProviderInfo: ProviderInfoDTO{ + Name: target.ProviderInfo.Name, + Version: target.ProviderInfo.Version, + Label: target.ProviderInfo.Label, + }, + Options: target.Options, + ApiKey: target.ApiKey, + IsDefault: target.IsDefault, } return targetDTO @@ -27,11 +42,24 @@ func ToTargetDTO(target *target.Target) TargetDTO { func ToTarget(targetDTO TargetDTO) *target.Target { target := target.Target{ - Id: targetDTO.Id, - Name: targetDTO.Name, - TargetConfig: targetDTO.TargetConfig, - ApiKey: targetDTO.ApiKey, + Id: targetDTO.Id, + Name: targetDTO.Name, + ProviderInfo: target.ProviderInfo{ + Name: targetDTO.ProviderInfo.Name, + Version: targetDTO.ProviderInfo.Version, + Label: targetDTO.ProviderInfo.Label, + }, + Options: targetDTO.Options, + IsDefault: targetDTO.IsDefault, + ApiKey: targetDTO.ApiKey, } return &target } + +func ToTargetViewDTO(targetDto TargetDTO) *target.TargetViewDTO { + return &target.TargetViewDTO{ + Target: *ToTarget(targetDto), + WorkspaceCount: len(targetDto.Workspaces), + } +} diff --git a/pkg/db/dto/target_config.go b/pkg/db/dto/target_config.go index feb6c2fc03..ea9f79280f 100644 --- a/pkg/db/dto/target_config.go +++ b/pkg/db/dto/target_config.go @@ -3,37 +3,37 @@ package dto -import "github.com/daytonaio/daytona/pkg/provider" +import ( + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" +) type TargetConfigDTO struct { - Name string `json:"name" gorm:"primaryKey"` - ProviderName string `json:"providerName"` - ProviderLabel *string `json:"providerLabel,omitempty"` - ProviderVersion string `json:"providerVersion"` - Options string `json:"options"` - IsDefault bool `json:"isDefault"` + Name string `json:"name" gorm:"primaryKey"` + ProviderInfo ProviderInfoDTO `json:"providerInfo" gorm:"serializer:json"` + Options string `json:"options"` } -func ToTargetConfigDTO(targetConfig *provider.TargetConfig) TargetConfigDTO { +func ToTargetConfigDTO(targetConfig *config.TargetConfig) TargetConfigDTO { return TargetConfigDTO{ - Name: targetConfig.Name, - ProviderName: targetConfig.ProviderInfo.Name, - ProviderLabel: targetConfig.ProviderInfo.Label, - ProviderVersion: targetConfig.ProviderInfo.Version, - Options: targetConfig.Options, - IsDefault: targetConfig.IsDefault, + Name: targetConfig.Name, + ProviderInfo: ProviderInfoDTO{ + Name: targetConfig.ProviderInfo.Name, + Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, + }, + Options: targetConfig.Options, } } -func ToTargetConfig(targetConfigDTO TargetConfigDTO) *provider.TargetConfig { - return &provider.TargetConfig{ +func ToTargetConfig(targetConfigDTO TargetConfigDTO) *config.TargetConfig { + return &config.TargetConfig{ Name: targetConfigDTO.Name, - ProviderInfo: provider.ProviderInfo{ - Name: targetConfigDTO.ProviderName, - Label: targetConfigDTO.ProviderLabel, - Version: targetConfigDTO.ProviderVersion, + ProviderInfo: target.ProviderInfo{ + Name: targetConfigDTO.ProviderInfo.Name, + Version: targetConfigDTO.ProviderInfo.Version, + Label: targetConfigDTO.ProviderInfo.Label, }, - Options: targetConfigDTO.Options, - IsDefault: targetConfigDTO.IsDefault, + Options: targetConfigDTO.Options, } } diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index 59be63cd7e..ad4f0dbeb1 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -8,7 +8,7 @@ import ( "github.com/daytonaio/daytona/internal/util" . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target/config" ) type TargetConfigStore struct { @@ -24,7 +24,7 @@ func NewTargetConfigStore(db *gorm.DB) (*TargetConfigStore, error) { return &TargetConfigStore{db: db}, nil } -func (s *TargetConfigStore) List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { +func (s *TargetConfigStore) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { targetConfigDTOs := []TargetConfigDTO{} tx := processTargetConfigFilters(s.db, filter).Find(&targetConfigDTOs) @@ -32,18 +32,18 @@ func (s *TargetConfigStore) List(filter *provider.TargetConfigFilter) ([]*provid return nil, tx.Error } - return util.ArrayMap(targetConfigDTOs, func(targetConfigDTO TargetConfigDTO) *provider.TargetConfig { + return util.ArrayMap(targetConfigDTOs, func(targetConfigDTO TargetConfigDTO) *config.TargetConfig { return ToTargetConfig(targetConfigDTO) }), nil } -func (s *TargetConfigStore) Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) { +func (s *TargetConfigStore) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { targetConfigDTO := TargetConfigDTO{} tx := processTargetConfigFilters(s.db, filter).First(&targetConfigDTO) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, provider.ErrTargetConfigNotFound + return nil, config.ErrTargetConfigNotFound } return nil, tx.Error } @@ -51,7 +51,7 @@ func (s *TargetConfigStore) Find(filter *provider.TargetConfigFilter) (*provider return ToTargetConfig(targetConfigDTO), nil } -func (s *TargetConfigStore) Save(targetConfig *provider.TargetConfig) error { +func (s *TargetConfigStore) Save(targetConfig *config.TargetConfig) error { tx := s.db.Save(ToTargetConfigDTO(targetConfig)) if tx.Error != nil { return tx.Error @@ -60,26 +60,23 @@ func (s *TargetConfigStore) Save(targetConfig *provider.TargetConfig) error { return nil } -func (s *TargetConfigStore) Delete(targetConfig *provider.TargetConfig) error { +func (s *TargetConfigStore) Delete(targetConfig *config.TargetConfig) error { tx := s.db.Delete(ToTargetConfigDTO(targetConfig)) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return provider.ErrTargetConfigNotFound + return config.ErrTargetConfigNotFound } return nil } -func processTargetConfigFilters(tx *gorm.DB, filter *provider.TargetConfigFilter) *gorm.DB { +func processTargetConfigFilters(tx *gorm.DB, filter *config.TargetConfigFilter) *gorm.DB { if filter != nil { if filter.Name != nil { tx = tx.Where("name = ?", *filter.Name) } - if filter.Default != nil { - tx = tx.Where("is_default = ?", *filter.Default) - } } return tx diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index bf55b32453..80243fb099 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -23,24 +23,34 @@ func NewTargetStore(db *gorm.DB) (*TargetStore, error) { return &TargetStore{db: db}, nil } -func (store *TargetStore) List() ([]*target.Target, error) { +func (s *TargetStore) List(filter *target.TargetFilter) ([]*target.TargetViewDTO, error) { targetDTOs := []TargetDTO{} - tx := store.db.Find(&targetDTOs) + + tx := processTargetFilters(s.db, filter).Preload("Workspaces").Find(&targetDTOs) if tx.Error != nil { return nil, tx.Error } - targets := []*target.Target{} + targetViewDTOs := []*target.TargetViewDTO{} for _, targetDTO := range targetDTOs { - targets = append(targets, ToTarget(targetDTO)) + viewDTO := &target.TargetViewDTO{ + Target: *ToTarget(targetDTO), + WorkspaceCount: len(targetDTO.Workspaces), + } + targetViewDTOs = append(targetViewDTOs, viewDTO) } - return targets, nil + return targetViewDTOs, nil } -func (w *TargetStore) Find(idOrName string) (*target.Target, error) { +func (s *TargetStore) Find(filter *target.TargetFilter) (*target.TargetViewDTO, error) { targetDTO := TargetDTO{} - tx := w.db.Where("id = ? OR name = ?", idOrName, idOrName).First(&targetDTO) + + tx := processTargetFilters(s.db, filter).Preload("Workspaces").First(&targetDTO) + if tx.Error != nil { + return nil, tx.Error + } + if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, target.ErrTargetNotFound @@ -48,11 +58,16 @@ func (w *TargetStore) Find(idOrName string) (*target.Target, error) { return nil, tx.Error } - return ToTarget(targetDTO), nil + targetViewDTO := &target.TargetViewDTO{ + Target: *ToTarget(targetDTO), + WorkspaceCount: len(targetDTO.Workspaces), + } + + return targetViewDTO, nil } -func (w *TargetStore) Save(target *target.Target) error { - tx := w.db.Save(ToTargetDTO(target)) +func (s *TargetStore) Save(target *target.Target) error { + tx := s.db.Save(ToTargetDTO(target)) if tx.Error != nil { return tx.Error } @@ -60,8 +75,8 @@ func (w *TargetStore) Save(target *target.Target) error { return nil } -func (w *TargetStore) Delete(t *target.Target) error { - tx := w.db.Delete(ToTargetDTO(t)) +func (s *TargetStore) Delete(t *target.Target) error { + tx := s.db.Delete(ToTargetDTO(t)) if tx.Error != nil { return tx.Error } @@ -71,3 +86,16 @@ func (w *TargetStore) Delete(t *target.Target) error { return nil } + +func processTargetFilters(tx *gorm.DB, filter *target.TargetFilter) *gorm.DB { + if filter != nil { + if filter.IdOrName != nil { + tx = tx.Where("id = ? OR name = ?", *filter.IdOrName, *filter.IdOrName) + } + if filter.Default != nil { + tx = tx.Where("is_default = ?", *filter.Default) + } + } + + return tx +} diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index 5ee67c14c0..e21507e998 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -29,9 +29,13 @@ var workspace1 = &workspace.Workspace{ } var target1 = &target.Target{ - Id: "123", - Name: "test", - TargetConfig: "local", + Id: "123", + Name: "test", + ProviderInfo: target.ProviderInfo{ + Name: "test-provider", + Version: "test", + }, + Options: "test-options", } type DockerClientTestSuiteConfig struct { diff --git a/pkg/docker/create.go b/pkg/docker/create.go index 97c2af2176..61ba08cf83 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -95,7 +95,7 @@ func (d *DockerClient) cloneWorkspaceRepository(opts *CreateWorkspaceOptions) er } gitService := git.Service{ - WorkspaceDir: fmt.Sprintf("/workdir/%s", opts.Workspace.Name), + WorkspaceDir: fmt.Sprintf("/workdir/%s", opts.Workspace.WorkspaceFolderName()), } cloneCmd := gitService.CloneRepositoryCmd(opts.Workspace.Repository, auth) @@ -203,7 +203,7 @@ func (d *DockerClient) updateContainerUserUidGid(containerId string, opts *Creat func (d *DockerClient) toCreateDevcontainerOptions(opts *CreateWorkspaceOptions, prebuild bool) CreateDevcontainerOptions { return CreateDevcontainerOptions{ WorkspaceDir: opts.WorkspaceDir, - WorkspaceName: opts.Workspace.Name, + WorkspaceFolderName: opts.Workspace.WorkspaceFolderName(), BuildConfig: opts.Workspace.BuildConfig, LogWriter: opts.LogWriter, SshClient: opts.SshClient, diff --git a/pkg/docker/create_devcontainer.go b/pkg/docker/create_devcontainer.go index c911bbfeea..1a31147958 100644 --- a/pkg/docker/create_devcontainer.go +++ b/pkg/docker/create_devcontainer.go @@ -42,7 +42,7 @@ type DevcontainerPaths struct { type CreateDevcontainerOptions struct { WorkspaceDir string // Name of the project inside the devcontainer - WorkspaceName string + WorkspaceFolderName string BuildConfig *buildconfig.BuildConfig LogWriter io.Writer SshClient *ssh.Client @@ -136,7 +136,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s // If the workspaceFolder is not set in the devcontainer.json, we set it to /workspaces/ if _, ok := devcontainerConfig["workspaceFolder"].(string); !ok { - workspaceFolder = fmt.Sprintf("/workspaces/%s", opts.WorkspaceName) + workspaceFolder = fmt.Sprintf("/workspaces/%s", opts.WorkspaceFolderName) devcontainerConfig["workspaceFolder"] = workspaceFolder } devcontainerConfig["workspaceMount"] = fmt.Sprintf("source=%s,target=%s,type=bind", opts.WorkspaceDir, workspaceFolder) @@ -202,7 +202,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s return "", "", err } - project.Name = fmt.Sprintf("%s-%s", opts.WorkspaceName, util.Hash(opts.WorkspaceDir)) + project.Name = fmt.Sprintf("%s-%s", opts.WorkspaceFolderName, util.Hash(opts.WorkspaceDir)) for _, service := range project.Services { if service.Build != nil { diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index 8d256537af..83fb08f88e 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -41,7 +41,7 @@ func (d *DockerClient) initWorkspaceContainer(opts *CreateWorkspaceOptions, moun mounts = append(mounts, mount.Mount{ Type: mount.TypeBind, Source: opts.WorkspaceDir, - Target: fmt.Sprintf("/home/%s/%s", opts.Workspace.User, opts.Workspace.Name), + Target: fmt.Sprintf("/home/%s/%s", opts.Workspace.User, opts.Workspace.WorkspaceFolderName()), }) } diff --git a/pkg/docker/create_test.go b/pkg/docker/create_test.go index 050232dc37..2f0aeed15b 100644 --- a/pkg/docker/create_test.go +++ b/pkg/docker/create_test.go @@ -92,7 +92,7 @@ func (s *DockerClientTestSuite) TestCreateWorkspace() { { Type: mount.TypeBind, Source: workspaceDir, - Target: fmt.Sprintf("/home/%s/%s", workspace1.User, workspace1.Name), + Target: fmt.Sprintf("/home/%s/%s", workspace1.User, workspace1.Repository.Name), }, }, }, diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go index f1efa11913..91ef677292 100644 --- a/pkg/docker/info_test.go +++ b/pkg/docker/info_test.go @@ -46,9 +46,13 @@ func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { func (s *DockerClientTestSuite) TestGetTargetInfo() { targetWithoutWorkspaces := &target.Target{ - Id: "123", - Name: "test", - TargetConfig: "local", + Id: "123", + Name: "test", + ProviderInfo: target.ProviderInfo{ + Name: "test-provider", + Version: "test", + }, + Options: "", } targetInfo, err := s.dockerClient.GetTargetInfo(targetWithoutWorkspaces) diff --git a/pkg/docker/pull_image.go b/pkg/docker/pull_image.go index 95aa8d5984..d06d8d8ede 100644 --- a/pkg/docker/pull_image.go +++ b/pkg/docker/pull_image.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/views" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/registry" @@ -68,7 +69,7 @@ func (d *DockerClient) PullImage(imageName string, cr *containerregistry.Contain return err } if logWriter != nil { - logWriter.Write([]byte("Image pulled successfully\n")) + logWriter.Write([]byte(views.GetPrettyLogLine("Image pulled successfully"))) } return nil diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index d5bee641bb..89a3da6f42 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -17,6 +17,8 @@ import ( os_util "github.com/daytonaio/daytona/pkg/os" . "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/shirou/gopsutil/process" @@ -148,6 +150,11 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool return fmt.Errorf("failed to get provider: %w", err) } + providerInfo, err := (*p).GetInfo() + if err != nil { + return err + } + existingTargetConfigs, err := m.targetConfigService.Map() if err != nil { return errors.New("failed to get target configs: " + err.Error()) @@ -165,7 +172,15 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool continue } - err := m.targetConfigService.Save(&targetConfig) + err = m.targetConfigService.Save(&config.TargetConfig{ + Name: targetConfig.Name, + ProviderInfo: target.ProviderInfo{ + Name: providerInfo.Name, + Version: providerInfo.Version, + Label: providerInfo.Label, + }, + Options: targetConfig.Options, + }) if err != nil { log.Errorf("Failed to set target %s: %s", targetConfig.Name, err) } else { diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 8fe906112f..8d0cd43707 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -33,6 +33,12 @@ type Provider interface { GetWorkspaceInfo(*WorkspaceRequest) (*workspace.WorkspaceInfo, error) } +type ProviderInfo struct { + Name string `json:"name" validate:"required"` + Label *string `json:"label" validate:"optional"` + Version string `json:"version" validate:"required"` +} + type ProviderPlugin struct { Impl Provider } diff --git a/pkg/provider/types.go b/pkg/provider/types.go index 401c9dbd82..3b55daedc3 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -10,12 +10,6 @@ import ( "github.com/daytonaio/daytona/pkg/workspace" ) -type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Label *string `json:"label" validate:"optional"` - Version string `json:"version" validate:"required"` -} - type InitializeProviderRequest struct { BasePath string DaytonaDownloadUrl string @@ -32,12 +26,11 @@ type InitializeProviderRequest struct { } type TargetRequest struct { - TargetConfigOptions string - Target *target.Target + Target *target.Target } type WorkspaceRequest struct { - TargetConfigOptions string + Target *target.Target ContainerRegistry *containerregistry.ContainerRegistry Workspace *workspace.Workspace GitProviderConfig *gitprovider.GitProviderConfig @@ -46,12 +39,10 @@ type WorkspaceRequest struct { } type TargetConfig struct { - Name string `json:"name" validate:"required"` - ProviderInfo ProviderInfo `json:"providerInfo" validate:"required"` + Name string `json:"name" validate:"required"` // JSON encoded map of options - Options string `json:"options" validate:"required"` - IsDefault bool `json:"isDefault" validate:"required"` -} // @name TargetConfig + Options string `json:"options" validate:"required"` +} type TargetConfigManifest map[string]TargetConfigProperty // @name TargetConfigManifest diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index 10d0e0d76b..1767525cbd 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -8,28 +8,27 @@ import ( "github.com/daytonaio/daytona/pkg/target" ) -func (p *Provisioner) CreateTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) +func (p *Provisioner) CreateTarget(t *target.Target) error { + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).CreateTarget(&provider.TargetRequest{ - TargetConfigOptions: targetConfig.Options, - Target: target, + Target: t, }) return err } func (p *Provisioner) CreateWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.TargetConfig.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.Target.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ - TargetConfigOptions: params.TargetConfig.Options, + Target: params.Target, Workspace: params.Workspace, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index 776bb2b94a..9b211b4a6f 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -9,29 +9,28 @@ import ( "github.com/daytonaio/daytona/pkg/workspace" ) -func (p *Provisioner) DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) +func (p *Provisioner) DestroyTarget(t *target.Target) error { + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).DestroyTarget(&provider.TargetRequest{ - TargetConfigOptions: targetConfig.Options, - Target: target, + Target: t, }) return err } -func (p *Provisioner) DestroyWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) +func (p *Provisioner) DestroyWorkspace(ws *workspace.Workspace, t *target.Target) error { + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).DestroyWorkspace(&provider.WorkspaceRequest{ - TargetConfigOptions: targetConfig.Options, - Workspace: ws, + Target: t, + Workspace: ws, }) return err diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go index d92e8092a1..5f4f08928f 100644 --- a/pkg/provisioner/info.go +++ b/pkg/provisioner/info.go @@ -17,19 +17,18 @@ type TargetInfoResult struct { } // Gets the target info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetTargetInfo(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) { +func (p *Provisioner) GetTargetInfo(ctx context.Context, t *target.Target) (*target.TargetInfo, error) { ch := make(chan TargetInfoResult, 1) go func() { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { ch <- TargetInfoResult{nil, err} return } info, err := (*targetProvider).GetTargetInfo(&provider.TargetRequest{ - TargetConfigOptions: targetConfig.Options, - Target: target, + Target: t, }) ch <- TargetInfoResult{info, err} @@ -49,19 +48,19 @@ type WorkspaceInfoResult struct { } // Gets the workspace info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) { +func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, t *target.Target) (*workspace.WorkspaceInfo, error) { ch := make(chan WorkspaceInfoResult, 1) go func() { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { ch <- WorkspaceInfoResult{nil, err} return } info, err := (*targetProvider).GetWorkspaceInfo(&provider.WorkspaceRequest{ - TargetConfigOptions: targetConfig.Options, - Workspace: workspace, + Target: t, + Workspace: workspace, }) ch <- WorkspaceInfoResult{info, err} diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index d182c2bdc5..af696e6bd5 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -8,7 +8,6 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/workspace" @@ -16,7 +15,7 @@ import ( type WorkspaceParams struct { Workspace *workspace.Workspace - TargetConfig *provider.TargetConfig + Target *target.Target ContainerRegistry *containerregistry.ContainerRegistry GitProviderConfig *gitprovider.GitProviderConfig BuilderImage string @@ -24,17 +23,17 @@ type WorkspaceParams struct { } type IProvisioner interface { - CreateTarget(target *target.Target, targetConfig *provider.TargetConfig) error - StartTarget(target *target.Target, targetConfig *provider.TargetConfig) error - StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error - GetTargetInfo(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) (*target.TargetInfo, error) - DestroyTarget(target *target.Target, targetConfig *provider.TargetConfig) error + CreateTarget(target *target.Target) error + StartTarget(target *target.Target) error + StopTarget(target *target.Target) error + GetTargetInfo(ctx context.Context, target *target.Target) (*target.TargetInfo, error) + DestroyTarget(target *target.Target) error CreateWorkspace(params WorkspaceParams) error - DestroyWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error + DestroyWorkspace(workspace *workspace.Workspace, target *target.Target) error StartWorkspace(params WorkspaceParams) error - StopWorkspace(workspace *workspace.Workspace, targetConfig *provider.TargetConfig) error - GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, targetConfig *provider.TargetConfig) (*workspace.WorkspaceInfo, error) + StopWorkspace(workspace *workspace.Workspace, target *target.Target) error + GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, target *target.Target) (*workspace.WorkspaceInfo, error) } type ProvisionerConfig struct { diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index ff05d0bc8c..6cb66861af 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -8,28 +8,27 @@ import ( "github.com/daytonaio/daytona/pkg/target" ) -func (p *Provisioner) StartTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) +func (p *Provisioner) StartTarget(t *target.Target) error { + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StartTarget(&provider.TargetRequest{ - TargetConfigOptions: targetConfig.Options, - Target: target, + Target: t, }) return err } func (p *Provisioner) StartWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.TargetConfig.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.Target.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ - TargetConfigOptions: params.TargetConfig.Options, + Target: params.Target, Workspace: params.Workspace, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index a57833e889..abe71c4e0f 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -9,29 +9,28 @@ import ( "github.com/daytonaio/daytona/pkg/workspace" ) -func (p *Provisioner) StopTarget(target *target.Target, targetConfig *provider.TargetConfig) error { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) +func (p *Provisioner) StopTarget(t *target.Target) error { + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StopTarget(&provider.TargetRequest{ - TargetConfigOptions: targetConfig.Options, - Target: target, + Target: t, }) return err } -func (p *Provisioner) StopWorkspace(ws *workspace.Workspace, targetConfig *provider.TargetConfig) error { - targetProvider, err := p.providerManager.GetProvider(targetConfig.ProviderInfo.Name) +func (p *Provisioner) StopWorkspace(ws *workspace.Workspace, t *target.Target) error { + targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StopWorkspace(&provider.WorkspaceRequest{ - TargetConfigOptions: targetConfig.Options, - Workspace: ws, + Target: t, + Workspace: ws, }) return err diff --git a/pkg/server/purge.go b/pkg/server/purge.go index f2a74fb8c9..65306cb068 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -36,7 +36,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { return []error{err} } - targets, err := s.TargetService.ListTargets(ctx, false) + targets, err := s.TargetService.ListTargets(ctx, nil, false) if err != nil { s.trackPurgeError(ctx, force, err) if !force { diff --git a/pkg/server/targetconfigs/dto/target_config.go b/pkg/server/targetconfigs/dto/target_config.go index 97671f5b61..45ad810873 100644 --- a/pkg/server/targetconfigs/dto/target_config.go +++ b/pkg/server/targetconfigs/dto/target_config.go @@ -3,10 +3,10 @@ package dto -import "github.com/daytonaio/daytona/pkg/provider" +import "github.com/daytonaio/daytona/pkg/target" type CreateTargetConfigDTO struct { - Name string `json:"name" validate:"required"` - ProviderInfo provider.ProviderInfo `json:"providerInfo" validate:"required"` - Options string `json:"options" validate:"required"` + Name string `json:"name" validate:"required"` + ProviderInfo target.ProviderInfo `json:"providerInfo" validate:"required"` + Options string `json:"options" validate:"required"` } // @name CreateTargetConfigDTO diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index 8eaf81e85f..fb3cd148c9 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -4,25 +4,23 @@ package targetconfigs import ( - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target/config" ) type ITargetConfigService interface { - Delete(targetConfig *provider.TargetConfig) error - Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) - List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) - Map() (map[string]*provider.TargetConfig, error) - Save(targetConfig *provider.TargetConfig) error - SetDefault(targetConfig *provider.TargetConfig) error + Delete(targetConfig *config.TargetConfig) error + Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) + List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) + Map() (map[string]*config.TargetConfig, error) + Save(targetConfig *config.TargetConfig) error } type TargetConfigServiceConfig struct { - TargetConfigStore provider.TargetConfigStore + TargetConfigStore config.TargetConfigStore } type TargetConfigService struct { - targetConfigStore provider.TargetConfigStore + targetConfigStore config.TargetConfigStore } func NewTargetConfigService(config TargetConfigServiceConfig) ITargetConfigService { @@ -31,17 +29,17 @@ func NewTargetConfigService(config TargetConfigServiceConfig) ITargetConfigServi } } -func (s *TargetConfigService) List(filter *provider.TargetConfigFilter) ([]*provider.TargetConfig, error) { +func (s *TargetConfigService) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { return s.targetConfigStore.List(filter) } -func (s *TargetConfigService) Map() (map[string]*provider.TargetConfig, error) { +func (s *TargetConfigService) Map() (map[string]*config.TargetConfig, error) { list, err := s.targetConfigStore.List(nil) if err != nil { return nil, err } - targetConfigs := make(map[string]*provider.TargetConfig) + targetConfigs := make(map[string]*config.TargetConfig) for _, targetConfig := range list { targetConfigs[targetConfig.Name] = targetConfig } @@ -49,46 +47,14 @@ func (s *TargetConfigService) Map() (map[string]*provider.TargetConfig, error) { return targetConfigs, nil } -func (s *TargetConfigService) Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) { +func (s *TargetConfigService) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { return s.targetConfigStore.Find(filter) } -func (s *TargetConfigService) Save(targetConfig *provider.TargetConfig) error { - err := s.targetConfigStore.Save(targetConfig) - if err != nil { - return err - } - - return s.SetDefault(targetConfig) +func (s *TargetConfigService) Save(targetConfig *config.TargetConfig) error { + return s.targetConfigStore.Save(targetConfig) } -func (s *TargetConfigService) Delete(targetConfig *provider.TargetConfig) error { +func (s *TargetConfigService) Delete(targetConfig *config.TargetConfig) error { return s.targetConfigStore.Delete(targetConfig) } - -func (s *TargetConfigService) SetDefault(targetConfig *provider.TargetConfig) error { - currentConfig, err := s.Find(&provider.TargetConfigFilter{ - Name: &targetConfig.Name, - }) - if err != nil { - return err - } - - defaultConfig, err := s.Find(&provider.TargetConfigFilter{ - Default: util.Pointer(true), - }) - if err != nil && err != provider.ErrTargetConfigNotFound { - return err - } - - if defaultConfig != nil { - defaultConfig.IsDefault = false - err := s.targetConfigStore.Save(defaultConfig) - if err != nil { - return err - } - } - - currentConfig.IsDefault = true - return s.targetConfigStore.Save(currentConfig) -} diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go index 83b8c22d2e..19e337be90 100644 --- a/pkg/server/targetconfigs/service_test.go +++ b/pkg/server/targetconfigs/service_test.go @@ -7,54 +7,55 @@ import ( "testing" t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" "github.com/stretchr/testify/suite" ) -var targetConfig1 *provider.TargetConfig = &provider.TargetConfig{ +var targetConfig1 *config.TargetConfig = &config.TargetConfig{ Name: "targetConfig1", - ProviderInfo: provider.ProviderInfo{ + ProviderInfo: target.ProviderInfo{ Name: "provider1", Version: "v1", }, Options: "", } -var targetConfig2 *provider.TargetConfig = &provider.TargetConfig{ +var targetConfig2 *config.TargetConfig = &config.TargetConfig{ Name: "targetConfig2", - ProviderInfo: provider.ProviderInfo{ + ProviderInfo: target.ProviderInfo{ Name: "provider2", Version: "v1", }, Options: "", } -var targetConfig3 *provider.TargetConfig = &provider.TargetConfig{ +var targetConfig3 *config.TargetConfig = &config.TargetConfig{ Name: "targetConfig3", - ProviderInfo: provider.ProviderInfo{ - Name: "provider1", + ProviderInfo: target.ProviderInfo{ + Name: "provider3", Version: "v1", }, Options: "", } -var targetConfig4 *provider.TargetConfig = &provider.TargetConfig{ +var targetConfig4 *config.TargetConfig = &config.TargetConfig{ Name: "newTargetConfig", - ProviderInfo: provider.ProviderInfo{ + ProviderInfo: target.ProviderInfo{ Name: "provider2", Version: "v1", }, Options: "", } -var expectedConfigs []*provider.TargetConfig -var expectedConfigMap map[string]*provider.TargetConfig +var expectedConfigs []*config.TargetConfig +var expectedConfigMap map[string]*config.TargetConfig type TargetConfigServiceTestSuite struct { suite.Suite targetConfigService targetconfigs.ITargetConfigService - targetConfigStore provider.TargetConfigStore + targetConfigStore config.TargetConfigStore } func NewTargetConfigServiceTestSuite() *TargetConfigServiceTestSuite { @@ -62,11 +63,11 @@ func NewTargetConfigServiceTestSuite() *TargetConfigServiceTestSuite { } func (s *TargetConfigServiceTestSuite) SetupTest() { - expectedConfigs = []*provider.TargetConfig{ + expectedConfigs = []*config.TargetConfig{ targetConfig1, targetConfig2, targetConfig3, } - expectedConfigMap = map[string]*provider.TargetConfig{ + expectedConfigMap = map[string]*config.TargetConfig{ targetConfig1.Name: targetConfig1, targetConfig2.Name: targetConfig2, targetConfig3.Name: targetConfig3, @@ -105,27 +106,13 @@ func (s *TargetConfigServiceTestSuite) TestMap() { func (s *TargetConfigServiceTestSuite) TestFind() { require := s.Require() - targetConfig, err := s.targetConfigService.Find(&provider.TargetConfigFilter{ + targetConfig, err := s.targetConfigService.Find(&config.TargetConfigFilter{ Name: &targetConfig1.Name, }) require.Nil(err) require.Equal(targetConfig1, targetConfig) } -func (s *TargetConfigServiceTestSuite) TestSetDefault() { - require := s.Require() - - err := s.targetConfigService.SetDefault(targetConfig2) - require.Nil(err) - - targetConfig, err := s.targetConfigService.Find(&provider.TargetConfigFilter{ - Name: &targetConfig2.Name, - }) - require.Nil(err) - - require.Equal(targetConfig2, targetConfig) -} - func (s *TargetConfigServiceTestSuite) TestSave() { expectedConfigs = append(expectedConfigs, targetConfig4) diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index fc762b0b90..d8e7abb7e9 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -10,10 +10,11 @@ import ( "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" ) @@ -36,11 +37,16 @@ func isValidTargetName(name string) bool { } func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*target.Target, error) { - _, err := s.targetStore.Find(req.Name) + _, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &req.Id}) if err == nil { return nil, ErrTargetAlreadyExists } + tc, err := s.targetConfigStore.Find(&config.TargetConfigFilter{Name: &req.TargetConfigName}) + if err != nil { + return s.handleCreateError(ctx, nil, err) + } + // Repo name is taken as the name for target by default if !isValidTargetName(req.Name) { return nil, ErrInvalidTargetName @@ -49,12 +55,8 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT tg := &target.Target{ Id: req.Id, Name: req.Name, - TargetConfig: req.TargetConfig, - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &tg.TargetConfig}) - if err != nil { - return s.handleCreateError(ctx, nil, err) + ProviderInfo: tc.ProviderInfo, + Options: tc.Options, } apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, tg.Id) @@ -80,18 +82,30 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err = s.provisioner.CreateTarget(tg, targetConfig) + err = s.provisioner.CreateTarget(tg) if err != nil { - return nil, err + return s.handleCreateError(ctx, tg, err) } - targetLogger.Write([]byte("Target creation complete. Pending start...\n")) + targetLogger.Write([]byte(views.GetPrettyLogLine("Target creation complete"))) - err = s.startTarget(tg, targetConfig, targetLogger) + err = s.startTarget(tg, targetLogger) if err != nil { return s.handleCreateError(ctx, tg, err) } + tg, err = s.handleCreateError(ctx, tg, err) + if err != nil { + return nil, err + } + + err = s.SetDefault(ctx, tg.Id) + if err != nil { + return nil, err + } + + tg.IsDefault = true + return s.handleCreateError(ctx, tg, err) } @@ -102,7 +116,7 @@ func (s *TargetService) handleCreateError(ctx context.Context, target *target.Ta clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) + telemetryProps := telemetry.NewTargetEventProps(ctx, target) event := telemetry.ServerEventTargetCreated if err != nil { telemetryProps["error"] = err.Error() diff --git a/pkg/server/targets/dto/target.go b/pkg/server/targets/dto/target.go index 8d0c1689e4..1d455f8233 100644 --- a/pkg/server/targets/dto/target.go +++ b/pkg/server/targets/dto/target.go @@ -8,12 +8,12 @@ import ( ) type TargetDTO struct { - target.Target + target.TargetViewDTO Info *target.TargetInfo `json:"info" validate:"optional"` } // @name TargetDTO type CreateTargetDTO struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - TargetConfig string `json:"targetConfig" validate:"required"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfigName string `json:"targetConfigName" validate:"required"` } // @name CreateTargetDTO diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 648f64f331..50862b94f2 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -9,38 +9,33 @@ import ( "fmt" "time" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) -func (s *TargetService) GetTarget(ctx context.Context, targetId string, verbose bool) (*dto.TargetDTO, error) { - tg, err := s.targetStore.Find(targetId) +func (s *TargetService) GetTarget(ctx context.Context, filter *target.TargetFilter, verbose bool) (*dto.TargetDTO, error) { + tg, err := s.targetStore.Find(filter) if err != nil { return nil, ErrTargetNotFound } response := dto.TargetDTO{ - Target: *tg, + TargetViewDTO: *tg, } if !verbose { return &response, nil } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &tg.TargetConfig}) - if err != nil { - return nil, err - } - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() resultCh := make(chan provisioner.TargetInfoResult, 1) go func() { - targetInfo, err := s.provisioner.GetTargetInfo(ctx, tg, targetConfig) + targetInfo, err := s.provisioner.GetTargetInfo(ctx, &tg.Target) resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} }() diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index 6abd19ac33..abbffab2b7 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -10,14 +10,14 @@ import ( "sync" "time" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) -func (s *TargetService) ListTargets(ctx context.Context, verbose bool) ([]dto.TargetDTO, error) { - targets, err := s.targetStore.List() +func (s *TargetService) ListTargets(ctx context.Context, filter *target.TargetFilter, verbose bool) ([]dto.TargetDTO, error) { + targets, err := s.targetStore.List(filter) if err != nil { return nil, err } @@ -26,7 +26,7 @@ func (s *TargetService) ListTargets(ctx context.Context, verbose bool) ([]dto.Ta response := []dto.TargetDTO{} for i, t := range targets { - response = append(response, dto.TargetDTO{Target: *t}) + response = append(response, dto.TargetDTO{TargetViewDTO: *t}) if !verbose { continue } @@ -35,19 +35,13 @@ func (s *TargetService) ListTargets(ctx context.Context, verbose bool) ([]dto.Ta go func(i int) { defer wg.Done() - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &t.TargetConfig}) - if err != nil { - log.Error(fmt.Errorf("failed to get target config for %s", t.TargetConfig)) - return - } - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() resultCh := make(chan provisioner.TargetInfoResult, 1) go func() { - targetInfo, err := s.provisioner.GetTargetInfo(ctx, t, targetConfig) + targetInfo, err := s.provisioner.GetTargetInfo(ctx, &t.Target) resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} }() diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 6ee3dcb65e..6bf0f78304 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -7,28 +7,22 @@ import ( "context" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(targetId) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleRemoveError(ctx, target, ErrTargetNotFound) + return s.handleRemoveError(ctx, &target.Target, ErrTargetNotFound) } log.Infof("Destroying target %s", target.Id) - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + err = s.provisioner.DestroyTarget(&target.Target) if err != nil { - return s.handleRemoveError(ctx, target, err) - } - - err = s.provisioner.DestroyTarget(target, targetConfig) - if err != nil { - return s.handleRemoveError(ctx, target, err) + return s.handleRemoveError(ctx, &target.Target, err) } // Should not fail the whole operation if the API key cannot be revoked @@ -44,23 +38,21 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error log.Error(err) } - err = s.targetStore.Delete(target) + err = s.targetStore.Delete(&target.Target) - return s.handleRemoveError(ctx, target, err) + return s.handleRemoveError(ctx, &target.Target, err) } // ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(targetId) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, nil, ErrTargetNotFound) } log.Infof("Destroying target %s", target.Id) - targetConfig, _ := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) - - err = s.provisioner.DestroyTarget(target, targetConfig) + err = s.provisioner.DestroyTarget(&target.Target) if err != nil { log.Error(err) } @@ -70,9 +62,9 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) log.Error(err) } - err = s.targetStore.Delete(target) + err = s.targetStore.Delete(&target.Target) - return s.handleRemoveError(ctx, target, err) + return s.handleRemoveError(ctx, &target.Target, err) } func (s *TargetService) handleRemoveError(ctx context.Context, target *target.Target, err error) error { @@ -82,7 +74,7 @@ func (s *TargetService) handleRemoveError(ctx context.Context, target *target.Ta clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) + telemetryProps := telemetry.NewTargetEventProps(ctx, target) event := telemetry.ServerEventTargetDestroyed if err != nil { telemetryProps["error"] = err.Error() diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 6c48213fa1..ecee6f48db 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -8,27 +8,28 @@ import ( "io" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" "github.com/daytonaio/daytona/pkg/telemetry" ) type ITargetService interface { CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*target.Target, error) - GetTarget(ctx context.Context, targetId string, verbose bool) (*dto.TargetDTO, error) + GetTarget(ctx context.Context, filter *target.TargetFilter, verbose bool) (*dto.TargetDTO, error) GetTargetLogReader(targetId string) (io.Reader, error) - ListTargets(ctx context.Context, verbose bool) ([]dto.TargetDTO, error) + ListTargets(ctx context.Context, filter *target.TargetFilter, verbose bool) ([]dto.TargetDTO, error) StartTarget(ctx context.Context, targetId string) error StopTarget(ctx context.Context, targetId string) error + SetDefault(ctx context.Context, targetId string) error RemoveTarget(ctx context.Context, targetId string) error ForceRemoveTarget(ctx context.Context, targetId string) error } type targetConfigStore interface { - Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) + Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) } type TargetServiceConfig struct { diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index cc9a0cbfab..b4bb51219e 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -7,15 +7,16 @@ import ( "context" "testing" - t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" + t_targetconfigs "github.com/daytonaio/daytona/internal/testing/server/targetconfigs" t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/target/config" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -24,9 +25,11 @@ import ( const serverApiUrl = "http://localhost:3986" const serverUrl = "http://localhost:3987" -var targetConfig = provider.TargetConfig{ - Name: "test-target-config", - ProviderInfo: provider.ProviderInfo{ +var tg = &target.Target{ + Id: "test", + Name: "test", + ApiKey: "test", + ProviderInfo: target.ProviderInfo{ Name: "test-provider", Version: "test", }, @@ -34,9 +37,18 @@ var targetConfig = provider.TargetConfig{ } var createTargetDTO = dto.CreateTargetDTO{ - Name: "test", - Id: "test", - TargetConfig: targetConfig.Name, + Name: "test", + Id: "test", + TargetConfigName: "test", +} + +var tc = config.TargetConfig{ + Name: "test", + ProviderInfo: target.ProviderInfo{ + Name: "test-provider", + Version: "test", + }, + Options: "test-options", } var targetInfo = target.TargetInfo{ @@ -45,13 +57,19 @@ var targetInfo = target.TargetInfo{ } func TestTargetService(t *testing.T) { + tg.EnvVars = target.GetTargetEnvVars(tg, target.TargetEnvVarParams{ + ApiUrl: serverApiUrl, + ServerUrl: serverUrl, + ClientId: "test-client-id", + }, false) + ctx := context.Background() - ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test") + ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") targetStore := t_targets.NewInMemoryTargetStore() - targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() - err := targetConfigStore.Save(&targetConfig) + + err := targetConfigStore.Save(&tc) require.Nil(t, err) apiKeyService := mocks.NewMockApiKeyService() @@ -71,8 +89,8 @@ func TestTargetService(t *testing.T) { }) t.Run("CreateTarget", func(t *testing.T) { - mockProvisioner.On("CreateTarget", mock.Anything, &targetConfig).Return(nil) - mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("CreateTarget", tg).Return(nil) + mockProvisioner.On("StartTarget", tg).Return(nil) apiKeyService.On("Generate", apikey.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) @@ -81,7 +99,13 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, target) - targetEquals(t, createTargetDTO, target) + // Must be true after creation + tg.IsDefault = true + + targetEquals(t, tg, target) + + tg.EnvVars = nil + tg.ApiKey = "" }) t.Run("CreateTarget fails when target already exists", func(t *testing.T) { @@ -90,19 +114,10 @@ func TestTargetService(t *testing.T) { require.Equal(t, targets.ErrTargetAlreadyExists, err) }) - t.Run("CreateTarget fails name validation", func(t *testing.T) { - invalidTargetRequest := createTargetDTO - invalidTargetRequest.Name = "invalid name" - - _, err := service.CreateTarget(ctx, invalidTargetRequest) - require.NotNil(t, err) - require.Equal(t, targets.ErrInvalidTargetName, err) - }) - t.Run("GetTarget", func(t *testing.T) { - mockProvisioner.On("GetTargetInfo", mock.Anything, mock.Anything, &targetConfig).Return(&targetInfo, nil) + mockProvisioner.On("GetTargetInfo", mock.Anything, tg).Return(&targetInfo, nil) - target, err := service.GetTarget(ctx, createTargetDTO.Id, true) + target, err := service.GetTarget(ctx, &target.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Nil(t, err) require.NotNil(t, target) @@ -111,16 +126,14 @@ func TestTargetService(t *testing.T) { }) t.Run("GetTarget fails when target not found", func(t *testing.T) { - _, err := service.GetTarget(ctx, "invalid-id", true) + _, err := service.GetTarget(ctx, &target.TargetFilter{IdOrName: util.Pointer("invalid-id")}, true) require.NotNil(t, err) require.Equal(t, targets.ErrTargetNotFound, err) }) t.Run("ListTargets", func(t *testing.T) { verbose := false - mockProvisioner.On("GetTargetInfo", mock.Anything, mock.Anything, &targetConfig).Return(&targetInfo, nil) - - targets, err := service.ListTargets(ctx, verbose) + targets, err := service.ListTargets(ctx, nil, verbose) require.Nil(t, err) require.Len(t, targets, 1) @@ -132,9 +145,8 @@ func TestTargetService(t *testing.T) { t.Run("ListTargets - verbose", func(t *testing.T) { verbose := true - mockProvisioner.On("GetTargetInfo", mock.Anything, mock.Anything, &targetConfig).Return(&targetInfo, nil) - targets, err := service.ListTargets(ctx, verbose) + targets, err := service.ListTargets(ctx, nil, verbose) require.Nil(t, err) require.Len(t, targets, 1) @@ -145,15 +157,21 @@ func TestTargetService(t *testing.T) { }) t.Run("StartTarget", func(t *testing.T) { - mockProvisioner.On("StartTarget", mock.Anything, &targetConfig).Return(nil) + tg.EnvVars = target.GetTargetEnvVars(tg, target.TargetEnvVarParams{ + ApiUrl: serverApiUrl, + ServerUrl: serverUrl, + ClientId: "test-client-id", + }, false) err := service.StartTarget(ctx, createTargetDTO.Id) require.Nil(t, err) + + tg.EnvVars = nil }) t.Run("StopTarget", func(t *testing.T) { - mockProvisioner.On("StopTarget", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopTarget", tg).Return(nil) err := service.StopTarget(ctx, createTargetDTO.Id) @@ -161,44 +179,55 @@ func TestTargetService(t *testing.T) { }) t.Run("RemoveTarget", func(t *testing.T) { - mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyTarget", tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetTarget(ctx, createTargetDTO.Id, true) + _, err = service.GetTarget(ctx, &target.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Equal(t, targets.ErrTargetNotFound, err) }) t.Run("ForceRemoveTarget", func(t *testing.T) { - err := targetStore.Save(&target.Target{Id: createTargetDTO.Id, TargetConfig: targetConfig.Name}) + err := targetStore.Save(tg) require.Nil(t, err) - mockProvisioner.On("DestroyTarget", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyTarget", tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetTarget(ctx, createTargetDTO.Id, true) + _, err = service.GetTarget(ctx, &target.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Equal(t, targets.ErrTargetNotFound, err) }) + t.Run("CreateTarget fails name validation", func(t *testing.T) { + invalidTargetRequest := createTargetDTO + invalidTargetRequest.Name = "invalid name" + + _, err := service.CreateTarget(ctx, invalidTargetRequest) + require.NotNil(t, err) + require.Equal(t, targets.ErrInvalidTargetName, err) + }) + t.Cleanup(func() { apiKeyService.AssertExpectations(t) mockProvisioner.AssertExpectations(t) }) } -func targetEquals(t *testing.T, req dto.CreateTargetDTO, target *target.Target) { +func targetEquals(t *testing.T, t1, t2 *target.Target) { t.Helper() - require.Equal(t, req.Id, target.Id) - require.Equal(t, req.Name, target.Name) - require.Equal(t, req.TargetConfig, target.TargetConfig) + require.Equal(t, t1.Id, t2.Id) + require.Equal(t, t1.Name, t2.Name) + require.Equal(t, t1.ProviderInfo, t2.ProviderInfo) + require.Equal(t, t1.Options, t2.Options) + require.Equal(t, t1.IsDefault, t2.IsDefault) } func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, verbose bool) { @@ -206,7 +235,8 @@ func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO require.Equal(t, req.Id, target.Id) require.Equal(t, req.Name, target.Name) - require.Equal(t, req.TargetConfig, target.TargetConfig) + require.Equal(t, tc.ProviderInfo, target.ProviderInfo) + require.Equal(t, tc.Options, target.Options) if verbose { require.Equal(t, target.Info.Name, targetInfo.Name) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go new file mode 100644 index 0000000000..eadc9561b9 --- /dev/null +++ b/pkg/server/targets/set-default.go @@ -0,0 +1,49 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "context" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/target" +) + +func (s *TargetService) SetDefault(ctx context.Context, id string) error { + currentTarget, err := s.GetTarget(ctx, &target.TargetFilter{ + IdOrName: &id, + }, false) + if err != nil || currentTarget == nil { + return err + } + + defaultTarget, err := s.GetTarget(ctx, &target.TargetFilter{ + Default: util.Pointer(true), + }, false) + if err != nil && !target.IsTargetNotFound(err) { + return err + } + + if defaultTarget != nil { + defaultTarget.IsDefault = false + err := s.targetStore.Save(TargetDtoToTarget(*defaultTarget)) + if err != nil { + return err + } + } + + currentTarget.IsDefault = true + return s.targetStore.Save(TargetDtoToTarget(*currentTarget)) +} + +func TargetDtoToTarget(targetDto dto.TargetDTO) *target.Target { + return &target.Target{ + Id: targetDto.Id, + Name: targetDto.Name, + ProviderInfo: targetDto.ProviderInfo, + Options: targetDto.Options, + IsDefault: targetDto.IsDefault, + } +} diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index 01d587ce17..445a76a377 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -9,54 +9,49 @@ import ( "io" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" "github.com/daytonaio/daytona/internal/util" ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(targetId) + t, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStartError(ctx, nil, ErrTargetNotFound) } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &t.TargetConfig}) - if err != nil { - return s.handleStartError(ctx, t, err) - } - targetLogger := s.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) defer targetLogger.Close() logger := io.MultiWriter(&util.InfoLogWriter{}, targetLogger) - t.EnvVars = target.GetTargetEnvVars(t, target.TargetEnvVarParams{ + t.EnvVars = target.GetTargetEnvVars(&t.Target, target.TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err = s.startTarget(t, targetConfig, logger) + err = s.startTarget(&t.Target, logger) if err != nil { - return s.handleStartError(ctx, t, err) + return s.handleStartError(ctx, &t.Target, err) } - return s.handleStartError(ctx, t, err) + return s.handleStartError(ctx, &t.Target, err) } -func (s *TargetService) startTarget(target *target.Target, targetConfig *provider.TargetConfig, targetLogger io.Writer) error { +func (s *TargetService) startTarget(target *target.Target, targetLogger io.Writer) error { targetLogger.Write([]byte("Starting target\n")) - err := s.provisioner.StartTarget(target, targetConfig) + err := s.provisioner.StartTarget(target) if err != nil { return err } - targetLogger.Write([]byte(fmt.Sprintf("Target %s started\n", target.Name))) + targetLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Target %s started", target.Name)))) return err } @@ -68,7 +63,7 @@ func (s *TargetService) handleStartError(ctx context.Context, target *target.Tar clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) + telemetryProps := telemetry.NewTargetEventProps(ctx, target) event := telemetry.ServerEventTargetStarted if err != nil { telemetryProps["error"] = err.Error() diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index a07d3bf0ff..e838122b87 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -6,26 +6,20 @@ package targets import ( "context" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(targetId) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStopError(ctx, nil, ErrTargetNotFound) } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) - if err != nil { - return s.handleStopError(ctx, target, err) - } - - err = s.provisioner.StopTarget(target, targetConfig) + err = s.provisioner.StopTarget(&target.Target) - return s.handleStopError(ctx, target, err) + return s.handleStopError(ctx, &target.Target, err) } func (s *TargetService) handleStopError(ctx context.Context, target *target.Target, err error) error { @@ -35,7 +29,7 @@ func (s *TargetService) handleStopError(ctx context.Context, target *target.Targ clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target, nil) + telemetryProps := telemetry.NewTargetEventProps(ctx, target) event := telemetry.ServerEventTargetStopped if err != nil { telemetryProps["error"] = err.Error() diff --git a/pkg/server/workspaceconfig/service.go b/pkg/server/workspaceconfig/service.go index 803e4e9c25..1bd1d565c4 100644 --- a/pkg/server/workspaceconfig/service.go +++ b/pkg/server/workspaceconfig/service.go @@ -70,7 +70,7 @@ func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { Url: &workspaceConfig.RepositoryUrl, Default: util.Pointer(true), }) - if err != nil && err != config.ErrWorkspaceConfigNotFound { + if err != nil && !config.IsWorkspaceConfigNotFound(err) { return err } diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 3baa8faf30..e3b2c3d811 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -16,10 +16,11 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/workspace" "github.com/daytonaio/daytona/pkg/workspace/buildconfig" @@ -49,12 +50,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo return s.handleCreateError(ctx, nil, ErrWorkspaceAlreadyExists) } - target, err := s.targetStore.Find(req.TargetId) - if err != nil { - return s.handleCreateError(ctx, nil, err) - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &req.TargetId}) if err != nil { return s.handleCreateError(ctx, nil, err) } @@ -156,7 +152,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo err = s.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ Workspace: w, - TargetConfig: targetConfig, + Target: &target.Target, ContainerRegistry: cr, GitProviderConfig: gc, BuilderImage: s.builderImage, @@ -166,9 +162,9 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo return s.handleCreateError(ctx, w, err) } - workspaceLogger.Write([]byte(fmt.Sprintf("Workspace %s created\n", w.Name))) + workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s created", w.Name)))) - err = s.startWorkspace(w, targetConfig, workspaceLogger) + err = s.startWorkspace(w, &target.Target, workspaceLogger) return s.handleCreateError(ctx, w, err) } diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index ce7ee7e0a9..5ec8921491 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -9,9 +9,9 @@ import ( "fmt" "time" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) @@ -29,12 +29,7 @@ func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, return response, nil } - target, err := s.targetStore.Find(ws.TargetId) - if err != nil { - return nil, err - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) if err != nil { return nil, err } @@ -45,7 +40,7 @@ func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, resultCh := make(chan provisioner.WorkspaceInfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, targetConfig) + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, &target.Target) resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} }() diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index d02a9a068d..d00ffd9289 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -10,9 +10,9 @@ import ( "sync" "time" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) @@ -35,41 +35,35 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] go func(i int) { defer wg.Done() - target, err := s.targetStore.Find(ws.TargetId) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) if err != nil { log.Error(fmt.Errorf("failed to get target for %s", ws.TargetId)) return } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) - if err != nil { - log.Error(fmt.Errorf("failed to get target config for %s", target.TargetConfig)) - return - } - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() resultCh := make(chan provisioner.WorkspaceInfoResult, 1) go func() { - targetInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, targetConfig) - resultCh <- provisioner.WorkspaceInfoResult{Info: targetInfo, Err: err} + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, &target.Target) + resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} }() select { case res := <-resultCh: if res.Err != nil { - log.Error(fmt.Errorf("failed to get target info for %s: %v", ws.Name, res.Err)) + log.Error(fmt.Errorf("failed to get workspace info for %s: %v", ws.Name, res.Err)) return } response[i].Info = res.Info case <-ctx.Done(): if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting target info for %s", ws.Name)) + log.Warn(fmt.Sprintf("timeout getting workspace info for %s", ws.Name)) } else { - log.Warn(fmt.Sprintf("cancelled getting target info for %s", ws.Name)) + log.Warn(fmt.Sprintf("cancelled getting workspace info for %s", ws.Name)) } } }(i) diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index 7ac100e207..5965894b85 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -8,7 +8,7 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" @@ -22,17 +22,12 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri log.Infof("Destroying workspace %s", ws.Name) - target, err := s.targetStore.Find(ws.TargetId) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) if err != nil { return s.handleRemoveError(ctx, &ws.Workspace, err) } - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) - if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, err) - } - - err = s.provisioner.DestroyWorkspace(&ws.Workspace, targetConfig) + err = s.provisioner.DestroyWorkspace(&ws.Workspace, &target.Target) if err != nil { return s.handleRemoveError(ctx, &ws.Workspace, err) } @@ -63,17 +58,12 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId log.Infof("Destroying workspace %s", ws.Name) - target, err := s.targetStore.Find(ws.TargetId) - if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, err) - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) if err != nil { return s.handleRemoveError(ctx, &ws.Workspace, err) } - err = s.provisioner.DestroyWorkspace(&ws.Workspace, targetConfig) + err = s.provisioner.DestroyWorkspace(&ws.Workspace, &target.Target) if err != nil { log.Error(err) } diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index 97899ca668..e1bcca0691 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -8,13 +8,11 @@ import ( "io" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" @@ -35,20 +33,14 @@ type IWorkspaceService interface { } type targetStore interface { - Find(idOrName string) (*target.Target, error) -} - -type targetConfigStore interface { - Find(filter *provider.TargetConfigFilter) (*provider.TargetConfig, error) + Find(filter *target.TargetFilter) (*target.TargetViewDTO, error) } type WorkspaceServiceConfig struct { WorkspaceStore workspace.Store TargetStore targetStore - TargetConfigStore targetConfigStore ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService - WorkspaceConfigService workspaceconfig.IWorkspaceConfigService ServerApiUrl string ServerUrl string ServerVersion string @@ -66,10 +58,8 @@ func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { return &WorkspaceService{ workspaceStore: config.WorkspaceStore, targetStore: config.TargetStore, - targetConfigStore: config.TargetConfigStore, containerRegistryService: config.ContainerRegistryService, buildService: config.BuildService, - workspaceConfigService: config.WorkspaceConfigService, serverApiUrl: config.ServerApiUrl, serverUrl: config.ServerUrl, serverVersion: config.ServerVersion, @@ -87,10 +77,8 @@ func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { type WorkspaceService struct { workspaceStore workspace.Store targetStore targetStore - targetConfigStore targetConfigStore containerRegistryService containerregistries.IContainerRegistryService buildService builds.IBuildService - workspaceConfigService workspaceconfig.IWorkspaceConfigService provisioner provisioner.IProvisioner apiKeyService apikeys.IApiKeyService serverApiUrl string diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 64f3d8c5ac..5aa587f93c 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" @@ -18,7 +17,6 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" @@ -35,14 +33,6 @@ const serverVersion = "0.0.0-test" const defaultWorkspaceUser = "daytona" const defaultWorkspaceImage = "daytonaio/workspace-project:latest" -var targetConfig = provider.TargetConfig{ - Name: "test-target-config", - ProviderInfo: provider.ProviderInfo{ - Name: "test-provider", - Version: "test", - }, - Options: "test-options", -} var gitProviderConfigId = "github" var baseApiUrl = "https://api.github.com" @@ -57,9 +47,13 @@ var gitProviderConfig = gitprovider.GitProviderConfig{ } var tg = &target.Target{ - Id: "123", - Name: "test", - TargetConfig: targetConfig.Name, + Id: "123", + Name: "test", + ProviderInfo: target.ProviderInfo{ + Name: "test-provider", + Version: "test", + }, + Options: "test-options", } var createWorkspaceDTO = dto.CreateWorkspaceDTO{ @@ -88,11 +82,32 @@ var workspaceInfo = workspace.WorkspaceInfo{ TargetId: "123", } -var ws *workspace.Workspace +var ws = &workspace.Workspace{ + Id: "123", + Name: "workspace1", + ApiKey: createWorkspaceDTO.Name, + GitProviderConfigId: &gitProviderConfig.Id, + Repository: &gitprovider.GitRepository{ + Id: "123", + Url: "https://github.com/daytonaio/daytona", + Name: "daytona", + Branch: "main", + Sha: "sha1", + }, + Image: defaultWorkspaceImage, + User: defaultWorkspaceUser, + TargetId: tg.Id, +} func TestTargetService(t *testing.T) { + ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ + ApiUrl: serverApiUrl, + ServerUrl: serverUrl, + ClientId: "test-client-id", + }, false) + ctx := context.Background() - ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test") + ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") targetStore := t_targets.NewInMemoryTargetStore() err := targetStore.Save(tg) @@ -102,13 +117,6 @@ func TestTargetService(t *testing.T) { containerRegistryService := mocks.NewMockContainerRegistryService() - workspaceConfigService := mocks.NewMockWorkspaceConfigService() - - targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() - - err = targetConfigStore.Save(&targetConfig) - require.Nil(t, err) - apiKeyService := mocks.NewMockApiKeyService() gitProviderService := mocks.NewMockGitProviderService() mockProvisioner := mocks.NewMockProvisioner() @@ -119,11 +127,9 @@ func TestTargetService(t *testing.T) { service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ TargetStore: targetStore, WorkspaceStore: workspaceStore, - TargetConfigStore: targetConfigStore, ServerApiUrl: serverApiUrl, ServerUrl: serverUrl, ContainerRegistryService: containerRegistryService, - WorkspaceConfigService: workspaceConfigService, DefaultWorkspaceImage: defaultWorkspaceImage, DefaultWorkspaceUser: defaultWorkspaceUser, ApiKeyService: apiKeyService, @@ -161,7 +167,7 @@ func TestTargetService(t *testing.T) { mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ Workspace: ws, - TargetConfig: &targetConfig, + Target: tg, ContainerRegistry: containerRegistry, GitProviderConfig: &gitProviderConfig, BuilderImage: defaultWorkspaceImage, @@ -169,7 +175,7 @@ func TestTargetService(t *testing.T) { }).Return(nil) mockProvisioner.On("StartWorkspace", provisioner.WorkspaceParams{ Workspace: ws, - TargetConfig: &targetConfig, + Target: tg, ContainerRegistry: containerRegistry, GitProviderConfig: &gitProviderConfig, BuilderImage: defaultWorkspaceImage, @@ -183,10 +189,9 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, workspace) - ws = &workspace.Workspace - ws.EnvVars = nil + workspaceEquals(t, ws, &workspace.Workspace, defaultWorkspaceImage) - workspaceEquals(t, createWorkspaceDTO, &workspace.Workspace, defaultWorkspaceImage) + ws.EnvVars = nil }) t.Run("CreateWorkspace fails when workspace already exists", func(t *testing.T) { @@ -205,7 +210,7 @@ func TestTargetService(t *testing.T) { }) t.Run("GetWorkspace", func(t *testing.T) { - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, ws, &targetConfig).Return(&workspaceInfo, nil) + mockProvisioner.On("GetWorkspaceInfo", ws, tg).Return(&workspaceInfo, nil) w, err := service.GetWorkspace(ctx, ws.Id, true) @@ -236,7 +241,7 @@ func TestTargetService(t *testing.T) { t.Skip("Need to figure out how to test the ListWorkspaces goroutine") verbose := true - mockProvisioner.On("GetWorkspaceInfo", mock.Anything, ws, &targetConfig).Return(&workspaceInfo, nil) + mockProvisioner.On("GetWorkspaceInfo", ws, tg).Return(&workspaceInfo, nil) workspaces, err := service.ListWorkspaces(ctx, verbose) @@ -247,7 +252,7 @@ func TestTargetService(t *testing.T) { }) t.Run("StartWorkspace", func(t *testing.T) { - mockProvisioner.On("StartWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StartWorkspace", mock.Anything, tg).Return(nil) err := service.StartWorkspace(ctx, createWorkspaceDTO.Id) @@ -255,7 +260,7 @@ func TestTargetService(t *testing.T) { }) t.Run("StopWorkspace", func(t *testing.T) { - mockProvisioner.On("StopWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("StopWorkspace", mock.Anything, tg).Return(nil) err := service.StopWorkspace(ctx, createWorkspaceDTO.Id) @@ -263,7 +268,7 @@ func TestTargetService(t *testing.T) { }) t.Run("RemoveWorkspace", func(t *testing.T) { - mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyWorkspace", mock.Anything, tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveWorkspace(ctx, createWorkspaceDTO.Id) @@ -278,7 +283,7 @@ func TestTargetService(t *testing.T) { err := workspaceStore.Save(ws) require.Nil(t, err) - mockProvisioner.On("DestroyWorkspace", mock.Anything, &targetConfig).Return(nil) + mockProvisioner.On("DestroyWorkspace", mock.Anything, tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveWorkspace(ctx, createWorkspaceDTO.Id) @@ -313,15 +318,18 @@ func TestTargetService(t *testing.T) { }) } -func workspaceEquals(t *testing.T, req dto.CreateWorkspaceDTO, ws *workspace.Workspace, workspaceImage string) { +func workspaceEquals(t *testing.T, ws1, ws2 *workspace.Workspace, workspaceImage string) { t.Helper() - // TODO: add more assertions - require.Equal(t, req.Id, ws.Id) - require.Equal(t, req.Name, ws.Name) - require.Equal(t, req.TargetId, ws.TargetId) - require.Equal(t, ws.Image, workspaceImage) - require.Equal(t, ws.User, "daytona") + require.Equal(t, ws1.Id, ws2.Id) + require.Equal(t, ws1.Name, ws2.Name) + require.Equal(t, ws1.TargetId, ws2.TargetId) + require.Equal(t, ws1.Image, ws2.Image) + require.Equal(t, ws1.User, ws2.User) + require.Equal(t, ws1.ApiKey, ws2.ApiKey) + require.Equal(t, ws1.Repository.Id, ws2.Repository.Id) + require.Equal(t, ws1.Repository.Url, ws2.Repository.Url) + require.Equal(t, ws1.Repository.Name, ws2.Repository.Name) } func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto.WorkspaceDTO, workspaceInfo workspace.WorkspaceInfo, workspaceImage string, verbose bool) { diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index 44280fbee4..9a3100f9c8 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -11,9 +11,10 @@ import ( "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" ) @@ -24,12 +25,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin return s.handleStartError(ctx, &ws.Workspace, ErrWorkspaceNotFound) } - target, err := s.targetStore.Find(ws.TargetId) - if err != nil { - return s.handleStartError(ctx, &ws.Workspace, err) - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) if err != nil { return s.handleStartError(ctx, &ws.Workspace, err) } @@ -45,7 +41,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err = s.startWorkspace(&workspaceToStart, targetConfig, workspaceLogger) + err = s.startWorkspace(&workspaceToStart, &target.Target, workspaceLogger) if err != nil { return s.handleStartError(ctx, &ws.Workspace, err) } @@ -53,7 +49,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin return s.handleStartError(ctx, &ws.Workspace, err) } -func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, targetConfig *provider.TargetConfig, logger io.Writer) error { +func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, target *target.Target, logger io.Writer) error { logger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) cr, err := s.containerRegistryService.FindByImageName(w.Image) @@ -77,7 +73,7 @@ func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, targetConfig * err = s.provisioner.StartWorkspace(provisioner.WorkspaceParams{ Workspace: w, - TargetConfig: targetConfig, + Target: target, ContainerRegistry: cr, GitProviderConfig: gc, BuilderImage: s.builderImage, @@ -87,7 +83,7 @@ func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, targetConfig * return err } - logger.Write([]byte(fmt.Sprintf("Workspace %s started\n", w.Name))) + logger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s started", w.Name)))) return nil } diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index e0def5ba99..2b0353fe18 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -7,7 +7,7 @@ import ( "context" "time" - "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" @@ -19,18 +19,13 @@ func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string return s.handleStopError(ctx, &ws.Workspace, ErrWorkspaceNotFound) } - target, err := s.targetStore.Find(ws.TargetId) - if err != nil { - return s.handleStopError(ctx, &ws.Workspace, err) - } - - targetConfig, err := s.targetConfigStore.Find(&provider.TargetConfigFilter{Name: &target.TargetConfig}) + target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) if err != nil { return s.handleStopError(ctx, &ws.Workspace, err) } // todo: go routines - err = s.provisioner.StopWorkspace(&ws.Workspace, targetConfig) + err = s.provisioner.StopWorkspace(&ws.Workspace, &target.Target) if err != nil { return s.handleStopError(ctx, &ws.Workspace, err) } diff --git a/pkg/tailscale/forward_unix.go b/pkg/tailscale/forward_unix.go index 1d31bd458d..ee06842d88 100644 --- a/pkg/tailscale/forward_unix.go +++ b/pkg/tailscale/forward_unix.go @@ -12,7 +12,6 @@ import ( ) type ForwardConfig struct { - Ctx context.Context TsnetConn *tsnet.Server Hostname string SshPort int @@ -20,7 +19,7 @@ type ForwardConfig struct { RemoteSock string } -func ForwardRemoteUnixSock(config ForwardConfig) (chan bool, chan error) { +func ForwardRemoteUnixSock(ctx context.Context, config ForwardConfig) (chan bool, chan error) { sshTun := tunnel.NewUnix(config.TsnetConn, config.LocalSock, config.Hostname, config.SshPort, config.RemoteSock) errChan := make(chan error) @@ -44,7 +43,7 @@ func ForwardRemoteUnixSock(config ForwardConfig) (chan bool, chan error) { }) go func() { - errChan <- sshTun.Start(config.Ctx) + errChan <- sshTun.Start(ctx) }() return startedChann, errChan diff --git a/pkg/target/config/config.go b/pkg/target/config/config.go new file mode 100644 index 0000000000..0143ee00d7 --- /dev/null +++ b/pkg/target/config/config.go @@ -0,0 +1,13 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package config + +import "github.com/daytonaio/daytona/pkg/target" + +type TargetConfig struct { + Name string `json:"name" validate:"required"` + ProviderInfo target.ProviderInfo `json:"providerInfo" validate:"required"` + // JSON encoded map of options + Options string `json:"options" validate:"required"` +} // @name TargetConfig diff --git a/pkg/provider/store.go b/pkg/target/config/store.go similarity index 91% rename from pkg/provider/store.go rename to pkg/target/config/store.go index fcb66aec6f..c35e462a26 100644 --- a/pkg/provider/store.go +++ b/pkg/target/config/store.go @@ -1,13 +1,12 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package provider +package config import "errors" type TargetConfigFilter struct { - Name *string - Default *bool + Name *string } type TargetConfigStore interface { diff --git a/pkg/target/store.go b/pkg/target/store.go index 5b0e61e859..aa92f0cea6 100644 --- a/pkg/target/store.go +++ b/pkg/target/store.go @@ -5,13 +5,23 @@ package target import "errors" +type TargetFilter struct { + IdOrName *string + Default *bool +} + type Store interface { - List() ([]*Target, error) - Find(idOrName string) (*Target, error) + List(filter *TargetFilter) ([]*TargetViewDTO, error) + Find(filter *TargetFilter) (*TargetViewDTO, error) Save(target *Target) error Delete(target *Target) error } +type TargetViewDTO struct { + Target + WorkspaceCount int `json:"workspaceCount" validate:"required"` +} // @name TargetViewDTO + var ( ErrTargetNotFound = errors.New("target not found") ) diff --git a/pkg/target/target.go b/pkg/target/target.go index 33dfd9a682..aa67c49de6 100644 --- a/pkg/target/target.go +++ b/pkg/target/target.go @@ -4,11 +4,14 @@ package target type Target struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - TargetConfig string `json:"targetConfig" validate:"required"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"-"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + ProviderInfo ProviderInfo `json:"providerInfo" validate:"required"` + // JSON encoded map of options + Options string `json:"options" validate:"required"` + ApiKey string `json:"-"` + EnvVars map[string]string `json:"-"` + IsDefault bool `json:"default" validate:"required"` } // @name Target type TargetInfo struct { @@ -16,6 +19,12 @@ type TargetInfo struct { ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` } // @name TargetInfo +type ProviderInfo struct { + Name string `json:"name" validate:"required"` + Version string `json:"version" validate:"required"` + Label *string `json:"label" validate:"optional"` +} // @name TargetProviderInfo + type TargetEnvVarParams struct { ApiUrl string ServerUrl string diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index 8ff064ef5e..6337c09348 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/workspace" ) @@ -44,7 +43,7 @@ const ( ServerEventWorkspaceStopError ServerEvent = "server_workspace_stopped_error" ) -func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfig *provider.TargetConfig) map[string]interface{} { +func NewTargetEventProps(ctx context.Context, target *target.Target) map[string]interface{} { props := map[string]interface{}{} sessionId := SessionId(ctx) @@ -55,12 +54,9 @@ func NewTargetEventProps(ctx context.Context, target *target.Target, targetConfi if target != nil { props["target_id"] = target.Id - } - - if targetConfig != nil { - props["target_name"] = targetConfig.Name - props["target_provider"] = targetConfig.ProviderInfo.Name - props["target_provider_version"] = targetConfig.ProviderInfo.Version + props["target_name"] = target.Name + props["target_provider"] = target.ProviderInfo.Name + props["target_provider_version"] = target.ProviderInfo.Version } return props diff --git a/pkg/views/common.go b/pkg/views/common.go index d63f2d0547..912a5f983e 100644 --- a/pkg/views/common.go +++ b/pkg/views/common.go @@ -38,8 +38,6 @@ var DefaultHorizontalMargin = 1 var TUITableMinimumWidth = 80 -var CheckmarkSymbol = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓") - var SeparatorString = lipgloss.NewStyle().Foreground(LightGray).Render("===") var ( @@ -181,3 +179,8 @@ func GetEnvVarsInput(envVars *map[string]string) *huh.Text { return nil }) } + +// Bolds the message and prepends a checkmark +func GetPrettyLogLine(message string) string { + return fmt.Sprintf("%s \033[1m%s\033[0m\n", lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓").String(), message) +} diff --git a/pkg/views/logs/display.go b/pkg/views/logs/display.go index 7ff17eea64..a6c713e765 100644 --- a/pkg/views/logs/display.go +++ b/pkg/views/logs/display.go @@ -5,6 +5,7 @@ package logs import ( "fmt" + "slices" "strings" "github.com/charmbracelet/lipgloss" @@ -54,12 +55,7 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { prefix := lipgloss.NewStyle().Foreground(prefixColor).Bold(true).Render(formatPrefixText(prefixText)) if index == STATIC_INDEX { - if logEntry.Source == string(logs.LogSourceProvider) && prefixText == PROVIDER_PREFIX { - line = fmt.Sprintf("%s%s\033[1m%s\033[0m", prefixPadding, prefix, line) - } else { - line = fmt.Sprintf("%s%s%s \033[1m%s\033[0m", prefixPadding, prefix, views.CheckmarkSymbol, line) - } - fmt.Print(line) + fmt.Printf("%s%s\033[1m%s\033[0m", prefixPadding, prefix, line) return } @@ -89,12 +85,10 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { fmt.Print(result) } -func CalculateLongestPrefixLength(workspaceNames []string) { - for _, workspaceName := range workspaceNames { - if len(workspaceName) > longestPrefixLength { - longestPrefixLength = len(workspaceName) - } - } +func SetupLongestPrefixLength(workspaceNames []string) { + longestPrefixLength = len(slices.MaxFunc(workspaceNames, func(a, b string) int { + return len(a) - len(b) + })) } func formatPrefixText(input string) string { diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index 9d53b742e3..1ce02c42fa 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -31,6 +31,23 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("ID", target.Id) + "\n" + providerLabel := target.ProviderInfo.Name + if target.ProviderInfo.Label != nil { + providerLabel = *target.ProviderInfo.Label + } + + output += getInfoLine("Provider", providerLabel) + "\n" + + if target.Default { + output += getInfoLine("Default", "Yes") + "\n" + } + + output += getInfoLine("Options", target.Options) + "\n" + + if target.Info != nil { + output += getInfoLine("Metadata", *target.Info.ProviderMetadata) + "\n" + } + terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) if err != nil { fmt.Println(output) diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index 8dbf1b3951..cd0960d2c5 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -5,6 +5,7 @@ package list import ( "fmt" + "sort" "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/internal/util" @@ -15,8 +16,11 @@ import ( ) type RowData struct { - Name string - TargetConfig string + Name string + Provider string + Default bool + WorkspaceCount string + Options string } func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileName string) { @@ -25,10 +29,25 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa return } - headers := []string{"Target", "Target Config"} + SortTargets(&targetList) + + headers := []string{"Target", "Provider", "Default", "# Workspaces", "Options"} data := util.ArrayMap(targetList, func(target apiclient.TargetDTO) []string { - return getRowFromRowData(RowData{Name: target.Name, TargetConfig: target.TargetConfig}) + provider := target.ProviderInfo.Name + if target.ProviderInfo.Label != nil { + provider = *target.ProviderInfo.Label + } + + rowData := RowData{ + Name: target.Name, + Provider: provider, + Default: target.Default, + WorkspaceCount: fmt.Sprintf("%d", target.WorkspaceCount), + Options: target.Options, + } + + return getRowFromRowData(rowData) }) footer := lipgloss.NewStyle().Foreground(views.LightGray).Render(views.GetListFooter(activeProfileName, &views.Padding{})) @@ -51,8 +70,25 @@ func renderUnstyledList(targetList []apiclient.TargetDTO) { } func getRowFromRowData(rowData RowData) []string { + var isDefault string + + if rowData.Default { + isDefault = views.ActiveStyle.Render("Yes") + } else { + isDefault = views.InactiveStyle.Render("/") + } + return []string{ views.NameStyle.Render(rowData.Name), - views.DefaultRowDataStyle.Render(rowData.TargetConfig), + views.DefaultRowDataStyle.Render(rowData.Provider), + isDefault, + views.DefaultRowDataStyle.Render(rowData.WorkspaceCount), + views.DefaultRowDataStyle.Render(rowData.Options), } } + +func SortTargets(targetList *[]apiclient.TargetDTO) { + sort.Slice(*targetList, func(i, j int) bool { + return (*targetList)[i].Default && !(*targetList)[j].Default + }) +} diff --git a/pkg/views/target/name.go b/pkg/views/target/name.go new file mode 100644 index 0000000000..bf1b4da023 --- /dev/null +++ b/pkg/views/target/name.go @@ -0,0 +1,38 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "errors" + "log" + + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/pkg/views" +) + +func SetTargetNameView(name *string, existingNames []string) { + form := huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("Target Name"). + Value(name). + Validate(func(str string) error { + if str == "" { + return errors.New("name can not be blank") + } + for _, existingName := range existingNames { + if existingName == str { + return errors.New("name already in use") + } + } + return nil + }), + ), + ).WithHeight(5).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + log.Fatal(err) + } +} diff --git a/pkg/views/target/selection/target.go b/pkg/views/target/selection/target.go index 1fa697cabc..a74e4f3a73 100644 --- a/pkg/views/target/selection/target.go +++ b/pkg/views/target/selection/target.go @@ -6,29 +6,36 @@ package selection import ( "fmt" "os" - "strings" "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + list_view "github.com/daytonaio/daytona/pkg/views/target/list" ) -func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, action string) []list.Item { +var NewTargetIdentifier = "" +func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, withNewTarget bool, action string) []list.Item { // Initialize an empty list of items. items := []list.Item{} // Populate items with titles and descriptions from targets. for _, target := range targets { - var workspacesInfo []string + var providerName string + + if target.ProviderInfo.Label != nil { + providerName = *target.ProviderInfo.Label + } else { + providerName = target.ProviderInfo.Name + } newItem := item[apiclient.TargetDTO]{ title: target.Name, id: target.Id, - desc: strings.Join(workspacesInfo, ", "), - targetConfig: target.TargetConfig, + desc: providerName, + target: &target, choiceProperty: target, } @@ -40,12 +47,22 @@ func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, ac items = append(items, newItem) } + if withNewTarget { + items = append(items, item[apiclient.TargetDTO]{ + title: "+ Create a new target", + id: NewTargetIdentifier, + desc: "", + target: &apiclient.TargetDTO{Name: "+ Create a new target"}, + choiceProperty: apiclient.TargetDTO{Name: NewTargetIdentifier}, + }) + } + return items } -func getTargetProgramEssentials(modelTitle string, actionVerb string, targets []apiclient.TargetDTO, footerText string, isMultipleSelect bool) tea.Model { +func getTargetProgramEssentials(modelTitle string, withNewTarget bool, actionVerb string, targets []apiclient.TargetDTO, footerText string, isMultipleSelect bool) tea.Model { - items := generateTargetList(targets, isMultipleSelect, actionVerb) + items := generateTargetList(targets, isMultipleSelect, withNewTarget, actionVerb) d := ItemDelegate[apiclient.TargetDTO]{} @@ -73,8 +90,10 @@ func getTargetProgramEssentials(modelTitle string, actionVerb string, targets [] return p } -func selectTargetPrompt(targets []apiclient.TargetDTO, actionVerb string, choiceChan chan<- *apiclient.TargetDTO) { - p := getTargetProgramEssentials("Select a Target To ", actionVerb, targets, "", false) +func selectTargetPrompt(targets []apiclient.TargetDTO, withNewTarget bool, actionVerb string, choiceChan chan<- *apiclient.TargetDTO) { + list_view.SortTargets(&targets) + + p := getTargetProgramEssentials("Select a Target To ", withNewTarget, actionVerb, targets, "", false) if m, ok := p.(model[apiclient.TargetDTO]); ok && m.choice != nil { choiceChan <- m.choice } else { @@ -82,17 +101,19 @@ func selectTargetPrompt(targets []apiclient.TargetDTO, actionVerb string, choice } } -func GetTargetFromPrompt(targets []apiclient.TargetDTO, actionVerb string) *apiclient.TargetDTO { +func GetTargetFromPrompt(targets []apiclient.TargetDTO, withNewTarget bool, actionVerb string) *apiclient.TargetDTO { choiceChan := make(chan *apiclient.TargetDTO) - go selectTargetPrompt(targets, actionVerb, choiceChan) + go selectTargetPrompt(targets, withNewTarget, actionVerb, choiceChan) return <-choiceChan } func selectTargetsFromPrompt(targets []apiclient.TargetDTO, actionVerb string, choiceChan chan<- []*apiclient.TargetDTO) { - footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark target.\nPress 'enter' to %s the current/marked targets.", actionVerb)) - p := getTargetProgramEssentials("Select Targets To ", actionVerb, targets, footerText, true) + list_view.SortTargets(&targets) + + footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark a target.\nPress 'enter' to %s the current/marked targets.", actionVerb)) + p := getTargetProgramEssentials("Select Targets To ", false, actionVerb, targets, footerText, true) m, ok := p.(model[apiclient.TargetDTO]) if ok && m.choices != nil { diff --git a/pkg/views/target/selection/view.go b/pkg/views/target/selection/view.go index 886c4ff8a5..514b043c02 100644 --- a/pkg/views/target/selection/view.go +++ b/pkg/views/target/selection/view.go @@ -15,6 +15,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" "golang.org/x/term" ) @@ -34,18 +35,27 @@ var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). Render type item[T any] struct { - id, title, desc, targetConfig string - choiceProperty T - isMarked bool - isMultipleSelect bool - action string + id, title, desc string + target *apiclient.TargetDTO + choiceProperty T + isMarked bool + isMultipleSelect bool + action string } -func (i item[T]) Title() string { return i.title } -func (i item[T]) Id() string { return i.id } -func (i item[T]) Description() string { return i.desc } -func (i item[T]) FilterValue() string { return i.title } -func (i item[T]) TargetConfig() string { return i.targetConfig } +func (i item[T]) Title() string { + title := i.title + + if i.target.Default { + title += " (default)" + } + + return title +} + +func (i item[T]) Id() string { return i.id } +func (i item[T]) Description() string { return i.desc } +func (i item[T]) FilterValue() string { return i.title } type model[T any] struct { list list.Model @@ -143,7 +153,10 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) title := baseStyles.Render(i.Title()) - idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetConfig()) + idWithTargetConfigString := i.Id() + if i.Id() == NewTargetIdentifier { + idWithTargetConfigString = "" + } idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) description := baseStyles.Render(i.Description()) diff --git a/pkg/views/targetconfig/list.go b/pkg/views/targetconfig/list.go index ae8793fc9c..675e30fd78 100644 --- a/pkg/views/targetconfig/list.go +++ b/pkg/views/targetconfig/list.go @@ -15,7 +15,6 @@ import ( type rowData struct { ConfigName string Provider string - IsDefault string Options string } @@ -29,7 +28,7 @@ func ListTargetConfigs(targetConfigs []apiclient.TargetConfig) { } table := util.GetTableView(data, []string{ - "Name", "Provider", "Default", "Options", + "Name", "Provider", "Options", }, nil, func() { renderUnstyledList(targetConfigs) }) @@ -38,23 +37,18 @@ func ListTargetConfigs(targetConfigs []apiclient.TargetConfig) { } func getRowFromRowData(targetConfig *apiclient.TargetConfig) []string { - var isDefault string var data rowData data.ConfigName = targetConfig.Name data.Provider = targetConfig.ProviderInfo.Name - data.Options = targetConfig.Options - - if targetConfig.IsDefault { - isDefault = views.ActiveStyle.Render("Yes") - } else { - isDefault = views.InactiveStyle.Render("/") + if targetConfig.ProviderInfo.Label != nil { + data.Provider = *targetConfig.ProviderInfo.Label } + data.Options = targetConfig.Options row := []string{ views.NameStyle.Render(data.ConfigName), views.DefaultRowDataStyle.Render(data.Provider), - isDefault, views.DefaultRowDataStyle.Render(data.Options), } @@ -77,10 +71,6 @@ func renderUnstyledList(targetConfigs []apiclient.TargetConfig) { output += fmt.Sprintf("%s %s", views.GetPropertyKey("Provider: "), targetConfig.ProviderInfo.Name) + "\n\n" - if targetConfig.IsDefault { - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Default: "), "Yes") + "\n\n" - } - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Options: "), targetConfig.Options) + "\n\n" if targetConfig.Name != targetConfigs[len(targetConfigs)-1].Name { diff --git a/pkg/views/targetconfig/select.go b/pkg/views/targetconfig/select.go index ce4650092e..26693a4a3e 100644 --- a/pkg/views/targetconfig/select.go +++ b/pkg/views/targetconfig/select.go @@ -20,13 +20,13 @@ const NewTargetConfigName = "+ New Target Config" type TargetConfigView struct { Name string Options string - IsDefault bool ProviderInfo ProviderInfo } type ProviderInfo struct { Name string Version string + Label *string Installed *bool } @@ -68,6 +68,7 @@ func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activePro ProviderInfo: ProviderInfo{ Name: providerView.Name, Version: providerView.Version, + Label: providerView.Label, Installed: providerView.Installed, }, }, @@ -94,12 +95,12 @@ func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activePro func ToTargetConfigView(targetConfig apiclient.TargetConfig) TargetConfigView { return TargetConfigView{ - Name: targetConfig.Name, - Options: targetConfig.Options, - IsDefault: targetConfig.IsDefault, + Name: targetConfig.Name, + Options: targetConfig.Options, ProviderInfo: ProviderInfo{ Name: targetConfig.ProviderInfo.Name, Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, }, } } diff --git a/pkg/views/targetconfig/set.go b/pkg/views/targetconfig/set.go index 84abd39ff9..efaf6f98e2 100644 --- a/pkg/views/targetconfig/set.go +++ b/pkg/views/targetconfig/set.go @@ -24,7 +24,7 @@ import ( func NewTargetConfigNameInput(name *string, existingNames []string) error { input := huh.NewInput(). - Title("Name"). + Title("Target Config Name"). Value(name). Validate(func(s string) error { if s == "" { diff --git a/pkg/views/targetconfig/view.go b/pkg/views/targetconfig/view.go index 3449bf2f78..ef5dfa54ae 100644 --- a/pkg/views/targetconfig/view.go +++ b/pkg/views/targetconfig/view.go @@ -16,17 +16,15 @@ type item struct { targetConfig TargetConfigView } -func (i item) Title() string { - title := i.targetConfig.Name +func (i item) Title() string { return i.targetConfig.Name } - if i.targetConfig.IsDefault { - title += " (default)" - } - - return title -} func (i item) Description() string { desc := i.targetConfig.ProviderInfo.Name + + if i.targetConfig.ProviderInfo.Label != nil { + desc = *i.targetConfig.ProviderInfo.Label + } + if i.targetConfig.ProviderInfo.Installed != nil { if !*i.targetConfig.ProviderInfo.Installed { desc += " (needs installing)" diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index 808b16b8b8..62ab403553 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -43,7 +43,7 @@ func NotifyEmptyTargetList(tip bool) { func NotifyEmptyWorkspaceList(tip bool) { views.RenderInfoMessageBold("No workspaces found") if tip { - views.RenderTip("Use 'daytona create' to create a target") + views.RenderTip("Use 'daytona create' to create a workspace") } } diff --git a/pkg/views/util/table.go b/pkg/views/util/table.go index 62196d1156..6456d5dd60 100644 --- a/pkg/views/util/table.go +++ b/pkg/views/util/table.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "regexp" + "strings" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss/table" @@ -68,7 +69,7 @@ func getMinimumWidth(data [][]string) int { // Remove ANSI escape codes regex := regexp.MustCompile("\x1b\\[[0-9;]*[a-zA-Z]") strippedCell := regex.ReplaceAllString(cell, "") - width += len(strippedCell) + width += longestLineLength(strippedCell) if width > widestRow { widestRow = width } @@ -77,3 +78,17 @@ func getMinimumWidth(data [][]string) int { } return widestRow } + +// Returns the length of the longest line in a string +func longestLineLength(input string) int { + lines := strings.Split(input, "\n") + maxLength := 0 + + for _, line := range lines { + if len(line) > maxLength { + maxLength = len(line) + } + } + + return maxLength +} diff --git a/pkg/views/workspace/create/configuration.go b/pkg/views/workspace/create/configuration.go index 0048ac7340..6b25bfb92e 100644 --- a/pkg/views/workspace/create/configuration.go +++ b/pkg/views/workspace/create/configuration.go @@ -22,9 +22,10 @@ const ( DEVCONTAINER_FILEPATH = ".devcontainer/devcontainer.json" ) -var configurationHelpLine = lipgloss.NewStyle().Foreground(views.Gray).Render("enter: next f10: advanced configuration") +var configurationHelpLine = lipgloss.NewStyle().Foreground(views.Gray).Render("enter: next f10: configuration screen") type WorkspaceConfigurationData struct { + Name string BuildChoice string DevcontainerFilePath string Image string @@ -34,6 +35,7 @@ type WorkspaceConfigurationData struct { func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePath string, currentWorkspace *apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults) *WorkspaceConfigurationData { workspaceConfigurationData := &WorkspaceConfigurationData{ + Name: currentWorkspace.Name, BuildChoice: string(buildChoice), DevcontainerFilePath: defaults.DevcontainerFilePath, Image: *defaults.Image, @@ -100,37 +102,40 @@ func RunWorkspaceConfiguration(workspaceList *[]apiclient.CreateWorkspaceDTO, de } for i := range *workspaceList { - if (*workspaceList)[i].Name == currentWorkspace.Name { - if workspaceConfigurationData.BuildChoice == string(views_util.NONE) { - (*workspaceList)[i].BuildConfig = nil - (*workspaceList)[i].Image = defaults.Image - (*workspaceList)[i].User = defaults.ImageUser - } + if (*workspaceList)[i].Id != currentWorkspace.Id { + continue + } - if workspaceConfigurationData.BuildChoice == string(views_util.CUSTOMIMAGE) { - (*workspaceList)[i].BuildConfig = nil - (*workspaceList)[i].Image = &workspaceConfigurationData.Image - (*workspaceList)[i].User = &workspaceConfigurationData.User - } + if workspaceConfigurationData.BuildChoice == string(views_util.NONE) { + (*workspaceList)[i].BuildConfig = nil + (*workspaceList)[i].Image = defaults.Image + (*workspaceList)[i].User = defaults.ImageUser + } - if workspaceConfigurationData.BuildChoice == string(views_util.AUTOMATIC) { - (*workspaceList)[i].BuildConfig = &apiclient.BuildConfig{} - (*workspaceList)[i].Image = defaults.Image - (*workspaceList)[i].User = defaults.ImageUser - } + if workspaceConfigurationData.BuildChoice == string(views_util.CUSTOMIMAGE) { + (*workspaceList)[i].BuildConfig = nil + (*workspaceList)[i].Image = &workspaceConfigurationData.Image + (*workspaceList)[i].User = &workspaceConfigurationData.User + } - if workspaceConfigurationData.BuildChoice == string(views_util.DEVCONTAINER) { - (*workspaceList)[i].BuildConfig = &apiclient.BuildConfig{ - Devcontainer: &apiclient.DevcontainerConfig{ - FilePath: workspaceConfigurationData.DevcontainerFilePath, - }, - } - (*workspaceList)[i].Image = nil - (*workspaceList)[i].User = nil - } + if workspaceConfigurationData.BuildChoice == string(views_util.AUTOMATIC) { + (*workspaceList)[i].BuildConfig = &apiclient.BuildConfig{} + (*workspaceList)[i].Image = defaults.Image + (*workspaceList)[i].User = defaults.ImageUser + } - (*workspaceList)[i].EnvVars = workspaceConfigurationData.EnvVars + if workspaceConfigurationData.BuildChoice == string(views_util.DEVCONTAINER) { + (*workspaceList)[i].BuildConfig = &apiclient.BuildConfig{ + Devcontainer: &apiclient.DevcontainerConfig{ + FilePath: workspaceConfigurationData.DevcontainerFilePath, + }, + } + (*workspaceList)[i].Image = nil + (*workspaceList)[i].User = nil } + + (*workspaceList)[i].Name = workspaceConfigurationData.Name + (*workspaceList)[i].EnvVars = workspaceConfigurationData.EnvVars } if len(*workspaceList) == 1 { @@ -157,6 +162,11 @@ func GetWorkspaceConfigurationForm(workspaceConfiguration *WorkspaceConfiguratio } form := huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("Name"). + Value(&workspaceConfiguration.Name), + ), huh.NewGroup( huh.NewSelect[string](). Title("Choose a build configuration"). diff --git a/pkg/views/workspace/create/summary.go b/pkg/views/workspace/create/summary.go index c25dc21bc5..6fedecc09c 100644 --- a/pkg/views/workspace/create/summary.go +++ b/pkg/views/workspace/create/summary.go @@ -12,7 +12,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/huh" "github.com/charmbracelet/lipgloss" - util "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -21,6 +21,8 @@ import ( type WorkspaceDetail string const ( + Repository WorkspaceDetail = "Repository" + Branch WorkspaceDetail = "Branch" Build WorkspaceDetail = "Build" DevcontainerConfig WorkspaceDetail = "Devcontainer Config" Image WorkspaceDetail = "Image" @@ -43,22 +45,23 @@ type SummaryModel struct { } type SubmissionFormConfig struct { - ChosenName *string - SuggestedName string - ExistingNames []string - WorkspaceList *[]apiclient.CreateWorkspaceDTO - NameLabel string - Defaults *views_util.WorkspaceConfigDefaults + ChosenName *string + SuggestedName string + WorkspaceList *[]apiclient.CreateWorkspaceDTO + NameLabel string + Defaults *views_util.WorkspaceConfigDefaults + ExistingWorkspaceNames []string + ImportConfirmation *bool } -var configureCheck bool +var doneCheck bool var userCancelled bool var WorkspacesConfigurationChanged bool -func RunSubmissionForm(config SubmissionFormConfig, wtImport *bool) error { - configureCheck = false +func RunSubmissionForm(config SubmissionFormConfig) error { + doneCheck = true - m := NewSummaryModel(config, wtImport) + m := NewSummaryModel(config) if _, err := tea.NewProgram(m, tea.WithAltScreen()).Run(); err != nil { return err @@ -68,7 +71,7 @@ func RunSubmissionForm(config SubmissionFormConfig, wtImport *bool) error { return errors.New("user cancelled") } - if !configureCheck { + if doneCheck { return nil } @@ -77,29 +80,34 @@ func RunSubmissionForm(config SubmissionFormConfig, wtImport *bool) error { } var err error - WorkspacesConfigurationChanged, err = RunWorkspaceConfiguration(config.WorkspaceList, *config.Defaults, *wtImport) + isImporting := false + if config.ImportConfirmation != nil { + isImporting = *config.ImportConfirmation + } + + WorkspacesConfigurationChanged, err = RunWorkspaceConfiguration(config.WorkspaceList, *config.Defaults, isImporting) if err != nil { return err } - return RunSubmissionForm(config, wtImport) + return RunSubmissionForm(config) } func RenderSummary(name string, workspaceList []apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults, nameLabel string) (string, error) { var output string - if name == "" { + if nameLabel == "" { output = views.GetStyledMainTitle("SUMMARY") } else { - output = views.GetStyledMainTitle(fmt.Sprintf("SUMMARY - %s %s", nameLabel, name)) + output = views.GetStyledMainTitle(fmt.Sprintf("SUMMARY - Target %s", nameLabel)) } output += "\n\n" for i := range workspaceList { if len(workspaceList) == 1 { - output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render("Workspace"), (workspaceList[i].Source.Repository.Url)) + output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render("Workspace"), (workspaceList[i].Name)) } else { - output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render(fmt.Sprintf("%s #%d", "Workspace", i+1)), (workspaceList[i].Source.Repository.Url)) + output += fmt.Sprintf("%s - %s\n", lipgloss.NewStyle().Foreground(views.Green).Render(fmt.Sprintf("%s #%d", "Workspace", i+1)), (workspaceList[i].Name)) } workspaceBuildChoice, choiceName := views_util.GetWorkspaceBuildChoice(workspaceList[i], defaults) @@ -113,7 +121,9 @@ func RenderSummary(name string, workspaceList []apiclient.CreateWorkspaceDTO, de } func renderWorkspaceDetails(workspace apiclient.CreateWorkspaceDTO, buildChoice views_util.BuildChoice, choiceName string) string { - output := workspaceDetailOutput(Build, choiceName) + output := workspaceDetailOutput(Repository, workspace.Source.Repository.Url) + "\n" + output += workspaceDetailOutput(Branch, workspace.Source.Repository.Branch) + "\n" + output += workspaceDetailOutput(Build, choiceName) if buildChoice == views_util.DEVCONTAINER { if workspace.BuildConfig != nil { @@ -157,20 +167,19 @@ func workspaceDetailOutput(workspaceDetailKey WorkspaceDetail, workspaceDetailVa return fmt.Sprintf("\t%s%-*s%s", lipgloss.NewStyle().Foreground(views.Green).Render(string(workspaceDetailKey)), DEFAULT_PADDING-len(string(workspaceDetailKey)), EMPTY_STRING, workspaceDetailValue) } -func NewSummaryModel(config SubmissionFormConfig, wtImport *bool) SummaryModel { +func NewSummaryModel(config SubmissionFormConfig) SummaryModel { m := SummaryModel{width: maxWidth} m.lg = lipgloss.DefaultRenderer() m.styles = NewStyles(m.lg) - m.name = *config.ChosenName m.workspaceList = *config.WorkspaceList m.defaults = config.Defaults m.nameLabel = config.NameLabel - if *config.ChosenName == "" { + if config.ChosenName != nil && *config.ChosenName == "" { *config.ChosenName = config.SuggestedName } - if !*wtImport { + if config.ImportConfirmation == nil || !*config.ImportConfirmation { m.form = huh.NewForm( huh.NewGroup( huh.NewInput(). @@ -182,7 +191,7 @@ func NewSummaryModel(config SubmissionFormConfig, wtImport *bool) SummaryModel { if err != nil { return err } - for _, name := range config.ExistingNames { + for _, name := range config.ExistingWorkspaceNames { if name == result { return errors.New("name already exists") } @@ -197,10 +206,17 @@ func NewSummaryModel(config SubmissionFormConfig, wtImport *bool) SummaryModel { huh.NewGroup( huh.NewConfirm(). Title("Is the above information correct?"). - Value(wtImport), + Value(config.ImportConfirmation), ), ).WithShowHelp(false).WithTheme(views.GetCustomTheme()) } + m.form = huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Good to go?").Affirmative("Create").Negative("Configure"). + Value(&doneCheck), + ), + ).WithShowHelp(false).WithTheme(views.GetCustomTheme()) return m } @@ -220,7 +236,7 @@ func (m SummaryModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "f10": m.quitting = true m.form.State = huh.StateCompleted - configureCheck = true + doneCheck = false return m, tea.Quit } } @@ -250,13 +266,11 @@ func (m SummaryModel) View() string { view := m.form.WithHeight(5).View() + "\n" + configurationHelpLine - if len(m.workspaceList) > 1 || len(m.workspaceList) == 1 && WorkspacesConfigurationChanged { - summary, err := RenderSummary(m.name, m.workspaceList, m.defaults, m.nameLabel) - if err != nil { - log.Fatal(err) - } - view = views.GetBorderedMessage(summary) + "\n" + view + summary, err := RenderSummary(m.name, m.workspaceList, m.defaults, m.nameLabel) + if err != nil { + log.Fatal(err) } + view = views.GetBorderedMessage(summary) + "\n" + view return view } diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index a7d1122979..a986cf294f 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -26,7 +26,7 @@ type RowData struct { func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { if len(workspaceList) == 0 { - views_util.NotifyEmptyTargetList(true) + views_util.NotifyEmptyWorkspaceList(true) return } @@ -127,7 +127,6 @@ func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { } return w1.State.Uptime < w2.State.Uptime }) - } func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) *RowData { diff --git a/pkg/workspace/workspace.go b/pkg/workspace/workspace.go index b38838fdd7..ce6f147c0c 100644 --- a/pkg/workspace/workspace.go +++ b/pkg/workspace/workspace.go @@ -25,6 +25,13 @@ type Workspace struct { GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` } // @name Workspace +func (w *Workspace) WorkspaceFolderName() string { + if w.Repository != nil { + return w.Repository.Name + } + return w.Name +} + type WorkspaceInfo struct { Name string `json:"name" validate:"required"` Created string `json:"created" validate:"required"` From 018635c109810c33436af14ceec386d8971b0e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 7 Nov 2024 11:32:07 +0100 Subject: [PATCH 06/76] fix: multi select and info workspace view (#1321, #1322) Signed-off-by: Luka Brecic --- docs/daytona_delete.md | 2 +- docs/daytona_start.md | 2 +- docs/daytona_stop.md | 2 +- hack/docs/daytona_delete.yaml | 2 +- hack/docs/daytona_start.yaml | 2 +- hack/docs/daytona_stop.yaml | 2 +- pkg/cmd/build/delete.go | 2 +- pkg/cmd/build/info.go | 2 +- pkg/cmd/build/logs.go | 2 +- pkg/cmd/build/run.go | 4 +- pkg/cmd/gitprovider/delete.go | 2 +- pkg/cmd/gitprovider/update.go | 2 +- pkg/cmd/prebuild/add.go | 4 +- pkg/cmd/prebuild/delete.go | 2 +- pkg/cmd/prebuild/info.go | 2 +- pkg/cmd/prebuild/update.go | 2 +- pkg/cmd/workspace/code.go | 5 +- pkg/cmd/workspace/create/add_from_config.go | 35 +-- pkg/cmd/workspace/create/branch_wizard.go | 74 +++--- pkg/cmd/workspace/create/cmd.go | 4 +- pkg/cmd/workspace/create/creation_data.go | 52 ++-- .../workspace/create/process_cmd_arguments.go | 80 +++--- pkg/cmd/workspace/create/process_prompting.go | 36 +-- pkg/cmd/workspace/create/repository_wizard.go | 38 ++- pkg/cmd/workspace/delete.go | 9 +- pkg/cmd/workspace/list.go | 3 +- pkg/cmd/workspace/ssh.go | 3 +- pkg/cmd/workspace/start.go | 32 ++- pkg/cmd/workspace/stop.go | 28 +-- pkg/cmd/workspaceconfig/add.go | 4 +- pkg/cmd/workspaceconfig/delete.go | 2 +- pkg/cmd/workspaceconfig/info.go | 2 +- pkg/cmd/workspaceconfig/setdefault.go | 2 +- pkg/cmd/workspaceconfig/update.go | 2 +- pkg/views/{workspace => }/selection/branch.go | 0 pkg/views/{workspace => }/selection/build.go | 0 .../{workspace => }/selection/checkout.go | 0 pkg/views/{workspace => }/selection/common.go | 0 .../{workspace => }/selection/gitprovider.go | 0 .../selection/gitproviderconfig.go | 0 .../{workspace => }/selection/namespace.go | 0 .../{workspace => }/selection/prebuild.go | 0 .../{workspace => }/selection/pullrequest.go | 0 .../{workspace => }/selection/repository.go | 0 pkg/views/{workspace => }/selection/sample.go | 0 pkg/views/selection/view.go | 227 ++++++++++++++++++ .../selection/workspaceconfig.go | 0 .../selection/workspacerequest.go | 0 pkg/views/workspace/create/configuration.go | 2 +- pkg/views/workspace/create/summary.go | 42 ++-- pkg/views/workspace/info/view.go | 7 +- pkg/views/workspace/selection/view.go | 44 ++-- pkg/views/workspace/selection/workspace.go | 108 +++++++-- 53 files changed, 588 insertions(+), 289 deletions(-) rename pkg/views/{workspace => }/selection/branch.go (100%) rename pkg/views/{workspace => }/selection/build.go (100%) rename pkg/views/{workspace => }/selection/checkout.go (100%) rename pkg/views/{workspace => }/selection/common.go (100%) rename pkg/views/{workspace => }/selection/gitprovider.go (100%) rename pkg/views/{workspace => }/selection/gitproviderconfig.go (100%) rename pkg/views/{workspace => }/selection/namespace.go (100%) rename pkg/views/{workspace => }/selection/prebuild.go (100%) rename pkg/views/{workspace => }/selection/pullrequest.go (100%) rename pkg/views/{workspace => }/selection/repository.go (100%) rename pkg/views/{workspace => }/selection/sample.go (100%) create mode 100644 pkg/views/selection/view.go rename pkg/views/{workspace => }/selection/workspaceconfig.go (100%) rename pkg/views/{workspace => }/selection/workspacerequest.go (100%) diff --git a/docs/daytona_delete.md b/docs/daytona_delete.md index 33e0cdfb89..ef221eea81 100644 --- a/docs/daytona_delete.md +++ b/docs/daytona_delete.md @@ -3,7 +3,7 @@ Delete a workspace ``` -daytona delete [WORKSPACE] [flags] +daytona delete [WORKSPACE]... [flags] ``` ### Options diff --git a/docs/daytona_start.md b/docs/daytona_start.md index 4edea44931..a176da8837 100644 --- a/docs/daytona_start.md +++ b/docs/daytona_start.md @@ -3,7 +3,7 @@ Start a workspace ``` -daytona start [WORKSPACE] [flags] +daytona start [WORKSPACE]... [flags] ``` ### Options diff --git a/docs/daytona_stop.md b/docs/daytona_stop.md index 868b1b037c..f44baec41b 100644 --- a/docs/daytona_stop.md +++ b/docs/daytona_stop.md @@ -3,7 +3,7 @@ Stop a workspace ``` -daytona stop [WORKSPACE] [flags] +daytona stop [WORKSPACE]... [flags] ``` ### Options diff --git a/hack/docs/daytona_delete.yaml b/hack/docs/daytona_delete.yaml index f7e3545122..96a5c8d97b 100644 --- a/hack/docs/daytona_delete.yaml +++ b/hack/docs/daytona_delete.yaml @@ -1,6 +1,6 @@ name: daytona delete synopsis: Delete a workspace -usage: daytona delete [WORKSPACE] [flags] +usage: daytona delete [WORKSPACE]... [flags] options: - name: all shorthand: a diff --git a/hack/docs/daytona_start.yaml b/hack/docs/daytona_start.yaml index 9078fc247e..1c4e966446 100644 --- a/hack/docs/daytona_start.yaml +++ b/hack/docs/daytona_start.yaml @@ -1,6 +1,6 @@ name: daytona start synopsis: Start a workspace -usage: daytona start [WORKSPACE] [flags] +usage: daytona start [WORKSPACE]... [flags] options: - name: all shorthand: a diff --git a/hack/docs/daytona_stop.yaml b/hack/docs/daytona_stop.yaml index d9c14e0d03..1d63c27376 100644 --- a/hack/docs/daytona_stop.yaml +++ b/hack/docs/daytona_stop.yaml @@ -1,6 +1,6 @@ name: daytona stop synopsis: Stop a workspace -usage: daytona stop [WORKSPACE] [flags] +usage: daytona stop [WORKSPACE]... [flags] options: - name: all shorthand: a diff --git a/pkg/cmd/build/delete.go b/pkg/cmd/build/delete.go index e9400d1577..4db45f59e0 100644 --- a/pkg/cmd/build/delete.go +++ b/pkg/cmd/build/delete.go @@ -9,8 +9,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/info.go b/pkg/cmd/build/info.go index 7af105a0be..b471f46674 100644 --- a/pkg/cmd/build/info.go +++ b/pkg/cmd/build/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/build/info" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index d9df00bf35..2d2213a251 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index 774a76c747..e8a5fdddcf 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/daytonaio/daytona/pkg/views/selection" "github.com/spf13/cobra" ) @@ -45,7 +45,7 @@ var buildRunCmd = &cobra.Command{ return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := create.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := create.GetBranchFromWorkspaceConfig(ctx, workspaceConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/gitprovider/delete.go b/pkg/cmd/gitprovider/delete.go index af357b0db3..f11a451001 100644 --- a/pkg/cmd/gitprovider/delete.go +++ b/pkg/cmd/gitprovider/delete.go @@ -11,8 +11,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/gitprovider/update.go b/pkg/cmd/gitprovider/update.go index 15da83e337..2f550bc972 100644 --- a/pkg/cmd/gitprovider/update.go +++ b/pkg/cmd/gitprovider/update.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/add.go index 1058988332..1ac47caecf 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/add.go @@ -17,7 +17,7 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" + "github.com/daytonaio/daytona/pkg/views/selection" "github.com/spf13/cobra" ) @@ -75,7 +75,7 @@ var prebuildAddCmd = &cobra.Command{ return errors.New("The chosen workspace config does not have a build configuration") } - chosenBranch, err := create.GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := create.GetBranchFromWorkspaceConfig(ctx, workspaceConfig, apiClient, 0) if err != nil { return err } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index f27f82e2ae..e51be1a8e1 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -10,8 +10,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index 7633802ca5..874a61bc6c 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -11,8 +11,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/prebuild/info" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index 061db9238e..1358f62533 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/build" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go index 5ff380e61b..2fd916f33b 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/workspace/code.go @@ -15,7 +15,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/common" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/server/workspaces" ide_views "github.com/daytonaio/daytona/pkg/views/ide" @@ -94,7 +93,7 @@ var CodeCmd = &cobra.Command{ providerMetadata := *ws.Info.ProviderMetadata - gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + gpgKey, err := common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) if err != nil { log.Warn(err) } @@ -102,7 +101,7 @@ var CodeCmd = &cobra.Command{ yesFlag, _ := cmd.Flags().GetBool("yes") ideList := config.GetIdeList() ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList) - return workspace_common.OpenIDE(ideId, activeProfile, ws.Id, providerMetadata, yesFlag, gpgKey) + return common.OpenIDE(ideId, activeProfile, ws.Id, providerMetadata, yesFlag, gpgKey) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return common.GetWorkspaceNameCompletions() diff --git a/pkg/cmd/workspace/create/add_from_config.go b/pkg/cmd/workspace/create/add_from_config.go index 37d98a2bf1..f742e03b38 100644 --- a/pkg/cmd/workspace/create/add_from_config.go +++ b/pkg/cmd/workspace/create/add_from_config.go @@ -11,14 +11,21 @@ import ( "github.com/daytonaio/daytona/pkg/common" ) -func AddWorkspaceFromConfig(workspaceConfig *apiclient.WorkspaceConfig, apiClient *apiclient.APIClient, workspaces *[]apiclient.CreateWorkspaceDTO, branchFlag *string) (*string, error) { +type AddWorkspaceFromConfigParams struct { + WorkspaceConfig *apiclient.WorkspaceConfig + ApiClient *apiclient.APIClient + Workspaces *[]apiclient.CreateWorkspaceDTO + BranchFlag *string +} + +func AddWorkspaceFromConfig(ctx context.Context, params AddWorkspaceFromConfigParams) (*string, error) { chosenBranchName := "" - if branchFlag != nil { - chosenBranchName = *branchFlag + if params.BranchFlag != nil { + chosenBranchName = *params.BranchFlag } if chosenBranchName == "" { - chosenBranch, err := GetBranchFromWorkspaceConfig(workspaceConfig, apiClient, 0) + chosenBranch, err := GetBranchFromWorkspaceConfig(ctx, params.WorkspaceConfig, params.ApiClient, 0) if err != nil { return nil, err } @@ -29,8 +36,8 @@ func AddWorkspaceFromConfig(workspaceConfig *apiclient.WorkspaceConfig, apiClien chosenBranchName = chosenBranch.Name } - configRepo, res, err := apiClient.GitProviderAPI.GetGitContext(context.Background()).Repository(apiclient.GetRepositoryContext{ - Url: workspaceConfig.RepositoryUrl, + configRepo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + Url: params.WorkspaceConfig.RepositoryUrl, Branch: &chosenBranchName, }).Execute() if err != nil { @@ -38,17 +45,17 @@ func AddWorkspaceFromConfig(workspaceConfig *apiclient.WorkspaceConfig, apiClien } workspace := &apiclient.CreateWorkspaceDTO{ - Name: workspaceConfig.Name, - GitProviderConfigId: workspaceConfig.GitProviderConfigId, + Name: params.WorkspaceConfig.Name, + GitProviderConfigId: params.WorkspaceConfig.GitProviderConfigId, Source: apiclient.CreateWorkspaceSourceDTO{ Repository: *configRepo, }, - BuildConfig: workspaceConfig.BuildConfig, - Image: &workspaceConfig.Image, - User: &workspaceConfig.User, - EnvVars: workspaceConfig.EnvVars, + BuildConfig: params.WorkspaceConfig.BuildConfig, + Image: ¶ms.WorkspaceConfig.Image, + User: ¶ms.WorkspaceConfig.User, + EnvVars: params.WorkspaceConfig.EnvVars, } - *workspaces = append(*workspaces, *workspace) + *params.Workspaces = append(*params.Workspaces, *workspace) - return &workspaceConfig.Name, nil + return ¶ms.WorkspaceConfig.Name, nil } diff --git a/pkg/cmd/workspace/create/branch_wizard.go b/pkg/cmd/workspace/create/branch_wizard.go index f3c13571cc..50092d11c6 100644 --- a/pkg/cmd/workspace/create/branch_wizard.go +++ b/pkg/cmd/workspace/create/branch_wizard.go @@ -13,11 +13,11 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) -type BranchWizardConfig struct { +type BranchWizardParams struct { ApiClient *apiclient.APIClient GitProviderConfigId string NamespaceId string @@ -27,7 +27,7 @@ type BranchWizardConfig struct { ProviderId string } -func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, error) { +func SetBranchFromWizard(params BranchWizardParams) (*apiclient.GitRepository, error) { var branchList []apiclient.GitBranch var checkoutOptions []selection.CheckoutOption page := int32(1) @@ -37,7 +37,7 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e ctx := context.Background() err = views_util.WithSpinner("Loading", func() error { - branches, _, err := config.ApiClient.GitProviderAPI.GetRepoBranches(ctx, config.GitProviderConfigId, url.QueryEscape(config.NamespaceId), url.QueryEscape(config.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() + branches, _, err := params.ApiClient.GitProviderAPI.GetRepoBranches(ctx, params.GitProviderConfigId, url.QueryEscape(params.NamespaceId), url.QueryEscape(params.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() if err != nil { return err } @@ -55,9 +55,9 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e } if len(branchList) == 1 { - config.ChosenRepo.Branch = branchList[0].Name - config.ChosenRepo.Sha = branchList[0].Sha - return config.ChosenRepo, nil + params.ChosenRepo.Branch = branchList[0].Name + params.ChosenRepo.Sha = branchList[0].Sha + return params.ChosenRepo, nil } var prList []apiclient.GitPullRequest @@ -66,7 +66,7 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e perPage = 1 err = views_util.WithSpinner("Loading", func() error { - prs, _, err := config.ApiClient.GitProviderAPI.GetRepoPRs(ctx, config.GitProviderConfigId, url.QueryEscape(config.NamespaceId), url.QueryEscape(config.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() + prs, _, err := params.ApiClient.GitProviderAPI.GetRepoPRs(ctx, params.GitProviderConfigId, url.QueryEscape(params.NamespaceId), url.QueryEscape(params.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() if err != nil { return err } @@ -79,20 +79,20 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e return nil, err } - namespace := config.Namespace + namespace := params.Namespace if namespace == "" { - namespace = config.ChosenRepo.Owner + namespace = params.ChosenRepo.Owner } - parentIdentifier := fmt.Sprintf("%s/%s/%s", config.ProviderId, namespace, config.ChosenRepo.Name) + parentIdentifier := fmt.Sprintf("%s/%s/%s", params.ProviderId, namespace, params.ChosenRepo.Name) if len(prList) == 0 { - return runGetBranchFromPromptWithPagination(ctx, config, parentIdentifier, 1, 100) + return runGetBranchFromPromptWithPagination(ctx, params, parentIdentifier, 1, 100) } checkoutOptions = append(checkoutOptions, selection.CheckoutDefault) checkoutOptions = append(checkoutOptions, selection.CheckoutBranch) checkoutOptions = append(checkoutOptions, selection.CheckoutPR) - chosenCheckoutOption := selection.GetCheckoutOptionFromPrompt(config.WorkspaceOrder, checkoutOptions, parentIdentifier) + chosenCheckoutOption := selection.GetCheckoutOptionFromPrompt(params.WorkspaceOrder, checkoutOptions, parentIdentifier) if chosenCheckoutOption == (selection.CheckoutOption{}) { return nil, common.ErrCtrlCAbort @@ -100,20 +100,20 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e if chosenCheckoutOption == selection.CheckoutDefault { // Get the default branch from context - repo, res, err := config.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: config.ChosenRepo.Url, + repo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + Url: params.ChosenRepo.Url, }).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - config.ChosenRepo.Branch = repo.Branch + params.ChosenRepo.Branch = repo.Branch - return config.ChosenRepo, nil + return params.ChosenRepo, nil } if chosenCheckoutOption == selection.CheckoutBranch { - return runGetBranchFromPromptWithPagination(ctx, config, parentIdentifier, 1, 100) + return runGetBranchFromPromptWithPagination(ctx, params, parentIdentifier, 1, 100) } else if chosenCheckoutOption == selection.CheckoutPR { page = 1 perPage = 100 @@ -125,7 +125,7 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e for { err = views_util.WithSpinner("Loading Pull Requests", func() error { - prs, _, err := config.ApiClient.GitProviderAPI.GetRepoPRs(ctx, config.GitProviderConfigId, url.QueryEscape(config.NamespaceId), url.QueryEscape(config.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() + prs, _, err := params.ApiClient.GitProviderAPI.GetRepoPRs(ctx, params.GitProviderConfigId, url.QueryEscape(params.NamespaceId), url.QueryEscape(params.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() if err != nil { return err } @@ -140,7 +140,7 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e } // Check first if the git provider supports pagination - if isGitProviderWithUnsupportedPagination(config.ProviderId) { + if isGitProviderWithUnsupportedPagination(params.ProviderId) { disablePagination = true } else { // Check if we have reached the end of the list @@ -155,21 +155,21 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e } // User will either choose a PR or navigate the pages - chosenPullRequest, navigate := selection.GetPullRequestFromPrompt(prList, config.WorkspaceOrder, selectionListOptions) + chosenPullRequest, navigate := selection.GetPullRequestFromPrompt(prList, params.WorkspaceOrder, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { page++ continue } } else if chosenPullRequest != nil { - config.ChosenRepo.Branch = chosenPullRequest.Branch - config.ChosenRepo.Sha = chosenPullRequest.Sha - config.ChosenRepo.Id = chosenPullRequest.SourceRepoId - config.ChosenRepo.Name = chosenPullRequest.SourceRepoName - config.ChosenRepo.Owner = chosenPullRequest.SourceRepoOwner - config.ChosenRepo.Url = chosenPullRequest.SourceRepoUrl - - return config.ChosenRepo, nil + params.ChosenRepo.Branch = chosenPullRequest.Branch + params.ChosenRepo.Sha = chosenPullRequest.Sha + params.ChosenRepo.Id = chosenPullRequest.SourceRepoId + params.ChosenRepo.Name = chosenPullRequest.SourceRepoName + params.ChosenRepo.Owner = chosenPullRequest.SourceRepoOwner + params.ChosenRepo.Url = chosenPullRequest.SourceRepoUrl + + return params.ChosenRepo, nil } else { // If user aborts or there's no selection return nil, errors.New("must select a pull request") @@ -177,10 +177,10 @@ func SetBranchFromWizard(config BranchWizardConfig) (*apiclient.GitRepository, e } } - return config.ChosenRepo, nil + return params.ChosenRepo, nil } -func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWizardConfig, parentIdentifier string, page, perPage int32) (*apiclient.GitRepository, error) { +func runGetBranchFromPromptWithPagination(ctx context.Context, params BranchWizardParams, parentIdentifier string, page, perPage int32) (*apiclient.GitRepository, error) { var branchList []apiclient.GitBranch disablePagination := false curPageItemsNum := 0 @@ -190,7 +190,7 @@ func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWiza for { err = views_util.WithSpinner("Loading Branches", func() error { - branches, _, err := config.ApiClient.GitProviderAPI.GetRepoBranches(ctx, config.GitProviderConfigId, url.QueryEscape(config.NamespaceId), url.QueryEscape(config.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() + branches, _, err := params.ApiClient.GitProviderAPI.GetRepoBranches(ctx, params.GitProviderConfigId, url.QueryEscape(params.NamespaceId), url.QueryEscape(params.ChosenRepo.Id)).Page(page).PerPage(perPage).Execute() if err != nil { return err } @@ -205,7 +205,7 @@ func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWiza } // Check first if the git provider supports pagination - if isGitProviderWithUnsupportedPagination(config.GitProviderConfigId) { + if isGitProviderWithUnsupportedPagination(params.GitProviderConfigId) { disablePagination = true } else { // Check if we have reached the end of the list @@ -220,17 +220,17 @@ func runGetBranchFromPromptWithPagination(ctx context.Context, config BranchWiza } // User will either choose a branch or navigate the pages - branch, navigate := selection.GetBranchFromPrompt(branchList, config.WorkspaceOrder, selectionListOptions) + branch, navigate := selection.GetBranchFromPrompt(branchList, params.WorkspaceOrder, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { page++ continue // Fetch the next page of branches } } else if branch != nil { - config.ChosenRepo.Branch = branch.Name - config.ChosenRepo.Sha = branch.Sha + params.ChosenRepo.Branch = branch.Name + params.ChosenRepo.Sha = branch.Sha - return config.ChosenRepo, nil + return params.ChosenRepo, nil } else { // If user aborts or there's no selection return nil, errors.New("must select a branch") diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 0f7ecc5417..3c4c7ce826 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -89,7 +89,7 @@ var CreateCmd = &cobra.Command{ } if promptUsingTUI { - err = ProcessPrompting(ctx, ProcessPromptingConfig{ + err = ProcessPrompting(ctx, ProcessPromptingParams{ ApiClient: apiClient, CreateWorkspaceDtos: &createWorkspaceDtos, ExistingWorkspaces: &existingWorkspaces, @@ -106,7 +106,7 @@ var CreateCmd = &cobra.Command{ } } } else { - existingWorkspaceConfigNames, err = ProcessCmdArguments(ctx, ProcessCmdArgumentsConfig{ + existingWorkspaceConfigNames, err = ProcessCmdArguments(ctx, ProcessCmdArgumentsParams{ ApiClient: apiClient, RepoUrls: args, CreateWorkspaceDtos: &createWorkspaceDtos, diff --git a/pkg/cmd/workspace/create/creation_data.go b/pkg/cmd/workspace/create/creation_data.go index 580a8a3f3e..be77ba4982 100644 --- a/pkg/cmd/workspace/create/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -18,13 +18,13 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/docker/docker/pkg/stringid" ) -type WorkspacesDataPromptConfig struct { +type WorkspacesDataPromptParams struct { UserGitProviders []apiclient.GitProvider WorkspaceConfigs []apiclient.WorkspaceConfig Manual bool @@ -35,13 +35,13 @@ type WorkspacesDataPromptConfig struct { Defaults *views_util.WorkspaceConfigDefaults } -func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]apiclient.CreateWorkspaceDTO, error) { +func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesDataPromptParams) ([]apiclient.CreateWorkspaceDTO, error) { var workspaceList []apiclient.CreateWorkspaceDTO // keep track of visited repos, will help in keeping workspace names unique // since these are later saved into the db under a unique constraint field. selectedRepos := make(map[string]int) - for i := 1; config.MultiWorkspace || i == 1; i++ { + for i := 1; params.MultiWorkspace || i == 1; i++ { var err error if i > 2 { @@ -54,8 +54,8 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a } } - if len(config.WorkspaceConfigs) > 0 && !config.BlankWorkspace { - workspaceConfig := selection.GetWorkspaceConfigFromPrompt(config.WorkspaceConfigs, i, true, false, "Use") + if len(params.WorkspaceConfigs) > 0 && !params.BlankWorkspace { + workspaceConfig := selection.GetWorkspaceConfigFromPrompt(params.WorkspaceConfigs, i, true, false, "Use") if workspaceConfig == nil { return nil, common.ErrCtrlCAbort } @@ -78,7 +78,7 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a Url: workspaceConfig.RepositoryUrl, } - branch, err := GetBranchFromWorkspaceConfig(workspaceConfig, config.ApiClient, i) + branch, err := GetBranchFromWorkspaceConfig(ctx, workspaceConfig, params.ApiClient, i) if err != nil { return nil, err } @@ -88,7 +88,7 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a getRepoContext.Sha = &branch.Sha } - configRepo, res, err := config.ApiClient.GitProviderAPI.GetGitContext(context.Background()).Repository(getRepoContext).Execute() + configRepo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(getRepoContext).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -100,8 +100,8 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a Repository: *configRepo, }, BuildConfig: workspaceConfig.BuildConfig, - Image: config.Defaults.Image, - User: config.Defaults.ImageUser, + Image: params.Defaults.Image, + User: params.Defaults.ImageUser, EnvVars: workspaceConfig.EnvVars, } @@ -114,7 +114,7 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a } if workspaceConfig.GitProviderConfigId == nil || *workspaceConfig.GitProviderConfigId == "" { - gitProviderConfigId, res, err := config.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(context.Background(), url.QueryEscape(workspaceConfig.RepositoryUrl)).Execute() + gitProviderConfigId, res, err := params.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(workspaceConfig.RepositoryUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -126,12 +126,12 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a } } - providerRepo, gitProviderConfigId, err := getRepositoryFromWizard(RepositoryWizardConfig{ - ApiClient: config.ApiClient, - UserGitProviders: config.UserGitProviders, - Manual: config.Manual, - MultiWorkspace: config.MultiWorkspace, - SkipBranchSelection: config.SkipBranchSelection, + providerRepo, gitProviderConfigId, err := getRepositoryFromWizard(ctx, RepositoryWizardParams{ + ApiClient: params.ApiClient, + UserGitProviders: params.UserGitProviders, + Manual: params.Manual, + MultiWorkspace: params.MultiWorkspace, + SkipBranchSelection: params.SkipBranchSelection, WorkspaceOrder: i, SelectedRepos: selectedRepos, }) @@ -140,7 +140,7 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a } if gitProviderConfigId == selection.CustomRepoIdentifier || gitProviderConfigId == selection.CREATE_FROM_SAMPLE { - gitProviderConfigs, res, err := config.ApiClient.GitProviderAPI.ListGitProvidersForUrl(context.Background(), url.QueryEscape(providerRepo.Url)).Execute() + gitProviderConfigs, res, err := params.ApiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(providerRepo.Url)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -164,7 +164,7 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a getRepoContext := createGetRepoContextFromRepository(providerRepo) var res *http.Response - providerRepo, res, err = config.ApiClient.GitProviderAPI.GetGitContext(context.Background()).Repository(getRepoContext).Execute() + providerRepo, res, err = params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(getRepoContext).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -174,7 +174,7 @@ func GetWorkspacesCreationDataFromPrompt(config WorkspacesDataPromptConfig) ([]a return nil, err } - workspaceList = append(workspaceList, newCreateWorkspaceConfigDTO(config, providerRepo, providerRepoName, gitProviderConfigId)) + workspaceList = append(workspaceList, newCreateWorkspaceConfigDTO(params, providerRepo, providerRepoName, gitProviderConfigId)) } return workspaceList, nil @@ -212,9 +212,7 @@ func GetSanitizedWorkspaceName(workspaceName string) (string, error) { return workspaceName, nil } -func GetBranchFromWorkspaceConfig(workspaceConfig *apiclient.WorkspaceConfig, apiClient *apiclient.APIClient, workspaceOrder int) (*apiclient.GitBranch, error) { - ctx := context.Background() - +func GetBranchFromWorkspaceConfig(ctx context.Context, workspaceConfig *apiclient.WorkspaceConfig, apiClient *apiclient.APIClient, workspaceOrder int) (*apiclient.GitBranch, error) { encodedURLParam := url.QueryEscape(workspaceConfig.RepositoryUrl) repoResponse, res, err := apiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ @@ -229,7 +227,7 @@ func GetBranchFromWorkspaceConfig(workspaceConfig *apiclient.WorkspaceConfig, ap return nil, apiclient_util.HandleErrorResponse(res, err) } - branchWizardConfig := BranchWizardConfig{ + branchWizardConfig := BranchWizardParams{ ApiClient: apiClient, GitProviderConfigId: gitProviderConfigId, NamespaceId: repoResponse.Owner, @@ -315,7 +313,7 @@ func GetGitProviderConfigIdFromFlag(ctx context.Context, apiClient *apiclient.AP return nil, fmt.Errorf("git provider config '%s' not found", *gitProviderConfigFlag) } -func newCreateWorkspaceConfigDTO(config WorkspacesDataPromptConfig, providerRepo *apiclient.GitRepository, providerRepoName string, gitProviderConfigId string) apiclient.CreateWorkspaceDTO { +func newCreateWorkspaceConfigDTO(params WorkspacesDataPromptParams, providerRepo *apiclient.GitRepository, providerRepoName string, gitProviderConfigId string) apiclient.CreateWorkspaceDTO { workspace := apiclient.CreateWorkspaceDTO{ Name: providerRepoName, GitProviderConfigId: &gitProviderConfigId, @@ -323,8 +321,8 @@ func newCreateWorkspaceConfigDTO(config WorkspacesDataPromptConfig, providerRepo Repository: *providerRepo, }, BuildConfig: &apiclient.BuildConfig{}, - Image: config.Defaults.Image, - User: config.Defaults.ImageUser, + Image: params.Defaults.Image, + User: params.Defaults.ImageUser, EnvVars: map[string]string{}, } diff --git a/pkg/cmd/workspace/create/process_cmd_arguments.go b/pkg/cmd/workspace/create/process_cmd_arguments.go index 7f4a569969..afdedff50a 100644 --- a/pkg/cmd/workspace/create/process_cmd_arguments.go +++ b/pkg/cmd/workspace/create/process_cmd_arguments.go @@ -14,11 +14,11 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) -type ProcessCmdArgumentsConfig struct { +type ProcessCmdArgumentsParams struct { ApiClient *apiclient.APIClient RepoUrls []string CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO @@ -27,7 +27,7 @@ type ProcessCmdArgumentsConfig struct { BlankFlag bool } -type ProcessGitUrlConfig struct { +type ProcessGitUrlParams struct { ApiClient *apiclient.APIClient RepoUrl string CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO @@ -36,16 +36,16 @@ type ProcessGitUrlConfig struct { BlankFlag bool } -func ProcessCmdArguments(ctx context.Context, config ProcessCmdArgumentsConfig) ([]string, error) { - if len(config.RepoUrls) == 0 { +func ProcessCmdArguments(ctx context.Context, params ProcessCmdArgumentsParams) ([]string, error) { + if len(params.RepoUrls) == 0 { return nil, fmt.Errorf("no repository URLs provided") } - if len(config.RepoUrls) > 1 && workspace_common.CheckAnyWorkspaceConfigurationFlagSet(config.WorkspaceConfigurationFlags) { + if len(params.RepoUrls) > 1 && workspace_common.CheckAnyWorkspaceConfigurationFlagSet(params.WorkspaceConfigurationFlags) { return nil, fmt.Errorf("can't set custom workspace configuration properties for multiple workspaces") } - if *config.WorkspaceConfigurationFlags.Builder != "" && *config.WorkspaceConfigurationFlags.Builder != views_util.DEVCONTAINER && *config.WorkspaceConfigurationFlags.DevcontainerPath != "" { + if *params.WorkspaceConfigurationFlags.Builder != "" && *params.WorkspaceConfigurationFlags.Builder != views_util.DEVCONTAINER && *params.WorkspaceConfigurationFlags.DevcontainerPath != "" { return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) } @@ -53,22 +53,22 @@ func ProcessCmdArguments(ctx context.Context, config ProcessCmdArgumentsConfig) existingWorkspaceConfigNames := []string{} - for i, repoUrl := range config.RepoUrls { + for i, repoUrl := range params.RepoUrls { var branch *string - if len(*config.WorkspaceConfigurationFlags.Branches) > i { - branch = &(*config.WorkspaceConfigurationFlags.Branches)[i] + if len(*params.WorkspaceConfigurationFlags.Branches) > i { + branch = &(*params.WorkspaceConfigurationFlags.Branches)[i] } validatedUrl, err := util.GetValidatedUrl(repoUrl) if err == nil { // The argument is a Git URL - existingWorkspaceConfigName, err := processGitURL(ctx, ProcessGitUrlConfig{ - ApiClient: config.ApiClient, + existingWorkspaceConfigName, err := processGitURL(ctx, ProcessGitUrlParams{ + ApiClient: params.ApiClient, RepoUrl: validatedUrl, - CreateWorkspaceDtos: config.CreateWorkspaceDtos, - WorkspaceConfigurationFlags: config.WorkspaceConfigurationFlags, + CreateWorkspaceDtos: params.CreateWorkspaceDtos, + WorkspaceConfigurationFlags: params.WorkspaceConfigurationFlags, Branch: branch, - BlankFlag: config.BlankFlag, + BlankFlag: params.BlankFlag, }) if err != nil { return nil, err @@ -83,12 +83,17 @@ func ProcessCmdArguments(ctx context.Context, config ProcessCmdArgumentsConfig) } // The argument is not a Git URL - try getting the workspace config - workspaceConfig, _, err = config.ApiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, repoUrl).Execute() + workspaceConfig, _, err = params.ApiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, repoUrl).Execute() if err != nil { return nil, fmt.Errorf("failed to parse the URL or fetch the workspace config for '%s'", repoUrl) } - existingWorkspaceConfigName, err := AddWorkspaceFromConfig(workspaceConfig, config.ApiClient, config.CreateWorkspaceDtos, branch) + existingWorkspaceConfigName, err := AddWorkspaceFromConfig(ctx, AddWorkspaceFromConfigParams{ + WorkspaceConfig: workspaceConfig, + ApiClient: params.ApiClient, + Workspaces: params.CreateWorkspaceDtos, + BranchFlag: branch, + }) if err != nil { return nil, err } @@ -99,20 +104,25 @@ func ProcessCmdArguments(ctx context.Context, config ProcessCmdArgumentsConfig) } } - generateWorkspaceIds(config.CreateWorkspaceDtos) - setInitialWorkspaceNames(config.CreateWorkspaceDtos, *config.ExistingWorkspaces) + generateWorkspaceIds(params.CreateWorkspaceDtos) + setInitialWorkspaceNames(params.CreateWorkspaceDtos, *params.ExistingWorkspaces) return existingWorkspaceConfigNames, nil } -func processGitURL(ctx context.Context, config ProcessGitUrlConfig) (*string, error) { - encodedURLParam := url.QueryEscape(config.RepoUrl) +func processGitURL(ctx context.Context, params ProcessGitUrlParams) (*string, error) { + encodedURLParam := url.QueryEscape(params.RepoUrl) - if !config.BlankFlag { - workspaceConfig, res, err := config.ApiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() + if !params.BlankFlag { + workspaceConfig, res, err := params.ApiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() if err == nil { - workspaceConfig.GitProviderConfigId = config.WorkspaceConfigurationFlags.GitProviderConfig - return AddWorkspaceFromConfig(workspaceConfig, config.ApiClient, config.CreateWorkspaceDtos, config.Branch) + workspaceConfig.GitProviderConfigId = params.WorkspaceConfigurationFlags.GitProviderConfig + return AddWorkspaceFromConfig(ctx, AddWorkspaceFromConfigParams{ + WorkspaceConfig: workspaceConfig, + ApiClient: params.ApiClient, + Workspaces: params.CreateWorkspaceDtos, + BranchFlag: params.Branch, + }) } if res.StatusCode != http.StatusNotFound { @@ -120,9 +130,9 @@ func processGitURL(ctx context.Context, config ProcessGitUrlConfig) (*string, er } } - repo, res, err := config.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: config.RepoUrl, - Branch: config.Branch, + repo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + Url: params.RepoUrl, + Branch: params.Branch, }).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) @@ -133,19 +143,19 @@ func processGitURL(ctx context.Context, config ProcessGitUrlConfig) (*string, er return nil, err } - config.WorkspaceConfigurationFlags.GitProviderConfig, err = GetGitProviderConfigIdFromFlag(ctx, config.ApiClient, config.WorkspaceConfigurationFlags.GitProviderConfig) + params.WorkspaceConfigurationFlags.GitProviderConfig, err = GetGitProviderConfigIdFromFlag(ctx, params.ApiClient, params.WorkspaceConfigurationFlags.GitProviderConfig) if err != nil { return nil, err } - if config.WorkspaceConfigurationFlags.GitProviderConfig == nil || *config.WorkspaceConfigurationFlags.GitProviderConfig == "" { - gitProviderConfigs, res, err := config.ApiClient.GitProviderAPI.ListGitProvidersForUrl(context.Background(), url.QueryEscape(config.RepoUrl)).Execute() + if params.WorkspaceConfigurationFlags.GitProviderConfig == nil || *params.WorkspaceConfigurationFlags.GitProviderConfig == "" { + gitProviderConfigs, res, err := params.ApiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(params.RepoUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } if len(gitProviderConfigs) == 1 { - config.WorkspaceConfigurationFlags.GitProviderConfig = &gitProviderConfigs[0].Id + params.WorkspaceConfigurationFlags.GitProviderConfig = &gitProviderConfigs[0].Id } else if len(gitProviderConfigs) > 1 { gp := selection.GetGitProviderConfigFromPrompt(selection.GetGitProviderConfigParams{ GitProviderConfigs: gitProviderConfigs, @@ -154,11 +164,11 @@ func processGitURL(ctx context.Context, config ProcessGitUrlConfig) (*string, er if gp == nil { return nil, common.ErrCtrlCAbort } - config.WorkspaceConfigurationFlags.GitProviderConfig = &gp.Id + params.WorkspaceConfigurationFlags.GitProviderConfig = &gp.Id } } - workspace, err := GetCreateWorkspaceDtoFromFlags(config.WorkspaceConfigurationFlags) + workspace, err := GetCreateWorkspaceDtoFromFlags(params.WorkspaceConfigurationFlags) if err != nil { return nil, err } @@ -168,7 +178,7 @@ func processGitURL(ctx context.Context, config ProcessGitUrlConfig) (*string, er Repository: *repo, } - *config.CreateWorkspaceDtos = append(*config.CreateWorkspaceDtos, *workspace) + *params.CreateWorkspaceDtos = append(*params.CreateWorkspaceDtos, *workspace) return nil, nil } diff --git a/pkg/cmd/workspace/create/process_prompting.go b/pkg/cmd/workspace/create/process_prompting.go index 61bf818c45..605530dead 100644 --- a/pkg/cmd/workspace/create/process_prompting.go +++ b/pkg/cmd/workspace/create/process_prompting.go @@ -15,7 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/views/workspace/create" ) -type ProcessPromptingConfig struct { +type ProcessPromptingParams struct { ApiClient *apiclient.APIClient CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO ExistingWorkspaces *[]apiclient.WorkspaceDTO @@ -26,22 +26,22 @@ type ProcessPromptingConfig struct { IsImporting *bool } -func ProcessPrompting(ctx context.Context, config ProcessPromptingConfig) error { - if workspace_common.CheckAnyWorkspaceConfigurationFlagSet(config.WorkspaceConfigurationFlags) || (config.WorkspaceConfigurationFlags.Branches != nil && len(*config.WorkspaceConfigurationFlags.Branches) > 0) { +func ProcessPrompting(ctx context.Context, params ProcessPromptingParams) error { + if workspace_common.CheckAnyWorkspaceConfigurationFlagSet(params.WorkspaceConfigurationFlags) || (params.WorkspaceConfigurationFlags.Branches != nil && len(*params.WorkspaceConfigurationFlags.Branches) > 0) { return errors.New("please provide the repository URL in order to set up custom workspace details through the CLI") } - gitProviders, res, err := config.ApiClient.GitProviderAPI.ListGitProviders(ctx).Execute() + gitProviders, res, err := params.ApiClient.GitProviderAPI.ListGitProviders(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - workspaceConfigs, res, err := config.ApiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceConfigs, res, err := params.ApiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - apiServerConfig, res, err := config.ApiClient.ServerAPI.GetConfig(context.Background()).Execute() + apiServerConfig, res, err := params.ApiClient.ServerAPI.GetConfig(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -53,13 +53,13 @@ func ProcessPrompting(ctx context.Context, config ProcessPromptingConfig) error DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - *config.CreateWorkspaceDtos, err = GetWorkspacesCreationDataFromPrompt(WorkspacesDataPromptConfig{ + *params.CreateWorkspaceDtos, err = GetWorkspacesCreationDataFromPrompt(ctx, WorkspacesDataPromptParams{ UserGitProviders: gitProviders, WorkspaceConfigs: workspaceConfigs, - Manual: *config.WorkspaceConfigurationFlags.Manual, - MultiWorkspace: config.MultiWorkspaceFlag, - BlankWorkspace: config.BlankFlag, - ApiClient: config.ApiClient, + Manual: *params.WorkspaceConfigurationFlags.Manual, + MultiWorkspace: params.MultiWorkspaceFlag, + BlankWorkspace: params.BlankFlag, + ApiClient: params.ApiClient, Defaults: workspaceDefaults, }) @@ -67,15 +67,15 @@ func ProcessPrompting(ctx context.Context, config ProcessPromptingConfig) error return err } - generateWorkspaceIds(config.CreateWorkspaceDtos) - setInitialWorkspaceNames(config.CreateWorkspaceDtos, *config.ExistingWorkspaces) + generateWorkspaceIds(params.CreateWorkspaceDtos) + setInitialWorkspaceNames(params.CreateWorkspaceDtos, *params.ExistingWorkspaces) - submissionFormConfig := create.SubmissionFormConfig{ - ChosenName: &config.TargetName, - WorkspaceList: config.CreateWorkspaceDtos, - NameLabel: config.TargetName, + submissionFormConfig := create.SubmissionFormParams{ + ChosenName: ¶ms.TargetName, + WorkspaceList: params.CreateWorkspaceDtos, + NameLabel: params.TargetName, Defaults: workspaceDefaults, - ExistingWorkspaceNames: util.ArrayMap(*config.ExistingWorkspaces, func(w apiclient.WorkspaceDTO) string { + ExistingWorkspaceNames: util.ArrayMap(*params.ExistingWorkspaces, func(w apiclient.WorkspaceDTO) string { return w.Name }), } diff --git a/pkg/cmd/workspace/create/repository_wizard.go b/pkg/cmd/workspace/create/repository_wizard.go index fc9979a441..de66fa7809 100644 --- a/pkg/cmd/workspace/create/repository_wizard.go +++ b/pkg/cmd/workspace/create/repository_wizard.go @@ -13,9 +13,9 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" ) @@ -38,7 +38,7 @@ func gitProviderAppendsPersonalNamespace(providerId string) bool { } } -type RepositoryWizardConfig struct { +type RepositoryWizardParams struct { ApiClient *apiclient.APIClient UserGitProviders []apiclient.GitProvider Manual bool @@ -48,27 +48,25 @@ type RepositoryWizardConfig struct { SelectedRepos map[string]int } -func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepository, string, error) { +func getRepositoryFromWizard(ctx context.Context, params RepositoryWizardParams) (*apiclient.GitRepository, string, error) { var gitProviderConfigId string var namespaceId string var err error - ctx := context.Background() - - samples, res, err := config.ApiClient.SampleAPI.ListSamples(ctx).Execute() + samples, res, err := params.ApiClient.SampleAPI.ListSamples(ctx).Execute() if err != nil { log.Debug("Error fetching samples: ", apiclient_util.HandleErrorResponse(res, err)) } - if (len(config.UserGitProviders) == 0 && len(samples) == 0) || config.Manual { - repo, err := create.GetRepositoryFromUrlInput(config.MultiWorkspace, config.WorkspaceOrder, config.ApiClient, config.SelectedRepos) + if (len(params.UserGitProviders) == 0 && len(samples) == 0) || params.Manual { + repo, err := create.GetRepositoryFromUrlInput(params.MultiWorkspace, params.WorkspaceOrder, params.ApiClient, params.SelectedRepos) return repo, selection.CustomRepoIdentifier, err } supportedProviders := config_const.GetSupportedGitProviders() var gitProviderViewList []gitprovider_view.GitProviderView - for _, gitProvider := range config.UserGitProviders { + for _, gitProvider := range params.UserGitProviders { for _, supportedProvider := range supportedProviders { if gitProvider.ProviderId == supportedProvider.Id { gitProviderViewList = append(gitProviderViewList, @@ -84,13 +82,13 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos } } - gitProviderConfigId = selection.GetProviderIdFromPrompt(gitProviderViewList, config.WorkspaceOrder, len(samples) > 0) + gitProviderConfigId = selection.GetProviderIdFromPrompt(gitProviderViewList, params.WorkspaceOrder, len(samples) > 0) if gitProviderConfigId == "" { return nil, "", common.ErrCtrlCAbort } if gitProviderConfigId == selection.CustomRepoIdentifier { - repo, err := create.GetRepositoryFromUrlInput(config.MultiWorkspace, config.WorkspaceOrder, config.ApiClient, config.SelectedRepos) + repo, err := create.GetRepositoryFromUrlInput(params.MultiWorkspace, params.WorkspaceOrder, params.ApiClient, params.SelectedRepos) return repo, selection.CustomRepoIdentifier, err } @@ -100,7 +98,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos return nil, "", common.ErrCtrlCAbort } - repo, res, err := config.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + repo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ Url: sample.GitUrl, }).Execute() if err != nil { @@ -130,7 +128,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos for { err = views_util.WithSpinner("Loading Namespaces", func() error { - namespaces, _, err := config.ApiClient.GitProviderAPI.GetNamespaces(ctx, gitProviderConfigId).Page(page).PerPage(perPage).Execute() + namespaces, _, err := params.ApiClient.GitProviderAPI.GetNamespaces(ctx, gitProviderConfigId).Page(page).PerPage(perPage).Execute() if err != nil { return err } @@ -169,7 +167,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos CursorIndex: selectionListCursorIdx, } - namespaceId, navigate = selection.GetNamespaceIdFromPrompt(namespaceList, config.WorkspaceOrder, selectionListOptions) + namespaceId, navigate = selection.GetNamespaceIdFromPrompt(namespaceList, params.WorkspaceOrder, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { @@ -199,7 +197,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos // Fetch repos for the current page err = views_util.WithSpinner("Loading Repositories", func() error { - repos, _, err := config.ApiClient.GitProviderAPI.GetRepositories(ctx, gitProviderConfigId, namespaceId).Page(page).PerPage(perPage).Execute() + repos, _, err := params.ApiClient.GitProviderAPI.GetRepositories(ctx, gitProviderConfigId, namespaceId).Page(page).PerPage(perPage).Execute() if err != nil { return err } @@ -229,7 +227,7 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos } // User will either choose a repo or navigate the pages - chosenRepo, navigate = selection.GetRepositoryFromPrompt(providerRepos, config.WorkspaceOrder, config.SelectedRepos, selectionListOptions) + chosenRepo, navigate = selection.GetRepositoryFromPrompt(providerRepos, params.WorkspaceOrder, params.SelectedRepos, selectionListOptions) if !disablePagination && navigate != "" { if navigate == views.ListNavigationText { page++ @@ -243,17 +241,17 @@ func getRepositoryFromWizard(config RepositoryWizardConfig) (*apiclient.GitRepos } } - if config.SkipBranchSelection { + if params.SkipBranchSelection { return chosenRepo, gitProviderConfigId, nil } - repoWithBranch, err := SetBranchFromWizard(BranchWizardConfig{ - ApiClient: config.ApiClient, + repoWithBranch, err := SetBranchFromWizard(BranchWizardParams{ + ApiClient: params.ApiClient, GitProviderConfigId: gitProviderConfigId, NamespaceId: namespaceId, Namespace: namespace, ChosenRepo: chosenRepo, - WorkspaceOrder: config.WorkspaceOrder, + WorkspaceOrder: params.WorkspaceOrder, ProviderId: providerId, }) diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index 4efbba1aa9..868d2f306e 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -24,9 +24,8 @@ import ( var yesFlag bool var forceFlag bool -// FIXME: multi-select delete var DeleteCmd = &cobra.Command{ - Use: "delete [WORKSPACE]", + Use: "delete [WORKSPACE]...", Short: "Delete a workspace", GroupID: util.TARGET_GROUP, Aliases: []string{"remove", "rm"}, @@ -84,11 +83,7 @@ var DeleteCmd = &cobra.Command{ return nil } - workspaceToDelete := selection.GetWorkspaceFromPrompt(workspaceList, "Delete") - if workspaceToDelete == nil { - return nil - } - workspaceDeleteList = append(workspaceDeleteList, workspaceToDelete) + workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, "Delete") } else { for _, arg := range args { workspace, err := apiclient_util.GetWorkspace(arg, false) diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 785cd8e5ad..99bc106e54 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -9,7 +9,6 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/workspace/list" "github.com/spf13/cobra" @@ -27,7 +26,7 @@ var ListCmd = &cobra.Command{ ctx := context.Background() var specifyGitProviders bool - apiClient, err := apiclient_util.GetApiClient(nil) + apiClient, err := apiclient.GetApiClient(nil) if err != nil { return err } diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index f068b4c2d9..64651d3aa5 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -17,7 +17,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/common" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -99,7 +98,7 @@ var SshCmd = &cobra.Command{ sshArgs = append(sshArgs, args[1:]...) } - gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, ws.GitProviderConfigId) + gpgKey, err := common.GetGitProviderGpgKey(apiClient, ctx, ws.GitProviderConfigId) if err != nil { log.Warn(err) } diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index cbe9b091e5..adfe7ef967 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -14,7 +14,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/common" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/views" ide_views "github.com/daytonaio/daytona/pkg/views/ide" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -28,12 +27,11 @@ var allFlag bool var codeFlag bool var StartCmd = &cobra.Command{ - Use: "start [WORKSPACE]", + Use: "start [WORKSPACE]...", Short: "Start a workspace", - Args: cobra.RangeArgs(0, 1), GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var selectedWorkspaces []apiclient.WorkspaceDTO + var selectedWorkspaces []*apiclient.WorkspaceDTO var activeProfile config.Profile var ideId string var ideList []config.Ide @@ -62,18 +60,16 @@ var StartCmd = &cobra.Command{ return nil } - selectedWorkspace := selection.GetWorkspaceFromPrompt(workspaceList, "Start") - if selectedWorkspace == nil { - return nil - } - selectedWorkspaces = append(selectedWorkspaces, *selectedWorkspace) + selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Start") } else { - workspace, err := apiclient_util.GetWorkspace(args[0], true) - if err != nil { - return err + for _, arg := range args { + workspace, err := apiclient_util.GetWorkspace(arg, false) + if err != nil { + log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) + continue + } + selectedWorkspaces = append(selectedWorkspaces, workspace) } - - selectedWorkspaces = append(selectedWorkspaces, *workspace) } if len(selectedWorkspaces) == 1 { @@ -103,11 +99,11 @@ var StartCmd = &cobra.Command{ } } - err = StartWorkspace(apiClient, workspace) + err = StartWorkspace(apiClient, *workspace) if err != nil { return err } - gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) + gpgKey, err := common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) if err != nil { log.Warn(err) } @@ -116,14 +112,14 @@ var StartCmd = &cobra.Command{ if codeFlag { ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList) - err = workspace_common.OpenIDE(ideId, activeProfile, ws.Id, workspaceProviderMetadata, yesFlag, gpgKey) + err = common.OpenIDE(ideId, activeProfile, ws.Id, workspaceProviderMetadata, yesFlag, gpgKey) if err != nil { return err } } } else { for _, ws := range selectedWorkspaces { - err := StartWorkspace(apiClient, ws) + err := StartWorkspace(apiClient, *ws) if err != nil { log.Errorf("Failed to start workspace %s: %v\n\n", ws.Name, err) continue diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go index 76f3dbbd9f..efc3de00c5 100644 --- a/pkg/cmd/workspace/stop.go +++ b/pkg/cmd/workspace/stop.go @@ -22,12 +22,11 @@ import ( ) var StopCmd = &cobra.Command{ - Use: "stop [WORKSPACE]", + Use: "stop [WORKSPACE]...", Short: "Stop a workspace", - Args: cobra.RangeArgs(0, 1), GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var selectedWorkspaces []apiclient.WorkspaceDTO + var selectedWorkspaces []*apiclient.WorkspaceDTO ctx := context.Background() @@ -50,24 +49,23 @@ var StopCmd = &cobra.Command{ views_util.NotifyEmptyWorkspaceList(true) return nil } - selectedWorkspace := selection.GetWorkspaceFromPrompt(workspaceList, "Stop") - if selectedWorkspace == nil { - return nil - } - selectedWorkspaces = append(selectedWorkspaces, *selectedWorkspace) + + selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Stop") } else { - workspace, err := apiclient_util.GetWorkspace(args[0], true) - if err != nil { - return err + for _, arg := range args { + workspace, err := apiclient_util.GetWorkspace(arg, false) + if err != nil { + log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) + continue + } + selectedWorkspaces = append(selectedWorkspaces, workspace) } - - selectedWorkspaces = append(selectedWorkspaces, *workspace) } if len(selectedWorkspaces) == 1 { workspace := selectedWorkspaces[0] - err = StopWorkspace(apiClient, workspace) + err = StopWorkspace(apiClient, *workspace) if err != nil { return err } @@ -75,7 +73,7 @@ var StopCmd = &cobra.Command{ views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' stopped successfully", workspace.Name)) } else { for _, ws := range selectedWorkspaces { - err := StopWorkspace(apiClient, ws) + err := StopWorkspace(apiClient, *ws) if err != nil { log.Errorf("Failed to stop workspace %s: %v\n\n", ws.Name, err) continue diff --git a/pkg/cmd/workspaceconfig/add.go b/pkg/cmd/workspaceconfig/add.go index b4a0185119..6f66d6a37a 100644 --- a/pkg/cmd/workspaceconfig/add.go +++ b/pkg/cmd/workspaceconfig/add.go @@ -89,7 +89,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, } - createDtos, err = create_cmd.GetWorkspacesCreationDataFromPrompt(create_cmd.WorkspacesDataPromptConfig{ + createDtos, err = create_cmd.GetWorkspacesCreationDataFromPrompt(ctx, create_cmd.WorkspacesDataPromptParams{ UserGitProviders: gitProviders, Manual: *workspaceConfigurationFlags.Manual, MultiWorkspace: false, @@ -123,7 +123,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap chosenName := create_cmd.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) - submissionFormConfig := create.SubmissionFormConfig{ + submissionFormConfig := create.SubmissionFormParams{ ChosenName: &chosenName, SuggestedName: chosenName, ExistingWorkspaceNames: existingWorkspaceConfigNames, diff --git a/pkg/cmd/workspaceconfig/delete.go b/pkg/cmd/workspaceconfig/delete.go index b7517ac5bd..42cd96fb0f 100644 --- a/pkg/cmd/workspaceconfig/delete.go +++ b/pkg/cmd/workspaceconfig/delete.go @@ -11,8 +11,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/info.go b/pkg/cmd/workspaceconfig/info.go index c4c003bc6d..04b786222b 100644 --- a/pkg/cmd/workspaceconfig/info.go +++ b/pkg/cmd/workspaceconfig/info.go @@ -10,8 +10,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/setdefault.go b/pkg/cmd/workspaceconfig/setdefault.go index bd55947237..c56fcd372b 100644 --- a/pkg/cmd/workspaceconfig/setdefault.go +++ b/pkg/cmd/workspaceconfig/setdefault.go @@ -9,8 +9,8 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/update.go b/pkg/cmd/workspaceconfig/update.go index d4c153c6f1..1a2f4209ea 100644 --- a/pkg/cmd/workspaceconfig/update.go +++ b/pkg/cmd/workspaceconfig/update.go @@ -11,9 +11,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/views/workspace/selection/branch.go b/pkg/views/selection/branch.go similarity index 100% rename from pkg/views/workspace/selection/branch.go rename to pkg/views/selection/branch.go diff --git a/pkg/views/workspace/selection/build.go b/pkg/views/selection/build.go similarity index 100% rename from pkg/views/workspace/selection/build.go rename to pkg/views/selection/build.go diff --git a/pkg/views/workspace/selection/checkout.go b/pkg/views/selection/checkout.go similarity index 100% rename from pkg/views/workspace/selection/checkout.go rename to pkg/views/selection/checkout.go diff --git a/pkg/views/workspace/selection/common.go b/pkg/views/selection/common.go similarity index 100% rename from pkg/views/workspace/selection/common.go rename to pkg/views/selection/common.go diff --git a/pkg/views/workspace/selection/gitprovider.go b/pkg/views/selection/gitprovider.go similarity index 100% rename from pkg/views/workspace/selection/gitprovider.go rename to pkg/views/selection/gitprovider.go diff --git a/pkg/views/workspace/selection/gitproviderconfig.go b/pkg/views/selection/gitproviderconfig.go similarity index 100% rename from pkg/views/workspace/selection/gitproviderconfig.go rename to pkg/views/selection/gitproviderconfig.go diff --git a/pkg/views/workspace/selection/namespace.go b/pkg/views/selection/namespace.go similarity index 100% rename from pkg/views/workspace/selection/namespace.go rename to pkg/views/selection/namespace.go diff --git a/pkg/views/workspace/selection/prebuild.go b/pkg/views/selection/prebuild.go similarity index 100% rename from pkg/views/workspace/selection/prebuild.go rename to pkg/views/selection/prebuild.go diff --git a/pkg/views/workspace/selection/pullrequest.go b/pkg/views/selection/pullrequest.go similarity index 100% rename from pkg/views/workspace/selection/pullrequest.go rename to pkg/views/selection/pullrequest.go diff --git a/pkg/views/workspace/selection/repository.go b/pkg/views/selection/repository.go similarity index 100% rename from pkg/views/workspace/selection/repository.go rename to pkg/views/selection/repository.go diff --git a/pkg/views/workspace/selection/sample.go b/pkg/views/selection/sample.go similarity index 100% rename from pkg/views/workspace/selection/sample.go rename to pkg/views/selection/sample.go diff --git a/pkg/views/selection/view.go b/pkg/views/selection/view.go new file mode 100644 index 0000000000..cea73f872f --- /dev/null +++ b/pkg/views/selection/view.go @@ -0,0 +1,227 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package selection + +import ( + "fmt" + "io" + "log" + "os" + "strings" + "time" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +var CustomRepoIdentifier = "" + +const CREATE_FROM_SAMPLE = "" + +var selectedStyles = lipgloss.NewStyle(). + Border(lipgloss.NormalBorder(), false, false, false, true). + BorderForeground(views.Green). + Bold(true). + Padding(0, 0, 0, 1) + +var statusMessageGreenStyle = lipgloss.NewStyle().Bold(true). + Foreground(lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#04B575"}). + Render + +var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). + Foreground(lipgloss.AdaptiveColor{Light: "#FF474C", Dark: "#FF474C"}). + Render + +type item[T any] struct { + id, title, desc, createdTime, uptime, targetName string + choiceProperty T + isMarked bool + isMultipleSelect bool + action string +} + +func (i item[T]) Title() string { return i.title } +func (i item[T]) Id() string { return i.id } +func (i item[T]) Description() string { return i.desc } +func (i item[T]) FilterValue() string { return i.title } +func (i item[T]) CreatedTime() string { return i.createdTime } +func (i item[T]) Uptime() string { return i.uptime } +func (i item[T]) TargetName() string { return i.targetName } + +type model[T any] struct { + list list.Model + choice *T + choices []*T + footer string + initialWidthSet bool +} + +func (m model[T]) Init() tea.Cmd { + return nil +} + +func (m model[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + if !m.initialWidthSet { + _, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + m.list.SetWidth(150) + } + } + + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "ctrl+c": + return m, tea.Quit + + case "enter": + i, ok := m.list.SelectedItem().(item[T]) + if ok { + m.choice = &i.choiceProperty + } + targetList := m.list.Items() + var choices []*T + for _, target := range targetList { + if target.(item[T]).isMarked { + targetItem, ok := target.(item[T]) + if !ok { + continue + } + choices = append(choices, &targetItem.choiceProperty) + } + + } + m.choices = choices + return m, tea.Quit + } + + case tea.WindowSizeMsg: + h, v := views.DocStyle.GetFrameSize() + m.list.SetSize(msg.Width-h, msg.Height-v) + } + + var cmd tea.Cmd + m.list, cmd = m.list.Update(msg) + return m, cmd +} + +func (m model[T]) View() string { + if m.footer == "" { + c, err := config.GetConfig() + if err != nil { + log.Fatal(err) + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + log.Fatal(err) + } + + m.footer = views.GetListFooter(activeProfile.Name, views.DefaultListFooterPadding) + } + + terminalWidth, terminalHeight, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + return "" + } + + if m.list.FilterState() == list.Filtering { + return views.DocStyle.MaxWidth(terminalWidth - 4).MaxHeight(terminalHeight - 4).Render(m.list.View() + m.footer) + } + + return views.DocStyle.MaxWidth(terminalWidth - 4).Height(terminalHeight - 2).Render(m.list.View() + m.footer) +} + +type ItemDelegate[T any] struct { +} + +func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem list.Item) { + i, _ := listItem.(item[T]) // Cast the listItem to your custom item type + s := strings.Builder{} + + var isSelected = index == m.Index() + + baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) + + title := baseStyles.Render(i.Title()) + idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetName()) + idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + description := baseStyles.Render(i.Description()) + + // Add the created/updated time if it's available + timeWidth := m.Width() - baseStyles.GetHorizontalFrameSize() - lipgloss.Width(title) + timeStyles := lipgloss.NewStyle(). + Align(lipgloss.Right). + Width(timeWidth) + timeString := timeStyles.Render("") + if i.Uptime() != "" { + timeString = timeStyles.Render(i.Uptime()) + } else if i.CreatedTime() != "" { + timeString = timeStyles.Render(fmt.Sprintf("created %s", i.CreatedTime())) + } + + // Adjust styles as the user moves through the menu + if isSelected { + title = selectedStyles.Foreground(views.Green).Render(i.Title()) + idWithTargetConfig = selectedStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) + timeString = timeStyles.Foreground(views.DimmedGreen).Render(timeString) + } + + // Render to the terminal + s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, timeString)) + s.WriteRune('\n') + s.WriteString(idWithTargetConfig) + s.WriteRune('\n') + s.WriteString(description) + s.WriteRune('\n') + + fmt.Fprint(w, s.String()) +} + +func (d ItemDelegate[T]) Height() int { + height := lipgloss.NewStyle().GetVerticalFrameSize() + 4 + return height +} + +func (d ItemDelegate[T]) Spacing() int { + return 0 +} + +func (d ItemDelegate[T]) Update(msg tea.Msg, m *list.Model) tea.Cmd { + i, ok := m.SelectedItem().(item[T]) + if !ok { + return nil + } + + m.StatusMessageLifetime = time.Millisecond * 2000 + + var title string + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "x": + if !i.isMultipleSelect { + return nil + } + if i.isMarked { + i.title = strings.TrimPrefix(i.title, statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action))) + i.isMarked = false + m.SetItem(m.Index(), i) + return m.NewStatusMessage(statusMessageGreenStyle("Removed target from list: ") + statusMessageGreenStyle(i.title)) + } + + title = i.title + i.title = statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action)) + statusMessageGreenStyle(i.title) + i.isMarked = true + m.SetItem(m.Index(), i) + return m.NewStatusMessage(statusMessageDangerStyle("Added target to list: ") + statusMessageGreenStyle(title)) + } + } + return nil +} diff --git a/pkg/views/workspace/selection/workspaceconfig.go b/pkg/views/selection/workspaceconfig.go similarity index 100% rename from pkg/views/workspace/selection/workspaceconfig.go rename to pkg/views/selection/workspaceconfig.go diff --git a/pkg/views/workspace/selection/workspacerequest.go b/pkg/views/selection/workspacerequest.go similarity index 100% rename from pkg/views/workspace/selection/workspacerequest.go rename to pkg/views/selection/workspacerequest.go diff --git a/pkg/views/workspace/create/configuration.go b/pkg/views/workspace/create/configuration.go index 6b25bfb92e..8ad666c0fd 100644 --- a/pkg/views/workspace/create/configuration.go +++ b/pkg/views/workspace/create/configuration.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" ) const ( diff --git a/pkg/views/workspace/create/summary.go b/pkg/views/workspace/create/summary.go index 6fedecc09c..d15abdeed2 100644 --- a/pkg/views/workspace/create/summary.go +++ b/pkg/views/workspace/create/summary.go @@ -44,7 +44,7 @@ type SummaryModel struct { nameLabel string } -type SubmissionFormConfig struct { +type SubmissionFormParams struct { ChosenName *string SuggestedName string WorkspaceList *[]apiclient.CreateWorkspaceDTO @@ -58,10 +58,10 @@ var doneCheck bool var userCancelled bool var WorkspacesConfigurationChanged bool -func RunSubmissionForm(config SubmissionFormConfig) error { +func RunSubmissionForm(params SubmissionFormParams) error { doneCheck = true - m := NewSummaryModel(config) + m := NewSummaryModel(params) if _, err := tea.NewProgram(m, tea.WithAltScreen()).Run(); err != nil { return err @@ -75,22 +75,22 @@ func RunSubmissionForm(config SubmissionFormConfig) error { return nil } - if config.Defaults.Image == nil || config.Defaults.ImageUser == nil { + if params.Defaults.Image == nil || params.Defaults.ImageUser == nil { return errors.New("default workspace entries are not set") } var err error - isImporting := false - if config.ImportConfirmation != nil { - isImporting = *config.ImportConfirmation + importConfirmation := false + if params.ImportConfirmation != nil { + importConfirmation = *params.ImportConfirmation } - WorkspacesConfigurationChanged, err = RunWorkspaceConfiguration(config.WorkspaceList, *config.Defaults, isImporting) + WorkspacesConfigurationChanged, err = RunWorkspaceConfiguration(params.WorkspaceList, *params.Defaults, importConfirmation) if err != nil { return err } - return RunSubmissionForm(config) + return RunSubmissionForm(params) } func RenderSummary(name string, workspaceList []apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults, nameLabel string) (string, error) { @@ -167,36 +167,36 @@ func workspaceDetailOutput(workspaceDetailKey WorkspaceDetail, workspaceDetailVa return fmt.Sprintf("\t%s%-*s%s", lipgloss.NewStyle().Foreground(views.Green).Render(string(workspaceDetailKey)), DEFAULT_PADDING-len(string(workspaceDetailKey)), EMPTY_STRING, workspaceDetailValue) } -func NewSummaryModel(config SubmissionFormConfig) SummaryModel { +func NewSummaryModel(params SubmissionFormParams) SummaryModel { m := SummaryModel{width: maxWidth} m.lg = lipgloss.DefaultRenderer() m.styles = NewStyles(m.lg) - m.workspaceList = *config.WorkspaceList - m.defaults = config.Defaults - m.nameLabel = config.NameLabel + m.workspaceList = *params.WorkspaceList + m.defaults = params.Defaults + m.nameLabel = params.NameLabel - if config.ChosenName != nil && *config.ChosenName == "" { - *config.ChosenName = config.SuggestedName + if params.ChosenName != nil && *params.ChosenName == "" { + *params.ChosenName = params.SuggestedName } - if config.ImportConfirmation == nil || !*config.ImportConfirmation { + if params.ImportConfirmation == nil || !*params.ImportConfirmation { m.form = huh.NewForm( huh.NewGroup( huh.NewInput(). - Title(fmt.Sprintf("%s name", config.NameLabel)). - Value(config.ChosenName). + Title(fmt.Sprintf("%s name", params.NameLabel)). + Value(params.ChosenName). Key("name"). Validate(func(str string) error { result, err := util.GetValidatedName(str) if err != nil { return err } - for _, name := range config.ExistingWorkspaceNames { + for _, name := range params.ExistingWorkspaceNames { if name == result { return errors.New("name already exists") } } - *config.ChosenName = result + *params.ChosenName = result return nil }), ), @@ -206,7 +206,7 @@ func NewSummaryModel(config SubmissionFormConfig) SummaryModel { huh.NewGroup( huh.NewConfirm(). Title("Is the above information correct?"). - Value(config.ImportConfirmation), + Value(params.ImportConfirmation), ), ).WithShowHelp(false).WithTheme(views.GetCustomTheme()) } diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go index d8880b5df8..b7c8217986 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/workspace/info/view.go @@ -98,16 +98,11 @@ func getSingleWorkspaceOutput(workspace *apiclient.WorkspaceDTO, isCreationView output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) if !isCreationView { - output += getInfoLine("Target ID", workspace.TargetId) + "\n" + output += getInfoLine("Target", fmt.Sprintf("%s (%s)", workspace.TargetName, workspace.TargetId)) + "\n" } output += getInfoLine("Repository", repositoryUrl) - if !isCreationView { - output += "\n" - output += getInfoLine("Workspace", workspace.Name) - } - return output } diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/workspace/selection/view.go index 23b6464407..fe757cde3d 100644 --- a/pkg/views/workspace/selection/view.go +++ b/pkg/views/workspace/selection/view.go @@ -15,14 +15,11 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" "golang.org/x/term" ) -var CustomRepoIdentifier = "" - -const CREATE_FROM_SAMPLE = "" - var selectedStyles = lipgloss.NewStyle(). Border(lipgloss.NormalBorder(), false, false, false, true). BorderForeground(views.Green). @@ -38,20 +35,22 @@ var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). Render type item[T any] struct { - id, title, desc, createdTime, uptime, targetConfig string - choiceProperty T - isMarked bool - isMultipleSelect bool - action string + id, title, desc, targetName, repository, createdTime, uptime string + workspace *apiclient.WorkspaceDTO + choiceProperty T + isMarked bool + isMultipleSelect bool + action string } -func (i item[T]) Title() string { return i.title } -func (i item[T]) Id() string { return i.id } -func (i item[T]) Description() string { return i.desc } -func (i item[T]) FilterValue() string { return i.title } -func (i item[T]) CreatedTime() string { return i.createdTime } -func (i item[T]) Uptime() string { return i.uptime } -func (i item[T]) TargetConfig() string { return i.targetConfig } +func (i item[T]) Title() string { return i.title } +func (i item[T]) Id() string { return i.id } +func (i item[T]) Description() string { return i.desc } +func (i item[T]) TargetName() string { return i.targetName } +func (i item[T]) Repository() string { return i.repository } +func (i item[T]) CreatedTime() string { return i.createdTime } +func (i item[T]) Uptime() string { return i.uptime } +func (i item[T]) FilterValue() string { return i.title } type model[T any] struct { list list.Model @@ -149,8 +148,12 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) title := baseStyles.Render(i.Title()) - idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetConfig()) + idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetName()) + if i.Id() == NewWorkspaceIdentifier { + idWithTargetConfigString = "" + } idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + repository := baseStyles.Foreground(views.DimmedGreen).Render(i.Repository()) description := baseStyles.Render(i.Description()) // Add the created/updated time if it's available @@ -169,6 +172,7 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l if isSelected { title = selectedStyles.Foreground(views.Green).Render(i.Title()) idWithTargetConfig = selectedStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + repository = selectedStyles.Foreground(views.DimmedGreen).Render(i.Repository()) description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) timeString = timeStyles.Foreground(views.DimmedGreen).Render(timeString) } @@ -178,8 +182,12 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l s.WriteRune('\n') s.WriteString(idWithTargetConfig) s.WriteRune('\n') - s.WriteString(description) + s.WriteString(repository) s.WriteRune('\n') + if i.Description() != "" { + s.WriteString(description) + s.WriteRune('\n') + } fmt.Fprint(w, s.String()) } diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go index b78d5e3bfd..6664c114d3 100644 --- a/pkg/views/workspace/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -7,43 +7,72 @@ import ( "fmt" "os" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + list_view "github.com/daytonaio/daytona/pkg/views/workspace/list" ) -func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) *apiclient.WorkspaceDTO { - choiceChan := make(chan *apiclient.WorkspaceDTO) - go selectWorkspacePrompt(workspaces, actionVerb, choiceChan) - return <-choiceChan -} +var NewWorkspaceIdentifier = "" -func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- *apiclient.WorkspaceDTO) { +func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect bool, action string) []list.Item { + // Initialize an empty list of items. items := []list.Item{} + // Populate items with titles and descriptions from workspaces. for _, workspace := range workspaces { workspaceName := workspace.Name if workspace.Name == "" { workspaceName = "Unnamed Workspace" } - newItem := item[apiclient.WorkspaceDTO]{title: workspaceName, desc: "", choiceProperty: workspace} + // Get the time if available + uptime := "" + createdTime := "" + + if workspace.Info != nil { + createdTime = util.FormatTimestamp(workspace.Info.Created) + } + + if workspace.State != nil { + if workspace.State.Uptime == 0 { + uptime = "STOPPED" + } else { + uptime = fmt.Sprintf("up %s", util.FormatUptime(workspace.State.Uptime)) + } + } + + newItem := item[apiclient.WorkspaceDTO]{ + title: workspaceName, + id: workspace.Id, + desc: "", + targetName: workspace.TargetName, + repository: workspace.Repository.Url, + createdTime: createdTime, + uptime: uptime, + workspace: &workspace, + choiceProperty: workspace, + } + + if isMultipleSelect { + newItem.isMultipleSelect = true + newItem.action = action + } + items = append(items, newItem) } - d := list.NewDefaultDelegate() + return items +} + +func getWorkspaceProgramEssentials(modelTitle string, actionVerb string, workspaces []apiclient.WorkspaceDTO, footerText string, isMultipleSelect bool) tea.Model { - d.Styles.SelectedTitle = lipgloss.NewStyle(). - Border(lipgloss.NormalBorder(), false, false, false, true). - BorderForeground(views.Green). - Foreground(views.Green). - Bold(true). - Padding(0, 0, 0, 1) + items := generateWorkspaceList(workspaces, isMultipleSelect, actionVerb) - d.Styles.SelectedDesc = d.Styles.SelectedTitle.Foreground(views.DimmedGreen) + d := ItemDelegate[apiclient.WorkspaceDTO]{} l := list.New(items, d, 0, 0) @@ -55,18 +84,59 @@ func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb strin m := model[apiclient.WorkspaceDTO]{list: l} - m.list.Title = views.GetStyledMainTitle("Select a Workspace To " + actionVerb) + m.list.Title = views.GetStyledMainTitle(modelTitle + actionVerb) m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) + m.footer = footerText p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() + if err != nil { fmt.Println("Error running program:", err) os.Exit(1) } + return p +} + +func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- *apiclient.WorkspaceDTO) { + list_view.SortWorkspaces(&workspaces, true) + + p := getWorkspaceProgramEssentials("Select a Workspace To ", actionVerb, workspaces, "", false) if m, ok := p.(model[apiclient.WorkspaceDTO]); ok && m.choice != nil { choiceChan <- m.choice } else { choiceChan <- nil } } + +func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) *apiclient.WorkspaceDTO { + choiceChan := make(chan *apiclient.WorkspaceDTO) + + go selectWorkspacePrompt(workspaces, actionVerb, choiceChan) + + return <-choiceChan +} + +func selectWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- []*apiclient.WorkspaceDTO) { + list_view.SortWorkspaces(&workspaces, true) + + footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark a workspace.\nPress 'enter' to %s the current/marked workspaces.", actionVerb)) + p := getWorkspaceProgramEssentials("Select Workspaces To ", actionVerb, workspaces, footerText, true) + + m, ok := p.(model[apiclient.WorkspaceDTO]) + if ok && m.choices != nil { + choiceChan <- m.choices + } else if ok && m.choice != nil { + choiceChan <- []*apiclient.WorkspaceDTO{m.choice} + } else { + choiceChan <- nil + } +} + +func GetWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) []*apiclient.WorkspaceDTO { + choiceChan := make(chan []*apiclient.WorkspaceDTO) + + go selectWorkspacesFromPrompt(workspaces, actionVerb, choiceChan) + + return <-choiceChan +} From 78cbd1b0232d8476d55e0f5ab361e4bbb21aafb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Tue, 12 Nov 2024 09:44:07 +0100 Subject: [PATCH 07/76] feat: add multi-select to restart cmd (#1328) Signed-off-by: Luka Brecic --- pkg/cmd/workspace/restart.go | 41 +++++++++++++++++++-------- pkg/views/workspace/selection/view.go | 4 +-- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/workspace/restart.go index 6ef66626af..a41f8bd649 100644 --- a/pkg/cmd/workspace/restart.go +++ b/pkg/cmd/workspace/restart.go @@ -14,17 +14,17 @@ import ( "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var RestartCmd = &cobra.Command{ - Use: "restart [WORKSPACE]", + Use: "restart [WORKSPACE]...", Short: "Restart a workspace", - Args: cobra.RangeArgs(0, 1), GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var workspace *apiclient.WorkspaceDTO + var selectedWorkspaces []*apiclient.WorkspaceDTO ctx := context.Background() @@ -44,24 +44,41 @@ var RestartCmd = &cobra.Command{ } if len(args) == 0 { - workspace := selection.GetWorkspaceFromPrompt(workspaceList, "Restart") - if workspace == nil { + selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Restart") + if selectedWorkspaces == nil { return nil } } else { - workspace, err = apiclient_util.GetWorkspace(args[0], false) + for _, arg := range args { + workspace, err := apiclient_util.GetWorkspace(arg, false) + if err != nil { + log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) + continue + } + selectedWorkspaces = append(selectedWorkspaces, workspace) + } + } + + if len(selectedWorkspaces) == 1 { + workspace := selectedWorkspaces[0] + + err = RestartWorkspace(apiClient, *workspace) if err != nil { return err } - } - err = RestartWorkspace(apiClient, *workspace) - if err != nil { - return err + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' restarted successfully", workspace.Name)) + } else { + for _, ws := range selectedWorkspaces { + err := RestartWorkspace(apiClient, *ws) + if err != nil { + log.Errorf("Failed to restart workspace %s: %v\n\n", ws.Name, err) + continue + } + views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' restarted successfully", ws.Name)) + } } - views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' restarted successfully", workspace.Name)) - return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/workspace/selection/view.go index fe757cde3d..b41396fd6c 100644 --- a/pkg/views/workspace/selection/view.go +++ b/pkg/views/workspace/selection/view.go @@ -221,14 +221,14 @@ func (d ItemDelegate[T]) Update(msg tea.Msg, m *list.Model) tea.Cmd { i.title = strings.TrimPrefix(i.title, statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action))) i.isMarked = false m.SetItem(m.Index(), i) - return m.NewStatusMessage(statusMessageGreenStyle("Removed target from list: ") + statusMessageGreenStyle(i.title)) + return m.NewStatusMessage(statusMessageGreenStyle("Removed workspace from list: ") + statusMessageGreenStyle(i.title)) } title = i.title i.title = statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action)) + statusMessageGreenStyle(i.title) i.isMarked = true m.SetItem(m.Index(), i) - return m.NewStatusMessage(statusMessageDangerStyle("Added target to list: ") + statusMessageGreenStyle(title)) + return m.NewStatusMessage(statusMessageDangerStyle("Added workspace to list: ") + statusMessageGreenStyle(title)) } } return nil From b9589d505b65a2f0a9791c880ed3e19202625c3f Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Tue, 12 Nov 2024 17:47:36 +0000 Subject: [PATCH 08/76] refactor: remove database DTOs Signed-off-by: Toma Puljak --- docs/daytona_restart.md | 2 +- hack/docs/daytona_restart.yaml | 2 +- internal/cmd/tailscale/forward.go | 4 +- internal/testing/build/mocks/build_service.go | 15 +- internal/testing/build/store.go | 37 +- internal/testing/docker/mocks/client.go | 26 +- internal/testing/git/mocks/gitservice.go | 8 +- .../testing/provider/targetconfigs/store.go | 73 ---- internal/testing/server/apikeys/store.go | 23 +- .../server/containerregistries/store.go | 23 +- internal/testing/server/profiledata/store.go | 13 +- .../testing/server/targetconfigs/store.go | 26 +- .../server/targets/mocks/api_key_service.go | 8 +- .../server/targets/mocks/build_service.go | 13 +- .../testing/server/targets/mocks/builder.go | 25 +- .../mocks/container_registry_service.go | 20 +- .../targets/mocks/git_provider_service.go | 15 +- .../server/targets/mocks/provisioner.go | 29 +- .../server/targets/mocks/workspace_config.go | 9 +- .../targets/mocks/workspace_config_service.go | 19 +- internal/testing/server/targets/store.go | 39 +-- .../testing/server/workspaceconfig/store.go | 29 +- internal/testing/server/workspaces/store.go | 33 +- .../apiclient/conversion/target_config.go | 6 +- .../util/apiclient/conversion/workspace.go | 56 ++- pkg/agent/agent.go | 10 +- pkg/agent/agent_test.go | 19 +- pkg/agent/types.go | 4 +- pkg/api/controllers/apikey/generate.go | 4 +- pkg/api/controllers/build/build.go | 16 +- pkg/api/controllers/containerregistry/set.go | 4 +- pkg/api/controllers/gitprovider/dto/dto.go | 18 +- .../controllers/gitprovider/gitprovider.go | 16 +- .../controllers/profiledata/profile_data.go | 15 +- pkg/api/controllers/target/dto/dto.go | 6 +- pkg/api/controllers/target/target.go | 4 +- pkg/api/controllers/targetconfig/remove.go | 4 +- pkg/api/controllers/workspace/create.go | 2 +- pkg/api/controllers/workspace/dto/dto.go | 8 +- pkg/api/controllers/workspace/state.go | 4 +- .../controllers/workspace/toolbox/toolbox.go | 3 +- .../workspaceconfig/prebuild/prebuild.go | 16 +- .../workspaceconfig/workspace_config.go | 14 +- pkg/api/docs/docs.go | 142 ++++---- pkg/api/docs/swagger.json | 142 ++++---- pkg/api/docs/swagger.yaml | 102 +++--- pkg/api/middlewares/auth.go | 8 +- pkg/apiclient/README.md | 6 +- pkg/apiclient/api/openapi.yaml | 328 +++++++++++++----- pkg/apiclient/api_workspace.go | 8 +- pkg/apiclient/docs/ApiKey.md | 10 +- pkg/apiclient/docs/Build.md | 10 +- ...pikeyApiKeyType.md => ModelsApiKeyType.md} | 2 +- ...BuildBuildState.md => ModelsBuildState.md} | 2 +- pkg/apiclient/docs/ProfileAPI.md | 2 +- pkg/apiclient/docs/ProfileData.md | 23 +- pkg/apiclient/docs/Target.md | 26 ++ pkg/apiclient/docs/TargetDTO.md | 27 +- .../{WorkspaceViewDTO.md => Workspace.md} | 112 +++--- pkg/apiclient/docs/WorkspaceAPI.md | 6 +- pkg/apiclient/docs/WorkspaceDTO.md | 40 +-- pkg/apiclient/model_api_key.go | 12 +- pkg/apiclient/model_apikey_api_key_type.go | 112 ------ pkg/apiclient/model_build.go | 12 +- pkg/apiclient/model_build_build_state.go | 122 ------- pkg/apiclient/model_models_api_key_type.go | 112 ++++++ pkg/apiclient/model_models_build_state.go | 122 +++++++ pkg/apiclient/model_profile_data.go | 30 +- pkg/apiclient/model_target.go | 36 ++ pkg/apiclient/model_target_dto.go | 48 +-- ...rkspace_view_dto.go => model_workspace.go} | 160 ++++----- pkg/apiclient/model_workspace_dto.go | 48 +-- pkg/apikey/store.go | 22 -- pkg/build/builder.go | 17 +- pkg/build/builder_test.go | 6 +- pkg/build/detect/detect.go | 10 +- pkg/build/devcontainer.go | 7 +- pkg/build/factory.go | 25 +- pkg/build/mocks/gitprovider_config_store.go | 6 +- pkg/build/runner.go | 48 +-- pkg/build/runner_test.go | 15 +- pkg/cmd/agent/agent.go | 8 +- pkg/cmd/server/serve.go | 26 +- pkg/cmd/workspace/common/get_gpg_key.go | 10 +- pkg/cmd/workspace/create/cmd.go | 4 +- pkg/cmd/workspace/ssh-proxy.go | 4 +- pkg/cmd/workspaceconfig/export.go | 2 +- pkg/cmd/workspaceconfig/import.go | 4 +- pkg/containerregistry/store.go | 21 -- pkg/db/api_key_store.go | 52 ++- pkg/db/build_store.go | 41 +-- pkg/db/container_registry_store.go | 37 +- pkg/db/dto/api_key.go | 30 -- pkg/db/dto/build.go | 57 --- pkg/db/dto/container_registry.go | 34 -- pkg/db/dto/git_provider.go | 47 --- pkg/db/dto/profile_data.go | 26 -- pkg/db/dto/target.go | 65 ---- pkg/db/dto/target_config.go | 39 --- pkg/db/dto/workspace.go | 257 -------------- pkg/db/dto/workspace_config.go | 86 ----- pkg/db/gitprovider_config_store.go | 42 +-- pkg/db/profile_data_store.go | 23 +- pkg/db/target_config_store.go | 39 +-- pkg/db/target_store.go | 52 +-- pkg/db/workspace_config_store.go | 39 +-- pkg/db/workspace_store.go | 39 +-- pkg/docker/client.go | 37 +- pkg/docker/client_test.go | 12 +- pkg/docker/create.go | 4 +- pkg/docker/create_devcontainer.go | 11 +- pkg/docker/create_image.go | 4 +- pkg/docker/destroy.go | 9 +- pkg/docker/info.go | 15 +- pkg/docker/info_test.go | 6 +- pkg/docker/pull_image.go | 6 +- pkg/docker/push_image.go | 4 +- pkg/docker/start.go | 4 +- pkg/docker/stop.go | 6 +- pkg/git/config.go | 9 +- pkg/git/service.go | 24 +- pkg/git/status.go | 10 +- pkg/gitprovider/store.go | 21 -- pkg/gitprovider/types.go | 18 - pkg/{apikey/apikey.go => models/api_key.go} | 6 +- pkg/{build => models}/build.go | 32 +- .../config.go => models/build_config.go} | 2 +- .../config.go => models/container_config.go} | 2 +- .../container_registry.go | 4 +- pkg/models/git_provider_config.go | 22 ++ pkg/{workspace/config => models}/prebuild.go | 24 +- pkg/models/profile_data.go | 9 + pkg/models/target.go | 27 ++ .../config.go => models/target_config.go} | 8 +- pkg/{workspace => models}/workspace.go | 77 ++-- .../config.go => models/workspace_config.go} | 26 +- pkg/profiledata/profile_data.go | 8 - pkg/provider/manager/manager.go | 13 +- pkg/provider/provider.go | 13 +- pkg/provider/rpc_client.go | 11 +- pkg/provider/rpc_server.go | 7 +- pkg/provider/types.go | 22 +- pkg/provisioner/create.go | 7 +- pkg/provisioner/destroy.go | 10 +- pkg/provisioner/info.go | 14 +- pkg/provisioner/provisioner.go | 31 +- pkg/provisioner/start.go | 7 +- pkg/provisioner/stop.go | 10 +- pkg/server/apikeys/apikeys.go | 12 +- pkg/server/apikeys/apikeys_test.go | 12 +- pkg/server/apikeys/service.go | 10 +- pkg/server/apikeys/service_test.go | 8 +- pkg/server/apikeys/store.go | 26 ++ pkg/server/apikeys/validate.go | 6 +- pkg/server/apikeys/validate_test.go | 12 +- pkg/server/builds/dto/builds.go | 4 +- pkg/server/builds/service.go | 29 +- pkg/server/builds/service_test.go | 56 ++- pkg/{build => server/builds}/store.go | 22 +- pkg/server/containerregistries/service.go | 28 +- .../containerregistries/service_test.go | 6 +- pkg/server/containerregistries/store.go | 25 ++ pkg/server/gitproviders/config.go | 11 +- pkg/server/gitproviders/gitprovider.go | 5 +- pkg/server/gitproviders/remove.go | 6 +- pkg/server/gitproviders/service.go | 27 +- pkg/server/gitproviders/store.go | 30 ++ .../util/workspace_config_store.go | 30 ++ pkg/server/profiledata/service.go | 34 +- pkg/server/profiledata/service_test.go | 20 +- pkg/{ => server}/profiledata/store.go | 16 +- pkg/server/registry/service.go | 6 +- pkg/server/server.go | 6 +- pkg/server/targetconfigs/dto/target_config.go | 4 +- pkg/server/targetconfigs/service.go | 28 +- pkg/server/targetconfigs/service_test.go | 33 +- .../config => server/targetconfigs}/store.go | 16 +- pkg/server/targets/create.go | 19 +- pkg/server/targets/dto/target.go | 6 +- pkg/server/targets/env_vars.go | 32 ++ pkg/server/targets/error.go | 4 + pkg/server/targets/get.go | 7 +- pkg/server/targets/list.go | 7 +- pkg/server/targets/remove.go | 24 +- pkg/server/targets/service.go | 16 +- pkg/server/targets/service_test.go | 32 +- pkg/server/targets/set-default.go | 12 +- pkg/server/targets/start.go | 16 +- pkg/server/targets/stop.go | 10 +- pkg/server/targets/store.go | 20 ++ .../dto/workspaceconfig.go | 18 +- .../prebuild.go | 66 ++-- .../prebuild_test.go | 57 +-- .../service.go | 34 +- .../service_test.go | 50 +-- .../workspaceconfigs}/store.go | 18 +- pkg/server/workspaces/create.go | 48 ++- pkg/server/workspaces/dto/workspace.go | 9 +- pkg/server/workspaces/env_vars.go | 34 ++ pkg/server/workspaces/get.go | 10 +- pkg/server/workspaces/list.go | 11 +- pkg/server/workspaces/remove.go | 33 +- pkg/server/workspaces/service.go | 19 +- pkg/server/workspaces/service_test.go | 38 +- pkg/server/workspaces/start.go | 37 +- pkg/server/workspaces/stop.go | 20 +- pkg/server/workspaces/store.go | 20 ++ pkg/target/store.go | 31 -- pkg/target/target.go | 52 --- pkg/telemetry/server_events.go | 10 +- pkg/views/target/list/view.go | 2 +- pkg/views/workspace/info/view.go | 2 +- pkg/views/workspace/list/view.go | 2 +- pkg/views/workspace/selection/workspace.go | 2 +- pkg/workspace/store.go | 26 -- 215 files changed, 2630 insertions(+), 3114 deletions(-) delete mode 100644 internal/testing/provider/targetconfigs/store.go rename pkg/apiclient/docs/{ApikeyApiKeyType.md => ModelsApiKeyType.md} (94%) rename pkg/apiclient/docs/{BuildBuildState.md => ModelsBuildState.md} (96%) rename pkg/apiclient/docs/{WorkspaceViewDTO.md => Workspace.md} (62%) delete mode 100644 pkg/apiclient/model_apikey_api_key_type.go delete mode 100644 pkg/apiclient/model_build_build_state.go create mode 100644 pkg/apiclient/model_models_api_key_type.go create mode 100644 pkg/apiclient/model_models_build_state.go rename pkg/apiclient/{model_workspace_view_dto.go => model_workspace.go} (65%) delete mode 100644 pkg/apikey/store.go delete mode 100644 pkg/containerregistry/store.go delete mode 100644 pkg/db/dto/api_key.go delete mode 100644 pkg/db/dto/build.go delete mode 100644 pkg/db/dto/container_registry.go delete mode 100644 pkg/db/dto/git_provider.go delete mode 100644 pkg/db/dto/profile_data.go delete mode 100644 pkg/db/dto/target.go delete mode 100644 pkg/db/dto/target_config.go delete mode 100644 pkg/db/dto/workspace.go delete mode 100644 pkg/db/dto/workspace_config.go delete mode 100644 pkg/gitprovider/store.go rename pkg/{apikey/apikey.go => models/api_key.go} (70%) rename pkg/{build => models}/build.go (70%) rename pkg/{workspace/buildconfig/config.go => models/build_config.go} (96%) rename pkg/{workspace/containerconfig/config.go => models/container_config.go} (90%) rename pkg/{containerregistry => models}/container_registry.go (88%) create mode 100644 pkg/models/git_provider_config.go rename pkg/{workspace/config => models}/prebuild.go (65%) create mode 100644 pkg/models/profile_data.go create mode 100644 pkg/models/target.go rename pkg/{target/config/config.go => models/target_config.go} (51%) rename pkg/{workspace => models}/workspace.go (71%) rename pkg/{workspace/config/config.go => models/workspace_config.go} (53%) delete mode 100644 pkg/profiledata/profile_data.go create mode 100644 pkg/server/apikeys/store.go rename pkg/{build => server/builds}/store.go (60%) create mode 100644 pkg/server/containerregistries/store.go create mode 100644 pkg/server/gitproviders/store.go create mode 100644 pkg/server/gitproviders/util/workspace_config_store.go rename pkg/{ => server}/profiledata/store.go (52%) rename pkg/{target/config => server/targetconfigs}/store.go (52%) create mode 100644 pkg/server/targets/env_vars.go create mode 100644 pkg/server/targets/store.go rename pkg/server/{workspaceconfig => workspaceconfigs}/dto/workspaceconfig.go (59%) rename pkg/server/{workspaceconfig => workspaceconfigs}/prebuild.go (83%) rename pkg/server/{workspaceconfig => workspaceconfigs}/prebuild_test.go (77%) rename pkg/server/{workspaceconfig => workspaceconfigs}/service.go (70%) rename pkg/server/{workspaceconfig => workspaceconfigs}/service_test.go (73%) rename pkg/{workspace/config => server/workspaceconfigs}/store.go (67%) create mode 100644 pkg/server/workspaces/env_vars.go create mode 100644 pkg/server/workspaces/store.go delete mode 100644 pkg/target/store.go delete mode 100644 pkg/target/target.go delete mode 100644 pkg/workspace/store.go diff --git a/docs/daytona_restart.md b/docs/daytona_restart.md index 98ff4b8092..9aa98ed36a 100644 --- a/docs/daytona_restart.md +++ b/docs/daytona_restart.md @@ -3,7 +3,7 @@ Restart a workspace ``` -daytona restart [WORKSPACE] [flags] +daytona restart [WORKSPACE]... [flags] ``` ### Options inherited from parent commands diff --git a/hack/docs/daytona_restart.yaml b/hack/docs/daytona_restart.yaml index db758636a6..d2b1eb9724 100644 --- a/hack/docs/daytona_restart.yaml +++ b/hack/docs/daytona_restart.yaml @@ -1,6 +1,6 @@ name: daytona restart synopsis: Restart a workspace -usage: daytona restart [WORKSPACE] [flags] +usage: daytona restart [WORKSPACE]... [flags] inherited_options: - name: help default_value: "false" diff --git a/internal/cmd/tailscale/forward.go b/internal/cmd/tailscale/forward.go index b69f4179f2..e441282ae9 100644 --- a/internal/cmd/tailscale/forward.go +++ b/internal/cmd/tailscale/forward.go @@ -10,8 +10,8 @@ import ( "net" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/workspace" "tailscale.com/tsnet" ) @@ -47,7 +47,7 @@ func ForwardPort(workspaceId string, targetPort uint16, profile config.Profile) return } - targetUrl := fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(workspaceId), targetPort) + targetUrl := fmt.Sprintf("%s:%d", (models.Workspace{Id: workspaceId}).Hostname(), targetPort) go handlePortConnection(conn, tsConn, targetUrl, errChan) } diff --git a/internal/testing/build/mocks/build_service.go b/internal/testing/build/mocks/build_service.go index da8936b99f..1711944025 100644 --- a/internal/testing/build/mocks/build_service.go +++ b/internal/testing/build/mocks/build_service.go @@ -6,7 +6,8 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" "github.com/stretchr/testify/mock" ) @@ -18,24 +19,24 @@ func NewMockBuildService() *MockBuildService { return &MockBuildService{} } -func (m *MockBuildService) Create(b *build.Build) error { +func (m *MockBuildService) Create(b *models.Build) error { args := m.Called(b) return args.Error(0) } -func (m *MockBuildService) Update(b *build.Build) error { +func (m *MockBuildService) Update(b *models.Build) error { args := m.Called(b) return args.Error(0) } -func (m *MockBuildService) Find(id string) (*build.Build, error) { +func (m *MockBuildService) Find(id string) (*models.Build, error) { args := m.Called(id) - return args.Get(0).(*build.Build), args.Error(1) + return args.Get(0).(*models.Build), args.Error(1) } -func (m *MockBuildService) List(filter *build.Filter) ([]*build.Build, error) { +func (m *MockBuildService) List(filter *builds.BuildFilter) ([]*models.Build, error) { args := m.Called(filter) - return args.Get(0).([]*build.Build), args.Error(1) + return args.Get(0).([]*models.Build), args.Error(1) } func (m *MockBuildService) Delete(id string) error { diff --git a/internal/testing/build/store.go b/internal/testing/build/store.go index 56f54cb1d8..f014f3671e 100644 --- a/internal/testing/build/store.go +++ b/internal/testing/build/store.go @@ -8,32 +8,33 @@ package build import ( "fmt" - "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" ) type InMemoryBuildStore struct { - builds map[string]*build.Build + builds map[string]*models.Build } -func NewInMemoryBuildStore() build.Store { +func NewInMemoryBuildStore() builds.BuildStore { return &InMemoryBuildStore{ - builds: make(map[string]*build.Build), + builds: make(map[string]*models.Build), } } -func (s *InMemoryBuildStore) Find(filter *build.Filter) (*build.Build, error) { - builds, err := s.processFilters(filter) +func (s *InMemoryBuildStore) Find(filter *builds.BuildFilter) (*models.Build, error) { + b, err := s.processFilters(filter) if err != nil { return nil, err } - if len(builds) == 0 { - return nil, build.ErrBuildNotFound + if len(b) == 0 { + return nil, builds.ErrBuildNotFound } - return builds[0], nil + return b[0], nil } -func (s *InMemoryBuildStore) List(filter *build.Filter) ([]*build.Build, error) { +func (s *InMemoryBuildStore) List(filter *builds.BuildFilter) ([]*models.Build, error) { builds, err := s.processFilters(filter) if err != nil { return nil, err @@ -42,7 +43,7 @@ func (s *InMemoryBuildStore) List(filter *build.Filter) ([]*build.Build, error) return builds, nil } -func (s *InMemoryBuildStore) Save(result *build.Build) error { +func (s *InMemoryBuildStore) Save(result *models.Build) error { s.builds[result.Id] = result return nil } @@ -52,9 +53,9 @@ func (s *InMemoryBuildStore) Delete(id string) error { return nil } -func (s *InMemoryBuildStore) processFilters(filter *build.Filter) ([]*build.Build, error) { - var result []*build.Build - filteredBuilds := make(map[string]*build.Build) +func (s *InMemoryBuildStore) processFilters(filter *builds.BuildFilter) ([]*models.Build, error) { + var result []*models.Build + filteredBuilds := make(map[string]*models.Build) for k, v := range s.builds { filteredBuilds[k] = v } @@ -63,9 +64,9 @@ func (s *InMemoryBuildStore) processFilters(filter *build.Filter) ([]*build.Buil if filter.Id != nil { b, ok := s.builds[*filter.Id] if ok { - return []*build.Build{b}, nil + return []*models.Build{b}, nil } else { - return []*build.Build{}, fmt.Errorf("build with id %s not found", *filter.Id) + return []*models.Build{}, fmt.Errorf("build with id %s not found", *filter.Id) } } if filter.States != nil { @@ -97,7 +98,7 @@ func (s *InMemoryBuildStore) processFilters(filter *build.Filter) ([]*build.Buil } } if filter.GetNewest != nil && *filter.GetNewest { - var newestBuild *build.Build + var newestBuild *models.Build for _, b := range filteredBuilds { if newestBuild == nil { newestBuild = b @@ -108,7 +109,7 @@ func (s *InMemoryBuildStore) processFilters(filter *build.Filter) ([]*build.Buil } } if newestBuild != nil { - return []*build.Build{newestBuild}, nil + return []*models.Build{newestBuild}, nil } } if filter.BuildConfig != nil { diff --git a/internal/testing/docker/mocks/client.go b/internal/testing/docker/mocks/client.go index eea229c2ff..0b52a04ae6 100644 --- a/internal/testing/docker/mocks/client.go +++ b/internal/testing/docker/mocks/client.go @@ -8,10 +8,8 @@ package mocks import ( "io" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/mock" ) @@ -25,47 +23,47 @@ func NewMockClient() *MockClient { return &MockClient{} } -func (c *MockClient) CreateWorkspace(w *workspace.Workspace, serverDownloadUrl string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error { +func (c *MockClient) CreateWorkspace(w *models.Workspace, serverDownloadUrl string, cr *models.ContainerRegistry, logWriter io.Writer) error { args := c.Called(w, serverDownloadUrl, cr, logWriter) return args.Error(0) } -func (c *MockClient) CreateTarget(target *target.Target, logWriter io.Writer) error { +func (c *MockClient) CreateTarget(target *models.Target, logWriter io.Writer) error { args := c.Called(target, logWriter) return args.Error(0) } -func (c *MockClient) DestroyWorkspace(w *workspace.Workspace) error { +func (c *MockClient) DestroyWorkspace(w *models.Workspace) error { args := c.Called(w) return args.Error(0) } -func (c *MockClient) DestroyTarget(target *target.Target) error { +func (c *MockClient) DestroyTarget(target *models.Target) error { args := c.Called(target) return args.Error(0) } -func (c *MockClient) StartWorkspace(w *workspace.Workspace) error { +func (c *MockClient) StartWorkspace(w *models.Workspace) error { args := c.Called(w) return args.Error(0) } -func (c *MockClient) StopWorkspace(w *workspace.Workspace) error { +func (c *MockClient) StopWorkspace(w *models.Workspace) error { args := c.Called(w) return args.Error(0) } -func (c *MockClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.WorkspaceInfo, error) { +func (c *MockClient) GetWorkspaceInfo(w *models.Workspace) (*models.WorkspaceInfo, error) { args := c.Called(w) - return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) + return args.Get(0).(*models.WorkspaceInfo), args.Error(1) } -func (c *MockClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, error) { +func (c *MockClient) GetTargetInfo(t *models.Target) (*models.TargetInfo, error) { args := c.Called(t) - return args.Get(0).(*target.TargetInfo), args.Error(1) + return args.Get(0).(*models.TargetInfo), args.Error(1) } -func (c *MockClient) GetWorkspaceContainerName(w *workspace.Workspace) string { +func (c *MockClient) GetWorkspaceContainerName(w *models.Workspace) string { args := c.Called(w) return args.String(0) } diff --git a/internal/testing/git/mocks/gitservice.go b/internal/testing/git/mocks/gitservice.go index bdcf4e2ebd..5d96540435 100644 --- a/internal/testing/git/mocks/gitservice.go +++ b/internal/testing/git/mocks/gitservice.go @@ -7,7 +7,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/mock" ) @@ -31,14 +31,14 @@ func (m *MockGitService) RepositoryExists() (bool, error) { return args.Bool(0), args.Error(1) } -func (m *MockGitService) SetGitConfig(userData *gitprovider.GitUser, providerConfig *gitprovider.GitProviderConfig) error { +func (m *MockGitService) SetGitConfig(userData *gitprovider.GitUser, providerConfig *models.GitProviderConfig) error { args := m.Called(userData, providerConfig) return args.Error(0) } -func (m *MockGitService) GetGitStatus() (*workspace.GitStatus, error) { +func (m *MockGitService) GetGitStatus() (*models.GitStatus, error) { args := m.Called() - return args.Get(0).(*workspace.GitStatus), args.Error(1) + return args.Get(0).(*models.GitStatus), args.Error(1) } func NewMockGitService() *MockGitService { diff --git a/internal/testing/provider/targetconfigs/store.go b/internal/testing/provider/targetconfigs/store.go deleted file mode 100644 index a047dc16db..0000000000 --- a/internal/testing/provider/targetconfigs/store.go +++ /dev/null @@ -1,73 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package targetconfigs - -import ( - "fmt" - - "github.com/daytonaio/daytona/pkg/target/config" -) - -type InMemoryTargetConfigStore struct { - targetConfigs map[string]*config.TargetConfig -} - -func NewInMemoryTargetConfigStore() config.TargetConfigStore { - return &InMemoryTargetConfigStore{ - targetConfigs: make(map[string]*config.TargetConfig), - } -} - -func (s *InMemoryTargetConfigStore) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { - return s.processFilters(filter) -} - -func (s *InMemoryTargetConfigStore) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { - targetConfigs, err := s.processFilters(filter) - if err != nil { - return nil, err - } - if len(targetConfigs) == 0 { - return nil, config.ErrTargetConfigNotFound - } - - return targetConfigs[0], nil -} - -func (s *InMemoryTargetConfigStore) Save(targetConfig *config.TargetConfig) error { - s.targetConfigs[targetConfig.Name] = targetConfig - return nil -} - -func (s *InMemoryTargetConfigStore) Delete(targetConfig *config.TargetConfig) error { - delete(s.targetConfigs, targetConfig.Name) - return nil -} - -func (s *InMemoryTargetConfigStore) processFilters(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { - var result []*config.TargetConfig - targetConfigs := make(map[string]*config.TargetConfig) - for k, v := range s.targetConfigs { - targetConfigs[k] = v - } - - if filter != nil { - if filter.Name != nil { - targetConfig, ok := s.targetConfigs[*filter.Name] - if ok { - return []*config.TargetConfig{targetConfig}, nil - } else { - return []*config.TargetConfig{}, fmt.Errorf("target config with name %s not found", *filter.Name) - } - } - } - - for _, targetConfig := range targetConfigs { - result = append(result, targetConfig) - } - - return result, nil -} diff --git a/internal/testing/server/apikeys/store.go b/internal/testing/server/apikeys/store.go index 63fd23d0c9..528fd3d0cb 100644 --- a/internal/testing/server/apikeys/store.go +++ b/internal/testing/server/apikeys/store.go @@ -6,21 +6,22 @@ package apikeys import ( - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/apikeys" ) type InMemoryApiKeyStore struct { - apiKeys map[string]*apikey.ApiKey + apiKeys map[string]*models.ApiKey } -func NewInMemoryApiKeyStore() apikey.Store { +func NewInMemoryApiKeyStore() apikeys.ApiKeyStore { return &InMemoryApiKeyStore{ - apiKeys: make(map[string]*apikey.ApiKey), + apiKeys: make(map[string]*models.ApiKey), } } -func (s *InMemoryApiKeyStore) List() ([]*apikey.ApiKey, error) { - apiKeys := []*apikey.ApiKey{} +func (s *InMemoryApiKeyStore) List() ([]*models.ApiKey, error) { + apiKeys := []*models.ApiKey{} for _, a := range s.apiKeys { apiKeys = append(apiKeys, a) } @@ -28,16 +29,16 @@ func (s *InMemoryApiKeyStore) List() ([]*apikey.ApiKey, error) { return apiKeys, nil } -func (s *InMemoryApiKeyStore) Find(key string) (*apikey.ApiKey, error) { +func (s *InMemoryApiKeyStore) Find(key string) (*models.ApiKey, error) { apiKey, ok := s.apiKeys[key] if !ok { - return nil, apikey.ErrApiKeyNotFound + return nil, apikeys.ErrApiKeyNotFound } return apiKey, nil } -func (s *InMemoryApiKeyStore) FindByName(name string) (*apikey.ApiKey, error) { +func (s *InMemoryApiKeyStore) FindByName(name string) (*models.ApiKey, error) { for _, a := range s.apiKeys { if a.Name == name { return a, nil @@ -47,12 +48,12 @@ func (s *InMemoryApiKeyStore) FindByName(name string) (*apikey.ApiKey, error) { return nil, nil } -func (s *InMemoryApiKeyStore) Save(apiKey *apikey.ApiKey) error { +func (s *InMemoryApiKeyStore) Save(apiKey *models.ApiKey) error { s.apiKeys[apiKey.KeyHash] = apiKey return nil } -func (s *InMemoryApiKeyStore) Delete(apiKey *apikey.ApiKey) error { +func (s *InMemoryApiKeyStore) Delete(apiKey *models.ApiKey) error { delete(s.apiKeys, apiKey.KeyHash) return nil } diff --git a/internal/testing/server/containerregistries/store.go b/internal/testing/server/containerregistries/store.go index c3adb67066..8491ed60c3 100644 --- a/internal/testing/server/containerregistries/store.go +++ b/internal/testing/server/containerregistries/store.go @@ -6,21 +6,22 @@ package containerregistries import ( - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/containerregistries" ) type InMemoryContainerRegistryStore struct { - crs map[string]*containerregistry.ContainerRegistry + crs map[string]*models.ContainerRegistry } -func NewInMemoryContainerRegistryStore() containerregistry.Store { +func NewInMemoryContainerRegistryStore() containerregistries.ContainerRegistryStore { return &InMemoryContainerRegistryStore{ - crs: make(map[string]*containerregistry.ContainerRegistry), + crs: make(map[string]*models.ContainerRegistry), } } -func (s *InMemoryContainerRegistryStore) List() ([]*containerregistry.ContainerRegistry, error) { - crs := []*containerregistry.ContainerRegistry{} +func (s *InMemoryContainerRegistryStore) List() ([]*models.ContainerRegistry, error) { + crs := []*models.ContainerRegistry{} for _, cr := range s.crs { crs = append(crs, cr) } @@ -28,24 +29,24 @@ func (s *InMemoryContainerRegistryStore) List() ([]*containerregistry.ContainerR return crs, nil } -func (s *InMemoryContainerRegistryStore) Find(server string) (*containerregistry.ContainerRegistry, error) { +func (s *InMemoryContainerRegistryStore) Find(server string) (*models.ContainerRegistry, error) { cr, ok := s.crs[server] if !ok { - return nil, containerregistry.ErrContainerRegistryNotFound + return nil, containerregistries.ErrContainerRegistryNotFound } return cr, nil } -func (s *InMemoryContainerRegistryStore) Save(cr *containerregistry.ContainerRegistry) error { +func (s *InMemoryContainerRegistryStore) Save(cr *models.ContainerRegistry) error { s.crs[cr.Server] = cr return nil } -func (s *InMemoryContainerRegistryStore) Delete(cr *containerregistry.ContainerRegistry) error { +func (s *InMemoryContainerRegistryStore) Delete(cr *models.ContainerRegistry) error { _, ok := s.crs[cr.Server] if !ok { - return containerregistry.ErrContainerRegistryNotFound + return containerregistries.ErrContainerRegistryNotFound } delete(s.crs, cr.Server) return nil diff --git a/internal/testing/server/profiledata/store.go b/internal/testing/server/profiledata/store.go index 0f88efbc63..ffed06c22a 100644 --- a/internal/testing/server/profiledata/store.go +++ b/internal/testing/server/profiledata/store.go @@ -6,20 +6,21 @@ package profiledata import ( - "github.com/daytonaio/daytona/pkg/profiledata" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/profiledata" ) type InMemoryProfileDataStore struct { - profileData *profiledata.ProfileData + profileData *models.ProfileData } -func NewInMemoryProfileDataStore() profiledata.Store { +func NewInMemoryProfileDataStore() profiledata.ProfileDataStore { return &InMemoryProfileDataStore{ profileData: nil, } } -func (s *InMemoryProfileDataStore) Get() (*profiledata.ProfileData, error) { +func (s *InMemoryProfileDataStore) Get(id string) (*models.ProfileData, error) { if s.profileData == nil { return nil, profiledata.ErrProfileDataNotFound } @@ -27,12 +28,12 @@ func (s *InMemoryProfileDataStore) Get() (*profiledata.ProfileData, error) { return s.profileData, nil } -func (s *InMemoryProfileDataStore) Save(profileData *profiledata.ProfileData) error { +func (s *InMemoryProfileDataStore) Save(profileData *models.ProfileData) error { s.profileData = profileData return nil } -func (s *InMemoryProfileDataStore) Delete() error { +func (s *InMemoryProfileDataStore) Delete(id string) error { s.profileData = nil return nil } diff --git a/internal/testing/server/targetconfigs/store.go b/internal/testing/server/targetconfigs/store.go index 8bd545b2ad..c275c84d4f 100644 --- a/internal/testing/server/targetconfigs/store.go +++ b/internal/testing/server/targetconfigs/store.go @@ -8,55 +8,55 @@ package targetconfigs import ( "fmt" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" ) type InMemoryTargetConfigStore struct { - targetConfigs map[string]*config.TargetConfig + targetConfigs map[string]*models.TargetConfig } -func NewInMemoryTargetConfigStore() config.TargetConfigStore { +func NewInMemoryTargetConfigStore() targetconfigs.TargetConfigStore { return &InMemoryTargetConfigStore{ - targetConfigs: make(map[string]*config.TargetConfig), + targetConfigs: make(map[string]*models.TargetConfig), } } -func (s *InMemoryTargetConfigStore) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) List(filter *targetconfigs.TargetConfigFilter) ([]*models.TargetConfig, error) { return s.processFilters(filter) } -func (s *InMemoryTargetConfigStore) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) Find(filter *targetconfigs.TargetConfigFilter) (*models.TargetConfig, error) { targets, err := s.processFilters(filter) if err != nil { return nil, err } if len(targets) == 0 { - return nil, target.ErrTargetNotFound + return nil, targetconfigs.ErrTargetConfigNotFound } return targets[0], nil } -func (s *InMemoryTargetConfigStore) Save(targetConfig *config.TargetConfig) error { +func (s *InMemoryTargetConfigStore) Save(targetConfig *models.TargetConfig) error { s.targetConfigs[targetConfig.Name] = targetConfig return nil } -func (s *InMemoryTargetConfigStore) Delete(targetConfig *config.TargetConfig) error { +func (s *InMemoryTargetConfigStore) Delete(targetConfig *models.TargetConfig) error { delete(s.targetConfigs, targetConfig.Name) return nil } -func (s *InMemoryTargetConfigStore) processFilters(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { - var result []*config.TargetConfig +func (s *InMemoryTargetConfigStore) processFilters(filter *targetconfigs.TargetConfigFilter) ([]*models.TargetConfig, error) { + var result []*models.TargetConfig if filter != nil { if filter.Name != nil { t, ok := s.targetConfigs[*filter.Name] if ok { - return []*config.TargetConfig{t}, nil + return []*models.TargetConfig{t}, nil } else { return nil, fmt.Errorf("target config with id or name %s not found", *filter.Name) } diff --git a/internal/testing/server/targets/mocks/api_key_service.go b/internal/testing/server/targets/mocks/api_key_service.go index 340d53d02e..716719a280 100644 --- a/internal/testing/server/targets/mocks/api_key_service.go +++ b/internal/testing/server/targets/mocks/api_key_service.go @@ -6,7 +6,7 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/mock" ) @@ -18,7 +18,7 @@ func NewMockApiKeyService() *mockApiKeyService { return &mockApiKeyService{} } -func (s *mockApiKeyService) Generate(keyType apikey.ApiKeyType, name string) (string, error) { +func (s *mockApiKeyService) Generate(keyType models.ApiKeyType, name string) (string, error) { args := s.Called(keyType, name) return args.String(0), args.Error(1) } @@ -38,9 +38,9 @@ func (s *mockApiKeyService) IsTargetApiKey(apiKey string) bool { return args.Bool(0) } -func (s *mockApiKeyService) ListClientKeys() ([]*apikey.ApiKey, error) { +func (s *mockApiKeyService) ListClientKeys() ([]*models.ApiKey, error) { args := s.Called() - return args.Get(0).([]*apikey.ApiKey), args.Error(1) + return args.Get(0).([]*models.ApiKey), args.Error(1) } func (s *mockApiKeyService) Revoke(name string) error { diff --git a/internal/testing/server/targets/mocks/build_service.go b/internal/testing/server/targets/mocks/build_service.go index 4e91444b0a..ee29eb788e 100644 --- a/internal/testing/server/targets/mocks/build_service.go +++ b/internal/testing/server/targets/mocks/build_service.go @@ -9,7 +9,8 @@ import ( "io" "time" - "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/builds/dto" "github.com/stretchr/testify/mock" ) @@ -27,17 +28,17 @@ func (m *MockBuildService) Create(createBuildDto dto.BuildCreationData) (string, return args.String(0), args.Error(1) } -func (m *MockBuildService) Find(filter *build.Filter) (*build.Build, error) { +func (m *MockBuildService) Find(filter *builds.BuildFilter) (*models.Build, error) { args := m.Called(filter) - return args.Get(0).(*build.Build), args.Error(1) + return args.Get(0).(*models.Build), args.Error(1) } -func (m *MockBuildService) List(filter *build.Filter) ([]*build.Build, error) { +func (m *MockBuildService) List(filter *builds.BuildFilter) ([]*models.Build, error) { args := m.Called(filter) - return args.Get(0).([]*build.Build), args.Error(1) + return args.Get(0).([]*models.Build), args.Error(1) } -func (m *MockBuildService) MarkForDeletion(filter *build.Filter, force bool) []error { +func (m *MockBuildService) MarkForDeletion(filter *builds.BuildFilter, force bool) []error { args := m.Called(filter, force) return args.Get(0).([]error) } diff --git a/internal/testing/server/targets/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go index 04b637d924..40e98387f1 100644 --- a/internal/testing/server/targets/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -9,21 +9,20 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/mock" ) -var MockBuild = &build.Build{ +var MockBuild = &models.Build{ Id: "1", - State: build.BuildStatePendingRun, + State: models.BuildStatePendingRun, Image: util.Pointer("image"), User: util.Pointer("user"), - ContainerConfig: containerconfig.ContainerConfig{ + ContainerConfig: models.ContainerConfig{ Image: "test", User: "test", }, - BuildConfig: &buildconfig.BuildConfig{ + BuildConfig: &models.BuildConfig{ Devcontainer: MockWorkspaceConfig.BuildConfig.Devcontainer, }, Repository: &gitprovider.GitRepository{ @@ -36,21 +35,21 @@ type MockBuilderFactory struct { mock.Mock } -func (f *MockBuilderFactory) Create(build build.Build, workspaceDir string) (build.IBuilder, error) { +func (f *MockBuilderFactory) Create(build models.Build, workspaceDir string) (build.IBuilder, error) { args := f.Called(build, workspaceDir) return args.Get(0).(*MockBuilder), args.Error(1) } -func (f *MockBuilderFactory) CheckExistingBuild(b build.Build) (*build.Build, error) { +func (f *MockBuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, error) { args := f.Called(b) - return args.Get(0).(*build.Build), args.Error(1) + return args.Get(0).(*models.Build), args.Error(1) } type MockBuilder struct { mock.Mock } -func (b *MockBuilder) Build(build build.Build) (string, string, error) { +func (b *MockBuilder) Build(build models.Build) (string, string, error) { args := b.Called(build) return args.String(0), args.String(1), args.Error(2) } @@ -60,17 +59,17 @@ func (b *MockBuilder) CleanUp() error { return args.Error(0) } -func (b *MockBuilder) Publish(build build.Build) error { +func (b *MockBuilder) Publish(build models.Build) error { args := b.Called(build) return args.Error(0) } -func (b *MockBuilder) SaveBuild(r build.Build) error { +func (b *MockBuilder) SaveBuild(r models.Build) error { args := b.Called(r) return args.Error(0) } -func (b *MockBuilder) GetImageName(build build.Build) (string, error) { +func (b *MockBuilder) GetImageName(build models.Build) (string, error) { args := b.Called(build) return args.String(0), args.Error(1) } diff --git a/internal/testing/server/targets/mocks/container_registry_service.go b/internal/testing/server/targets/mocks/container_registry_service.go index b172c80115..86768e5c99 100644 --- a/internal/testing/server/targets/mocks/container_registry_service.go +++ b/internal/testing/server/targets/mocks/container_registry_service.go @@ -6,7 +6,7 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/mock" ) @@ -23,27 +23,27 @@ func (m *mockContainerRegistryService) Delete(server string) error { return args.Error(0) } -func (m *mockContainerRegistryService) Find(server string) (*containerregistry.ContainerRegistry, error) { +func (m *mockContainerRegistryService) Find(server string) (*models.ContainerRegistry, error) { args := m.Called(server) - return args.Get(0).(*containerregistry.ContainerRegistry), args.Error(1) + return args.Get(0).(*models.ContainerRegistry), args.Error(1) } -func (m *mockContainerRegistryService) FindByImageName(imageName string) (*containerregistry.ContainerRegistry, error) { +func (m *mockContainerRegistryService) FindByImageName(imageName string) (*models.ContainerRegistry, error) { args := m.Called(imageName) - return args.Get(0).(*containerregistry.ContainerRegistry), args.Error(1) + return args.Get(0).(*models.ContainerRegistry), args.Error(1) } -func (m *mockContainerRegistryService) List() ([]*containerregistry.ContainerRegistry, error) { +func (m *mockContainerRegistryService) List() ([]*models.ContainerRegistry, error) { args := m.Called() - return args.Get(0).([]*containerregistry.ContainerRegistry), args.Error(1) + return args.Get(0).([]*models.ContainerRegistry), args.Error(1) } -func (m *mockContainerRegistryService) Map() (map[string]*containerregistry.ContainerRegistry, error) { +func (m *mockContainerRegistryService) Map() (map[string]*models.ContainerRegistry, error) { args := m.Called() - return args.Get(0).(map[string]*containerregistry.ContainerRegistry), args.Error(1) + return args.Get(0).(map[string]*models.ContainerRegistry), args.Error(1) } -func (m *mockContainerRegistryService) Save(cr *containerregistry.ContainerRegistry) error { +func (m *mockContainerRegistryService) Save(cr *models.ContainerRegistry) error { args := m.Called(cr) return args.Error(0) } diff --git a/internal/testing/server/targets/mocks/git_provider_service.go b/internal/testing/server/targets/mocks/git_provider_service.go index a58a54c763..d8cedef6bf 100644 --- a/internal/testing/server/targets/mocks/git_provider_service.go +++ b/internal/testing/server/targets/mocks/git_provider_service.go @@ -9,6 +9,7 @@ import ( "net/http" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/mock" ) @@ -20,14 +21,14 @@ func NewMockGitProviderService() *MockGitProviderService { return &MockGitProviderService{} } -func (m *MockGitProviderService) GetConfig(id string) (*gitprovider.GitProviderConfig, error) { +func (m *MockGitProviderService) GetConfig(id string) (*models.GitProviderConfig, error) { args := m.Called(id) - return args.Get(0).(*gitprovider.GitProviderConfig), args.Error(1) + return args.Get(0).(*models.GitProviderConfig), args.Error(1) } -func (m *MockGitProviderService) ListConfigsForUrl(url string) ([]*gitprovider.GitProviderConfig, error) { +func (m *MockGitProviderService) ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) { args := m.Called(url) - return args.Get(0).([]*gitprovider.GitProviderConfig), args.Error(1) + return args.Get(0).([]*models.GitProviderConfig), args.Error(1) } func (m *MockGitProviderService) GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) { @@ -70,9 +71,9 @@ func (m *MockGitProviderService) GetRepositories(gitProviderId string, namespace return args.Get(0).([]*gitprovider.GitRepository), args.Error(1) } -func (m *MockGitProviderService) ListConfigs() ([]*gitprovider.GitProviderConfig, error) { +func (m *MockGitProviderService) ListConfigs() ([]*models.GitProviderConfig, error) { args := m.Called() - return args.Get(0).([]*gitprovider.GitProviderConfig), args.Error(1) + return args.Get(0).([]*models.GitProviderConfig), args.Error(1) } func (m *MockGitProviderService) RemoveGitProvider(gitProviderId string) error { @@ -80,7 +81,7 @@ func (m *MockGitProviderService) RemoveGitProvider(gitProviderId string) error { return args.Error(0) } -func (m *MockGitProviderService) SetGitProviderConfig(providerConfig *gitprovider.GitProviderConfig) error { +func (m *MockGitProviderService) SetGitProviderConfig(providerConfig *models.GitProviderConfig) error { args := m.Called(providerConfig) return args.Error(0) } diff --git a/internal/testing/server/targets/mocks/provisioner.go b/internal/testing/server/targets/mocks/provisioner.go index 743f3cf5aa..c227cc21c4 100644 --- a/internal/testing/server/targets/mocks/provisioner.go +++ b/internal/testing/server/targets/mocks/provisioner.go @@ -8,9 +8,8 @@ package mocks import ( "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/stretchr/testify/mock" ) @@ -27,24 +26,24 @@ func (p *mockProvisioner) CreateWorkspace(params provisioner.WorkspaceParams) er return args.Error(0) } -func (p *mockProvisioner) CreateTarget(t *target.Target) error { +func (p *mockProvisioner) CreateTarget(t *models.Target) error { args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) DestroyWorkspace(ws *workspace.Workspace, t *target.Target) error { - args := p.Called(ws, t) +func (p *mockProvisioner) DestroyWorkspace(ws *models.Workspace) error { + args := p.Called(ws) return args.Error(0) } -func (p *mockProvisioner) DestroyTarget(t *target.Target) error { +func (p *mockProvisioner) DestroyTarget(t *models.Target) error { args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) GetTargetInfo(ctx context.Context, t *target.Target) (*target.TargetInfo, error) { +func (p *mockProvisioner) GetTargetInfo(ctx context.Context, t *models.Target) (*models.TargetInfo, error) { args := p.Called(ctx, t) - return args.Get(0).(*target.TargetInfo), args.Error(1) + return args.Get(0).(*models.TargetInfo), args.Error(1) } func (p *mockProvisioner) StartWorkspace(params provisioner.WorkspaceParams) error { @@ -52,22 +51,22 @@ func (p *mockProvisioner) StartWorkspace(params provisioner.WorkspaceParams) err return args.Error(0) } -func (p *mockProvisioner) StartTarget(t *target.Target) error { +func (p *mockProvisioner) StartTarget(t *models.Target) error { args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) StopWorkspace(ws *workspace.Workspace, t *target.Target) error { - args := p.Called(ws, t) +func (p *mockProvisioner) StopWorkspace(ws *models.Workspace) error { + args := p.Called(ws) return args.Error(0) } -func (p *mockProvisioner) StopTarget(t *target.Target) error { +func (p *mockProvisioner) StopTarget(t *models.Target) error { args := p.Called(t) return args.Error(0) } -func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *workspace.Workspace, t *target.Target) (*workspace.WorkspaceInfo, error) { - args := p.Called(ctx, w, t) - return args.Get(0).(*workspace.WorkspaceInfo), args.Error(1) +func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *models.Workspace) (*models.WorkspaceInfo, error) { + args := p.Called(ctx, w) + return args.Get(0).(*models.WorkspaceInfo), args.Error(1) } diff --git a/internal/testing/server/targets/mocks/workspace_config.go b/internal/testing/server/targets/mocks/workspace_config.go index c1c239d01f..fad49d0e7e 100644 --- a/internal/testing/server/targets/mocks/workspace_config.go +++ b/internal/testing/server/targets/mocks/workspace_config.go @@ -6,13 +6,12 @@ package mocks import ( - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/models" ) -var MockWorkspaceConfig = config.WorkspaceConfig{ - BuildConfig: &buildconfig.BuildConfig{ - Devcontainer: &buildconfig.DevcontainerConfig{ +var MockWorkspaceConfig = models.WorkspaceConfig{ + BuildConfig: &models.BuildConfig{ + Devcontainer: &models.DevcontainerConfig{ FilePath: ".devcontainer/devcontainer.json", }, }, diff --git a/internal/testing/server/targets/mocks/workspace_config_service.go b/internal/testing/server/targets/mocks/workspace_config_service.go index adc65f422a..4fbecb774c 100644 --- a/internal/testing/server/targets/mocks/workspace_config_service.go +++ b/internal/testing/server/targets/mocks/workspace_config_service.go @@ -7,8 +7,9 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" "github.com/stretchr/testify/mock" ) @@ -25,14 +26,14 @@ func (m *mockWorkspaceConfigService) Delete(name string, force bool) []error { return args.Get(0).([]error) } -func (m *mockWorkspaceConfigService) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { +func (m *mockWorkspaceConfigService) Find(filter *workspaceconfigs.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { args := m.Called(filter) - return args.Get(0).(*config.WorkspaceConfig), args.Error(1) + return args.Get(0).(*models.WorkspaceConfig), args.Error(1) } -func (m *mockWorkspaceConfigService) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { +func (m *mockWorkspaceConfigService) List(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { args := m.Called(filter) - return args.Get(0).([]*config.WorkspaceConfig), args.Error(1) + return args.Get(0).([]*models.WorkspaceConfig), args.Error(1) } func (m *mockWorkspaceConfigService) SetDefault(name string) error { @@ -40,7 +41,7 @@ func (m *mockWorkspaceConfigService) SetDefault(name string) error { return args.Error(0) } -func (m *mockWorkspaceConfigService) Save(wc *config.WorkspaceConfig) error { +func (m *mockWorkspaceConfigService) Save(wc *models.WorkspaceConfig) error { args := m.Called(wc) return args.Error(0) } @@ -50,12 +51,12 @@ func (m *mockWorkspaceConfigService) SetPrebuild(workspaceConfigName string, cre return args.Get(0).(*dto.PrebuildDTO), args.Error(1) } -func (m *mockWorkspaceConfigService) FindPrebuild(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) { +func (m *mockWorkspaceConfigService) FindPrebuild(workspaceConfigFilter *workspaceconfigs.WorkspaceConfigFilter, prebuildFilter *workspaceconfigs.PrebuildFilter) (*dto.PrebuildDTO, error) { args := m.Called(workspaceConfigFilter, prebuildFilter) return args.Get(0).(*dto.PrebuildDTO), args.Error(1) } -func (m *mockWorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (m *mockWorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *workspaceconfigs.WorkspaceConfigFilter, prebuildFilter *workspaceconfigs.PrebuildFilter) ([]*dto.PrebuildDTO, error) { args := m.Called(workspaceConfigFilter, prebuildFilter) return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) } diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go index 4bdea399f2..061c20d00a 100644 --- a/internal/testing/server/targets/store.go +++ b/internal/testing/server/targets/store.go @@ -8,37 +8,38 @@ package targets import ( "fmt" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targets" ) type InMemoryTargetStore struct { - targets map[string]*target.Target + targets map[string]*models.Target } -func NewInMemoryTargetStore() target.Store { +func NewInMemoryTargetStore() targets.TargetStore { return &InMemoryTargetStore{ - targets: make(map[string]*target.Target), + targets: make(map[string]*models.Target), } } -func (s *InMemoryTargetStore) List(filter *target.TargetFilter) ([]*target.TargetViewDTO, error) { +func (s *InMemoryTargetStore) List(filter *targets.TargetFilter) ([]*models.Target, error) { return s.processFilters(filter) } -func (s *InMemoryTargetStore) Find(filter *target.TargetFilter) (*target.TargetViewDTO, error) { - targets, err := s.processFilters(filter) +func (s *InMemoryTargetStore) Find(filter *targets.TargetFilter) (*models.Target, error) { + t, err := s.processFilters(filter) if err != nil { return nil, err } - if len(targets) == 0 { - return nil, target.ErrTargetNotFound + if len(t) == 0 { + return nil, targets.ErrTargetNotFound } - return targets[0], nil + return t[0], nil } -func (s *InMemoryTargetStore) Save(target *target.Target) error { +func (s *InMemoryTargetStore) Save(target *models.Target) error { tg := *target tg.EnvVars = nil tg.ApiKey = "" @@ -47,27 +48,25 @@ func (s *InMemoryTargetStore) Save(target *target.Target) error { return nil } -func (s *InMemoryTargetStore) Delete(target *target.Target) error { +func (s *InMemoryTargetStore) Delete(target *models.Target) error { delete(s.targets, target.Id) return nil } -func (s *InMemoryTargetStore) processFilters(filter *target.TargetFilter) ([]*target.TargetViewDTO, error) { - var result []*target.TargetViewDTO - filteredTargets := make(map[string]*target.TargetViewDTO) +func (s *InMemoryTargetStore) processFilters(filter *targets.TargetFilter) ([]*models.Target, error) { + var result []*models.Target + filteredTargets := make(map[string]*models.Target) for k, v := range s.targets { - filteredTargets[k] = &target.TargetViewDTO{ - Target: *v, - } + filteredTargets[k] = v } if filter != nil { if filter.IdOrName != nil { t, ok := s.targets[*filter.IdOrName] if ok { - return []*target.TargetViewDTO{{Target: *t}}, nil + return []*models.Target{t}, nil } else { - return []*target.TargetViewDTO{}, fmt.Errorf("target with id or name %s not found", *filter.IdOrName) + return []*models.Target{}, fmt.Errorf("target with id or name %s not found", *filter.IdOrName) } } if filter.Default != nil { diff --git a/internal/testing/server/workspaceconfig/store.go b/internal/testing/server/workspaceconfig/store.go index 747031ca45..989b243a8a 100644 --- a/internal/testing/server/workspaceconfig/store.go +++ b/internal/testing/server/workspaceconfig/store.go @@ -8,48 +8,49 @@ package workspaceconfig import ( "fmt" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" ) type InMemoryWorkspaceConfigStore struct { - workspaceConfigs map[string]*config.WorkspaceConfig + workspaceConfigs map[string]*models.WorkspaceConfig } -func NewInMemoryWorkspaceConfigStore() config.Store { +func NewInMemoryWorkspaceConfigStore() workspaceconfigs.WorkspaceConfigStore { return &InMemoryWorkspaceConfigStore{ - workspaceConfigs: make(map[string]*config.WorkspaceConfig), + workspaceConfigs: make(map[string]*models.WorkspaceConfig), } } -func (s *InMemoryWorkspaceConfigStore) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { +func (s *InMemoryWorkspaceConfigStore) List(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { return s.processFilters(filter) } -func (s *InMemoryWorkspaceConfigStore) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { +func (s *InMemoryWorkspaceConfigStore) Find(filter *workspaceconfigs.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { workspaceConfigs, err := s.processFilters(filter) if err != nil { return nil, err } if len(workspaceConfigs) == 0 { - return nil, config.ErrWorkspaceConfigNotFound + return nil, workspaceconfigs.ErrWorkspaceConfigNotFound } return workspaceConfigs[0], nil } -func (s *InMemoryWorkspaceConfigStore) Save(workspaceConfig *config.WorkspaceConfig) error { +func (s *InMemoryWorkspaceConfigStore) Save(workspaceConfig *models.WorkspaceConfig) error { s.workspaceConfigs[workspaceConfig.Name] = workspaceConfig return nil } -func (s *InMemoryWorkspaceConfigStore) Delete(workspaceConfig *config.WorkspaceConfig) error { +func (s *InMemoryWorkspaceConfigStore) Delete(workspaceConfig *models.WorkspaceConfig) error { delete(s.workspaceConfigs, workspaceConfig.Name) return nil } -func (s *InMemoryWorkspaceConfigStore) processFilters(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { - var result []*config.WorkspaceConfig - filteredWorkspaceConfigs := make(map[string]*config.WorkspaceConfig) +func (s *InMemoryWorkspaceConfigStore) processFilters(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { + var result []*models.WorkspaceConfig + filteredWorkspaceConfigs := make(map[string]*models.WorkspaceConfig) for k, v := range s.workspaceConfigs { filteredWorkspaceConfigs[k] = v } @@ -58,9 +59,9 @@ func (s *InMemoryWorkspaceConfigStore) processFilters(filter *config.WorkspaceCo if filter.Name != nil { workspaceConfig, ok := s.workspaceConfigs[*filter.Name] if ok { - return []*config.WorkspaceConfig{workspaceConfig}, nil + return []*models.WorkspaceConfig{workspaceConfig}, nil } else { - return []*config.WorkspaceConfig{}, fmt.Errorf("workspace config with name %s not found", *filter.Name) + return []*models.WorkspaceConfig{}, fmt.Errorf("workspace config with name %s not found", *filter.Name) } } if filter.Url != nil { diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go index fa705ebaa4..c382a9f134 100644 --- a/internal/testing/server/workspaces/store.go +++ b/internal/testing/server/workspaces/store.go @@ -5,47 +5,50 @@ package workspaces -import "github.com/daytonaio/daytona/pkg/workspace" +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaces" +) type InMemoryWorkspaceStore struct { - workspaces map[string]*workspace.Workspace + workspaces map[string]*models.Workspace } -func NewInMemoryWorkspaceStore() workspace.Store { +func NewInMemoryWorkspaceStore() workspaces.WorkspaceStore { return &InMemoryWorkspaceStore{ - workspaces: make(map[string]*workspace.Workspace), + workspaces: make(map[string]*models.Workspace), } } -func (s *InMemoryWorkspaceStore) List() ([]*workspace.WorkspaceViewDTO, error) { - workspaceViewDTOs := []*workspace.WorkspaceViewDTO{} +func (s *InMemoryWorkspaceStore) List() ([]*models.Workspace, error) { + workspaces := []*models.Workspace{} for _, w := range s.workspaces { - workspaceViewDTOs = append(workspaceViewDTOs, &workspace.WorkspaceViewDTO{Workspace: *w}) + workspaces = append(workspaces, w) } - return workspaceViewDTOs, nil + return workspaces, nil } -func (s *InMemoryWorkspaceStore) Find(idOrName string) (*workspace.WorkspaceViewDTO, error) { - t, ok := s.workspaces[idOrName] +func (s *InMemoryWorkspaceStore) Find(idOrName string) (*models.Workspace, error) { + w, ok := s.workspaces[idOrName] if !ok { for _, w := range s.workspaces { if w.Name == idOrName { - return &workspace.WorkspaceViewDTO{Workspace: *w}, nil + return w, nil } } - return nil, workspace.ErrWorkspaceNotFound + return nil, workspaces.ErrWorkspaceNotFound } - return &workspace.WorkspaceViewDTO{Workspace: *t}, nil + return w, nil } -func (s *InMemoryWorkspaceStore) Save(workspace *workspace.Workspace) error { +func (s *InMemoryWorkspaceStore) Save(workspace *models.Workspace) error { s.workspaces[workspace.Id] = workspace return nil } -func (s *InMemoryWorkspaceStore) Delete(workspace *workspace.Workspace) error { +func (s *InMemoryWorkspaceStore) Delete(workspace *models.Workspace) error { delete(s.workspaces, workspace.Id) return nil } diff --git a/internal/util/apiclient/conversion/target_config.go b/internal/util/apiclient/conversion/target_config.go index 40a9fcee15..91a9931e2c 100644 --- a/internal/util/apiclient/conversion/target_config.go +++ b/internal/util/apiclient/conversion/target_config.go @@ -4,12 +4,12 @@ package conversion import ( + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" - "github.com/daytonaio/daytona/pkg/target/config" ) -func ToTargetConfig(createTargetConfigDto dto.CreateTargetConfigDTO) *config.TargetConfig { - return &config.TargetConfig{ +func ToTargetConfig(createTargetConfigDto dto.CreateTargetConfigDTO) *models.TargetConfig { + return &models.TargetConfig{ Name: createTargetConfigDto.Name, ProviderInfo: createTargetConfigDto.ProviderInfo, Options: createTargetConfigDto.Options, diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go index c28a74c0f2..285521da2d 100644 --- a/internal/util/apiclient/conversion/workspace.go +++ b/internal/util/apiclient/conversion/workspace.go @@ -6,14 +6,12 @@ package conversion import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" - wc_dto "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" + "github.com/daytonaio/daytona/pkg/models" + wc_dto "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" workspace_dto "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/config" ) -func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *workspace.Workspace { +func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { if workspaceDTO == nil { return nil } @@ -29,27 +27,27 @@ func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *workspace.Workspace { Url: workspaceDTO.Repository.Url, } - var workspaceState *workspace.WorkspaceState + var workspaceState *models.WorkspaceState if workspaceDTO.State != nil { uptime := workspaceDTO.State.Uptime - workspaceState = &workspace.WorkspaceState{ + workspaceState = &models.WorkspaceState{ UpdatedAt: workspaceDTO.State.UpdatedAt, Uptime: uint64(uptime), GitStatus: ToGitStatus(workspaceDTO.State.GitStatus), } } - var workspaceBuild *buildconfig.BuildConfig + var workspaceBuild *models.BuildConfig if workspaceDTO.BuildConfig != nil { - workspaceBuild = &buildconfig.BuildConfig{} + workspaceBuild = &models.BuildConfig{} if workspaceDTO.BuildConfig.Devcontainer != nil { - workspaceBuild.Devcontainer = &buildconfig.DevcontainerConfig{ + workspaceBuild.Devcontainer = &models.DevcontainerConfig{ FilePath: workspaceDTO.BuildConfig.Devcontainer.FilePath, } } } - workspace := &workspace.Workspace{ + workspace := &models.Workspace{ Id: workspaceDTO.Id, Name: workspaceDTO.Name, Image: workspaceDTO.Image, @@ -69,16 +67,16 @@ func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *workspace.Workspace { return workspace } -func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *workspace.GitStatus { +func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *models.GitStatus { if gitStatusDTO == nil { return nil } - files := []*workspace.FileStatus{} + files := []*models.FileStatus{} for _, fileDTO := range gitStatusDTO.FileStatus { - staging := workspace.Status(string(fileDTO.Staging)) - worktree := workspace.Status(string(fileDTO.Worktree)) - file := &workspace.FileStatus{ + staging := models.Status(string(fileDTO.Staging)) + worktree := models.Status(string(fileDTO.Worktree)) + file := &models.FileStatus{ Name: fileDTO.Name, Extra: fileDTO.Extra, Staging: staging, @@ -100,7 +98,7 @@ func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *workspace.GitStatus { branchPublished = *gitStatusDTO.BranchPublished } - return &workspace.GitStatus{ + return &models.GitStatus{ CurrentBranch: gitStatusDTO.CurrentBranch, Files: files, BranchPublished: branchPublished, @@ -109,7 +107,7 @@ func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *workspace.GitStatus { } } -func ToGitStatusDTO(gitStatus *workspace.GitStatus) *apiclient.GitStatus { +func ToGitStatusDTO(gitStatus *models.GitStatus) *apiclient.GitStatus { if gitStatus == nil { return nil } @@ -151,8 +149,8 @@ func ToGitStatusDTO(gitStatus *workspace.GitStatus) *apiclient.GitStatus { } } -func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) *config.WorkspaceConfig { - result := &config.WorkspaceConfig{ +func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) *models.WorkspaceConfig { + result := &models.WorkspaceConfig{ Name: createWorkspaceConfigDto.Name, BuildConfig: createWorkspaceConfigDto.BuildConfig, EnvVars: createWorkspaceConfigDto.EnvVars, @@ -172,8 +170,8 @@ func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) return result } -func CreateDtoToWorkspace(createWorkspaceDto workspace_dto.CreateWorkspaceDTO) *workspace.Workspace { - w := &workspace.Workspace{ +func CreateDtoToWorkspace(createWorkspaceDto workspace_dto.CreateWorkspaceDTO) *models.Workspace { + w := &models.Workspace{ Id: createWorkspaceDto.Id, Name: createWorkspaceDto.Name, BuildConfig: createWorkspaceDto.BuildConfig, @@ -193,17 +191,3 @@ func CreateDtoToWorkspace(createWorkspaceDto workspace_dto.CreateWorkspaceDTO) * return w } - -func CreateConfigDtoToWorkspace(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) *workspace.Workspace { - return &workspace.Workspace{ - Name: createWorkspaceConfigDto.Name, - Image: *createWorkspaceConfigDto.Image, - User: *createWorkspaceConfigDto.User, - BuildConfig: createWorkspaceConfigDto.BuildConfig, - GitProviderConfigId: createWorkspaceConfigDto.GitProviderConfigId, - Repository: &gitprovider.GitRepository{ - Url: createWorkspaceConfigDto.RepositoryUrl, - }, - EnvVars: createWorkspaceConfigDto.EnvVars, - } -} diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 542e79a981..8ebf68d8fc 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -19,7 +19,7 @@ import ( agent_config "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/go-git/go-git/v5/plumbing/transport/http" log "github.com/sirupsen/logrus" ) @@ -125,10 +125,10 @@ func (a *Agent) startWorkspaceMode() error { } } - var providerConfig *gitprovider.GitProviderConfig + var providerConfig *models.GitProviderConfig if gitProvider != nil { - providerConfig = &gitprovider.GitProviderConfig{ - SigningMethod: (*gitprovider.SigningMethod)(gitProvider.SigningMethod), + providerConfig = &models.GitProviderConfig{ + SigningMethod: (*models.SigningMethod)(gitProvider.SigningMethod), SigningKey: gitProvider.SigningKey, } } @@ -227,7 +227,7 @@ func (a *Agent) updateWorkspaceState() error { return err } - var gitStatus *workspace.GitStatus + var gitStatus *models.GitStatus if a.Config.SkipClone == "" { var err error gitStatus, err = a.Git.GetGitStatus() diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 0a0b8e5021..ddfeeb7261 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -16,11 +16,10 @@ import ( "github.com/daytonaio/daytona/pkg/agent" "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" ) -var workspace1 = &workspace.Workspace{ +var workspace1 = &models.Workspace{ Id: "123", Name: "test", Repository: &gitprovider.GitRepository{ @@ -29,30 +28,30 @@ var workspace1 = &workspace.Workspace{ Name: "daytona", }, TargetId: "123", - State: &workspace.WorkspaceState{ + State: &models.WorkspaceState{ UpdatedAt: "123", Uptime: 148, GitStatus: gitStatus1, }, } -var target1 = &target.Target{ +var target1 = &models.Target{ Id: "123", Name: "test", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, Options: "test-options", } -var gitStatus1 = &workspace.GitStatus{ +var gitStatus1 = &models.GitStatus{ CurrentBranch: "main", - Files: []*workspace.FileStatus{{ + Files: []*models.FileStatus{{ Name: "File1", Extra: "", - Staging: workspace.Modified, - Worktree: workspace.Modified, + Staging: models.Modified, + Worktree: models.Modified, }}, } diff --git a/pkg/agent/types.go b/pkg/agent/types.go index 02405a531f..1756e47f3a 100644 --- a/pkg/agent/types.go +++ b/pkg/agent/types.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/config" "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" ) type SshServer interface { @@ -33,5 +33,5 @@ type Agent struct { LogWriter io.Writer TelemetryEnabled bool startTime time.Time - Workspace *workspace.Workspace + Workspace *models.Workspace } diff --git a/pkg/api/controllers/apikey/generate.go b/pkg/api/controllers/apikey/generate.go index 2d4fe8fa56..25b3aeba2d 100644 --- a/pkg/api/controllers/apikey/generate.go +++ b/pkg/api/controllers/apikey/generate.go @@ -7,7 +7,7 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -28,7 +28,7 @@ func GenerateApiKey(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.ApiKeyService.Generate(apikey.ApiKeyTypeClient, apiKeyName) + response, err := server.ApiKeyService.Generate(models.ApiKeyTypeClient, apiKeyName) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get API keys: %w", err)) return diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index 2b724d0e16..5f35bbcaf9 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -10,11 +10,11 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/api/controllers/build/dto" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/builds" builds_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/gin-gonic/gin" ) @@ -39,7 +39,7 @@ func CreateBuild(ctx *gin.Context) { s := server.GetInstance(nil) - workspaceConfig, err := s.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := s.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ Name: &createBuildDto.WorkspaceConfigName, }) if err != nil { @@ -99,12 +99,12 @@ func GetBuild(ctx *gin.Context) { server := server.GetInstance(nil) - b, err := server.BuildService.Find(&build.Filter{ + b, err := server.BuildService.Find(&builds.BuildFilter{ Id: &buildId, }) if err != nil { statusCode := http.StatusInternalServerError - if build.IsBuildNotFound(err) { + if builds.IsBuildNotFound(err) { statusCode = http.StatusNotFound } ctx.AbortWithError(statusCode, fmt.Errorf("failed to find build: %w", err)) @@ -200,7 +200,7 @@ func DeleteBuild(ctx *gin.Context) { server := server.GetInstance(nil) - errs := server.BuildService.MarkForDeletion(&build.Filter{ + errs := server.BuildService.MarkForDeletion(&builds.BuildFilter{ Id: &buildId, }, force) if len(errs) > 0 { @@ -242,7 +242,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { server := server.GetInstance(nil) // Fail if prebuild does not exist - _, err = server.WorkspaceConfigService.FindPrebuild(nil, &config.PrebuildFilter{ + _, err = server.WorkspaceConfigService.FindPrebuild(nil, &workspaceconfigs.PrebuildFilter{ Id: &prebuildId, }) if err != nil { @@ -250,7 +250,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { return } - errs := server.BuildService.MarkForDeletion(&build.Filter{ + errs := server.BuildService.MarkForDeletion(&builds.BuildFilter{ PrebuildIds: &[]string{prebuildId}, }, force) if len(errs) > 0 { diff --git a/pkg/api/controllers/containerregistry/set.go b/pkg/api/controllers/containerregistry/set.go index aadb0e63a0..21c6197d97 100644 --- a/pkg/api/controllers/containerregistry/set.go +++ b/pkg/api/controllers/containerregistry/set.go @@ -8,7 +8,7 @@ import ( "net/http" "net/url" - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -33,7 +33,7 @@ func SetContainerRegistry(ctx *gin.Context) { return } - var req containerregistry.ContainerRegistry + var req models.ContainerRegistry err = ctx.BindJSON(&req) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) diff --git a/pkg/api/controllers/gitprovider/dto/dto.go b/pkg/api/controllers/gitprovider/dto/dto.go index 9a46b18219..217d058487 100644 --- a/pkg/api/controllers/gitprovider/dto/dto.go +++ b/pkg/api/controllers/gitprovider/dto/dto.go @@ -4,7 +4,7 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" ) type RepositoryUrl struct { @@ -12,12 +12,12 @@ type RepositoryUrl struct { } // @name RepositoryUrl type SetGitProviderConfig struct { - Id string `json:"id" validate:"optional"` - ProviderId string `json:"providerId" validate:"required"` - Username *string `json:"username,omitempty" validate:"optional"` - Token string `json:"token" validate:"required"` - BaseApiUrl *string `json:"baseApiUrl,omitempty" validate:"optional"` - Alias *string `json:"alias,omitempty" validate:"optional"` - SigningKey *string `json:"signingKey,omitempty" validate:"optional"` - SigningMethod *gitprovider.SigningMethod `json:"signingMethod,omitempty" validate:"optional"` + Id string `json:"id" validate:"optional"` + ProviderId string `json:"providerId" validate:"required"` + Username *string `json:"username,omitempty" validate:"optional"` + Token string `json:"token" validate:"required"` + BaseApiUrl *string `json:"baseApiUrl,omitempty" validate:"optional"` + Alias *string `json:"alias,omitempty" validate:"optional"` + SigningKey *string `json:"signingKey,omitempty" validate:"optional"` + SigningMethod *models.SigningMethod `json:"signingMethod,omitempty" validate:"optional"` } // @name SetGitProviderConfig diff --git a/pkg/api/controllers/gitprovider/gitprovider.go b/pkg/api/controllers/gitprovider/gitprovider.go index 004422b20f..75ffa842bc 100644 --- a/pkg/api/controllers/gitprovider/gitprovider.go +++ b/pkg/api/controllers/gitprovider/gitprovider.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers" "github.com/daytonaio/daytona/pkg/api/controllers/gitprovider/dto" - "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -25,12 +25,12 @@ import ( // @Summary List Git providers // @Description List Git providers // @Produce json -// @Success 200 {array} gitprovider.GitProviderConfig +// @Success 200 {array} models.GitProviderConfig // @Router /gitprovider [get] // // @id ListGitProviders func ListGitProviders(ctx *gin.Context) { - var response []*gitprovider.GitProviderConfig + var response []*models.GitProviderConfig server := server.GetInstance(nil) @@ -55,7 +55,7 @@ func ListGitProviders(ctx *gin.Context) { // @Description List Git providers for url // @Produce json // @Param url path string true "Url" -// @Success 200 {array} gitprovider.GitProviderConfig +// @Success 200 {array} models.GitProviderConfig // @Router /gitprovider/for-url/{url} [get] // // @id ListGitProvidersForUrl @@ -77,7 +77,7 @@ func ListGitProvidersForUrl(ctx *gin.Context) { } apiKeyType, ok := ctx.Get("apiKeyType") - if !ok || apiKeyType == apikey.ApiKeyTypeClient { + if !ok || apiKeyType == models.ApiKeyTypeClient { for _, gitProvider := range gitProviders { gitProvider.Token = "" } @@ -93,7 +93,7 @@ func ListGitProvidersForUrl(ctx *gin.Context) { // @Description Get Git provider // @Produce plain // @Param gitProviderId path string true "ID" -// @Success 200 {object} gitprovider.GitProviderConfig +// @Success 200 {object} models.GitProviderConfig // @Router /gitprovider/{gitProviderId} [get] // // @id GetGitProvider @@ -113,7 +113,7 @@ func GetGitProvider(ctx *gin.Context) { } apiKeyType, ok := ctx.Get("apiKeyType") - if !ok || apiKeyType == apikey.ApiKeyTypeClient { + if !ok || apiKeyType == models.ApiKeyTypeClient { gitProvider.Token = "" } @@ -175,7 +175,7 @@ func SetGitProvider(ctx *gin.Context) { return } - gitProviderConfig := gitprovider.GitProviderConfig{ + gitProviderConfig := models.GitProviderConfig{ Id: setConfigDto.Id, ProviderId: setConfigDto.ProviderId, Token: setConfigDto.Token, diff --git a/pkg/api/controllers/profiledata/profile_data.go b/pkg/api/controllers/profiledata/profile_data.go index 1101a96fe2..1a38f73b22 100644 --- a/pkg/api/controllers/profiledata/profile_data.go +++ b/pkg/api/controllers/profiledata/profile_data.go @@ -7,8 +7,9 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/pkg/profiledata" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/gin-gonic/gin" ) @@ -18,16 +19,16 @@ import ( // @Summary Get profile data // @Description Get profile data // @Accept json -// @Success 200 {object} profiledata.ProfileData +// @Success 200 {object} models.ProfileData // @Router /profile [get] // // @id GetProfileData func GetProfileData(ctx *gin.Context) { server := server.GetInstance(nil) - profileData, err := server.ProfileDataService.Get() + profileData, err := server.ProfileDataService.Get("") if err != nil { if profiledata.IsProfileDataNotFound(err) { - ctx.JSON(200, &profiledata.ProfileData{}) + ctx.JSON(200, &models.ProfileData{}) return } ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get profile data: %w", err)) @@ -43,13 +44,13 @@ func GetProfileData(ctx *gin.Context) { // @Summary Set profile data // @Description Set profile data // @Accept json -// @Param profileData body profiledata.ProfileData true "Profile data" +// @Param profileData body models.ProfileData true "Profile data" // @Success 201 // @Router /profile [put] // // @id SetProfileData func SetProfileData(ctx *gin.Context) { - var req profiledata.ProfileData + var req models.ProfileData err := ctx.BindJSON(&req) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) @@ -77,7 +78,7 @@ func SetProfileData(ctx *gin.Context) { // @id DeleteProfileData func DeleteProfileData(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.ProfileDataService.Delete() + err := server.ProfileDataService.Delete("") if err != nil { if profiledata.IsProfileDataNotFound(err) { ctx.Status(204) diff --git a/pkg/api/controllers/target/dto/dto.go b/pkg/api/controllers/target/dto/dto.go index cc9237f7d9..28a8c45fe3 100644 --- a/pkg/api/controllers/target/dto/dto.go +++ b/pkg/api/controllers/target/dto/dto.go @@ -3,9 +3,9 @@ package dto -import "github.com/daytonaio/daytona/pkg/workspace" +import "github.com/daytonaio/daytona/pkg/models" type SetWorkspaceState struct { - Uptime uint64 `json:"uptime" validate:"required"` - GitStatus *workspace.GitStatus `json:"gitStatus,omitempty" validate:"optional"` + Uptime uint64 `json:"uptime" validate:"required"` + GitStatus *models.GitStatus `json:"gitStatus,omitempty" validate:"optional"` } // @name SetWorkspaceState diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index 75741efca8..af1fed1adb 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/server/targets" "github.com/gin-gonic/gin" ) @@ -43,7 +43,7 @@ func GetTarget(ctx *gin.Context) { server := server.GetInstance(nil) - t, err := server.TargetService.GetTarget(ctx.Request.Context(), &target.TargetFilter{IdOrName: &targetId}, verbose) + t, err := server.TargetService.GetTarget(ctx.Request.Context(), &targets.TargetFilter{IdOrName: &targetId}, verbose) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get target: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/remove.go index d38c41ef1d..8e101b171b 100644 --- a/pkg/api/controllers/targetconfig/remove.go +++ b/pkg/api/controllers/targetconfig/remove.go @@ -8,7 +8,7 @@ import ( "net/http" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/target/config" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/gin-gonic/gin" ) @@ -27,7 +27,7 @@ func RemoveTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfig, err := server.TargetConfigService.Find(&config.TargetConfigFilter{ + targetConfig, err := server.TargetConfigService.Find(&targetconfigs.TargetConfigFilter{ Name: &configName, }) if err != nil { diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go index 4d0740cbb7..25e744badb 100644 --- a/pkg/api/controllers/workspace/create.go +++ b/pkg/api/controllers/workspace/create.go @@ -19,7 +19,7 @@ import ( // @Description Create a workspace // @Param workspace body CreateWorkspaceDTO true "Create workspace" // @Produce json -// @Success 200 {object} WorkspaceViewDTO +// @Success 200 {object} Workspace // @Router /workspace [post] // // @id CreateWorkspace diff --git a/pkg/api/controllers/workspace/dto/dto.go b/pkg/api/controllers/workspace/dto/dto.go index cc9237f7d9..d2ad79480b 100644 --- a/pkg/api/controllers/workspace/dto/dto.go +++ b/pkg/api/controllers/workspace/dto/dto.go @@ -3,9 +3,11 @@ package dto -import "github.com/daytonaio/daytona/pkg/workspace" +import ( + "github.com/daytonaio/daytona/pkg/models" +) type SetWorkspaceState struct { - Uptime uint64 `json:"uptime" validate:"required"` - GitStatus *workspace.GitStatus `json:"gitStatus,omitempty" validate:"optional"` + Uptime uint64 `json:"uptime" validate:"required"` + GitStatus *models.GitStatus `json:"gitStatus,omitempty" validate:"optional"` } // @name SetWorkspaceState diff --git a/pkg/api/controllers/workspace/state.go b/pkg/api/controllers/workspace/state.go index 8db98f4255..b86edee39b 100644 --- a/pkg/api/controllers/workspace/state.go +++ b/pkg/api/controllers/workspace/state.go @@ -9,8 +9,8 @@ import ( "time" "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/gin-gonic/gin" ) @@ -37,7 +37,7 @@ func SetWorkspaceState(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.WorkspaceService.SetWorkspaceState(workspaceId, &workspace.WorkspaceState{ + _, err = server.WorkspaceService.SetWorkspaceState(workspaceId, &models.WorkspaceState{ Uptime: setWorkspaceStateDTO.Uptime, UpdatedAt: time.Now().Format(time.RFC1123), GitStatus: setWorkspaceStateDTO.GitStatus, diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index c5a650d247..5e2bd97ff3 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -17,7 +17,6 @@ import ( "github.com/daytonaio/daytona/pkg/agent/toolbox/config" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) @@ -61,7 +60,7 @@ func forwardRequestToToolbox(ctx *gin.Context) { var client *http.Client var websocketDialer *websocket.Dialer - workspaceHostname := workspace.GetWorkspaceHostname(w.Id) + workspaceHostname := w.Hostname() route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/toolbox/", workspaceId), "", 1) query := ctx.Request.URL.Query().Encode() diff --git a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go index 34ad0c16ff..de8676e589 100644 --- a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go +++ b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go @@ -10,8 +10,8 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" "github.com/gin-gonic/gin" ) @@ -32,13 +32,13 @@ func GetPrebuild(ctx *gin.Context) { prebuildId := ctx.Param("prebuildId") server := server.GetInstance(nil) - res, err := server.WorkspaceConfigService.FindPrebuild(&config.WorkspaceConfigFilter{ + res, err := server.WorkspaceConfigService.FindPrebuild(&workspaceconfigs.WorkspaceConfigFilter{ Name: &configName, - }, &config.PrebuildFilter{ + }, &workspaceconfigs.PrebuildFilter{ Id: &prebuildId, }) if err != nil { - if config.IsPrebuildNotFound(err) { + if workspaceconfigs.IsPrebuildNotFound(err) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) return } @@ -116,10 +116,10 @@ func ListPrebuilds(ctx *gin.Context) { func ListPrebuildsForWorkspaceConfig(ctx *gin.Context) { configName := ctx.Param("configName") - var workspaceConfigFilter *config.WorkspaceConfigFilter + var workspaceConfigFilter *workspaceconfigs.WorkspaceConfigFilter if configName != "" { - workspaceConfigFilter = &config.WorkspaceConfigFilter{ + workspaceConfigFilter = &workspaceconfigs.WorkspaceConfigFilter{ Name: &configName, } } @@ -166,7 +166,7 @@ func DeletePrebuild(ctx *gin.Context) { server := server.GetInstance(nil) errs := server.WorkspaceConfigService.DeletePrebuild(configName, prebuildId, force) if len(errs) > 0 { - if config.IsPrebuildNotFound(errs[0]) { + if workspaceconfigs.IsPrebuildNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) return } diff --git a/pkg/api/controllers/workspaceconfig/workspace_config.go b/pkg/api/controllers/workspaceconfig/workspace_config.go index 059e38ea6e..a7cd3d2ccd 100644 --- a/pkg/api/controllers/workspaceconfig/workspace_config.go +++ b/pkg/api/controllers/workspaceconfig/workspace_config.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) @@ -35,7 +35,7 @@ func GetWorkspaceConfig(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceConfig, err := server.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := server.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ Name: &configName, }) if err != nil { @@ -68,13 +68,13 @@ func GetDefaultWorkspaceConfig(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceConfigs, err := server.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + workspaceConfigs, err := server.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ Url: &decodedURLParam, Default: util.Pointer(true), }) if err != nil { statusCode := http.StatusInternalServerError - if config.IsWorkspaceConfigNotFound(err) { + if workspaceconfigs.IsWorkspaceConfigNotFound(err) { statusCode = http.StatusNotFound ctx.AbortWithStatus(statusCode) log.Debugf("Workspace config not added for git url: %s", decodedURLParam) @@ -193,7 +193,7 @@ func DeleteWorkspaceConfig(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceConfig, err := server.WorkspaceConfigService.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := server.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ Name: &configName, }) if err != nil { @@ -203,7 +203,7 @@ func DeleteWorkspaceConfig(ctx *gin.Context) { errs := server.WorkspaceConfigService.Delete(workspaceConfig.Name, force) if len(errs) > 0 { - if config.IsWorkspaceConfigNotFound(errs[0]) { + if workspaceconfigs.IsWorkspaceConfigNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("workspace config not found")) return } diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index b36993c22a..973819ca35 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1480,7 +1480,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceViewDTO" + "$ref": "#/definitions/Workspace" } } } @@ -3339,7 +3339,7 @@ const docTemplate = `{ "type": "string" }, "type": { - "$ref": "#/definitions/apikey.ApiKeyType" + "$ref": "#/definitions/models.ApiKeyType" } } }, @@ -3384,7 +3384,7 @@ const docTemplate = `{ "$ref": "#/definitions/GitRepository" }, "state": { - "$ref": "#/definitions/build.BuildState" + "$ref": "#/definitions/models.BuildState" }, "updatedAt": { "type": "string" @@ -4515,7 +4515,8 @@ const docTemplate = `{ "ProfileData": { "type": "object", "required": [ - "envVars" + "envVars", + "id" ], "properties": { "envVars": { @@ -4523,6 +4524,9 @@ const docTemplate = `{ "additionalProperties": { "type": "string" } + }, + "id": { + "type": "string" } } }, @@ -4848,6 +4852,12 @@ const docTemplate = `{ }, "providerInfo": { "$ref": "#/definitions/TargetProviderInfo" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/Workspace" + } } } }, @@ -4921,8 +4931,7 @@ const docTemplate = `{ "id", "name", "options", - "providerInfo", - "workspaceCount" + "providerInfo" ], "properties": { "default": { @@ -4944,8 +4953,11 @@ const docTemplate = `{ "providerInfo": { "$ref": "#/definitions/TargetProviderInfo" }, - "workspaceCount": { - "type": "integer" + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/Workspace" + } } } }, @@ -4981,6 +4993,57 @@ const docTemplate = `{ } } }, + "Workspace": { + "type": "object", + "required": [ + "envVars", + "id", + "image", + "name", + "repository", + "target", + "targetId", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repository": { + "$ref": "#/definitions/GitRepository" + }, + "state": { + "$ref": "#/definitions/WorkspaceState" + }, + "target": { + "$ref": "#/definitions/Target" + }, + "targetId": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, "WorkspaceConfig": { "type": "object", "required": [ @@ -5035,8 +5098,8 @@ const docTemplate = `{ "image", "name", "repository", + "target", "targetId", - "targetName", "user" ], "properties": { @@ -5070,10 +5133,10 @@ const docTemplate = `{ "state": { "$ref": "#/definitions/WorkspaceState" }, - "targetId": { - "type": "string" + "target": { + "$ref": "#/definitions/Target" }, - "targetName": { + "targetId": { "type": "string" }, "user": { @@ -5133,58 +5196,7 @@ const docTemplate = `{ } } }, - "WorkspaceViewDTO": { - "type": "object", - "required": [ - "envVars", - "id", - "image", - "name", - "repository", - "targetId", - "targetName", - "user" - ], - "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { - "type": "string" - }, - "id": { - "type": "string" - }, - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "repository": { - "$ref": "#/definitions/GitRepository" - }, - "state": { - "$ref": "#/definitions/WorkspaceState" - }, - "targetId": { - "type": "string" - }, - "targetName": { - "type": "string" - }, - "user": { - "type": "string" - } - } - }, - "apikey.ApiKeyType": { + "models.ApiKeyType": { "type": "string", "enum": [ "client", @@ -5197,7 +5209,7 @@ const docTemplate = `{ "ApiKeyTypeTarget" ] }, - "build.BuildState": { + "models.BuildState": { "type": "string", "enum": [ "pending-run", diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index eb26c4ed7e..bb8f19e3fd 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1477,7 +1477,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceViewDTO" + "$ref": "#/definitions/Workspace" } } } @@ -3336,7 +3336,7 @@ "type": "string" }, "type": { - "$ref": "#/definitions/apikey.ApiKeyType" + "$ref": "#/definitions/models.ApiKeyType" } } }, @@ -3381,7 +3381,7 @@ "$ref": "#/definitions/GitRepository" }, "state": { - "$ref": "#/definitions/build.BuildState" + "$ref": "#/definitions/models.BuildState" }, "updatedAt": { "type": "string" @@ -4512,7 +4512,8 @@ "ProfileData": { "type": "object", "required": [ - "envVars" + "envVars", + "id" ], "properties": { "envVars": { @@ -4520,6 +4521,9 @@ "additionalProperties": { "type": "string" } + }, + "id": { + "type": "string" } } }, @@ -4845,6 +4849,12 @@ }, "providerInfo": { "$ref": "#/definitions/TargetProviderInfo" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/Workspace" + } } } }, @@ -4918,8 +4928,7 @@ "id", "name", "options", - "providerInfo", - "workspaceCount" + "providerInfo" ], "properties": { "default": { @@ -4941,8 +4950,11 @@ "providerInfo": { "$ref": "#/definitions/TargetProviderInfo" }, - "workspaceCount": { - "type": "integer" + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/Workspace" + } } } }, @@ -4978,6 +4990,57 @@ } } }, + "Workspace": { + "type": "object", + "required": [ + "envVars", + "id", + "image", + "name", + "repository", + "target", + "targetId", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "repository": { + "$ref": "#/definitions/GitRepository" + }, + "state": { + "$ref": "#/definitions/WorkspaceState" + }, + "target": { + "$ref": "#/definitions/Target" + }, + "targetId": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, "WorkspaceConfig": { "type": "object", "required": [ @@ -5032,8 +5095,8 @@ "image", "name", "repository", + "target", "targetId", - "targetName", "user" ], "properties": { @@ -5067,10 +5130,10 @@ "state": { "$ref": "#/definitions/WorkspaceState" }, - "targetId": { - "type": "string" + "target": { + "$ref": "#/definitions/Target" }, - "targetName": { + "targetId": { "type": "string" }, "user": { @@ -5130,58 +5193,7 @@ } } }, - "WorkspaceViewDTO": { - "type": "object", - "required": [ - "envVars", - "id", - "image", - "name", - "repository", - "targetId", - "targetName", - "user" - ], - "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { - "type": "string" - }, - "id": { - "type": "string" - }, - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "repository": { - "$ref": "#/definitions/GitRepository" - }, - "state": { - "$ref": "#/definitions/WorkspaceState" - }, - "targetId": { - "type": "string" - }, - "targetName": { - "type": "string" - }, - "user": { - "type": "string" - } - } - }, - "apikey.ApiKeyType": { + "models.ApiKeyType": { "type": "string", "enum": [ "client", @@ -5194,7 +5206,7 @@ "ApiKeyTypeTarget" ] }, - "build.BuildState": { + "models.BuildState": { "type": "string", "enum": [ "pending-run", diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index b0d9c48adc..4739285a9e 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -8,7 +8,7 @@ definitions: description: Workspace or client name type: string type: - $ref: '#/definitions/apikey.ApiKeyType' + $ref: '#/definitions/models.ApiKeyType' required: - keyHash - name @@ -35,7 +35,7 @@ definitions: repository: $ref: '#/definitions/GitRepository' state: - $ref: '#/definitions/build.BuildState' + $ref: '#/definitions/models.BuildState' updatedAt: type: string user: @@ -815,8 +815,11 @@ definitions: additionalProperties: type: string type: object + id: + type: string required: - envVars + - id type: object Provider: properties: @@ -1037,6 +1040,10 @@ definitions: type: string providerInfo: $ref: '#/definitions/TargetProviderInfo' + workspaces: + items: + $ref: '#/definitions/Workspace' + type: array required: - default - id @@ -1109,15 +1116,16 @@ definitions: type: string providerInfo: $ref: '#/definitions/TargetProviderInfo' - workspaceCount: - type: integer + workspaces: + items: + $ref: '#/definitions/Workspace' + type: array required: - default - id - name - options - providerInfo - - workspaceCount type: object TargetInfo: properties: @@ -1140,6 +1148,42 @@ definitions: - name - version type: object + Workspace: + properties: + buildConfig: + $ref: '#/definitions/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + id: + type: string + image: + type: string + name: + type: string + repository: + $ref: '#/definitions/GitRepository' + state: + $ref: '#/definitions/WorkspaceState' + target: + $ref: '#/definitions/Target' + targetId: + type: string + user: + type: string + required: + - envVars + - id + - image + - name + - repository + - target + - targetId + - user + type: object WorkspaceConfig: properties: buildConfig: @@ -1194,10 +1238,10 @@ definitions: $ref: '#/definitions/GitRepository' state: $ref: '#/definitions/WorkspaceState' + target: + $ref: '#/definitions/Target' targetId: type: string - targetName: - type: string user: type: string required: @@ -1206,8 +1250,8 @@ definitions: - image - name - repository + - target - targetId - - targetName - user type: object WorkspaceDirResponse: @@ -1245,43 +1289,7 @@ definitions: - updatedAt - uptime type: object - WorkspaceViewDTO: - properties: - buildConfig: - $ref: '#/definitions/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - id: - type: string - image: - type: string - name: - type: string - repository: - $ref: '#/definitions/GitRepository' - state: - $ref: '#/definitions/WorkspaceState' - targetId: - type: string - targetName: - type: string - user: - type: string - required: - - envVars - - id - - image - - name - - repository - - targetId - - targetName - - user - type: object - apikey.ApiKeyType: + models.ApiKeyType: enum: - client - workspace @@ -1291,7 +1299,7 @@ definitions: - ApiKeyTypeClient - ApiKeyTypeWorkspace - ApiKeyTypeTarget - build.BuildState: + models.BuildState: enum: - pending-run - running @@ -2313,7 +2321,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/WorkspaceViewDTO' + $ref: '#/definitions/Workspace' summary: Create a workspace tags: - workspace diff --git a/pkg/api/middlewares/auth.go b/pkg/api/middlewares/auth.go index 80b3e09aa8..1074e4879c 100644 --- a/pkg/api/middlewares/auth.go +++ b/pkg/api/middlewares/auth.go @@ -7,7 +7,7 @@ import ( "errors" "strings" - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -33,12 +33,12 @@ func AuthMiddleware() gin.HandlerFunc { return } - apiKeyType := apikey.ApiKeyTypeClient + apiKeyType := models.ApiKeyTypeClient if server.ApiKeyService.IsTargetApiKey(token) { - apiKeyType = apikey.ApiKeyTypeTarget + apiKeyType = models.ApiKeyTypeTarget } else if server.ApiKeyService.IsWorkspaceApiKey(token) { - apiKeyType = apikey.ApiKeyTypeWorkspace + apiKeyType = models.ApiKeyTypeWorkspace } ctx.Set("apiKeyType", apiKeyType) diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 42388bf53f..bbb0792fa8 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -184,9 +184,7 @@ Class | Method | HTTP request | Description ## Documentation For Models - [ApiKey](docs/ApiKey.md) - - [ApikeyApiKeyType](docs/ApikeyApiKeyType.md) - [Build](docs/Build.md) - - [BuildBuildState](docs/BuildBuildState.md) - [BuildConfig](docs/BuildConfig.md) - [CachedBuild](docs/CachedBuild.md) - [CloneTarget](docs/CloneTarget.md) @@ -236,6 +234,8 @@ Class | Method | HTTP request | Description - [LspServerRequest](docs/LspServerRequest.md) - [LspSymbol](docs/LspSymbol.md) - [Match](docs/Match.md) + - [ModelsApiKeyType](docs/ModelsApiKeyType.md) + - [ModelsBuildState](docs/ModelsBuildState.md) - [NetworkKey](docs/NetworkKey.md) - [Position](docs/Position.md) - [PrebuildConfig](docs/PrebuildConfig.md) @@ -262,12 +262,12 @@ Class | Method | HTTP request | Description - [TargetDTO](docs/TargetDTO.md) - [TargetInfo](docs/TargetInfo.md) - [TargetProviderInfo](docs/TargetProviderInfo.md) + - [Workspace](docs/Workspace.md) - [WorkspaceConfig](docs/WorkspaceConfig.md) - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) - [WorkspaceInfo](docs/WorkspaceInfo.md) - [WorkspaceState](docs/WorkspaceState.md) - - [WorkspaceViewDTO](docs/WorkspaceViewDTO.md) ## Documentation For Authorization diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index c41c44a1ff..947e26b745 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -1052,7 +1052,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/WorkspaceViewDTO' + $ref: '#/components/schemas/Workspace' description: OK summary: Create a workspace tags: @@ -2425,7 +2425,7 @@ components: description: Workspace or client name type: string type: - $ref: '#/components/schemas/apikey.ApiKeyType' + $ref: '#/components/schemas/models.ApiKeyType' required: - keyHash - name @@ -2482,7 +2482,7 @@ components: repository: $ref: '#/components/schemas/GitRepository' state: - $ref: '#/components/schemas/build.BuildState' + $ref: '#/components/schemas/models.BuildState' updatedAt: type: string user: @@ -3599,13 +3599,17 @@ components: example: envVars: key: envVars + id: id properties: envVars: additionalProperties: type: string type: object + id: + type: string required: - envVars + - id type: object Provider: example: @@ -3911,6 +3915,9 @@ components: name: name options: options id: id + workspaces: + - null + - null providerInfo: name: name label: label @@ -3927,6 +3934,10 @@ components: type: string providerInfo: $ref: '#/components/schemas/TargetProviderInfo' + workspaces: + items: + $ref: '#/components/schemas/Workspace' + type: array required: - default - id @@ -3996,8 +4007,116 @@ components: default: true name: name options: options - workspaceCount: 0 id: id + workspaces: + - buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + targetId: targetId + envVars: + key: envVars + name: name + id: id + state: + gitStatus: + behind: 6 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 0 + branchPublished: true + currentBranch: currentBranch + updatedAt: updatedAt + uptime: 1 + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + user: user + target: + default: true + name: name + options: options + id: id + workspaces: + - null + - null + providerInfo: + name: name + label: label + version: version + - buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + targetId: targetId + envVars: + key: envVars + name: name + id: id + state: + gitStatus: + behind: 6 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 0 + branchPublished: true + currentBranch: currentBranch + updatedAt: updatedAt + uptime: 1 + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + user: user + target: + default: true + name: name + options: options + id: id + workspaces: + - null + - null + providerInfo: + name: name + label: label + version: version info: providerMetadata: providerMetadata name: name @@ -4019,15 +4138,16 @@ components: type: string providerInfo: $ref: '#/components/schemas/TargetProviderInfo' - workspaceCount: - type: integer + workspaces: + items: + $ref: '#/components/schemas/Workspace' + type: array required: - default - id - name - options - providerInfo - - workspaceCount type: object TargetInfo: example: @@ -4057,6 +4177,97 @@ components: - name - version type: object + Workspace: + example: + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + targetId: targetId + envVars: + key: envVars + name: name + id: id + state: + gitStatus: + behind: 6 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 0 + branchPublished: true + currentBranch: currentBranch + updatedAt: updatedAt + uptime: 1 + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url + user: user + target: + default: true + name: name + options: options + id: id + workspaces: + - null + - null + providerInfo: + name: name + label: label + version: version + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + id: + type: string + image: + type: string + name: + type: string + repository: + $ref: '#/components/schemas/GitRepository' + state: + $ref: '#/components/schemas/WorkspaceState' + target: + $ref: '#/components/schemas/Target' + targetId: + type: string + user: + type: string + required: + - envVars + - id + - image + - name + - repository + - target + - targetId + - user + type: object WorkspaceConfig: example: prebuilds: @@ -4129,7 +4340,6 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image - targetName: targetName targetId: targetId envVars: key: envVars @@ -4170,6 +4380,18 @@ components: isRunning: true created: created name: name + target: + default: true + name: name + options: options + id: id + workspaces: + - null + - null + providerInfo: + name: name + label: label + version: version properties: buildConfig: $ref: '#/components/schemas/BuildConfig' @@ -4191,10 +4413,10 @@ components: $ref: '#/components/schemas/GitRepository' state: $ref: '#/components/schemas/WorkspaceState' + target: + $ref: '#/components/schemas/Target' targetId: type: string - targetName: - type: string user: type: string required: @@ -4203,8 +4425,8 @@ components: - image - name - repository + - target - targetId - - targetName - user type: object WorkspaceDirResponse: @@ -4267,87 +4489,7 @@ components: - updatedAt - uptime type: object - WorkspaceViewDTO: - example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - targetName: targetName - targetId: targetId - envVars: - key: envVars - name: name - id: id - state: - gitStatus: - behind: 6 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 0 - branchPublished: true - currentBranch: currentBranch - updatedAt: updatedAt - uptime: 1 - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url - user: user - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - id: - type: string - image: - type: string - name: - type: string - repository: - $ref: '#/components/schemas/GitRepository' - state: - $ref: '#/components/schemas/WorkspaceState' - targetId: - type: string - targetName: - type: string - user: - type: string - required: - - envVars - - id - - image - - name - - repository - - targetId - - targetName - - user - type: object - apikey.ApiKeyType: + models.ApiKeyType: enum: - client - workspace @@ -4357,7 +4499,7 @@ components: - ApiKeyTypeClient - ApiKeyTypeWorkspace - ApiKeyTypeTarget - build.BuildState: + models.BuildState: enum: - pending-run - running diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index 60a311eec9..c19aaf9215 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -34,7 +34,7 @@ func (r ApiCreateWorkspaceRequest) Workspace(workspace CreateWorkspaceDTO) ApiCr return r } -func (r ApiCreateWorkspaceRequest) Execute() (*WorkspaceViewDTO, *http.Response, error) { +func (r ApiCreateWorkspaceRequest) Execute() (*Workspace, *http.Response, error) { return r.ApiService.CreateWorkspaceExecute(r) } @@ -55,13 +55,13 @@ func (a *WorkspaceAPIService) CreateWorkspace(ctx context.Context) ApiCreateWork // Execute executes the request // -// @return WorkspaceViewDTO -func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest) (*WorkspaceViewDTO, *http.Response, error) { +// @return Workspace +func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest) (*Workspace, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile - localVarReturnValue *WorkspaceViewDTO + localVarReturnValue *Workspace ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.CreateWorkspace") diff --git a/pkg/apiclient/docs/ApiKey.md b/pkg/apiclient/docs/ApiKey.md index 996156ee0a..15ad2efb40 100644 --- a/pkg/apiclient/docs/ApiKey.md +++ b/pkg/apiclient/docs/ApiKey.md @@ -6,13 +6,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **KeyHash** | **string** | | **Name** | **string** | Workspace or client name | -**Type** | [**ApikeyApiKeyType**](ApikeyApiKeyType.md) | | +**Type** | [**ModelsApiKeyType**](ModelsApiKeyType.md) | | ## Methods ### NewApiKey -`func NewApiKey(keyHash string, name string, type_ ApikeyApiKeyType, ) *ApiKey` +`func NewApiKey(keyHash string, name string, type_ ModelsApiKeyType, ) *ApiKey` NewApiKey instantiates a new ApiKey object This constructor will assign default values to properties that have it defined, @@ -69,20 +69,20 @@ SetName sets Name field to given value. ### GetType -`func (o *ApiKey) GetType() ApikeyApiKeyType` +`func (o *ApiKey) GetType() ModelsApiKeyType` GetType returns the Type field if non-nil, zero value otherwise. ### GetTypeOk -`func (o *ApiKey) GetTypeOk() (*ApikeyApiKeyType, bool)` +`func (o *ApiKey) GetTypeOk() (*ModelsApiKeyType, bool)` GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetType -`func (o *ApiKey) SetType(v ApikeyApiKeyType)` +`func (o *ApiKey) SetType(v ModelsApiKeyType)` SetType sets Type field to given value. diff --git a/pkg/apiclient/docs/Build.md b/pkg/apiclient/docs/Build.md index e020561cf3..690ad8d492 100644 --- a/pkg/apiclient/docs/Build.md +++ b/pkg/apiclient/docs/Build.md @@ -12,7 +12,7 @@ Name | Type | Description | Notes **Image** | Pointer to **string** | | [optional] **PrebuildId** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | -**State** | [**BuildBuildState**](BuildBuildState.md) | | +**State** | [**ModelsBuildState**](ModelsBuildState.md) | | **UpdatedAt** | **string** | | **User** | Pointer to **string** | | [optional] @@ -20,7 +20,7 @@ Name | Type | Description | Notes ### NewBuild -`func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state BuildBuildState, updatedAt string, ) *Build` +`func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ModelsBuildState, updatedAt string, ) *Build` NewBuild instantiates a new Build object This constructor will assign default values to properties that have it defined, @@ -207,20 +207,20 @@ SetRepository sets Repository field to given value. ### GetState -`func (o *Build) GetState() BuildBuildState` +`func (o *Build) GetState() ModelsBuildState` GetState returns the State field if non-nil, zero value otherwise. ### GetStateOk -`func (o *Build) GetStateOk() (*BuildBuildState, bool)` +`func (o *Build) GetStateOk() (*ModelsBuildState, bool)` GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetState -`func (o *Build) SetState(v BuildBuildState)` +`func (o *Build) SetState(v ModelsBuildState)` SetState sets State field to given value. diff --git a/pkg/apiclient/docs/ApikeyApiKeyType.md b/pkg/apiclient/docs/ModelsApiKeyType.md similarity index 94% rename from pkg/apiclient/docs/ApikeyApiKeyType.md rename to pkg/apiclient/docs/ModelsApiKeyType.md index 3471cb39b8..28da6f6fb4 100644 --- a/pkg/apiclient/docs/ApikeyApiKeyType.md +++ b/pkg/apiclient/docs/ModelsApiKeyType.md @@ -1,4 +1,4 @@ -# ApikeyApiKeyType +# ModelsApiKeyType ## Enum diff --git a/pkg/apiclient/docs/BuildBuildState.md b/pkg/apiclient/docs/ModelsBuildState.md similarity index 96% rename from pkg/apiclient/docs/BuildBuildState.md rename to pkg/apiclient/docs/ModelsBuildState.md index 8a8b6a9b71..fe1a303454 100644 --- a/pkg/apiclient/docs/BuildBuildState.md +++ b/pkg/apiclient/docs/ModelsBuildState.md @@ -1,4 +1,4 @@ -# BuildBuildState +# ModelsBuildState ## Enum diff --git a/pkg/apiclient/docs/ProfileAPI.md b/pkg/apiclient/docs/ProfileAPI.md index 45e45d2fad..d28d60ab8e 100644 --- a/pkg/apiclient/docs/ProfileAPI.md +++ b/pkg/apiclient/docs/ProfileAPI.md @@ -151,7 +151,7 @@ import ( ) func main() { - profileData := *openapiclient.NewProfileData(map[string]string{"key": "Inner_example"}) // ProfileData | Profile data + profileData := *openapiclient.NewProfileData(map[string]string{"key": "Inner_example"}, "Id_example") // ProfileData | Profile data configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/docs/ProfileData.md b/pkg/apiclient/docs/ProfileData.md index eaa420b011..89f13e8b1e 100644 --- a/pkg/apiclient/docs/ProfileData.md +++ b/pkg/apiclient/docs/ProfileData.md @@ -5,12 +5,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **EnvVars** | **map[string]string** | | +**Id** | **string** | | ## Methods ### NewProfileData -`func NewProfileData(envVars map[string]string, ) *ProfileData` +`func NewProfileData(envVars map[string]string, id string, ) *ProfileData` NewProfileData instantiates a new ProfileData object This constructor will assign default values to properties that have it defined, @@ -45,6 +46,26 @@ and a boolean to check if the value has been set. SetEnvVars sets EnvVars field to given value. +### GetId + +`func (o *ProfileData) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *ProfileData) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *ProfileData) SetId(v string)` + +SetId sets Id field to given value. + + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index 0b847f6831..e52538ca6b 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -9,6 +9,7 @@ Name | Type | Description | Notes **Name** | **string** | | **Options** | **string** | JSON encoded map of options | **ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | +**Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] ## Methods @@ -129,6 +130,31 @@ and a boolean to check if the value has been set. SetProviderInfo sets ProviderInfo field to given value. +### GetWorkspaces + +`func (o *Target) GetWorkspaces() []Workspace` + +GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. + +### GetWorkspacesOk + +`func (o *Target) GetWorkspacesOk() (*[]Workspace, bool)` + +GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetWorkspaces + +`func (o *Target) SetWorkspaces(v []Workspace)` + +SetWorkspaces sets Workspaces field to given value. + +### HasWorkspaces + +`func (o *Target) HasWorkspaces() bool` + +HasWorkspaces returns a boolean if a field has been set. + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index 33e2f59480..c07c23c39c 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -10,13 +10,13 @@ Name | Type | Description | Notes **Name** | **string** | | **Options** | **string** | JSON encoded map of options | **ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | -**WorkspaceCount** | **int32** | | +**Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] ## Methods ### NewTargetDTO -`func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, workspaceCount int32, ) *TargetDTO` +`func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -156,25 +156,30 @@ and a boolean to check if the value has been set. SetProviderInfo sets ProviderInfo field to given value. -### GetWorkspaceCount +### GetWorkspaces -`func (o *TargetDTO) GetWorkspaceCount() int32` +`func (o *TargetDTO) GetWorkspaces() []Workspace` -GetWorkspaceCount returns the WorkspaceCount field if non-nil, zero value otherwise. +GetWorkspaces returns the Workspaces field if non-nil, zero value otherwise. -### GetWorkspaceCountOk +### GetWorkspacesOk -`func (o *TargetDTO) GetWorkspaceCountOk() (*int32, bool)` +`func (o *TargetDTO) GetWorkspacesOk() (*[]Workspace, bool)` -GetWorkspaceCountOk returns a tuple with the WorkspaceCount field if it's non-nil, zero value otherwise +GetWorkspacesOk returns a tuple with the Workspaces field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetWorkspaceCount +### SetWorkspaces -`func (o *TargetDTO) SetWorkspaceCount(v int32)` +`func (o *TargetDTO) SetWorkspaces(v []Workspace)` -SetWorkspaceCount sets WorkspaceCount field to given value. +SetWorkspaces sets Workspaces field to given value. +### HasWorkspaces + +`func (o *TargetDTO) HasWorkspaces() bool` + +HasWorkspaces returns a boolean if a field has been set. [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/WorkspaceViewDTO.md b/pkg/apiclient/docs/Workspace.md similarity index 62% rename from pkg/apiclient/docs/WorkspaceViewDTO.md rename to pkg/apiclient/docs/Workspace.md index 098ae0c2c4..2926f6d46f 100644 --- a/pkg/apiclient/docs/WorkspaceViewDTO.md +++ b/pkg/apiclient/docs/Workspace.md @@ -1,4 +1,4 @@ -# WorkspaceViewDTO +# Workspace ## Properties @@ -12,260 +12,260 @@ Name | Type | Description | Notes **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | **State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] +**Target** | [**Target**](Target.md) | | **TargetId** | **string** | | -**TargetName** | **string** | | **User** | **string** | | ## Methods -### NewWorkspaceViewDTO +### NewWorkspace -`func NewWorkspaceViewDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string, ) *WorkspaceViewDTO` +`func NewWorkspace(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string, ) *Workspace` -NewWorkspaceViewDTO instantiates a new WorkspaceViewDTO object +NewWorkspace instantiates a new Workspace object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceViewDTOWithDefaults +### NewWorkspaceWithDefaults -`func NewWorkspaceViewDTOWithDefaults() *WorkspaceViewDTO` +`func NewWorkspaceWithDefaults() *Workspace` -NewWorkspaceViewDTOWithDefaults instantiates a new WorkspaceViewDTO object +NewWorkspaceWithDefaults instantiates a new Workspace object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *WorkspaceViewDTO) GetBuildConfig() BuildConfig` +`func (o *Workspace) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *WorkspaceViewDTO) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *WorkspaceViewDTO) SetBuildConfig(v BuildConfig)` +`func (o *Workspace) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *WorkspaceViewDTO) HasBuildConfig() bool` +`func (o *Workspace) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetEnvVars -`func (o *WorkspaceViewDTO) GetEnvVars() map[string]string` +`func (o *Workspace) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *WorkspaceViewDTO) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *WorkspaceViewDTO) SetEnvVars(v map[string]string)` +`func (o *Workspace) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *WorkspaceViewDTO) GetGitProviderConfigId() string` +`func (o *Workspace) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *WorkspaceViewDTO) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *WorkspaceViewDTO) SetGitProviderConfigId(v string)` +`func (o *Workspace) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *WorkspaceViewDTO) HasGitProviderConfigId() bool` +`func (o *Workspace) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetId -`func (o *WorkspaceViewDTO) GetId() string` +`func (o *Workspace) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *WorkspaceViewDTO) GetIdOk() (*string, bool)` +`func (o *Workspace) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *WorkspaceViewDTO) SetId(v string)` +`func (o *Workspace) SetId(v string)` SetId sets Id field to given value. ### GetImage -`func (o *WorkspaceViewDTO) GetImage() string` +`func (o *Workspace) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *WorkspaceViewDTO) GetImageOk() (*string, bool)` +`func (o *Workspace) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *WorkspaceViewDTO) SetImage(v string)` +`func (o *Workspace) SetImage(v string)` SetImage sets Image field to given value. ### GetName -`func (o *WorkspaceViewDTO) GetName() string` +`func (o *Workspace) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *WorkspaceViewDTO) GetNameOk() (*string, bool)` +`func (o *Workspace) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *WorkspaceViewDTO) SetName(v string)` +`func (o *Workspace) SetName(v string)` SetName sets Name field to given value. ### GetRepository -`func (o *WorkspaceViewDTO) GetRepository() GitRepository` +`func (o *Workspace) GetRepository() GitRepository` GetRepository returns the Repository field if non-nil, zero value otherwise. ### GetRepositoryOk -`func (o *WorkspaceViewDTO) GetRepositoryOk() (*GitRepository, bool)` +`func (o *Workspace) GetRepositoryOk() (*GitRepository, bool)` GetRepositoryOk returns a tuple with the Repository field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepository -`func (o *WorkspaceViewDTO) SetRepository(v GitRepository)` +`func (o *Workspace) SetRepository(v GitRepository)` SetRepository sets Repository field to given value. ### GetState -`func (o *WorkspaceViewDTO) GetState() WorkspaceState` +`func (o *Workspace) GetState() WorkspaceState` GetState returns the State field if non-nil, zero value otherwise. ### GetStateOk -`func (o *WorkspaceViewDTO) GetStateOk() (*WorkspaceState, bool)` +`func (o *Workspace) GetStateOk() (*WorkspaceState, bool)` GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetState -`func (o *WorkspaceViewDTO) SetState(v WorkspaceState)` +`func (o *Workspace) SetState(v WorkspaceState)` SetState sets State field to given value. ### HasState -`func (o *WorkspaceViewDTO) HasState() bool` +`func (o *Workspace) HasState() bool` HasState returns a boolean if a field has been set. -### GetTargetId +### GetTarget -`func (o *WorkspaceViewDTO) GetTargetId() string` +`func (o *Workspace) GetTarget() Target` -GetTargetId returns the TargetId field if non-nil, zero value otherwise. +GetTarget returns the Target field if non-nil, zero value otherwise. -### GetTargetIdOk +### GetTargetOk -`func (o *WorkspaceViewDTO) GetTargetIdOk() (*string, bool)` +`func (o *Workspace) GetTargetOk() (*Target, bool)` -GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise +GetTargetOk returns a tuple with the Target field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetId +### SetTarget -`func (o *WorkspaceViewDTO) SetTargetId(v string)` +`func (o *Workspace) SetTarget(v Target)` -SetTargetId sets TargetId field to given value. +SetTarget sets Target field to given value. -### GetTargetName +### GetTargetId -`func (o *WorkspaceViewDTO) GetTargetName() string` +`func (o *Workspace) GetTargetId() string` -GetTargetName returns the TargetName field if non-nil, zero value otherwise. +GetTargetId returns the TargetId field if non-nil, zero value otherwise. -### GetTargetNameOk +### GetTargetIdOk -`func (o *WorkspaceViewDTO) GetTargetNameOk() (*string, bool)` +`func (o *Workspace) GetTargetIdOk() (*string, bool)` -GetTargetNameOk returns a tuple with the TargetName field if it's non-nil, zero value otherwise +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetName +### SetTargetId -`func (o *WorkspaceViewDTO) SetTargetName(v string)` +`func (o *Workspace) SetTargetId(v string)` -SetTargetName sets TargetName field to given value. +SetTargetId sets TargetId field to given value. ### GetUser -`func (o *WorkspaceViewDTO) GetUser() string` +`func (o *Workspace) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *WorkspaceViewDTO) GetUserOk() (*string, bool)` +`func (o *Workspace) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *WorkspaceViewDTO) SetUser(v string)` +`func (o *Workspace) SetUser(v string)` SetUser sets User field to given value. diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 451a932d25..ebedbbff1a 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -16,7 +16,7 @@ Method | HTTP request | Description ## CreateWorkspace -> WorkspaceViewDTO CreateWorkspace(ctx).Workspace(workspace).Execute() +> Workspace CreateWorkspace(ctx).Workspace(workspace).Execute() Create a workspace @@ -44,7 +44,7 @@ func main() { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.CreateWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `CreateWorkspace`: WorkspaceViewDTO + // response from `CreateWorkspace`: Workspace fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.CreateWorkspace`: %v\n", resp) } ``` @@ -64,7 +64,7 @@ Name | Type | Description | Notes ### Return type -[**WorkspaceViewDTO**](WorkspaceViewDTO.md) +[**Workspace**](Workspace.md) ### Authorization diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md index 7f292d664d..6167bddc2b 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -13,15 +13,15 @@ Name | Type | Description | Notes **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | **State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] +**Target** | [**Target**](Target.md) | | **TargetId** | **string** | | -**TargetName** | **string** | | **User** | **string** | | ## Methods ### NewWorkspaceDTO -`func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string, ) *WorkspaceDTO` +`func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string, ) *WorkspaceDTO` NewWorkspaceDTO instantiates a new WorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -236,44 +236,44 @@ SetState sets State field to given value. HasState returns a boolean if a field has been set. -### GetTargetId +### GetTarget -`func (o *WorkspaceDTO) GetTargetId() string` +`func (o *WorkspaceDTO) GetTarget() Target` -GetTargetId returns the TargetId field if non-nil, zero value otherwise. +GetTarget returns the Target field if non-nil, zero value otherwise. -### GetTargetIdOk +### GetTargetOk -`func (o *WorkspaceDTO) GetTargetIdOk() (*string, bool)` +`func (o *WorkspaceDTO) GetTargetOk() (*Target, bool)` -GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise +GetTargetOk returns a tuple with the Target field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetId +### SetTarget -`func (o *WorkspaceDTO) SetTargetId(v string)` +`func (o *WorkspaceDTO) SetTarget(v Target)` -SetTargetId sets TargetId field to given value. +SetTarget sets Target field to given value. -### GetTargetName +### GetTargetId -`func (o *WorkspaceDTO) GetTargetName() string` +`func (o *WorkspaceDTO) GetTargetId() string` -GetTargetName returns the TargetName field if non-nil, zero value otherwise. +GetTargetId returns the TargetId field if non-nil, zero value otherwise. -### GetTargetNameOk +### GetTargetIdOk -`func (o *WorkspaceDTO) GetTargetNameOk() (*string, bool)` +`func (o *WorkspaceDTO) GetTargetIdOk() (*string, bool)` -GetTargetNameOk returns a tuple with the TargetName field if it's non-nil, zero value otherwise +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetName +### SetTargetId -`func (o *WorkspaceDTO) SetTargetName(v string)` +`func (o *WorkspaceDTO) SetTargetId(v string)` -SetTargetName sets TargetName field to given value. +SetTargetId sets TargetId field to given value. ### GetUser diff --git a/pkg/apiclient/model_api_key.go b/pkg/apiclient/model_api_key.go index 121ae4528d..226adc61c2 100644 --- a/pkg/apiclient/model_api_key.go +++ b/pkg/apiclient/model_api_key.go @@ -24,7 +24,7 @@ type ApiKey struct { KeyHash string `json:"keyHash"` // Workspace or client name Name string `json:"name"` - Type ApikeyApiKeyType `json:"type"` + Type ModelsApiKeyType `json:"type"` } type _ApiKey ApiKey @@ -33,7 +33,7 @@ type _ApiKey ApiKey // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewApiKey(keyHash string, name string, type_ ApikeyApiKeyType) *ApiKey { +func NewApiKey(keyHash string, name string, type_ ModelsApiKeyType) *ApiKey { this := ApiKey{} this.KeyHash = keyHash this.Name = name @@ -98,9 +98,9 @@ func (o *ApiKey) SetName(v string) { } // GetType returns the Type field value -func (o *ApiKey) GetType() ApikeyApiKeyType { +func (o *ApiKey) GetType() ModelsApiKeyType { if o == nil { - var ret ApikeyApiKeyType + var ret ModelsApiKeyType return ret } @@ -109,7 +109,7 @@ func (o *ApiKey) GetType() ApikeyApiKeyType { // GetTypeOk returns a tuple with the Type field value // and a boolean to check if the value has been set. -func (o *ApiKey) GetTypeOk() (*ApikeyApiKeyType, bool) { +func (o *ApiKey) GetTypeOk() (*ModelsApiKeyType, bool) { if o == nil { return nil, false } @@ -117,7 +117,7 @@ func (o *ApiKey) GetTypeOk() (*ApikeyApiKeyType, bool) { } // SetType sets field value -func (o *ApiKey) SetType(v ApikeyApiKeyType) { +func (o *ApiKey) SetType(v ModelsApiKeyType) { o.Type = v } diff --git a/pkg/apiclient/model_apikey_api_key_type.go b/pkg/apiclient/model_apikey_api_key_type.go deleted file mode 100644 index 7228586047..0000000000 --- a/pkg/apiclient/model_apikey_api_key_type.go +++ /dev/null @@ -1,112 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "encoding/json" - "fmt" -) - -// ApikeyApiKeyType the model 'ApikeyApiKeyType' -type ApikeyApiKeyType string - -// List of apikey.ApiKeyType -const ( - ApiKeyTypeClient ApikeyApiKeyType = "client" - ApiKeyTypeWorkspace ApikeyApiKeyType = "workspace" - ApiKeyTypeTarget ApikeyApiKeyType = "target" -) - -// All allowed values of ApikeyApiKeyType enum -var AllowedApikeyApiKeyTypeEnumValues = []ApikeyApiKeyType{ - "client", - "workspace", - "target", -} - -func (v *ApikeyApiKeyType) UnmarshalJSON(src []byte) error { - var value string - err := json.Unmarshal(src, &value) - if err != nil { - return err - } - enumTypeValue := ApikeyApiKeyType(value) - for _, existing := range AllowedApikeyApiKeyTypeEnumValues { - if existing == enumTypeValue { - *v = enumTypeValue - return nil - } - } - - return fmt.Errorf("%+v is not a valid ApikeyApiKeyType", value) -} - -// NewApikeyApiKeyTypeFromValue returns a pointer to a valid ApikeyApiKeyType -// for the value passed as argument, or an error if the value passed is not allowed by the enum -func NewApikeyApiKeyTypeFromValue(v string) (*ApikeyApiKeyType, error) { - ev := ApikeyApiKeyType(v) - if ev.IsValid() { - return &ev, nil - } else { - return nil, fmt.Errorf("invalid value '%v' for ApikeyApiKeyType: valid values are %v", v, AllowedApikeyApiKeyTypeEnumValues) - } -} - -// IsValid return true if the value is valid for the enum, false otherwise -func (v ApikeyApiKeyType) IsValid() bool { - for _, existing := range AllowedApikeyApiKeyTypeEnumValues { - if existing == v { - return true - } - } - return false -} - -// Ptr returns reference to apikey.ApiKeyType value -func (v ApikeyApiKeyType) Ptr() *ApikeyApiKeyType { - return &v -} - -type NullableApikeyApiKeyType struct { - value *ApikeyApiKeyType - isSet bool -} - -func (v NullableApikeyApiKeyType) Get() *ApikeyApiKeyType { - return v.value -} - -func (v *NullableApikeyApiKeyType) Set(val *ApikeyApiKeyType) { - v.value = val - v.isSet = true -} - -func (v NullableApikeyApiKeyType) IsSet() bool { - return v.isSet -} - -func (v *NullableApikeyApiKeyType) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableApikeyApiKeyType(val *ApikeyApiKeyType) *NullableApikeyApiKeyType { - return &NullableApikeyApiKeyType{value: val, isSet: true} -} - -func (v NullableApikeyApiKeyType) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableApikeyApiKeyType) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_build.go b/pkg/apiclient/model_build.go index 5651cbcb24..a1b59a5369 100644 --- a/pkg/apiclient/model_build.go +++ b/pkg/apiclient/model_build.go @@ -29,7 +29,7 @@ type Build struct { Image *string `json:"image,omitempty"` PrebuildId string `json:"prebuildId"` Repository GitRepository `json:"repository"` - State BuildBuildState `json:"state"` + State ModelsBuildState `json:"state"` UpdatedAt string `json:"updatedAt"` User *string `json:"user,omitempty"` } @@ -40,7 +40,7 @@ type _Build Build // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state BuildBuildState, updatedAt string) *Build { +func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ModelsBuildState, updatedAt string) *Build { this := Build{} this.ContainerConfig = containerConfig this.CreatedAt = createdAt @@ -270,9 +270,9 @@ func (o *Build) SetRepository(v GitRepository) { } // GetState returns the State field value -func (o *Build) GetState() BuildBuildState { +func (o *Build) GetState() ModelsBuildState { if o == nil { - var ret BuildBuildState + var ret ModelsBuildState return ret } @@ -281,7 +281,7 @@ func (o *Build) GetState() BuildBuildState { // GetStateOk returns a tuple with the State field value // and a boolean to check if the value has been set. -func (o *Build) GetStateOk() (*BuildBuildState, bool) { +func (o *Build) GetStateOk() (*ModelsBuildState, bool) { if o == nil { return nil, false } @@ -289,7 +289,7 @@ func (o *Build) GetStateOk() (*BuildBuildState, bool) { } // SetState sets field value -func (o *Build) SetState(v BuildBuildState) { +func (o *Build) SetState(v ModelsBuildState) { o.State = v } diff --git a/pkg/apiclient/model_build_build_state.go b/pkg/apiclient/model_build_build_state.go deleted file mode 100644 index c31c266c19..0000000000 --- a/pkg/apiclient/model_build_build_state.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "encoding/json" - "fmt" -) - -// BuildBuildState the model 'BuildBuildState' -type BuildBuildState string - -// List of build.BuildState -const ( - BuildStatePendingRun BuildBuildState = "pending-run" - BuildStateRunning BuildBuildState = "running" - BuildStateError BuildBuildState = "error" - BuildStateSuccess BuildBuildState = "success" - BuildStatePublished BuildBuildState = "published" - BuildStatePendingDelete BuildBuildState = "pending-delete" - BuildStatePendingForcedDelete BuildBuildState = "pending-forced-delete" - BuildStateDeleting BuildBuildState = "deleting" -) - -// All allowed values of BuildBuildState enum -var AllowedBuildBuildStateEnumValues = []BuildBuildState{ - "pending-run", - "running", - "error", - "success", - "published", - "pending-delete", - "pending-forced-delete", - "deleting", -} - -func (v *BuildBuildState) UnmarshalJSON(src []byte) error { - var value string - err := json.Unmarshal(src, &value) - if err != nil { - return err - } - enumTypeValue := BuildBuildState(value) - for _, existing := range AllowedBuildBuildStateEnumValues { - if existing == enumTypeValue { - *v = enumTypeValue - return nil - } - } - - return fmt.Errorf("%+v is not a valid BuildBuildState", value) -} - -// NewBuildBuildStateFromValue returns a pointer to a valid BuildBuildState -// for the value passed as argument, or an error if the value passed is not allowed by the enum -func NewBuildBuildStateFromValue(v string) (*BuildBuildState, error) { - ev := BuildBuildState(v) - if ev.IsValid() { - return &ev, nil - } else { - return nil, fmt.Errorf("invalid value '%v' for BuildBuildState: valid values are %v", v, AllowedBuildBuildStateEnumValues) - } -} - -// IsValid return true if the value is valid for the enum, false otherwise -func (v BuildBuildState) IsValid() bool { - for _, existing := range AllowedBuildBuildStateEnumValues { - if existing == v { - return true - } - } - return false -} - -// Ptr returns reference to build.BuildState value -func (v BuildBuildState) Ptr() *BuildBuildState { - return &v -} - -type NullableBuildBuildState struct { - value *BuildBuildState - isSet bool -} - -func (v NullableBuildBuildState) Get() *BuildBuildState { - return v.value -} - -func (v *NullableBuildBuildState) Set(val *BuildBuildState) { - v.value = val - v.isSet = true -} - -func (v NullableBuildBuildState) IsSet() bool { - return v.isSet -} - -func (v *NullableBuildBuildState) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableBuildBuildState(val *BuildBuildState) *NullableBuildBuildState { - return &NullableBuildBuildState{value: val, isSet: true} -} - -func (v NullableBuildBuildState) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableBuildBuildState) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_models_api_key_type.go b/pkg/apiclient/model_models_api_key_type.go new file mode 100644 index 0000000000..94ef5ef217 --- /dev/null +++ b/pkg/apiclient/model_models_api_key_type.go @@ -0,0 +1,112 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ModelsApiKeyType the model 'ModelsApiKeyType' +type ModelsApiKeyType string + +// List of models.ApiKeyType +const ( + ApiKeyTypeClient ModelsApiKeyType = "client" + ApiKeyTypeWorkspace ModelsApiKeyType = "workspace" + ApiKeyTypeTarget ModelsApiKeyType = "target" +) + +// All allowed values of ModelsApiKeyType enum +var AllowedModelsApiKeyTypeEnumValues = []ModelsApiKeyType{ + "client", + "workspace", + "target", +} + +func (v *ModelsApiKeyType) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ModelsApiKeyType(value) + for _, existing := range AllowedModelsApiKeyTypeEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ModelsApiKeyType", value) +} + +// NewModelsApiKeyTypeFromValue returns a pointer to a valid ModelsApiKeyType +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewModelsApiKeyTypeFromValue(v string) (*ModelsApiKeyType, error) { + ev := ModelsApiKeyType(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ModelsApiKeyType: valid values are %v", v, AllowedModelsApiKeyTypeEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ModelsApiKeyType) IsValid() bool { + for _, existing := range AllowedModelsApiKeyTypeEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to models.ApiKeyType value +func (v ModelsApiKeyType) Ptr() *ModelsApiKeyType { + return &v +} + +type NullableModelsApiKeyType struct { + value *ModelsApiKeyType + isSet bool +} + +func (v NullableModelsApiKeyType) Get() *ModelsApiKeyType { + return v.value +} + +func (v *NullableModelsApiKeyType) Set(val *ModelsApiKeyType) { + v.value = val + v.isSet = true +} + +func (v NullableModelsApiKeyType) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsApiKeyType) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsApiKeyType(val *ModelsApiKeyType) *NullableModelsApiKeyType { + return &NullableModelsApiKeyType{value: val, isSet: true} +} + +func (v NullableModelsApiKeyType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsApiKeyType) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_models_build_state.go b/pkg/apiclient/model_models_build_state.go new file mode 100644 index 0000000000..4ef142560c --- /dev/null +++ b/pkg/apiclient/model_models_build_state.go @@ -0,0 +1,122 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ModelsBuildState the model 'ModelsBuildState' +type ModelsBuildState string + +// List of models.BuildState +const ( + BuildStatePendingRun ModelsBuildState = "pending-run" + BuildStateRunning ModelsBuildState = "running" + BuildStateError ModelsBuildState = "error" + BuildStateSuccess ModelsBuildState = "success" + BuildStatePublished ModelsBuildState = "published" + BuildStatePendingDelete ModelsBuildState = "pending-delete" + BuildStatePendingForcedDelete ModelsBuildState = "pending-forced-delete" + BuildStateDeleting ModelsBuildState = "deleting" +) + +// All allowed values of ModelsBuildState enum +var AllowedModelsBuildStateEnumValues = []ModelsBuildState{ + "pending-run", + "running", + "error", + "success", + "published", + "pending-delete", + "pending-forced-delete", + "deleting", +} + +func (v *ModelsBuildState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ModelsBuildState(value) + for _, existing := range AllowedModelsBuildStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ModelsBuildState", value) +} + +// NewModelsBuildStateFromValue returns a pointer to a valid ModelsBuildState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewModelsBuildStateFromValue(v string) (*ModelsBuildState, error) { + ev := ModelsBuildState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ModelsBuildState: valid values are %v", v, AllowedModelsBuildStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ModelsBuildState) IsValid() bool { + for _, existing := range AllowedModelsBuildStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to models.BuildState value +func (v ModelsBuildState) Ptr() *ModelsBuildState { + return &v +} + +type NullableModelsBuildState struct { + value *ModelsBuildState + isSet bool +} + +func (v NullableModelsBuildState) Get() *ModelsBuildState { + return v.value +} + +func (v *NullableModelsBuildState) Set(val *ModelsBuildState) { + v.value = val + v.isSet = true +} + +func (v NullableModelsBuildState) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsBuildState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsBuildState(val *ModelsBuildState) *NullableModelsBuildState { + return &NullableModelsBuildState{value: val, isSet: true} +} + +func (v NullableModelsBuildState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsBuildState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_profile_data.go b/pkg/apiclient/model_profile_data.go index d7eabbe8f4..94859c102d 100644 --- a/pkg/apiclient/model_profile_data.go +++ b/pkg/apiclient/model_profile_data.go @@ -22,6 +22,7 @@ var _ MappedNullable = &ProfileData{} // ProfileData struct for ProfileData type ProfileData struct { EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` } type _ProfileData ProfileData @@ -30,9 +31,10 @@ type _ProfileData ProfileData // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewProfileData(envVars map[string]string) *ProfileData { +func NewProfileData(envVars map[string]string, id string) *ProfileData { this := ProfileData{} this.EnvVars = envVars + this.Id = id return &this } @@ -68,6 +70,30 @@ func (o *ProfileData) SetEnvVars(v map[string]string) { o.EnvVars = v } +// GetId returns the Id field value +func (o *ProfileData) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *ProfileData) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *ProfileData) SetId(v string) { + o.Id = v +} + func (o ProfileData) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -79,6 +105,7 @@ func (o ProfileData) MarshalJSON() ([]byte, error) { func (o ProfileData) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["envVars"] = o.EnvVars + toSerialize["id"] = o.Id return toSerialize, nil } @@ -88,6 +115,7 @@ func (o *ProfileData) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "envVars", + "id", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index 8828ee4b68..fc04b3ebe0 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -27,6 +27,7 @@ type Target struct { // JSON encoded map of options Options string `json:"options"` ProviderInfo TargetProviderInfo `json:"providerInfo"` + Workspaces []Workspace `json:"workspaces,omitempty"` } type _Target Target @@ -173,6 +174,38 @@ func (o *Target) SetProviderInfo(v TargetProviderInfo) { o.ProviderInfo = v } +// GetWorkspaces returns the Workspaces field value if set, zero value otherwise. +func (o *Target) GetWorkspaces() []Workspace { + if o == nil || IsNil(o.Workspaces) { + var ret []Workspace + return ret + } + return o.Workspaces +} + +// GetWorkspacesOk returns a tuple with the Workspaces field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Target) GetWorkspacesOk() ([]Workspace, bool) { + if o == nil || IsNil(o.Workspaces) { + return nil, false + } + return o.Workspaces, true +} + +// HasWorkspaces returns a boolean if a field has been set. +func (o *Target) HasWorkspaces() bool { + if o != nil && !IsNil(o.Workspaces) { + return true + } + + return false +} + +// SetWorkspaces gets a reference to the given []Workspace and assigns it to the Workspaces field. +func (o *Target) SetWorkspaces(v []Workspace) { + o.Workspaces = v +} + func (o Target) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -188,6 +221,9 @@ func (o Target) ToMap() (map[string]interface{}, error) { toSerialize["name"] = o.Name toSerialize["options"] = o.Options toSerialize["providerInfo"] = o.ProviderInfo + if !IsNil(o.Workspaces) { + toSerialize["workspaces"] = o.Workspaces + } return toSerialize, nil } diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 2808022c4a..64b78e829f 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -26,9 +26,9 @@ type TargetDTO struct { Info *TargetInfo `json:"info,omitempty"` Name string `json:"name"` // JSON encoded map of options - Options string `json:"options"` - ProviderInfo TargetProviderInfo `json:"providerInfo"` - WorkspaceCount int32 `json:"workspaceCount"` + Options string `json:"options"` + ProviderInfo TargetProviderInfo `json:"providerInfo"` + Workspaces []Workspace `json:"workspaces,omitempty"` } type _TargetDTO TargetDTO @@ -37,14 +37,13 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, workspaceCount int32) *TargetDTO { +func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo) *TargetDTO { this := TargetDTO{} this.Default = default_ this.Id = id this.Name = name this.Options = options this.ProviderInfo = providerInfo - this.WorkspaceCount = workspaceCount return &this } @@ -208,28 +207,36 @@ func (o *TargetDTO) SetProviderInfo(v TargetProviderInfo) { o.ProviderInfo = v } -// GetWorkspaceCount returns the WorkspaceCount field value -func (o *TargetDTO) GetWorkspaceCount() int32 { - if o == nil { - var ret int32 +// GetWorkspaces returns the Workspaces field value if set, zero value otherwise. +func (o *TargetDTO) GetWorkspaces() []Workspace { + if o == nil || IsNil(o.Workspaces) { + var ret []Workspace return ret } - - return o.WorkspaceCount + return o.Workspaces } -// GetWorkspaceCountOk returns a tuple with the WorkspaceCount field value +// GetWorkspacesOk returns a tuple with the Workspaces field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *TargetDTO) GetWorkspaceCountOk() (*int32, bool) { - if o == nil { +func (o *TargetDTO) GetWorkspacesOk() ([]Workspace, bool) { + if o == nil || IsNil(o.Workspaces) { return nil, false } - return &o.WorkspaceCount, true + return o.Workspaces, true +} + +// HasWorkspaces returns a boolean if a field has been set. +func (o *TargetDTO) HasWorkspaces() bool { + if o != nil && !IsNil(o.Workspaces) { + return true + } + + return false } -// SetWorkspaceCount sets field value -func (o *TargetDTO) SetWorkspaceCount(v int32) { - o.WorkspaceCount = v +// SetWorkspaces gets a reference to the given []Workspace and assigns it to the Workspaces field. +func (o *TargetDTO) SetWorkspaces(v []Workspace) { + o.Workspaces = v } func (o TargetDTO) MarshalJSON() ([]byte, error) { @@ -250,7 +257,9 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["name"] = o.Name toSerialize["options"] = o.Options toSerialize["providerInfo"] = o.ProviderInfo - toSerialize["workspaceCount"] = o.WorkspaceCount + if !IsNil(o.Workspaces) { + toSerialize["workspaces"] = o.Workspaces + } return toSerialize, nil } @@ -264,7 +273,6 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { "name", "options", "providerInfo", - "workspaceCount", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_workspace_view_dto.go b/pkg/apiclient/model_workspace.go similarity index 65% rename from pkg/apiclient/model_workspace_view_dto.go rename to pkg/apiclient/model_workspace.go index 6591d6035e..de0cfb7a0d 100644 --- a/pkg/apiclient/model_workspace_view_dto.go +++ b/pkg/apiclient/model_workspace.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the WorkspaceViewDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &WorkspaceViewDTO{} +// checks if the Workspace type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Workspace{} -// WorkspaceViewDTO struct for WorkspaceViewDTO -type WorkspaceViewDTO struct { +// Workspace struct for Workspace +type Workspace struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` @@ -29,40 +29,40 @@ type WorkspaceViewDTO struct { Name string `json:"name"` Repository GitRepository `json:"repository"` State *WorkspaceState `json:"state,omitempty"` + Target Target `json:"target"` TargetId string `json:"targetId"` - TargetName string `json:"targetName"` User string `json:"user"` } -type _WorkspaceViewDTO WorkspaceViewDTO +type _Workspace Workspace -// NewWorkspaceViewDTO instantiates a new WorkspaceViewDTO object +// NewWorkspace instantiates a new Workspace object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceViewDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string) *WorkspaceViewDTO { - this := WorkspaceViewDTO{} +func NewWorkspace(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string) *Workspace { + this := Workspace{} this.EnvVars = envVars this.Id = id this.Image = image this.Name = name this.Repository = repository + this.Target = target this.TargetId = targetId - this.TargetName = targetName this.User = user return &this } -// NewWorkspaceViewDTOWithDefaults instantiates a new WorkspaceViewDTO object +// NewWorkspaceWithDefaults instantiates a new Workspace object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceViewDTOWithDefaults() *WorkspaceViewDTO { - this := WorkspaceViewDTO{} +func NewWorkspaceWithDefaults() *Workspace { + this := Workspace{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *WorkspaceViewDTO) GetBuildConfig() BuildConfig { +func (o *Workspace) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -72,7 +72,7 @@ func (o *WorkspaceViewDTO) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *Workspace) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -80,7 +80,7 @@ func (o *WorkspaceViewDTO) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *WorkspaceViewDTO) HasBuildConfig() bool { +func (o *Workspace) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -89,12 +89,12 @@ func (o *WorkspaceViewDTO) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *WorkspaceViewDTO) SetBuildConfig(v BuildConfig) { +func (o *Workspace) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetEnvVars returns the EnvVars field value -func (o *WorkspaceViewDTO) GetEnvVars() map[string]string { +func (o *Workspace) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -105,7 +105,7 @@ func (o *WorkspaceViewDTO) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetEnvVarsOk() (*map[string]string, bool) { +func (o *Workspace) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -113,12 +113,12 @@ func (o *WorkspaceViewDTO) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *WorkspaceViewDTO) SetEnvVars(v map[string]string) { +func (o *Workspace) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *WorkspaceViewDTO) GetGitProviderConfigId() string { +func (o *Workspace) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -128,7 +128,7 @@ func (o *WorkspaceViewDTO) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetGitProviderConfigIdOk() (*string, bool) { +func (o *Workspace) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -136,7 +136,7 @@ func (o *WorkspaceViewDTO) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *WorkspaceViewDTO) HasGitProviderConfigId() bool { +func (o *Workspace) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -145,12 +145,12 @@ func (o *WorkspaceViewDTO) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *WorkspaceViewDTO) SetGitProviderConfigId(v string) { +func (o *Workspace) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetId returns the Id field value -func (o *WorkspaceViewDTO) GetId() string { +func (o *Workspace) GetId() string { if o == nil { var ret string return ret @@ -161,7 +161,7 @@ func (o *WorkspaceViewDTO) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetIdOk() (*string, bool) { +func (o *Workspace) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -169,12 +169,12 @@ func (o *WorkspaceViewDTO) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *WorkspaceViewDTO) SetId(v string) { +func (o *Workspace) SetId(v string) { o.Id = v } // GetImage returns the Image field value -func (o *WorkspaceViewDTO) GetImage() string { +func (o *Workspace) GetImage() string { if o == nil { var ret string return ret @@ -185,7 +185,7 @@ func (o *WorkspaceViewDTO) GetImage() string { // GetImageOk returns a tuple with the Image field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetImageOk() (*string, bool) { +func (o *Workspace) GetImageOk() (*string, bool) { if o == nil { return nil, false } @@ -193,12 +193,12 @@ func (o *WorkspaceViewDTO) GetImageOk() (*string, bool) { } // SetImage sets field value -func (o *WorkspaceViewDTO) SetImage(v string) { +func (o *Workspace) SetImage(v string) { o.Image = v } // GetName returns the Name field value -func (o *WorkspaceViewDTO) GetName() string { +func (o *Workspace) GetName() string { if o == nil { var ret string return ret @@ -209,7 +209,7 @@ func (o *WorkspaceViewDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetNameOk() (*string, bool) { +func (o *Workspace) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -217,12 +217,12 @@ func (o *WorkspaceViewDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *WorkspaceViewDTO) SetName(v string) { +func (o *Workspace) SetName(v string) { o.Name = v } // GetRepository returns the Repository field value -func (o *WorkspaceViewDTO) GetRepository() GitRepository { +func (o *Workspace) GetRepository() GitRepository { if o == nil { var ret GitRepository return ret @@ -233,7 +233,7 @@ func (o *WorkspaceViewDTO) GetRepository() GitRepository { // GetRepositoryOk returns a tuple with the Repository field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetRepositoryOk() (*GitRepository, bool) { +func (o *Workspace) GetRepositoryOk() (*GitRepository, bool) { if o == nil { return nil, false } @@ -241,12 +241,12 @@ func (o *WorkspaceViewDTO) GetRepositoryOk() (*GitRepository, bool) { } // SetRepository sets field value -func (o *WorkspaceViewDTO) SetRepository(v GitRepository) { +func (o *Workspace) SetRepository(v GitRepository) { o.Repository = v } // GetState returns the State field value if set, zero value otherwise. -func (o *WorkspaceViewDTO) GetState() WorkspaceState { +func (o *Workspace) GetState() WorkspaceState { if o == nil || IsNil(o.State) { var ret WorkspaceState return ret @@ -256,7 +256,7 @@ func (o *WorkspaceViewDTO) GetState() WorkspaceState { // GetStateOk returns a tuple with the State field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetStateOk() (*WorkspaceState, bool) { +func (o *Workspace) GetStateOk() (*WorkspaceState, bool) { if o == nil || IsNil(o.State) { return nil, false } @@ -264,7 +264,7 @@ func (o *WorkspaceViewDTO) GetStateOk() (*WorkspaceState, bool) { } // HasState returns a boolean if a field has been set. -func (o *WorkspaceViewDTO) HasState() bool { +func (o *Workspace) HasState() bool { if o != nil && !IsNil(o.State) { return true } @@ -273,60 +273,60 @@ func (o *WorkspaceViewDTO) HasState() bool { } // SetState gets a reference to the given WorkspaceState and assigns it to the State field. -func (o *WorkspaceViewDTO) SetState(v WorkspaceState) { +func (o *Workspace) SetState(v WorkspaceState) { o.State = &v } -// GetTargetId returns the TargetId field value -func (o *WorkspaceViewDTO) GetTargetId() string { +// GetTarget returns the Target field value +func (o *Workspace) GetTarget() Target { if o == nil { - var ret string + var ret Target return ret } - return o.TargetId + return o.Target } -// GetTargetIdOk returns a tuple with the TargetId field value +// GetTargetOk returns a tuple with the Target field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetTargetIdOk() (*string, bool) { +func (o *Workspace) GetTargetOk() (*Target, bool) { if o == nil { return nil, false } - return &o.TargetId, true + return &o.Target, true } -// SetTargetId sets field value -func (o *WorkspaceViewDTO) SetTargetId(v string) { - o.TargetId = v +// SetTarget sets field value +func (o *Workspace) SetTarget(v Target) { + o.Target = v } -// GetTargetName returns the TargetName field value -func (o *WorkspaceViewDTO) GetTargetName() string { +// GetTargetId returns the TargetId field value +func (o *Workspace) GetTargetId() string { if o == nil { var ret string return ret } - return o.TargetName + return o.TargetId } -// GetTargetNameOk returns a tuple with the TargetName field value +// GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetTargetNameOk() (*string, bool) { +func (o *Workspace) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.TargetName, true + return &o.TargetId, true } -// SetTargetName sets field value -func (o *WorkspaceViewDTO) SetTargetName(v string) { - o.TargetName = v +// SetTargetId sets field value +func (o *Workspace) SetTargetId(v string) { + o.TargetId = v } // GetUser returns the User field value -func (o *WorkspaceViewDTO) GetUser() string { +func (o *Workspace) GetUser() string { if o == nil { var ret string return ret @@ -337,7 +337,7 @@ func (o *WorkspaceViewDTO) GetUser() string { // GetUserOk returns a tuple with the User field value // and a boolean to check if the value has been set. -func (o *WorkspaceViewDTO) GetUserOk() (*string, bool) { +func (o *Workspace) GetUserOk() (*string, bool) { if o == nil { return nil, false } @@ -345,11 +345,11 @@ func (o *WorkspaceViewDTO) GetUserOk() (*string, bool) { } // SetUser sets field value -func (o *WorkspaceViewDTO) SetUser(v string) { +func (o *Workspace) SetUser(v string) { o.User = v } -func (o WorkspaceViewDTO) MarshalJSON() ([]byte, error) { +func (o Workspace) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -357,7 +357,7 @@ func (o WorkspaceViewDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o WorkspaceViewDTO) ToMap() (map[string]interface{}, error) { +func (o Workspace) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -373,13 +373,13 @@ func (o WorkspaceViewDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.State) { toSerialize["state"] = o.State } + toSerialize["target"] = o.Target toSerialize["targetId"] = o.TargetId - toSerialize["targetName"] = o.TargetName toSerialize["user"] = o.User return toSerialize, nil } -func (o *WorkspaceViewDTO) UnmarshalJSON(data []byte) (err error) { +func (o *Workspace) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -389,8 +389,8 @@ func (o *WorkspaceViewDTO) UnmarshalJSON(data []byte) (err error) { "image", "name", "repository", + "target", "targetId", - "targetName", "user", } @@ -408,53 +408,53 @@ func (o *WorkspaceViewDTO) UnmarshalJSON(data []byte) (err error) { } } - varWorkspaceViewDTO := _WorkspaceViewDTO{} + varWorkspace := _Workspace{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspaceViewDTO) + err = decoder.Decode(&varWorkspace) if err != nil { return err } - *o = WorkspaceViewDTO(varWorkspaceViewDTO) + *o = Workspace(varWorkspace) return err } -type NullableWorkspaceViewDTO struct { - value *WorkspaceViewDTO +type NullableWorkspace struct { + value *Workspace isSet bool } -func (v NullableWorkspaceViewDTO) Get() *WorkspaceViewDTO { +func (v NullableWorkspace) Get() *Workspace { return v.value } -func (v *NullableWorkspaceViewDTO) Set(val *WorkspaceViewDTO) { +func (v *NullableWorkspace) Set(val *Workspace) { v.value = val v.isSet = true } -func (v NullableWorkspaceViewDTO) IsSet() bool { +func (v NullableWorkspace) IsSet() bool { return v.isSet } -func (v *NullableWorkspaceViewDTO) Unset() { +func (v *NullableWorkspace) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspaceViewDTO(val *WorkspaceViewDTO) *NullableWorkspaceViewDTO { - return &NullableWorkspaceViewDTO{value: val, isSet: true} +func NewNullableWorkspace(val *Workspace) *NullableWorkspace { + return &NullableWorkspace{value: val, isSet: true} } -func (v NullableWorkspaceViewDTO) MarshalJSON() ([]byte, error) { +func (v NullableWorkspace) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspaceViewDTO) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspace) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go index 9604431821..0e3f8ac924 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_workspace_dto.go @@ -30,8 +30,8 @@ type WorkspaceDTO struct { Name string `json:"name"` Repository GitRepository `json:"repository"` State *WorkspaceState `json:"state,omitempty"` + Target Target `json:"target"` TargetId string `json:"targetId"` - TargetName string `json:"targetName"` User string `json:"user"` } @@ -41,15 +41,15 @@ type _WorkspaceDTO WorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, targetId string, targetName string, user string) *WorkspaceDTO { +func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string) *WorkspaceDTO { this := WorkspaceDTO{} this.EnvVars = envVars this.Id = id this.Image = image this.Name = name this.Repository = repository + this.Target = target this.TargetId = targetId - this.TargetName = targetName this.User = user return &this } @@ -310,52 +310,52 @@ func (o *WorkspaceDTO) SetState(v WorkspaceState) { o.State = &v } -// GetTargetId returns the TargetId field value -func (o *WorkspaceDTO) GetTargetId() string { +// GetTarget returns the Target field value +func (o *WorkspaceDTO) GetTarget() Target { if o == nil { - var ret string + var ret Target return ret } - return o.TargetId + return o.Target } -// GetTargetIdOk returns a tuple with the TargetId field value +// GetTargetOk returns a tuple with the Target field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetTargetIdOk() (*string, bool) { +func (o *WorkspaceDTO) GetTargetOk() (*Target, bool) { if o == nil { return nil, false } - return &o.TargetId, true + return &o.Target, true } -// SetTargetId sets field value -func (o *WorkspaceDTO) SetTargetId(v string) { - o.TargetId = v +// SetTarget sets field value +func (o *WorkspaceDTO) SetTarget(v Target) { + o.Target = v } -// GetTargetName returns the TargetName field value -func (o *WorkspaceDTO) GetTargetName() string { +// GetTargetId returns the TargetId field value +func (o *WorkspaceDTO) GetTargetId() string { if o == nil { var ret string return ret } - return o.TargetName + return o.TargetId } -// GetTargetNameOk returns a tuple with the TargetName field value +// GetTargetIdOk returns a tuple with the TargetId field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetTargetNameOk() (*string, bool) { +func (o *WorkspaceDTO) GetTargetIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.TargetName, true + return &o.TargetId, true } -// SetTargetName sets field value -func (o *WorkspaceDTO) SetTargetName(v string) { - o.TargetName = v +// SetTargetId sets field value +func (o *WorkspaceDTO) SetTargetId(v string) { + o.TargetId = v } // GetUser returns the User field value @@ -409,8 +409,8 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.State) { toSerialize["state"] = o.State } + toSerialize["target"] = o.Target toSerialize["targetId"] = o.TargetId - toSerialize["targetName"] = o.TargetName toSerialize["user"] = o.User return toSerialize, nil } @@ -425,8 +425,8 @@ func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { "image", "name", "repository", + "target", "targetId", - "targetName", "user", } diff --git a/pkg/apikey/store.go b/pkg/apikey/store.go deleted file mode 100644 index be44c9dd10..0000000000 --- a/pkg/apikey/store.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package apikey - -import "errors" - -type Store interface { - List() ([]*ApiKey, error) - Find(key string) (*ApiKey, error) - FindByName(name string) (*ApiKey, error) - Save(apiKey *ApiKey) error - Delete(apiKey *ApiKey) error -} - -var ( - ErrApiKeyNotFound = errors.New("api key not found") -) - -func IsApiKeyNotFound(err error) bool { - return err.Error() == ErrApiKeyNotFound.Error() -} diff --git a/pkg/build/builder.go b/pkg/build/builder.go index 11ed46ae83..71924ce909 100644 --- a/pkg/build/builder.go +++ b/pkg/build/builder.go @@ -8,31 +8,32 @@ import ( "encoding/hex" "fmt" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" ) type IBuilder interface { - Build(build Build) (string, string, error) + Build(build models.Build) (string, string, error) CleanUp() error - Publish(build Build) error - GetImageName(build Build) (string, error) + Publish(build models.Build) error + GetImageName(build models.Build) (string, error) } type Builder struct { id string workspaceDir string image string - containerRegistry *containerregistry.ContainerRegistry - buildImageContainerRegistry *containerregistry.ContainerRegistry - buildStore Store + containerRegistry *models.ContainerRegistry + buildImageContainerRegistry *models.ContainerRegistry + buildStore builds.BuildStore buildImageNamespace string loggerFactory logs.LoggerFactory defaultWorkspaceImage string defaultWorkspaceUser string } -func (b *Builder) GetImageName(build Build) (string, error) { +func (b *Builder) GetImageName(build models.Build) (string, error) { hash, err := build.GetBuildHash() if err != nil { return "", err diff --git a/pkg/build/builder_test.go b/pkg/build/builder_test.go index e574398425..e0c308cbad 100644 --- a/pkg/build/builder_test.go +++ b/pkg/build/builder_test.go @@ -10,15 +10,17 @@ import ( git_mocks "github.com/daytonaio/daytona/internal/testing/git/mocks" builder_mocks "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" "github.com/stretchr/testify/suite" ) -var expectedBuilds []*build.Build +var expectedBuilds []*models.Build type BuilderTestSuite struct { suite.Suite mockGitService *git_mocks.MockGitService - mockBuildStore build.Store + mockBuildStore builds.BuildStore builder build.IBuilder } diff --git a/pkg/build/detect/detect.go b/pkg/build/detect/detect.go index daca0e52ae..6bbbd431e9 100644 --- a/pkg/build/detect/detect.go +++ b/pkg/build/detect/detect.go @@ -8,8 +8,8 @@ import ( "path" "path/filepath" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type BuilderType string @@ -19,7 +19,7 @@ var ( BuilderTypeImage BuilderType = "image" ) -func DetectWorkspaceBuilderType(buildConfig *buildconfig.BuildConfig, workspaceDir string, sshClient *ssh.Client) (BuilderType, error) { +func DetectWorkspaceBuilderType(buildConfig *models.BuildConfig, workspaceDir string, sshClient *ssh.Client) (BuilderType, error) { if buildConfig == nil { return BuilderTypeImage, nil } @@ -30,20 +30,20 @@ func DetectWorkspaceBuilderType(buildConfig *buildconfig.BuildConfig, workspaceD if sshClient != nil { if _, err := sshClient.ReadFile(path.Join(workspaceDir, ".devcontainer/devcontainer.json")); err == nil { - buildConfig.Devcontainer = &buildconfig.DevcontainerConfig{ + buildConfig.Devcontainer = &models.DevcontainerConfig{ FilePath: ".devcontainer/devcontainer.json", } return BuilderTypeDevcontainer, nil } if _, err := sshClient.ReadFile(path.Join(workspaceDir, ".devcontainer.json")); err == nil { - buildConfig.Devcontainer = &buildconfig.DevcontainerConfig{ + buildConfig.Devcontainer = &models.DevcontainerConfig{ FilePath: ".devcontainer.json", } return BuilderTypeDevcontainer, nil } } else { if devcontainerFilePath, pathError := findDevcontainerConfigFilePath(workspaceDir); pathError == nil { - buildConfig.Devcontainer = &buildconfig.DevcontainerConfig{ + buildConfig.Devcontainer = &models.DevcontainerConfig{ FilePath: devcontainerFilePath, } diff --git a/pkg/build/devcontainer.go b/pkg/build/devcontainer.go index 7db816de04..59e9f513a7 100644 --- a/pkg/build/devcontainer.go +++ b/pkg/build/devcontainer.go @@ -11,6 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/detect" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) @@ -27,7 +28,7 @@ type DevcontainerBuilder struct { builderDockerPort uint16 } -func (b *DevcontainerBuilder) Build(build Build) (string, string, error) { +func (b *DevcontainerBuilder) Build(build models.Build) (string, string, error) { builderType, err := detect.DetectWorkspaceBuilderType(build.BuildConfig, b.workspaceDir, nil) if err != nil { return "", "", err @@ -44,7 +45,7 @@ func (b *DevcontainerBuilder) CleanUp() error { return os.RemoveAll(b.workspaceDir) } -func (b *DevcontainerBuilder) Publish(build Build) error { +func (b *DevcontainerBuilder) Publish(build models.Build) error { buildLogger := b.loggerFactory.CreateBuildLogger(build.Id, logs.LogSourceBuilder) defer buildLogger.Close() @@ -64,7 +65,7 @@ func (b *DevcontainerBuilder) Publish(build Build) error { return dockerClient.PushImage(*build.Image, b.buildImageContainerRegistry, buildLogger) } -func (b *DevcontainerBuilder) buildDevcontainer(build Build) (string, string, error) { +func (b *DevcontainerBuilder) buildDevcontainer(build models.Build) (string, string, error) { buildLogger := b.loggerFactory.CreateBuildLogger(build.Id, logs.LogSourceBuilder) defer buildLogger.Close() diff --git a/pkg/build/factory.go b/pkg/build/factory.go index 3e8b67ffe8..367cda10b9 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -7,22 +7,23 @@ import ( "errors" "fmt" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" + "github.com/daytonaio/daytona/pkg/server/builds" "github.com/docker/docker/pkg/stringid" ) type IBuilderFactory interface { - Create(build Build, workspaceDir string) (IBuilder, error) - CheckExistingBuild(build Build) (*Build, error) + Create(build models.Build, workspaceDir string) (IBuilder, error) + CheckExistingBuild(build models.Build) (*models.Build, error) } type BuilderFactory struct { - containerRegistry *containerregistry.ContainerRegistry - buildImageContainerRegistry *containerregistry.ContainerRegistry + containerRegistry *models.ContainerRegistry + buildImageContainerRegistry *models.ContainerRegistry buildImageNamespace string - buildStore Store + buildStore builds.BuildStore loggerFactory logs.LoggerFactory image string defaultWorkspaceImage string @@ -31,9 +32,9 @@ type BuilderFactory struct { type BuilderFactoryConfig struct { Image string - ContainerRegistry *containerregistry.ContainerRegistry - BuildImageContainerRegistry *containerregistry.ContainerRegistry - BuildStore Store + ContainerRegistry *models.ContainerRegistry + BuildImageContainerRegistry *models.ContainerRegistry + BuildStore builds.BuildStore BuildImageNamespace string // Namespace to be used when tagging and pushing the build image LoggerFactory logs.LoggerFactory DefaultWorkspaceImage string @@ -53,17 +54,17 @@ func NewBuilderFactory(config BuilderFactoryConfig) IBuilderFactory { } } -func (f *BuilderFactory) Create(build Build, workspaceDir string) (IBuilder, error) { +func (f *BuilderFactory) Create(build models.Build, workspaceDir string) (IBuilder, error) { // TODO: Implement factory logic after adding prebuilds and other builder types return f.newDevcontainerBuilder(workspaceDir) } -func (f *BuilderFactory) CheckExistingBuild(b Build) (*Build, error) { +func (f *BuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, error) { if b.Repository == nil { return nil, errors.New("repository must be set") } - build, err := f.buildStore.Find(&Filter{ + build, err := f.buildStore.Find(&builds.BuildFilter{ Branch: &b.Repository.Branch, RepositoryUrl: &b.Repository.Url, BuildConfig: b.BuildConfig, diff --git a/pkg/build/mocks/gitprovider_config_store.go b/pkg/build/mocks/gitprovider_config_store.go index 46f18054ef..cd9a14aa79 100644 --- a/pkg/build/mocks/gitprovider_config_store.go +++ b/pkg/build/mocks/gitprovider_config_store.go @@ -4,7 +4,7 @@ package build import ( - "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/mock" ) @@ -12,7 +12,7 @@ type MockGitProviderConfigStore struct { mock.Mock } -func (s *MockGitProviderConfigStore) ListConfigsForUrl(url string) ([]*gitprovider.GitProviderConfig, error) { +func (s *MockGitProviderConfigStore) ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) { args := s.Called(url) - return args.Get(0).([]*gitprovider.GitProviderConfig), args.Error(1) + return args.Get(0).([]*models.GitProviderConfig), args.Error(1) } diff --git a/pkg/build/runner.go b/pkg/build/runner.go index d18510b861..3a9918718e 100644 --- a/pkg/build/runner.go +++ b/pkg/build/runner.go @@ -10,12 +10,12 @@ import ( "sync" "github.com/charmbracelet/lipgloss" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/scheduler" + "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/docker/docker/client" "github.com/go-git/go-git/v5/plumbing/transport/http" @@ -26,9 +26,9 @@ type BuildRunnerInstanceConfig struct { Interval string Scheduler scheduler.IScheduler BuildRunnerId string - ContainerRegistry *containerregistry.ContainerRegistry + ContainerRegistry *models.ContainerRegistry GitProviderStore GitProviderStore - BuildStore Store + BuildStore builds.BuildStore BuilderFactory IBuilderFactory LoggerFactory logs.LoggerFactory BasePath string @@ -40,9 +40,9 @@ type BuildRunner struct { Id string scheduler scheduler.IScheduler runInterval string - containerRegistry *containerregistry.ContainerRegistry + containerRegistry *models.ContainerRegistry gitProviderStore GitProviderStore - buildStore Store + buildStore builds.BuildStore builderFactory IBuilderFactory loggerFactory logs.LoggerFactory basePath string @@ -53,14 +53,14 @@ type BuildRunner struct { type BuildProcessConfig struct { Builder IBuilder BuildLogger logs.Logger - Build *Build + Build *models.Build WorkspaceDir string GitService git.IGitService Wg *sync.WaitGroup } type GitProviderStore interface { - ListConfigsForUrl(url string) ([]*gitprovider.GitProviderConfig, error) + ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) } func NewBuildRunner(config BuildRunnerInstanceConfig) *BuildRunner { @@ -100,8 +100,8 @@ func (r *BuildRunner) Stop() { } func (r *BuildRunner) RunBuilds() { - builds, err := r.buildStore.List(&Filter{ - States: &[]BuildState{BuildStatePendingRun, BuildStatePublished}, + builds, err := r.buildStore.List(&builds.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePendingRun, models.BuildStatePublished}, }) if err != nil { log.Error(err) @@ -110,7 +110,7 @@ func (r *BuildRunner) RunBuilds() { var wg sync.WaitGroup for _, b := range builds { - if b.State == BuildStatePendingRun { + if b.State == models.BuildStatePendingRun { wg.Add(1) if b.BuildConfig == nil { @@ -142,7 +142,7 @@ func (r *BuildRunner) RunBuilds() { _, _, err = cli.ImageInspectWithRaw(context.Background(), imageName) if err == nil { - b.State = BuildStatePublished + b.State = models.BuildStatePublished err = r.buildStore.Save(b) if err != nil { r.handleBuildError(*b, builder, err, buildLogger) @@ -151,7 +151,7 @@ func (r *BuildRunner) RunBuilds() { return } - b.BuildConfig.CachedBuild = GetCachedBuild(b, builds) + b.BuildConfig.CachedBuild = models.GetCachedBuild(b, builds) go r.RunBuildProcess(BuildProcessConfig{ Builder: builder, @@ -171,8 +171,8 @@ func (r *BuildRunner) RunBuilds() { } func (r *BuildRunner) DeleteBuilds() { - markedForDeletionBuilds, err := r.buildStore.List(&Filter{ - States: &[]BuildState{BuildStatePendingDelete, BuildStatePendingForcedDelete}, + markedForDeletionBuilds, err := r.buildStore.List(&builds.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePendingDelete, models.BuildStatePendingForcedDelete}, }) if err != nil { log.Error(err) @@ -193,13 +193,13 @@ func (r *BuildRunner) DeleteBuilds() { for _, b := range markedForDeletionBuilds { wg.Add(1) - go func(b *Build) { + go func(b *models.Build) { buildLogger := r.loggerFactory.CreateBuildLogger(b.Id, logs.LogSourceBuilder) defer buildLogger.Close() - force := b.State == BuildStatePendingForcedDelete + force := b.State == models.BuildStatePendingForcedDelete - b.State = BuildStateDeleting + b.State = models.BuildStateDeleting err = r.buildStore.Save(b) if err != nil { r.handleBuildError(*b, nil, err, buildLogger) @@ -233,7 +233,7 @@ func (r *BuildRunner) RunBuildProcess(config BuildProcessConfig) { defer config.Wg.Done() } - config.Build.State = BuildStateRunning + config.Build.State = models.BuildStateRunning err := r.buildStore.Save(config.Build) if err != nil { r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) @@ -267,7 +267,7 @@ func (r *BuildRunner) RunBuildProcess(config BuildProcessConfig) { config.Build.Image = &image config.Build.User = &user - config.Build.State = BuildStateSuccess + config.Build.State = models.BuildStateSuccess err = r.buildStore.Save(config.Build) if err != nil { r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) @@ -280,7 +280,7 @@ func (r *BuildRunner) RunBuildProcess(config BuildProcessConfig) { return } - config.Build.State = BuildStatePublished + config.Build.State = models.BuildStatePublished err = r.buildStore.Save(config.Build) if err != nil { r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) @@ -300,13 +300,13 @@ func (r *BuildRunner) RunBuildProcess(config BuildProcessConfig) { } } -func (r *BuildRunner) handleBuildError(b Build, builder IBuilder, err error, buildLogger logs.Logger) { +func (r *BuildRunner) handleBuildError(b models.Build, builder IBuilder, err error, buildLogger logs.Logger) { var errMsg string errMsg += "################################################\n" errMsg += fmt.Sprintf("#### BUILD FAILED FOR %s: %s\n", b.Id, err.Error()) errMsg += "################################################\n" - b.State = BuildStateError + b.State = models.BuildStateError err = r.buildStore.Save(&b) if err != nil { errMsg += fmt.Sprintf("Error saving build: %s\n", err.Error()) @@ -326,7 +326,7 @@ func (r *BuildRunner) handleBuildError(b Build, builder IBuilder, err error, bui } } -func (r *BuildRunner) logTelemetry(ctx context.Context, b Build, err error) { +func (r *BuildRunner) logTelemetry(ctx context.Context, b models.Build, err error) { telemetryProps := telemetry.NewBuildRunnerEventProps(ctx, b.Id, string(b.State)) event := telemetry.BuildRunnerEventRunBuild if err != nil { diff --git a/pkg/build/runner_test.go b/pkg/build/runner_test.go index d9d5a0ece3..ee7ea69368 100644 --- a/pkg/build/runner_test.go +++ b/pkg/build/runner_test.go @@ -13,14 +13,15 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" t_gitprovider "github.com/daytonaio/daytona/pkg/build/mocks" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" ) -var gitProviderConfig = gitprovider.GitProviderConfig{ +var gitProviderConfig = models.GitProviderConfig{ Id: "github", Username: "daytonaio", Token: "", @@ -34,7 +35,7 @@ type BuildRunnerTestSuite struct { mockScheduler mocks.MockScheduler mockGitService git_mocks.MockGitService loggerFactory logs.LoggerFactory - mockBuildStore build.Store + mockBuildStore builds.BuildStore mockGitProviderConfigStore t_gitprovider.MockGitProviderConfigStore Runner build.BuildRunner } @@ -103,7 +104,7 @@ func (s *BuildRunnerTestSuite) TestRun() { func (s *BuildRunnerTestSuite) TestRunBuildProcess() { pendingBuild := *mocks.MockBuild - s.mockGitProviderConfigStore.On("ListConfigsForUrl", pendingBuild.Repository.Url).Return([]*gitprovider.GitProviderConfig{&gitProviderConfig}, nil) + s.mockGitProviderConfigStore.On("ListConfigsForUrl", pendingBuild.Repository.Url).Return([]*models.GitProviderConfig{&gitProviderConfig}, nil) s.mockGitService.On("CloneRepository", pendingBuild.Repository, &http.BasicAuth{ Username: gitProviderConfig.Username, }).Return(nil) @@ -114,11 +115,11 @@ func (s *BuildRunnerTestSuite) TestRunBuildProcess() { }).Return(nil) runningBuild := *mocks.MockBuild - runningBuild.State = build.BuildStateRunning + runningBuild.State = models.BuildStateRunning s.mockBuilder.On("Build", runningBuild).Return("image", "user", nil) successBuild := *mocks.MockBuild - successBuild.State = build.BuildStateSuccess + successBuild.State = models.BuildStateSuccess successBuild.Image = util.Pointer("image") successBuild.User = util.Pointer("user") s.mockBuilder.On("Publish", successBuild).Return(nil) @@ -143,5 +144,5 @@ func (s *BuildRunnerTestSuite) TestRunBuildProcess() { s.Require().Equal(mocks.MockBuild.Image, util.Pointer("image")) s.Require().Equal(mocks.MockBuild.User, util.Pointer("user")) - s.Require().Equal(mocks.MockBuild.State, build.BuildStatePublished) + s.Require().Equal(mocks.MockBuild.State, models.BuildStatePublished) } diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index ee1ebf21bf..23153b3455 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -21,7 +21,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -49,7 +49,7 @@ var AgentCmd = &cobra.Command{ telemetryEnabled := os.Getenv("DAYTONA_TELEMETRY_ENABLED") == "true" - var ws *workspace.Workspace + var ws *models.Workspace c.WorkspaceDir = os.Getenv("HOME") if agentMode == agent_config.ModeWorkspace { @@ -100,7 +100,7 @@ var AgentCmd = &cobra.Command{ tailscaleHostname := c.TargetId if agentMode == agent_config.ModeWorkspace { - tailscaleHostname = workspace.GetWorkspaceHostname(c.WorkspaceId) + tailscaleHostname = ws.Hostname() } toolBoxServer := &toolbox.Server{ @@ -149,7 +149,7 @@ func setLogLevel() { } } -func getWorkspace(c *agent_config.Config, telemetryEnabled bool) (*workspace.Workspace, error) { +func getWorkspace(c *agent_config.Config, telemetryEnabled bool) (*models.Workspace, error) { ctx := context.Background() apiClient, err := apiclient_util.GetAgentApiClient(c.Server.ApiUrl, c.Server.ApiKey, c.ClientId, telemetryEnabled) diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 971f3341bf..9c30713e09 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -18,11 +18,10 @@ import ( "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/api" - "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/db" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/provisioner" @@ -31,12 +30,13 @@ import ( "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" + gp_util "github.com/daytonaio/daytona/pkg/server/gitproviders/util" "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" @@ -271,12 +271,12 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ ConfigStore: gitProviderConfigStore, - WorkspaceConfigStore: workspaceConfigStore, + WorkspaceConfigStore: gp_util.FromWorkspaceConfigStore(workspaceConfigStore), }) prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) - workspaceConfigService := workspaceconfig.NewWorkspaceConfigService(workspaceconfig.WorkspaceConfigServiceConfig{ + workspaceConfigService := workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ PrebuildWebhookEndpoint: prebuildWebhookEndpoint, ConfigStore: workspaceConfigStore, BuildService: buildService, @@ -301,7 +301,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if c.BuilderRegistryServer == "local" { cr, err := containerRegistryService.FindByImageName(c.LocalBuilderRegistryImage) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { return nil, err } @@ -445,19 +445,19 @@ func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetry Store: containerRegistryStore, }) - var buildImageCr *containerregistry.ContainerRegistry + var builderRegistry *models.ContainerRegistry if c.BuilderRegistryServer != "local" { - buildImageCr, err = containerRegistryService.Find(c.BuilderRegistryServer) + builderRegistry, err = containerRegistryService.Find(c.BuilderRegistryServer) if err != nil { - buildImageCr = &containerregistry.ContainerRegistry{ + builderRegistry = &models.ContainerRegistry{ Server: c.BuilderRegistryServer, } } } cr, err := containerRegistryService.FindByImageName(c.BuilderImage) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { return nil, err } @@ -469,7 +469,7 @@ func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetry builderFactory := build.NewBuilderFactory(build.BuilderFactoryConfig{ Image: c.BuilderImage, ContainerRegistry: cr, - BuildImageContainerRegistry: buildImageCr, + BuildImageContainerRegistry: builderRegistry, BuildStore: buildStore, BuildImageNamespace: buildImageNamespace, LoggerFactory: loggerFactory, @@ -481,7 +481,7 @@ func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetry Interval: buildRunnerConfig.Interval, Scheduler: build.NewCronScheduler(), BuildRunnerId: buildRunnerConfig.Id, - ContainerRegistry: buildImageCr, + ContainerRegistry: builderRegistry, TelemetryEnabled: buildRunnerConfig.TelemetryEnabled, GitProviderStore: gitProviderService, BuildStore: buildStore, @@ -546,7 +546,7 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { } } - apiKey, err := server.ApiKeyService.Generate(apikey.ApiKeyTypeClient, "default") + apiKey, err := server.ApiKeyService.Generate(models.ApiKeyTypeClient, "default") if err != nil { return err } diff --git a/pkg/cmd/workspace/common/get_gpg_key.go b/pkg/cmd/workspace/common/get_gpg_key.go index 516c13d7aa..da917cd0b0 100644 --- a/pkg/cmd/workspace/common/get_gpg_key.go +++ b/pkg/cmd/workspace/common/get_gpg_key.go @@ -8,7 +8,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" ) func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (string, error) { @@ -16,7 +16,7 @@ func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, p return "", nil } - var providerConfig *gitprovider.GitProviderConfig + var providerConfig *models.GitProviderConfig var gpgKey string gitProvider, res, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *providerConfigId).Execute() @@ -26,13 +26,13 @@ func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, p // Extract GPG key if present if gitProvider != nil { - providerConfig = &gitprovider.GitProviderConfig{ - SigningMethod: (*gitprovider.SigningMethod)(gitProvider.SigningMethod), + providerConfig = &models.GitProviderConfig{ + SigningMethod: (*models.SigningMethod)(gitProvider.SigningMethod), SigningKey: gitProvider.SigningKey, } if providerConfig.SigningMethod != nil && providerConfig.SigningKey != nil { - if *providerConfig.SigningMethod == gitprovider.SigningMethodGPG { + if *providerConfig.SigningMethod == models.SigningMethodGPG { gpgKey = *providerConfig.SigningKey } } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 3c4c7ce826..25b88cae4a 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -19,11 +19,11 @@ import ( workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/views" logs_view "github.com/daytonaio/daytona/pkg/views/logs" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/info" - "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" "tailscale.com/tsnet" @@ -339,7 +339,7 @@ func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile go func() { for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(workspaceId), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", models.Workspace{Id: workspaceId}.Hostname(), ssh_config.SSH_PORT)) if err == nil { connectChan <- dialConn.Close() return diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index 05b45d2419..e9fe822178 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -17,7 +17,7 @@ import ( ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" @@ -125,7 +125,7 @@ var SshProxyCmd = &cobra.Command{ errChan := make(chan error) - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", workspace.GetWorkspaceHostname(ws.Id), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", models.Workspace{Id: ws.Id}.Hostname(), ssh_config.SSH_PORT)) if err != nil { return err } diff --git a/pkg/cmd/workspaceconfig/export.go b/pkg/cmd/workspaceconfig/export.go index 784d36a28c..0e6c1467e9 100644 --- a/pkg/cmd/workspaceconfig/export.go +++ b/pkg/cmd/workspaceconfig/export.go @@ -14,8 +14,8 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) diff --git a/pkg/cmd/workspaceconfig/import.go b/pkg/cmd/workspaceconfig/import.go index 7c0cce2f58..49cc7c835b 100644 --- a/pkg/cmd/workspaceconfig/import.go +++ b/pkg/cmd/workspaceconfig/import.go @@ -16,9 +16,9 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/create" - "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" ) @@ -212,7 +212,7 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, return err } - submissionFormConfig := create.SubmissionFormConfig{ + submissionFormConfig := create.SubmissionFormParams{ ChosenName: &config.Name, SuggestedName: config.Name, ExistingWorkspaceNames: existingWorkspaceConfigNames, diff --git a/pkg/containerregistry/store.go b/pkg/containerregistry/store.go deleted file mode 100644 index b949af8701..0000000000 --- a/pkg/containerregistry/store.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import "errors" - -type Store interface { - List() ([]*ContainerRegistry, error) - Find(server string) (*ContainerRegistry, error) - Save(cr *ContainerRegistry) error - Delete(cr *ContainerRegistry) error -} - -var ( - ErrContainerRegistryNotFound = errors.New("container registry not found") -) - -func IsContainerRegistryNotFound(err error) bool { - return err.Error() == ErrContainerRegistryNotFound.Error() -} diff --git a/pkg/db/api_key_store.go b/pkg/db/api_key_store.go index c97647e7d1..9fee7b886e 100644 --- a/pkg/db/api_key_store.go +++ b/pkg/db/api_key_store.go @@ -4,8 +4,8 @@ package db import ( - "github.com/daytonaio/daytona/pkg/apikey" - . "github.com/daytonaio/daytona/pkg/db/dto" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/apikeys" "gorm.io/gorm" ) @@ -14,7 +14,7 @@ type ApiKeyStore struct { } func NewApiKeyStore(db *gorm.DB) (*ApiKeyStore, error) { - err := db.AutoMigrate(&ApiKeyDTO{}) + err := db.AutoMigrate(&models.ApiKey{}) if err != nil { return nil, err } @@ -22,54 +22,44 @@ func NewApiKeyStore(db *gorm.DB) (*ApiKeyStore, error) { return &ApiKeyStore{db: db}, nil } -func (a *ApiKeyStore) List() ([]*apikey.ApiKey, error) { - apiKeyDTOs := []ApiKeyDTO{} - tx := a.db.Find(&apiKeyDTOs) +func (a *ApiKeyStore) List() ([]*models.ApiKey, error) { + apiKeys := []*models.ApiKey{} + tx := a.db.Find(&apiKeys) if tx.Error != nil { return nil, tx.Error } - apiKeys := []*apikey.ApiKey{} - for _, apiKeyDTO := range apiKeyDTOs { - apiKey := ToApiKey(apiKeyDTO) - apiKeys = append(apiKeys, &apiKey) - } return apiKeys, nil } -func (a *ApiKeyStore) Find(key string) (*apikey.ApiKey, error) { - apiKeyDTO := ApiKeyDTO{} - tx := a.db.Where("key_hash = ?", key).First(&apiKeyDTO) +func (a *ApiKeyStore) Find(key string) (*models.ApiKey, error) { + apiKey := &models.ApiKey{} + tx := a.db.Where("key_hash = ?", key).First(apiKey) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, apikey.ErrApiKeyNotFound + return nil, apikeys.ErrApiKeyNotFound } return nil, tx.Error } - apiKey := ToApiKey(apiKeyDTO) - - return &apiKey, nil + return apiKey, nil } -func (a *ApiKeyStore) FindByName(name string) (*apikey.ApiKey, error) { - apiKeyDTO := ApiKeyDTO{} - tx := a.db.Where("name = ?", name).First(&apiKeyDTO) +func (a *ApiKeyStore) FindByName(name string) (*models.ApiKey, error) { + apiKey := &models.ApiKey{} + tx := a.db.Where("name = ?", name).First(apiKey) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, apikey.ErrApiKeyNotFound + return nil, apikeys.ErrApiKeyNotFound } return nil, tx.Error } - apiKey := ToApiKey(apiKeyDTO) - - return &apiKey, nil + return apiKey, nil } -func (a *ApiKeyStore) Save(apiKey *apikey.ApiKey) error { - apiKeyDTO := ToApiKeyDTO(*apiKey) - tx := a.db.Save(&apiKeyDTO) +func (a *ApiKeyStore) Save(apiKey *models.ApiKey) error { + tx := a.db.Save(apiKey) if tx.Error != nil { return tx.Error } @@ -77,13 +67,13 @@ func (a *ApiKeyStore) Save(apiKey *apikey.ApiKey) error { return nil } -func (a *ApiKeyStore) Delete(apiKey *apikey.ApiKey) error { - tx := a.db.Where("key_hash = ?", apiKey.KeyHash).Delete(&ApiKeyDTO{}) +func (a *ApiKeyStore) Delete(apiKey *models.ApiKey) error { + tx := a.db.Where("key_hash = ?", apiKey.KeyHash).Delete(&models.ApiKey{}) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return apikey.ErrApiKeyNotFound + return apikeys.ErrApiKeyNotFound } return nil diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index 0440a6aff5..ad85aa0294 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -9,9 +9,8 @@ import ( "strings" "sync" - "github.com/daytonaio/daytona/pkg/build" - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" "gorm.io/gorm" ) @@ -21,7 +20,7 @@ type BuildStore struct { } func NewBuildStore(db *gorm.DB) (*BuildStore, error) { - err := db.AutoMigrate(&BuildDTO{}) + err := db.AutoMigrate(&models.Build{}) if err != nil { return nil, err } @@ -29,50 +28,42 @@ func NewBuildStore(db *gorm.DB) (*BuildStore, error) { return &BuildStore{db: db}, nil } -func (b *BuildStore) Find(filter *build.Filter) (*build.Build, error) { +func (b *BuildStore) Find(filter *builds.BuildFilter) (*models.Build, error) { b.Lock.Lock() defer b.Lock.Unlock() - buildDTO := BuildDTO{} - tx := processBuildFilters(b.db, filter).First(&buildDTO) + build := &models.Build{} + tx := processBuildFilters(b.db, filter).First(build) if tx.Error != nil { if tx.Error == gorm.ErrRecordNotFound { - return nil, build.ErrBuildNotFound + return nil, builds.ErrBuildNotFound } return nil, tx.Error } - build := ToBuild(buildDTO) - return build, nil } -func (b *BuildStore) List(filter *build.Filter) ([]*build.Build, error) { +func (b *BuildStore) List(filter *builds.BuildFilter) ([]*models.Build, error) { b.Lock.Lock() defer b.Lock.Unlock() - buildDTOs := []BuildDTO{} - tx := processBuildFilters(b.db, filter).Find(&buildDTOs) + builds := []*models.Build{} + tx := processBuildFilters(b.db, filter).Find(&builds) if tx.Error != nil { return nil, tx.Error } - builds := []*build.Build{} - for _, buildDTO := range buildDTOs { - builds = append(builds, ToBuild(buildDTO)) - } - return builds, nil } -func (b *BuildStore) Save(build *build.Build) error { +func (b *BuildStore) Save(build *models.Build) error { b.Lock.Lock() defer b.Lock.Unlock() - buildDTO := ToBuildDTO(build) - tx := b.db.Save(&buildDTO) + tx := b.db.Save(build) if tx.Error != nil { return tx.Error } @@ -84,18 +75,18 @@ func (b *BuildStore) Delete(id string) error { b.Lock.Lock() defer b.Lock.Unlock() - tx := b.db.Where("id = ?", id).Delete(&BuildDTO{}) + tx := b.db.Where("id = ?", id).Delete(&models.Build{}) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return build.ErrBuildNotFound + return builds.ErrBuildNotFound } return nil } -func processBuildFilters(tx *gorm.DB, filter *build.Filter) *gorm.DB { +func processBuildFilters(tx *gorm.DB, filter *builds.BuildFilter) *gorm.DB { if filter != nil { if filter.Id != nil { tx = tx.Where("id = ?", *filter.Id) @@ -116,7 +107,7 @@ func processBuildFilters(tx *gorm.DB, filter *build.Filter) *gorm.DB { tx = tx.Order("created_at desc").Limit(1) } // Skip filtering when an automatic build config is provided - if filter.BuildConfig != nil && *filter.BuildConfig != (buildconfig.BuildConfig{}) { + if filter.BuildConfig != nil && *filter.BuildConfig != (models.BuildConfig{}) { buildConfigJSON, err := json.Marshal(filter.BuildConfig) if err == nil { tx = tx.Where("build_config = ?", string(buildConfigJSON)) diff --git a/pkg/db/container_registry_store.go b/pkg/db/container_registry_store.go index 3ef33d7062..55c956d927 100644 --- a/pkg/db/container_registry_store.go +++ b/pkg/db/container_registry_store.go @@ -6,8 +6,8 @@ package db import ( "gorm.io/gorm" - "github.com/daytonaio/daytona/pkg/containerregistry" - . "github.com/daytonaio/daytona/pkg/db/dto" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/containerregistries" ) type ContainerRegistryStore struct { @@ -15,7 +15,7 @@ type ContainerRegistryStore struct { } func NewContainerRegistryStore(db *gorm.DB) (*ContainerRegistryStore, error) { - err := db.AutoMigrate(&ContainerRegistryDTO{}) + err := db.AutoMigrate(&models.ContainerRegistry{}) if err != nil { return nil, err } @@ -23,36 +23,31 @@ func NewContainerRegistryStore(db *gorm.DB) (*ContainerRegistryStore, error) { return &ContainerRegistryStore{db: db}, nil } -func (s *ContainerRegistryStore) List() ([]*containerregistry.ContainerRegistry, error) { - containerRegistryDTOs := []ContainerRegistryDTO{} - tx := s.db.Find(&containerRegistryDTOs) +func (s *ContainerRegistryStore) List() ([]*models.ContainerRegistry, error) { + containerRegistries := []*models.ContainerRegistry{} + tx := s.db.Find(&containerRegistries) if tx.Error != nil { return nil, tx.Error } - containerRegistries := []*containerregistry.ContainerRegistry{} - for _, containerRegistryDTO := range containerRegistryDTOs { - containerRegistries = append(containerRegistries, ToContainerRegistry(containerRegistryDTO)) - } - return containerRegistries, nil } -func (s *ContainerRegistryStore) Find(server string) (*containerregistry.ContainerRegistry, error) { - containerRegistryDTO := ContainerRegistryDTO{} - tx := s.db.Where("server = ?", server).First(&containerRegistryDTO) +func (s *ContainerRegistryStore) Find(server string) (*models.ContainerRegistry, error) { + containerRegistry := &models.ContainerRegistry{} + tx := s.db.Where("server = ?", server).First(containerRegistry) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, containerregistry.ErrContainerRegistryNotFound + return nil, containerregistries.ErrContainerRegistryNotFound } return nil, tx.Error } - return ToContainerRegistry(containerRegistryDTO), nil + return containerRegistry, nil } -func (s *ContainerRegistryStore) Save(cr *containerregistry.ContainerRegistry) error { - tx := s.db.Save(ToContainerRegistryDTO(cr)) +func (s *ContainerRegistryStore) Save(cr *models.ContainerRegistry) error { + tx := s.db.Save(cr) if tx.Error != nil { return tx.Error } @@ -60,13 +55,13 @@ func (s *ContainerRegistryStore) Save(cr *containerregistry.ContainerRegistry) e return nil } -func (s *ContainerRegistryStore) Delete(cr *containerregistry.ContainerRegistry) error { - tx := s.db.Delete(ToContainerRegistryDTO(cr)) +func (s *ContainerRegistryStore) Delete(cr *models.ContainerRegistry) error { + tx := s.db.Delete(cr) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return containerregistry.ErrContainerRegistryNotFound + return containerregistries.ErrContainerRegistryNotFound } return nil diff --git a/pkg/db/dto/api_key.go b/pkg/db/dto/api_key.go deleted file mode 100644 index 4de69738f1..0000000000 --- a/pkg/db/dto/api_key.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/apikey" -) - -type ApiKeyDTO struct { - KeyHash string `gorm:"primaryKey"` - Type apikey.ApiKeyType - Name string `gorm:"uniqueIndex"` -} - -func ToApiKeyDTO(apiKey apikey.ApiKey) ApiKeyDTO { - return ApiKeyDTO{ - KeyHash: apiKey.KeyHash, - Type: apiKey.Type, - Name: apiKey.Name, - } -} - -func ToApiKey(apiKeyDTO ApiKeyDTO) apikey.ApiKey { - return apikey.ApiKey{ - KeyHash: apiKeyDTO.KeyHash, - Type: apiKeyDTO.Type, - Name: apiKeyDTO.Name, - } -} diff --git a/pkg/db/dto/build.go b/pkg/db/dto/build.go deleted file mode 100644 index b74299b9a6..0000000000 --- a/pkg/db/dto/build.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "time" - - "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/workspace/containerconfig" -) - -type BuildDTO struct { - Id string `json:"id" gorm:"primaryKey"` - State string `json:"state"` - Image *string `json:"image,omitempty"` - User *string `json:"user,omitempty"` - ContainerConfig containerconfig.ContainerConfig `gorm:"serializer:json"` - BuildConfig *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` - Repository RepositoryDTO `gorm:"serializer:json"` - EnvVars map[string]string `json:"envVars" gorm:"serializer:json"` - PrebuildId string `json:"prebuildId"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` -} - -func ToBuildDTO(build *build.Build) BuildDTO { - return BuildDTO{ - Id: build.Id, - State: string(build.State), - Image: build.Image, - User: build.User, - ContainerConfig: build.ContainerConfig, - BuildConfig: ToWorkspaceBuildDTO(build.BuildConfig), - Repository: ToRepositoryDTO(build.Repository), - EnvVars: build.EnvVars, - PrebuildId: build.PrebuildId, - CreatedAt: build.CreatedAt, - UpdatedAt: build.UpdatedAt, - } -} - -func ToBuild(buildDTO BuildDTO) *build.Build { - return &build.Build{ - Id: buildDTO.Id, - State: build.BuildState(buildDTO.State), - Image: buildDTO.Image, - User: buildDTO.User, - ContainerConfig: buildDTO.ContainerConfig, - BuildConfig: ToWorkspaceBuild(buildDTO.BuildConfig), - Repository: ToRepository(buildDTO.Repository), - EnvVars: buildDTO.EnvVars, - PrebuildId: buildDTO.PrebuildId, - CreatedAt: buildDTO.CreatedAt, - UpdatedAt: buildDTO.UpdatedAt, - } -} diff --git a/pkg/db/dto/container_registry.go b/pkg/db/dto/container_registry.go deleted file mode 100644 index c5ae103957..0000000000 --- a/pkg/db/dto/container_registry.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/containerregistry" -) - -type ContainerRegistryDTO struct { - Server string `gorm:"primaryKey"` - Username string `json:"username"` - Password string `json:"password"` -} - -func ToContainerRegistryDTO(cr *containerregistry.ContainerRegistry) ContainerRegistryDTO { - dto := ContainerRegistryDTO{ - Server: cr.Server, - Username: cr.Username, - Password: cr.Password, - } - - return dto -} - -func ToContainerRegistry(dto ContainerRegistryDTO) *containerregistry.ContainerRegistry { - cr := containerregistry.ContainerRegistry{ - Server: dto.Server, - Username: dto.Username, - Password: dto.Password, - } - - return &cr -} diff --git a/pkg/db/dto/git_provider.go b/pkg/db/dto/git_provider.go deleted file mode 100644 index d08bb586e7..0000000000 --- a/pkg/db/dto/git_provider.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/gitprovider" -) - -type GitProviderConfigDTO struct { - Id string `gorm:"primaryKey"` - ProviderId string `json:"providerId"` - Username string `json:"username"` - Token string `json:"token"` - BaseApiUrl *string `json:"baseApiUrl,omitempty"` - Alias string `gorm:"uniqueIndex" json:"alias"` - SigningKey *string `json:"siginingKey,omitempty"` - SigningMethod *gitprovider.SigningMethod `json:"siginingMethod,omitempty"` -} - -func ToGitProviderConfigDTO(gitProvider gitprovider.GitProviderConfig) GitProviderConfigDTO { - gitProviderDTO := GitProviderConfigDTO{ - Id: gitProvider.Id, - ProviderId: gitProvider.ProviderId, - Username: gitProvider.Username, - Token: gitProvider.Token, - BaseApiUrl: gitProvider.BaseApiUrl, - Alias: gitProvider.Alias, - SigningKey: gitProvider.SigningKey, - SigningMethod: gitProvider.SigningMethod, - } - - return gitProviderDTO -} - -func ToGitProviderConfig(gitProviderDTO GitProviderConfigDTO) gitprovider.GitProviderConfig { - return gitprovider.GitProviderConfig{ - Id: gitProviderDTO.Id, - ProviderId: gitProviderDTO.ProviderId, - Username: gitProviderDTO.Username, - Token: gitProviderDTO.Token, - BaseApiUrl: gitProviderDTO.BaseApiUrl, - Alias: gitProviderDTO.Alias, - SigningKey: gitProviderDTO.SigningKey, - SigningMethod: gitProviderDTO.SigningMethod, - } -} diff --git a/pkg/db/dto/profile_data.go b/pkg/db/dto/profile_data.go deleted file mode 100644 index 4dbb448adb..0000000000 --- a/pkg/db/dto/profile_data.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import "github.com/daytonaio/daytona/pkg/profiledata" - -const ProfileDataId = "profile_data" - -type ProfileDataDTO struct { - Id string `gorm:"primaryKey"` - EnvVars map[string]string `gorm:"serializer:json"` -} - -func ToProfileDataDTO(profileData *profiledata.ProfileData) ProfileDataDTO { - return ProfileDataDTO{ - Id: ProfileDataId, - EnvVars: profileData.EnvVars, - } -} - -func ToProfileData(profileDataDTO ProfileDataDTO) *profiledata.ProfileData { - return &profiledata.ProfileData{ - EnvVars: profileDataDTO.EnvVars, - } -} diff --git a/pkg/db/dto/target.go b/pkg/db/dto/target.go deleted file mode 100644 index 028d91b3d3..0000000000 --- a/pkg/db/dto/target.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/target" -) - -type TargetDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name" gorm:"unique"` - ProviderInfo ProviderInfoDTO `json:"providerInfo" gorm:"serializer:json"` - Options string `json:"options"` - ApiKey string `json:"apiKey"` - IsDefault bool `json:"isDefault"` - Workspaces []WorkspaceDTO `gorm:"foreignKey:TargetId;references:Id"` -} - -type ProviderInfoDTO struct { - Name string `json:"name" validate:"required"` - Version string `json:"version" validate:"required"` - Label *string `json:"label" validate:"optional"` -} - -func ToTargetDTO(target *target.Target) TargetDTO { - targetDTO := TargetDTO{ - Id: target.Id, - Name: target.Name, - ProviderInfo: ProviderInfoDTO{ - Name: target.ProviderInfo.Name, - Version: target.ProviderInfo.Version, - Label: target.ProviderInfo.Label, - }, - Options: target.Options, - ApiKey: target.ApiKey, - IsDefault: target.IsDefault, - } - - return targetDTO -} - -func ToTarget(targetDTO TargetDTO) *target.Target { - target := target.Target{ - Id: targetDTO.Id, - Name: targetDTO.Name, - ProviderInfo: target.ProviderInfo{ - Name: targetDTO.ProviderInfo.Name, - Version: targetDTO.ProviderInfo.Version, - Label: targetDTO.ProviderInfo.Label, - }, - Options: targetDTO.Options, - IsDefault: targetDTO.IsDefault, - ApiKey: targetDTO.ApiKey, - } - - return &target -} - -func ToTargetViewDTO(targetDto TargetDTO) *target.TargetViewDTO { - return &target.TargetViewDTO{ - Target: *ToTarget(targetDto), - WorkspaceCount: len(targetDto.Workspaces), - } -} diff --git a/pkg/db/dto/target_config.go b/pkg/db/dto/target_config.go deleted file mode 100644 index ea9f79280f..0000000000 --- a/pkg/db/dto/target_config.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" -) - -type TargetConfigDTO struct { - Name string `json:"name" gorm:"primaryKey"` - ProviderInfo ProviderInfoDTO `json:"providerInfo" gorm:"serializer:json"` - Options string `json:"options"` -} - -func ToTargetConfigDTO(targetConfig *config.TargetConfig) TargetConfigDTO { - return TargetConfigDTO{ - Name: targetConfig.Name, - ProviderInfo: ProviderInfoDTO{ - Name: targetConfig.ProviderInfo.Name, - Version: targetConfig.ProviderInfo.Version, - Label: targetConfig.ProviderInfo.Label, - }, - Options: targetConfig.Options, - } -} - -func ToTargetConfig(targetConfigDTO TargetConfigDTO) *config.TargetConfig { - return &config.TargetConfig{ - Name: targetConfigDTO.Name, - ProviderInfo: target.ProviderInfo{ - Name: targetConfigDTO.ProviderInfo.Name, - Version: targetConfigDTO.ProviderInfo.Version, - Label: targetConfigDTO.ProviderInfo.Label, - }, - Options: targetConfigDTO.Options, - } -} diff --git a/pkg/db/dto/workspace.go b/pkg/db/dto/workspace.go deleted file mode 100644 index 76d75efa25..0000000000 --- a/pkg/db/dto/workspace.go +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" -) - -type RepositoryDTO struct { - Id string `json:"id"` - Url string `json:"url"` - Name string `json:"name"` - Owner string `json:"owner"` - Sha string `json:"sha"` - Source string `json:"source"` - Branch string `json:"branch"` - PrNumber *uint32 `json:"prNumber,omitempty"` - Path *string `json:"path,omitempty"` - Target gitprovider.CloneTarget `json:"cloneTarget,omitempty"` -} - -type FileStatusDTO struct { - Name string `json:"name"` - Extra string `json:"extra"` - Staging string `json:"staging"` - Worktree string `json:"worktree"` -} - -type GitStatusDTO struct { - CurrentBranch string `json:"currentBranch"` - Files []*FileStatusDTO `json:"fileStatus"` - BranchPublished bool `json:"branchPublished,omitempty"` - Ahead int32 `json:"ahead,omitempty"` - Behind int32 `json:"behind,omitempty"` -} - -type WorkspaceStateDTO struct { - UpdatedAt string `json:"updatedAt"` - Uptime uint64 `json:"uptime"` - GitStatus *GitStatusDTO `json:"gitStatus"` -} - -type WorkspaceBuildDevcontainerDTO struct { - FilePath string `json:"filePath"` -} - -type WorkspaceBuildDTO struct { - Devcontainer *WorkspaceBuildDevcontainerDTO `json:"devcontainer"` -} - -type WorkspaceDTO struct { - Id string `gorm:"primaryKey"` - Name string `json:"name"` - Image string `json:"image"` - User string `json:"user"` - Build *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` - Repository RepositoryDTO `json:"repository" gorm:"serializer:json"` - TargetId string `json:"targetId" gorm:"foreignKey:TargetId;references:Id"` - Target TargetDTO `gorm:"foreignKey:TargetId"` - ApiKey string `json:"apiKey"` - State *WorkspaceStateDTO `json:"state,omitempty" gorm:"serializer:json"` - GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` -} - -func ToWorkspaceDTO(workspace *workspace.Workspace) WorkspaceDTO { - return WorkspaceDTO{ - Id: workspace.Id, - Name: workspace.Name, - Image: workspace.Image, - User: workspace.User, - Build: ToWorkspaceBuildDTO(workspace.BuildConfig), - Repository: ToRepositoryDTO(workspace.Repository), - TargetId: workspace.TargetId, - State: ToWorkspaceStateDTO(workspace.State), - ApiKey: workspace.ApiKey, - GitProviderConfigId: workspace.GitProviderConfigId, - } -} - -func ToRepositoryDTO(repo *gitprovider.GitRepository) RepositoryDTO { - repoDTO := RepositoryDTO{ - Url: repo.Url, - Name: repo.Name, - Id: repo.Id, - Owner: repo.Owner, - Sha: repo.Sha, - Source: repo.Source, - Branch: repo.Branch, - PrNumber: repo.PrNumber, - Path: repo.Path, - Target: repo.Target, - } - - return repoDTO -} - -func ToFileStatusDTO(status *workspace.FileStatus) *FileStatusDTO { - if status == nil { - return nil - } - - return &FileStatusDTO{ - Name: status.Name, - Extra: status.Extra, - Staging: string(status.Staging), - Worktree: string(status.Worktree), - } -} - -func ToGitStatusDTO(status *workspace.GitStatus) *GitStatusDTO { - if status == nil { - return nil - } - - statusDTO := &GitStatusDTO{ - CurrentBranch: status.CurrentBranch, - BranchPublished: status.BranchPublished, - Ahead: int32(status.Ahead), - Behind: int32(status.Behind), - } - - for _, file := range status.Files { - statusDTO.Files = append(statusDTO.Files, ToFileStatusDTO(file)) - } - - return statusDTO -} - -func ToWorkspaceStateDTO(state *workspace.WorkspaceState) *WorkspaceStateDTO { - if state == nil { - return nil - } - - return &WorkspaceStateDTO{ - UpdatedAt: state.UpdatedAt, - Uptime: state.Uptime, - GitStatus: ToGitStatusDTO(state.GitStatus), - } -} - -func ToWorkspaceBuildDTO(build *buildconfig.BuildConfig) *WorkspaceBuildDTO { - if build == nil { - return nil - } - - if build.Devcontainer == nil { - return &WorkspaceBuildDTO{} - } - - return &WorkspaceBuildDTO{ - Devcontainer: &WorkspaceBuildDevcontainerDTO{ - FilePath: build.Devcontainer.FilePath, - }, - } -} - -func ToWorkspace(workspaceDTO WorkspaceDTO) *workspace.Workspace { - return &workspace.Workspace{ - Id: workspaceDTO.Id, - Name: workspaceDTO.Name, - Image: workspaceDTO.Image, - User: workspaceDTO.User, - BuildConfig: ToWorkspaceBuild(workspaceDTO.Build), - Repository: ToRepository(workspaceDTO.Repository), - TargetId: workspaceDTO.TargetId, - State: ToWorkspaceState(workspaceDTO.State), - ApiKey: workspaceDTO.ApiKey, - GitProviderConfigId: workspaceDTO.GitProviderConfigId, - } -} - -func ToFileStatus(statusDTO *FileStatusDTO) *workspace.FileStatus { - if statusDTO == nil { - return nil - } - - return &workspace.FileStatus{ - Name: statusDTO.Name, - Extra: statusDTO.Extra, - Staging: workspace.Status(statusDTO.Staging), - Worktree: workspace.Status(statusDTO.Worktree), - } -} - -func ToGitStatus(statusDTO *GitStatusDTO) *workspace.GitStatus { - if statusDTO == nil { - return nil - } - - status := &workspace.GitStatus{ - CurrentBranch: statusDTO.CurrentBranch, - BranchPublished: statusDTO.BranchPublished, - Ahead: int(statusDTO.Ahead), - Behind: int(statusDTO.Behind), - } - - for _, file := range statusDTO.Files { - status.Files = append(status.Files, ToFileStatus(file)) - } - - return status -} - -func ToWorkspaceState(stateDTO *WorkspaceStateDTO) *workspace.WorkspaceState { - if stateDTO == nil { - return nil - } - - return &workspace.WorkspaceState{ - UpdatedAt: stateDTO.UpdatedAt, - Uptime: stateDTO.Uptime, - GitStatus: ToGitStatus(stateDTO.GitStatus), - } -} - -func ToRepository(repoDTO RepositoryDTO) *gitprovider.GitRepository { - repo := gitprovider.GitRepository{ - Url: repoDTO.Url, - Id: repoDTO.Id, - Name: repoDTO.Name, - Owner: repoDTO.Owner, - Branch: repoDTO.Branch, - Sha: repoDTO.Sha, - PrNumber: repoDTO.PrNumber, - Source: repoDTO.Source, - Path: repoDTO.Path, - Target: gitprovider.CloneTarget(repoDTO.Target), - } - - return &repo -} - -func ToWorkspaceBuild(buildDTO *WorkspaceBuildDTO) *buildconfig.BuildConfig { - if buildDTO == nil { - return nil - } - - if buildDTO.Devcontainer == nil { - return &buildconfig.BuildConfig{} - } - - return &buildconfig.BuildConfig{ - Devcontainer: &buildconfig.DevcontainerConfig{ - FilePath: buildDTO.Devcontainer.FilePath, - }, - } -} - -func ToWorkspaceViewDTO(workspaceDTO WorkspaceDTO) *workspace.WorkspaceViewDTO { - return &workspace.WorkspaceViewDTO{ - Workspace: *ToWorkspace(workspaceDTO), - TargetName: workspaceDTO.Target.Name, - } -} diff --git a/pkg/db/dto/workspace_config.go b/pkg/db/dto/workspace_config.go deleted file mode 100644 index 624b31d3f2..0000000000 --- a/pkg/db/dto/workspace_config.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/workspace/config" -) - -type WorkspaceConfigDTO struct { - Name string `gorm:"primaryKey"` - Image string `json:"image"` - User string `json:"user"` - Build *WorkspaceBuildDTO `json:"build,omitempty" gorm:"serializer:json"` - RepositoryUrl string `json:"repositoryUrl"` - EnvVars map[string]string `json:"envVars" gorm:"serializer:json"` - Prebuilds []PrebuildDTO `gorm:"serializer:json"` - IsDefault bool `json:"isDefault"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} - -type PrebuildDTO struct { - Id string `json:"id"` - Branch string `json:"branch"` - CommitInterval *int `json:"commitInterval,omitempty"` - TriggerFiles []string `json:"triggerFiles,omitempty"` - Retention int `json:"retention"` -} - -func ToWorkspaceConfigDTO(workspaceConfig *config.WorkspaceConfig) WorkspaceConfigDTO { - prebuilds := []PrebuildDTO{} - for _, prebuild := range workspaceConfig.Prebuilds { - prebuilds = append(prebuilds, ToPrebuildDTO(prebuild)) - } - - return WorkspaceConfigDTO{ - Name: workspaceConfig.Name, - Image: workspaceConfig.Image, - User: workspaceConfig.User, - Build: ToWorkspaceBuildDTO(workspaceConfig.BuildConfig), - RepositoryUrl: workspaceConfig.RepositoryUrl, - EnvVars: workspaceConfig.EnvVars, - Prebuilds: prebuilds, - IsDefault: workspaceConfig.IsDefault, - GitProviderConfigId: workspaceConfig.GitProviderConfigId, - } -} - -func ToWorkspaceConfig(workspaceConfigDTO WorkspaceConfigDTO) *config.WorkspaceConfig { - prebuilds := []*config.PrebuildConfig{} - for _, prebuildDTO := range workspaceConfigDTO.Prebuilds { - prebuilds = append(prebuilds, ToPrebuild(prebuildDTO)) - } - - return &config.WorkspaceConfig{ - Name: workspaceConfigDTO.Name, - Image: workspaceConfigDTO.Image, - User: workspaceConfigDTO.User, - BuildConfig: ToWorkspaceBuild(workspaceConfigDTO.Build), - RepositoryUrl: workspaceConfigDTO.RepositoryUrl, - EnvVars: workspaceConfigDTO.EnvVars, - Prebuilds: prebuilds, - IsDefault: workspaceConfigDTO.IsDefault, - GitProviderConfigId: workspaceConfigDTO.GitProviderConfigId, - } -} - -func ToPrebuildDTO(prebuild *config.PrebuildConfig) PrebuildDTO { - return PrebuildDTO{ - Id: prebuild.Id, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, - } -} - -func ToPrebuild(prebuildDTO PrebuildDTO) *config.PrebuildConfig { - return &config.PrebuildConfig{ - Id: prebuildDTO.Id, - Branch: prebuildDTO.Branch, - CommitInterval: prebuildDTO.CommitInterval, - TriggerFiles: prebuildDTO.TriggerFiles, - Retention: prebuildDTO.Retention, - } -} diff --git a/pkg/db/gitprovider_config_store.go b/pkg/db/gitprovider_config_store.go index 07c55b4d67..b0f3cc4c97 100644 --- a/pkg/db/gitprovider_config_store.go +++ b/pkg/db/gitprovider_config_store.go @@ -6,8 +6,8 @@ package db import ( "gorm.io/gorm" - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/gitproviders" ) type GitProviderConfigStore struct { @@ -15,7 +15,7 @@ type GitProviderConfigStore struct { } func NewGitProviderConfigStore(db *gorm.DB) (*GitProviderConfigStore, error) { - err := db.AutoMigrate(&GitProviderConfigDTO{}) + err := db.AutoMigrate(&models.GitProviderConfig{}) if err != nil { return nil, err } @@ -23,40 +23,31 @@ func NewGitProviderConfigStore(db *gorm.DB) (*GitProviderConfigStore, error) { return &GitProviderConfigStore{db: db}, nil } -func (p *GitProviderConfigStore) List() ([]*gitprovider.GitProviderConfig, error) { - gitProviderDTOs := []GitProviderConfigDTO{} - tx := p.db.Find(&gitProviderDTOs) +func (p *GitProviderConfigStore) List() ([]*models.GitProviderConfig, error) { + gitProviders := []*models.GitProviderConfig{} + tx := p.db.Find(&gitProviders) if tx.Error != nil { return nil, tx.Error } - gitProviders := []*gitprovider.GitProviderConfig{} - for _, gitProviderDTO := range gitProviderDTOs { - gitProvider := ToGitProviderConfig(gitProviderDTO) - gitProviders = append(gitProviders, &gitProvider) - } - return gitProviders, nil } -func (p *GitProviderConfigStore) Find(id string) (*gitprovider.GitProviderConfig, error) { - gitProviderDTO := GitProviderConfigDTO{} - tx := p.db.Where("id = ?", id).First(&gitProviderDTO) +func (p *GitProviderConfigStore) Find(id string) (*models.GitProviderConfig, error) { + gitProvider := &models.GitProviderConfig{} + tx := p.db.Where("id = ?", id).First(gitProvider) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, gitprovider.ErrGitProviderConfigNotFound + return nil, gitproviders.ErrGitProviderConfigNotFound } return nil, tx.Error } - gitProvider := ToGitProviderConfig(gitProviderDTO) - - return &gitProvider, nil + return gitProvider, nil } -func (p *GitProviderConfigStore) Save(gitProvider *gitprovider.GitProviderConfig) error { - gitProviderDTO := ToGitProviderConfigDTO(*gitProvider) - tx := p.db.Save(&gitProviderDTO) +func (p *GitProviderConfigStore) Save(gitProvider *models.GitProviderConfig) error { + tx := p.db.Save(gitProvider) if tx.Error != nil { return tx.Error } @@ -64,14 +55,13 @@ func (p *GitProviderConfigStore) Save(gitProvider *gitprovider.GitProviderConfig return nil } -func (p *GitProviderConfigStore) Delete(gitProvider *gitprovider.GitProviderConfig) error { - gitProviderDTO := ToGitProviderConfigDTO(*gitProvider) - tx := p.db.Delete(&gitProviderDTO) +func (p *GitProviderConfigStore) Delete(gitProvider *models.GitProviderConfig) error { + tx := p.db.Delete(gitProvider) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return gitprovider.ErrGitProviderConfigNotFound + return gitproviders.ErrGitProviderConfigNotFound } return nil diff --git a/pkg/db/profile_data_store.go b/pkg/db/profile_data_store.go index 0a5589bae3..822423f98b 100644 --- a/pkg/db/profile_data_store.go +++ b/pkg/db/profile_data_store.go @@ -4,8 +4,8 @@ package db import ( - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/profiledata" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/profiledata" "gorm.io/gorm" ) @@ -14,7 +14,7 @@ type ProfileDataStore struct { } func NewProfileDataStore(db *gorm.DB) (*ProfileDataStore, error) { - err := db.AutoMigrate(&ProfileDataDTO{}) + err := db.AutoMigrate(&models.ProfileData{}) if err != nil { return nil, err } @@ -22,9 +22,9 @@ func NewProfileDataStore(db *gorm.DB) (*ProfileDataStore, error) { return &ProfileDataStore{db: db}, nil } -func (p *ProfileDataStore) Get() (*profiledata.ProfileData, error) { - profileDataDTO := ProfileDataDTO{} - tx := p.db.Where("id = ?", ProfileDataId).First(&profileDataDTO) +func (p *ProfileDataStore) Get(id string) (*models.ProfileData, error) { + profileData := &models.ProfileData{} + tx := p.db.Where("id = ?", id).First(profileData) if tx.Error != nil { if tx.Error == gorm.ErrRecordNotFound { return nil, profiledata.ErrProfileDataNotFound @@ -32,14 +32,11 @@ func (p *ProfileDataStore) Get() (*profiledata.ProfileData, error) { return nil, tx.Error } - profileData := ToProfileData(profileDataDTO) - return profileData, nil } -func (p *ProfileDataStore) Save(profileData *profiledata.ProfileData) error { - profileDataDTO := ToProfileDataDTO(profileData) - tx := p.db.Save(&profileDataDTO) +func (p *ProfileDataStore) Save(profileData *models.ProfileData) error { + tx := p.db.Save(profileData) if tx.Error != nil { return tx.Error } @@ -47,8 +44,8 @@ func (p *ProfileDataStore) Save(profileData *profiledata.ProfileData) error { return nil } -func (p *ProfileDataStore) Delete() error { - tx := p.db.Where("id = ?", ProfileDataId).Delete(&ProfileDataDTO{}) +func (p *ProfileDataStore) Delete(id string) error { + tx := p.db.Where("id = ?", id).Delete(&models.ProfileData{}) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index ad4f0dbeb1..366436c18f 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -6,9 +6,8 @@ package db import ( "gorm.io/gorm" - "github.com/daytonaio/daytona/internal/util" - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/target/config" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" ) type TargetConfigStore struct { @@ -16,7 +15,7 @@ type TargetConfigStore struct { } func NewTargetConfigStore(db *gorm.DB) (*TargetConfigStore, error) { - err := db.AutoMigrate(&TargetConfigDTO{}) + err := db.AutoMigrate(&models.TargetConfig{}) if err != nil { return nil, err } @@ -24,35 +23,33 @@ func NewTargetConfigStore(db *gorm.DB) (*TargetConfigStore, error) { return &TargetConfigStore{db: db}, nil } -func (s *TargetConfigStore) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { - targetConfigDTOs := []TargetConfigDTO{} - tx := processTargetConfigFilters(s.db, filter).Find(&targetConfigDTOs) +func (s *TargetConfigStore) List(filter *targetconfigs.TargetConfigFilter) ([]*models.TargetConfig, error) { + targetConfigs := []*models.TargetConfig{} + tx := processTargetConfigFilters(s.db, filter).Find(&targetConfigs) if tx.Error != nil { return nil, tx.Error } - return util.ArrayMap(targetConfigDTOs, func(targetConfigDTO TargetConfigDTO) *config.TargetConfig { - return ToTargetConfig(targetConfigDTO) - }), nil + return targetConfigs, nil } -func (s *TargetConfigStore) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { - targetConfigDTO := TargetConfigDTO{} - tx := processTargetConfigFilters(s.db, filter).First(&targetConfigDTO) +func (s *TargetConfigStore) Find(filter *targetconfigs.TargetConfigFilter) (*models.TargetConfig, error) { + targetConfig := &models.TargetConfig{} + tx := processTargetConfigFilters(s.db, filter).First(targetConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, config.ErrTargetConfigNotFound + return nil, targetconfigs.ErrTargetConfigNotFound } return nil, tx.Error } - return ToTargetConfig(targetConfigDTO), nil + return targetConfig, nil } -func (s *TargetConfigStore) Save(targetConfig *config.TargetConfig) error { - tx := s.db.Save(ToTargetConfigDTO(targetConfig)) +func (s *TargetConfigStore) Save(targetConfig *models.TargetConfig) error { + tx := s.db.Save(targetConfig) if tx.Error != nil { return tx.Error } @@ -60,19 +57,19 @@ func (s *TargetConfigStore) Save(targetConfig *config.TargetConfig) error { return nil } -func (s *TargetConfigStore) Delete(targetConfig *config.TargetConfig) error { - tx := s.db.Delete(ToTargetConfigDTO(targetConfig)) +func (s *TargetConfigStore) Delete(targetConfig *models.TargetConfig) error { + tx := s.db.Delete(targetConfig) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return config.ErrTargetConfigNotFound + return targetconfigs.ErrTargetConfigNotFound } return nil } -func processTargetConfigFilters(tx *gorm.DB, filter *config.TargetConfigFilter) *gorm.DB { +func processTargetConfigFilters(tx *gorm.DB, filter *targetconfigs.TargetConfigFilter) *gorm.DB { if filter != nil { if filter.Name != nil { tx = tx.Where("name = ?", *filter.Name) diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index 80243fb099..485005863d 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -6,8 +6,8 @@ package db import ( "gorm.io/gorm" - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targets" ) type TargetStore struct { @@ -15,7 +15,7 @@ type TargetStore struct { } func NewTargetStore(db *gorm.DB) (*TargetStore, error) { - err := db.AutoMigrate(&TargetDTO{}) + err := db.AutoMigrate(&models.Target{}) if err != nil { return nil, err } @@ -23,51 +23,35 @@ func NewTargetStore(db *gorm.DB) (*TargetStore, error) { return &TargetStore{db: db}, nil } -func (s *TargetStore) List(filter *target.TargetFilter) ([]*target.TargetViewDTO, error) { - targetDTOs := []TargetDTO{} +func (s *TargetStore) List(filter *targets.TargetFilter) ([]*models.Target, error) { + targets := []*models.Target{} - tx := processTargetFilters(s.db, filter).Preload("Workspaces").Find(&targetDTOs) + tx := processTargetFilters(s.db, filter).Preload("Workspaces").Find(&targets) if tx.Error != nil { return nil, tx.Error } - - targetViewDTOs := []*target.TargetViewDTO{} - for _, targetDTO := range targetDTOs { - viewDTO := &target.TargetViewDTO{ - Target: *ToTarget(targetDTO), - WorkspaceCount: len(targetDTO.Workspaces), - } - targetViewDTOs = append(targetViewDTOs, viewDTO) - } - - return targetViewDTOs, nil + return targets, nil } -func (s *TargetStore) Find(filter *target.TargetFilter) (*target.TargetViewDTO, error) { - targetDTO := TargetDTO{} +func (s *TargetStore) Find(filter *targets.TargetFilter) (*models.Target, error) { + tg := &models.Target{} - tx := processTargetFilters(s.db, filter).Preload("Workspaces").First(&targetDTO) + tx := processTargetFilters(s.db, filter).Preload("Workspaces").First(tg) if tx.Error != nil { return nil, tx.Error } if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, target.ErrTargetNotFound + return nil, targets.ErrTargetNotFound } return nil, tx.Error } - - targetViewDTO := &target.TargetViewDTO{ - Target: *ToTarget(targetDTO), - WorkspaceCount: len(targetDTO.Workspaces), - } - - return targetViewDTO, nil + return tg, nil } -func (s *TargetStore) Save(target *target.Target) error { - tx := s.db.Save(ToTargetDTO(target)) +func (s *TargetStore) Save(target *models.Target) error { + tx := s.db.Save(target) if tx.Error != nil { return tx.Error } @@ -75,19 +59,19 @@ func (s *TargetStore) Save(target *target.Target) error { return nil } -func (s *TargetStore) Delete(t *target.Target) error { - tx := s.db.Delete(ToTargetDTO(t)) +func (s *TargetStore) Delete(t *models.Target) error { + tx := s.db.Delete(t) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return target.ErrTargetNotFound + return targets.ErrTargetNotFound } return nil } -func processTargetFilters(tx *gorm.DB, filter *target.TargetFilter) *gorm.DB { +func processTargetFilters(tx *gorm.DB, filter *targets.TargetFilter) *gorm.DB { if filter != nil { if filter.IdOrName != nil { tx = tx.Where("id = ? OR name = ?", *filter.IdOrName, *filter.IdOrName) diff --git a/pkg/db/workspace_config_store.go b/pkg/db/workspace_config_store.go index 87a7fb8a0a..1df557ae00 100644 --- a/pkg/db/workspace_config_store.go +++ b/pkg/db/workspace_config_store.go @@ -6,8 +6,8 @@ package db import ( "gorm.io/gorm" - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" ) type WorkspaceConfigStore struct { @@ -15,7 +15,7 @@ type WorkspaceConfigStore struct { } func NewWorkspaceConfigStore(db *gorm.DB) (*WorkspaceConfigStore, error) { - err := db.AutoMigrate(&WorkspaceConfigDTO{}) + err := db.AutoMigrate(&models.WorkspaceConfig{}) if err != nil { return nil, err } @@ -23,38 +23,33 @@ func NewWorkspaceConfigStore(db *gorm.DB) (*WorkspaceConfigStore, error) { return &WorkspaceConfigStore{db: db}, nil } -func (s *WorkspaceConfigStore) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { - workspaceConfigDTOs := []WorkspaceConfigDTO{} - tx := processWorkspaceConfigFilters(s.db, filter).Find(&workspaceConfigDTOs) +func (s *WorkspaceConfigStore) List(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { + workspaceConfigs := []*models.WorkspaceConfig{} + tx := processWorkspaceConfigFilters(s.db, filter).Find(&workspaceConfigs) if tx.Error != nil { return nil, tx.Error } - workspaceConfigs := []*config.WorkspaceConfig{} - for _, workspaceConfigDTO := range workspaceConfigDTOs { - workspaceConfigs = append(workspaceConfigs, ToWorkspaceConfig(workspaceConfigDTO)) - } - return workspaceConfigs, nil } -func (s *WorkspaceConfigStore) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { - workspaceConfigDTO := WorkspaceConfigDTO{} - tx := processWorkspaceConfigFilters(s.db, filter).First(&workspaceConfigDTO) +func (s *WorkspaceConfigStore) Find(filter *workspaceconfigs.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { + workspaceConfig := &models.WorkspaceConfig{} + tx := processWorkspaceConfigFilters(s.db, filter).First(workspaceConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, config.ErrWorkspaceConfigNotFound + return nil, workspaceconfigs.ErrWorkspaceConfigNotFound } return nil, tx.Error } - return ToWorkspaceConfig(workspaceConfigDTO), nil + return workspaceConfig, nil } -func (s *WorkspaceConfigStore) Save(workspaceConfig *config.WorkspaceConfig) error { - tx := s.db.Save(ToWorkspaceConfigDTO(workspaceConfig)) +func (s *WorkspaceConfigStore) Save(workspaceConfig *models.WorkspaceConfig) error { + tx := s.db.Save(workspaceConfig) if tx.Error != nil { return tx.Error } @@ -62,19 +57,19 @@ func (s *WorkspaceConfigStore) Save(workspaceConfig *config.WorkspaceConfig) err return nil } -func (s *WorkspaceConfigStore) Delete(workspaceConfig *config.WorkspaceConfig) error { - tx := s.db.Delete(ToWorkspaceConfigDTO(workspaceConfig)) +func (s *WorkspaceConfigStore) Delete(workspaceConfig *models.WorkspaceConfig) error { + tx := s.db.Delete(workspaceConfig) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return config.ErrWorkspaceConfigNotFound + return workspaceconfigs.ErrWorkspaceConfigNotFound } return nil } -func processWorkspaceConfigFilters(tx *gorm.DB, filter *config.WorkspaceConfigFilter) *gorm.DB { +func processWorkspaceConfigFilters(tx *gorm.DB, filter *workspaceconfigs.WorkspaceConfigFilter) *gorm.DB { if filter != nil { if filter.Name != nil { tx = tx.Where("name = ?", *filter.Name) diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go index ee938e1c16..42bcba4d36 100644 --- a/pkg/db/workspace_store.go +++ b/pkg/db/workspace_store.go @@ -7,8 +7,8 @@ import ( "gorm.io/gorm" "gorm.io/gorm/clause" - . "github.com/daytonaio/daytona/pkg/db/dto" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaces" ) type WorkspaceStore struct { @@ -16,7 +16,7 @@ type WorkspaceStore struct { } func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { - err := db.AutoMigrate(&WorkspaceDTO{}) + err := db.AutoMigrate(&models.Workspace{}) if err != nil { return nil, err } @@ -24,36 +24,31 @@ func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { return &WorkspaceStore{db: db}, nil } -func (store *WorkspaceStore) List() ([]*workspace.WorkspaceViewDTO, error) { - workspaceDTOs := []WorkspaceDTO{} - tx := store.db.Preload(clause.Associations).Find(&workspaceDTOs) +func (store *WorkspaceStore) List() ([]*models.Workspace, error) { + workspaces := []*models.Workspace{} + tx := store.db.Preload(clause.Associations).Find(&workspaces) if tx.Error != nil { return nil, tx.Error } - workspaceViewDTOs := []*workspace.WorkspaceViewDTO{} - for _, workspaceDTO := range workspaceDTOs { - workspaceViewDTOs = append(workspaceViewDTOs, ToWorkspaceViewDTO(workspaceDTO)) - } - - return workspaceViewDTOs, nil + return workspaces, nil } -func (w *WorkspaceStore) Find(idOrName string) (*workspace.WorkspaceViewDTO, error) { - workspaceDTO := WorkspaceDTO{} - tx := w.db.Preload(clause.Associations).Where("id = ? OR name = ?", idOrName, idOrName).First(&workspaceDTO) +func (w *WorkspaceStore) Find(idOrName string) (*models.Workspace, error) { + workspace := &models.Workspace{} + tx := w.db.Preload(clause.Associations).Where("id = ? OR name = ?", idOrName, idOrName).First(workspace) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, workspace.ErrWorkspaceNotFound + return nil, workspaces.ErrWorkspaceNotFound } return nil, tx.Error } - return ToWorkspaceViewDTO(workspaceDTO), nil + return workspace, nil } -func (w *WorkspaceStore) Save(workspace *workspace.Workspace) error { - tx := w.db.Save(ToWorkspaceDTO(workspace)) +func (w *WorkspaceStore) Save(workspace *models.Workspace) error { + tx := w.db.Save(workspace) if tx.Error != nil { return tx.Error } @@ -61,13 +56,13 @@ func (w *WorkspaceStore) Save(workspace *workspace.Workspace) error { return nil } -func (w *WorkspaceStore) Delete(t *workspace.Workspace) error { - tx := w.db.Delete(ToWorkspaceDTO(t)) +func (w *WorkspaceStore) Delete(workspace *models.Workspace) error { + tx := w.db.Delete(workspace) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return workspace.ErrWorkspaceNotFound + return workspaces.ErrWorkspaceNotFound } return nil diff --git a/pkg/docker/client.go b/pkg/docker/client.go index cc415875f2..e5a770155d 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -8,11 +8,8 @@ import ( "fmt" "io" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" @@ -20,35 +17,35 @@ import ( ) type CreateWorkspaceOptions struct { - Workspace *workspace.Workspace + Workspace *models.Workspace WorkspaceDir string - ContainerRegistry *containerregistry.ContainerRegistry + ContainerRegistry *models.ContainerRegistry LogWriter io.Writer - Gpc *gitprovider.GitProviderConfig + Gpc *models.GitProviderConfig SshClient *ssh.Client BuilderImage string - BuilderContainerRegistry *containerregistry.ContainerRegistry + BuilderContainerRegistry *models.ContainerRegistry } type IDockerClient interface { CreateWorkspace(opts *CreateWorkspaceOptions) error - CreateTarget(target *target.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error + CreateTarget(target *models.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error - DestroyWorkspace(workspace *workspace.Workspace, workspaceDir string, sshClient *ssh.Client) error - DestroyTarget(target *target.Target, targetDir string, sshClient *ssh.Client) error + DestroyWorkspace(workspace *models.Workspace, workspaceDir string, sshClient *ssh.Client) error + DestroyTarget(target *models.Target, targetDir string, sshClient *ssh.Client) error StartWorkspace(opts *CreateWorkspaceOptions, daytonaDownloadUrl string) error - StopWorkspace(workspace *workspace.Workspace, logWriter io.Writer) error + StopWorkspace(workspace *models.Workspace, logWriter io.Writer) error - GetWorkspaceInfo(workspace *workspace.Workspace) (*workspace.WorkspaceInfo, error) - GetTargetInfo(t *target.Target) (*target.TargetInfo, error) + GetWorkspaceInfo(workspace *models.Workspace) (*models.WorkspaceInfo, error) + GetTargetInfo(t *models.Target) (*models.TargetInfo, error) - GetWorkspaceContainerName(workspace *workspace.Workspace) string - GetWorkspaceVolumeName(workspace *workspace.Workspace) string + GetWorkspaceContainerName(workspace *models.Workspace) string + GetWorkspaceVolumeName(workspace *models.Workspace) string ExecSync(containerID string, config container.ExecOptions, outputWriter io.Writer) (*ExecResult, error) GetContainerLogs(containerName string, logWriter io.Writer) error - PullImage(imageName string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error - PushImage(imageName string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error + PullImage(imageName string, cr *models.ContainerRegistry, logWriter io.Writer) error + PushImage(imageName string, cr *models.ContainerRegistry, logWriter io.Writer) error DeleteImage(imageName string, force bool, logWriter io.Writer) error CreateFromDevcontainer(opts CreateDevcontainerOptions) (string, RemoteUser, error) @@ -69,7 +66,7 @@ type DockerClient struct { apiClient client.APIClient } -func (d *DockerClient) GetWorkspaceContainerName(workspace *workspace.Workspace) string { +func (d *DockerClient) GetWorkspaceContainerName(workspace *models.Workspace) string { containers, err := d.apiClient.ContainerList(context.Background(), container.ListOptions{ Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.target.id=%s", workspace.TargetId)), filters.Arg("label", fmt.Sprintf("daytona.workspace.name=%s", workspace.Name))), All: true, @@ -81,7 +78,7 @@ func (d *DockerClient) GetWorkspaceContainerName(workspace *workspace.Workspace) return containers[0].ID } -func (d *DockerClient) GetWorkspaceVolumeName(workspace *workspace.Workspace) string { +func (d *DockerClient) GetWorkspaceVolumeName(workspace *models.Workspace) string { return workspace.TargetId + "-" + workspace.Name } diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index e21507e998..d7ca1c6ad4 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -9,13 +9,11 @@ import ( "github.com/daytonaio/daytona/internal/testing/docker/mocks" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/suite" ) -var workspace1 = &workspace.Workspace{ +var workspace1 = &models.Workspace{ Name: "test", Repository: &gitprovider.GitRepository{ Id: "123", @@ -25,13 +23,13 @@ var workspace1 = &workspace.Workspace{ Image: "test-image:tag", User: "test-user", TargetId: "123", - BuildConfig: &buildconfig.BuildConfig{}, + BuildConfig: &models.BuildConfig{}, } -var target1 = &target.Target{ +var target1 = &models.Target{ Id: "123", Name: "test", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, diff --git a/pkg/docker/create.go b/pkg/docker/create.go index 61ba08cf83..26890d4e42 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -16,15 +16,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/detect" "github.com/daytonaio/daytona/pkg/git" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/go-git/go-git/v5/plumbing/transport/http" log "github.com/sirupsen/logrus" ) -func (d *DockerClient) CreateTarget(target *target.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error { +func (d *DockerClient) CreateTarget(target *models.Target, targetDir string, logWriter io.Writer, sshClient *ssh.Client) error { var err error if sshClient == nil { err = os.MkdirAll(targetDir, 0755) diff --git a/pkg/docker/create_devcontainer.go b/pkg/docker/create_devcontainer.go index 1a31147958..5149d376bc 100644 --- a/pkg/docker/create_devcontainer.go +++ b/pkg/docker/create_devcontainer.go @@ -19,9 +19,8 @@ import ( "github.com/compose-spec/compose-go/v2/cli" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build/devcontainer" - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/mount" @@ -43,15 +42,15 @@ type CreateDevcontainerOptions struct { WorkspaceDir string // Name of the project inside the devcontainer WorkspaceFolderName string - BuildConfig *buildconfig.BuildConfig + BuildConfig *models.BuildConfig LogWriter io.Writer SshClient *ssh.Client - ContainerRegistry *containerregistry.ContainerRegistry + ContainerRegistry *models.ContainerRegistry Prebuild bool EnvVars map[string]string IdLabels map[string]string BuilderImage string - BuilderContainerRegistry *containerregistry.ContainerRegistry + BuilderContainerRegistry *models.ContainerRegistry } func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (string, RemoteUser, error) { @@ -323,7 +322,7 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s return result.ContainerId, RemoteUser(result.RemoteUser), nil } -func (d *DockerClient) ensureDockerSockForward(builderImage string, builderContainerRegistry *containerregistry.ContainerRegistry, logWriter io.Writer) (string, error) { +func (d *DockerClient) ensureDockerSockForward(builderImage string, builderContainerRegistry *models.ContainerRegistry, logWriter io.Writer) (string, error) { ctx := context.Background() containers, err := d.apiClient.ContainerList(ctx, container.ListOptions{ diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index 83fb08f88e..e437607fb6 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -9,8 +9,8 @@ import ( "runtime" "time" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/docker/go-connections/nat" @@ -106,7 +106,7 @@ func (d *DockerClient) initWorkspaceContainer(opts *CreateWorkspaceOptions, moun return nil } -func GetContainerCreateConfig(workspace *workspace.Workspace, toolboxApiHostPort *uint16) *container.Config { +func GetContainerCreateConfig(workspace *models.Workspace, toolboxApiHostPort *uint16) *container.Config { envVars := []string{} for key, value := range workspace.EnvVars { diff --git a/pkg/docker/destroy.go b/pkg/docker/destroy.go index 4b168c275e..e930e77aa9 100644 --- a/pkg/docker/destroy.go +++ b/pkg/docker/destroy.go @@ -8,14 +8,13 @@ import ( "fmt" "os" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" ) -func (d *DockerClient) DestroyTarget(target *target.Target, targetDir string, sshClient *ssh.Client) error { +func (d *DockerClient) DestroyTarget(target *models.Target, targetDir string, sshClient *ssh.Client) error { if sshClient == nil { return os.RemoveAll(targetDir) } else { @@ -23,7 +22,7 @@ func (d *DockerClient) DestroyTarget(target *target.Target, targetDir string, ss } } -func (d *DockerClient) DestroyWorkspace(workspace *workspace.Workspace, workspaceDir string, sshClient *ssh.Client) error { +func (d *DockerClient) DestroyWorkspace(workspace *models.Workspace, workspaceDir string, sshClient *ssh.Client) error { err := d.removeWorkspaceContainer(workspace) if err != nil { return err @@ -36,7 +35,7 @@ func (d *DockerClient) DestroyWorkspace(workspace *workspace.Workspace, workspac } } -func (d *DockerClient) removeWorkspaceContainer(w *workspace.Workspace) error { +func (d *DockerClient) removeWorkspaceContainer(w *models.Workspace) error { ctx := context.Background() containerName := d.GetWorkspaceContainerName(w) diff --git a/pkg/docker/info.go b/pkg/docker/info.go index 4b6acb2c2d..a678175165 100644 --- a/pkg/docker/info.go +++ b/pkg/docker/info.go @@ -8,8 +8,7 @@ import ( "encoding/json" "fmt" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types" "github.com/docker/docker/client" ) @@ -17,8 +16,8 @@ import ( const ContainerNotFoundMetadata = "{\"state\": \"container not found\"}" const TargetMetadataFormat = "{\"networkId\": \"%s\"}" -func (d *DockerClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, error) { - targetInfo := &target.TargetInfo{ +func (d *DockerClient) GetTargetInfo(t *models.Target) (*models.TargetInfo, error) { + targetInfo := &models.TargetInfo{ Name: t.Name, ProviderMetadata: fmt.Sprintf(TargetMetadataFormat, t.Id), } @@ -26,7 +25,7 @@ func (d *DockerClient) GetTargetInfo(t *target.Target) (*target.TargetInfo, erro return targetInfo, nil } -func (d *DockerClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.WorkspaceInfo, error) { +func (d *DockerClient) GetWorkspaceInfo(w *models.Workspace) (*models.WorkspaceInfo, error) { isRunning := true info, err := d.getContainerInfo(w) if err != nil { @@ -38,7 +37,7 @@ func (d *DockerClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.Work } if info == nil || info.State == nil { - return &workspace.WorkspaceInfo{ + return &models.WorkspaceInfo{ Name: w.Name, IsRunning: isRunning, Created: "", @@ -46,7 +45,7 @@ func (d *DockerClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.Work }, nil } - workspaceInfo := &workspace.WorkspaceInfo{ + workspaceInfo := &models.WorkspaceInfo{ Name: w.Name, IsRunning: isRunning, Created: info.Created, @@ -63,7 +62,7 @@ func (d *DockerClient) GetWorkspaceInfo(w *workspace.Workspace) (*workspace.Work return workspaceInfo, nil } -func (d *DockerClient) getContainerInfo(w *workspace.Workspace) (*types.ContainerJSON, error) { +func (d *DockerClient) getContainerInfo(w *models.Workspace) (*types.ContainerJSON, error) { ctx := context.Background() info, err := d.apiClient.ContainerInspect(ctx, d.GetWorkspaceContainerName(w)) diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go index 91ef677292..7af80e2437 100644 --- a/pkg/docker/info_test.go +++ b/pkg/docker/info_test.go @@ -7,7 +7,7 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" "github.com/stretchr/testify/mock" @@ -45,10 +45,10 @@ func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { } func (s *DockerClientTestSuite) TestGetTargetInfo() { - targetWithoutWorkspaces := &target.Target{ + targetWithoutWorkspaces := &models.Target{ Id: "123", Name: "test", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, diff --git a/pkg/docker/pull_image.go b/pkg/docker/pull_image.go index d06d8d8ede..d5298b61b7 100644 --- a/pkg/docker/pull_image.go +++ b/pkg/docker/pull_image.go @@ -10,7 +10,7 @@ import ( "io" "strings" - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/views" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/image" @@ -18,7 +18,7 @@ import ( "github.com/docker/docker/pkg/jsonmessage" ) -func (d *DockerClient) PullImage(imageName string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error { +func (d *DockerClient) PullImage(imageName string, cr *models.ContainerRegistry, logWriter io.Writer) error { ctx := context.Background() tag := "latest" @@ -75,7 +75,7 @@ func (d *DockerClient) PullImage(imageName string, cr *containerregistry.Contain return nil } -func getRegistryAuth(cr *containerregistry.ContainerRegistry) string { +func getRegistryAuth(cr *models.ContainerRegistry) string { if cr == nil { // Sometimes registry auth fails if "" is sent, so sending "empty" instead return "empty" diff --git a/pkg/docker/push_image.go b/pkg/docker/push_image.go index 6151d25d5e..ca325e8e1a 100644 --- a/pkg/docker/push_image.go +++ b/pkg/docker/push_image.go @@ -7,12 +7,12 @@ import ( "context" "io" - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types/image" "github.com/docker/docker/pkg/jsonmessage" ) -func (d *DockerClient) PushImage(imageName string, cr *containerregistry.ContainerRegistry, logWriter io.Writer) error { +func (d *DockerClient) PushImage(imageName string, cr *models.ContainerRegistry, logWriter io.Writer) error { ctx := context.Background() if logWriter != nil { diff --git a/pkg/docker/start.go b/pkg/docker/start.go index 6d91c57666..26c23a465a 100644 --- a/pkg/docker/start.go +++ b/pkg/docker/start.go @@ -11,8 +11,8 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/build/detect" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/docker/docker/api/types/container" ) @@ -43,7 +43,7 @@ func (d *DockerClient) StartWorkspace(opts *CreateWorkspaceOptions, daytonaDownl return d.startDaytonaAgent(opts.Workspace, containerUser, daytonaDownloadUrl, opts.LogWriter) } -func (d *DockerClient) startDaytonaAgent(w *workspace.Workspace, containerUser, daytonaDownloadUrl string, logWriter io.Writer) error { +func (d *DockerClient) startDaytonaAgent(w *models.Workspace, containerUser, daytonaDownloadUrl string, logWriter io.Writer) error { errChan := make(chan error) r, pipeW := io.Pipe() diff --git a/pkg/docker/stop.go b/pkg/docker/stop.go index eeb6d8050a..1ac1c0236f 100644 --- a/pkg/docker/stop.go +++ b/pkg/docker/stop.go @@ -10,16 +10,16 @@ import ( "strings" "time" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" ) -func (d *DockerClient) StopWorkspace(w *workspace.Workspace, logWriter io.Writer) error { +func (d *DockerClient) StopWorkspace(w *models.Workspace, logWriter io.Writer) error { return d.stopWorkspaceContainer(w, logWriter) } -func (d *DockerClient) stopWorkspaceContainer(w *workspace.Workspace, logWriter io.Writer) error { +func (d *DockerClient) stopWorkspaceContainer(w *models.Workspace, logWriter io.Writer) error { containerName := d.GetWorkspaceContainerName(w) ctx := context.Background() diff --git a/pkg/git/config.go b/pkg/git/config.go index 1c6695bdc6..1ba90a4011 100644 --- a/pkg/git/config.go +++ b/pkg/git/config.go @@ -10,10 +10,11 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "gopkg.in/ini.v1" ) -func (s *Service) SetGitConfig(userData *gitprovider.GitUser, providerConfig *gitprovider.GitProviderConfig) error { +func (s *Service) SetGitConfig(userData *gitprovider.GitUser, providerConfig *models.GitProviderConfig) error { gitConfigFileName := s.GitConfigFileName var gitConfigContent []byte @@ -82,7 +83,7 @@ func (s *Service) SetGitConfig(userData *gitprovider.GitUser, providerConfig *gi return os.WriteFile(gitConfigFileName, buf.Bytes(), 0644) } -func (s *Service) setSigningConfig(cfg *ini.File, providerConfig *gitprovider.GitProviderConfig, userData *gitprovider.GitUser) error { +func (s *Service) setSigningConfig(cfg *ini.File, providerConfig *models.GitProviderConfig, userData *gitprovider.GitUser) error { if providerConfig == nil || providerConfig.SigningMethod == nil || providerConfig.SigningKey == nil { return nil } @@ -107,12 +108,12 @@ func (s *Service) setSigningConfig(cfg *ini.File, providerConfig *gitprovider.Gi } switch *providerConfig.SigningMethod { - case gitprovider.SigningMethodGPG: + case models.SigningMethodGPG: _, err := cfg.Section("commit").NewKey("gpgSign", "true") if err != nil { return err } - case gitprovider.SigningMethodSSH: + case models.SigningMethodSSH: err := s.configureAllowedSigners(userData.Email, *providerConfig.SigningKey) if err != nil { return err diff --git a/pkg/git/service.go b/pkg/git/service.go index 476ff7d2d1..09c8a52e69 100644 --- a/pkg/git/service.go +++ b/pkg/git/service.go @@ -9,28 +9,28 @@ import ( "path/filepath" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/transport/http" ) -var MapStatus map[git.StatusCode]workspace.Status = map[git.StatusCode]workspace.Status{ - git.Unmodified: workspace.Unmodified, - git.Untracked: workspace.Untracked, - git.Modified: workspace.Modified, - git.Added: workspace.Added, - git.Deleted: workspace.Deleted, - git.Renamed: workspace.Renamed, - git.Copied: workspace.Copied, - git.UpdatedButUnmerged: workspace.UpdatedButUnmerged, +var MapStatus map[git.StatusCode]models.Status = map[git.StatusCode]models.Status{ + git.Unmodified: models.Unmodified, + git.Untracked: models.Untracked, + git.Modified: models.Modified, + git.Added: models.Added, + git.Deleted: models.Deleted, + git.Renamed: models.Renamed, + git.Copied: models.Copied, + git.UpdatedButUnmerged: models.UpdatedButUnmerged, } type IGitService interface { CloneRepository(repo *gitprovider.GitRepository, auth *http.BasicAuth) error CloneRepositoryCmd(repo *gitprovider.GitRepository, auth *http.BasicAuth) []string RepositoryExists() (bool, error) - SetGitConfig(userData *gitprovider.GitUser, providerConfig *gitprovider.GitProviderConfig) error - GetGitStatus() (*workspace.GitStatus, error) + SetGitConfig(userData *gitprovider.GitUser, providerConfig *models.GitProviderConfig) error + GetGitStatus() (*models.GitStatus, error) } type Service struct { diff --git a/pkg/git/status.go b/pkg/git/status.go index dc0bafd4ff..c6fe7325ff 100644 --- a/pkg/git/status.go +++ b/pkg/git/status.go @@ -9,11 +9,11 @@ import ( "strconv" "strings" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" "github.com/go-git/go-git/v5" ) -func (s *Service) GetGitStatus() (*workspace.GitStatus, error) { +func (s *Service) GetGitStatus() (*models.GitStatus, error) { repo, err := git.PlainOpen(s.WorkspaceDir) if err != nil { return nil, err @@ -34,9 +34,9 @@ func (s *Service) GetGitStatus() (*workspace.GitStatus, error) { return nil, err } - files := []*workspace.FileStatus{} + files := []*models.FileStatus{} for path, file := range status { - files = append(files, &workspace.FileStatus{ + files = append(files, &models.FileStatus{ Name: path, Extra: file.Extra, Staging: MapStatus[file.Staging], @@ -54,7 +54,7 @@ func (s *Service) GetGitStatus() (*workspace.GitStatus, error) { return nil, err } - return &workspace.GitStatus{ + return &models.GitStatus{ CurrentBranch: ref.Name().Short(), Files: files, BranchPublished: branchPublished, diff --git a/pkg/gitprovider/store.go b/pkg/gitprovider/store.go deleted file mode 100644 index b60b56f911..0000000000 --- a/pkg/gitprovider/store.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package gitprovider - -import "errors" - -type ConfigStore interface { - List() ([]*GitProviderConfig, error) - Find(id string) (*GitProviderConfig, error) - Save(*GitProviderConfig) error - Delete(*GitProviderConfig) error -} - -var ( - ErrGitProviderConfigNotFound = errors.New("git provider config not found") -) - -func IsGitProviderNotFound(err error) bool { - return err.Error() == ErrGitProviderConfigNotFound.Error() -} diff --git a/pkg/gitprovider/types.go b/pkg/gitprovider/types.go index 5b38d2e310..71f2daab15 100644 --- a/pkg/gitprovider/types.go +++ b/pkg/gitprovider/types.go @@ -3,24 +3,6 @@ package gitprovider -type SigningMethod string // @name SigningMethod - -const ( - SigningMethodSSH SigningMethod = "ssh" - SigningMethodGPG SigningMethod = "gpg" -) - -type GitProviderConfig struct { - Id string `json:"id" validate:"required"` - ProviderId string `json:"providerId" validate:"required"` - Username string `json:"username" validate:"required"` - BaseApiUrl *string `json:"baseApiUrl,omitempty" validate:"optional"` - Token string `json:"token" validate:"required"` - Alias string `json:"alias" validate:"required"` - SigningKey *string `json:"signingKey,omitempty" validate:"optional"` - SigningMethod *SigningMethod `json:"signingMethod,omitempty" validate:"optional"` -} // @name GitProvider - type GitUser struct { Id string `json:"id" validate:"required"` Username string `json:"username" validate:"required"` diff --git a/pkg/apikey/apikey.go b/pkg/models/api_key.go similarity index 70% rename from pkg/apikey/apikey.go rename to pkg/models/api_key.go index 92f6bb8d8d..8032a20aad 100644 --- a/pkg/apikey/apikey.go +++ b/pkg/models/api_key.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package apikey +package models type ApiKeyType string @@ -12,8 +12,8 @@ const ( ) type ApiKey struct { - KeyHash string `json:"keyHash" validate:"required"` + KeyHash string `json:"keyHash" validate:"required" gorm:"primaryKey"` Type ApiKeyType `json:"type" validate:"required"` // Workspace or client name - Name string `json:"name" validate:"required"` + Name string `json:"name" validate:"required" gorm:"uniqueIndex"` } // @name ApiKey diff --git a/pkg/build/build.go b/pkg/models/build.go similarity index 70% rename from pkg/build/build.go rename to pkg/models/build.go index de3343e033..b663f30e42 100644 --- a/pkg/build/build.go +++ b/pkg/models/build.go @@ -1,6 +1,6 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package build +package models import ( "crypto/sha256" @@ -9,8 +9,6 @@ import ( "time" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/containerconfig" ) type BuildState string @@ -27,21 +25,21 @@ const ( ) type Build struct { - Id string `json:"id" validate:"required"` - State BuildState `json:"state" validate:"required"` - Image *string `json:"image" validate:"optional"` - User *string `json:"user" validate:"optional"` - ContainerConfig containerconfig.ContainerConfig `json:"containerConfig" validate:"required"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig" validate:"optional"` - Repository *gitprovider.GitRepository `json:"repository" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required"` - PrebuildId string `json:"prebuildId" validate:"required"` - CreatedAt time.Time `json:"createdAt" validate:"required"` - UpdatedAt time.Time `json:"updatedAt" validate:"required"` + Id string `json:"id" validate:"required" gorm:"primaryKey"` + State BuildState `json:"state" validate:"required"` + Image *string `json:"image" validate:"optional"` + User *string `json:"user" validate:"optional"` + ContainerConfig ContainerConfig `json:"containerConfig" validate:"required" gorm:"serializer:json"` + BuildConfig *BuildConfig `json:"buildConfig" validate:"optional" gorm:"serializer:json"` + Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` + PrebuildId string `json:"prebuildId" validate:"required"` + CreatedAt time.Time `json:"createdAt" validate:"required"` + UpdatedAt time.Time `json:"updatedAt" validate:"required"` } // @name Build func (b *Build) Compare(other *Build) (bool, error) { - if b.BuildConfig != nil && *b.BuildConfig == (buildconfig.BuildConfig{}) { + if b.BuildConfig != nil && *b.BuildConfig == (BuildConfig{}) { buildHash, err := b.getBuildHashWithoutBuildConfig() if err != nil { return false, err @@ -103,7 +101,7 @@ func (b *Build) getBuildHashWithoutBuildConfig() (string, error) { return hashStr, nil } -func GetCachedBuild(build *Build, builds []*Build) *buildconfig.CachedBuild { +func GetCachedBuild(build *Build, builds []*Build) *CachedBuild { var cachedBuild *Build for _, existingBuild := range builds { @@ -124,7 +122,7 @@ func GetCachedBuild(build *Build, builds []*Build) *buildconfig.CachedBuild { } if cachedBuild != nil && cachedBuild.Image != nil && cachedBuild.User != nil { - return &buildconfig.CachedBuild{ + return &CachedBuild{ Image: *cachedBuild.Image, User: *cachedBuild.User, } diff --git a/pkg/workspace/buildconfig/config.go b/pkg/models/build_config.go similarity index 96% rename from pkg/workspace/buildconfig/config.go rename to pkg/models/build_config.go index 30273d3017..70c3e654af 100644 --- a/pkg/workspace/buildconfig/config.go +++ b/pkg/models/build_config.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package buildconfig +package models type BuildConfig struct { Devcontainer *DevcontainerConfig `json:"devcontainer,omitempty" validate:"optional"` diff --git a/pkg/workspace/containerconfig/config.go b/pkg/models/container_config.go similarity index 90% rename from pkg/workspace/containerconfig/config.go rename to pkg/models/container_config.go index 04a73bbe7d..e2eecc6a5c 100644 --- a/pkg/workspace/containerconfig/config.go +++ b/pkg/models/container_config.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package containerconfig +package models type ContainerConfig struct { Image string `json:"image" validate:"required"` diff --git a/pkg/containerregistry/container_registry.go b/pkg/models/container_registry.go similarity index 88% rename from pkg/containerregistry/container_registry.go rename to pkg/models/container_registry.go index 3d1227c77c..24993ffc74 100644 --- a/pkg/containerregistry/container_registry.go +++ b/pkg/models/container_registry.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package containerregistry +package models import ( "errors" @@ -10,7 +10,7 @@ import ( // ContainerRegistry represents a container registry credentials type ContainerRegistry struct { - Server string `json:"server" validate:"required"` + Server string `json:"server" validate:"required" gorm:"primaryKey"` Username string `json:"username" validate:"required"` Password string `json:"password" validate:"required"` } // @name ContainerRegistry diff --git a/pkg/models/git_provider_config.go b/pkg/models/git_provider_config.go new file mode 100644 index 0000000000..876db7a207 --- /dev/null +++ b/pkg/models/git_provider_config.go @@ -0,0 +1,22 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +type SigningMethod string // @name SigningMethod + +const ( + SigningMethodSSH SigningMethod = "ssh" + SigningMethodGPG SigningMethod = "gpg" +) + +type GitProviderConfig struct { + Id string `json:"id" validate:"required" gorm:"primaryKey"` + ProviderId string `json:"providerId" validate:"required"` + Username string `json:"username" validate:"required"` + BaseApiUrl *string `json:"baseApiUrl,omitempty" validate:"optional"` + Token string `json:"token" validate:"required"` + Alias string `json:"alias" validate:"required" gorm:"uniqueIndex"` + SigningKey *string `json:"signingKey,omitempty" validate:"optional"` + SigningMethod *SigningMethod `json:"signingMethod,omitempty" validate:"optional"` +} // @name GitProvider diff --git a/pkg/workspace/config/prebuild.go b/pkg/models/prebuild.go similarity index 65% rename from pkg/workspace/config/prebuild.go rename to pkg/models/prebuild.go index f4a7a50573..15d89f63fc 100644 --- a/pkg/workspace/config/prebuild.go +++ b/pkg/models/prebuild.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package config +package models import ( "encoding/json" @@ -27,28 +27,36 @@ func (p *PrebuildConfig) GenerateId() error { return nil } -func (p *PrebuildConfig) Match(filter *PrebuildFilter) bool { - if filter.Id != nil && *filter.Id != p.Id { +type MatchParams struct { + WorkspaceConfigName *string + Id *string + Branch *string + CommitInterval *int + TriggerFiles *[]string +} + +func (p *PrebuildConfig) Match(params *MatchParams) bool { + if params.Id != nil && *params.Id != p.Id { return false } - if filter.Branch != nil && *filter.Branch != p.Branch { + if params.Branch != nil && *params.Branch != p.Branch { return false } - if filter.CommitInterval != nil && p.CommitInterval != nil && *filter.CommitInterval != *p.CommitInterval { + if params.CommitInterval != nil && p.CommitInterval != nil && *params.CommitInterval != *p.CommitInterval { return false } - if filter.TriggerFiles != nil { + if params.TriggerFiles != nil { // Sort the trigger files before checking if same sort.Strings(p.TriggerFiles) - sort.Strings(*filter.TriggerFiles) + sort.Strings(*params.TriggerFiles) triggerFilesJson, err := json.Marshal(p.TriggerFiles) if err != nil { return false } - filterFilesJson, err := json.Marshal(*filter.TriggerFiles) + filterFilesJson, err := json.Marshal(*params.TriggerFiles) if err != nil { return false } diff --git a/pkg/models/profile_data.go b/pkg/models/profile_data.go new file mode 100644 index 0000000000..1f2c6105a5 --- /dev/null +++ b/pkg/models/profile_data.go @@ -0,0 +1,9 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +type ProfileData struct { + Id string `json:"id" validate:"required" gorm:"primaryKey"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` +} // @name ProfileData diff --git a/pkg/models/target.go b/pkg/models/target.go new file mode 100644 index 0000000000..e6dedebe68 --- /dev/null +++ b/pkg/models/target.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +type Target struct { + Id string `json:"id" validate:"required" gorm:"primaryKey"` + Name string `json:"name" validate:"required" gorm:"unique"` + ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json"` + // JSON encoded map of options + Options string `json:"options" validate:"required"` + ApiKey string `json:"-"` + EnvVars map[string]string `json:"-" gorm:"serializer:json"` + IsDefault bool `json:"default" validate:"required"` + Workspaces []Workspace `gorm:"foreignKey:TargetId;references:Id"` +} // @name Target + +type TargetInfo struct { + Name string `json:"name" validate:"required"` + ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` +} // @name TargetInfo + +type ProviderInfo struct { + Name string `json:"name" validate:"required"` + Version string `json:"version" validate:"required"` + Label *string `json:"label" validate:"optional"` +} // @name TargetProviderInfo diff --git a/pkg/target/config/config.go b/pkg/models/target_config.go similarity index 51% rename from pkg/target/config/config.go rename to pkg/models/target_config.go index 0143ee00d7..a6868bc51b 100644 --- a/pkg/target/config/config.go +++ b/pkg/models/target_config.go @@ -1,13 +1,11 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package config - -import "github.com/daytonaio/daytona/pkg/target" +package models type TargetConfig struct { - Name string `json:"name" validate:"required"` - ProviderInfo target.ProviderInfo `json:"providerInfo" validate:"required"` + Name string `json:"name" validate:"required" gorm:"primaryKey"` + ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json"` // JSON encoded map of options Options string `json:"options" validate:"required"` } // @name TargetConfig diff --git a/pkg/workspace/workspace.go b/pkg/models/workspace.go similarity index 71% rename from pkg/workspace/workspace.go rename to pkg/models/workspace.go index ce6f147c0c..62ca68b1ba 100644 --- a/pkg/workspace/workspace.go +++ b/pkg/models/workspace.go @@ -1,27 +1,27 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspace +package models import ( "fmt" "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type Workspace struct { - Id string `json:"id" validate:"required"` + Id string `json:"id" validate:"required" gorm:"primaryKey"` Name string `json:"name" validate:"required"` Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` - Repository *gitprovider.GitRepository `json:"repository" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required"` - TargetId string `json:"targetId" validate:"required"` + BuildConfig *BuildConfig `json:"buildConfig,omitempty" validate:"optional" gorm:"serializer:json"` + Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` + TargetId string `json:"targetId" validate:"required" gorm:"foreignKey:TargetId;references:Id"` + Target Target `json:"target" validate:"required" gorm:"foreignKey:TargetId"` ApiKey string `json:"-"` - State *WorkspaceState `json:"state,omitempty" validate:"optional"` + State *WorkspaceState `json:"state,omitempty" validate:"optional" gorm:"serializer:json"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` } // @name Workspace @@ -32,6 +32,23 @@ func (w *Workspace) WorkspaceFolderName() string { return w.Name } +func (w Workspace) Hostname() string { + // Replace special chars with hyphen to form valid hostname + // String resulting in consecutive hyphens is also valid + workspaceId := w.Id + workspaceId = strings.ReplaceAll(workspaceId, "_", "-") + workspaceId = strings.ReplaceAll(workspaceId, "*", "-") + workspaceId = strings.ReplaceAll(workspaceId, ".", "-") + + hostname := fmt.Sprintf("ws-%s", workspaceId) + + if len(hostname) > 63 { + return hostname[:63] + } + + return hostname +} + type WorkspaceInfo struct { Name string `json:"name" validate:"required"` Created string `json:"created" validate:"required"` @@ -74,47 +91,3 @@ const ( Copied Status = "Copied" UpdatedButUnmerged Status = "Updated but unmerged" ) - -type WorkspaceEnvVarParams struct { - ApiUrl string - ServerUrl string - ServerVersion string - ClientId string -} - -func GetWorkspaceEnvVars(workspace *Workspace, params WorkspaceEnvVarParams, telemetryEnabled bool) map[string]string { - envVars := map[string]string{ - "DAYTONA_TARGET_ID": workspace.TargetId, - "DAYTONA_WORKSPACE_ID": workspace.Id, - "DAYTONA_WORKSPACE_REPOSITORY_URL": workspace.Repository.Url, - "DAYTONA_SERVER_API_KEY": workspace.ApiKey, - "DAYTONA_SERVER_VERSION": params.ServerVersion, - "DAYTONA_SERVER_URL": params.ServerUrl, - "DAYTONA_SERVER_API_URL": params.ApiUrl, - "DAYTONA_CLIENT_ID": params.ClientId, - // (HOME) will be replaced at runtime - "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", - } - - if telemetryEnabled { - envVars["DAYTONA_TELEMETRY_ENABLED"] = "true" - } - - return envVars -} - -func GetWorkspaceHostname(workspaceId string) string { - // Replace special chars with hyphen to form valid hostname - // String resulting in consecutive hyphens is also valid - workspaceId = strings.ReplaceAll(workspaceId, "_", "-") - workspaceId = strings.ReplaceAll(workspaceId, "*", "-") - workspaceId = strings.ReplaceAll(workspaceId, ".", "-") - - hostname := fmt.Sprintf("ws-%s", workspaceId) - - if len(hostname) > 63 { - return hostname[:63] - } - - return hostname -} diff --git a/pkg/workspace/config/config.go b/pkg/models/workspace_config.go similarity index 53% rename from pkg/workspace/config/config.go rename to pkg/models/workspace_config.go index 6321d0963e..ab065928ab 100644 --- a/pkg/workspace/config/config.go +++ b/pkg/models/workspace_config.go @@ -1,24 +1,22 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package config +package models import ( "errors" - - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" ) type WorkspaceConfig struct { - Name string `json:"name" validate:"required"` - Image string `json:"image" validate:"required"` - User string `json:"user" validate:"required"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` - RepositoryUrl string `json:"repositoryUrl" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required"` - IsDefault bool `json:"default" validate:"required"` - Prebuilds []*PrebuildConfig `json:"prebuilds" validate:"optional"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` + Name string `json:"name" validate:"required" gorm:"primaryKey"` + Image string `json:"image" validate:"required"` + User string `json:"user" validate:"required"` + BuildConfig *BuildConfig `json:"buildConfig,omitempty" validate:"optional" gorm:"serializer:json"` + RepositoryUrl string `json:"repositoryUrl" validate:"required"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` + IsDefault bool `json:"default" validate:"required"` + Prebuilds []*PrebuildConfig `json:"prebuilds" validate:"optional" gorm:"serializer:json"` + GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` } // @name WorkspaceConfig func (wc *WorkspaceConfig) SetPrebuild(p *PrebuildConfig) error { @@ -41,7 +39,7 @@ func (wc *WorkspaceConfig) SetPrebuild(p *PrebuildConfig) error { return nil } -func (wc *WorkspaceConfig) FindPrebuild(filter *PrebuildFilter) (*PrebuildConfig, error) { +func (wc *WorkspaceConfig) FindPrebuild(filter *MatchParams) (*PrebuildConfig, error) { for _, pb := range wc.Prebuilds { if pb.Match(filter) { return pb, nil @@ -51,7 +49,7 @@ func (wc *WorkspaceConfig) FindPrebuild(filter *PrebuildFilter) (*PrebuildConfig return nil, errors.New("prebuild not found") } -func (wc *WorkspaceConfig) ListPrebuilds(filter *PrebuildFilter) ([]*PrebuildConfig, error) { +func (wc *WorkspaceConfig) ListPrebuilds(filter *MatchParams) ([]*PrebuildConfig, error) { if filter == nil { return wc.Prebuilds, nil } diff --git a/pkg/profiledata/profile_data.go b/pkg/profiledata/profile_data.go deleted file mode 100644 index 29217a8758..0000000000 --- a/pkg/profiledata/profile_data.go +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package profiledata - -type ProfileData struct { - EnvVars map[string]string `json:"envVars" validate:"required"` -} // @name ProfileData diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index 89a3da6f42..e9d035a4a9 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -14,11 +14,10 @@ import ( "strings" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/models" os_util "github.com/daytonaio/daytona/pkg/os" . "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/shirou/gopsutil/process" @@ -172,9 +171,9 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool continue } - err = m.targetConfigService.Save(&config.TargetConfig{ + err = m.targetConfigService.Save(&models.TargetConfig{ Name: targetConfig.Name, - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: providerInfo.Name, Version: providerInfo.Version, Label: providerInfo.Label, @@ -182,12 +181,12 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool Options: targetConfig.Options, }) if err != nil { - log.Errorf("Failed to set target %s: %s", targetConfig.Name, err) + log.Errorf("Failed to set target config %s: %s", targetConfig.Name, err) } else { - log.Infof("Target %s set", targetConfig.Name) + log.Infof("Target config %s set", targetConfig.Name) } } - log.Infof("Preset targets set for %s", pluginRef.name) + log.Infof("Preset target configs set for %s", pluginRef.name) } log.Infof("Provider %s initialized", pluginRef.name) diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 8d0cd43707..4fb135a1f7 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -6,9 +6,8 @@ package provider import ( "net/rpc" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/hashicorp/go-plugin" ) @@ -24,19 +23,13 @@ type Provider interface { StartTarget(*TargetRequest) (*util.Empty, error) StopTarget(*TargetRequest) (*util.Empty, error) DestroyTarget(*TargetRequest) (*util.Empty, error) - GetTargetInfo(*TargetRequest) (*target.TargetInfo, error) + GetTargetInfo(*TargetRequest) (*models.TargetInfo, error) CreateWorkspace(*WorkspaceRequest) (*util.Empty, error) StartWorkspace(*WorkspaceRequest) (*util.Empty, error) StopWorkspace(*WorkspaceRequest) (*util.Empty, error) DestroyWorkspace(*WorkspaceRequest) (*util.Empty, error) - GetWorkspaceInfo(*WorkspaceRequest) (*workspace.WorkspaceInfo, error) -} - -type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Label *string `json:"label" validate:"optional"` - Version string `json:"version" validate:"required"` + GetWorkspaceInfo(*WorkspaceRequest) (*models.WorkspaceInfo, error) } type ProviderPlugin struct { diff --git a/pkg/provider/rpc_client.go b/pkg/provider/rpc_client.go index ed2a05f5d5..2cf0df32ab 100644 --- a/pkg/provider/rpc_client.go +++ b/pkg/provider/rpc_client.go @@ -6,9 +6,8 @@ package provider import ( "net/rpc" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" ) type ProviderRPCClient struct { @@ -65,8 +64,8 @@ func (m *ProviderRPCClient) DestroyTarget(targetReq *TargetRequest) (*util.Empty return new(util.Empty), err } -func (m *ProviderRPCClient) GetTargetInfo(targetReq *TargetRequest) (*target.TargetInfo, error) { - var response target.TargetInfo +func (m *ProviderRPCClient) GetTargetInfo(targetReq *TargetRequest) (*models.TargetInfo, error) { + var response models.TargetInfo err := m.client.Call("Plugin.GetTargetInfo", targetReq, &response) return &response, err } @@ -91,8 +90,8 @@ func (m *ProviderRPCClient) DestroyWorkspace(workspaceReq *WorkspaceRequest) (*u return new(util.Empty), err } -func (m *ProviderRPCClient) GetWorkspaceInfo(workspaceReq *WorkspaceRequest) (*workspace.WorkspaceInfo, error) { - var resp workspace.WorkspaceInfo +func (m *ProviderRPCClient) GetWorkspaceInfo(workspaceReq *WorkspaceRequest) (*models.WorkspaceInfo, error) { + var resp models.WorkspaceInfo err := m.client.Call("Plugin.GetWorkspaceInfo", workspaceReq, &resp) return &resp, err } diff --git a/pkg/provider/rpc_server.go b/pkg/provider/rpc_server.go index 10f1a9b35f..f00a07a2d6 100644 --- a/pkg/provider/rpc_server.go +++ b/pkg/provider/rpc_server.go @@ -4,9 +4,8 @@ package provider import ( + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider/util" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" ) type ProviderRPCServer struct { @@ -77,7 +76,7 @@ func (m *ProviderRPCServer) DestroyTarget(arg *TargetRequest, resp *util.Empty) return err } -func (m *ProviderRPCServer) GetTargetInfo(arg *TargetRequest, resp *target.TargetInfo) error { +func (m *ProviderRPCServer) GetTargetInfo(arg *TargetRequest, resp *models.TargetInfo) error { info, err := m.Impl.GetTargetInfo(arg) if err != nil { return err @@ -107,7 +106,7 @@ func (m *ProviderRPCServer) DestroyWorkspace(arg *WorkspaceRequest, resp *util.E return err } -func (m *ProviderRPCServer) GetWorkspaceInfo(arg *WorkspaceRequest, resp *workspace.WorkspaceInfo) error { +func (m *ProviderRPCServer) GetWorkspaceInfo(arg *WorkspaceRequest, resp *models.WorkspaceInfo) error { info, err := m.Impl.GetWorkspaceInfo(arg) if err != nil { return err diff --git a/pkg/provider/types.go b/pkg/provider/types.go index 3b55daedc3..f559745495 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -4,10 +4,7 @@ package provider import ( - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" ) type InitializeProviderRequest struct { @@ -26,16 +23,21 @@ type InitializeProviderRequest struct { } type TargetRequest struct { - Target *target.Target + Target *models.Target } type WorkspaceRequest struct { - Target *target.Target - ContainerRegistry *containerregistry.ContainerRegistry - Workspace *workspace.Workspace - GitProviderConfig *gitprovider.GitProviderConfig BuilderImage string - BuilderContainerRegistry *containerregistry.ContainerRegistry + BuilderContainerRegistry *models.ContainerRegistry + ContainerRegistry *models.ContainerRegistry + Workspace *models.Workspace + GitProviderConfig *models.GitProviderConfig +} + +type ProviderInfo struct { + Name string `json:"name" validate:"required"` + Label *string `json:"label" validate:"optional"` + Version string `json:"version" validate:"required"` } type TargetConfig struct { diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index 1767525cbd..da3bf7a795 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -4,11 +4,11 @@ package provisioner import ( + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/target" ) -func (p *Provisioner) CreateTarget(t *target.Target) error { +func (p *Provisioner) CreateTarget(t *models.Target) error { targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err @@ -22,13 +22,12 @@ func (p *Provisioner) CreateTarget(t *target.Target) error { } func (p *Provisioner) CreateWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ - Target: params.Target, Workspace: params.Workspace, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index 9b211b4a6f..dd23977a58 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -4,12 +4,11 @@ package provisioner import ( + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" ) -func (p *Provisioner) DestroyTarget(t *target.Target) error { +func (p *Provisioner) DestroyTarget(t *models.Target) error { targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err @@ -22,14 +21,13 @@ func (p *Provisioner) DestroyTarget(t *target.Target) error { return err } -func (p *Provisioner) DestroyWorkspace(ws *workspace.Workspace, t *target.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) +func (p *Provisioner) DestroyWorkspace(ws *models.Workspace) error { + targetProvider, err := p.providerManager.GetProvider(ws.Target.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).DestroyWorkspace(&provider.WorkspaceRequest{ - Target: t, Workspace: ws, }) diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go index 5f4f08928f..d64f20c66e 100644 --- a/pkg/provisioner/info.go +++ b/pkg/provisioner/info.go @@ -6,18 +6,17 @@ package provisioner import ( "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" ) type TargetInfoResult struct { - Info *target.TargetInfo + Info *models.TargetInfo Err error } // Gets the target info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetTargetInfo(ctx context.Context, t *target.Target) (*target.TargetInfo, error) { +func (p *Provisioner) GetTargetInfo(ctx context.Context, t *models.Target) (*models.TargetInfo, error) { ch := make(chan TargetInfoResult, 1) go func() { @@ -43,23 +42,22 @@ func (p *Provisioner) GetTargetInfo(ctx context.Context, t *target.Target) (*tar } type WorkspaceInfoResult struct { - Info *workspace.WorkspaceInfo + Info *models.WorkspaceInfo Err error } // Gets the workspace info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, t *target.Target) (*workspace.WorkspaceInfo, error) { +func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *models.Workspace) (*models.WorkspaceInfo, error) { ch := make(chan WorkspaceInfoResult, 1) go func() { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(workspace.Target.ProviderInfo.Name) if err != nil { ch <- WorkspaceInfoResult{nil, err} return } info, err := (*targetProvider).GetWorkspaceInfo(&provider.WorkspaceRequest{ - Target: t, Workspace: workspace, }) diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index af696e6bd5..85e93a57e7 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -6,34 +6,31 @@ package provisioner import ( "context" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" ) type WorkspaceParams struct { - Workspace *workspace.Workspace - Target *target.Target - ContainerRegistry *containerregistry.ContainerRegistry - GitProviderConfig *gitprovider.GitProviderConfig + Workspace *models.Workspace + Target *models.Target + ContainerRegistry *models.ContainerRegistry + GitProviderConfig *models.GitProviderConfig BuilderImage string - BuilderImageContainerRegistry *containerregistry.ContainerRegistry + BuilderImageContainerRegistry *models.ContainerRegistry } type IProvisioner interface { - CreateTarget(target *target.Target) error - StartTarget(target *target.Target) error - StopTarget(target *target.Target) error - GetTargetInfo(ctx context.Context, target *target.Target) (*target.TargetInfo, error) - DestroyTarget(target *target.Target) error + CreateTarget(target *models.Target) error + StartTarget(target *models.Target) error + StopTarget(target *models.Target) error + GetTargetInfo(ctx context.Context, target *models.Target) (*models.TargetInfo, error) + DestroyTarget(target *models.Target) error CreateWorkspace(params WorkspaceParams) error - DestroyWorkspace(workspace *workspace.Workspace, target *target.Target) error + DestroyWorkspace(workspace *models.Workspace) error StartWorkspace(params WorkspaceParams) error - StopWorkspace(workspace *workspace.Workspace, target *target.Target) error - GetWorkspaceInfo(ctx context.Context, workspace *workspace.Workspace, target *target.Target) (*workspace.WorkspaceInfo, error) + StopWorkspace(workspace *models.Workspace) error + GetWorkspaceInfo(ctx context.Context, workspace *models.Workspace) (*models.WorkspaceInfo, error) } type ProvisionerConfig struct { diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index 6cb66861af..9e018b4e26 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -4,11 +4,11 @@ package provisioner import ( + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/target" ) -func (p *Provisioner) StartTarget(t *target.Target) error { +func (p *Provisioner) StartTarget(t *models.Target) error { targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err @@ -22,13 +22,12 @@ func (p *Provisioner) StartTarget(t *target.Target) error { } func (p *Provisioner) StartWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ - Target: params.Target, Workspace: params.Workspace, ContainerRegistry: params.ContainerRegistry, GitProviderConfig: params.GitProviderConfig, diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index abe71c4e0f..f1e1dcb7b7 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -4,12 +4,11 @@ package provisioner import ( + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" ) -func (p *Provisioner) StopTarget(t *target.Target) error { +func (p *Provisioner) StopTarget(t *models.Target) error { targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) if err != nil { return err @@ -22,14 +21,13 @@ func (p *Provisioner) StopTarget(t *target.Target) error { return err } -func (p *Provisioner) StopWorkspace(ws *workspace.Workspace, t *target.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) +func (p *Provisioner) StopWorkspace(ws *models.Workspace) error { + targetProvider, err := p.providerManager.GetProvider(ws.Target.ProviderInfo.Name) if err != nil { return err } _, err = (*targetProvider).StopWorkspace(&provider.WorkspaceRequest{ - Target: t, Workspace: ws, }) diff --git a/pkg/server/apikeys/apikeys.go b/pkg/server/apikeys/apikeys.go index fc46dcea00..59c8b9fec9 100644 --- a/pkg/server/apikeys/apikeys.go +++ b/pkg/server/apikeys/apikeys.go @@ -5,19 +5,19 @@ package apikeys import ( "github.com/daytonaio/daytona/internal/apikeys" - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" ) -func (s *ApiKeyService) ListClientKeys() ([]*apikey.ApiKey, error) { +func (s *ApiKeyService) ListClientKeys() ([]*models.ApiKey, error) { keys, err := s.apiKeyStore.List() if err != nil { return nil, err } - clientKeys := []*apikey.ApiKey{} + clientKeys := []*models.ApiKey{} for _, key := range keys { - if key.Type == apikey.ApiKeyTypeClient { + if key.Type == models.ApiKeyTypeClient { clientKeys = append(clientKeys, key) } } @@ -34,10 +34,10 @@ func (s *ApiKeyService) Revoke(name string) error { return s.apiKeyStore.Delete(apiKey) } -func (s *ApiKeyService) Generate(keyType apikey.ApiKeyType, name string) (string, error) { +func (s *ApiKeyService) Generate(keyType models.ApiKeyType, name string) (string, error) { key := apikeys.GenerateRandomKey() - apiKey := &apikey.ApiKey{ + apiKey := &models.ApiKey{ KeyHash: apikeys.HashKey(key), Type: keyType, Name: name, diff --git a/pkg/server/apikeys/apikeys_test.go b/pkg/server/apikeys/apikeys_test.go index 9ab9ca3092..cbc9ba6e47 100644 --- a/pkg/server/apikeys/apikeys_test.go +++ b/pkg/server/apikeys/apikeys_test.go @@ -3,10 +3,12 @@ package apikeys_test -import "github.com/daytonaio/daytona/pkg/apikey" +import ( + "github.com/daytonaio/daytona/pkg/models" +) func (s *ApiKeyServiceTestSuite) TestListClientKeys() { - expectedKeys := []*apikey.ApiKey{} + expectedKeys := []*models.ApiKey{} keyNames := []string{} keyNames = append(keyNames, clientKeyNames...) @@ -24,7 +26,7 @@ func (s *ApiKeyServiceTestSuite) TestListClientKeys() { } func (s *ApiKeyServiceTestSuite) TestRevoke() { - expectedKeys := []*apikey.ApiKey{} + expectedKeys := []*models.ApiKey{} keyNames := []string{} keyNames = append(keyNames, clientKeyNames[1:]...) @@ -45,7 +47,7 @@ func (s *ApiKeyServiceTestSuite) TestRevoke() { } func (s *ApiKeyServiceTestSuite) TestGenerate() { - expectedKeys := []*apikey.ApiKey{} + expectedKeys := []*models.ApiKey{} keyNames := []string{} keyNames = append(keyNames, clientKeyNames...) @@ -59,7 +61,7 @@ func (s *ApiKeyServiceTestSuite) TestGenerate() { require := s.Require() - _, err := s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) + _, err := s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) require.Nil(err) apiKey, err := s.apiKeyStore.FindByName(keyName) diff --git a/pkg/server/apikeys/service.go b/pkg/server/apikeys/service.go index 83b1c5074d..67680ba882 100644 --- a/pkg/server/apikeys/service.go +++ b/pkg/server/apikeys/service.go @@ -3,19 +3,19 @@ package apikeys -import "github.com/daytonaio/daytona/pkg/apikey" +import "github.com/daytonaio/daytona/pkg/models" type IApiKeyService interface { - Generate(keyType apikey.ApiKeyType, name string) (string, error) + Generate(keyType models.ApiKeyType, name string) (string, error) IsWorkspaceApiKey(apiKey string) bool IsTargetApiKey(apiKey string) bool IsValidApiKey(apiKey string) bool - ListClientKeys() ([]*apikey.ApiKey, error) + ListClientKeys() ([]*models.ApiKey, error) Revoke(name string) error } type ApiKeyServiceConfig struct { - ApiKeyStore apikey.Store + ApiKeyStore ApiKeyStore } func NewApiKeyService(config ApiKeyServiceConfig) IApiKeyService { @@ -25,5 +25,5 @@ func NewApiKeyService(config ApiKeyServiceConfig) IApiKeyService { } type ApiKeyService struct { - apiKeyStore apikey.Store + apiKeyStore ApiKeyStore } diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index 9b4ef92d2e..d3d62ca6d8 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -7,7 +7,7 @@ import ( "testing" t_apikeys "github.com/daytonaio/daytona/internal/testing/server/apikeys" - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/stretchr/testify/suite" ) @@ -18,7 +18,7 @@ var workspaceKeyNames []string = []string{"workspace1", "workspace2"} type ApiKeyServiceTestSuite struct { suite.Suite apiKeyService apikeys.IApiKeyService - apiKeyStore apikey.Store + apiKeyStore apikeys.ApiKeyStore } func NewApiKeyServiceTestSuite() *ApiKeyServiceTestSuite { @@ -32,11 +32,11 @@ func (s *ApiKeyServiceTestSuite) SetupTest() { }) for _, keyName := range clientKeyNames { - _, _ = s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) + _, _ = s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) } for _, keyName := range workspaceKeyNames { - _, _ = s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) + _, _ = s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, keyName) } } diff --git a/pkg/server/apikeys/store.go b/pkg/server/apikeys/store.go new file mode 100644 index 0000000000..c5d6ab0914 --- /dev/null +++ b/pkg/server/apikeys/store.go @@ -0,0 +1,26 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package apikeys + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type ApiKeyStore interface { + List() ([]*models.ApiKey, error) + Find(key string) (*models.ApiKey, error) + FindByName(name string) (*models.ApiKey, error) + Save(apiKey *models.ApiKey) error + Delete(apiKey *models.ApiKey) error +} + +var ( + ErrApiKeyNotFound = errors.New("api key not found") +) + +func IsApiKeyNotFound(err error) bool { + return err.Error() == ErrApiKeyNotFound.Error() +} diff --git a/pkg/server/apikeys/validate.go b/pkg/server/apikeys/validate.go index c5372011cf..121b230628 100644 --- a/pkg/server/apikeys/validate.go +++ b/pkg/server/apikeys/validate.go @@ -5,7 +5,7 @@ package apikeys import ( "github.com/daytonaio/daytona/internal/apikeys" - "github.com/daytonaio/daytona/pkg/apikey" + "github.com/daytonaio/daytona/pkg/models" ) func (s *ApiKeyService) IsValidApiKey(apiKey string) bool { @@ -23,7 +23,7 @@ func (s *ApiKeyService) IsWorkspaceApiKey(apiKey string) bool { return false } - if key.Type != apikey.ApiKeyTypeWorkspace { + if key.Type != models.ApiKeyTypeWorkspace { return false } @@ -38,7 +38,7 @@ func (s *ApiKeyService) IsTargetApiKey(apiKey string) bool { return false } - if key.Type != apikey.ApiKeyTypeTarget { + if key.Type != models.ApiKeyTypeTarget { return false } diff --git a/pkg/server/apikeys/validate_test.go b/pkg/server/apikeys/validate_test.go index 040100062f..dc527db45b 100644 --- a/pkg/server/apikeys/validate_test.go +++ b/pkg/server/apikeys/validate_test.go @@ -3,14 +3,14 @@ package apikeys_test -import "github.com/daytonaio/daytona/pkg/apikey" +import "github.com/daytonaio/daytona/pkg/models" func (s *ApiKeyServiceTestSuite) TestIsValidKey_True() { keyName := "api-key" require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, keyName) require.Nil(err) res := s.apiKeyService.IsValidApiKey(apiKey) @@ -31,7 +31,7 @@ func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_True() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, keyName) require.Nil(err) res := s.apiKeyService.IsWorkspaceApiKey(apiKey) @@ -43,7 +43,7 @@ func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_False() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) require.Nil(err) res := s.apiKeyService.IsWorkspaceApiKey(apiKey) @@ -55,7 +55,7 @@ func (s *ApiKeyServiceTestSuite) TestIsIsTargetApiKey_True() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, keyName) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeTarget, keyName) require.Nil(err) res := s.apiKeyService.IsTargetApiKey(apiKey) @@ -67,7 +67,7 @@ func (s *ApiKeyServiceTestSuite) TestIsTargetApiKey_False() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeClient, keyName) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) require.Nil(err) res := s.apiKeyService.IsTargetApiKey(apiKey) diff --git a/pkg/server/builds/dto/builds.go b/pkg/server/builds/dto/builds.go index 7cadf1e552..f307d62f70 100644 --- a/pkg/server/builds/dto/builds.go +++ b/pkg/server/builds/dto/builds.go @@ -5,13 +5,13 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/models" ) type BuildCreationData struct { Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig" validate:"optional"` + BuildConfig *models.BuildConfig `json:"buildConfig" validate:"optional"` Repository *gitprovider.GitRepository `json:"repository" validate:"optional"` EnvVars map[string]string `json:"envVars" validate:"required"` PrebuildId string `json:"prebuildId" validate:"required"` diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index b16424eee8..a7a7b323cd 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -8,30 +8,29 @@ import ( "io" "time" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/workspace/containerconfig" "github.com/docker/docker/pkg/stringid" ) type IBuildService interface { Create(dto.BuildCreationData) (string, error) - Find(filter *build.Filter) (*build.Build, error) - List(filter *build.Filter) ([]*build.Build, error) - MarkForDeletion(filter *build.Filter, force bool) []error + Find(filter *BuildFilter) (*models.Build, error) + List(filter *BuildFilter) ([]*models.Build, error) + MarkForDeletion(filter *BuildFilter, force bool) []error Delete(id string) error AwaitEmptyList(time.Duration) error GetBuildLogReader(buildId string) (io.Reader, error) } type BuildServiceConfig struct { - BuildStore build.Store + BuildStore BuildStore LoggerFactory logs.LoggerFactory } type BuildService struct { - buildStore build.Store + buildStore BuildStore loggerFactory logs.LoggerFactory } @@ -43,14 +42,14 @@ func NewBuildService(config BuildServiceConfig) IBuildService { } func (s *BuildService) Create(b dto.BuildCreationData) (string, error) { - var newBuild build.Build + var newBuild models.Build id := stringid.GenerateRandomID() id = stringid.TruncateID(id) newBuild.Id = id - newBuild.State = build.BuildStatePendingRun - newBuild.ContainerConfig = containerconfig.ContainerConfig{ + newBuild.State = models.BuildStatePendingRun + newBuild.ContainerConfig = models.ContainerConfig{ Image: b.Image, User: b.User, } @@ -67,15 +66,15 @@ func (s *BuildService) Create(b dto.BuildCreationData) (string, error) { return id, nil } -func (s *BuildService) Find(filter *build.Filter) (*build.Build, error) { +func (s *BuildService) Find(filter *BuildFilter) (*models.Build, error) { return s.buildStore.Find(filter) } -func (s *BuildService) List(filter *build.Filter) ([]*build.Build, error) { +func (s *BuildService) List(filter *BuildFilter) ([]*models.Build, error) { return s.buildStore.List(filter) } -func (s *BuildService) MarkForDeletion(filter *build.Filter, force bool) []error { +func (s *BuildService) MarkForDeletion(filter *BuildFilter, force bool) []error { var errors []error builds, err := s.List(filter) @@ -85,9 +84,9 @@ func (s *BuildService) MarkForDeletion(filter *build.Filter, force bool) []error for _, b := range builds { if force { - b.State = build.BuildStatePendingForcedDelete + b.State = models.BuildStatePendingForcedDelete } else { - b.State = build.BuildStatePendingDelete + b.State = models.BuildStatePendingDelete } err = s.buildStore.Save(b) diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index f0608a3434..2ed1cd1fc6 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -7,34 +7,32 @@ import ( "testing" build_internal "github.com/daytonaio/daytona/internal/testing/build" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" - "github.com/daytonaio/daytona/pkg/workspace/containerconfig" "github.com/stretchr/testify/suite" ) var build1Image = "image1" var build1User = "user1" -var build1 *build.Build = &build.Build{ +var build1 *models.Build = &models.Build{ Id: "id1", - ContainerConfig: containerconfig.ContainerConfig{ + ContainerConfig: models.ContainerConfig{ Image: build1Image, User: build1User, }, - BuildConfig: &buildconfig.BuildConfig{}, + BuildConfig: &models.BuildConfig{}, Repository: &gitprovider.GitRepository{ Sha: "sha1", }, - State: build.BuildStatePublished, + State: models.BuildStatePublished, } -var build2 *build.Build = &build.Build{ +var build2 *models.Build = &models.Build{ Id: "id2", - ContainerConfig: containerconfig.ContainerConfig{ + ContainerConfig: models.ContainerConfig{ Image: "image2", User: "user2", }, @@ -42,12 +40,12 @@ var build2 *build.Build = &build.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha2", }, - State: build.BuildStatePublished, + State: models.BuildStatePublished, } -var build3 *build.Build = &build.Build{ +var build3 *models.Build = &models.Build{ Id: "id3", - ContainerConfig: containerconfig.ContainerConfig{ + ContainerConfig: models.ContainerConfig{ Image: "image3", User: "user3", }, @@ -55,12 +53,12 @@ var build3 *build.Build = &build.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha3", }, - State: build.BuildStatePendingRun, + State: models.BuildStatePendingRun, } -var build4 *build.Build = &build.Build{ +var build4 *models.Build = &models.Build{ Id: "id4", - ContainerConfig: containerconfig.ContainerConfig{ + ContainerConfig: models.ContainerConfig{ Image: "image4", User: "user4", }, @@ -68,19 +66,19 @@ var build4 *build.Build = &build.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha4", }, - State: build.BuildStatePendingRun, + State: models.BuildStatePendingRun, } -var expectedBuilds []*build.Build -var expectedFilteredBuilds []*build.Build +var expectedBuilds []*models.Build +var expectedFilteredBuilds []*models.Build -var expectedBuildsMap map[string]*build.Build -var expectedFilteredBuildsMap map[string]*build.Build +var expectedBuildsMap map[string]*models.Build +var expectedFilteredBuildsMap map[string]*models.Build type BuildServiceTestSuite struct { suite.Suite buildService builds.IBuildService - buildStore build.Store + buildStore builds.BuildStore } func NewBuildServiceTestSuite() *BuildServiceTestSuite { @@ -88,21 +86,21 @@ func NewBuildServiceTestSuite() *BuildServiceTestSuite { } func (s *BuildServiceTestSuite) SetupTest() { - expectedBuilds = []*build.Build{ + expectedBuilds = []*models.Build{ build1, build2, build3, } - expectedBuildsMap = map[string]*build.Build{ + expectedBuildsMap = map[string]*models.Build{ build1.Id: build1, build2.Id: build2, build3.Id: build3, } - expectedFilteredBuilds = []*build.Build{ + expectedFilteredBuilds = []*models.Build{ build1, build2, } - expectedFilteredBuildsMap = map[string]*build.Build{ + expectedFilteredBuildsMap = map[string]*models.Build{ build1.Id: build1, build2.Id: build2, } @@ -132,7 +130,7 @@ func (s *BuildServiceTestSuite) TestList() { func (s *BuildServiceTestSuite) TestFind() { require := s.Require() - build, err := s.buildService.Find(&build.Filter{ + build, err := s.buildService.Find(&builds.BuildFilter{ Id: &build1.Id, }) require.Nil(err) @@ -166,16 +164,16 @@ func (s *BuildServiceTestSuite) TestMarkForDeletion() { require := s.Require() - err := s.buildService.MarkForDeletion(&build.Filter{ + err := s.buildService.MarkForDeletion(&builds.BuildFilter{ Id: &build3.Id, }, false) require.Nil(err) - b, errs := s.buildService.Find(&build.Filter{ + b, errs := s.buildService.Find(&builds.BuildFilter{ Id: &build3.Id, }) require.Nil(errs) - require.Equal(b.State, build.BuildStatePendingDelete) + require.Equal(b.State, models.BuildStatePendingDelete) } func (s *BuildServiceTestSuite) TestDelete() { diff --git a/pkg/build/store.go b/pkg/server/builds/store.go similarity index 60% rename from pkg/build/store.go rename to pkg/server/builds/store.go index 1b863afa73..c77e0ec940 100644 --- a/pkg/build/store.go +++ b/pkg/server/builds/store.go @@ -1,18 +1,18 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package build +package builds import ( "errors" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/models" ) -type Store interface { - Find(filter *Filter) (*Build, error) - List(filter *Filter) ([]*Build, error) - Save(build *Build) error +type BuildStore interface { + Find(filter *BuildFilter) (*models.Build, error) + List(filter *BuildFilter) ([]*models.Build, error) + Save(build *models.Build) error Delete(id string) error } @@ -24,18 +24,18 @@ func IsBuildNotFound(err error) bool { return err.Error() == ErrBuildNotFound.Error() } -type Filter struct { +type BuildFilter struct { Id *string - States *[]BuildState + States *[]models.BuildState PrebuildIds *[]string GetNewest *bool - BuildConfig *buildconfig.BuildConfig + BuildConfig *models.BuildConfig RepositoryUrl *string Branch *string EnvVars *map[string]string } -func (f *Filter) StatesToInterface() []interface{} { +func (f *BuildFilter) StatesToInterface() []interface{} { args := make([]interface{}, len(*f.States)) for i, v := range *f.States { args[i] = v @@ -43,7 +43,7 @@ func (f *Filter) StatesToInterface() []interface{} { return args } -func (f *Filter) PrebuildIdsToInterface() []interface{} { +func (f *BuildFilter) PrebuildIdsToInterface() []interface{} { args := make([]interface{}, len(*f.PrebuildIds)) for i, v := range *f.PrebuildIds { args[i] = v diff --git a/pkg/server/containerregistries/service.go b/pkg/server/containerregistries/service.go index cac16963e7..df4ea2a311 100644 --- a/pkg/server/containerregistries/service.go +++ b/pkg/server/containerregistries/service.go @@ -6,24 +6,24 @@ package containerregistries import ( "strings" - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" ) type IContainerRegistryService interface { Delete(server string) error - Find(server string) (*containerregistry.ContainerRegistry, error) - FindByImageName(imageName string) (*containerregistry.ContainerRegistry, error) - List() ([]*containerregistry.ContainerRegistry, error) - Map() (map[string]*containerregistry.ContainerRegistry, error) - Save(cr *containerregistry.ContainerRegistry) error + Find(server string) (*models.ContainerRegistry, error) + FindByImageName(imageName string) (*models.ContainerRegistry, error) + List() ([]*models.ContainerRegistry, error) + Map() (map[string]*models.ContainerRegistry, error) + Save(cr *models.ContainerRegistry) error } type ContainerRegistryServiceConfig struct { - Store containerregistry.Store + Store ContainerRegistryStore } type ContainerRegistryService struct { - store containerregistry.Store + store ContainerRegistryStore } func NewContainerRegistryService(config ContainerRegistryServiceConfig) IContainerRegistryService { @@ -32,17 +32,17 @@ func NewContainerRegistryService(config ContainerRegistryServiceConfig) IContain } } -func (s *ContainerRegistryService) List() ([]*containerregistry.ContainerRegistry, error) { +func (s *ContainerRegistryService) List() ([]*models.ContainerRegistry, error) { return s.store.List() } -func (s *ContainerRegistryService) Map() (map[string]*containerregistry.ContainerRegistry, error) { +func (s *ContainerRegistryService) Map() (map[string]*models.ContainerRegistry, error) { list, err := s.store.List() if err != nil { return nil, err } - crs := make(map[string]*containerregistry.ContainerRegistry) + crs := make(map[string]*models.ContainerRegistry) for _, cr := range list { crs[cr.Server] = cr } @@ -50,17 +50,17 @@ func (s *ContainerRegistryService) Map() (map[string]*containerregistry.Containe return crs, nil } -func (s *ContainerRegistryService) Find(server string) (*containerregistry.ContainerRegistry, error) { +func (s *ContainerRegistryService) Find(server string) (*models.ContainerRegistry, error) { return s.store.Find(server) } -func (s *ContainerRegistryService) FindByImageName(imageName string) (*containerregistry.ContainerRegistry, error) { +func (s *ContainerRegistryService) FindByImageName(imageName string) (*models.ContainerRegistry, error) { server := getImageServer(imageName) return s.Find(server) } -func (s *ContainerRegistryService) Save(cr *containerregistry.ContainerRegistry) error { +func (s *ContainerRegistryService) Save(cr *models.ContainerRegistry) error { return s.store.Save(cr) } diff --git a/pkg/server/containerregistries/service_test.go b/pkg/server/containerregistries/service_test.go index 800fbdc12e..bbd2793587 100644 --- a/pkg/server/containerregistries/service_test.go +++ b/pkg/server/containerregistries/service_test.go @@ -7,7 +7,7 @@ import ( "testing" t_containerregistries "github.com/daytonaio/daytona/internal/testing/server/containerregistries" - "github.com/daytonaio/daytona/pkg/containerregistry" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/stretchr/testify/require" ) @@ -20,7 +20,7 @@ func TestContainerRegistryService(t *testing.T) { }) t.Run("CreateContainerRegistry", func(t *testing.T) { - var crOrg = &containerregistry.ContainerRegistry{ + var crOrg = &models.ContainerRegistry{ Server: "example.com", Username: "user", Password: "password", @@ -37,7 +37,7 @@ func TestContainerRegistryService(t *testing.T) { }) t.Run("FindByImageName", func(t *testing.T) { - var crOrg = &containerregistry.ContainerRegistry{ + var crOrg = &models.ContainerRegistry{ Server: "example.com", Username: "user", Password: "password", diff --git a/pkg/server/containerregistries/store.go b/pkg/server/containerregistries/store.go new file mode 100644 index 0000000000..b10a84965d --- /dev/null +++ b/pkg/server/containerregistries/store.go @@ -0,0 +1,25 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package containerregistries + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type ContainerRegistryStore interface { + List() ([]*models.ContainerRegistry, error) + Find(server string) (*models.ContainerRegistry, error) + Save(cr *models.ContainerRegistry) error + Delete(cr *models.ContainerRegistry) error +} + +var ( + ErrContainerRegistryNotFound = errors.New("container registry not found") +) + +func IsContainerRegistryNotFound(err error) bool { + return err.Error() == ErrContainerRegistryNotFound.Error() +} diff --git a/pkg/server/gitproviders/config.go b/pkg/server/gitproviders/config.go index 0e825f344c..c28f14b096 100644 --- a/pkg/server/gitproviders/config.go +++ b/pkg/server/gitproviders/config.go @@ -8,19 +8,20 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/pkg/stringid" ) -func (s *GitProviderService) GetConfig(id string) (*gitprovider.GitProviderConfig, error) { +func (s *GitProviderService) GetConfig(id string) (*models.GitProviderConfig, error) { return s.configStore.Find(id) } -func (s *GitProviderService) ListConfigs() ([]*gitprovider.GitProviderConfig, error) { +func (s *GitProviderService) ListConfigs() ([]*models.GitProviderConfig, error) { return s.configStore.List() } -func (s *GitProviderService) ListConfigsForUrl(repoUrl string) ([]*gitprovider.GitProviderConfig, error) { - var gpcs []*gitprovider.GitProviderConfig +func (s *GitProviderService) ListConfigsForUrl(repoUrl string) ([]*models.GitProviderConfig, error) { + var gpcs []*models.GitProviderConfig gitProviders, err := s.configStore.List() if err != nil { @@ -50,7 +51,7 @@ func (s *GitProviderService) ListConfigsForUrl(repoUrl string) ([]*gitprovider.G return gpcs, nil } -func (s *GitProviderService) SetGitProviderConfig(providerConfig *gitprovider.GitProviderConfig) error { +func (s *GitProviderService) SetGitProviderConfig(providerConfig *models.GitProviderConfig) error { gitProvider, err := s.newGitProvider(providerConfig) if err != nil { return err diff --git a/pkg/server/gitproviders/gitprovider.go b/pkg/server/gitproviders/gitprovider.go index 6f4356c358..f5816b54a6 100644 --- a/pkg/server/gitproviders/gitprovider.go +++ b/pkg/server/gitproviders/gitprovider.go @@ -11,6 +11,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" ) func (s *GitProviderService) GetGitProviderForUrl(repoUrl string) (gitprovider.GitProvider, string, error) { @@ -46,7 +47,7 @@ func (s *GitProviderService) GetGitProviderForUrl(repoUrl string) (gitprovider.G } for _, p := range config.GetSupportedGitProviders() { - gitProvider, err := s.newGitProvider(&gitprovider.GitProviderConfig{ + gitProvider, err := s.newGitProvider(&models.GitProviderConfig{ ProviderId: p.Id, Id: p.Id, Username: "", @@ -66,7 +67,7 @@ func (s *GitProviderService) GetGitProviderForUrl(repoUrl string) (gitprovider.G } func (s *GitProviderService) GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) { - var provider *gitprovider.GitProviderConfig + var provider *models.GitProviderConfig gitProviders, err := s.configStore.List() if err != nil { diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index 8d724160a9..76d8cead50 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -3,8 +3,6 @@ package gitproviders -import "github.com/daytonaio/daytona/pkg/workspace/config" - func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { gitProvider, err := s.configStore.Find(gitProviderId) if err != nil { @@ -12,9 +10,7 @@ func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { } // Check if workspace configs need to be updated - workspaceConfigs, err := s.workspaceConfigStore.List(&config.WorkspaceConfigFilter{ - GitProviderConfigId: &gitProviderId, - }) + workspaceConfigs, err := s.workspaceConfigStore.List(gitProviderId) if err != nil { return err diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index efeb647933..783eb6daa6 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -10,12 +10,12 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/models" ) type IGitProviderService interface { - GetConfig(id string) (*gitprovider.GitProviderConfig, error) - ListConfigsForUrl(url string) ([]*gitprovider.GitProviderConfig, error) + GetConfig(id string) (*models.GitProviderConfig, error) + ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) GetGitProvider(id string) (gitprovider.GitProvider, error) GetGitProviderForUrl(url string) (gitprovider.GitProvider, string, error) GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) @@ -24,27 +24,22 @@ type IGitProviderService interface { GetRepoBranches(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) GetRepoPRs(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) GetRepositories(gitProviderId string, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) - ListConfigs() ([]*gitprovider.GitProviderConfig, error) + ListConfigs() ([]*models.GitProviderConfig, error) RemoveGitProvider(gitProviderId string) error - SetGitProviderConfig(providerConfig *gitprovider.GitProviderConfig) error + SetGitProviderConfig(providerConfig *models.GitProviderConfig) error GetLastCommitSha(repo *gitprovider.GitRepository) (string, error) RegisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) GetPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) UnregisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, id string) error } -type WorkspaceConfigStore interface { - Save(workspaceConfig *config.WorkspaceConfig) error - List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) -} - type GitProviderServiceConfig struct { - ConfigStore gitprovider.ConfigStore + ConfigStore GitProviderConfigStore WorkspaceConfigStore WorkspaceConfigStore } type GitProviderService struct { - configStore gitprovider.ConfigStore + configStore GitProviderConfigStore workspaceConfigStore WorkspaceConfigStore } @@ -61,8 +56,8 @@ func (s *GitProviderService) GetGitProvider(id string) (gitprovider.GitProvider, providerConfig, err := s.configStore.Find(id) if err != nil { // If config is not defined, use the default (public) client without token - if gitprovider.IsGitProviderNotFound(err) { - providerConfig = &gitprovider.GitProviderConfig{ + if IsGitProviderNotFound(err) { + providerConfig = &models.GitProviderConfig{ Id: id, ProviderId: id, Username: "", @@ -128,7 +123,7 @@ func (s *GitProviderService) GetLastCommitSha(repo *gitprovider.GitRepository) ( hostname := strings.TrimPrefix(repo.Source, "www.") providerId := strings.Split(hostname, ".")[0] - provider, err = s.newGitProvider(&gitprovider.GitProviderConfig{ + provider, err = s.newGitProvider(&models.GitProviderConfig{ Id: "", ProviderId: providerId, Username: "", @@ -153,7 +148,7 @@ func (s *GitProviderService) GetLastCommitSha(repo *gitprovider.GitRepository) ( }) } -func (s *GitProviderService) newGitProvider(config *gitprovider.GitProviderConfig) (gitprovider.GitProvider, error) { +func (s *GitProviderService) newGitProvider(config *models.GitProviderConfig) (gitprovider.GitProvider, error) { baseApiUrl := "" if config.BaseApiUrl != nil { baseApiUrl = *config.BaseApiUrl diff --git a/pkg/server/gitproviders/store.go b/pkg/server/gitproviders/store.go new file mode 100644 index 0000000000..8be4233d9b --- /dev/null +++ b/pkg/server/gitproviders/store.go @@ -0,0 +1,30 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package gitproviders + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type GitProviderConfigStore interface { + List() ([]*models.GitProviderConfig, error) + Find(id string) (*models.GitProviderConfig, error) + Save(*models.GitProviderConfig) error + Delete(*models.GitProviderConfig) error +} + +type WorkspaceConfigStore interface { + Save(workspaceConfig *models.WorkspaceConfig) error + List(gitProviderConfigId string) ([]*models.WorkspaceConfig, error) +} + +var ( + ErrGitProviderConfigNotFound = errors.New("git provider config not found") +) + +func IsGitProviderNotFound(err error) bool { + return err.Error() == ErrGitProviderConfigNotFound.Error() +} diff --git a/pkg/server/gitproviders/util/workspace_config_store.go b/pkg/server/gitproviders/util/workspace_config_store.go new file mode 100644 index 0000000000..284c48a5f7 --- /dev/null +++ b/pkg/server/gitproviders/util/workspace_config_store.go @@ -0,0 +1,30 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package uitl + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" +) + +type store struct { + store workspaceconfigs.WorkspaceConfigStore +} + +func (s *store) Save(workspaceConfig *models.WorkspaceConfig) error { + return s.store.Save(workspaceConfig) +} + +func (s *store) List(gitProviderConfigId string) ([]*models.WorkspaceConfig, error) { + return s.store.List(&workspaceconfigs.WorkspaceConfigFilter{ + GitProviderConfigId: &gitProviderConfigId, + }) +} + +func FromWorkspaceConfigStore(workspaceConfigStore workspaceconfigs.WorkspaceConfigStore) gitproviders.WorkspaceConfigStore { + return &store{ + store: workspaceConfigStore, + } +} diff --git a/pkg/server/profiledata/service.go b/pkg/server/profiledata/service.go index 3e1ca818ce..920658aef0 100644 --- a/pkg/server/profiledata/service.go +++ b/pkg/server/profiledata/service.go @@ -4,17 +4,17 @@ package profiledata import ( - . "github.com/daytonaio/daytona/pkg/profiledata" + "github.com/daytonaio/daytona/pkg/models" ) type IProfileDataService interface { - Get() (*ProfileData, error) - Save(profileData *ProfileData) error - Delete() error + Get(id string) (*models.ProfileData, error) + Save(profileData *models.ProfileData) error + Delete(id string) error } type ProfileDataServiceConfig struct { - ProfileDataStore Store + ProfileDataStore ProfileDataStore } func NewProfileDataService(config ProfileDataServiceConfig) IProfileDataService { @@ -24,17 +24,29 @@ func NewProfileDataService(config ProfileDataServiceConfig) IProfileDataService } type ProfileDataService struct { - profileDataStore Store + profileDataStore ProfileDataStore } -func (s *ProfileDataService) Get() (*ProfileData, error) { - return s.profileDataStore.Get() +func (s *ProfileDataService) Get(id string) (*models.ProfileData, error) { + if id == "" { + id = ProfileDataId + } + + return s.profileDataStore.Get(id) } -func (s *ProfileDataService) Save(profileData *ProfileData) error { +func (s *ProfileDataService) Save(profileData *models.ProfileData) error { + if profileData.Id == "" { + profileData.Id = ProfileDataId + } + return s.profileDataStore.Save(profileData) } -func (s *ProfileDataService) Delete() error { - return s.profileDataStore.Delete() +func (s *ProfileDataService) Delete(id string) error { + if id == "" { + id = ProfileDataId + } + + return s.profileDataStore.Delete(id) } diff --git a/pkg/server/profiledata/service_test.go b/pkg/server/profiledata/service_test.go index b73af6ce99..6841936a08 100644 --- a/pkg/server/profiledata/service_test.go +++ b/pkg/server/profiledata/service_test.go @@ -7,7 +7,7 @@ import ( "testing" t_profiledata "github.com/daytonaio/daytona/internal/testing/server/profiledata" - . "github.com/daytonaio/daytona/pkg/profiledata" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/stretchr/testify/suite" ) @@ -15,7 +15,7 @@ import ( type ProfileDataServiceTestSuite struct { suite.Suite profileDataService profiledata.IProfileDataService - profileDataStore Store + profileDataStore profiledata.ProfileDataStore } func NewApiKeyServiceTestSuite() *ProfileDataServiceTestSuite { @@ -34,13 +34,13 @@ func TestApiKeyService(t *testing.T) { } func (s *ProfileDataServiceTestSuite) TestReturnsProfileDataNotFound() { - profileData, err := s.profileDataService.Get() + profileData, err := s.profileDataService.Get("") s.Require().Nil(profileData) - s.Require().True(IsProfileDataNotFound(err)) + s.Require().True(profiledata.IsProfileDataNotFound(err)) } func (s *ProfileDataServiceTestSuite) TestSaveProfileData() { - profileData := &ProfileData{ + profileData := &models.ProfileData{ EnvVars: map[string]string{ "key1": "value1", }, @@ -49,14 +49,14 @@ func (s *ProfileDataServiceTestSuite) TestSaveProfileData() { err := s.profileDataService.Save(profileData) s.Require().Nil(err) - profileDataFromStore, err := s.profileDataStore.Get() + profileDataFromStore, err := s.profileDataStore.Get("") s.Require().Nil(err) s.Require().NotNil(profileDataFromStore) s.Require().Equal(profileData, profileDataFromStore) } func (s *ProfileDataServiceTestSuite) TestDeleteProfileData() { - profileData := &ProfileData{ + profileData := &models.ProfileData{ EnvVars: map[string]string{ "key1": "value1", }, @@ -65,10 +65,10 @@ func (s *ProfileDataServiceTestSuite) TestDeleteProfileData() { err := s.profileDataService.Save(profileData) s.Require().Nil(err) - err = s.profileDataService.Delete() + err = s.profileDataService.Delete("") s.Require().Nil(err) - profileDataFromStore, err := s.profileDataStore.Get() + profileDataFromStore, err := s.profileDataStore.Get("") s.Require().Nil(profileDataFromStore) - s.Require().True(IsProfileDataNotFound(err)) + s.Require().True(profiledata.IsProfileDataNotFound(err)) } diff --git a/pkg/profiledata/store.go b/pkg/server/profiledata/store.go similarity index 52% rename from pkg/profiledata/store.go rename to pkg/server/profiledata/store.go index 985c9d1997..794f006f60 100644 --- a/pkg/profiledata/store.go +++ b/pkg/server/profiledata/store.go @@ -3,14 +3,20 @@ package profiledata -import "errors" +import ( + "errors" -type Store interface { - Get() (*ProfileData, error) - Save(profileData *ProfileData) error - Delete() error + "github.com/daytonaio/daytona/pkg/models" +) + +type ProfileDataStore interface { + Get(id string) (*models.ProfileData, error) + Save(profileData *models.ProfileData) error + Delete(id string) error } +const ProfileDataId = "profile_data" + var ( ErrProfileDataNotFound = errors.New("profile data not found") ) diff --git a/pkg/server/registry/service.go b/pkg/server/registry/service.go index 9d6e819e72..b797c3efa0 100644 --- a/pkg/server/registry/service.go +++ b/pkg/server/registry/service.go @@ -12,9 +12,9 @@ import ( "os" "time" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/frpc" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" @@ -29,7 +29,7 @@ type LocalContainerRegistryConfig struct { DataPath string Port uint32 Image string - ContainerRegistry *containerregistry.ContainerRegistry + ContainerRegistry *models.ContainerRegistry Logger io.Writer Frps *server.FRPSConfig ServerId string @@ -51,7 +51,7 @@ type LocalContainerRegistry struct { dataPath string port uint32 image string - containerRegistry *containerregistry.ContainerRegistry + containerRegistry *models.ContainerRegistry logger io.Writer frps *server.FRPSConfig serverId string diff --git a/pkg/server/server.go b/pkg/server/server.go index a139065af3..7b70285d89 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -15,7 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/hashicorp/go-plugin" @@ -30,7 +30,7 @@ type ServerInstanceConfig struct { TargetConfigService targetconfigs.ITargetConfigService ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService - WorkspaceConfigService workspaceconfig.IWorkspaceConfigService + WorkspaceConfigService workspaceconfigs.IWorkspaceConfigService WorkspaceService workspaces.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry TargetService targets.ITargetService @@ -83,7 +83,7 @@ type Server struct { TargetConfigService targetconfigs.ITargetConfigService ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService - WorkspaceConfigService workspaceconfig.IWorkspaceConfigService + WorkspaceConfigService workspaceconfigs.IWorkspaceConfigService WorkspaceService workspaces.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry TargetService targets.ITargetService diff --git a/pkg/server/targetconfigs/dto/target_config.go b/pkg/server/targetconfigs/dto/target_config.go index 45ad810873..7c1918fbf2 100644 --- a/pkg/server/targetconfigs/dto/target_config.go +++ b/pkg/server/targetconfigs/dto/target_config.go @@ -3,10 +3,10 @@ package dto -import "github.com/daytonaio/daytona/pkg/target" +import "github.com/daytonaio/daytona/pkg/models" type CreateTargetConfigDTO struct { Name string `json:"name" validate:"required"` - ProviderInfo target.ProviderInfo `json:"providerInfo" validate:"required"` + ProviderInfo models.ProviderInfo `json:"providerInfo" validate:"required"` Options string `json:"options" validate:"required"` } // @name CreateTargetConfigDTO diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index fb3cd148c9..0c860934c6 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -4,23 +4,23 @@ package targetconfigs import ( - "github.com/daytonaio/daytona/pkg/target/config" + "github.com/daytonaio/daytona/pkg/models" ) type ITargetConfigService interface { - Delete(targetConfig *config.TargetConfig) error - Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) - List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) - Map() (map[string]*config.TargetConfig, error) - Save(targetConfig *config.TargetConfig) error + Delete(targetConfig *models.TargetConfig) error + Find(filter *TargetConfigFilter) (*models.TargetConfig, error) + List(filter *TargetConfigFilter) ([]*models.TargetConfig, error) + Map() (map[string]*models.TargetConfig, error) + Save(targetConfig *models.TargetConfig) error } type TargetConfigServiceConfig struct { - TargetConfigStore config.TargetConfigStore + TargetConfigStore TargetConfigStore } type TargetConfigService struct { - targetConfigStore config.TargetConfigStore + targetConfigStore TargetConfigStore } func NewTargetConfigService(config TargetConfigServiceConfig) ITargetConfigService { @@ -29,17 +29,17 @@ func NewTargetConfigService(config TargetConfigServiceConfig) ITargetConfigServi } } -func (s *TargetConfigService) List(filter *config.TargetConfigFilter) ([]*config.TargetConfig, error) { +func (s *TargetConfigService) List(filter *TargetConfigFilter) ([]*models.TargetConfig, error) { return s.targetConfigStore.List(filter) } -func (s *TargetConfigService) Map() (map[string]*config.TargetConfig, error) { +func (s *TargetConfigService) Map() (map[string]*models.TargetConfig, error) { list, err := s.targetConfigStore.List(nil) if err != nil { return nil, err } - targetConfigs := make(map[string]*config.TargetConfig) + targetConfigs := make(map[string]*models.TargetConfig) for _, targetConfig := range list { targetConfigs[targetConfig.Name] = targetConfig } @@ -47,14 +47,14 @@ func (s *TargetConfigService) Map() (map[string]*config.TargetConfig, error) { return targetConfigs, nil } -func (s *TargetConfigService) Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) { +func (s *TargetConfigService) Find(filter *TargetConfigFilter) (*models.TargetConfig, error) { return s.targetConfigStore.Find(filter) } -func (s *TargetConfigService) Save(targetConfig *config.TargetConfig) error { +func (s *TargetConfigService) Save(targetConfig *models.TargetConfig) error { return s.targetConfigStore.Save(targetConfig) } -func (s *TargetConfigService) Delete(targetConfig *config.TargetConfig) error { +func (s *TargetConfigService) Delete(targetConfig *models.TargetConfig) error { return s.targetConfigStore.Delete(targetConfig) } diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go index 19e337be90..efc5d9e4ae 100644 --- a/pkg/server/targetconfigs/service_test.go +++ b/pkg/server/targetconfigs/service_test.go @@ -6,56 +6,55 @@ package targetconfigs_test import ( "testing" - t_targetconfigs "github.com/daytonaio/daytona/internal/testing/provider/targetconfigs" + t_targetconfigs "github.com/daytonaio/daytona/internal/testing/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" "github.com/stretchr/testify/suite" ) -var targetConfig1 *config.TargetConfig = &config.TargetConfig{ +var targetConfig1 *models.TargetConfig = &models.TargetConfig{ Name: "targetConfig1", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "provider1", Version: "v1", }, Options: "", } -var targetConfig2 *config.TargetConfig = &config.TargetConfig{ +var targetConfig2 *models.TargetConfig = &models.TargetConfig{ Name: "targetConfig2", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "provider2", Version: "v1", }, Options: "", } -var targetConfig3 *config.TargetConfig = &config.TargetConfig{ +var targetConfig3 *models.TargetConfig = &models.TargetConfig{ Name: "targetConfig3", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "provider3", Version: "v1", }, Options: "", } -var targetConfig4 *config.TargetConfig = &config.TargetConfig{ +var targetConfig4 *models.TargetConfig = &models.TargetConfig{ Name: "newTargetConfig", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "provider2", Version: "v1", }, Options: "", } -var expectedConfigs []*config.TargetConfig -var expectedConfigMap map[string]*config.TargetConfig +var expectedConfigs []*models.TargetConfig +var expectedConfigMap map[string]*models.TargetConfig type TargetConfigServiceTestSuite struct { suite.Suite targetConfigService targetconfigs.ITargetConfigService - targetConfigStore config.TargetConfigStore + targetConfigStore targetconfigs.TargetConfigStore } func NewTargetConfigServiceTestSuite() *TargetConfigServiceTestSuite { @@ -63,11 +62,11 @@ func NewTargetConfigServiceTestSuite() *TargetConfigServiceTestSuite { } func (s *TargetConfigServiceTestSuite) SetupTest() { - expectedConfigs = []*config.TargetConfig{ + expectedConfigs = []*models.TargetConfig{ targetConfig1, targetConfig2, targetConfig3, } - expectedConfigMap = map[string]*config.TargetConfig{ + expectedConfigMap = map[string]*models.TargetConfig{ targetConfig1.Name: targetConfig1, targetConfig2.Name: targetConfig2, targetConfig3.Name: targetConfig3, @@ -106,7 +105,7 @@ func (s *TargetConfigServiceTestSuite) TestMap() { func (s *TargetConfigServiceTestSuite) TestFind() { require := s.Require() - targetConfig, err := s.targetConfigService.Find(&config.TargetConfigFilter{ + targetConfig, err := s.targetConfigService.Find(&targetconfigs.TargetConfigFilter{ Name: &targetConfig1.Name, }) require.Nil(err) diff --git a/pkg/target/config/store.go b/pkg/server/targetconfigs/store.go similarity index 52% rename from pkg/target/config/store.go rename to pkg/server/targetconfigs/store.go index c35e462a26..55c47f999e 100644 --- a/pkg/target/config/store.go +++ b/pkg/server/targetconfigs/store.go @@ -1,19 +1,23 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package config +package targetconfigs -import "errors" +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) type TargetConfigFilter struct { Name *string } type TargetConfigStore interface { - List(filter *TargetConfigFilter) ([]*TargetConfig, error) - Find(filter *TargetConfigFilter) (*TargetConfig, error) - Save(targetConfig *TargetConfig) error - Delete(targetConfig *TargetConfig) error + List(filter *TargetConfigFilter) ([]*models.TargetConfig, error) + Find(filter *TargetConfigFilter) (*models.TargetConfig, error) + Save(targetConfig *models.TargetConfig) error + Delete(targetConfig *models.TargetConfig) error } var ( diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index d8e7abb7e9..60a91e29cf 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -8,11 +8,10 @@ import ( "fmt" "regexp" - "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" @@ -36,13 +35,13 @@ func isValidTargetName(name string) bool { return true } -func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*target.Target, error) { - _, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &req.Id}) +func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) { + _, err := s.targetStore.Find(&TargetFilter{IdOrName: &req.Id}) if err == nil { return nil, ErrTargetAlreadyExists } - tc, err := s.targetConfigStore.Find(&config.TargetConfigFilter{Name: &req.TargetConfigName}) + tc, err := s.targetConfigStore.Find(&targetconfigs.TargetConfigFilter{Name: &req.TargetConfigName}) if err != nil { return s.handleCreateError(ctx, nil, err) } @@ -52,14 +51,14 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT return nil, ErrInvalidTargetName } - tg := &target.Target{ + tg := &models.Target{ Id: req.Id, Name: req.Name, ProviderInfo: tc.ProviderInfo, Options: tc.Options, } - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeTarget, tg.Id) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeTarget, tg.Id) if err != nil { return s.handleCreateError(ctx, nil, err) } @@ -75,7 +74,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", tg.Name, tg.Id))) - tg.EnvVars = target.GetTargetEnvVars(tg, target.TargetEnvVarParams{ + tg.EnvVars = GetTargetEnvVars(tg, TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, @@ -109,7 +108,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT return s.handleCreateError(ctx, tg, err) } -func (s *TargetService) handleCreateError(ctx context.Context, target *target.Target, err error) (*target.Target, error) { +func (s *TargetService) handleCreateError(ctx context.Context, target *models.Target, err error) (*models.Target, error) { if !telemetry.TelemetryEnabled(ctx) { return target, err } diff --git a/pkg/server/targets/dto/target.go b/pkg/server/targets/dto/target.go index 1d455f8233..f57c93d22b 100644 --- a/pkg/server/targets/dto/target.go +++ b/pkg/server/targets/dto/target.go @@ -4,12 +4,12 @@ package dto import ( - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" ) type TargetDTO struct { - target.TargetViewDTO - Info *target.TargetInfo `json:"info" validate:"optional"` + models.Target + Info *models.TargetInfo `json:"info" validate:"optional"` } // @name TargetDTO type CreateTargetDTO struct { diff --git a/pkg/server/targets/env_vars.go b/pkg/server/targets/env_vars.go new file mode 100644 index 0000000000..4464506f2f --- /dev/null +++ b/pkg/server/targets/env_vars.go @@ -0,0 +1,32 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import "github.com/daytonaio/daytona/pkg/models" + +type TargetEnvVarParams struct { + ApiUrl string + ServerUrl string + ServerVersion string + ClientId string +} + +func GetTargetEnvVars(target *models.Target, params TargetEnvVarParams, telemetryEnabled bool) map[string]string { + envVars := map[string]string{ + "DAYTONA_TARGET_ID": target.Id, + "DAYTONA_SERVER_API_KEY": target.ApiKey, + "DAYTONA_SERVER_VERSION": params.ServerVersion, + "DAYTONA_SERVER_URL": params.ServerUrl, + "DAYTONA_SERVER_API_URL": params.ApiUrl, + "DAYTONA_CLIENT_ID": params.ClientId, + // (HOME) will be replaced at runtime + "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", + } + + if telemetryEnabled { + envVars["DAYTONA_TELEMETRY_ENABLED"] = "true" + } + + return envVars +} diff --git a/pkg/server/targets/error.go b/pkg/server/targets/error.go index a0e3b1544b..19ecbabe30 100644 --- a/pkg/server/targets/error.go +++ b/pkg/server/targets/error.go @@ -12,3 +12,7 @@ var ( ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") ErrTargetNotFound = errors.New("target not found") ) + +func IsTargetNotFound(err error) bool { + return err.Error() == ErrTargetNotFound.Error() +} diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 50862b94f2..cad61862b0 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -11,18 +11,17 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) -func (s *TargetService) GetTarget(ctx context.Context, filter *target.TargetFilter, verbose bool) (*dto.TargetDTO, error) { +func (s *TargetService) GetTarget(ctx context.Context, filter *TargetFilter, verbose bool) (*dto.TargetDTO, error) { tg, err := s.targetStore.Find(filter) if err != nil { return nil, ErrTargetNotFound } response := dto.TargetDTO{ - TargetViewDTO: *tg, + Target: *tg, } if !verbose { @@ -35,7 +34,7 @@ func (s *TargetService) GetTarget(ctx context.Context, filter *target.TargetFilt resultCh := make(chan provisioner.TargetInfoResult, 1) go func() { - targetInfo, err := s.provisioner.GetTargetInfo(ctx, &tg.Target) + targetInfo, err := s.provisioner.GetTargetInfo(ctx, tg) resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} }() diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index abbffab2b7..d20f2cac2e 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -12,11 +12,10 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) -func (s *TargetService) ListTargets(ctx context.Context, filter *target.TargetFilter, verbose bool) ([]dto.TargetDTO, error) { +func (s *TargetService) ListTargets(ctx context.Context, filter *TargetFilter, verbose bool) ([]dto.TargetDTO, error) { targets, err := s.targetStore.List(filter) if err != nil { return nil, err @@ -26,7 +25,7 @@ func (s *TargetService) ListTargets(ctx context.Context, filter *target.TargetFi response := []dto.TargetDTO{} for i, t := range targets { - response = append(response, dto.TargetDTO{TargetViewDTO: *t}) + response = append(response, dto.TargetDTO{Target: *t}) if !verbose { continue } @@ -41,7 +40,7 @@ func (s *TargetService) ListTargets(ctx context.Context, filter *target.TargetFi resultCh := make(chan provisioner.TargetInfoResult, 1) go func() { - targetInfo, err := s.provisioner.GetTargetInfo(ctx, &t.Target) + targetInfo, err := s.provisioner.GetTargetInfo(ctx, t) resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} }() diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 6bf0f78304..48338e03b2 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -7,22 +7,22 @@ import ( "context" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleRemoveError(ctx, &target.Target, ErrTargetNotFound) + return s.handleRemoveError(ctx, target, ErrTargetNotFound) } log.Infof("Destroying target %s", target.Id) - err = s.provisioner.DestroyTarget(&target.Target) + err = s.provisioner.DestroyTarget(target) if err != nil { - return s.handleRemoveError(ctx, &target.Target, err) + return s.handleRemoveError(ctx, target, err) } // Should not fail the whole operation if the API key cannot be revoked @@ -38,21 +38,21 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error log.Error(err) } - err = s.targetStore.Delete(&target.Target) + err = s.targetStore.Delete(target) - return s.handleRemoveError(ctx, &target.Target, err) + return s.handleRemoveError(ctx, target, err) } // ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, nil, ErrTargetNotFound) } log.Infof("Destroying target %s", target.Id) - err = s.provisioner.DestroyTarget(&target.Target) + err = s.provisioner.DestroyTarget(target) if err != nil { log.Error(err) } @@ -62,12 +62,12 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) log.Error(err) } - err = s.targetStore.Delete(&target.Target) + err = s.targetStore.Delete(target) - return s.handleRemoveError(ctx, &target.Target, err) + return s.handleRemoveError(ctx, target, err) } -func (s *TargetService) handleRemoveError(ctx context.Context, target *target.Target, err error) error { +func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Target, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index ecee6f48db..73202997bb 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -8,19 +8,19 @@ import ( "io" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/apikeys" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" "github.com/daytonaio/daytona/pkg/telemetry" ) type ITargetService interface { - CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*target.Target, error) - GetTarget(ctx context.Context, filter *target.TargetFilter, verbose bool) (*dto.TargetDTO, error) + CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) + GetTarget(ctx context.Context, filter *TargetFilter, verbose bool) (*dto.TargetDTO, error) GetTargetLogReader(targetId string) (io.Reader, error) - ListTargets(ctx context.Context, filter *target.TargetFilter, verbose bool) ([]dto.TargetDTO, error) + ListTargets(ctx context.Context, filter *TargetFilter, verbose bool) ([]dto.TargetDTO, error) StartTarget(ctx context.Context, targetId string) error StopTarget(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error @@ -29,11 +29,11 @@ type ITargetService interface { } type targetConfigStore interface { - Find(filter *config.TargetConfigFilter) (*config.TargetConfig, error) + Find(filter *targetconfigs.TargetConfigFilter) (*models.TargetConfig, error) } type TargetServiceConfig struct { - TargetStore target.Store + TargetStore TargetStore TargetConfigStore targetConfigStore ServerApiUrl string ServerUrl string @@ -59,7 +59,7 @@ func NewTargetService(config TargetServiceConfig) ITargetService { } type TargetService struct { - targetStore target.Store + targetStore TargetStore targetConfigStore targetConfigStore provisioner provisioner.IProvisioner apiKeyService apikeys.IApiKeyService diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index b4bb51219e..1294b2d2a0 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -11,12 +11,10 @@ import ( t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/apikey" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/target/config" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -25,11 +23,11 @@ import ( const serverApiUrl = "http://localhost:3986" const serverUrl = "http://localhost:3987" -var tg = &target.Target{ +var tg = &models.Target{ Id: "test", Name: "test", ApiKey: "test", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, @@ -42,22 +40,22 @@ var createTargetDTO = dto.CreateTargetDTO{ TargetConfigName: "test", } -var tc = config.TargetConfig{ +var tc = models.TargetConfig{ Name: "test", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, Options: "test-options", } -var targetInfo = target.TargetInfo{ +var targetInfo = models.TargetInfo{ Name: createTargetDTO.Name, ProviderMetadata: "provider-metadata-test", } func TestTargetService(t *testing.T) { - tg.EnvVars = target.GetTargetEnvVars(tg, target.TargetEnvVarParams{ + tg.EnvVars = targets.GetTargetEnvVars(tg, targets.TargetEnvVarParams{ ApiUrl: serverApiUrl, ServerUrl: serverUrl, ClientId: "test-client-id", @@ -92,7 +90,7 @@ func TestTargetService(t *testing.T) { mockProvisioner.On("CreateTarget", tg).Return(nil) mockProvisioner.On("StartTarget", tg).Return(nil) - apiKeyService.On("Generate", apikey.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) + apiKeyService.On("Generate", models.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) target, err := service.CreateTarget(ctx, createTargetDTO) @@ -117,7 +115,7 @@ func TestTargetService(t *testing.T) { t.Run("GetTarget", func(t *testing.T) { mockProvisioner.On("GetTargetInfo", mock.Anything, tg).Return(&targetInfo, nil) - target, err := service.GetTarget(ctx, &target.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + target, err := service.GetTarget(ctx, &targets.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Nil(t, err) require.NotNil(t, target) @@ -126,7 +124,7 @@ func TestTargetService(t *testing.T) { }) t.Run("GetTarget fails when target not found", func(t *testing.T) { - _, err := service.GetTarget(ctx, &target.TargetFilter{IdOrName: util.Pointer("invalid-id")}, true) + _, err := service.GetTarget(ctx, &targets.TargetFilter{IdOrName: util.Pointer("invalid-id")}, true) require.NotNil(t, err) require.Equal(t, targets.ErrTargetNotFound, err) }) @@ -157,7 +155,7 @@ func TestTargetService(t *testing.T) { }) t.Run("StartTarget", func(t *testing.T) { - tg.EnvVars = target.GetTargetEnvVars(tg, target.TargetEnvVarParams{ + tg.EnvVars = targets.GetTargetEnvVars(tg, targets.TargetEnvVarParams{ ApiUrl: serverApiUrl, ServerUrl: serverUrl, ClientId: "test-client-id", @@ -186,7 +184,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetTarget(ctx, &target.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + _, err = service.GetTarget(ctx, &targets.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Equal(t, targets.ErrTargetNotFound, err) }) @@ -201,7 +199,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetTarget(ctx, &target.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + _, err = service.GetTarget(ctx, &targets.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Equal(t, targets.ErrTargetNotFound, err) }) @@ -220,7 +218,7 @@ func TestTargetService(t *testing.T) { }) } -func targetEquals(t *testing.T, t1, t2 *target.Target) { +func targetEquals(t *testing.T, t1, t2 *models.Target) { t.Helper() require.Equal(t, t1.Id, t2.Id) @@ -230,7 +228,7 @@ func targetEquals(t *testing.T, t1, t2 *target.Target) { require.Equal(t, t1.IsDefault, t2.IsDefault) } -func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo target.TargetInfo, verbose bool) { +func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo models.TargetInfo, verbose bool) { t.Helper() require.Equal(t, req.Id, target.Id) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index eadc9561b9..bc710b2b63 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -7,22 +7,22 @@ import ( "context" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets/dto" - "github.com/daytonaio/daytona/pkg/target" ) func (s *TargetService) SetDefault(ctx context.Context, id string) error { - currentTarget, err := s.GetTarget(ctx, &target.TargetFilter{ + currentTarget, err := s.GetTarget(ctx, &TargetFilter{ IdOrName: &id, }, false) if err != nil || currentTarget == nil { return err } - defaultTarget, err := s.GetTarget(ctx, &target.TargetFilter{ + defaultTarget, err := s.GetTarget(ctx, &TargetFilter{ Default: util.Pointer(true), }, false) - if err != nil && !target.IsTargetNotFound(err) { + if err != nil && !IsTargetNotFound(err) { return err } @@ -38,8 +38,8 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { return s.targetStore.Save(TargetDtoToTarget(*currentTarget)) } -func TargetDtoToTarget(targetDto dto.TargetDTO) *target.Target { - return &target.Target{ +func TargetDtoToTarget(targetDto dto.TargetDTO) *models.Target { + return &models.Target{ Id: targetDto.Id, Name: targetDto.Name, ProviderInfo: targetDto.ProviderInfo, diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index 445a76a377..ce22c2b93f 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -9,7 +9,7 @@ import ( "io" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" @@ -18,7 +18,7 @@ import ( ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) + t, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStartError(ctx, nil, ErrTargetNotFound) } @@ -28,22 +28,22 @@ func (s *TargetService) StartTarget(ctx context.Context, targetId string) error logger := io.MultiWriter(&util.InfoLogWriter{}, targetLogger) - t.EnvVars = target.GetTargetEnvVars(&t.Target, target.TargetEnvVarParams{ + t.EnvVars = GetTargetEnvVars(t, TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err = s.startTarget(&t.Target, logger) + err = s.startTarget(t, logger) if err != nil { - return s.handleStartError(ctx, &t.Target, err) + return s.handleStartError(ctx, t, err) } - return s.handleStartError(ctx, &t.Target, err) + return s.handleStartError(ctx, t, err) } -func (s *TargetService) startTarget(target *target.Target, targetLogger io.Writer) error { +func (s *TargetService) startTarget(target *models.Target, targetLogger io.Writer) error { targetLogger.Write([]byte("Starting target\n")) err := s.provisioner.StartTarget(target) @@ -56,7 +56,7 @@ func (s *TargetService) startTarget(target *target.Target, targetLogger io.Write return err } -func (s *TargetService) handleStartError(ctx context.Context, target *target.Target, err error) error { +func (s *TargetService) handleStartError(ctx context.Context, target *models.Target, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index e838122b87..c30e89f4b3 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -6,23 +6,23 @@ package targets import ( "context" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStopError(ctx, nil, ErrTargetNotFound) } - err = s.provisioner.StopTarget(&target.Target) + err = s.provisioner.StopTarget(target) - return s.handleStopError(ctx, &target.Target, err) + return s.handleStopError(ctx, target, err) } -func (s *TargetService) handleStopError(ctx context.Context, target *target.Target, err error) error { +func (s *TargetService) handleStopError(ctx context.Context, target *models.Target, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/targets/store.go b/pkg/server/targets/store.go new file mode 100644 index 0000000000..27e7e7ee85 --- /dev/null +++ b/pkg/server/targets/store.go @@ -0,0 +1,20 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "github.com/daytonaio/daytona/pkg/models" +) + +type TargetFilter struct { + IdOrName *string + Default *bool +} + +type TargetStore interface { + List(filter *TargetFilter) ([]*models.Target, error) + Find(filter *TargetFilter) (*models.Target, error) + Save(target *models.Target) error + Delete(target *models.Target) error +} diff --git a/pkg/server/workspaceconfig/dto/workspaceconfig.go b/pkg/server/workspaceconfigs/dto/workspaceconfig.go similarity index 59% rename from pkg/server/workspaceconfig/dto/workspaceconfig.go rename to pkg/server/workspaceconfigs/dto/workspaceconfig.go index b63c97c266..2762223438 100644 --- a/pkg/server/workspaceconfig/dto/workspaceconfig.go +++ b/pkg/server/workspaceconfigs/dto/workspaceconfig.go @@ -3,18 +3,16 @@ package dto -import ( - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" -) +import "github.com/daytonaio/daytona/pkg/models" type CreateWorkspaceConfigDTO struct { - Name string `json:"name" validate:"required"` - Image *string `json:"image,omitempty" validate:"optional"` - User *string `json:"user,omitempty" validate:"optional"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` - RepositoryUrl string `json:"repositoryUrl" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` + Name string `json:"name" validate:"required"` + Image *string `json:"image,omitempty" validate:"optional"` + User *string `json:"user,omitempty" validate:"optional"` + BuildConfig *models.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` + RepositoryUrl string `json:"repositoryUrl" validate:"required"` + EnvVars map[string]string `json:"envVars" validate:"required"` + GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` } // @name CreateWorkspaceConfigDTO type PrebuildDTO struct { diff --git a/pkg/server/workspaceconfig/prebuild.go b/pkg/server/workspaceconfigs/prebuild.go similarity index 83% rename from pkg/server/workspaceconfig/prebuild.go rename to pkg/server/workspaceconfigs/prebuild.go index c4b54c9798..69bdb951b6 100644 --- a/pkg/server/workspaceconfig/prebuild.go +++ b/pkg/server/workspaceconfigs/prebuild.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspaceconfigs import ( "errors" @@ -11,22 +11,22 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" - "github.com/daytonaio/daytona/pkg/workspace/containerconfig" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" log "github.com/sirupsen/logrus" ) func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { - workspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := s.Find(&WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { return nil, err } - existingPrebuild, _ := workspaceConfig.FindPrebuild(&config.PrebuildFilter{ + existingPrebuild, _ := workspaceConfig.FindPrebuild(&models.MatchParams{ Branch: &createPrebuildDto.Branch, }) @@ -50,7 +50,7 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP return nil, err } - prebuild := &config.PrebuildConfig{ + prebuild := &models.PrebuildConfig{ Branch: createPrebuildDto.Branch, CommitInterval: createPrebuildDto.CommitInterval, TriggerFiles: createPrebuildDto.TriggerFiles, @@ -108,13 +108,19 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP }, nil } -func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) { +func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) (*dto.PrebuildDTO, error) { wc, err := s.configStore.Find(workspaceConfigFilter) if err != nil { - return nil, config.ErrWorkspaceConfigNotFound + return nil, ErrWorkspaceConfigNotFound } - prebuild, err := wc.FindPrebuild(prebuildFilter) + prebuild, err := wc.FindPrebuild(&models.MatchParams{ + Id: prebuildFilter.Id, + Branch: prebuildFilter.Branch, + CommitInterval: prebuildFilter.CommitInterval, + TriggerFiles: prebuildFilter.TriggerFiles, + WorkspaceConfigName: prebuildFilter.WorkspaceConfigName, + }) if err != nil { return nil, err } @@ -129,11 +135,11 @@ func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *config.Work }, nil } -func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) ([]*dto.PrebuildDTO, error) { var result []*dto.PrebuildDTO wcs, err := s.configStore.List(workspaceConfigFilter) if err != nil { - return nil, config.ErrWorkspaceConfigNotFound + return nil, ErrWorkspaceConfigNotFound } for _, wc := range wcs { @@ -153,7 +159,7 @@ func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *config.Wor } func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id string, force bool) []error { - workspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := s.Find(&WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { @@ -162,7 +168,7 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s // Get all prebuilds for this workspace config's repository URL and // if this is the last prebuild, unregister the Git provider webhook - prebuilds, err := s.ListPrebuilds(&config.WorkspaceConfigFilter{ + prebuilds, err := s.ListPrebuilds(&WorkspaceConfigFilter{ Url: &workspaceConfig.RepositoryUrl, }, nil) if err != nil { @@ -203,7 +209,7 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s } } - errs := s.buildService.MarkForDeletion(&build.Filter{ + errs := s.buildService.MarkForDeletion(&builds.BuildFilter{ PrebuildIds: &[]string{id}, }, force) if len(errs) > 0 { @@ -230,9 +236,9 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s } func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { - var buildsToTrigger []build.Build + var buildsToTrigger []models.Build - workspaceConfigs, err := s.List(&config.WorkspaceConfigFilter{ + workspaceConfigs, err := s.List(&WorkspaceConfigFilter{ Url: &data.Url, }) if err != nil { @@ -251,7 +257,7 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) } for _, workspaceConfig := range workspaceConfigs { - prebuild, err := workspaceConfig.FindPrebuild(&config.PrebuildFilter{ + prebuild, err := workspaceConfig.FindPrebuild(&models.MatchParams{ Branch: &data.Branch, }) if err != nil || prebuild == nil { @@ -261,8 +267,8 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) // Check if the commit's affected files and prebuild config's trigger files have any overlap if len(prebuild.TriggerFiles) > 0 { if slicesHaveCommonEntry(prebuild.TriggerFiles, data.AffectedFiles) { - buildsToTrigger = append(buildsToTrigger, build.Build{ - ContainerConfig: containerconfig.ContainerConfig{ + buildsToTrigger = append(buildsToTrigger, models.Build{ + ContainerConfig: models.ContainerConfig{ Image: workspaceConfig.Image, User: workspaceConfig.User, }, @@ -275,13 +281,13 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) } } - newestBuild, err := s.buildService.Find(&build.Filter{ + newestBuild, err := s.buildService.Find(&builds.BuildFilter{ PrebuildIds: &[]string{prebuild.Id}, GetNewest: util.Pointer(true), }) if err != nil { - buildsToTrigger = append(buildsToTrigger, build.Build{ - ContainerConfig: containerconfig.ContainerConfig{ + buildsToTrigger = append(buildsToTrigger, models.Build{ + ContainerConfig: models.ContainerConfig{ Image: workspaceConfig.Image, User: workspaceConfig.User, }, @@ -300,8 +306,8 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) // Check if the commit interval has been reached if prebuild.CommitInterval != nil && commitsRange >= *prebuild.CommitInterval { - buildsToTrigger = append(buildsToTrigger, build.Build{ - ContainerConfig: containerconfig.ContainerConfig{ + buildsToTrigger = append(buildsToTrigger, models.Build{ + ContainerConfig: models.ContainerConfig{ Image: workspaceConfig.Image, User: workspaceConfig.User, }, @@ -339,17 +345,17 @@ func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { return err } - builds, err := s.buildService.List(&build.Filter{ - States: &[]build.BuildState{build.BuildStatePublished}, + existingBuilds, err := s.buildService.List(&builds.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePublished}, }) if err != nil { return err } - buildMap := make(map[string][]build.Build) + buildMap := make(map[string][]models.Build) // Group builds by their prebuildId - for _, b := range builds { + for _, b := range existingBuilds { buildMap[b.PrebuildId] = append(buildMap[b.PrebuildId], *b) } @@ -367,7 +373,7 @@ func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { // Mark the oldest builds for deletion for i := 0; i < numToDelete; i++ { - errs := s.buildService.MarkForDeletion(&build.Filter{ + errs := s.buildService.MarkForDeletion(&builds.BuildFilter{ Id: &associatedBuilds[i].Id, }, false) if len(errs) > 0 { diff --git a/pkg/server/workspaceconfig/prebuild_test.go b/pkg/server/workspaceconfigs/prebuild_test.go similarity index 77% rename from pkg/server/workspaceconfig/prebuild_test.go rename to pkg/server/workspaceconfigs/prebuild_test.go index a47401fba2..04e6c65370 100644 --- a/pkg/server/workspaceconfig/prebuild_test.go +++ b/pkg/server/workspaceconfigs/prebuild_test.go @@ -1,20 +1,21 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig_test +package workspaceconfigs_test import ( "time" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/builds" build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" ) -var prebuild1 *config.PrebuildConfig = &config.PrebuildConfig{ +var prebuild1 = &models.PrebuildConfig{ Id: "1", Branch: "feat", CommitInterval: util.Pointer(3), @@ -22,7 +23,7 @@ var prebuild1 *config.PrebuildConfig = &config.PrebuildConfig{ TriggerFiles: []string{"file1", "file2"}, } -var prebuild2 *config.PrebuildConfig = &config.PrebuildConfig{ +var prebuild2 = &models.PrebuildConfig{ Id: "2", Branch: "dev", CommitInterval: util.Pointer(1), @@ -30,7 +31,7 @@ var prebuild2 *config.PrebuildConfig = &config.PrebuildConfig{ TriggerFiles: []string{"file1", "file2"}, } -var prebuild3 *config.PrebuildConfig = &config.PrebuildConfig{ +var prebuild3 = &models.PrebuildConfig{ Id: "3", Branch: "new", CommitInterval: util.Pointer(1), @@ -38,7 +39,7 @@ var prebuild3 *config.PrebuildConfig = &config.PrebuildConfig{ TriggerFiles: []string{"file1", "file2"}, } -var prebuild1Dto *dto.PrebuildDTO = &dto.PrebuildDTO{ +var prebuild1Dto = &dto.PrebuildDTO{ WorkspaceConfigName: workspaceConfig1.Name, Id: prebuild1.Id, Branch: prebuild1.Branch, @@ -53,11 +54,11 @@ var repository1 *gitprovider.GitRepository = &gitprovider.GitRepository{ Sha: "sha1", } -var expectedPrebuilds []*config.PrebuildConfig -var expectedFilteredPrebuilds []*config.PrebuildConfig +var expectedPrebuilds []*models.PrebuildConfig +var expectedFilteredPrebuilds []*models.PrebuildConfig -var expectedPrebuildsMap map[string]*config.PrebuildConfig -var expectedFilteredPrebuildsMap map[string]*config.PrebuildConfig +var expectedPrebuildsMap map[string]*models.PrebuildConfig +var expectedFilteredPrebuildsMap map[string]*models.PrebuildConfig func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { require := s.Require() @@ -77,7 +78,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { }) require.Nil(err) - prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&config.WorkspaceConfigFilter{ + prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&workspaceconfigs.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }, nil) require.Nil(err) @@ -87,9 +88,9 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { func (s *WorkspaceConfigServiceTestSuite) TestFindPrebuild() { require := s.Require() - prebuild, err := s.workspaceConfigService.FindPrebuild(&config.WorkspaceConfigFilter{ + prebuild, err := s.workspaceConfigService.FindPrebuild(&workspaceconfigs.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, - }, &config.PrebuildFilter{ + }, &workspaceconfigs.PrebuildFilter{ Id: &prebuild1.Id, }) require.Nil(err) @@ -98,7 +99,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestFindPrebuild() { func (s *WorkspaceConfigServiceTestSuite) TestListPrebuilds() { require := s.Require() - prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&config.WorkspaceConfigFilter{ + prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&workspaceconfigs.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }, nil) require.Nil(err) @@ -111,14 +112,14 @@ func (s *WorkspaceConfigServiceTestSuite) TestDeletePrebuild() { require := s.Require() - s.buildService.On("MarkForDeletion", &build.Filter{ + s.buildService.On("MarkForDeletion", &builds.BuildFilter{ PrebuildIds: &[]string{prebuild2.Id}, }, false).Return([]error{}) err := s.workspaceConfigService.DeletePrebuild(workspaceConfig1.Name, prebuild2.Id, false) require.Nil(err) - prebuildDtos, errs := s.workspaceConfigService.ListPrebuilds(&config.WorkspaceConfigFilter{ + prebuildDtos, errs := s.workspaceConfigService.ListPrebuilds(&workspaceconfigs.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }, nil) require.Nil(errs) @@ -142,10 +143,10 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventCommitInterval() { Image: workspaceConfig1.Image, }).Return("", nil) - s.buildService.On("Find", &build.Filter{ + s.buildService.On("Find", &builds.BuildFilter{ PrebuildIds: &[]string{prebuild1.Id}, GetNewest: util.Pointer(true), - }).Return(&build.Build{ + }).Return(&models.Build{ Id: "1", PrebuildId: prebuild1.Id, Repository: repository1, @@ -197,36 +198,36 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { func (s *WorkspaceConfigServiceTestSuite) TestEnforceRetentionPolicy() { require := s.Require() - s.buildService.On("List", &build.Filter{ - States: &[]build.BuildState{build.BuildStatePublished}, - }).Return([]*build.Build{ + s.buildService.On("List", &builds.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePublished}, + }).Return([]*models.Build{ { Id: "1", PrebuildId: "1", - State: build.BuildStatePublished, + State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -4), }, { Id: "2", PrebuildId: "1", - State: build.BuildStatePublished, + State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -3), }, { Id: "3", PrebuildId: "1", - State: build.BuildStatePublished, + State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -2), }, { Id: "4", PrebuildId: "1", - State: build.BuildStatePublished, + State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -1), }, }, nil) - s.buildService.On("MarkForDeletion", &build.Filter{ + s.buildService.On("MarkForDeletion", &builds.BuildFilter{ Id: util.Pointer("1"), }, false).Return([]error{}) diff --git a/pkg/server/workspaceconfig/service.go b/pkg/server/workspaceconfigs/service.go similarity index 70% rename from pkg/server/workspaceconfig/service.go rename to pkg/server/workspaceconfigs/service.go index 1bd1d565c4..ad085537d4 100644 --- a/pkg/server/workspaceconfig/service.go +++ b/pkg/server/workspaceconfigs/service.go @@ -1,29 +1,29 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspaceconfigs import ( "strings" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig/dto" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" ) type IWorkspaceConfigService interface { - Save(workspaceConfig *config.WorkspaceConfig) error - Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) - List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) + Save(workspaceConfig *models.WorkspaceConfig) error + Find(filter *WorkspaceConfigFilter) (*models.WorkspaceConfig, error) + List(filter *WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) SetDefault(workspaceConfigName string) error Delete(workspaceConfigName string, force bool) []error SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) - FindPrebuild(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) (*dto.PrebuildDTO, error) - ListPrebuilds(workspaceConfigFilter *config.WorkspaceConfigFilter, prebuildFilter *config.PrebuildFilter) ([]*dto.PrebuildDTO, error) + FindPrebuild(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) (*dto.PrebuildDTO, error) + ListPrebuilds(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) ([]*dto.PrebuildDTO, error) DeletePrebuild(workspaceConfigName string, id string, force bool) []error StartRetentionPoller() error @@ -33,14 +33,14 @@ type IWorkspaceConfigService interface { type WorkspaceConfigServiceConfig struct { PrebuildWebhookEndpoint string - ConfigStore config.Store + ConfigStore WorkspaceConfigStore BuildService builds.IBuildService GitProviderService gitproviders.IGitProviderService } type WorkspaceConfigService struct { prebuildWebhookEndpoint string - configStore config.Store + configStore WorkspaceConfigStore buildService builds.IBuildService gitProviderService gitproviders.IGitProviderService } @@ -54,23 +54,23 @@ func NewWorkspaceConfigService(config WorkspaceConfigServiceConfig) IWorkspaceCo } } -func (s *WorkspaceConfigService) List(filter *config.WorkspaceConfigFilter) ([]*config.WorkspaceConfig, error) { +func (s *WorkspaceConfigService) List(filter *WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { return s.configStore.List(filter) } func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { - workspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := s.Find(&WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { return err } - defaultWorkspaceConfig, err := s.Find(&config.WorkspaceConfigFilter{ + defaultWorkspaceConfig, err := s.Find(&WorkspaceConfigFilter{ Url: &workspaceConfig.RepositoryUrl, Default: util.Pointer(true), }) - if err != nil && !config.IsWorkspaceConfigNotFound(err) { + if err != nil && !IsWorkspaceConfigNotFound(err) { return err } @@ -86,7 +86,7 @@ func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { return s.configStore.Save(workspaceConfig) } -func (s *WorkspaceConfigService) Find(filter *config.WorkspaceConfigFilter) (*config.WorkspaceConfig, error) { +func (s *WorkspaceConfigService) Find(filter *WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { if filter != nil && filter.Url != nil { cleanedUrl := util.CleanUpRepositoryUrl(*filter.Url) if !strings.HasSuffix(cleanedUrl, ".git") { @@ -97,7 +97,7 @@ func (s *WorkspaceConfigService) Find(filter *config.WorkspaceConfigFilter) (*co return s.configStore.Find(filter) } -func (s *WorkspaceConfigService) Save(workspaceConfig *config.WorkspaceConfig) error { +func (s *WorkspaceConfigService) Save(workspaceConfig *models.WorkspaceConfig) error { workspaceConfig.RepositoryUrl = util.CleanUpRepositoryUrl(workspaceConfig.RepositoryUrl) err := s.configStore.Save(workspaceConfig) @@ -109,7 +109,7 @@ func (s *WorkspaceConfigService) Save(workspaceConfig *config.WorkspaceConfig) e } func (s *WorkspaceConfigService) Delete(workspaceConfigName string, force bool) []error { - wc, err := s.Find(&config.WorkspaceConfigFilter{ + wc, err := s.Find(&WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { diff --git a/pkg/server/workspaceconfig/service_test.go b/pkg/server/workspaceconfigs/service_test.go similarity index 73% rename from pkg/server/workspaceconfig/service_test.go rename to pkg/server/workspaceconfigs/service_test.go index 43908653d8..eab0ffe933 100644 --- a/pkg/server/workspaceconfig/service_test.go +++ b/pkg/server/workspaceconfigs/service_test.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig_test +package workspaceconfigs_test import ( "testing" @@ -10,28 +10,28 @@ import ( "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" workspaceconfig_internal "github.com/daytonaio/daytona/internal/testing/server/workspaceconfig" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/server/workspaceconfig" - "github.com/daytonaio/daytona/pkg/workspace/config" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/stretchr/testify/suite" ) var workspaceConfig1Image = "image1" var workspaceConfig1User = "user1" -var workspaceConfig1 *config.WorkspaceConfig = &config.WorkspaceConfig{ +var workspaceConfig1 = &models.WorkspaceConfig{ Name: "wc1", Image: workspaceConfig1Image, User: workspaceConfig1User, BuildConfig: nil, RepositoryUrl: repository1.Url, IsDefault: true, - Prebuilds: []*config.PrebuildConfig{ + Prebuilds: []*models.PrebuildConfig{ prebuild1, prebuild2, }, } -var workspaceConfig2 *config.WorkspaceConfig = &config.WorkspaceConfig{ +var workspaceConfig2 = &models.WorkspaceConfig{ Name: "wc2", Image: "image2", User: "user2", @@ -39,7 +39,7 @@ var workspaceConfig2 *config.WorkspaceConfig = &config.WorkspaceConfig{ RepositoryUrl: "https://github.com/daytonaio/daytona.git", } -var workspaceConfig3 *config.WorkspaceConfig = &config.WorkspaceConfig{ +var workspaceConfig3 = &models.WorkspaceConfig{ Name: "wc3", Image: "image3", User: "user3", @@ -47,7 +47,7 @@ var workspaceConfig3 *config.WorkspaceConfig = &config.WorkspaceConfig{ RepositoryUrl: "https://github.com/daytonaio/daytona3.git", } -var workspaceConfig4 *config.WorkspaceConfig = &config.WorkspaceConfig{ +var workspaceConfig4 = &models.WorkspaceConfig{ Name: "wc4", Image: "image4", User: "user4", @@ -55,16 +55,16 @@ var workspaceConfig4 *config.WorkspaceConfig = &config.WorkspaceConfig{ RepositoryUrl: "https://github.com/daytonaio/daytona4.git", } -var expectedWorkspaceConfigs []*config.WorkspaceConfig -var expectedFilteredWorkspaceConfigs []*config.WorkspaceConfig +var expectedWorkspaceConfigs []*models.WorkspaceConfig +var expectedFilteredWorkspaceConfigs []*models.WorkspaceConfig -var expectedWorkspaceConfigsMap map[string]*config.WorkspaceConfig -var expectedFilteredWorkspaceConfigsMap map[string]*config.WorkspaceConfig +var expectedWorkspaceConfigsMap map[string]*models.WorkspaceConfig +var expectedFilteredWorkspaceConfigsMap map[string]*models.WorkspaceConfig type WorkspaceConfigServiceTestSuite struct { suite.Suite - workspaceConfigService workspaceconfig.IWorkspaceConfigService - workspaceConfigStore config.Store + workspaceConfigService workspaceconfigs.IWorkspaceConfigService + workspaceConfigStore workspaceconfigs.WorkspaceConfigStore gitProviderService mocks.MockGitProviderService buildService mocks.MockBuildService gitProvider git_provider_mock.MockGitProvider @@ -75,44 +75,44 @@ func NewConfigServiceTestSuite() *WorkspaceConfigServiceTestSuite { } func (s *WorkspaceConfigServiceTestSuite) SetupTest() { - expectedWorkspaceConfigs = []*config.WorkspaceConfig{ + expectedWorkspaceConfigs = []*models.WorkspaceConfig{ workspaceConfig1, workspaceConfig2, workspaceConfig3, } - expectedPrebuilds = []*config.PrebuildConfig{ + expectedPrebuilds = []*models.PrebuildConfig{ prebuild1, prebuild2, } - expectedWorkspaceConfigsMap = map[string]*config.WorkspaceConfig{ + expectedWorkspaceConfigsMap = map[string]*models.WorkspaceConfig{ workspaceConfig1.Name: workspaceConfig1, workspaceConfig2.Name: workspaceConfig2, workspaceConfig3.Name: workspaceConfig3, } - expectedPrebuildsMap = map[string]*config.PrebuildConfig{ + expectedPrebuildsMap = map[string]*models.PrebuildConfig{ prebuild1.Id: prebuild1, prebuild2.Id: prebuild2, } - expectedFilteredWorkspaceConfigs = []*config.WorkspaceConfig{ + expectedFilteredWorkspaceConfigs = []*models.WorkspaceConfig{ workspaceConfig1, workspaceConfig2, } - expectedFilteredPrebuilds = []*config.PrebuildConfig{ + expectedFilteredPrebuilds = []*models.PrebuildConfig{ prebuild1, } - expectedFilteredWorkspaceConfigsMap = map[string]*config.WorkspaceConfig{ + expectedFilteredWorkspaceConfigsMap = map[string]*models.WorkspaceConfig{ workspaceConfig1.Name: workspaceConfig1, workspaceConfig2.Name: workspaceConfig2, } - expectedFilteredPrebuildsMap = map[string]*config.PrebuildConfig{ + expectedFilteredPrebuildsMap = map[string]*models.PrebuildConfig{ prebuild1.Id: prebuild1, } s.workspaceConfigStore = workspaceconfig_internal.NewInMemoryWorkspaceConfigStore() - s.workspaceConfigService = workspaceconfig.NewWorkspaceConfigService(workspaceconfig.WorkspaceConfigServiceConfig{ + s.workspaceConfigService = workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ ConfigStore: s.workspaceConfigStore, GitProviderService: &s.gitProviderService, BuildService: &s.buildService, @@ -138,7 +138,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestList() { func (s *WorkspaceConfigServiceTestSuite) TestFind() { require := s.Require() - workspaceConfig, err := s.workspaceConfigService.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := s.workspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }) require.Nil(err) @@ -150,7 +150,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetDefault() { err := s.workspaceConfigService.SetDefault(workspaceConfig2.Name) require.Nil(err) - workspaceConfig, err := s.workspaceConfigService.Find(&config.WorkspaceConfigFilter{ + workspaceConfig, err := s.workspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ Url: util.Pointer(workspaceConfig1.RepositoryUrl), Default: util.Pointer(true), }) diff --git a/pkg/workspace/config/store.go b/pkg/server/workspaceconfigs/store.go similarity index 67% rename from pkg/workspace/config/store.go rename to pkg/server/workspaceconfigs/store.go index b54218101f..2c0bdc59af 100644 --- a/pkg/workspace/config/store.go +++ b/pkg/server/workspaceconfigs/store.go @@ -1,9 +1,13 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package config +package workspaceconfigs -import "errors" +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) type WorkspaceConfigFilter struct { Name *string @@ -21,11 +25,11 @@ type PrebuildFilter struct { TriggerFiles *[]string } -type Store interface { - List(filter *WorkspaceConfigFilter) ([]*WorkspaceConfig, error) - Find(filter *WorkspaceConfigFilter) (*WorkspaceConfig, error) - Save(workspaceConfig *WorkspaceConfig) error - Delete(workspaceConfig *WorkspaceConfig) error +type WorkspaceConfigStore interface { + List(filter *WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) + Find(filter *WorkspaceConfigFilter) (*models.WorkspaceConfig, error) + Save(workspaceConfig *models.WorkspaceConfig) error + Delete(workspaceConfig *models.WorkspaceConfig) error } var ( diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index e3b2c3d811..a898d448e7 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -11,18 +11,16 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" - "github.com/daytonaio/daytona/pkg/apikey" - "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" log "github.com/sirupsen/logrus" ) @@ -44,18 +42,19 @@ func isValidWorkspaceName(name string) bool { return true } -func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*workspace.WorkspaceViewDTO, error) { +func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*models.Workspace, error) { _, err := s.workspaceStore.Find(req.Name) if err == nil { return s.handleCreateError(ctx, nil, ErrWorkspaceAlreadyExists) } - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &req.TargetId}) + target, err := s.targetStore.Find(&targets.TargetFilter{IdOrName: &req.TargetId}) if err != nil { return s.handleCreateError(ctx, nil, err) } w := conversion.CreateDtoToWorkspace(req) + w.Target = *target if !isValidWorkspaceName(w.Name) { return s.handleCreateError(ctx, w, ErrInvalidWorkspaceName) @@ -100,7 +99,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo w.User = s.defaultWorkspaceUser } - apiKey, err := s.apiKeyService.Generate(apikey.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", w.Id)) + apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", w.Id)) if err != nil { return s.handleCreateError(ctx, w, err) } @@ -116,7 +115,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo defer workspaceLogger.Close() workspaceWithEnv := *w - workspaceWithEnv.EnvVars = workspace.GetWorkspaceEnvVars(w, workspace.WorkspaceEnvVarParams{ + workspaceWithEnv.EnvVars = GetWorkspaceEnvVars(w, WorkspaceEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, @@ -132,27 +131,26 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) cr, err := s.containerRegistryService.FindByImageName(w.Image) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { return s.handleCreateError(ctx, w, err) } builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { return s.handleCreateError(ctx, w, err) } - var gc *gitprovider.GitProviderConfig + var gc *models.GitProviderConfig if w.GitProviderConfigId != nil { gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) - if err != nil && !gitprovider.IsGitProviderNotFound(err) { + if err != nil && !gitproviders.IsGitProviderNotFound(err) { return s.handleCreateError(ctx, w, err) } } err = s.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ Workspace: w, - Target: &target.Target, ContainerRegistry: cr, GitProviderConfig: gc, BuilderImage: s.builderImage, @@ -164,17 +162,17 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s created", w.Name)))) - err = s.startWorkspace(w, &target.Target, workspaceLogger) + err = s.startWorkspace(w, workspaceLogger) return s.handleCreateError(ctx, w, err) } -func (s *WorkspaceService) handleCreateError(ctx context.Context, w *workspace.Workspace, err error) (*workspace.WorkspaceViewDTO, error) { +func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Workspace, err error) (*models.Workspace, error) { if !telemetry.TelemetryEnabled(ctx) { if w == nil { return nil, err } - return &workspace.WorkspaceViewDTO{Workspace: *w}, err + return w, err } clientId := telemetry.ClientId(ctx) @@ -194,15 +192,15 @@ func (s *WorkspaceService) handleCreateError(ctx context.Context, w *workspace.W return nil, err } - return &workspace.WorkspaceViewDTO{Workspace: *w}, err + return w, err } -func (s *WorkspaceService) getCachedBuildForWorkspace(w *workspace.Workspace) (*buildconfig.CachedBuild, error) { - validStates := &[]build.BuildState{ - build.BuildState(build.BuildStatePublished), +func (s *WorkspaceService) getCachedBuildForWorkspace(w *models.Workspace) (*models.CachedBuild, error) { + validStates := &[]models.BuildState{ + models.BuildStatePublished, } - build, err := s.buildService.Find(&build.Filter{ + build, err := s.buildService.Find(&builds.BuildFilter{ States: validStates, RepositoryUrl: &w.Repository.Url, Branch: &w.Repository.Branch, @@ -218,7 +216,7 @@ func (s *WorkspaceService) getCachedBuildForWorkspace(w *workspace.Workspace) (* return nil, errors.New("cached build is missing image or user") } - return &buildconfig.CachedBuild{ + return &models.CachedBuild{ User: *build.User, Image: *build.Image, }, nil diff --git a/pkg/server/workspaces/dto/workspace.go b/pkg/server/workspaces/dto/workspace.go index 826812c1fc..9bc6c44bb8 100644 --- a/pkg/server/workspaces/dto/workspace.go +++ b/pkg/server/workspaces/dto/workspace.go @@ -5,13 +5,12 @@ package dto import ( "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/workspace" - "github.com/daytonaio/daytona/pkg/workspace/buildconfig" + "github.com/daytonaio/daytona/pkg/models" ) type WorkspaceDTO struct { - workspace.WorkspaceViewDTO - Info *workspace.WorkspaceInfo `json:"info" validate:"optional"` + models.Workspace + Info *models.WorkspaceInfo `json:"info" validate:"optional"` } // @name WorkspaceDTO type CreateWorkspaceDTO struct { @@ -19,7 +18,7 @@ type CreateWorkspaceDTO struct { Name string `json:"name" validate:"required"` Image *string `json:"image,omitempty" validate:"optional"` User *string `json:"user,omitempty" validate:"optional"` - BuildConfig *buildconfig.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` + BuildConfig *models.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` Source CreateWorkspaceSourceDTO `json:"source" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` TargetId string `json:"targetId" validate:"required"` diff --git a/pkg/server/workspaces/env_vars.go b/pkg/server/workspaces/env_vars.go new file mode 100644 index 0000000000..e6b7afe96f --- /dev/null +++ b/pkg/server/workspaces/env_vars.go @@ -0,0 +1,34 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import "github.com/daytonaio/daytona/pkg/models" + +type WorkspaceEnvVarParams struct { + ApiUrl string + ServerUrl string + ServerVersion string + ClientId string +} + +func GetWorkspaceEnvVars(workspace *models.Workspace, params WorkspaceEnvVarParams, telemetryEnabled bool) map[string]string { + envVars := map[string]string{ + "DAYTONA_TARGET_ID": workspace.TargetId, + "DAYTONA_WORKSPACE_ID": workspace.Id, + "DAYTONA_WORKSPACE_REPOSITORY_URL": workspace.Repository.Url, + "DAYTONA_SERVER_API_KEY": workspace.ApiKey, + "DAYTONA_SERVER_VERSION": params.ServerVersion, + "DAYTONA_SERVER_URL": params.ServerUrl, + "DAYTONA_SERVER_API_URL": params.ApiUrl, + "DAYTONA_CLIENT_ID": params.ClientId, + // (HOME) will be replaced at runtime + "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", + } + + if telemetryEnabled { + envVars["DAYTONA_TELEMETRY_ENABLED"] = "true" + } + + return envVars +} diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index 5ec8921491..51921a72d1 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -11,7 +11,6 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) @@ -22,25 +21,20 @@ func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, } response := &dto.WorkspaceDTO{ - WorkspaceViewDTO: *ws, + Workspace: *ws, } if !verbose { return response, nil } - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) - if err != nil { - return nil, err - } - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() resultCh := make(chan provisioner.WorkspaceInfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, &target.Target) + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws) resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} }() diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index d00ffd9289..02f9819821 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -12,7 +12,6 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/target" log "github.com/sirupsen/logrus" ) @@ -26,7 +25,7 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] response := []dto.WorkspaceDTO{} for i, ws := range workspaces { - response = append(response, dto.WorkspaceDTO{WorkspaceViewDTO: *ws}) + response = append(response, dto.WorkspaceDTO{Workspace: *ws}) if !verbose { continue } @@ -35,19 +34,13 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] go func(i int) { defer wg.Done() - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) - if err != nil { - log.Error(fmt.Errorf("failed to get target for %s", ws.TargetId)) - return - } - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() resultCh := make(chan provisioner.WorkspaceInfoResult, 1) go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, &ws.Workspace, &target.Target) + workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws) resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} }() diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index 5965894b85..8e074a2373 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -8,28 +8,22 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, ErrWorkspaceNotFound) + return s.handleRemoveError(ctx, ws, ErrWorkspaceNotFound) } log.Infof("Destroying workspace %s", ws.Name) - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) + err = s.provisioner.DestroyWorkspace(ws) if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, err) - } - - err = s.provisioner.DestroyWorkspace(&ws.Workspace, &target.Target) - if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, err) + return s.handleRemoveError(ctx, ws, err) } err = s.apiKeyService.Revoke(fmt.Sprintf("ws-%s", ws.Id)) @@ -44,26 +38,21 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri log.Error(err) } - err = s.workspaceStore.Delete(&ws.Workspace) + err = s.workspaceStore.Delete(ws) - return s.handleRemoveError(ctx, &ws.Workspace, err) + return s.handleRemoveError(ctx, ws, err) } // ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, ErrWorkspaceNotFound) + return s.handleRemoveError(ctx, ws, ErrWorkspaceNotFound) } log.Infof("Destroying workspace %s", ws.Name) - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) - if err != nil { - return s.handleRemoveError(ctx, &ws.Workspace, err) - } - - err = s.provisioner.DestroyWorkspace(&ws.Workspace, &target.Target) + err = s.provisioner.DestroyWorkspace(ws) if err != nil { log.Error(err) } @@ -80,12 +69,12 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId log.Error(err) } - err = s.workspaceStore.Delete(&ws.Workspace) + err = s.workspaceStore.Delete(ws) - return s.handleRemoveError(ctx, &ws.Workspace, err) + return s.handleRemoveError(ctx, ws, err) } -func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *workspace.Workspace, err error) error { +func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Workspace, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index e1bcca0691..d9639927ee 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -8,19 +8,18 @@ import ( "io" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" ) type IWorkspaceService interface { - CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*workspace.WorkspaceViewDTO, error) + CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*models.Workspace, error) GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) StartWorkspace(ctx context.Context, workspaceId string) error @@ -29,15 +28,11 @@ type IWorkspaceService interface { ForceRemoveWorkspace(ctx context.Context, workspaceId string) error GetWorkspaceLogReader(workspaceId string) (io.Reader, error) - SetWorkspaceState(workspaceId string, state *workspace.WorkspaceState) (*workspace.WorkspaceViewDTO, error) -} - -type targetStore interface { - Find(filter *target.TargetFilter) (*target.TargetViewDTO, error) + SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) } type WorkspaceServiceConfig struct { - WorkspaceStore workspace.Store + WorkspaceStore WorkspaceStore TargetStore targetStore ContainerRegistryService containerregistries.IContainerRegistryService BuildService builds.IBuildService @@ -75,7 +70,7 @@ func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { } type WorkspaceService struct { - workspaceStore workspace.Store + workspaceStore WorkspaceStore targetStore targetStore containerRegistryService containerregistries.IContainerRegistryService buildService builds.IBuildService @@ -92,14 +87,14 @@ type WorkspaceService struct { telemetryService telemetry.TelemetryService } -func (s *WorkspaceService) SetWorkspaceState(workspaceId string, state *workspace.WorkspaceState) (*workspace.WorkspaceViewDTO, error) { +func (s *WorkspaceService) SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { return nil, ErrWorkspaceNotFound } ws.State = state - return ws, s.workspaceStore.Save(&ws.Workspace) + return ws, s.workspaceStore.Save(ws) } func (s *WorkspaceService) GetWorkspaceLogReader(workspaceId string) (io.Reader, error) { diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 5aa587f93c..72ffc98f20 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -13,16 +13,14 @@ import ( "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/apikey" - "github.com/daytonaio/daytona/pkg/containerregistry" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/server/workspaces/dto" - "github.com/daytonaio/daytona/pkg/target" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -37,7 +35,7 @@ var gitProviderConfigId = "github" var baseApiUrl = "https://api.github.com" -var gitProviderConfig = gitprovider.GitProviderConfig{ +var gitProviderConfig = models.GitProviderConfig{ Id: "github", ProviderId: gitProviderConfigId, Alias: "test-alias", @@ -46,10 +44,10 @@ var gitProviderConfig = gitprovider.GitProviderConfig{ BaseApiUrl: &baseApiUrl, } -var tg = &target.Target{ +var tg = &models.Target{ Id: "123", Name: "test", - ProviderInfo: target.ProviderInfo{ + ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, @@ -74,7 +72,7 @@ var createWorkspaceDTO = dto.CreateWorkspaceDTO{ TargetId: tg.Id, } -var workspaceInfo = workspace.WorkspaceInfo{ +var workspaceInfo = models.WorkspaceInfo{ Name: createWorkspaceDTO.Name, Created: "1 min ago", IsRunning: true, @@ -82,7 +80,7 @@ var workspaceInfo = workspace.WorkspaceInfo{ TargetId: "123", } -var ws = &workspace.Workspace{ +var ws = &models.Workspace{ Id: "123", Name: "workspace1", ApiKey: createWorkspaceDTO.Name, @@ -100,7 +98,7 @@ var ws = &workspace.Workspace{ } func TestTargetService(t *testing.T) { - ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ + ws.EnvVars = workspaces.GetWorkspaceEnvVars(ws, workspaces.WorkspaceEnvVarParams{ ApiUrl: serverApiUrl, ServerUrl: serverUrl, ClientId: "test-client-id", @@ -139,15 +137,15 @@ func TestTargetService(t *testing.T) { }) t.Run("CreateWorkspace", func(t *testing.T) { - var containerRegistry *containerregistry.ContainerRegistry + var containerRegistry *models.ContainerRegistry - containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, containerregistry.ErrContainerRegistryNotFound) + containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, containerregistries.ErrContainerRegistryNotFound) gitProviderService.On("GetLastCommitSha", createWorkspaceDTO.Source.Repository).Return("123", nil) - apiKeyService.On("Generate", apikey.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) + apiKeyService.On("Generate", models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) - ws := &workspace.Workspace{ + ws := &models.Workspace{ Name: createWorkspaceDTO.Name, Image: *createWorkspaceDTO.Image, User: *createWorkspaceDTO.User, @@ -158,7 +156,7 @@ func TestTargetService(t *testing.T) { TargetId: createWorkspaceDTO.Id, } - ws.EnvVars = workspace.GetWorkspaceEnvVars(ws, workspace.WorkspaceEnvVarParams{ + ws.EnvVars = workspaces.GetWorkspaceEnvVars(ws, workspaces.WorkspaceEnvVarParams{ ApiUrl: serverApiUrl, ServerUrl: serverUrl, ServerVersion: serverVersion, @@ -189,7 +187,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, workspace) - workspaceEquals(t, ws, &workspace.Workspace, defaultWorkspaceImage) + workspaceEquals(t, ws, workspace, defaultWorkspaceImage) ws.EnvVars = nil }) @@ -299,10 +297,10 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) updatedAt := time.Now().Format(time.RFC1123) - res, err := service.SetWorkspaceState(createWorkspaceDTO.Id, &workspace.WorkspaceState{ + res, err := service.SetWorkspaceState(createWorkspaceDTO.Id, &models.WorkspaceState{ UpdatedAt: updatedAt, Uptime: 10, - GitStatus: &workspace.GitStatus{ + GitStatus: &models.GitStatus{ CurrentBranch: "main", }, }) @@ -318,7 +316,7 @@ func TestTargetService(t *testing.T) { }) } -func workspaceEquals(t *testing.T, ws1, ws2 *workspace.Workspace, workspaceImage string) { +func workspaceEquals(t *testing.T, ws1, ws2 *models.Workspace, workspaceImage string) { t.Helper() require.Equal(t, ws1.Id, ws2.Id) @@ -332,7 +330,7 @@ func workspaceEquals(t *testing.T, ws1, ws2 *workspace.Workspace, workspaceImage require.Equal(t, ws1.Repository.Name, ws2.Repository.Name) } -func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto.WorkspaceDTO, workspaceInfo workspace.WorkspaceInfo, workspaceImage string, verbose bool) { +func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto.WorkspaceDTO, workspaceInfo models.WorkspaceInfo, workspaceImage string, verbose bool) { t.Helper() require.Equal(t, req.Id, workspace.Id) diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index 9a3100f9c8..f794dc9c7c 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -8,72 +8,65 @@ import ( "fmt" "io" - "github.com/daytonaio/daytona/pkg/containerregistry" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleStartError(ctx, &ws.Workspace, ErrWorkspaceNotFound) - } - - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) - if err != nil { - return s.handleStartError(ctx, &ws.Workspace, err) + return s.handleStartError(ctx, ws, ErrWorkspaceNotFound) } workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) defer workspaceLogger.Close() - workspaceToStart := ws.Workspace - workspaceToStart.EnvVars = workspace.GetWorkspaceEnvVars(&ws.Workspace, workspace.WorkspaceEnvVarParams{ + workspaceToStart := ws + workspaceToStart.EnvVars = GetWorkspaceEnvVars(ws, WorkspaceEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err = s.startWorkspace(&workspaceToStart, &target.Target, workspaceLogger) + err = s.startWorkspace(workspaceToStart, workspaceLogger) if err != nil { - return s.handleStartError(ctx, &ws.Workspace, err) + return s.handleStartError(ctx, ws, err) } - return s.handleStartError(ctx, &ws.Workspace, err) + return s.handleStartError(ctx, ws, err) } -func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, target *target.Target, logger io.Writer) error { +func (s *WorkspaceService) startWorkspace(w *models.Workspace, logger io.Writer) error { logger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) cr, err := s.containerRegistryService.FindByImageName(w.Image) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { return err } builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) - if err != nil && !containerregistry.IsContainerRegistryNotFound(err) { + if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { return err } - var gc *gitprovider.GitProviderConfig + var gc *models.GitProviderConfig if w.GitProviderConfigId != nil { gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) - if err != nil && !gitprovider.IsGitProviderNotFound(err) { + if err != nil && !gitproviders.IsGitProviderNotFound(err) { return err } } err = s.provisioner.StartWorkspace(provisioner.WorkspaceParams{ Workspace: w, - Target: target, ContainerRegistry: cr, GitProviderConfig: gc, BuilderImage: s.builderImage, @@ -88,7 +81,7 @@ func (s *WorkspaceService) startWorkspace(w *workspace.Workspace, target *target return nil } -func (s *WorkspaceService) handleStartError(ctx context.Context, w *workspace.Workspace, err error) error { +func (s *WorkspaceService) handleStartError(ctx context.Context, w *models.Workspace, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 2b0353fe18..5ccbc60b68 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -7,39 +7,33 @@ import ( "context" "time" - "github.com/daytonaio/daytona/pkg/target" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/workspace" log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleStopError(ctx, &ws.Workspace, ErrWorkspaceNotFound) - } - - target, err := s.targetStore.Find(&target.TargetFilter{IdOrName: &ws.TargetId}) - if err != nil { - return s.handleStopError(ctx, &ws.Workspace, err) + return s.handleStopError(ctx, ws, ErrWorkspaceNotFound) } // todo: go routines - err = s.provisioner.StopWorkspace(&ws.Workspace, &target.Target) + err = s.provisioner.StopWorkspace(ws) if err != nil { - return s.handleStopError(ctx, &ws.Workspace, err) + return s.handleStopError(ctx, ws, err) } if ws.State != nil { ws.State.Uptime = 0 ws.State.UpdatedAt = time.Now().Format(time.RFC1123) } - err = s.workspaceStore.Save(&ws.Workspace) + err = s.workspaceStore.Save(ws) - return s.handleStopError(ctx, &ws.Workspace, err) + return s.handleStopError(ctx, ws, err) } -func (s *WorkspaceService) handleStopError(ctx context.Context, w *workspace.Workspace, err error) error { +func (s *WorkspaceService) handleStopError(ctx context.Context, w *models.Workspace, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/workspaces/store.go b/pkg/server/workspaces/store.go new file mode 100644 index 0000000000..9c3a37cddc --- /dev/null +++ b/pkg/server/workspaces/store.go @@ -0,0 +1,20 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targets" +) + +type WorkspaceStore interface { + List() ([]*models.Workspace, error) + Find(idOrName string) (*models.Workspace, error) + Save(workspace *models.Workspace) error + Delete(workspace *models.Workspace) error +} + +type targetStore interface { + Find(filter *targets.TargetFilter) (*models.Target, error) +} diff --git a/pkg/target/store.go b/pkg/target/store.go deleted file mode 100644 index aa92f0cea6..0000000000 --- a/pkg/target/store.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -import "errors" - -type TargetFilter struct { - IdOrName *string - Default *bool -} - -type Store interface { - List(filter *TargetFilter) ([]*TargetViewDTO, error) - Find(filter *TargetFilter) (*TargetViewDTO, error) - Save(target *Target) error - Delete(target *Target) error -} - -type TargetViewDTO struct { - Target - WorkspaceCount int `json:"workspaceCount" validate:"required"` -} // @name TargetViewDTO - -var ( - ErrTargetNotFound = errors.New("target not found") -) - -func IsTargetNotFound(err error) bool { - return err.Error() == ErrTargetNotFound.Error() -} diff --git a/pkg/target/target.go b/pkg/target/target.go deleted file mode 100644 index aa67c49de6..0000000000 --- a/pkg/target/target.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package target - -type Target struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - ProviderInfo ProviderInfo `json:"providerInfo" validate:"required"` - // JSON encoded map of options - Options string `json:"options" validate:"required"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"-"` - IsDefault bool `json:"default" validate:"required"` -} // @name Target - -type TargetInfo struct { - Name string `json:"name" validate:"required"` - ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` -} // @name TargetInfo - -type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Version string `json:"version" validate:"required"` - Label *string `json:"label" validate:"optional"` -} // @name TargetProviderInfo - -type TargetEnvVarParams struct { - ApiUrl string - ServerUrl string - ServerVersion string - ClientId string -} - -func GetTargetEnvVars(target *Target, params TargetEnvVarParams, telemetryEnabled bool) map[string]string { - envVars := map[string]string{ - "DAYTONA_TARGET_ID": target.Id, - "DAYTONA_SERVER_API_KEY": target.ApiKey, - "DAYTONA_SERVER_VERSION": params.ServerVersion, - "DAYTONA_SERVER_URL": params.ServerUrl, - "DAYTONA_SERVER_API_URL": params.ApiUrl, - "DAYTONA_CLIENT_ID": params.ClientId, - // (HOME) will be replaced at runtime - "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", - } - - if telemetryEnabled { - envVars["DAYTONA_TELEMETRY_ENABLED"] = "true" - } - - return envVars -} diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index 6337c09348..b969e4390a 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -9,8 +9,7 @@ import ( "strings" "time" - "github.com/daytonaio/daytona/pkg/target" - "github.com/daytonaio/daytona/pkg/workspace" + "github.com/daytonaio/daytona/pkg/models" ) type ServerEvent string @@ -43,7 +42,7 @@ const ( ServerEventWorkspaceStopError ServerEvent = "server_workspace_stopped_error" ) -func NewTargetEventProps(ctx context.Context, target *target.Target) map[string]interface{} { +func NewTargetEventProps(ctx context.Context, target *models.Target) map[string]interface{} { props := map[string]interface{}{} sessionId := SessionId(ctx) @@ -62,13 +61,16 @@ func NewTargetEventProps(ctx context.Context, target *target.Target) map[string] return props } -func NewWorkspaceEventProps(ctx context.Context, workspace *workspace.Workspace) map[string]interface{} { +func NewWorkspaceEventProps(ctx context.Context, workspace *models.Workspace) map[string]interface{} { props := map[string]interface{}{} if workspace == nil { return props } + props["workspace_provider"] = workspace.Target.ProviderInfo.Name + props["workspace_provider_version"] = workspace.Target.ProviderInfo.Version + if isImagePublic(workspace.Image) { props["workspace_image"] = workspace.Image } diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index cd0960d2c5..c92666fa75 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -43,7 +43,7 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa Name: target.Name, Provider: provider, Default: target.Default, - WorkspaceCount: fmt.Sprintf("%d", target.WorkspaceCount), + WorkspaceCount: fmt.Sprintf("%d", len(target.Workspaces)), Options: target.Options, } diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go index b7c8217986..4bea836aff 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/workspace/info/view.go @@ -98,7 +98,7 @@ func getSingleWorkspaceOutput(workspace *apiclient.WorkspaceDTO, isCreationView output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) if !isCreationView { - output += getInfoLine("Target", fmt.Sprintf("%s (%s)", workspace.TargetName, workspace.TargetId)) + "\n" + output += getInfoLine("Target", fmt.Sprintf("%s (%s)", workspace.Target.Name, workspace.TargetId)) + "\n" } output += getInfoLine("Repository", repositoryUrl) diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index a986cf294f..9e7437cc52 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -135,7 +135,7 @@ func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) rowData.Branch = workspace.Repository.Branch - rowData.TargetName = workspace.TargetName + views_util.AdditionalPropertyPadding + rowData.TargetName = workspace.Target.Name + views_util.AdditionalPropertyPadding if workspace.Info != nil { rowData.Created = util.FormatTimestamp(workspace.Info.Created) diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go index 6664c114d3..4ce5ddb217 100644 --- a/pkg/views/workspace/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -49,7 +49,7 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect title: workspaceName, id: workspace.Id, desc: "", - targetName: workspace.TargetName, + targetName: workspace.Target.Name, repository: workspace.Repository.Url, createdTime: createdTime, uptime: uptime, diff --git a/pkg/workspace/store.go b/pkg/workspace/store.go deleted file mode 100644 index c436f15297..0000000000 --- a/pkg/workspace/store.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspace - -import "errors" - -type Store interface { - List() ([]*WorkspaceViewDTO, error) - Find(idOrName string) (*WorkspaceViewDTO, error) - Save(workspace *Workspace) error - Delete(workspace *Workspace) error -} - -type WorkspaceViewDTO struct { - Workspace - TargetName string `json:"targetName" validate:"required"` -} // @name WorkspaceViewDTO - -var ( - ErrWorkspaceNotFound = errors.New("workspace not found") -) - -func IsWorkspaceNotFound(err error) bool { - return err.Error() == ErrWorkspaceNotFound.Error() -} From ba8a5281fc9da174f34b87a0ba4a7238c0215c43 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Wed, 13 Nov 2024 16:16:28 +0000 Subject: [PATCH 09/76] refactor: service and store restructure Signed-off-by: Toma Puljak --- internal/cmd/tailscale/forward.go | 4 +- internal/testing/build/mocks/build_service.go | 4 +- internal/testing/build/store.go | 12 +- internal/testing/server/apikeys/store.go | 6 +- .../server/containerregistries/store.go | 8 +- internal/testing/server/profiledata/store.go | 6 +- .../testing/server/targetconfigs/store.go | 12 +- .../server/targets/mocks/build_service.go | 12 +- .../targets/mocks/workspace_config_service.go | 10 +- internal/testing/server/targets/store.go | 9 +- .../testing/server/workspaceconfig/store.go | 12 +- internal/testing/server/workspaces/store.go | 3 +- .../util/apiclient/conversion/workspace.go | 23 -- pkg/api/controllers/build/build.go | 56 +---- pkg/api/controllers/build/dto/dto.go | 11 - .../controllers/profiledata/profile_data.go | 6 +- pkg/api/controllers/target/target.go | 4 +- pkg/api/controllers/targetconfig/remove.go | 4 +- pkg/api/controllers/workspace/create.go | 4 +- .../workspaceconfig/prebuild/prebuild.go | 14 +- .../workspaceconfig/workspace_config.go | 12 +- pkg/build/builder.go | 4 +- pkg/build/builder_test.go | 4 +- pkg/build/factory.go | 8 +- pkg/build/runner.go | 10 +- pkg/build/runner_test.go | 4 +- pkg/cmd/agent/agent.go | 3 +- pkg/cmd/server/serve.go | 234 +++++++++++++++--- pkg/cmd/workspace/common/get_gpg_key.go | 13 +- pkg/cmd/workspace/create/cmd.go | 3 +- pkg/cmd/workspace/ssh-proxy.go | 4 +- pkg/common/workspace_hostname.go | 25 ++ pkg/db/api_key_store.go | 10 +- pkg/db/build_store.go | 14 +- pkg/db/container_registry_store.go | 8 +- pkg/db/gitprovider_config_store.go | 8 +- pkg/db/profile_data_store.go | 6 +- pkg/db/target_config_store.go | 14 +- pkg/db/target_store.go | 9 +- pkg/db/workspace_config_store.go | 12 +- pkg/models/build.go | 5 + pkg/models/build_config.go | 18 -- pkg/models/container_config.go | 9 - pkg/models/prebuild.go | 69 ------ pkg/models/workspace.go | 28 +-- pkg/models/workspace_config.go | 62 +++++ pkg/provider/manager/manager.go | 24 +- pkg/server/apikeys/service.go | 20 +- pkg/server/apikeys/service_test.go | 6 +- pkg/server/builds/dto/builds.go | 18 -- pkg/server/builds/service.go | 81 +++--- pkg/server/builds/service_test.go | 26 +- pkg/server/containerregistries/service.go | 17 +- pkg/server/gitproviders/remove.go | 16 +- pkg/server/gitproviders/service.go | 41 +-- .../util/workspace_config_store.go | 30 --- pkg/server/profiledata/service.go | 20 +- pkg/server/profiledata/service_test.go | 10 +- pkg/server/server.go | 46 ++-- pkg/server/targetconfigs/service.go | 20 +- pkg/server/targetconfigs/service_test.go | 8 +- pkg/server/targets/create.go | 8 +- pkg/server/targets/get.go | 3 +- pkg/server/targets/list.go | 3 +- pkg/server/targets/remove.go | 9 +- pkg/server/targets/service.go | 81 +++--- pkg/server/targets/service_test.go | 30 ++- pkg/server/targets/set-default.go | 5 +- pkg/server/targets/start.go | 3 +- pkg/server/targets/stop.go | 3 +- pkg/server/workspaceconfigs/prebuild.go | 144 ++++------- pkg/server/workspaceconfigs/prebuild_test.go | 43 ++-- pkg/server/workspaceconfigs/service.go | 80 +++--- pkg/server/workspaceconfigs/service_test.go | 78 +++++- pkg/server/workspaces/create.go | 65 ++--- pkg/server/workspaces/get.go | 6 +- pkg/server/workspaces/list.go | 8 +- pkg/server/workspaces/remove.go | 6 +- pkg/server/workspaces/service.go | 125 +++++----- pkg/server/workspaces/service_test.go | 62 +++-- pkg/server/workspaces/start.go | 21 +- pkg/server/workspaces/stop.go | 2 +- pkg/services/api_key.go | 15 ++ pkg/services/build.go | 29 +++ pkg/services/container_registry.go | 15 ++ pkg/services/git_provider.go | 31 +++ pkg/services/profile_data.go | 12 + pkg/services/target.go | 25 ++ pkg/services/target_config.go | 17 ++ .../workspaces/dto => services}/workspace.go | 40 ++- pkg/services/workspace_config.go | 28 +++ .../apikeys/store.go => stores/api_key.go} | 2 +- .../builds/store.go => stores/build.go} | 2 +- .../store.go => stores/container_registry.go} | 2 +- .../store.go => stores/git_provider.go} | 7 +- .../store.go => stores/profile_data.go} | 2 +- .../targets/store.go => stores/target.go} | 2 +- .../store.go => stores/target_config.go} | 2 +- .../store.go => stores/workspace.go} | 7 +- .../store.go => stores/workspace_config.go} | 2 +- 100 files changed, 1214 insertions(+), 1010 deletions(-) delete mode 100644 pkg/api/controllers/build/dto/dto.go create mode 100644 pkg/common/workspace_hostname.go delete mode 100644 pkg/models/build_config.go delete mode 100644 pkg/models/container_config.go delete mode 100644 pkg/models/prebuild.go delete mode 100644 pkg/server/builds/dto/builds.go delete mode 100644 pkg/server/gitproviders/util/workspace_config_store.go create mode 100644 pkg/services/api_key.go create mode 100644 pkg/services/build.go create mode 100644 pkg/services/container_registry.go create mode 100644 pkg/services/git_provider.go create mode 100644 pkg/services/profile_data.go create mode 100644 pkg/services/target.go create mode 100644 pkg/services/target_config.go rename pkg/{server/workspaces/dto => services}/workspace.go (52%) create mode 100644 pkg/services/workspace_config.go rename pkg/{server/apikeys/store.go => stores/api_key.go} (97%) rename pkg/{server/builds/store.go => stores/build.go} (98%) rename pkg/{server/containerregistries/store.go => stores/container_registry.go} (95%) rename pkg/{server/gitproviders/store.go => stores/git_provider.go} (75%) rename pkg/{server/profiledata/store.go => stores/profile_data.go} (96%) rename pkg/{server/targets/store.go => stores/target.go} (96%) rename pkg/{server/targetconfigs/store.go => stores/target_config.go} (96%) rename pkg/{server/workspaces/store.go => stores/workspace.go} (67%) rename pkg/{server/workspaceconfigs/store.go => stores/workspace_config.go} (97%) diff --git a/internal/cmd/tailscale/forward.go b/internal/cmd/tailscale/forward.go index e441282ae9..6ebf8cf700 100644 --- a/internal/cmd/tailscale/forward.go +++ b/internal/cmd/tailscale/forward.go @@ -10,7 +10,7 @@ import ( "net" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/ports" "tailscale.com/tsnet" ) @@ -47,7 +47,7 @@ func ForwardPort(workspaceId string, targetPort uint16, profile config.Profile) return } - targetUrl := fmt.Sprintf("%s:%d", (models.Workspace{Id: workspaceId}).Hostname(), targetPort) + targetUrl := fmt.Sprintf("%s:%d", common.GetWorkspaceHostname(workspaceId), targetPort) go handlePortConnection(conn, tsConn, targetUrl, errChan) } diff --git a/internal/testing/build/mocks/build_service.go b/internal/testing/build/mocks/build_service.go index 1711944025..7d24000b7b 100644 --- a/internal/testing/build/mocks/build_service.go +++ b/internal/testing/build/mocks/build_service.go @@ -7,7 +7,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/mock" ) @@ -34,7 +34,7 @@ func (m *MockBuildService) Find(id string) (*models.Build, error) { return args.Get(0).(*models.Build), args.Error(1) } -func (m *MockBuildService) List(filter *builds.BuildFilter) ([]*models.Build, error) { +func (m *MockBuildService) List(filter *stores.BuildFilter) ([]*models.Build, error) { args := m.Called(filter) return args.Get(0).([]*models.Build), args.Error(1) } diff --git a/internal/testing/build/store.go b/internal/testing/build/store.go index f014f3671e..ef6949b251 100644 --- a/internal/testing/build/store.go +++ b/internal/testing/build/store.go @@ -9,32 +9,32 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryBuildStore struct { builds map[string]*models.Build } -func NewInMemoryBuildStore() builds.BuildStore { +func NewInMemoryBuildStore() stores.BuildStore { return &InMemoryBuildStore{ builds: make(map[string]*models.Build), } } -func (s *InMemoryBuildStore) Find(filter *builds.BuildFilter) (*models.Build, error) { +func (s *InMemoryBuildStore) Find(filter *stores.BuildFilter) (*models.Build, error) { b, err := s.processFilters(filter) if err != nil { return nil, err } if len(b) == 0 { - return nil, builds.ErrBuildNotFound + return nil, stores.ErrBuildNotFound } return b[0], nil } -func (s *InMemoryBuildStore) List(filter *builds.BuildFilter) ([]*models.Build, error) { +func (s *InMemoryBuildStore) List(filter *stores.BuildFilter) ([]*models.Build, error) { builds, err := s.processFilters(filter) if err != nil { return nil, err @@ -53,7 +53,7 @@ func (s *InMemoryBuildStore) Delete(id string) error { return nil } -func (s *InMemoryBuildStore) processFilters(filter *builds.BuildFilter) ([]*models.Build, error) { +func (s *InMemoryBuildStore) processFilters(filter *stores.BuildFilter) ([]*models.Build, error) { var result []*models.Build filteredBuilds := make(map[string]*models.Build) for k, v := range s.builds { diff --git a/internal/testing/server/apikeys/store.go b/internal/testing/server/apikeys/store.go index 528fd3d0cb..419a8d0bab 100644 --- a/internal/testing/server/apikeys/store.go +++ b/internal/testing/server/apikeys/store.go @@ -7,14 +7,14 @@ package apikeys import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/apikeys" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryApiKeyStore struct { apiKeys map[string]*models.ApiKey } -func NewInMemoryApiKeyStore() apikeys.ApiKeyStore { +func NewInMemoryApiKeyStore() stores.ApiKeyStore { return &InMemoryApiKeyStore{ apiKeys: make(map[string]*models.ApiKey), } @@ -32,7 +32,7 @@ func (s *InMemoryApiKeyStore) List() ([]*models.ApiKey, error) { func (s *InMemoryApiKeyStore) Find(key string) (*models.ApiKey, error) { apiKey, ok := s.apiKeys[key] if !ok { - return nil, apikeys.ErrApiKeyNotFound + return nil, stores.ErrApiKeyNotFound } return apiKey, nil diff --git a/internal/testing/server/containerregistries/store.go b/internal/testing/server/containerregistries/store.go index 8491ed60c3..17a6c26f65 100644 --- a/internal/testing/server/containerregistries/store.go +++ b/internal/testing/server/containerregistries/store.go @@ -7,14 +7,14 @@ package containerregistries import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryContainerRegistryStore struct { crs map[string]*models.ContainerRegistry } -func NewInMemoryContainerRegistryStore() containerregistries.ContainerRegistryStore { +func NewInMemoryContainerRegistryStore() stores.ContainerRegistryStore { return &InMemoryContainerRegistryStore{ crs: make(map[string]*models.ContainerRegistry), } @@ -32,7 +32,7 @@ func (s *InMemoryContainerRegistryStore) List() ([]*models.ContainerRegistry, er func (s *InMemoryContainerRegistryStore) Find(server string) (*models.ContainerRegistry, error) { cr, ok := s.crs[server] if !ok { - return nil, containerregistries.ErrContainerRegistryNotFound + return nil, stores.ErrContainerRegistryNotFound } return cr, nil @@ -46,7 +46,7 @@ func (s *InMemoryContainerRegistryStore) Save(cr *models.ContainerRegistry) erro func (s *InMemoryContainerRegistryStore) Delete(cr *models.ContainerRegistry) error { _, ok := s.crs[cr.Server] if !ok { - return containerregistries.ErrContainerRegistryNotFound + return stores.ErrContainerRegistryNotFound } delete(s.crs, cr.Server) return nil diff --git a/internal/testing/server/profiledata/store.go b/internal/testing/server/profiledata/store.go index ffed06c22a..2427224224 100644 --- a/internal/testing/server/profiledata/store.go +++ b/internal/testing/server/profiledata/store.go @@ -7,14 +7,14 @@ package profiledata import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/profiledata" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryProfileDataStore struct { profileData *models.ProfileData } -func NewInMemoryProfileDataStore() profiledata.ProfileDataStore { +func NewInMemoryProfileDataStore() stores.ProfileDataStore { return &InMemoryProfileDataStore{ profileData: nil, } @@ -22,7 +22,7 @@ func NewInMemoryProfileDataStore() profiledata.ProfileDataStore { func (s *InMemoryProfileDataStore) Get(id string) (*models.ProfileData, error) { if s.profileData == nil { - return nil, profiledata.ErrProfileDataNotFound + return nil, stores.ErrProfileDataNotFound } return s.profileData, nil diff --git a/internal/testing/server/targetconfigs/store.go b/internal/testing/server/targetconfigs/store.go index c275c84d4f..9dab10ce14 100644 --- a/internal/testing/server/targetconfigs/store.go +++ b/internal/testing/server/targetconfigs/store.go @@ -9,31 +9,31 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryTargetConfigStore struct { targetConfigs map[string]*models.TargetConfig } -func NewInMemoryTargetConfigStore() targetconfigs.TargetConfigStore { +func NewInMemoryTargetConfigStore() stores.TargetConfigStore { return &InMemoryTargetConfigStore{ targetConfigs: make(map[string]*models.TargetConfig), } } -func (s *InMemoryTargetConfigStore) List(filter *targetconfigs.TargetConfigFilter) ([]*models.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { return s.processFilters(filter) } -func (s *InMemoryTargetConfigStore) Find(filter *targetconfigs.TargetConfigFilter) (*models.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) { targets, err := s.processFilters(filter) if err != nil { return nil, err } if len(targets) == 0 { - return nil, targetconfigs.ErrTargetConfigNotFound + return nil, stores.ErrTargetConfigNotFound } return targets[0], nil @@ -49,7 +49,7 @@ func (s *InMemoryTargetConfigStore) Delete(targetConfig *models.TargetConfig) er return nil } -func (s *InMemoryTargetConfigStore) processFilters(filter *targetconfigs.TargetConfigFilter) ([]*models.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) processFilters(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { var result []*models.TargetConfig if filter != nil { diff --git a/internal/testing/server/targets/mocks/build_service.go b/internal/testing/server/targets/mocks/build_service.go index ee29eb788e..153c581198 100644 --- a/internal/testing/server/targets/mocks/build_service.go +++ b/internal/testing/server/targets/mocks/build_service.go @@ -10,8 +10,8 @@ import ( "time" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/builds/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/mock" ) @@ -23,22 +23,22 @@ func NewMockBuildService() *MockBuildService { return &MockBuildService{} } -func (m *MockBuildService) Create(createBuildDto dto.BuildCreationData) (string, error) { +func (m *MockBuildService) Create(createBuildDto services.CreateBuildDTO) (string, error) { args := m.Called(createBuildDto) return args.String(0), args.Error(1) } -func (m *MockBuildService) Find(filter *builds.BuildFilter) (*models.Build, error) { +func (m *MockBuildService) Find(filter *stores.BuildFilter) (*models.Build, error) { args := m.Called(filter) return args.Get(0).(*models.Build), args.Error(1) } -func (m *MockBuildService) List(filter *builds.BuildFilter) ([]*models.Build, error) { +func (m *MockBuildService) List(filter *stores.BuildFilter) ([]*models.Build, error) { args := m.Called(filter) return args.Get(0).([]*models.Build), args.Error(1) } -func (m *MockBuildService) MarkForDeletion(filter *builds.BuildFilter, force bool) []error { +func (m *MockBuildService) MarkForDeletion(filter *stores.BuildFilter, force bool) []error { args := m.Called(filter, force) return args.Get(0).([]error) } diff --git a/internal/testing/server/targets/mocks/workspace_config_service.go b/internal/testing/server/targets/mocks/workspace_config_service.go index 4fbecb774c..a21cb30da6 100644 --- a/internal/testing/server/targets/mocks/workspace_config_service.go +++ b/internal/testing/server/targets/mocks/workspace_config_service.go @@ -8,8 +8,8 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/mock" ) @@ -26,12 +26,12 @@ func (m *mockWorkspaceConfigService) Delete(name string, force bool) []error { return args.Get(0).([]error) } -func (m *mockWorkspaceConfigService) Find(filter *workspaceconfigs.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { +func (m *mockWorkspaceConfigService) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { args := m.Called(filter) return args.Get(0).(*models.WorkspaceConfig), args.Error(1) } -func (m *mockWorkspaceConfigService) List(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { +func (m *mockWorkspaceConfigService) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { args := m.Called(filter) return args.Get(0).([]*models.WorkspaceConfig), args.Error(1) } @@ -51,12 +51,12 @@ func (m *mockWorkspaceConfigService) SetPrebuild(workspaceConfigName string, cre return args.Get(0).(*dto.PrebuildDTO), args.Error(1) } -func (m *mockWorkspaceConfigService) FindPrebuild(workspaceConfigFilter *workspaceconfigs.WorkspaceConfigFilter, prebuildFilter *workspaceconfigs.PrebuildFilter) (*dto.PrebuildDTO, error) { +func (m *mockWorkspaceConfigService) FindPrebuild(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { args := m.Called(workspaceConfigFilter, prebuildFilter) return args.Get(0).(*dto.PrebuildDTO), args.Error(1) } -func (m *mockWorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *workspaceconfigs.WorkspaceConfigFilter, prebuildFilter *workspaceconfigs.PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (m *mockWorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { args := m.Called(workspaceConfigFilter, prebuildFilter) return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) } diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go index 061c20d00a..24fb104a82 100644 --- a/internal/testing/server/targets/store.go +++ b/internal/testing/server/targets/store.go @@ -10,23 +10,24 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryTargetStore struct { targets map[string]*models.Target } -func NewInMemoryTargetStore() targets.TargetStore { +func NewInMemoryTargetStore() stores.TargetStore { return &InMemoryTargetStore{ targets: make(map[string]*models.Target), } } -func (s *InMemoryTargetStore) List(filter *targets.TargetFilter) ([]*models.Target, error) { +func (s *InMemoryTargetStore) List(filter *stores.TargetFilter) ([]*models.Target, error) { return s.processFilters(filter) } -func (s *InMemoryTargetStore) Find(filter *targets.TargetFilter) (*models.Target, error) { +func (s *InMemoryTargetStore) Find(filter *stores.TargetFilter) (*models.Target, error) { t, err := s.processFilters(filter) if err != nil { return nil, err @@ -53,7 +54,7 @@ func (s *InMemoryTargetStore) Delete(target *models.Target) error { return nil } -func (s *InMemoryTargetStore) processFilters(filter *targets.TargetFilter) ([]*models.Target, error) { +func (s *InMemoryTargetStore) processFilters(filter *stores.TargetFilter) ([]*models.Target, error) { var result []*models.Target filteredTargets := make(map[string]*models.Target) for k, v := range s.targets { diff --git a/internal/testing/server/workspaceconfig/store.go b/internal/testing/server/workspaceconfig/store.go index 989b243a8a..3b103b57fc 100644 --- a/internal/testing/server/workspaceconfig/store.go +++ b/internal/testing/server/workspaceconfig/store.go @@ -9,30 +9,30 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryWorkspaceConfigStore struct { workspaceConfigs map[string]*models.WorkspaceConfig } -func NewInMemoryWorkspaceConfigStore() workspaceconfigs.WorkspaceConfigStore { +func NewInMemoryWorkspaceConfigStore() stores.WorkspaceConfigStore { return &InMemoryWorkspaceConfigStore{ workspaceConfigs: make(map[string]*models.WorkspaceConfig), } } -func (s *InMemoryWorkspaceConfigStore) List(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { +func (s *InMemoryWorkspaceConfigStore) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { return s.processFilters(filter) } -func (s *InMemoryWorkspaceConfigStore) Find(filter *workspaceconfigs.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { +func (s *InMemoryWorkspaceConfigStore) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { workspaceConfigs, err := s.processFilters(filter) if err != nil { return nil, err } if len(workspaceConfigs) == 0 { - return nil, workspaceconfigs.ErrWorkspaceConfigNotFound + return nil, stores.ErrWorkspaceConfigNotFound } return workspaceConfigs[0], nil @@ -48,7 +48,7 @@ func (s *InMemoryWorkspaceConfigStore) Delete(workspaceConfig *models.WorkspaceC return nil } -func (s *InMemoryWorkspaceConfigStore) processFilters(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { +func (s *InMemoryWorkspaceConfigStore) processFilters(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { var result []*models.WorkspaceConfig filteredWorkspaceConfigs := make(map[string]*models.WorkspaceConfig) for k, v := range s.workspaceConfigs { diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go index c382a9f134..5876aeb304 100644 --- a/internal/testing/server/workspaces/store.go +++ b/internal/testing/server/workspaces/store.go @@ -8,13 +8,14 @@ package workspaces import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryWorkspaceStore struct { workspaces map[string]*models.Workspace } -func NewInMemoryWorkspaceStore() workspaces.WorkspaceStore { +func NewInMemoryWorkspaceStore() stores.WorkspaceStore { return &InMemoryWorkspaceStore{ workspaces: make(map[string]*models.Workspace), } diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go index 285521da2d..48b8c84322 100644 --- a/internal/util/apiclient/conversion/workspace.go +++ b/internal/util/apiclient/conversion/workspace.go @@ -8,7 +8,6 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" wc_dto "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" - workspace_dto "github.com/daytonaio/daytona/pkg/server/workspaces/dto" ) func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { @@ -169,25 +168,3 @@ func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) return result } - -func CreateDtoToWorkspace(createWorkspaceDto workspace_dto.CreateWorkspaceDTO) *models.Workspace { - w := &models.Workspace{ - Id: createWorkspaceDto.Id, - Name: createWorkspaceDto.Name, - BuildConfig: createWorkspaceDto.BuildConfig, - Repository: createWorkspaceDto.Source.Repository, - EnvVars: createWorkspaceDto.EnvVars, - TargetId: createWorkspaceDto.TargetId, - GitProviderConfigId: createWorkspaceDto.GitProviderConfigId, - } - - if createWorkspaceDto.Image != nil { - w.Image = *createWorkspaceDto.Image - } - - if createWorkspaceDto.User != nil { - w.User = *createWorkspaceDto.User - } - - return w -} diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index 5f35bbcaf9..b0cac8bb34 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -9,12 +9,9 @@ import ( "net/http" "strconv" - "github.com/daytonaio/daytona/pkg/api/controllers/build/dto" - "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/builds" - builds_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -30,7 +27,7 @@ import ( // // @id CreateBuild func CreateBuild(ctx *gin.Context) { - var createBuildDto dto.CreateBuildDTO + var createBuildDto services.CreateBuildDTO err := ctx.BindJSON(&createBuildDto) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) @@ -39,42 +36,7 @@ func CreateBuild(ctx *gin.Context) { s := server.GetInstance(nil) - workspaceConfig, err := s.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ - Name: &createBuildDto.WorkspaceConfigName, - }) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace config: %s", err.Error())) - return - } - - gitProvider, _, err := s.GitProviderService.GetGitProviderForUrl(workspaceConfig.RepositoryUrl) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get git provider for url: %s", err.Error())) - return - } - - repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: workspaceConfig.RepositoryUrl, - Branch: &createBuildDto.Branch, - }) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get repository: %s", err.Error())) - return - } - - newBuildDto := builds_dto.BuildCreationData{ - Image: workspaceConfig.Image, - User: workspaceConfig.User, - BuildConfig: workspaceConfig.BuildConfig, - Repository: repo, - EnvVars: createBuildDto.EnvVars, - } - - if createBuildDto.PrebuildId != nil { - newBuildDto.PrebuildId = *createBuildDto.PrebuildId - } - - buildId, err := s.BuildService.Create(newBuildDto) + buildId, err := s.BuildService.Create(createBuildDto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create build: %s", err.Error())) return @@ -99,12 +61,12 @@ func GetBuild(ctx *gin.Context) { server := server.GetInstance(nil) - b, err := server.BuildService.Find(&builds.BuildFilter{ + b, err := server.BuildService.Find(&stores.BuildFilter{ Id: &buildId, }) if err != nil { statusCode := http.StatusInternalServerError - if builds.IsBuildNotFound(err) { + if stores.IsBuildNotFound(err) { statusCode = http.StatusNotFound } ctx.AbortWithError(statusCode, fmt.Errorf("failed to find build: %w", err)) @@ -200,7 +162,7 @@ func DeleteBuild(ctx *gin.Context) { server := server.GetInstance(nil) - errs := server.BuildService.MarkForDeletion(&builds.BuildFilter{ + errs := server.BuildService.MarkForDeletion(&stores.BuildFilter{ Id: &buildId, }, force) if len(errs) > 0 { @@ -242,7 +204,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { server := server.GetInstance(nil) // Fail if prebuild does not exist - _, err = server.WorkspaceConfigService.FindPrebuild(nil, &workspaceconfigs.PrebuildFilter{ + _, err = server.WorkspaceConfigService.FindPrebuild(nil, &stores.PrebuildFilter{ Id: &prebuildId, }) if err != nil { @@ -250,7 +212,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { return } - errs := server.BuildService.MarkForDeletion(&builds.BuildFilter{ + errs := server.BuildService.MarkForDeletion(&stores.BuildFilter{ PrebuildIds: &[]string{prebuildId}, }, force) if len(errs) > 0 { diff --git a/pkg/api/controllers/build/dto/dto.go b/pkg/api/controllers/build/dto/dto.go deleted file mode 100644 index 9f9a26554b..0000000000 --- a/pkg/api/controllers/build/dto/dto.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -type CreateBuildDTO struct { - WorkspaceConfigName string `json:"workspaceConfigName" validate:"required"` - Branch string `json:"branch" validate:"required"` - PrebuildId *string `json:"prebuildId" validate:"optional"` - EnvVars map[string]string `json:"envVars" validate:"required"` -} // @name CreateBuildDTO diff --git a/pkg/api/controllers/profiledata/profile_data.go b/pkg/api/controllers/profiledata/profile_data.go index 1a38f73b22..15b7a0ade4 100644 --- a/pkg/api/controllers/profiledata/profile_data.go +++ b/pkg/api/controllers/profiledata/profile_data.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/profiledata" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -27,7 +27,7 @@ func GetProfileData(ctx *gin.Context) { server := server.GetInstance(nil) profileData, err := server.ProfileDataService.Get("") if err != nil { - if profiledata.IsProfileDataNotFound(err) { + if stores.IsProfileDataNotFound(err) { ctx.JSON(200, &models.ProfileData{}) return } @@ -80,7 +80,7 @@ func DeleteProfileData(ctx *gin.Context) { server := server.GetInstance(nil) err := server.ProfileDataService.Delete("") if err != nil { - if profiledata.IsProfileDataNotFound(err) { + if stores.IsProfileDataNotFound(err) { ctx.Status(204) return } diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index af1fed1adb..ce3b333ba8 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -43,7 +43,7 @@ func GetTarget(ctx *gin.Context) { server := server.GetInstance(nil) - t, err := server.TargetService.GetTarget(ctx.Request.Context(), &targets.TargetFilter{IdOrName: &targetId}, verbose) + t, err := server.TargetService.GetTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, verbose) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get target: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/remove.go index 8e101b171b..000d6f54b8 100644 --- a/pkg/api/controllers/targetconfig/remove.go +++ b/pkg/api/controllers/targetconfig/remove.go @@ -8,7 +8,7 @@ import ( "net/http" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -27,7 +27,7 @@ func RemoveTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfig, err := server.TargetConfigService.Find(&targetconfigs.TargetConfigFilter{ + targetConfig, err := server.TargetConfigService.Find(&stores.TargetConfigFilter{ Name: &configName, }) if err != nil { diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go index 25e744badb..89ca5481ea 100644 --- a/pkg/api/controllers/workspace/create.go +++ b/pkg/api/controllers/workspace/create.go @@ -8,7 +8,7 @@ import ( "net/http" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" ) @@ -24,7 +24,7 @@ import ( // // @id CreateWorkspace func CreateWorkspace(ctx *gin.Context) { - var createWorkspaceReq dto.CreateWorkspaceDTO + var createWorkspaceReq services.CreateWorkspaceDTO err := ctx.BindJSON(&createWorkspaceReq) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) diff --git a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go index de8676e589..c3ad48944d 100644 --- a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go +++ b/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go @@ -10,8 +10,8 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -32,13 +32,13 @@ func GetPrebuild(ctx *gin.Context) { prebuildId := ctx.Param("prebuildId") server := server.GetInstance(nil) - res, err := server.WorkspaceConfigService.FindPrebuild(&workspaceconfigs.WorkspaceConfigFilter{ + res, err := server.WorkspaceConfigService.FindPrebuild(&stores.WorkspaceConfigFilter{ Name: &configName, - }, &workspaceconfigs.PrebuildFilter{ + }, &stores.PrebuildFilter{ Id: &prebuildId, }) if err != nil { - if workspaceconfigs.IsPrebuildNotFound(err) { + if stores.IsPrebuildNotFound(err) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) return } @@ -116,10 +116,10 @@ func ListPrebuilds(ctx *gin.Context) { func ListPrebuildsForWorkspaceConfig(ctx *gin.Context) { configName := ctx.Param("configName") - var workspaceConfigFilter *workspaceconfigs.WorkspaceConfigFilter + var workspaceConfigFilter *stores.WorkspaceConfigFilter if configName != "" { - workspaceConfigFilter = &workspaceconfigs.WorkspaceConfigFilter{ + workspaceConfigFilter = &stores.WorkspaceConfigFilter{ Name: &configName, } } @@ -166,7 +166,7 @@ func DeletePrebuild(ctx *gin.Context) { server := server.GetInstance(nil) errs := server.WorkspaceConfigService.DeletePrebuild(configName, prebuildId, force) if len(errs) > 0 { - if workspaceconfigs.IsPrebuildNotFound(errs[0]) { + if stores.IsPrebuildNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) return } diff --git a/pkg/api/controllers/workspaceconfig/workspace_config.go b/pkg/api/controllers/workspaceconfig/workspace_config.go index a7cd3d2ccd..04a6626b64 100644 --- a/pkg/api/controllers/workspaceconfig/workspace_config.go +++ b/pkg/api/controllers/workspaceconfig/workspace_config.go @@ -13,8 +13,8 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" ) @@ -35,7 +35,7 @@ func GetWorkspaceConfig(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceConfig, err := server.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ + workspaceConfig, err := server.WorkspaceConfigService.Find(&stores.WorkspaceConfigFilter{ Name: &configName, }) if err != nil { @@ -68,13 +68,13 @@ func GetDefaultWorkspaceConfig(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceConfigs, err := server.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ + workspaceConfigs, err := server.WorkspaceConfigService.Find(&stores.WorkspaceConfigFilter{ Url: &decodedURLParam, Default: util.Pointer(true), }) if err != nil { statusCode := http.StatusInternalServerError - if workspaceconfigs.IsWorkspaceConfigNotFound(err) { + if stores.IsWorkspaceConfigNotFound(err) { statusCode = http.StatusNotFound ctx.AbortWithStatus(statusCode) log.Debugf("Workspace config not added for git url: %s", decodedURLParam) @@ -193,7 +193,7 @@ func DeleteWorkspaceConfig(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceConfig, err := server.WorkspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ + workspaceConfig, err := server.WorkspaceConfigService.Find(&stores.WorkspaceConfigFilter{ Name: &configName, }) if err != nil { @@ -203,7 +203,7 @@ func DeleteWorkspaceConfig(ctx *gin.Context) { errs := server.WorkspaceConfigService.Delete(workspaceConfig.Name, force) if len(errs) > 0 { - if workspaceconfigs.IsWorkspaceConfigNotFound(errs[0]) { + if stores.IsWorkspaceConfigNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("workspace config not found")) return } diff --git a/pkg/build/builder.go b/pkg/build/builder.go index 71924ce909..f529a8b9e8 100644 --- a/pkg/build/builder.go +++ b/pkg/build/builder.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" ) type IBuilder interface { @@ -26,7 +26,7 @@ type Builder struct { image string containerRegistry *models.ContainerRegistry buildImageContainerRegistry *models.ContainerRegistry - buildStore builds.BuildStore + buildStore stores.BuildStore buildImageNamespace string loggerFactory logs.LoggerFactory defaultWorkspaceImage string diff --git a/pkg/build/builder_test.go b/pkg/build/builder_test.go index e0c308cbad..c86b0a9059 100644 --- a/pkg/build/builder_test.go +++ b/pkg/build/builder_test.go @@ -11,7 +11,7 @@ import ( builder_mocks "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) @@ -20,7 +20,7 @@ var expectedBuilds []*models.Build type BuilderTestSuite struct { suite.Suite mockGitService *git_mocks.MockGitService - mockBuildStore builds.BuildStore + mockBuildStore stores.BuildStore builder build.IBuilder } diff --git a/pkg/build/factory.go b/pkg/build/factory.go index 367cda10b9..10e7283e59 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" "github.com/docker/docker/pkg/stringid" ) @@ -23,7 +23,7 @@ type BuilderFactory struct { containerRegistry *models.ContainerRegistry buildImageContainerRegistry *models.ContainerRegistry buildImageNamespace string - buildStore builds.BuildStore + buildStore stores.BuildStore loggerFactory logs.LoggerFactory image string defaultWorkspaceImage string @@ -34,7 +34,7 @@ type BuilderFactoryConfig struct { Image string ContainerRegistry *models.ContainerRegistry BuildImageContainerRegistry *models.ContainerRegistry - BuildStore builds.BuildStore + BuildStore stores.BuildStore BuildImageNamespace string // Namespace to be used when tagging and pushing the build image LoggerFactory logs.LoggerFactory DefaultWorkspaceImage string @@ -64,7 +64,7 @@ func (f *BuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, erro return nil, errors.New("repository must be set") } - build, err := f.buildStore.Find(&builds.BuildFilter{ + build, err := f.buildStore.Find(&stores.BuildFilter{ Branch: &b.Repository.Branch, RepositoryUrl: &b.Repository.Url, BuildConfig: b.BuildConfig, diff --git a/pkg/build/runner.go b/pkg/build/runner.go index 3a9918718e..cb020102ad 100644 --- a/pkg/build/runner.go +++ b/pkg/build/runner.go @@ -15,7 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/scheduler" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/docker/docker/client" "github.com/go-git/go-git/v5/plumbing/transport/http" @@ -28,7 +28,7 @@ type BuildRunnerInstanceConfig struct { BuildRunnerId string ContainerRegistry *models.ContainerRegistry GitProviderStore GitProviderStore - BuildStore builds.BuildStore + BuildStore stores.BuildStore BuilderFactory IBuilderFactory LoggerFactory logs.LoggerFactory BasePath string @@ -42,7 +42,7 @@ type BuildRunner struct { runInterval string containerRegistry *models.ContainerRegistry gitProviderStore GitProviderStore - buildStore builds.BuildStore + buildStore stores.BuildStore builderFactory IBuilderFactory loggerFactory logs.LoggerFactory basePath string @@ -100,7 +100,7 @@ func (r *BuildRunner) Stop() { } func (r *BuildRunner) RunBuilds() { - builds, err := r.buildStore.List(&builds.BuildFilter{ + builds, err := r.buildStore.List(&stores.BuildFilter{ States: &[]models.BuildState{models.BuildStatePendingRun, models.BuildStatePublished}, }) if err != nil { @@ -171,7 +171,7 @@ func (r *BuildRunner) RunBuilds() { } func (r *BuildRunner) DeleteBuilds() { - markedForDeletionBuilds, err := r.buildStore.List(&builds.BuildFilter{ + markedForDeletionBuilds, err := r.buildStore.List(&stores.BuildFilter{ States: &[]models.BuildState{models.BuildStatePendingDelete, models.BuildStatePendingForcedDelete}, }) if err != nil { diff --git a/pkg/build/runner_test.go b/pkg/build/runner_test.go index ee7ea69368..531e05a79f 100644 --- a/pkg/build/runner_test.go +++ b/pkg/build/runner_test.go @@ -15,7 +15,7 @@ import ( t_gitprovider "github.com/daytonaio/daytona/pkg/build/mocks" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" @@ -35,7 +35,7 @@ type BuildRunnerTestSuite struct { mockScheduler mocks.MockScheduler mockGitService git_mocks.MockGitService loggerFactory logs.LoggerFactory - mockBuildStore builds.BuildStore + mockBuildStore stores.BuildStore mockGitProviderConfigStore t_gitprovider.MockGitProviderConfigStore Runner build.BuildRunner } diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index 23153b3455..cf07f4e1ae 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -20,6 +20,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/ssh" "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/git" "github.com/daytonaio/daytona/pkg/models" log "github.com/sirupsen/logrus" @@ -100,7 +101,7 @@ var AgentCmd = &cobra.Command{ tailscaleHostname := c.TargetId if agentMode == agent_config.ModeWorkspace { - tailscaleHostname = ws.Hostname() + tailscaleHostname = common.GetWorkspaceHostname(ws.Id) } toolBoxServer := &toolbox.Server{ diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 9c30713e09..46f943d84f 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -4,6 +4,7 @@ package server import ( + "context" "errors" "fmt" "net/url" @@ -20,6 +21,7 @@ import ( "github.com/daytonaio/daytona/pkg/api" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/db" + "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" @@ -30,7 +32,6 @@ import ( "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/gitproviders" - gp_util "github.com/daytonaio/daytona/pkg/server/gitproviders/util" "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/registry" @@ -38,6 +39,8 @@ import ( "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -264,14 +267,49 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe Store: containerRegistryStore, }) - buildService := builds.NewBuildService(builds.BuildServiceConfig{ - BuildStore: buildStore, - LoggerFactory: loggerFactory, + gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ + ConfigStore: gitProviderConfigStore, + DetachWorkspaceConfigs: func(ctx context.Context, gitProviderConfigId string) error { + workspaceConfigs, err := workspaceConfigStore.List(&stores.WorkspaceConfigFilter{ + GitProviderConfigId: &gitProviderConfigId, + }) + + if err != nil { + return err + } + + for _, workspaceConfig := range workspaceConfigs { + workspaceConfig.GitProviderConfigId = nil + err = workspaceConfigStore.Save(workspaceConfig) + if err != nil { + return err + } + } + + return nil + }, }) - gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ - ConfigStore: gitProviderConfigStore, - WorkspaceConfigStore: gp_util.FromWorkspaceConfigStore(workspaceConfigStore), + buildService := builds.NewBuildService(builds.BuildServiceConfig{ + BuildStore: buildStore, + FindWorkspaceConfig: func(ctx context.Context, name string) (*models.WorkspaceConfig, error) { + return workspaceConfigStore.Find(&stores.WorkspaceConfigFilter{ + Name: &name, + }) + }, + GetRepositoryContext: func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) { + gitProvider, _, err := gitProviderService.GetGitProviderForUrl(url) + if err != nil { + return nil, err + } + + repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ + Url: url, + }) + + return repo, err + }, + LoggerFactory: loggerFactory, }) prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) @@ -279,8 +317,68 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe workspaceConfigService := workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ PrebuildWebhookEndpoint: prebuildWebhookEndpoint, ConfigStore: workspaceConfigStore, - BuildService: buildService, - GitProviderService: gitProviderService, + FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { + return buildService.Find(&stores.BuildFilter{ + PrebuildIds: &[]string{prebuildId}, + GetNewest: util.Pointer(true), + }) + }, + ListPublishedBuilds: func(ctx context.Context) ([]*models.Build, error) { + return buildService.List(&stores.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePublished}, + }) + }, + CreateBuild: func(ctx context.Context, workspaceConfig *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error { + createBuildDto := services.CreateBuildDTO{ + WorkspaceConfigName: workspaceConfig.Name, + Branch: repo.Branch, + PrebuildId: &prebuildId, + EnvVars: workspaceConfig.EnvVars, + } + + _, err := buildService.Create(createBuildDto) + return err + }, + DeleteBuilds: func(ctx context.Context, id, prebuildId *string, force bool) []error { + var prebuildIds *[]string + if prebuildId != nil { + prebuildIds = &[]string{*prebuildId} + } + + return buildService.MarkForDeletion(&stores.BuildFilter{ + Id: id, + PrebuildIds: prebuildIds, + }, force) + }, + GetRepositoryContext: func(ctx context.Context, url string) (*gitprovider.GitRepository, string, error) { + gitProvider, gitProviderId, err := gitProviderService.GetGitProviderForUrl(url) + if err != nil { + return nil, "", err + } + + repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ + Url: url, + }) + + return repo, gitProviderId, err + }, + FindPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { + return gitProviderService.GetPrebuildWebhook(gitProviderId, repo, endpointUrl) + }, + UnregisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error { + return gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repo, id) + }, + RegisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { + return gitProviderService.RegisterPrebuildWebhook(gitProviderId, repo, endpointUrl) + }, + GetCommitsRange: func(ctx context.Context, repo *gitprovider.GitRepository, initialSha, currentSha string) (int, error) { + gitProvider, _, err := gitProviderService.GetGitProviderForUrl(repo.Url) + if err != nil { + return 0, err + } + + return gitProvider.GetCommitsRange(repo, initialSha, currentSha) + }, }) err = workspaceConfigService.StartRetentionPoller() @@ -301,7 +399,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if c.BuilderRegistryServer == "local" { cr, err := containerRegistryService.FindByImageName(c.LocalBuilderRegistryImage) - if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { + if err != nil && !stores.IsContainerRegistryNotFound(err) { return nil, err } @@ -335,12 +433,17 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ServerVersion: version, RegistryUrl: c.RegistryUrl, BaseDir: c.ProvidersDir, - CreateProviderNetworkKey: func(providerName string) (string, error) { + CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { return headscaleServer.CreateAuthKey() }, - ServerPort: c.HeadscalePort, - ApiPort: c.ApiPort, - TargetConfigService: targetConfigService, + ServerPort: c.HeadscalePort, + ApiPort: c.ApiPort, + GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { + return targetConfigService.Map() + }, + CreateTargetConfig: func(ctx context.Context, targetConfig *models.TargetConfig) error { + return targetConfigService.Save(targetConfig) + }, }) provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ @@ -348,33 +451,86 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }) targetService := targets.NewTargetService(targets.TargetServiceConfig{ - TargetStore: targetStore, - TargetConfigStore: targetConfigStore, - ApiKeyService: apiKeyService, - ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - ServerVersion: version, - ServerUrl: headscaleUrl, - Provisioner: provisioner, - LoggerFactory: loggerFactory, - TelemetryService: telemetryService, + TargetStore: targetStore, + FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { + return targetConfigService.Find(&stores.TargetConfigFilter{Name: &name}) + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(models.ApiKeyTypeTarget, name) + }, + RevokeApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Revoke(name) + }, + ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + ServerVersion: version, + ServerUrl: headscaleUrl, + Provisioner: provisioner, + LoggerFactory: loggerFactory, + TelemetryService: telemetryService, }) workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ - WorkspaceStore: workspaceStore, - TargetStore: targetStore, - ApiKeyService: apiKeyService, - GitProviderService: gitProviderService, - ContainerRegistryService: containerRegistryService, - BuilderImage: c.BuilderImage, - BuildService: buildService, - ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - ServerVersion: version, - ServerUrl: headscaleUrl, - DefaultWorkspaceImage: c.DefaultWorkspaceImage, - DefaultWorkspaceUser: c.DefaultWorkspaceUser, - Provisioner: provisioner, - LoggerFactory: loggerFactory, - TelemetryService: telemetryService, + BuilderImage: c.BuilderImage, + WorkspaceStore: workspaceStore, + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + t, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, false) + if err != nil { + return nil, err + } + return &t.Target, nil + }, + FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { + return containerRegistryService.FindByImageName(image) + }, + FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { + validStates := &[]models.BuildState{ + models.BuildStatePublished, + } + + build, err := buildService.Find(&stores.BuildFilter{ + States: validStates, + RepositoryUrl: &w.Repository.Url, + Branch: &w.Repository.Branch, + EnvVars: &w.EnvVars, + BuildConfig: w.BuildConfig, + GetNewest: util.Pointer(true), + }) + if err != nil { + return nil, err + } + + if build.Image == nil || build.User == nil { + return nil, errors.New("cached build is missing image or user") + } + + return &models.CachedBuild{ + User: *build.User, + Image: *build.Image, + }, nil + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(models.ApiKeyTypeWorkspace, name) + }, + RevokeApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Revoke(name) + }, + ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { + return gitProviderService.ListConfigsForUrl(repoUrl) + }, + FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { + return gitProviderService.GetConfig(id) + }, + GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { + return gitProviderService.GetLastCommitSha(repo) + }, + TrackTelemetryEvent: telemetryService.TrackServerEvent, + ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + ServerVersion: version, + ServerUrl: headscaleUrl, + DefaultWorkspaceImage: c.DefaultWorkspaceImage, + DefaultWorkspaceUser: c.DefaultWorkspaceUser, + Provisioner: provisioner, + LoggerFactory: loggerFactory, }) profileDataService := profiledata.NewProfileDataService(profiledata.ProfileDataServiceConfig{ @@ -457,7 +613,7 @@ func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetry } cr, err := containerRegistryService.FindByImageName(c.BuilderImage) - if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { + if err != nil && !stores.IsContainerRegistryNotFound(err) { return nil, err } diff --git a/pkg/cmd/workspace/common/get_gpg_key.go b/pkg/cmd/workspace/common/get_gpg_key.go index da917cd0b0..d4551c9274 100644 --- a/pkg/cmd/workspace/common/get_gpg_key.go +++ b/pkg/cmd/workspace/common/get_gpg_key.go @@ -8,7 +8,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/models" ) func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (string, error) { @@ -16,7 +15,6 @@ func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, p return "", nil } - var providerConfig *models.GitProviderConfig var gpgKey string gitProvider, res, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *providerConfigId).Execute() @@ -26,14 +24,9 @@ func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, p // Extract GPG key if present if gitProvider != nil { - providerConfig = &models.GitProviderConfig{ - SigningMethod: (*models.SigningMethod)(gitProvider.SigningMethod), - SigningKey: gitProvider.SigningKey, - } - - if providerConfig.SigningMethod != nil && providerConfig.SigningKey != nil { - if *providerConfig.SigningMethod == models.SigningMethodGPG { - gpgKey = *providerConfig.SigningKey + if gitProvider.SigningMethod != nil && gitProvider.SigningKey != nil { + if *gitProvider.SigningMethod == apiclient.SigningMethodGPG { + gpgKey = *gitProvider.SigningKey } } } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 25b88cae4a..4891446bca 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -19,7 +19,6 @@ import ( workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/views" logs_view "github.com/daytonaio/daytona/pkg/views/logs" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -339,7 +338,7 @@ func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile go func() { for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", models.Workspace{Id: workspaceId}.Hostname(), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", common.GetWorkspaceHostname(workspaceId), ssh_config.SSH_PORT)) if err == nil { connectChan <- dialConn.Close() return diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index e9fe822178..60f7eae530 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -16,8 +16,8 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" @@ -125,7 +125,7 @@ var SshProxyCmd = &cobra.Command{ errChan := make(chan error) - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", models.Workspace{Id: ws.Id}.Hostname(), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", common.GetWorkspaceHostname(ws.Id), ssh_config.SSH_PORT)) if err != nil { return err } diff --git a/pkg/common/workspace_hostname.go b/pkg/common/workspace_hostname.go new file mode 100644 index 0000000000..a49c25e3e5 --- /dev/null +++ b/pkg/common/workspace_hostname.go @@ -0,0 +1,25 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "fmt" + "strings" +) + +func GetWorkspaceHostname(workspaceId string) string { + // Replace special chars with hyphen to form valid hostname + // String resulting in consecutive hyphens is also valid + workspaceId = strings.ReplaceAll(workspaceId, "_", "-") + workspaceId = strings.ReplaceAll(workspaceId, "*", "-") + workspaceId = strings.ReplaceAll(workspaceId, ".", "-") + + hostname := fmt.Sprintf("ws-%s", workspaceId) + + if len(hostname) > 63 { + return hostname[:63] + } + + return hostname +} diff --git a/pkg/db/api_key_store.go b/pkg/db/api_key_store.go index 9fee7b886e..92afdd4433 100644 --- a/pkg/db/api_key_store.go +++ b/pkg/db/api_key_store.go @@ -5,7 +5,7 @@ package db import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/apikeys" + "github.com/daytonaio/daytona/pkg/stores" "gorm.io/gorm" ) @@ -13,7 +13,7 @@ type ApiKeyStore struct { db *gorm.DB } -func NewApiKeyStore(db *gorm.DB) (*ApiKeyStore, error) { +func NewApiKeyStore(db *gorm.DB) (stores.ApiKeyStore, error) { err := db.AutoMigrate(&models.ApiKey{}) if err != nil { return nil, err @@ -37,7 +37,7 @@ func (a *ApiKeyStore) Find(key string) (*models.ApiKey, error) { tx := a.db.Where("key_hash = ?", key).First(apiKey) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, apikeys.ErrApiKeyNotFound + return nil, stores.ErrApiKeyNotFound } return nil, tx.Error } @@ -50,7 +50,7 @@ func (a *ApiKeyStore) FindByName(name string) (*models.ApiKey, error) { tx := a.db.Where("name = ?", name).First(apiKey) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, apikeys.ErrApiKeyNotFound + return nil, stores.ErrApiKeyNotFound } return nil, tx.Error } @@ -73,7 +73,7 @@ func (a *ApiKeyStore) Delete(apiKey *models.ApiKey) error { return tx.Error } if tx.RowsAffected == 0 { - return apikeys.ErrApiKeyNotFound + return stores.ErrApiKeyNotFound } return nil diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index ad85aa0294..15705778da 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -10,7 +10,7 @@ import ( "sync" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/stores" "gorm.io/gorm" ) @@ -19,7 +19,7 @@ type BuildStore struct { Lock sync.Mutex } -func NewBuildStore(db *gorm.DB) (*BuildStore, error) { +func NewBuildStore(db *gorm.DB) (stores.BuildStore, error) { err := db.AutoMigrate(&models.Build{}) if err != nil { return nil, err @@ -28,7 +28,7 @@ func NewBuildStore(db *gorm.DB) (*BuildStore, error) { return &BuildStore{db: db}, nil } -func (b *BuildStore) Find(filter *builds.BuildFilter) (*models.Build, error) { +func (b *BuildStore) Find(filter *stores.BuildFilter) (*models.Build, error) { b.Lock.Lock() defer b.Lock.Unlock() @@ -37,7 +37,7 @@ func (b *BuildStore) Find(filter *builds.BuildFilter) (*models.Build, error) { if tx.Error != nil { if tx.Error == gorm.ErrRecordNotFound { - return nil, builds.ErrBuildNotFound + return nil, stores.ErrBuildNotFound } return nil, tx.Error } @@ -45,7 +45,7 @@ func (b *BuildStore) Find(filter *builds.BuildFilter) (*models.Build, error) { return build, nil } -func (b *BuildStore) List(filter *builds.BuildFilter) ([]*models.Build, error) { +func (b *BuildStore) List(filter *stores.BuildFilter) ([]*models.Build, error) { b.Lock.Lock() defer b.Lock.Unlock() @@ -80,13 +80,13 @@ func (b *BuildStore) Delete(id string) error { return tx.Error } if tx.RowsAffected == 0 { - return builds.ErrBuildNotFound + return stores.ErrBuildNotFound } return nil } -func processBuildFilters(tx *gorm.DB, filter *builds.BuildFilter) *gorm.DB { +func processBuildFilters(tx *gorm.DB, filter *stores.BuildFilter) *gorm.DB { if filter != nil { if filter.Id != nil { tx = tx.Where("id = ?", *filter.Id) diff --git a/pkg/db/container_registry_store.go b/pkg/db/container_registry_store.go index 55c956d927..ecca43d387 100644 --- a/pkg/db/container_registry_store.go +++ b/pkg/db/container_registry_store.go @@ -7,14 +7,14 @@ import ( "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/stores" ) type ContainerRegistryStore struct { db *gorm.DB } -func NewContainerRegistryStore(db *gorm.DB) (*ContainerRegistryStore, error) { +func NewContainerRegistryStore(db *gorm.DB) (stores.ContainerRegistryStore, error) { err := db.AutoMigrate(&models.ContainerRegistry{}) if err != nil { return nil, err @@ -38,7 +38,7 @@ func (s *ContainerRegistryStore) Find(server string) (*models.ContainerRegistry, tx := s.db.Where("server = ?", server).First(containerRegistry) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, containerregistries.ErrContainerRegistryNotFound + return nil, stores.ErrContainerRegistryNotFound } return nil, tx.Error } @@ -61,7 +61,7 @@ func (s *ContainerRegistryStore) Delete(cr *models.ContainerRegistry) error { return tx.Error } if tx.RowsAffected == 0 { - return containerregistries.ErrContainerRegistryNotFound + return stores.ErrContainerRegistryNotFound } return nil diff --git a/pkg/db/gitprovider_config_store.go b/pkg/db/gitprovider_config_store.go index b0f3cc4c97..ca398b7567 100644 --- a/pkg/db/gitprovider_config_store.go +++ b/pkg/db/gitprovider_config_store.go @@ -7,14 +7,14 @@ import ( "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/stores" ) type GitProviderConfigStore struct { db *gorm.DB } -func NewGitProviderConfigStore(db *gorm.DB) (*GitProviderConfigStore, error) { +func NewGitProviderConfigStore(db *gorm.DB) (stores.GitProviderConfigStore, error) { err := db.AutoMigrate(&models.GitProviderConfig{}) if err != nil { return nil, err @@ -38,7 +38,7 @@ func (p *GitProviderConfigStore) Find(id string) (*models.GitProviderConfig, err tx := p.db.Where("id = ?", id).First(gitProvider) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, gitproviders.ErrGitProviderConfigNotFound + return nil, stores.ErrGitProviderConfigNotFound } return nil, tx.Error } @@ -61,7 +61,7 @@ func (p *GitProviderConfigStore) Delete(gitProvider *models.GitProviderConfig) e return tx.Error } if tx.RowsAffected == 0 { - return gitproviders.ErrGitProviderConfigNotFound + return stores.ErrGitProviderConfigNotFound } return nil diff --git a/pkg/db/profile_data_store.go b/pkg/db/profile_data_store.go index 822423f98b..768a02f148 100644 --- a/pkg/db/profile_data_store.go +++ b/pkg/db/profile_data_store.go @@ -5,7 +5,7 @@ package db import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/profiledata" + "github.com/daytonaio/daytona/pkg/stores" "gorm.io/gorm" ) @@ -27,7 +27,7 @@ func (p *ProfileDataStore) Get(id string) (*models.ProfileData, error) { tx := p.db.Where("id = ?", id).First(profileData) if tx.Error != nil { if tx.Error == gorm.ErrRecordNotFound { - return nil, profiledata.ErrProfileDataNotFound + return nil, stores.ErrProfileDataNotFound } return nil, tx.Error } @@ -50,7 +50,7 @@ func (p *ProfileDataStore) Delete(id string) error { return tx.Error } if tx.RowsAffected == 0 { - return profiledata.ErrProfileDataNotFound + return stores.ErrProfileDataNotFound } return nil diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index 366436c18f..06ef717cb3 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -7,14 +7,14 @@ import ( "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/stores" ) type TargetConfigStore struct { db *gorm.DB } -func NewTargetConfigStore(db *gorm.DB) (*TargetConfigStore, error) { +func NewTargetConfigStore(db *gorm.DB) (stores.TargetConfigStore, error) { err := db.AutoMigrate(&models.TargetConfig{}) if err != nil { return nil, err @@ -23,7 +23,7 @@ func NewTargetConfigStore(db *gorm.DB) (*TargetConfigStore, error) { return &TargetConfigStore{db: db}, nil } -func (s *TargetConfigStore) List(filter *targetconfigs.TargetConfigFilter) ([]*models.TargetConfig, error) { +func (s *TargetConfigStore) List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { targetConfigs := []*models.TargetConfig{} tx := processTargetConfigFilters(s.db, filter).Find(&targetConfigs) @@ -34,13 +34,13 @@ func (s *TargetConfigStore) List(filter *targetconfigs.TargetConfigFilter) ([]*m return targetConfigs, nil } -func (s *TargetConfigStore) Find(filter *targetconfigs.TargetConfigFilter) (*models.TargetConfig, error) { +func (s *TargetConfigStore) Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) { targetConfig := &models.TargetConfig{} tx := processTargetConfigFilters(s.db, filter).First(targetConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, targetconfigs.ErrTargetConfigNotFound + return nil, stores.ErrTargetConfigNotFound } return nil, tx.Error } @@ -63,13 +63,13 @@ func (s *TargetConfigStore) Delete(targetConfig *models.TargetConfig) error { return tx.Error } if tx.RowsAffected == 0 { - return targetconfigs.ErrTargetConfigNotFound + return stores.ErrTargetConfigNotFound } return nil } -func processTargetConfigFilters(tx *gorm.DB, filter *targetconfigs.TargetConfigFilter) *gorm.DB { +func processTargetConfigFilters(tx *gorm.DB, filter *stores.TargetConfigFilter) *gorm.DB { if filter != nil { if filter.Name != nil { tx = tx.Where("name = ?", *filter.Name) diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index 485005863d..f2d648125d 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -8,13 +8,14 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/stores" ) type TargetStore struct { db *gorm.DB } -func NewTargetStore(db *gorm.DB) (*TargetStore, error) { +func NewTargetStore(db *gorm.DB) (stores.TargetStore, error) { err := db.AutoMigrate(&models.Target{}) if err != nil { return nil, err @@ -23,7 +24,7 @@ func NewTargetStore(db *gorm.DB) (*TargetStore, error) { return &TargetStore{db: db}, nil } -func (s *TargetStore) List(filter *targets.TargetFilter) ([]*models.Target, error) { +func (s *TargetStore) List(filter *stores.TargetFilter) ([]*models.Target, error) { targets := []*models.Target{} tx := processTargetFilters(s.db, filter).Preload("Workspaces").Find(&targets) @@ -33,7 +34,7 @@ func (s *TargetStore) List(filter *targets.TargetFilter) ([]*models.Target, erro return targets, nil } -func (s *TargetStore) Find(filter *targets.TargetFilter) (*models.Target, error) { +func (s *TargetStore) Find(filter *stores.TargetFilter) (*models.Target, error) { tg := &models.Target{} tx := processTargetFilters(s.db, filter).Preload("Workspaces").First(tg) @@ -71,7 +72,7 @@ func (s *TargetStore) Delete(t *models.Target) error { return nil } -func processTargetFilters(tx *gorm.DB, filter *targets.TargetFilter) *gorm.DB { +func processTargetFilters(tx *gorm.DB, filter *stores.TargetFilter) *gorm.DB { if filter != nil { if filter.IdOrName != nil { tx = tx.Where("id = ? OR name = ?", *filter.IdOrName, *filter.IdOrName) diff --git a/pkg/db/workspace_config_store.go b/pkg/db/workspace_config_store.go index 1df557ae00..d8c0fec894 100644 --- a/pkg/db/workspace_config_store.go +++ b/pkg/db/workspace_config_store.go @@ -7,7 +7,7 @@ import ( "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/stores" ) type WorkspaceConfigStore struct { @@ -23,7 +23,7 @@ func NewWorkspaceConfigStore(db *gorm.DB) (*WorkspaceConfigStore, error) { return &WorkspaceConfigStore{db: db}, nil } -func (s *WorkspaceConfigStore) List(filter *workspaceconfigs.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { +func (s *WorkspaceConfigStore) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { workspaceConfigs := []*models.WorkspaceConfig{} tx := processWorkspaceConfigFilters(s.db, filter).Find(&workspaceConfigs) @@ -34,13 +34,13 @@ func (s *WorkspaceConfigStore) List(filter *workspaceconfigs.WorkspaceConfigFilt return workspaceConfigs, nil } -func (s *WorkspaceConfigStore) Find(filter *workspaceconfigs.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { +func (s *WorkspaceConfigStore) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { workspaceConfig := &models.WorkspaceConfig{} tx := processWorkspaceConfigFilters(s.db, filter).First(workspaceConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, workspaceconfigs.ErrWorkspaceConfigNotFound + return nil, stores.ErrWorkspaceConfigNotFound } return nil, tx.Error } @@ -63,13 +63,13 @@ func (s *WorkspaceConfigStore) Delete(workspaceConfig *models.WorkspaceConfig) e return tx.Error } if tx.RowsAffected == 0 { - return workspaceconfigs.ErrWorkspaceConfigNotFound + return stores.ErrWorkspaceConfigNotFound } return nil } -func processWorkspaceConfigFilters(tx *gorm.DB, filter *workspaceconfigs.WorkspaceConfigFilter) *gorm.DB { +func processWorkspaceConfigFilters(tx *gorm.DB, filter *stores.WorkspaceConfigFilter) *gorm.DB { if filter != nil { if filter.Name != nil { tx = tx.Where("name = ?", *filter.Name) diff --git a/pkg/models/build.go b/pkg/models/build.go index b663f30e42..b07aa34d0e 100644 --- a/pkg/models/build.go +++ b/pkg/models/build.go @@ -38,6 +38,11 @@ type Build struct { UpdatedAt time.Time `json:"updatedAt" validate:"required"` } // @name Build +type ContainerConfig struct { + Image string `json:"image" validate:"required"` + User string `json:"user" validate:"required"` +} // @name ContainerConfig + func (b *Build) Compare(other *Build) (bool, error) { if b.BuildConfig != nil && *b.BuildConfig == (BuildConfig{}) { buildHash, err := b.getBuildHashWithoutBuildConfig() diff --git a/pkg/models/build_config.go b/pkg/models/build_config.go deleted file mode 100644 index 70c3e654af..0000000000 --- a/pkg/models/build_config.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package models - -type BuildConfig struct { - Devcontainer *DevcontainerConfig `json:"devcontainer,omitempty" validate:"optional"` - CachedBuild *CachedBuild `json:"cachedBuild,omitempty" validate:"optional"` -} // @name BuildConfig - -type DevcontainerConfig struct { - FilePath string `json:"filePath" validate:"required"` -} // @name DevcontainerConfig - -type CachedBuild struct { - User string `json:"user" validate:"required"` - Image string `json:"image" validate:"required"` -} // @name CachedBuild diff --git a/pkg/models/container_config.go b/pkg/models/container_config.go deleted file mode 100644 index e2eecc6a5c..0000000000 --- a/pkg/models/container_config.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package models - -type ContainerConfig struct { - Image string `json:"image" validate:"required"` - User string `json:"user" validate:"required"` -} // @name ContainerConfig diff --git a/pkg/models/prebuild.go b/pkg/models/prebuild.go deleted file mode 100644 index 15d89f63fc..0000000000 --- a/pkg/models/prebuild.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package models - -import ( - "encoding/json" - "sort" - - "github.com/docker/docker/pkg/stringid" -) - -// PrebuildConfig holds configuration for the prebuild process -type PrebuildConfig struct { - Id string `json:"id" validate:"required"` - Branch string `json:"branch" validate:"required"` - CommitInterval *int `json:"commitInterval" validate:"required"` - TriggerFiles []string `json:"triggerFiles" validate:"required"` - Retention int `json:"retention" validate:"required"` -} // @name PrebuildConfig - -func (p *PrebuildConfig) GenerateId() error { - id := stringid.GenerateRandomID() - id = stringid.TruncateID(id) - - p.Id = id - return nil -} - -type MatchParams struct { - WorkspaceConfigName *string - Id *string - Branch *string - CommitInterval *int - TriggerFiles *[]string -} - -func (p *PrebuildConfig) Match(params *MatchParams) bool { - if params.Id != nil && *params.Id != p.Id { - return false - } - - if params.Branch != nil && *params.Branch != p.Branch { - return false - } - - if params.CommitInterval != nil && p.CommitInterval != nil && *params.CommitInterval != *p.CommitInterval { - return false - } - - if params.TriggerFiles != nil { - // Sort the trigger files before checking if same - sort.Strings(p.TriggerFiles) - sort.Strings(*params.TriggerFiles) - triggerFilesJson, err := json.Marshal(p.TriggerFiles) - if err != nil { - return false - } - filterFilesJson, err := json.Marshal(*params.TriggerFiles) - if err != nil { - return false - } - if string(triggerFilesJson) != string(filterFilesJson) { - return false - } - } - - return true -} diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index 62ca68b1ba..149afa52fb 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -4,9 +4,6 @@ package models import ( - "fmt" - "strings" - "github.com/daytonaio/daytona/pkg/gitprovider" ) @@ -32,22 +29,19 @@ func (w *Workspace) WorkspaceFolderName() string { return w.Name } -func (w Workspace) Hostname() string { - // Replace special chars with hyphen to form valid hostname - // String resulting in consecutive hyphens is also valid - workspaceId := w.Id - workspaceId = strings.ReplaceAll(workspaceId, "_", "-") - workspaceId = strings.ReplaceAll(workspaceId, "*", "-") - workspaceId = strings.ReplaceAll(workspaceId, ".", "-") - - hostname := fmt.Sprintf("ws-%s", workspaceId) +type BuildConfig struct { + Devcontainer *DevcontainerConfig `json:"devcontainer,omitempty" validate:"optional"` + CachedBuild *CachedBuild `json:"cachedBuild,omitempty" validate:"optional"` +} // @name BuildConfig - if len(hostname) > 63 { - return hostname[:63] - } +type DevcontainerConfig struct { + FilePath string `json:"filePath" validate:"required"` +} // @name DevcontainerConfig - return hostname -} +type CachedBuild struct { + User string `json:"user" validate:"required"` + Image string `json:"image" validate:"required"` +} // @name CachedBuild type WorkspaceInfo struct { Name string `json:"name" validate:"required"` diff --git a/pkg/models/workspace_config.go b/pkg/models/workspace_config.go index ab065928ab..30ae43b46e 100644 --- a/pkg/models/workspace_config.go +++ b/pkg/models/workspace_config.go @@ -4,7 +4,11 @@ package models import ( + "encoding/json" "errors" + "sort" + + "github.com/docker/docker/pkg/stringid" ) type WorkspaceConfig struct { @@ -77,3 +81,61 @@ func (wc *WorkspaceConfig) RemovePrebuild(id string) error { wc.Prebuilds = newPrebuilds return nil } + +// PrebuildConfig holds configuration for the prebuild process +type PrebuildConfig struct { + Id string `json:"id" validate:"required"` + Branch string `json:"branch" validate:"required"` + CommitInterval *int `json:"commitInterval" validate:"required"` + TriggerFiles []string `json:"triggerFiles" validate:"required"` + Retention int `json:"retention" validate:"required"` +} // @name PrebuildConfig + +func (p *PrebuildConfig) GenerateId() error { + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + + p.Id = id + return nil +} + +type MatchParams struct { + WorkspaceConfigName *string + Id *string + Branch *string + CommitInterval *int + TriggerFiles *[]string +} + +func (p *PrebuildConfig) Match(params *MatchParams) bool { + if params.Id != nil && *params.Id != p.Id { + return false + } + + if params.Branch != nil && *params.Branch != p.Branch { + return false + } + + if params.CommitInterval != nil && p.CommitInterval != nil && *params.CommitInterval != *p.CommitInterval { + return false + } + + if params.TriggerFiles != nil { + // Sort the trigger files before checking if same + sort.Strings(p.TriggerFiles) + sort.Strings(*params.TriggerFiles) + triggerFilesJson, err := json.Marshal(p.TriggerFiles) + if err != nil { + return false + } + filterFilesJson, err := json.Marshal(*params.TriggerFiles) + if err != nil { + return false + } + if string(triggerFilesJson) != string(filterFilesJson) { + return false + } + } + + return true +} diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index e9d035a4a9..8ed8d9f651 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -17,7 +17,6 @@ import ( "github.com/daytonaio/daytona/pkg/models" os_util "github.com/daytonaio/daytona/pkg/os" . "github.com/daytonaio/daytona/pkg/provider" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/shirou/gopsutil/process" @@ -50,15 +49,16 @@ type IProviderManager interface { } type ProviderManagerConfig struct { + GetTargetConfigMap func(ctx context.Context) (map[string]*models.TargetConfig, error) + CreateTargetConfig func(ctx context.Context, targetConfig *models.TargetConfig) error + CreateProviderNetworkKey func(ctx context.Context, providerName string) (string, error) DaytonaDownloadUrl string ServerUrl string ServerVersion string ApiUrl string LogsDir string - TargetConfigService targetconfigs.ITargetConfigService RegistryUrl string BaseDir string - CreateProviderNetworkKey func(providerName string) (string, error) ServerPort uint32 ApiPort uint32 } @@ -71,7 +71,8 @@ func NewProviderManager(config ProviderManagerConfig) *ProviderManager { serverVersion: config.ServerVersion, apiUrl: config.ApiUrl, logsDir: config.LogsDir, - targetConfigService: config.TargetConfigService, + getTargetConfigMap: config.GetTargetConfigMap, + createTargetConfig: config.CreateTargetConfig, registryUrl: config.RegistryUrl, baseDir: config.BaseDir, createProviderNetworkKey: config.CreateProviderNetworkKey, @@ -82,6 +83,9 @@ func NewProviderManager(config ProviderManagerConfig) *ProviderManager { type ProviderManager struct { pluginRefs map[string]*pluginRef + getTargetConfigMap func(ctx context.Context) (map[string]*models.TargetConfig, error) + createTargetConfig func(ctx context.Context, targetConfig *models.TargetConfig) error + createProviderNetworkKey func(ctx context.Context, providerName string) (string, error) daytonaDownloadUrl string serverUrl string serverVersion string @@ -89,10 +93,8 @@ type ProviderManager struct { serverPort uint32 apiPort uint32 logsDir string - targetConfigService targetconfigs.ITargetConfigService registryUrl string baseDir string - createProviderNetworkKey func(providerName string) (string, error) } func (m *ProviderManager) GetProvider(name string) (*Provider, error) { @@ -134,6 +136,8 @@ func (m *ProviderManager) GetProviders() map[string]Provider { } func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool) error { + ctx := context.Background() + pluginRef, err := m.initializeProvider(pluginPath) if err != nil { return err @@ -154,7 +158,7 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool return err } - existingTargetConfigs, err := m.targetConfigService.Map() + existingTargetConfigs, err := m.getTargetConfigMap(ctx) if err != nil { return errors.New("failed to get target configs: " + err.Error()) } @@ -171,7 +175,7 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool continue } - err = m.targetConfigService.Save(&models.TargetConfig{ + err = m.createTargetConfig(ctx, &models.TargetConfig{ Name: targetConfig.Name, ProviderInfo: models.ProviderInfo{ Name: providerInfo.Name, @@ -268,6 +272,8 @@ func (m *ProviderManager) Purge() error { } func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, error) { + ctx := context.Background() + pluginName := filepath.Base(pluginPath) pluginBasePath := filepath.Dir(pluginPath) @@ -304,7 +310,7 @@ func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, err return nil, errors.New("failed to initialize provider: " + err.Error()) } - networkKey, err := m.createProviderNetworkKey(pluginName) + networkKey, err := m.createProviderNetworkKey(ctx, pluginName) if err != nil { return nil, errors.New("failed to create network key: " + err.Error()) } diff --git a/pkg/server/apikeys/service.go b/pkg/server/apikeys/service.go index 67680ba882..31917a20a6 100644 --- a/pkg/server/apikeys/service.go +++ b/pkg/server/apikeys/service.go @@ -3,27 +3,21 @@ package apikeys -import "github.com/daytonaio/daytona/pkg/models" - -type IApiKeyService interface { - Generate(keyType models.ApiKeyType, name string) (string, error) - IsWorkspaceApiKey(apiKey string) bool - IsTargetApiKey(apiKey string) bool - IsValidApiKey(apiKey string) bool - ListClientKeys() ([]*models.ApiKey, error) - Revoke(name string) error -} +import ( + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" +) type ApiKeyServiceConfig struct { - ApiKeyStore ApiKeyStore + ApiKeyStore stores.ApiKeyStore } -func NewApiKeyService(config ApiKeyServiceConfig) IApiKeyService { +func NewApiKeyService(config ApiKeyServiceConfig) services.IApiKeyService { return &ApiKeyService{ apiKeyStore: config.ApiKeyStore, } } type ApiKeyService struct { - apiKeyStore ApiKeyStore + apiKeyStore stores.ApiKeyStore } diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index d3d62ca6d8..4e49149558 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -9,6 +9,8 @@ import ( t_apikeys "github.com/daytonaio/daytona/internal/testing/server/apikeys" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/apikeys" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) @@ -17,8 +19,8 @@ var workspaceKeyNames []string = []string{"workspace1", "workspace2"} type ApiKeyServiceTestSuite struct { suite.Suite - apiKeyService apikeys.IApiKeyService - apiKeyStore apikeys.ApiKeyStore + apiKeyService services.IApiKeyService + apiKeyStore stores.ApiKeyStore } func NewApiKeyServiceTestSuite() *ApiKeyServiceTestSuite { diff --git a/pkg/server/builds/dto/builds.go b/pkg/server/builds/dto/builds.go deleted file mode 100644 index f307d62f70..0000000000 --- a/pkg/server/builds/dto/builds.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/models" -) - -type BuildCreationData struct { - Image string `json:"image" validate:"required"` - User string `json:"user" validate:"required"` - BuildConfig *models.BuildConfig `json:"buildConfig" validate:"optional"` - Repository *gitprovider.GitRepository `json:"repository" validate:"optional"` - EnvVars map[string]string `json:"envVars" validate:"required"` - PrebuildId string `json:"prebuildId" validate:"required"` -} // @name BuildCreationData diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index a7a7b323cd..d6c2390cdd 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -4,61 +4,74 @@ package builds import ( + "context" "errors" "io" "time" + "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/docker/docker/pkg/stringid" ) -type IBuildService interface { - Create(dto.BuildCreationData) (string, error) - Find(filter *BuildFilter) (*models.Build, error) - List(filter *BuildFilter) ([]*models.Build, error) - MarkForDeletion(filter *BuildFilter, force bool) []error - Delete(id string) error - AwaitEmptyList(time.Duration) error - GetBuildLogReader(buildId string) (io.Reader, error) -} - type BuildServiceConfig struct { - BuildStore BuildStore - LoggerFactory logs.LoggerFactory + BuildStore stores.BuildStore + FindWorkspaceConfig func(ctx context.Context, name string) (*models.WorkspaceConfig, error) + GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) + LoggerFactory logs.LoggerFactory } type BuildService struct { - buildStore BuildStore - loggerFactory logs.LoggerFactory + buildStore stores.BuildStore + findWorkspaceConfig func(ctx context.Context, name string) (*models.WorkspaceConfig, error) + getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) + loggerFactory logs.LoggerFactory } -func NewBuildService(config BuildServiceConfig) IBuildService { +func NewBuildService(config BuildServiceConfig) services.IBuildService { return &BuildService{ - buildStore: config.BuildStore, - loggerFactory: config.LoggerFactory, + buildStore: config.BuildStore, + findWorkspaceConfig: config.FindWorkspaceConfig, + getRepositoryContext: config.GetRepositoryContext, + loggerFactory: config.LoggerFactory, } } -func (s *BuildService) Create(b dto.BuildCreationData) (string, error) { - var newBuild models.Build - +func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { id := stringid.GenerateRandomID() id = stringid.TruncateID(id) + ctx := context.Background() + + workspaceConfig, err := s.findWorkspaceConfig(ctx, b.WorkspaceConfigName) + if err != nil { + return "", err + } + + repo, err := s.getRepositoryContext(ctx, workspaceConfig.RepositoryUrl, b.Branch) + if err != nil { + return "", err + } + + newBuild := models.Build{ + Id: id, + State: models.BuildStatePendingRun, + ContainerConfig: models.ContainerConfig{ + Image: workspaceConfig.Image, + User: workspaceConfig.User, + }, + BuildConfig: workspaceConfig.BuildConfig, + Repository: repo, + EnvVars: b.EnvVars, + } - newBuild.Id = id - newBuild.State = models.BuildStatePendingRun - newBuild.ContainerConfig = models.ContainerConfig{ - Image: b.Image, - User: b.User, + if b.PrebuildId != nil { + newBuild.PrebuildId = *b.PrebuildId } - newBuild.BuildConfig = b.BuildConfig - newBuild.Repository = b.Repository - newBuild.EnvVars = b.EnvVars - newBuild.PrebuildId = b.PrebuildId - err := s.buildStore.Save(&newBuild) + err = s.buildStore.Save(&newBuild) if err != nil { return "", err } @@ -66,15 +79,15 @@ func (s *BuildService) Create(b dto.BuildCreationData) (string, error) { return id, nil } -func (s *BuildService) Find(filter *BuildFilter) (*models.Build, error) { +func (s *BuildService) Find(filter *stores.BuildFilter) (*models.Build, error) { return s.buildStore.Find(filter) } -func (s *BuildService) List(filter *BuildFilter) ([]*models.Build, error) { +func (s *BuildService) List(filter *stores.BuildFilter) ([]*models.Build, error) { return s.buildStore.List(filter) } -func (s *BuildService) MarkForDeletion(filter *BuildFilter, force bool) []error { +func (s *BuildService) MarkForDeletion(filter *stores.BuildFilter, force bool) []error { var errors []error builds, err := s.List(filter) diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 2ed1cd1fc6..74b3502510 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -10,7 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/builds/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) @@ -77,8 +78,8 @@ var expectedFilteredBuildsMap map[string]*models.Build type BuildServiceTestSuite struct { suite.Suite - buildService builds.IBuildService - buildStore builds.BuildStore + buildService services.IBuildService + buildStore stores.BuildStore } func NewBuildServiceTestSuite() *BuildServiceTestSuite { @@ -130,7 +131,7 @@ func (s *BuildServiceTestSuite) TestList() { func (s *BuildServiceTestSuite) TestFind() { require := s.Require() - build, err := s.buildService.Find(&builds.BuildFilter{ + build, err := s.buildService.Find(&stores.BuildFilter{ Id: &build1.Id, }) require.Nil(err) @@ -142,13 +143,12 @@ func (s *BuildServiceTestSuite) TestSave() { require := s.Require() - createBuildDto := dto.BuildCreationData{ - Image: build4.ContainerConfig.Image, - User: build4.ContainerConfig.User, - BuildConfig: build4.BuildConfig, - Repository: build4.Repository, - EnvVars: build4.EnvVars, - PrebuildId: build4.PrebuildId, + // FIXME: fix me + createBuildDto := services.CreateBuildDTO{ + WorkspaceConfigName: "workspaceConfigName", + Branch: "branch", + PrebuildId: &build4.PrebuildId, + EnvVars: build4.EnvVars, } _, err := s.buildService.Create(createBuildDto) @@ -164,12 +164,12 @@ func (s *BuildServiceTestSuite) TestMarkForDeletion() { require := s.Require() - err := s.buildService.MarkForDeletion(&builds.BuildFilter{ + err := s.buildService.MarkForDeletion(&stores.BuildFilter{ Id: &build3.Id, }, false) require.Nil(err) - b, errs := s.buildService.Find(&builds.BuildFilter{ + b, errs := s.buildService.Find(&stores.BuildFilter{ Id: &build3.Id, }) require.Nil(errs) diff --git a/pkg/server/containerregistries/service.go b/pkg/server/containerregistries/service.go index df4ea2a311..95f2e7b149 100644 --- a/pkg/server/containerregistries/service.go +++ b/pkg/server/containerregistries/service.go @@ -7,26 +7,19 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" ) -type IContainerRegistryService interface { - Delete(server string) error - Find(server string) (*models.ContainerRegistry, error) - FindByImageName(imageName string) (*models.ContainerRegistry, error) - List() ([]*models.ContainerRegistry, error) - Map() (map[string]*models.ContainerRegistry, error) - Save(cr *models.ContainerRegistry) error -} - type ContainerRegistryServiceConfig struct { - Store ContainerRegistryStore + Store stores.ContainerRegistryStore } type ContainerRegistryService struct { - store ContainerRegistryStore + store stores.ContainerRegistryStore } -func NewContainerRegistryService(config ContainerRegistryServiceConfig) IContainerRegistryService { +func NewContainerRegistryService(config ContainerRegistryServiceConfig) services.IContainerRegistryService { return &ContainerRegistryService{ store: config.Store, } diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index 76d8cead50..83ef4eba30 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -3,26 +3,20 @@ package gitproviders +import "context" + func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { + ctx := context.Background() + gitProvider, err := s.configStore.Find(gitProviderId) if err != nil { return err } - // Check if workspace configs need to be updated - workspaceConfigs, err := s.workspaceConfigStore.List(gitProviderId) - + err = s.detachWorkspaceConfigs(ctx, gitProvider.Id) if err != nil { return err } - for _, workspaceConfig := range workspaceConfigs { - workspaceConfig.GitProviderConfigId = nil - err = s.workspaceConfigStore.Save(workspaceConfig) - if err != nil { - return err - } - } - return s.configStore.Delete(gitProvider) } diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index 783eb6daa6..3b131dd13e 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -4,49 +4,32 @@ package gitproviders import ( + "context" "errors" "fmt" - "net/http" "strings" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" ) -type IGitProviderService interface { - GetConfig(id string) (*models.GitProviderConfig, error) - ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) - GetGitProvider(id string) (gitprovider.GitProvider, error) - GetGitProviderForUrl(url string) (gitprovider.GitProvider, string, error) - GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) - GetGitUser(gitProviderId string) (*gitprovider.GitUser, error) - GetNamespaces(gitProviderId string, options gitprovider.ListOptions) ([]*gitprovider.GitNamespace, error) - GetRepoBranches(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) - GetRepoPRs(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) - GetRepositories(gitProviderId string, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) - ListConfigs() ([]*models.GitProviderConfig, error) - RemoveGitProvider(gitProviderId string) error - SetGitProviderConfig(providerConfig *models.GitProviderConfig) error - GetLastCommitSha(repo *gitprovider.GitRepository) (string, error) - RegisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) - GetPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) - UnregisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, id string) error -} - type GitProviderServiceConfig struct { - ConfigStore GitProviderConfigStore - WorkspaceConfigStore WorkspaceConfigStore + ConfigStore stores.GitProviderConfigStore + + DetachWorkspaceConfigs func(ctx context.Context, gitProviderConfigId string) error } type GitProviderService struct { - configStore GitProviderConfigStore - workspaceConfigStore WorkspaceConfigStore + configStore stores.GitProviderConfigStore + detachWorkspaceConfigs func(ctx context.Context, gitProviderConfigId string) error } -func NewGitProviderService(config GitProviderServiceConfig) IGitProviderService { +func NewGitProviderService(config GitProviderServiceConfig) services.IGitProviderService { return &GitProviderService{ - configStore: config.ConfigStore, - workspaceConfigStore: config.WorkspaceConfigStore, + configStore: config.ConfigStore, + detachWorkspaceConfigs: config.DetachWorkspaceConfigs, } } @@ -56,7 +39,7 @@ func (s *GitProviderService) GetGitProvider(id string) (gitprovider.GitProvider, providerConfig, err := s.configStore.Find(id) if err != nil { // If config is not defined, use the default (public) client without token - if IsGitProviderNotFound(err) { + if stores.IsGitProviderNotFound(err) { providerConfig = &models.GitProviderConfig{ Id: id, ProviderId: id, diff --git a/pkg/server/gitproviders/util/workspace_config_store.go b/pkg/server/gitproviders/util/workspace_config_store.go deleted file mode 100644 index 284c48a5f7..0000000000 --- a/pkg/server/gitproviders/util/workspace_config_store.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package uitl - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" -) - -type store struct { - store workspaceconfigs.WorkspaceConfigStore -} - -func (s *store) Save(workspaceConfig *models.WorkspaceConfig) error { - return s.store.Save(workspaceConfig) -} - -func (s *store) List(gitProviderConfigId string) ([]*models.WorkspaceConfig, error) { - return s.store.List(&workspaceconfigs.WorkspaceConfigFilter{ - GitProviderConfigId: &gitProviderConfigId, - }) -} - -func FromWorkspaceConfigStore(workspaceConfigStore workspaceconfigs.WorkspaceConfigStore) gitproviders.WorkspaceConfigStore { - return &store{ - store: workspaceConfigStore, - } -} diff --git a/pkg/server/profiledata/service.go b/pkg/server/profiledata/service.go index 920658aef0..926d7b23fd 100644 --- a/pkg/server/profiledata/service.go +++ b/pkg/server/profiledata/service.go @@ -5,31 +5,27 @@ package profiledata import ( "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" ) -type IProfileDataService interface { - Get(id string) (*models.ProfileData, error) - Save(profileData *models.ProfileData) error - Delete(id string) error -} - type ProfileDataServiceConfig struct { - ProfileDataStore ProfileDataStore + ProfileDataStore stores.ProfileDataStore } -func NewProfileDataService(config ProfileDataServiceConfig) IProfileDataService { +func NewProfileDataService(config ProfileDataServiceConfig) services.IProfileDataService { return &ProfileDataService{ profileDataStore: config.ProfileDataStore, } } type ProfileDataService struct { - profileDataStore ProfileDataStore + profileDataStore stores.ProfileDataStore } func (s *ProfileDataService) Get(id string) (*models.ProfileData, error) { if id == "" { - id = ProfileDataId + id = stores.ProfileDataId } return s.profileDataStore.Get(id) @@ -37,7 +33,7 @@ func (s *ProfileDataService) Get(id string) (*models.ProfileData, error) { func (s *ProfileDataService) Save(profileData *models.ProfileData) error { if profileData.Id == "" { - profileData.Id = ProfileDataId + profileData.Id = stores.ProfileDataId } return s.profileDataStore.Save(profileData) @@ -45,7 +41,7 @@ func (s *ProfileDataService) Save(profileData *models.ProfileData) error { func (s *ProfileDataService) Delete(id string) error { if id == "" { - id = ProfileDataId + id = stores.ProfileDataId } return s.profileDataStore.Delete(id) diff --git a/pkg/server/profiledata/service_test.go b/pkg/server/profiledata/service_test.go index 6841936a08..df523162e0 100644 --- a/pkg/server/profiledata/service_test.go +++ b/pkg/server/profiledata/service_test.go @@ -9,13 +9,15 @@ import ( t_profiledata "github.com/daytonaio/daytona/internal/testing/server/profiledata" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/profiledata" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) type ProfileDataServiceTestSuite struct { suite.Suite - profileDataService profiledata.IProfileDataService - profileDataStore profiledata.ProfileDataStore + profileDataService services.IProfileDataService + profileDataStore stores.ProfileDataStore } func NewApiKeyServiceTestSuite() *ProfileDataServiceTestSuite { @@ -36,7 +38,7 @@ func TestApiKeyService(t *testing.T) { func (s *ProfileDataServiceTestSuite) TestReturnsProfileDataNotFound() { profileData, err := s.profileDataService.Get("") s.Require().Nil(profileData) - s.Require().True(profiledata.IsProfileDataNotFound(err)) + s.Require().True(stores.IsProfileDataNotFound(err)) } func (s *ProfileDataServiceTestSuite) TestSaveProfileData() { @@ -70,5 +72,5 @@ func (s *ProfileDataServiceTestSuite) TestDeleteProfileData() { profileDataFromStore, err := s.profileDataStore.Get("") s.Require().Nil(profileDataFromStore) - s.Require().True(profiledata.IsProfileDataNotFound(err)) + s.Require().True(stores.IsProfileDataNotFound(err)) } diff --git a/pkg/server/server.go b/pkg/server/server.go index 7b70285d89..9f50f858b1 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -8,15 +8,7 @@ import ( "os/signal" "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/server/apikeys" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/profiledata" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" - "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/hashicorp/go-plugin" @@ -27,17 +19,17 @@ type ServerInstanceConfig struct { Config Config Version string TailscaleServer TailscaleServer - TargetConfigService targetconfigs.ITargetConfigService - ContainerRegistryService containerregistries.IContainerRegistryService - BuildService builds.IBuildService - WorkspaceConfigService workspaceconfigs.IWorkspaceConfigService - WorkspaceService workspaces.IWorkspaceService + TargetConfigService services.ITargetConfigService + ContainerRegistryService services.IContainerRegistryService + BuildService services.IBuildService + WorkspaceConfigService services.IWorkspaceConfigService + WorkspaceService services.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry - TargetService targets.ITargetService - ApiKeyService apikeys.IApiKeyService - GitProviderService gitproviders.IGitProviderService + TargetService services.ITargetService + ApiKeyService services.IApiKeyService + GitProviderService services.IGitProviderService ProviderManager manager.IProviderManager - ProfileDataService profiledata.IProfileDataService + ProfileDataService services.IProfileDataService TelemetryService telemetry.TelemetryService } @@ -80,17 +72,17 @@ type Server struct { config Config Version string TailscaleServer TailscaleServer - TargetConfigService targetconfigs.ITargetConfigService - ContainerRegistryService containerregistries.IContainerRegistryService - BuildService builds.IBuildService - WorkspaceConfigService workspaceconfigs.IWorkspaceConfigService - WorkspaceService workspaces.IWorkspaceService + TargetConfigService services.ITargetConfigService + ContainerRegistryService services.IContainerRegistryService + BuildService services.IBuildService + WorkspaceConfigService services.IWorkspaceConfigService + WorkspaceService services.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry - TargetService targets.ITargetService - ApiKeyService apikeys.IApiKeyService - GitProviderService gitproviders.IGitProviderService + TargetService services.ITargetService + ApiKeyService services.IApiKeyService + GitProviderService services.IGitProviderService ProviderManager manager.IProviderManager - ProfileDataService profiledata.IProfileDataService + ProfileDataService services.IProfileDataService TelemetryService telemetry.TelemetryService } diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index 0c860934c6..f4af8f801c 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -5,31 +5,25 @@ package targetconfigs import ( "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" ) -type ITargetConfigService interface { - Delete(targetConfig *models.TargetConfig) error - Find(filter *TargetConfigFilter) (*models.TargetConfig, error) - List(filter *TargetConfigFilter) ([]*models.TargetConfig, error) - Map() (map[string]*models.TargetConfig, error) - Save(targetConfig *models.TargetConfig) error -} - type TargetConfigServiceConfig struct { - TargetConfigStore TargetConfigStore + TargetConfigStore stores.TargetConfigStore } type TargetConfigService struct { - targetConfigStore TargetConfigStore + targetConfigStore stores.TargetConfigStore } -func NewTargetConfigService(config TargetConfigServiceConfig) ITargetConfigService { +func NewTargetConfigService(config TargetConfigServiceConfig) services.ITargetConfigService { return &TargetConfigService{ targetConfigStore: config.TargetConfigStore, } } -func (s *TargetConfigService) List(filter *TargetConfigFilter) ([]*models.TargetConfig, error) { +func (s *TargetConfigService) List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { return s.targetConfigStore.List(filter) } @@ -47,7 +41,7 @@ func (s *TargetConfigService) Map() (map[string]*models.TargetConfig, error) { return targetConfigs, nil } -func (s *TargetConfigService) Find(filter *TargetConfigFilter) (*models.TargetConfig, error) { +func (s *TargetConfigService) Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) { return s.targetConfigStore.Find(filter) } diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go index efc5d9e4ae..05298f0f73 100644 --- a/pkg/server/targetconfigs/service_test.go +++ b/pkg/server/targetconfigs/service_test.go @@ -9,6 +9,8 @@ import ( t_targetconfigs "github.com/daytonaio/daytona/internal/testing/server/targetconfigs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) @@ -53,8 +55,8 @@ var expectedConfigMap map[string]*models.TargetConfig type TargetConfigServiceTestSuite struct { suite.Suite - targetConfigService targetconfigs.ITargetConfigService - targetConfigStore targetconfigs.TargetConfigStore + targetConfigService services.ITargetConfigService + targetConfigStore stores.TargetConfigStore } func NewTargetConfigServiceTestSuite() *TargetConfigServiceTestSuite { @@ -105,7 +107,7 @@ func (s *TargetConfigServiceTestSuite) TestMap() { func (s *TargetConfigServiceTestSuite) TestFind() { require := s.Require() - targetConfig, err := s.targetConfigService.Find(&targetconfigs.TargetConfigFilter{ + targetConfig, err := s.targetConfigService.Find(&stores.TargetConfigFilter{ Name: &targetConfig1.Name, }) require.Nil(err) diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index 60a91e29cf..cde279459d 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" @@ -36,12 +36,12 @@ func isValidTargetName(name string) bool { } func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) { - _, err := s.targetStore.Find(&TargetFilter{IdOrName: &req.Id}) + _, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &req.Id}) if err == nil { return nil, ErrTargetAlreadyExists } - tc, err := s.targetConfigStore.Find(&targetconfigs.TargetConfigFilter{Name: &req.TargetConfigName}) + tc, err := s.findTargetConfig(ctx, req.TargetConfigName) if err != nil { return s.handleCreateError(ctx, nil, err) } @@ -58,7 +58,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT Options: tc.Options, } - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeTarget, tg.Id) + apiKey, err := s.generateApiKey(ctx, tg.Id) if err != nil { return s.handleCreateError(ctx, nil, err) } diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index cad61862b0..24f8814223 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -11,10 +11,11 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *TargetService) GetTarget(ctx context.Context, filter *TargetFilter, verbose bool) (*dto.TargetDTO, error) { +func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, verbose bool) (*dto.TargetDTO, error) { tg, err := s.targetStore.Find(filter) if err != nil { return nil, ErrTargetNotFound diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index d20f2cac2e..b46796baab 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -12,10 +12,11 @@ import ( "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *TargetService) ListTargets(ctx context.Context, filter *TargetFilter, verbose bool) ([]dto.TargetDTO, error) { +func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, verbose bool) ([]dto.TargetDTO, error) { targets, err := s.targetStore.List(filter) if err != nil { return nil, err diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 48338e03b2..cec25ea88f 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -8,12 +8,13 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, target, ErrTargetNotFound) } @@ -26,7 +27,7 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error } // Should not fail the whole operation if the API key cannot be revoked - err = s.apiKeyService.Revoke(target.Id) + err = s.revokeApiKey(ctx, target.Id) if err != nil { log.Error(err) } @@ -45,7 +46,7 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error // ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, nil, ErrTargetNotFound) } @@ -57,7 +58,7 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) log.Error(err) } - err = s.apiKeyService.Revoke(target.Id) + err = s.revokeApiKey(ctx, target.Id) if err != nil { log.Error(err) } diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 73202997bb..836bd0b234 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -10,64 +10,53 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/apikeys" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" ) -type ITargetService interface { - CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) - GetTarget(ctx context.Context, filter *TargetFilter, verbose bool) (*dto.TargetDTO, error) - GetTargetLogReader(targetId string) (io.Reader, error) - ListTargets(ctx context.Context, filter *TargetFilter, verbose bool) ([]dto.TargetDTO, error) - StartTarget(ctx context.Context, targetId string) error - StopTarget(ctx context.Context, targetId string) error - SetDefault(ctx context.Context, targetId string) error - RemoveTarget(ctx context.Context, targetId string) error - ForceRemoveTarget(ctx context.Context, targetId string) error -} +type TargetServiceConfig struct { + TargetStore stores.TargetStore -type targetConfigStore interface { - Find(filter *targetconfigs.TargetConfigFilter) (*models.TargetConfig, error) -} + FindTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) + GenerateApiKey func(ctx context.Context, name string) (string, error) + RevokeApiKey func(ctx context.Context, name string) error -type TargetServiceConfig struct { - TargetStore TargetStore - TargetConfigStore targetConfigStore - ServerApiUrl string - ServerUrl string - ServerVersion string - Provisioner provisioner.IProvisioner - ApiKeyService apikeys.IApiKeyService - LoggerFactory logs.LoggerFactory - TelemetryService telemetry.TelemetryService + ServerApiUrl string + ServerUrl string + ServerVersion string + Provisioner provisioner.IProvisioner + LoggerFactory logs.LoggerFactory + TelemetryService telemetry.TelemetryService } -func NewTargetService(config TargetServiceConfig) ITargetService { +func NewTargetService(config TargetServiceConfig) services.ITargetService { return &TargetService{ - targetStore: config.TargetStore, - targetConfigStore: config.TargetConfigStore, - serverApiUrl: config.ServerApiUrl, - serverUrl: config.ServerUrl, - serverVersion: config.ServerVersion, - provisioner: config.Provisioner, - loggerFactory: config.LoggerFactory, - apiKeyService: config.ApiKeyService, - telemetryService: config.TelemetryService, + targetStore: config.TargetStore, + findTargetConfig: config.FindTargetConfig, + generateApiKey: config.GenerateApiKey, + revokeApiKey: config.RevokeApiKey, + serverApiUrl: config.ServerApiUrl, + serverUrl: config.ServerUrl, + serverVersion: config.ServerVersion, + provisioner: config.Provisioner, + loggerFactory: config.LoggerFactory, + telemetryService: config.TelemetryService, } } type TargetService struct { - targetStore TargetStore - targetConfigStore targetConfigStore - provisioner provisioner.IProvisioner - apiKeyService apikeys.IApiKeyService - serverApiUrl string - serverUrl string - serverVersion string - loggerFactory logs.LoggerFactory - telemetryService telemetry.TelemetryService + targetStore stores.TargetStore + findTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) + generateApiKey func(ctx context.Context, name string) (string, error) + revokeApiKey func(ctx context.Context, name string) error + + provisioner provisioner.IProvisioner + serverApiUrl string + serverUrl string + serverVersion string + loggerFactory logs.LoggerFactory + telemetryService telemetry.TelemetryService } func (s *TargetService) GetTargetLogReader(targetId string) (io.Reader, error) { diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 1294b2d2a0..fe19aadac0 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -15,6 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -77,13 +78,20 @@ func TestTargetService(t *testing.T) { buildLogsDir := t.TempDir() service := targets.NewTargetService(targets.TargetServiceConfig{ - TargetStore: targetStore, - TargetConfigStore: targetConfigStore, - ServerApiUrl: serverApiUrl, - ServerUrl: serverUrl, - ApiKeyService: apiKeyService, - Provisioner: mockProvisioner, - LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), + TargetStore: targetStore, + FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { + return targetConfigStore.Find(&stores.TargetConfigFilter{Name: &name}) + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(models.ApiKeyTypeTarget, name) + }, + RevokeApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Revoke(name) + }, + ServerApiUrl: serverApiUrl, + ServerUrl: serverUrl, + Provisioner: mockProvisioner, + LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), }) t.Run("CreateTarget", func(t *testing.T) { @@ -115,7 +123,7 @@ func TestTargetService(t *testing.T) { t.Run("GetTarget", func(t *testing.T) { mockProvisioner.On("GetTargetInfo", mock.Anything, tg).Return(&targetInfo, nil) - target, err := service.GetTarget(ctx, &targets.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + target, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Nil(t, err) require.NotNil(t, target) @@ -124,7 +132,7 @@ func TestTargetService(t *testing.T) { }) t.Run("GetTarget fails when target not found", func(t *testing.T) { - _, err := service.GetTarget(ctx, &targets.TargetFilter{IdOrName: util.Pointer("invalid-id")}, true) + _, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, true) require.NotNil(t, err) require.Equal(t, targets.ErrTargetNotFound, err) }) @@ -184,7 +192,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetTarget(ctx, &targets.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Equal(t, targets.ErrTargetNotFound, err) }) @@ -199,7 +207,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetTarget(ctx, &targets.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, true) require.Equal(t, targets.ErrTargetNotFound, err) }) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index bc710b2b63..9aebf60f34 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -9,17 +9,18 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/stores" ) func (s *TargetService) SetDefault(ctx context.Context, id string) error { - currentTarget, err := s.GetTarget(ctx, &TargetFilter{ + currentTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ IdOrName: &id, }, false) if err != nil || currentTarget == nil { return err } - defaultTarget, err := s.GetTarget(ctx, &TargetFilter{ + defaultTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ Default: util.Pointer(true), }, false) if err != nil && !IsTargetNotFound(err) { diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index ce22c2b93f..e9b4681b5b 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -10,6 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" @@ -18,7 +19,7 @@ import ( ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) + t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStartError(ctx, nil, ErrTargetNotFound) } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index c30e89f4b3..47afef24da 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -7,12 +7,13 @@ import ( "context" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStopError(ctx, nil, ErrTargetNotFound) } diff --git a/pkg/server/workspaceconfigs/prebuild.go b/pkg/server/workspaceconfigs/prebuild.go index 69bdb951b6..a89371959d 100644 --- a/pkg/server/workspaceconfigs/prebuild.go +++ b/pkg/server/workspaceconfigs/prebuild.go @@ -4,22 +4,23 @@ package workspaceconfigs import ( + "context" "errors" "fmt" "sort" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" - build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { - workspaceConfig, err := s.Find(&WorkspaceConfigFilter{ + ctx := context.Background() + + workspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { @@ -38,14 +39,7 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP return nil, errors.New("either the commit interval or trigger files must be specified") } - gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(workspaceConfig.RepositoryUrl) - if err != nil { - return nil, err - } - - repository, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: workspaceConfig.RepositoryUrl, - }) + repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceConfig.RepositoryUrl) if err != nil { return nil, err } @@ -74,13 +68,13 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP // Remember the new webhook ID in case config saving fails newWebhookId := "" - existingWebhookId, err := s.gitProviderService.GetPrebuildWebhook(gitProviderId, repository, s.prebuildWebhookEndpoint) + existingWebhookId, err := s.findPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) if err != nil { return nil, err } if existingWebhookId == nil { - newWebhookId, err = s.gitProviderService.RegisterPrebuildWebhook(gitProviderId, repository, s.prebuildWebhookEndpoint) + newWebhookId, err = s.registerPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) if err != nil { return nil, err } @@ -89,7 +83,7 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP err = s.configStore.Save(workspaceConfig) if err != nil { if newWebhookId != "" { - err = s.gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repository, newWebhookId) + err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, newWebhookId) if err != nil { log.Error(err) } @@ -108,10 +102,10 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP }, nil } -func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) (*dto.PrebuildDTO, error) { +func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { wc, err := s.configStore.Find(workspaceConfigFilter) if err != nil { - return nil, ErrWorkspaceConfigNotFound + return nil, stores.ErrWorkspaceConfigNotFound } prebuild, err := wc.FindPrebuild(&models.MatchParams{ @@ -135,11 +129,11 @@ func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *WorkspaceCo }, nil } -func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { var result []*dto.PrebuildDTO wcs, err := s.configStore.List(workspaceConfigFilter) if err != nil { - return nil, ErrWorkspaceConfigNotFound + return nil, stores.ErrWorkspaceConfigNotFound } for _, wc := range wcs { @@ -159,7 +153,9 @@ func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *WorkspaceC } func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id string, force bool) []error { - workspaceConfig, err := s.Find(&WorkspaceConfigFilter{ + ctx := context.Background() + + workspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { @@ -168,7 +164,7 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s // Get all prebuilds for this workspace config's repository URL and // if this is the last prebuild, unregister the Git provider webhook - prebuilds, err := s.ListPrebuilds(&WorkspaceConfigFilter{ + prebuilds, err := s.ListPrebuilds(&stores.WorkspaceConfigFilter{ Url: &workspaceConfig.RepositoryUrl, }, nil) if err != nil { @@ -176,19 +172,12 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s } if len(prebuilds) == 1 { - gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(workspaceConfig.RepositoryUrl) - if err != nil { - return []error{err} - } - - repository, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: workspaceConfig.RepositoryUrl, - }) + repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceConfig.RepositoryUrl) if err != nil { return []error{err} } - existingWebhookId, err := s.gitProviderService.GetPrebuildWebhook(gitProviderId, repository, s.prebuildWebhookEndpoint) + existingWebhookId, err := s.findPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) if err != nil { if force { log.Error(err) @@ -198,7 +187,7 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s } if existingWebhookId != nil { - err = s.gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repository, *existingWebhookId) + err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, *existingWebhookId) if err != nil { if force { log.Error(err) @@ -209,9 +198,7 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s } } - errs := s.buildService.MarkForDeletion(&builds.BuildFilter{ - PrebuildIds: &[]string{id}, - }, force) + errs := s.deleteBuilds(ctx, &id, nil, force) if len(errs) > 0 { if force { for _, err := range errs { @@ -235,23 +222,19 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s return nil } +// TODO: revise build trigger strategy +// We should discuss if the function should throw if the build can not be created or move on to the next one func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { - var buildsToTrigger []models.Build + ctx := context.Background() - workspaceConfigs, err := s.List(&WorkspaceConfigFilter{ + workspaceConfigs, err := s.List(&stores.WorkspaceConfigFilter{ Url: &data.Url, }) if err != nil { return err } - gitProvider, _, err := s.gitProviderService.GetGitProviderForUrl(data.Url) - if err != nil { - return fmt.Errorf("failed to get git provider for URL: %s", err) - } - repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: data.Url, - }) + repo, _, err := s.getRepositoryContext(ctx, data.Url) if err != nil { return fmt.Errorf("failed to get repository context: %s", err) } @@ -267,71 +250,34 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) // Check if the commit's affected files and prebuild config's trigger files have any overlap if len(prebuild.TriggerFiles) > 0 { if slicesHaveCommonEntry(prebuild.TriggerFiles, data.AffectedFiles) { - buildsToTrigger = append(buildsToTrigger, models.Build{ - ContainerConfig: models.ContainerConfig{ - Image: workspaceConfig.Image, - User: workspaceConfig.User, - }, - BuildConfig: workspaceConfig.BuildConfig, - Repository: repo, - EnvVars: workspaceConfig.EnvVars, - PrebuildId: prebuild.Id, - }) + err := s.createBuild(ctx, workspaceConfig, repo, prebuild.Id) + if err != nil { + return fmt.Errorf("failed to create build: %s", err) + } continue } } - newestBuild, err := s.buildService.Find(&builds.BuildFilter{ - PrebuildIds: &[]string{prebuild.Id}, - GetNewest: util.Pointer(true), - }) + newestBuild, err := s.findNewestBuild(ctx, prebuild.Id) if err != nil { - buildsToTrigger = append(buildsToTrigger, models.Build{ - ContainerConfig: models.ContainerConfig{ - Image: workspaceConfig.Image, - User: workspaceConfig.User, - }, - BuildConfig: workspaceConfig.BuildConfig, - Repository: repo, - EnvVars: workspaceConfig.EnvVars, - PrebuildId: prebuild.Id, - }) + err := s.createBuild(ctx, workspaceConfig, repo, prebuild.Id) + if err != nil { + return fmt.Errorf("failed to create build: %s", err) + } continue } - commitsRange, err := gitProvider.GetCommitsRange(repo, newestBuild.Repository.Sha, data.Sha) + commitsRange, err := s.getCommitsRange(ctx, repo, newestBuild.Repository.Sha, data.Sha) if err != nil { return fmt.Errorf("failed to get commits range: %s", err) } // Check if the commit interval has been reached if prebuild.CommitInterval != nil && commitsRange >= *prebuild.CommitInterval { - buildsToTrigger = append(buildsToTrigger, models.Build{ - ContainerConfig: models.ContainerConfig{ - Image: workspaceConfig.Image, - User: workspaceConfig.User, - }, - BuildConfig: workspaceConfig.BuildConfig, - Repository: repo, - EnvVars: workspaceConfig.EnvVars, - PrebuildId: prebuild.Id, - }) - } - } - - for _, build := range buildsToTrigger { - createBuildDto := build_dto.BuildCreationData{ - Image: build.ContainerConfig.Image, - User: build.ContainerConfig.User, - BuildConfig: build.BuildConfig, - Repository: build.Repository, - EnvVars: build.EnvVars, - PrebuildId: build.PrebuildId, - } - - _, err = s.buildService.Create(createBuildDto) - if err != nil { - return fmt.Errorf("failed to create build: %s", err) + err := s.createBuild(ctx, workspaceConfig, repo, prebuild.Id) + if err != nil { + return fmt.Errorf("failed to create build: %s", err) + } } } @@ -340,14 +286,14 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) // Marks the [retention] oldest published builds for deletion for each prebuild func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { + ctx := context.Background() + prebuilds, err := s.ListPrebuilds(nil, nil) if err != nil { return err } - existingBuilds, err := s.buildService.List(&builds.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePublished}, - }) + existingBuilds, err := s.listPublishedBuilds(ctx) if err != nil { return err } @@ -373,9 +319,7 @@ func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { // Mark the oldest builds for deletion for i := 0; i < numToDelete; i++ { - errs := s.buildService.MarkForDeletion(&builds.BuildFilter{ - Id: &associatedBuilds[i].Id, - }, false) + errs := s.deleteBuilds(ctx, &associatedBuilds[i].Id, nil, false) if len(errs) > 0 { for _, err := range errs { log.Error(err) diff --git a/pkg/server/workspaceconfigs/prebuild_test.go b/pkg/server/workspaceconfigs/prebuild_test.go index 04e6c65370..a74509341e 100644 --- a/pkg/server/workspaceconfigs/prebuild_test.go +++ b/pkg/server/workspaceconfigs/prebuild_test.go @@ -9,10 +9,9 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" - build_dto "github.com/daytonaio/daytona/pkg/server/builds/dto" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" ) var prebuild1 = &models.PrebuildConfig{ @@ -78,7 +77,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { }) require.Nil(err) - prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&workspaceconfigs.WorkspaceConfigFilter{ + prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&stores.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }, nil) require.Nil(err) @@ -88,9 +87,9 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { func (s *WorkspaceConfigServiceTestSuite) TestFindPrebuild() { require := s.Require() - prebuild, err := s.workspaceConfigService.FindPrebuild(&workspaceconfigs.WorkspaceConfigFilter{ + prebuild, err := s.workspaceConfigService.FindPrebuild(&stores.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, - }, &workspaceconfigs.PrebuildFilter{ + }, &stores.PrebuildFilter{ Id: &prebuild1.Id, }) require.Nil(err) @@ -99,7 +98,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestFindPrebuild() { func (s *WorkspaceConfigServiceTestSuite) TestListPrebuilds() { require := s.Require() - prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&workspaceconfigs.WorkspaceConfigFilter{ + prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&stores.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }, nil) require.Nil(err) @@ -112,14 +111,14 @@ func (s *WorkspaceConfigServiceTestSuite) TestDeletePrebuild() { require := s.Require() - s.buildService.On("MarkForDeletion", &builds.BuildFilter{ + s.buildService.On("MarkForDeletion", &stores.BuildFilter{ PrebuildIds: &[]string{prebuild2.Id}, }, false).Return([]error{}) err := s.workspaceConfigService.DeletePrebuild(workspaceConfig1.Name, prebuild2.Id, false) require.Nil(err) - prebuildDtos, errs := s.workspaceConfigService.ListPrebuilds(&workspaceconfigs.WorkspaceConfigFilter{ + prebuildDtos, errs := s.workspaceConfigService.ListPrebuilds(&stores.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }, nil) require.Nil(errs) @@ -136,14 +135,14 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventCommitInterval() { Url: repository1.Url, }).Return(repository1, nil) - s.buildService.On("Create", build_dto.BuildCreationData{ - PrebuildId: prebuild1.Id, - Repository: repository1, - User: workspaceConfig1.User, - Image: workspaceConfig1.Image, + s.buildService.On("Create", services.CreateBuildDTO{ + PrebuildId: &prebuild1.Id, + Branch: repository1.Branch, + WorkspaceConfigName: workspaceConfig1.Name, + EnvVars: workspaceConfig1.EnvVars, }).Return("", nil) - s.buildService.On("Find", &builds.BuildFilter{ + s.buildService.On("Find", &stores.BuildFilter{ PrebuildIds: &[]string{prebuild1.Id}, GetNewest: util.Pointer(true), }).Return(&models.Build{ @@ -174,11 +173,11 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { Url: repository1.Url, }).Return(repository1, nil) - s.buildService.On("Create", build_dto.BuildCreationData{ - PrebuildId: prebuild1.Id, - Repository: repository1, - User: workspaceConfig1.User, - Image: workspaceConfig1.Image, + s.buildService.On("Create", services.CreateBuildDTO{ + PrebuildId: &prebuild1.Id, + Branch: repository1.Branch, + WorkspaceConfigName: workspaceConfig1.Name, + EnvVars: workspaceConfig1.EnvVars, }).Return("", nil) data := gitprovider.GitEventData{ @@ -198,7 +197,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { func (s *WorkspaceConfigServiceTestSuite) TestEnforceRetentionPolicy() { require := s.Require() - s.buildService.On("List", &builds.BuildFilter{ + s.buildService.On("List", &stores.BuildFilter{ States: &[]models.BuildState{models.BuildStatePublished}, }).Return([]*models.Build{ { @@ -227,7 +226,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestEnforceRetentionPolicy() { }, }, nil) - s.buildService.On("MarkForDeletion", &builds.BuildFilter{ + s.buildService.On("MarkForDeletion", &stores.BuildFilter{ Id: util.Pointer("1"), }, false).Return([]error{}) diff --git a/pkg/server/workspaceconfigs/service.go b/pkg/server/workspaceconfigs/service.go index ad085537d4..3ebe41bf3e 100644 --- a/pkg/server/workspaceconfigs/service.go +++ b/pkg/server/workspaceconfigs/service.go @@ -4,73 +4,79 @@ package workspaceconfigs import ( + "context" "strings" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" ) -type IWorkspaceConfigService interface { - Save(workspaceConfig *models.WorkspaceConfig) error - Find(filter *WorkspaceConfigFilter) (*models.WorkspaceConfig, error) - List(filter *WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) - SetDefault(workspaceConfigName string) error - Delete(workspaceConfigName string, force bool) []error - - SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) - FindPrebuild(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) (*dto.PrebuildDTO, error) - ListPrebuilds(workspaceConfigFilter *WorkspaceConfigFilter, prebuildFilter *PrebuildFilter) ([]*dto.PrebuildDTO, error) - DeletePrebuild(workspaceConfigName string, id string, force bool) []error - - StartRetentionPoller() error - EnforceRetentionPolicy() error - ProcessGitEvent(gitprovider.GitEventData) error -} - type WorkspaceConfigServiceConfig struct { PrebuildWebhookEndpoint string - ConfigStore WorkspaceConfigStore - BuildService builds.IBuildService - GitProviderService gitproviders.IGitProviderService + ConfigStore stores.WorkspaceConfigStore + + FindNewestBuild func(ctx context.Context, prebuildId string) (*models.Build, error) + ListPublishedBuilds func(ctx context.Context) ([]*models.Build, error) + CreateBuild func(ctx context.Context, wc *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error + DeleteBuilds func(ctx context.Context, id, prebuildId *string, force bool) []error + GetRepositoryContext func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) + FindPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) + UnregisterPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error + RegisterPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) + GetCommitsRange func(ctx context.Context, repo *gitprovider.GitRepository, initialSha string, currentSha string) (int, error) } type WorkspaceConfigService struct { prebuildWebhookEndpoint string - configStore WorkspaceConfigStore - buildService builds.IBuildService - gitProviderService gitproviders.IGitProviderService + configStore stores.WorkspaceConfigStore + + findNewestBuild func(ctx context.Context, prebuildId string) (*models.Build, error) + listPublishedBuilds func(ctx context.Context) ([]*models.Build, error) + createBuild func(ctx context.Context, wc *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error + deleteBuilds func(ctx context.Context, id, prebuildId *string, force bool) []error + getRepositoryContext func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) + getCommitsRange func(ctx context.Context, repo *gitprovider.GitRepository, initialSha string, currentSha string) (int, error) + findPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) + unregisterPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error + registerPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) } -func NewWorkspaceConfigService(config WorkspaceConfigServiceConfig) IWorkspaceConfigService { +func NewWorkspaceConfigService(config WorkspaceConfigServiceConfig) services.IWorkspaceConfigService { return &WorkspaceConfigService{ - prebuildWebhookEndpoint: config.PrebuildWebhookEndpoint, - configStore: config.ConfigStore, - buildService: config.BuildService, - gitProviderService: config.GitProviderService, + prebuildWebhookEndpoint: config.PrebuildWebhookEndpoint, + configStore: config.ConfigStore, + findNewestBuild: config.FindNewestBuild, + listPublishedBuilds: config.ListPublishedBuilds, + createBuild: config.CreateBuild, + deleteBuilds: config.DeleteBuilds, + getRepositoryContext: config.GetRepositoryContext, + findPrebuildWebhook: config.FindPrebuildWebhook, + unregisterPrebuildWebhook: config.UnregisterPrebuildWebhook, + registerPrebuildWebhook: config.RegisterPrebuildWebhook, + getCommitsRange: config.GetCommitsRange, } } -func (s *WorkspaceConfigService) List(filter *WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { +func (s *WorkspaceConfigService) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { return s.configStore.List(filter) } func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { - workspaceConfig, err := s.Find(&WorkspaceConfigFilter{ + workspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { return err } - defaultWorkspaceConfig, err := s.Find(&WorkspaceConfigFilter{ + defaultWorkspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ Url: &workspaceConfig.RepositoryUrl, Default: util.Pointer(true), }) - if err != nil && !IsWorkspaceConfigNotFound(err) { + if err != nil && !stores.IsWorkspaceConfigNotFound(err) { return err } @@ -86,7 +92,7 @@ func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { return s.configStore.Save(workspaceConfig) } -func (s *WorkspaceConfigService) Find(filter *WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { +func (s *WorkspaceConfigService) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { if filter != nil && filter.Url != nil { cleanedUrl := util.CleanUpRepositoryUrl(*filter.Url) if !strings.HasSuffix(cleanedUrl, ".git") { @@ -109,7 +115,7 @@ func (s *WorkspaceConfigService) Save(workspaceConfig *models.WorkspaceConfig) e } func (s *WorkspaceConfigService) Delete(workspaceConfigName string, force bool) []error { - wc, err := s.Find(&WorkspaceConfigFilter{ + wc, err := s.Find(&stores.WorkspaceConfigFilter{ Name: &workspaceConfigName, }) if err != nil { diff --git a/pkg/server/workspaceconfigs/service_test.go b/pkg/server/workspaceconfigs/service_test.go index eab0ffe933..7b00caf581 100644 --- a/pkg/server/workspaceconfigs/service_test.go +++ b/pkg/server/workspaceconfigs/service_test.go @@ -4,14 +4,18 @@ package workspaceconfigs_test import ( + "context" "testing" git_provider_mock "github.com/daytonaio/daytona/internal/testing/gitprovider/mocks" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" workspaceconfig_internal "github.com/daytonaio/daytona/internal/testing/server/workspaceconfig" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) @@ -63,8 +67,8 @@ var expectedFilteredWorkspaceConfigsMap map[string]*models.WorkspaceConfig type WorkspaceConfigServiceTestSuite struct { suite.Suite - workspaceConfigService workspaceconfigs.IWorkspaceConfigService - workspaceConfigStore workspaceconfigs.WorkspaceConfigStore + workspaceConfigService services.IWorkspaceConfigService + workspaceConfigStore stores.WorkspaceConfigStore gitProviderService mocks.MockGitProviderService buildService mocks.MockBuildService gitProvider git_provider_mock.MockGitProvider @@ -113,9 +117,69 @@ func (s *WorkspaceConfigServiceTestSuite) SetupTest() { s.workspaceConfigStore = workspaceconfig_internal.NewInMemoryWorkspaceConfigStore() s.workspaceConfigService = workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ - ConfigStore: s.workspaceConfigStore, - GitProviderService: &s.gitProviderService, - BuildService: &s.buildService, + ConfigStore: s.workspaceConfigStore, + FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { + return s.buildService.Find(&stores.BuildFilter{ + PrebuildIds: &[]string{prebuildId}, + GetNewest: util.Pointer(true), + }) + }, + ListPublishedBuilds: func(ctx context.Context) ([]*models.Build, error) { + return s.buildService.List(&stores.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePublished}, + }) + }, + CreateBuild: func(ctx context.Context, workspaceConfig *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error { + createBuildDto := services.CreateBuildDTO{ + WorkspaceConfigName: workspaceConfig.Name, + Branch: repo.Branch, + PrebuildId: &prebuildId, + EnvVars: workspaceConfig.EnvVars, + } + + _, err := s.buildService.Create(createBuildDto) + return err + }, + DeleteBuilds: func(ctx context.Context, id, prebuildId *string, force bool) []error { + var prebuildIds *[]string + if prebuildId != nil { + prebuildIds = &[]string{*prebuildId} + } + + return s.buildService.MarkForDeletion(&stores.BuildFilter{ + Id: id, + PrebuildIds: prebuildIds, + }, force) + }, + GetRepositoryContext: func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) { + gitProvider, gitProviderId, err := s.gitProviderService.GetGitProviderForUrl(url) + if err != nil { + return nil, "", err + } + + repo, err = gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ + Url: url, + }) + + return repo, gitProviderId, err + }, + FindPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { + return s.gitProviderService.GetPrebuildWebhook(gitProviderId, repo, endpointUrl) + }, + UnregisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error { + return s.gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repo, id) + }, + RegisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { + return s.gitProviderService.RegisterPrebuildWebhook(gitProviderId, repo, endpointUrl) + }, + GetCommitsRange: func(ctx context.Context, repo *gitprovider.GitRepository, initialSha string, currentSha string) (int, error) { + gitProvider, _, err := s.gitProviderService.GetGitProviderForUrl(repo.Url) + if err != nil { + return 0, err + } + + return gitProvider.GetCommitsRange(repo, initialSha, currentSha) + }, }) for _, wc := range expectedWorkspaceConfigs { @@ -138,7 +202,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestList() { func (s *WorkspaceConfigServiceTestSuite) TestFind() { require := s.Require() - workspaceConfig, err := s.workspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ + workspaceConfig, err := s.workspaceConfigService.Find(&stores.WorkspaceConfigFilter{ Name: &workspaceConfig1.Name, }) require.Nil(err) @@ -150,7 +214,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetDefault() { err := s.workspaceConfigService.SetDefault(workspaceConfig2.Name) require.Nil(err) - workspaceConfig, err := s.workspaceConfigService.Find(&workspaceconfigs.WorkspaceConfigFilter{ + workspaceConfig, err := s.workspaceConfigService.Find(&stores.WorkspaceConfigFilter{ Url: util.Pointer(workspaceConfig1.RepositoryUrl), Default: util.Pointer(true), }) diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index a898d448e7..57f6a281a8 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -10,15 +10,11 @@ import ( "regexp" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" @@ -42,18 +38,18 @@ func isValidWorkspaceName(name string) bool { return true } -func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*models.Workspace, error) { +func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.CreateWorkspaceDTO) (*models.Workspace, error) { _, err := s.workspaceStore.Find(req.Name) if err == nil { return s.handleCreateError(ctx, nil, ErrWorkspaceAlreadyExists) } - target, err := s.targetStore.Find(&targets.TargetFilter{IdOrName: &req.TargetId}) + target, err := s.findTarget(ctx, req.TargetId) if err != nil { return s.handleCreateError(ctx, nil, err) } - w := conversion.CreateDtoToWorkspace(req) + w := req.ToWorkspace() w.Target = *target if !isValidWorkspaceName(w.Name) { @@ -62,7 +58,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo w.Repository.Url = util.CleanUpRepositoryUrl(w.Repository.Url) if w.GitProviderConfigId == nil || *w.GitProviderConfigId == "" { - configs, err := s.gitProviderService.ListConfigsForUrl(w.Repository.Url) + configs, err := s.listGitProviderConfigs(ctx, w.Repository.Url) if err != nil { return s.handleCreateError(ctx, w, err) } @@ -77,7 +73,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo } if w.Repository.Sha == "" { - sha, err := s.gitProviderService.GetLastCommitSha(w.Repository) + sha, err := s.getLastCommitSha(ctx, w.Repository) if err != nil { return s.handleCreateError(ctx, w, err) } @@ -85,7 +81,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo } if w.BuildConfig != nil { - cachedBuild, err := s.getCachedBuildForWorkspace(w) + cachedBuild, err := s.findCachedBuild(ctx, w) if err == nil { w.BuildConfig.CachedBuild = cachedBuild } @@ -99,7 +95,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo w.User = s.defaultWorkspaceUser } - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", w.Id)) + apiKey, err := s.generateApiKey(ctx, fmt.Sprintf("ws-%s", w.Id)) if err != nil { return s.handleCreateError(ctx, w, err) } @@ -130,21 +126,21 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) - cr, err := s.containerRegistryService.FindByImageName(w.Image) - if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { + cr, err := s.findContainerRegistry(ctx, w.Image) + if err != nil && !stores.IsContainerRegistryNotFound(err) { return s.handleCreateError(ctx, w, err) } - builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) - if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { + builderCr, err := s.findContainerRegistry(ctx, s.builderImage) + if err != nil && !stores.IsContainerRegistryNotFound(err) { return s.handleCreateError(ctx, w, err) } var gc *models.GitProviderConfig if w.GitProviderConfigId != nil { - gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) - if err != nil && !gitproviders.IsGitProviderNotFound(err) { + gc, err = s.findGitProviderConfig(ctx, *w.GitProviderConfigId) + if err != nil && !stores.IsGitProviderNotFound(err) { return s.handleCreateError(ctx, w, err) } } @@ -162,7 +158,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req dto.CreateWo workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s created", w.Name)))) - err = s.startWorkspace(w, workspaceLogger) + err = s.startWorkspace(ctx, w, workspaceLogger) return s.handleCreateError(ctx, w, err) } @@ -183,7 +179,7 @@ func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Work telemetryProps["error"] = err.Error() event = telemetry.ServerEventWorkspaceCreateError } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) if telemetryError != nil { log.Trace(err) } @@ -194,30 +190,3 @@ func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Work return w, err } - -func (s *WorkspaceService) getCachedBuildForWorkspace(w *models.Workspace) (*models.CachedBuild, error) { - validStates := &[]models.BuildState{ - models.BuildStatePublished, - } - - build, err := s.buildService.Find(&builds.BuildFilter{ - States: validStates, - RepositoryUrl: &w.Repository.Url, - Branch: &w.Repository.Branch, - EnvVars: &w.EnvVars, - BuildConfig: w.BuildConfig, - GetNewest: util.Pointer(true), - }) - if err != nil { - return nil, err - } - - if build.Image == nil || build.User == nil { - return nil, errors.New("cached build is missing image or user") - } - - return &models.CachedBuild{ - User: *build.User, - Image: *build.Image, - }, nil -} diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index 51921a72d1..1f6c2e0352 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -10,17 +10,17 @@ import ( "time" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/services" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) { +func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*services.WorkspaceDTO, error) { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { return nil, ErrWorkspaceNotFound } - response := &dto.WorkspaceDTO{ + response := &services.WorkspaceDTO{ Workspace: *ws, } diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index 02f9819821..6177b2e53f 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -11,21 +11,21 @@ import ( "time" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/services" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) { +func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([]services.WorkspaceDTO, error) { workspaces, err := s.workspaceStore.List() if err != nil { return nil, err } var wg sync.WaitGroup - response := []dto.WorkspaceDTO{} + response := []services.WorkspaceDTO{} for i, ws := range workspaces { - response = append(response, dto.WorkspaceDTO{Workspace: *ws}) + response = append(response, services.WorkspaceDTO{Workspace: *ws}) if !verbose { continue } diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index 8e074a2373..323bcc7399 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -26,7 +26,7 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri return s.handleRemoveError(ctx, ws, err) } - err = s.apiKeyService.Revoke(fmt.Sprintf("ws-%s", ws.Id)) + err = s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", ws.Id)) if err != nil { // Should not fail the whole operation if the API key cannot be revoked log.Error(err) @@ -57,7 +57,7 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId log.Error(err) } - err = s.apiKeyService.Revoke(fmt.Sprintf("ws-%s", ws.Id)) + err = s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", ws.Id)) if err != nil { // Should not fail the whole operation if the API key cannot be revoked log.Error(err) @@ -87,7 +87,7 @@ func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Work telemetryProps["error"] = err.Error() event = telemetry.ServerEventWorkspaceDestroyError } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) if telemetryError != nil { log.Trace(err) } diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index d9639927ee..dc5623bf79 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -7,84 +7,83 @@ import ( "context" "io" + "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/apikeys" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" ) -type IWorkspaceService interface { - CreateWorkspace(ctx context.Context, req dto.CreateWorkspaceDTO) (*models.Workspace, error) - GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*dto.WorkspaceDTO, error) - ListWorkspaces(ctx context.Context, verbose bool) ([]dto.WorkspaceDTO, error) - StartWorkspace(ctx context.Context, workspaceId string) error - StopWorkspace(ctx context.Context, workspaceId string) error - RemoveWorkspace(ctx context.Context, workspaceId string) error - ForceRemoveWorkspace(ctx context.Context, workspaceId string) error +type WorkspaceServiceConfig struct { + WorkspaceStore stores.WorkspaceStore - GetWorkspaceLogReader(workspaceId string) (io.Reader, error) - SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) -} + FindTarget func(ctx context.Context, targetId string) (*models.Target, error) + FindContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) + FindCachedBuild func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) + GenerateApiKey func(ctx context.Context, name string) (string, error) + RevokeApiKey func(ctx context.Context, name string) error + ListGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) + FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + GetLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) + TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error -type WorkspaceServiceConfig struct { - WorkspaceStore WorkspaceStore - TargetStore targetStore - ContainerRegistryService containerregistries.IContainerRegistryService - BuildService builds.IBuildService - ServerApiUrl string - ServerUrl string - ServerVersion string - Provisioner provisioner.IProvisioner - DefaultWorkspaceImage string - DefaultWorkspaceUser string - BuilderImage string - ApiKeyService apikeys.IApiKeyService - LoggerFactory logs.LoggerFactory - GitProviderService gitproviders.IGitProviderService - TelemetryService telemetry.TelemetryService + LoggerFactory logs.LoggerFactory + ServerApiUrl string + ServerUrl string + ServerVersion string + Provisioner provisioner.IProvisioner + DefaultWorkspaceImage string + DefaultWorkspaceUser string + BuilderImage string } -func NewWorkspaceService(config WorkspaceServiceConfig) IWorkspaceService { +func NewWorkspaceService(config WorkspaceServiceConfig) services.IWorkspaceService { return &WorkspaceService{ - workspaceStore: config.WorkspaceStore, - targetStore: config.TargetStore, - containerRegistryService: config.ContainerRegistryService, - buildService: config.BuildService, - serverApiUrl: config.ServerApiUrl, - serverUrl: config.ServerUrl, - serverVersion: config.ServerVersion, - defaultWorkspaceImage: config.DefaultWorkspaceImage, - defaultWorkspaceUser: config.DefaultWorkspaceUser, - builderImage: config.BuilderImage, - provisioner: config.Provisioner, - loggerFactory: config.LoggerFactory, - apiKeyService: config.ApiKeyService, - gitProviderService: config.GitProviderService, - telemetryService: config.TelemetryService, + workspaceStore: config.WorkspaceStore, + findTarget: config.FindTarget, + findContainerRegistry: config.FindContainerRegistry, + findCachedBuild: config.FindCachedBuild, + generateApiKey: config.GenerateApiKey, + revokeApiKey: config.RevokeApiKey, + listGitProviderConfigs: config.ListGitProviderConfigs, + findGitProviderConfig: config.FindGitProviderConfig, + getLastCommitSha: config.GetLastCommitSha, + trackTelemetryEvent: config.TrackTelemetryEvent, + + serverApiUrl: config.ServerApiUrl, + serverUrl: config.ServerUrl, + serverVersion: config.ServerVersion, + defaultWorkspaceImage: config.DefaultWorkspaceImage, + defaultWorkspaceUser: config.DefaultWorkspaceUser, + provisioner: config.Provisioner, + loggerFactory: config.LoggerFactory, + builderImage: config.BuilderImage, } } type WorkspaceService struct { - workspaceStore WorkspaceStore - targetStore targetStore - containerRegistryService containerregistries.IContainerRegistryService - buildService builds.IBuildService - provisioner provisioner.IProvisioner - apiKeyService apikeys.IApiKeyService - serverApiUrl string - serverUrl string - serverVersion string - defaultWorkspaceImage string - defaultWorkspaceUser string - builderImage string - loggerFactory logs.LoggerFactory - gitProviderService gitproviders.IGitProviderService - telemetryService telemetry.TelemetryService + workspaceStore stores.WorkspaceStore + + findTarget func(ctx context.Context, targetId string) (*models.Target, error) + findContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) + findCachedBuild func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) + generateApiKey func(ctx context.Context, name string) (string, error) + revokeApiKey func(ctx context.Context, name string) error + listGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) + findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + getLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) + trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + + provisioner provisioner.IProvisioner + serverApiUrl string + serverUrl string + serverVersion string + defaultWorkspaceImage string + defaultWorkspaceUser string + loggerFactory logs.LoggerFactory + builderImage string } func (s *WorkspaceService) SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) { diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 72ffc98f20..b7331e4dca 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -17,9 +17,9 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/server/workspaces/dto" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -54,11 +54,11 @@ var tg = &models.Target{ Options: "test-options", } -var createWorkspaceDTO = dto.CreateWorkspaceDTO{ +var createWorkspaceDTO = services.CreateWorkspaceDTO{ Id: "123", Name: "workspace1", GitProviderConfigId: &gitProviderConfig.Id, - Source: dto.CreateWorkspaceSourceDTO{ + Source: services.CreateWorkspaceSourceDTO{ Repository: &gitprovider.GitRepository{ Id: "123", Url: "https://github.com/daytonaio/daytona", @@ -123,23 +123,51 @@ func TestTargetService(t *testing.T) { buildLogsDir := t.TempDir() service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ - TargetStore: targetStore, - WorkspaceStore: workspaceStore, - ServerApiUrl: serverApiUrl, - ServerUrl: serverUrl, - ContainerRegistryService: containerRegistryService, - DefaultWorkspaceImage: defaultWorkspaceImage, - DefaultWorkspaceUser: defaultWorkspaceUser, - ApiKeyService: apiKeyService, - Provisioner: mockProvisioner, - LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), - GitProviderService: gitProviderService, + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + t, err := targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + if err != nil { + return nil, err + } + return t, nil + }, + FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { + return containerRegistryService.FindByImageName(image) + }, + FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { + return nil, nil + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(models.ApiKeyTypeWorkspace, name) + }, + RevokeApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Revoke(name) + }, + ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { + return gitProviderService.ListConfigsForUrl(repoUrl) + }, + FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { + return gitProviderService.GetConfig(id) + }, + GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { + return gitProviderService.GetLastCommitSha(repo) + }, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return nil + }, + WorkspaceStore: workspaceStore, + ServerApiUrl: serverApiUrl, + ServerUrl: serverUrl, + DefaultWorkspaceImage: defaultWorkspaceImage, + DefaultWorkspaceUser: defaultWorkspaceUser, + Provisioner: mockProvisioner, + LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), + BuilderImage: defaultWorkspaceImage, }) t.Run("CreateWorkspace", func(t *testing.T) { var containerRegistry *models.ContainerRegistry - containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, containerregistries.ErrContainerRegistryNotFound) + containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, stores.ErrContainerRegistryNotFound) gitProviderService.On("GetLastCommitSha", createWorkspaceDTO.Source.Repository).Return("123", nil) @@ -330,7 +358,7 @@ func workspaceEquals(t *testing.T, ws1, ws2 *models.Workspace, workspaceImage st require.Equal(t, ws1.Repository.Name, ws2.Repository.Name) } -func workspaceDtoEquals(t *testing.T, req dto.CreateWorkspaceDTO, workspace dto.WorkspaceDTO, workspaceInfo models.WorkspaceInfo, workspaceImage string, verbose bool) { +func workspaceDtoEquals(t *testing.T, req services.CreateWorkspaceDTO, workspace services.WorkspaceDTO, workspaceInfo models.WorkspaceInfo, workspaceImage string, verbose bool) { t.Helper() require.Equal(t, req.Id, workspace.Id) diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index f794dc9c7c..ed4af413f8 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -11,8 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" @@ -35,7 +34,7 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin ClientId: telemetry.ClientId(ctx), }, telemetry.TelemetryEnabled(ctx)) - err = s.startWorkspace(workspaceToStart, workspaceLogger) + err = s.startWorkspace(ctx, workspaceToStart, workspaceLogger) if err != nil { return s.handleStartError(ctx, ws, err) } @@ -43,24 +42,24 @@ func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId strin return s.handleStartError(ctx, ws, err) } -func (s *WorkspaceService) startWorkspace(w *models.Workspace, logger io.Writer) error { +func (s *WorkspaceService) startWorkspace(ctx context.Context, w *models.Workspace, logger io.Writer) error { logger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) - cr, err := s.containerRegistryService.FindByImageName(w.Image) - if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { + cr, err := s.findContainerRegistry(ctx, w.Image) + if err != nil && !stores.IsContainerRegistryNotFound(err) { return err } - builderCr, err := s.containerRegistryService.FindByImageName(s.builderImage) - if err != nil && !containerregistries.IsContainerRegistryNotFound(err) { + builderCr, err := s.findContainerRegistry(ctx, s.builderImage) + if err != nil && !stores.IsContainerRegistryNotFound(err) { return err } var gc *models.GitProviderConfig if w.GitProviderConfigId != nil { - gc, err = s.gitProviderService.GetConfig(*w.GitProviderConfigId) - if err != nil && !gitproviders.IsGitProviderNotFound(err) { + gc, err = s.findGitProviderConfig(ctx, *w.GitProviderConfigId) + if err != nil && !stores.IsGitProviderNotFound(err) { return err } } @@ -94,7 +93,7 @@ func (s *WorkspaceService) handleStartError(ctx context.Context, w *models.Works telemetryProps["error"] = err.Error() event = telemetry.ServerEventWorkspaceStartError } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) if telemetryError != nil { log.Trace(err) } diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 5ccbc60b68..19a95567f8 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -46,7 +46,7 @@ func (s *WorkspaceService) handleStopError(ctx context.Context, w *models.Worksp telemetryProps["error"] = err.Error() event = telemetry.ServerEventWorkspaceStopError } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) if telemetryError != nil { log.Trace(err) } diff --git a/pkg/services/api_key.go b/pkg/services/api_key.go new file mode 100644 index 0000000000..536314c404 --- /dev/null +++ b/pkg/services/api_key.go @@ -0,0 +1,15 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import "github.com/daytonaio/daytona/pkg/models" + +type IApiKeyService interface { + Generate(keyType models.ApiKeyType, name string) (string, error) + IsWorkspaceApiKey(apiKey string) bool + IsTargetApiKey(apiKey string) bool + IsValidApiKey(apiKey string) bool + ListClientKeys() ([]*models.ApiKey, error) + Revoke(name string) error +} diff --git a/pkg/services/build.go b/pkg/services/build.go new file mode 100644 index 0000000000..1129d94cdd --- /dev/null +++ b/pkg/services/build.go @@ -0,0 +1,29 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "io" + "time" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type IBuildService interface { + Create(CreateBuildDTO) (string, error) + Find(filter *stores.BuildFilter) (*models.Build, error) + List(filter *stores.BuildFilter) ([]*models.Build, error) + MarkForDeletion(filter *stores.BuildFilter, force bool) []error + Delete(id string) error + AwaitEmptyList(time.Duration) error + GetBuildLogReader(buildId string) (io.Reader, error) +} + +type CreateBuildDTO struct { + WorkspaceConfigName string `json:"workspaceConfigName" validate:"required"` + Branch string `json:"branch" validate:"required"` + PrebuildId *string `json:"prebuildId" validate:"optional"` + EnvVars map[string]string `json:"envVars" validate:"required"` +} // @name CreateBuildDTO diff --git a/pkg/services/container_registry.go b/pkg/services/container_registry.go new file mode 100644 index 0000000000..a6729ea0ad --- /dev/null +++ b/pkg/services/container_registry.go @@ -0,0 +1,15 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import "github.com/daytonaio/daytona/pkg/models" + +type IContainerRegistryService interface { + Delete(server string) error + Find(server string) (*models.ContainerRegistry, error) + FindByImageName(imageName string) (*models.ContainerRegistry, error) + List() ([]*models.ContainerRegistry, error) + Map() (map[string]*models.ContainerRegistry, error) + Save(cr *models.ContainerRegistry) error +} diff --git a/pkg/services/git_provider.go b/pkg/services/git_provider.go new file mode 100644 index 0000000000..4dde7183c0 --- /dev/null +++ b/pkg/services/git_provider.go @@ -0,0 +1,31 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "net/http" + + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" +) + +type IGitProviderService interface { + GetConfig(id string) (*models.GitProviderConfig, error) + ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) + GetGitProvider(id string) (gitprovider.GitProvider, error) + GetGitProviderForUrl(url string) (gitprovider.GitProvider, string, error) + GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) + GetGitUser(gitProviderId string) (*gitprovider.GitUser, error) + GetNamespaces(gitProviderId string, options gitprovider.ListOptions) ([]*gitprovider.GitNamespace, error) + GetRepoBranches(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) + GetRepoPRs(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) + GetRepositories(gitProviderId string, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) + ListConfigs() ([]*models.GitProviderConfig, error) + RemoveGitProvider(gitProviderId string) error + SetGitProviderConfig(providerConfig *models.GitProviderConfig) error + GetLastCommitSha(repo *gitprovider.GitRepository) (string, error) + RegisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) + GetPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) + UnregisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, id string) error +} diff --git a/pkg/services/profile_data.go b/pkg/services/profile_data.go new file mode 100644 index 0000000000..e5e181b332 --- /dev/null +++ b/pkg/services/profile_data.go @@ -0,0 +1,12 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import "github.com/daytonaio/daytona/pkg/models" + +type IProfileDataService interface { + Get(id string) (*models.ProfileData, error) + Save(profileData *models.ProfileData) error + Delete(id string) error +} diff --git a/pkg/services/target.go b/pkg/services/target.go new file mode 100644 index 0000000000..9a96c8068c --- /dev/null +++ b/pkg/services/target.go @@ -0,0 +1,25 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "context" + "io" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/stores" +) + +type ITargetService interface { + CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) + GetTarget(ctx context.Context, filter *stores.TargetFilter, verbose bool) (*dto.TargetDTO, error) + GetTargetLogReader(targetId string) (io.Reader, error) + ListTargets(ctx context.Context, filter *stores.TargetFilter, verbose bool) ([]dto.TargetDTO, error) + StartTarget(ctx context.Context, targetId string) error + StopTarget(ctx context.Context, targetId string) error + SetDefault(ctx context.Context, targetId string) error + RemoveTarget(ctx context.Context, targetId string) error + ForceRemoveTarget(ctx context.Context, targetId string) error +} diff --git a/pkg/services/target_config.go b/pkg/services/target_config.go new file mode 100644 index 0000000000..9235208888 --- /dev/null +++ b/pkg/services/target_config.go @@ -0,0 +1,17 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type ITargetConfigService interface { + Delete(targetConfig *models.TargetConfig) error + Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) + List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) + Map() (map[string]*models.TargetConfig, error) + Save(targetConfig *models.TargetConfig) error +} diff --git a/pkg/server/workspaces/dto/workspace.go b/pkg/services/workspace.go similarity index 52% rename from pkg/server/workspaces/dto/workspace.go rename to pkg/services/workspace.go index 9bc6c44bb8..9667b3411c 100644 --- a/pkg/server/workspaces/dto/workspace.go +++ b/pkg/services/workspace.go @@ -1,13 +1,29 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package dto +package services import ( + "context" + "io" + "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" ) +type IWorkspaceService interface { + CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*models.Workspace, error) + GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*WorkspaceDTO, error) + ListWorkspaces(ctx context.Context, verbose bool) ([]WorkspaceDTO, error) + StartWorkspace(ctx context.Context, workspaceId string) error + StopWorkspace(ctx context.Context, workspaceId string) error + RemoveWorkspace(ctx context.Context, workspaceId string) error + ForceRemoveWorkspace(ctx context.Context, workspaceId string) error + + GetWorkspaceLogReader(workspaceId string) (io.Reader, error) + SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) +} + type WorkspaceDTO struct { models.Workspace Info *models.WorkspaceInfo `json:"info" validate:"optional"` @@ -25,6 +41,28 @@ type CreateWorkspaceDTO struct { GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` } // @name CreateWorkspaceDTO +func (c *CreateWorkspaceDTO) ToWorkspace() *models.Workspace { + w := &models.Workspace{ + Id: c.Id, + Name: c.Name, + BuildConfig: c.BuildConfig, + Repository: c.Source.Repository, + EnvVars: c.EnvVars, + TargetId: c.TargetId, + GitProviderConfigId: c.GitProviderConfigId, + } + + if c.Image != nil { + w.Image = *c.Image + } + + if c.User != nil { + w.User = *c.User + } + + return w +} + type CreateWorkspaceSourceDTO struct { Repository *gitprovider.GitRepository `json:"repository" validate:"required"` } // @name CreateWorkspaceSourceDTO diff --git a/pkg/services/workspace_config.go b/pkg/services/workspace_config.go new file mode 100644 index 0000000000..708b8ce17d --- /dev/null +++ b/pkg/services/workspace_config.go @@ -0,0 +1,28 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/stores" +) + +type IWorkspaceConfigService interface { + Save(workspaceConfig *models.WorkspaceConfig) error + Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) + List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) + SetDefault(workspaceConfigName string) error + Delete(workspaceConfigName string, force bool) []error + + SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) + FindPrebuild(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) + ListPrebuilds(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) + DeletePrebuild(workspaceConfigName string, id string, force bool) []error + + StartRetentionPoller() error + EnforceRetentionPolicy() error + ProcessGitEvent(gitprovider.GitEventData) error +} diff --git a/pkg/server/apikeys/store.go b/pkg/stores/api_key.go similarity index 97% rename from pkg/server/apikeys/store.go rename to pkg/stores/api_key.go index c5d6ab0914..4dd9a3a351 100644 --- a/pkg/server/apikeys/store.go +++ b/pkg/stores/api_key.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package apikeys +package stores import ( "errors" diff --git a/pkg/server/builds/store.go b/pkg/stores/build.go similarity index 98% rename from pkg/server/builds/store.go rename to pkg/stores/build.go index c77e0ec940..6377cb95db 100644 --- a/pkg/server/builds/store.go +++ b/pkg/stores/build.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package builds +package stores import ( "errors" diff --git a/pkg/server/containerregistries/store.go b/pkg/stores/container_registry.go similarity index 95% rename from pkg/server/containerregistries/store.go rename to pkg/stores/container_registry.go index b10a84965d..1ed49c158c 100644 --- a/pkg/server/containerregistries/store.go +++ b/pkg/stores/container_registry.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package containerregistries +package stores import ( "errors" diff --git a/pkg/server/gitproviders/store.go b/pkg/stores/git_provider.go similarity index 75% rename from pkg/server/gitproviders/store.go rename to pkg/stores/git_provider.go index 8be4233d9b..dfd70ebb8c 100644 --- a/pkg/server/gitproviders/store.go +++ b/pkg/stores/git_provider.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package gitproviders +package stores import ( "errors" @@ -16,11 +16,6 @@ type GitProviderConfigStore interface { Delete(*models.GitProviderConfig) error } -type WorkspaceConfigStore interface { - Save(workspaceConfig *models.WorkspaceConfig) error - List(gitProviderConfigId string) ([]*models.WorkspaceConfig, error) -} - var ( ErrGitProviderConfigNotFound = errors.New("git provider config not found") ) diff --git a/pkg/server/profiledata/store.go b/pkg/stores/profile_data.go similarity index 96% rename from pkg/server/profiledata/store.go rename to pkg/stores/profile_data.go index 794f006f60..a947016670 100644 --- a/pkg/server/profiledata/store.go +++ b/pkg/stores/profile_data.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package profiledata +package stores import ( "errors" diff --git a/pkg/server/targets/store.go b/pkg/stores/target.go similarity index 96% rename from pkg/server/targets/store.go rename to pkg/stores/target.go index 27e7e7ee85..46e70640ba 100644 --- a/pkg/server/targets/store.go +++ b/pkg/stores/target.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package targets +package stores import ( "github.com/daytonaio/daytona/pkg/models" diff --git a/pkg/server/targetconfigs/store.go b/pkg/stores/target_config.go similarity index 96% rename from pkg/server/targetconfigs/store.go rename to pkg/stores/target_config.go index 55c47f999e..4601688855 100644 --- a/pkg/server/targetconfigs/store.go +++ b/pkg/stores/target_config.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package targetconfigs +package stores import ( "errors" diff --git a/pkg/server/workspaces/store.go b/pkg/stores/workspace.go similarity index 67% rename from pkg/server/workspaces/store.go rename to pkg/stores/workspace.go index 9c3a37cddc..cf9cc0958a 100644 --- a/pkg/server/workspaces/store.go +++ b/pkg/stores/workspace.go @@ -1,11 +1,10 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaces +package stores import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targets" ) type WorkspaceStore interface { @@ -14,7 +13,3 @@ type WorkspaceStore interface { Save(workspace *models.Workspace) error Delete(workspace *models.Workspace) error } - -type targetStore interface { - Find(filter *targets.TargetFilter) (*models.Target, error) -} diff --git a/pkg/server/workspaceconfigs/store.go b/pkg/stores/workspace_config.go similarity index 97% rename from pkg/server/workspaceconfigs/store.go rename to pkg/stores/workspace_config.go index 2c0bdc59af..f6f5a33692 100644 --- a/pkg/server/workspaceconfigs/store.go +++ b/pkg/stores/workspace_config.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfigs +package stores import ( "errors" From 3bb2849031da26d6446a7e6bd9427aa01d395996 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Wed, 27 Nov 2024 16:25:14 +0100 Subject: [PATCH 10/76] feat: resource state management using jobs (#1351) - async state management using jobs and job runners - soft deletion for workspaces/targets - workspace metadata and target metadata table to separately track uptime updates for each resource BREAKING CHANGES: - multiple database table structure updates Signed-off-by: Ivan Dagelic --- docs/agent_mode/daytona_agent.md | 2 +- hack/docs/agent_mode/daytona_agent.yaml | 4 +- internal/constants/deleted.go | 6 + internal/testing/job/store.go | 107 ++++ .../testing/server/targets/metadata_store.go | 75 +++ internal/testing/server/targets/store.go | 3 +- .../server/workspaces/metadata_store.go | 75 +++ internal/testing/server/workspaces/store.go | 3 +- internal/util/apiclient/api_client.go | 16 +- .../util/apiclient/conversion/workspace.go | 20 +- internal/util/deleted_name.go | 14 + internal/util/pointer.go | 9 - internal/util/time.go | 14 +- internal/util/{map.go => types.go} | 13 + internal/util/{target.go => workspace.go} | 0 pkg/agent/agent.go | 55 +- pkg/agent/agent_test.go | 11 +- pkg/agent/config/config.go | 2 +- pkg/api/controllers/job/job.go | 34 ++ pkg/api/controllers/target/create.go | 6 - pkg/api/controllers/target/dto/dto.go | 9 +- pkg/api/controllers/target/metadata.go | 48 ++ pkg/api/controllers/target/target.go | 14 +- pkg/api/controllers/workspace/dto/dto.go | 4 +- pkg/api/controllers/workspace/metadata.go | 49 ++ pkg/api/controllers/workspace/state.go | 51 -- .../controllers/workspace/toolbox/toolbox.go | 11 +- pkg/api/controllers/workspace/workspace.go | 19 +- pkg/api/docs/docs.go | 325 ++++++++++- pkg/api/docs/swagger.json | 325 ++++++++++- pkg/api/docs/swagger.yaml | 242 +++++++- pkg/api/middlewares/telemetry.go | 7 +- pkg/api/server.go | 9 +- pkg/api/util/hide.go | 72 +++ pkg/api/util/mask-options.go | 41 -- pkg/apiclient/README.md | 16 +- pkg/apiclient/api/openapi.yaml | 520 +++++++++++++++--- pkg/apiclient/api_job.go | 136 +++++ pkg/apiclient/api_target.go | 118 ++++ pkg/apiclient/api_workspace.go | 36 +- pkg/apiclient/client.go | 3 + pkg/apiclient/docs/Job.md | 203 +++++++ pkg/apiclient/docs/JobAPI.md | 70 +++ pkg/apiclient/docs/JobState.md | 17 + pkg/apiclient/docs/ModelsJobAction.md | 21 + pkg/apiclient/docs/ModelsResourceStateName.md | 41 ++ pkg/apiclient/docs/ResourceState.md | 98 ++++ pkg/apiclient/docs/ResourceType.md | 13 + pkg/apiclient/docs/SetTargetMetadata.md | 51 ++ ...kspaceState.md => SetWorkspaceMetadata.md} | 28 +- pkg/apiclient/docs/Target.md | 75 ++- pkg/apiclient/docs/TargetAPI.md | 71 +++ pkg/apiclient/docs/TargetDTO.md | 96 +++- pkg/apiclient/docs/TargetMetadata.md | 93 ++++ pkg/apiclient/docs/Workspace.md | 78 ++- pkg/apiclient/docs/WorkspaceAPI.md | 18 +- pkg/apiclient/docs/WorkspaceDTO.md | 67 ++- ...WorkspaceState.md => WorkspaceMetadata.md} | 55 +- pkg/apiclient/model_job.go | 360 ++++++++++++ pkg/apiclient/model_job_state.go | 114 ++++ pkg/apiclient/model_models_job_action.go | 118 ++++ .../model_models_resource_state_name.go | 138 +++++ pkg/apiclient/model_resource_state.go | 220 ++++++++ pkg/apiclient/model_resource_type.go | 110 ++++ pkg/apiclient/model_set_target_metadata.go | 156 ++++++ ...ate.go => model_set_workspace_metadata.go} | 68 +-- pkg/apiclient/model_target.go | 108 +++- pkg/apiclient/model_target_dto.go | 138 ++++- pkg/apiclient/model_target_metadata.go | 212 +++++++ pkg/apiclient/model_workspace.go | 128 +++-- pkg/apiclient/model_workspace_dto.go | 138 +++-- ...e_state.go => model_workspace_metadata.go} | 108 ++-- pkg/build/runner_config.go | 4 +- pkg/cmd/agent/agent.go | 8 +- pkg/cmd/agentmode/info.go | 2 +- pkg/cmd/common/await_state.go | 79 +++ .../common/configuration_flags.go | 0 pkg/cmd/{workspace => }/common/get_gpg_key.go | 0 pkg/cmd/{workspace => }/common/open_ide.go | 0 .../common/workspace_autocompletion.go | 14 +- pkg/cmd/provider/install.go | 2 +- pkg/cmd/provider/update.go | 2 +- pkg/cmd/purge.go | 11 +- pkg/cmd/server/bootstrap/get_build_runner.go | 111 ++++ pkg/cmd/server/bootstrap/get_job_runner.go | 148 +++++ .../server/bootstrap/get_server_instance.go | 427 ++++++++++++++ .../server/bootstrap/init_provider_manager.go | 87 +++ pkg/cmd/server/serve.go | 515 +---------------- pkg/cmd/target/create.go | 6 + pkg/cmd/target/delete.go | 17 +- pkg/cmd/target/info.go | 4 +- pkg/cmd/target/logs.go | 11 +- pkg/cmd/target/restart.go | 8 +- pkg/cmd/target/setdefault.go | 4 +- pkg/cmd/target/start.go | 95 +--- pkg/cmd/target/stop.go | 13 +- pkg/cmd/targetconfig/set.go | 2 +- pkg/cmd/workspace/code.go | 11 +- pkg/cmd/workspace/create/cmd.go | 23 +- pkg/cmd/workspace/create/creation_data.go | 4 +- .../workspace/create/process_cmd_arguments.go | 8 +- pkg/cmd/workspace/create/process_prompting.go | 6 +- pkg/cmd/workspace/delete.go | 17 +- pkg/cmd/workspace/info.go | 4 +- pkg/cmd/workspace/list.go | 1 - pkg/cmd/workspace/logs.go | 4 +- pkg/cmd/workspace/restart.go | 6 +- pkg/cmd/workspace/ssh-proxy.go | 4 +- pkg/cmd/workspace/ssh.go | 6 +- pkg/cmd/workspace/start.go | 14 +- pkg/cmd/workspace/stop.go | 14 +- pkg/cmd/workspaceconfig/add.go | 8 +- pkg/db/job_store.go | 104 ++++ pkg/db/target_metadata_store.go | 70 +++ pkg/db/target_store.go | 14 +- pkg/db/workspace_metadata_store.go | 70 +++ pkg/db/workspace_store.go | 27 +- pkg/docker/client.go | 6 +- pkg/docker/create.go | 4 +- pkg/docker/create_image.go | 4 +- pkg/docker/start_devcontainer.go | 2 +- pkg/jobs/jobs.go | 12 + pkg/jobs/target/create.go | 38 ++ pkg/jobs/target/delete.go | 42 ++ pkg/jobs/target/factory.go | 50 ++ pkg/jobs/target/restart.go | 19 + pkg/jobs/target/start.go | 33 ++ pkg/jobs/target/stop.go | 35 ++ pkg/jobs/target/target.go | 44 ++ pkg/jobs/workspace/create.go | 60 ++ pkg/jobs/workspace/delete.go | 42 ++ pkg/jobs/workspace/factory.go | 55 ++ pkg/jobs/workspace/restart.go | 19 + pkg/jobs/workspace/start.go | 60 ++ pkg/jobs/workspace/stop.go | 35 ++ pkg/jobs/workspace/workspace.go | 44 ++ pkg/models/job.go | 95 ++++ pkg/models/target.go | 46 +- pkg/models/workspace.go | 61 +- pkg/provider/manager/manager.go | 44 +- pkg/runners/runner.go | 17 + pkg/runners/runner/runner.go | 110 ++++ pkg/{build/scheduler.go => scheduler/cron.go} | 2 +- pkg/server/jobs/service.go | 46 ++ pkg/server/jobs/service_test.go | 137 +++++ pkg/server/purge.go | 3 +- pkg/server/server.go | 3 + pkg/server/targets/create.go | 91 ++- pkg/server/targets/dto/target.go | 3 +- pkg/server/targets/env_vars.go | 13 +- pkg/server/targets/error.go | 18 - pkg/server/targets/get.go | 24 +- pkg/server/targets/list.go | 27 +- pkg/server/targets/metadata.go | 22 + pkg/server/targets/remove.go | 62 ++- pkg/server/targets/service.go | 15 +- pkg/server/targets/service_test.go | 41 +- pkg/server/targets/set-default.go | 7 +- pkg/server/targets/start.go | 39 +- pkg/server/targets/stop.go | 5 +- pkg/server/workspaceconfigs/prebuild.go | 5 +- pkg/server/workspaces/create.go | 96 ++-- pkg/server/workspaces/env_vars.go | 13 +- pkg/server/workspaces/error.go | 15 - pkg/server/workspaces/get.go | 15 +- pkg/server/workspaces/list.go | 17 +- pkg/server/workspaces/metadata.go | 23 + pkg/server/workspaces/remove.go | 57 +- pkg/server/workspaces/service.go | 24 +- pkg/server/workspaces/service_test.go | 38 +- pkg/server/workspaces/start.go | 62 +-- pkg/server/workspaces/stop.go | 17 +- pkg/services/job.go | 16 + pkg/services/target.go | 24 +- pkg/services/workspace.go | 27 +- pkg/stores/job_store.go | 48 ++ pkg/stores/target.go | 10 + pkg/stores/target_metadata.go | 29 + pkg/stores/workspace.go | 10 + pkg/stores/workspace_metadata.go | 29 + pkg/views/common.go | 60 ++ pkg/views/styles.go | 26 + pkg/views/target/info/view.go | 15 + pkg/views/target/list/view.go | 61 +- pkg/views/target/selection/target.go | 8 + pkg/views/target/selection/view.go | 32 +- pkg/views/util/state_time.go | 19 + pkg/views/workspace/info/view.go | 70 +-- pkg/views/workspace/list/view.go | 100 ++-- pkg/views/workspace/selection/view.go | 36 +- pkg/views/workspace/selection/workspace.go | 14 +- 191 files changed, 8407 insertions(+), 1864 deletions(-) create mode 100644 internal/constants/deleted.go create mode 100644 internal/testing/job/store.go create mode 100644 internal/testing/server/targets/metadata_store.go create mode 100644 internal/testing/server/workspaces/metadata_store.go create mode 100644 internal/util/deleted_name.go delete mode 100644 internal/util/pointer.go rename internal/util/{map.go => types.go} (50%) rename internal/util/{target.go => workspace.go} (100%) create mode 100644 pkg/api/controllers/job/job.go create mode 100644 pkg/api/controllers/target/metadata.go create mode 100644 pkg/api/controllers/workspace/metadata.go delete mode 100644 pkg/api/controllers/workspace/state.go create mode 100644 pkg/api/util/hide.go delete mode 100644 pkg/api/util/mask-options.go create mode 100644 pkg/apiclient/api_job.go create mode 100644 pkg/apiclient/docs/Job.md create mode 100644 pkg/apiclient/docs/JobAPI.md create mode 100644 pkg/apiclient/docs/JobState.md create mode 100644 pkg/apiclient/docs/ModelsJobAction.md create mode 100644 pkg/apiclient/docs/ModelsResourceStateName.md create mode 100644 pkg/apiclient/docs/ResourceState.md create mode 100644 pkg/apiclient/docs/ResourceType.md create mode 100644 pkg/apiclient/docs/SetTargetMetadata.md rename pkg/apiclient/docs/{SetWorkspaceState.md => SetWorkspaceMetadata.md} (65%) create mode 100644 pkg/apiclient/docs/TargetMetadata.md rename pkg/apiclient/docs/{WorkspaceState.md => WorkspaceMetadata.md} (55%) create mode 100644 pkg/apiclient/model_job.go create mode 100644 pkg/apiclient/model_job_state.go create mode 100644 pkg/apiclient/model_models_job_action.go create mode 100644 pkg/apiclient/model_models_resource_state_name.go create mode 100644 pkg/apiclient/model_resource_state.go create mode 100644 pkg/apiclient/model_resource_type.go create mode 100644 pkg/apiclient/model_set_target_metadata.go rename pkg/apiclient/{model_set_workspace_state.go => model_set_workspace_metadata.go} (59%) create mode 100644 pkg/apiclient/model_target_metadata.go rename pkg/apiclient/{model_workspace_state.go => model_workspace_metadata.go} (53%) create mode 100644 pkg/cmd/common/await_state.go rename pkg/cmd/{workspace => }/common/configuration_flags.go (100%) rename pkg/cmd/{workspace => }/common/get_gpg_key.go (100%) rename pkg/cmd/{workspace => }/common/open_ide.go (100%) rename pkg/cmd/{workspace => }/common/workspace_autocompletion.go (77%) create mode 100644 pkg/cmd/server/bootstrap/get_build_runner.go create mode 100644 pkg/cmd/server/bootstrap/get_job_runner.go create mode 100644 pkg/cmd/server/bootstrap/get_server_instance.go create mode 100644 pkg/cmd/server/bootstrap/init_provider_manager.go create mode 100644 pkg/db/job_store.go create mode 100644 pkg/db/target_metadata_store.go create mode 100644 pkg/db/workspace_metadata_store.go create mode 100644 pkg/jobs/jobs.go create mode 100644 pkg/jobs/target/create.go create mode 100644 pkg/jobs/target/delete.go create mode 100644 pkg/jobs/target/factory.go create mode 100644 pkg/jobs/target/restart.go create mode 100644 pkg/jobs/target/start.go create mode 100644 pkg/jobs/target/stop.go create mode 100644 pkg/jobs/target/target.go create mode 100644 pkg/jobs/workspace/create.go create mode 100644 pkg/jobs/workspace/delete.go create mode 100644 pkg/jobs/workspace/factory.go create mode 100644 pkg/jobs/workspace/restart.go create mode 100644 pkg/jobs/workspace/start.go create mode 100644 pkg/jobs/workspace/stop.go create mode 100644 pkg/jobs/workspace/workspace.go create mode 100644 pkg/models/job.go create mode 100644 pkg/runners/runner.go create mode 100644 pkg/runners/runner/runner.go rename pkg/{build/scheduler.go => scheduler/cron.go} (97%) create mode 100644 pkg/server/jobs/service.go create mode 100644 pkg/server/jobs/service_test.go delete mode 100644 pkg/server/targets/error.go create mode 100644 pkg/server/targets/metadata.go delete mode 100644 pkg/server/workspaces/error.go create mode 100644 pkg/server/workspaces/metadata.go create mode 100644 pkg/services/job.go create mode 100644 pkg/stores/job_store.go create mode 100644 pkg/stores/target_metadata.go create mode 100644 pkg/stores/workspace_metadata.go create mode 100644 pkg/views/util/state_time.go diff --git a/docs/agent_mode/daytona_agent.md b/docs/agent_mode/daytona_agent.md index 7c19d6cdae..157fc8323e 100644 --- a/docs/agent_mode/daytona_agent.md +++ b/docs/agent_mode/daytona_agent.md @@ -9,7 +9,7 @@ daytona agent [flags] ### Options ``` - --host Run the agent in host mode + --target Run the agent in target mode ``` ### Options inherited from parent commands diff --git a/hack/docs/agent_mode/daytona_agent.yaml b/hack/docs/agent_mode/daytona_agent.yaml index 5034cc17be..41ded210cb 100644 --- a/hack/docs/agent_mode/daytona_agent.yaml +++ b/hack/docs/agent_mode/daytona_agent.yaml @@ -2,9 +2,9 @@ name: daytona agent synopsis: Start the agent process usage: daytona agent [flags] options: - - name: host + - name: target default_value: "false" - usage: Run the agent in host mode + usage: Run the agent in target mode inherited_options: - name: help default_value: "false" diff --git a/internal/constants/deleted.go b/internal/constants/deleted.go new file mode 100644 index 0000000000..4144baf107 --- /dev/null +++ b/internal/constants/deleted.go @@ -0,0 +1,6 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package constants + +const DELETED_CIRCUMFIX = "_DELETED_" diff --git a/internal/testing/job/store.go b/internal/testing/job/store.go new file mode 100644 index 0000000000..7f09149e71 --- /dev/null +++ b/internal/testing/job/store.go @@ -0,0 +1,107 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package job + +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type InMemoryJobStore struct { + jobs map[string]*models.Job +} + +func NewInMemoryJobStore() stores.JobStore { + return &InMemoryJobStore{ + jobs: make(map[string]*models.Job), + } +} + +func (s *InMemoryJobStore) List(filter *stores.JobFilter) ([]*models.Job, error) { + jobs, err := s.processFilters(filter) + if err != nil { + return nil, err + } + + return jobs, nil +} + +func (s *InMemoryJobStore) Find(filter *stores.JobFilter) (*models.Job, error) { + jobs, err := s.processFilters(filter) + if err != nil { + return nil, err + } + if len(jobs) == 0 { + return nil, stores.ErrJobNotFound + } + + return jobs[0], nil +} + +func (s *InMemoryJobStore) Save(job *models.Job) error { + s.jobs[job.Id] = job + return nil +} + +func (s *InMemoryJobStore) Delete(job *models.Job) error { + delete(s.jobs, job.Id) + return nil +} + +func (s *InMemoryJobStore) processFilters(filter *stores.JobFilter) ([]*models.Job, error) { + var result []*models.Job + filteredJobs := make(map[string]*models.Job) + for k, v := range s.jobs { + filteredJobs[k] = v + } + + if filter != nil { + if filter.Id != nil { + job, ok := s.jobs[*filter.Id] + if ok { + return []*models.Job{job}, nil + } else { + return []*models.Job{}, fmt.Errorf("job with id %s not found", *filter.Id) + } + } + if filter.States != nil { + for _, job := range filteredJobs { + check := false + for _, state := range *filter.States { + if job.State == state { + check = true + break + } + } + if !check { + delete(filteredJobs, job.Id) + } + } + } + if filter.Actions != nil { + for _, job := range filteredJobs { + check := false + for _, action := range *filter.Actions { + if job.Action == action { + check = true + break + } + } + if !check { + delete(filteredJobs, job.Id) + } + } + } + } + + for _, job := range filteredJobs { + result = append(result, job) + } + + return result, nil +} diff --git a/internal/testing/server/targets/metadata_store.go b/internal/testing/server/targets/metadata_store.go new file mode 100644 index 0000000000..6cd25b5683 --- /dev/null +++ b/internal/testing/server/targets/metadata_store.go @@ -0,0 +1,75 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type InMemoryTargetMetadataStore struct { + targetMetadataEntries map[string]*models.TargetMetadata +} + +func NewInMemoryTargetMetadataStore() stores.TargetMetadataStore { + return &InMemoryTargetMetadataStore{ + targetMetadataEntries: make(map[string]*models.TargetMetadata), + } +} + +func (s *InMemoryTargetMetadataStore) Find(filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { + metadatas, err := s.processFilters(filter) + if err != nil { + return nil, err + } + if len(metadatas) == 0 { + return nil, stores.ErrTargetMetadataNotFound + } + + return metadatas[0], nil +} + +func (s *InMemoryTargetMetadataStore) Save(targetMetadata *models.TargetMetadata) error { + s.targetMetadataEntries[targetMetadata.TargetId] = targetMetadata + return nil +} + +func (s *InMemoryTargetMetadataStore) Delete(targetMetadata *models.TargetMetadata) error { + delete(s.targetMetadataEntries, targetMetadata.TargetId) + return nil +} + +func (s *InMemoryTargetMetadataStore) processFilters(filter *stores.TargetMetadataFilter) ([]*models.TargetMetadata, error) { + var result []*models.TargetMetadata + filteredTargetMetadata := make(map[string]*models.TargetMetadata) + for k, v := range s.targetMetadataEntries { + filteredTargetMetadata[k] = v + } + + if filter != nil { + if filter.Id != nil { + m, ok := s.targetMetadataEntries[*filter.Id] + if ok { + return []*models.TargetMetadata{m}, nil + } else { + return []*models.TargetMetadata{}, nil + } + } + if filter.TargetId != nil { + for _, m := range filteredTargetMetadata { + if m.TargetId != *filter.TargetId { + delete(filteredTargetMetadata, m.TargetId) + } + } + } + } + + for _, m := range filteredTargetMetadata { + result = append(result, m) + } + + return result, nil +} diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go index 24fb104a82..d929b34b73 100644 --- a/internal/testing/server/targets/store.go +++ b/internal/testing/server/targets/store.go @@ -9,7 +9,6 @@ import ( "fmt" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/stores" ) @@ -34,7 +33,7 @@ func (s *InMemoryTargetStore) Find(filter *stores.TargetFilter) (*models.Target, } if len(t) == 0 { - return nil, targets.ErrTargetNotFound + return nil, stores.ErrTargetNotFound } return t[0], nil diff --git a/internal/testing/server/workspaces/metadata_store.go b/internal/testing/server/workspaces/metadata_store.go new file mode 100644 index 0000000000..a26c3e1813 --- /dev/null +++ b/internal/testing/server/workspaces/metadata_store.go @@ -0,0 +1,75 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type InMemoryWorkspaceMetadataStore struct { + workspaceMetadataEntries map[string]*models.WorkspaceMetadata +} + +func NewInMemoryWorkspaceMetadataStore() stores.WorkspaceMetadataStore { + return &InMemoryWorkspaceMetadataStore{ + workspaceMetadataEntries: make(map[string]*models.WorkspaceMetadata), + } +} + +func (s *InMemoryWorkspaceMetadataStore) Find(filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { + metadatas, err := s.processFilters(filter) + if err != nil { + return nil, err + } + if len(metadatas) == 0 { + return nil, stores.ErrWorkspaceMetadataNotFound + } + + return metadatas[0], nil +} + +func (s *InMemoryWorkspaceMetadataStore) Save(workspaceMetadata *models.WorkspaceMetadata) error { + s.workspaceMetadataEntries[workspaceMetadata.WorkspaceId] = workspaceMetadata + return nil +} + +func (s *InMemoryWorkspaceMetadataStore) Delete(workspaceMetadata *models.WorkspaceMetadata) error { + delete(s.workspaceMetadataEntries, workspaceMetadata.WorkspaceId) + return nil +} + +func (s *InMemoryWorkspaceMetadataStore) processFilters(filter *stores.WorkspaceMetadataFilter) ([]*models.WorkspaceMetadata, error) { + var result []*models.WorkspaceMetadata + filteredWorkspaceMetadata := make(map[string]*models.WorkspaceMetadata) + for k, v := range s.workspaceMetadataEntries { + filteredWorkspaceMetadata[k] = v + } + + if filter != nil { + if filter.Id != nil { + m, ok := s.workspaceMetadataEntries[*filter.Id] + if ok { + return []*models.WorkspaceMetadata{m}, nil + } else { + return []*models.WorkspaceMetadata{}, nil + } + } + if filter.WorkspaceId != nil { + for _, m := range filteredWorkspaceMetadata { + if m.WorkspaceId != *filter.WorkspaceId { + delete(filteredWorkspaceMetadata, m.WorkspaceId) + } + } + } + } + + for _, m := range filteredWorkspaceMetadata { + result = append(result, m) + } + + return result, nil +} diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go index 5876aeb304..7ed344e973 100644 --- a/internal/testing/server/workspaces/store.go +++ b/internal/testing/server/workspaces/store.go @@ -7,7 +7,6 @@ package workspaces import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/stores" ) @@ -38,7 +37,7 @@ func (s *InMemoryWorkspaceStore) Find(idOrName string) (*models.Workspace, error return w, nil } } - return nil, workspaces.ErrWorkspaceNotFound + return nil, stores.ErrWorkspaceNotFound } return w, nil diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index 5a89c6716e..9456cbf02e 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -114,34 +114,34 @@ func GetAgentApiClient(apiUrl, apiKey, clientId string, telemetryEnabled bool) ( return apiClient, nil } -func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, error) { +func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, int, error) { ctx := context.Background() apiClient, err := GetApiClient(nil) if err != nil { - return nil, err + return nil, -1, err } target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetNameOrId).Verbose(verbose).Execute() if err != nil { - return nil, HandleErrorResponse(res, err) + return nil, res.StatusCode, HandleErrorResponse(res, err) } - return target, nil + return target, res.StatusCode, nil } -func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceDTO, error) { +func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceDTO, int, error) { ctx := context.Background() apiClient, err := GetApiClient(nil) if err != nil { - return nil, err + return nil, -1, err } workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceNameOrId).Verbose(verbose).Execute() if err != nil { - return nil, HandleErrorResponse(res, err) + return nil, res.StatusCode, HandleErrorResponse(res, err) } - return workspace, nil + return workspace, res.StatusCode, nil } diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go index 48b8c84322..4b7d278e8b 100644 --- a/internal/util/apiclient/conversion/workspace.go +++ b/internal/util/apiclient/conversion/workspace.go @@ -4,6 +4,8 @@ package conversion import ( + "time" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" @@ -26,13 +28,17 @@ func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { Url: workspaceDTO.Repository.Url, } - var workspaceState *models.WorkspaceState - if workspaceDTO.State != nil { - uptime := workspaceDTO.State.Uptime - workspaceState = &models.WorkspaceState{ - UpdatedAt: workspaceDTO.State.UpdatedAt, + var workspaceMetadata *models.WorkspaceMetadata + if workspaceDTO.Metadata != nil { + updatedAt, err := time.Parse(time.RFC3339, workspaceDTO.Metadata.UpdatedAt) + if err != nil { + updatedAt = time.Unix(0, 0) + } + uptime := workspaceDTO.Metadata.Uptime + workspaceMetadata = &models.WorkspaceMetadata{ + UpdatedAt: updatedAt, Uptime: uint64(uptime), - GitStatus: ToGitStatus(workspaceDTO.State.GitStatus), + GitStatus: ToGitStatus(workspaceDTO.Metadata.GitStatus), } } @@ -54,7 +60,7 @@ func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { BuildConfig: workspaceBuild, Repository: repository, TargetId: workspaceDTO.TargetId, - State: workspaceState, + Metadata: workspaceMetadata, GitProviderConfigId: workspaceDTO.GitProviderConfigId, } diff --git a/internal/util/deleted_name.go b/internal/util/deleted_name.go new file mode 100644 index 0000000000..ce3de9aceb --- /dev/null +++ b/internal/util/deleted_name.go @@ -0,0 +1,14 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "fmt" + + "github.com/daytonaio/daytona/internal/constants" +) + +func AddDeletedToName(name string) string { + return fmt.Sprintf("%s%s%s", constants.DELETED_CIRCUMFIX, name, constants.DELETED_CIRCUMFIX) +} diff --git a/internal/util/pointer.go b/internal/util/pointer.go deleted file mode 100644 index 31aa816a6d..0000000000 --- a/internal/util/pointer.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package util - -// Use generics to create a pointer to a value -func Pointer[T any](d T) *T { - return &d -} diff --git a/internal/util/time.go b/internal/util/time.go index 399b7d19e0..6c0d73fb16 100644 --- a/internal/util/time.go +++ b/internal/util/time.go @@ -45,24 +45,24 @@ func FormatUptime(uptime int32) string { duration := time.Duration(uptime) * time.Second if duration < time.Minute { - return "< 1 minute" + return "< 1 minute ago" } else if duration < time.Hour { minutes := int(duration.Minutes()) if minutes == 1 { - return "1 minute" + return "1 minute ago" } - return fmt.Sprintf("%d minutes", minutes) + return fmt.Sprintf("%d minutes ago", minutes) } else if duration < 24*time.Hour { hours := int(duration.Hours()) if hours == 1 { - return "1 hour" + return "1 hour ago" } - return fmt.Sprintf("%d hours", hours) + return fmt.Sprintf("%d hours ago", hours) } else { days := int(duration.Hours() / 24) if days == 1 { - return "1 day" + return "1 day ago" } - return fmt.Sprintf("%d days", days) + return fmt.Sprintf("%d days ago", days) } } diff --git a/internal/util/map.go b/internal/util/types.go similarity index 50% rename from internal/util/map.go rename to internal/util/types.go index ce92c0052f..15a633c6f2 100644 --- a/internal/util/map.go +++ b/internal/util/types.go @@ -3,6 +3,11 @@ package util +// Use generics to create a pointer to a value +func Pointer[T any](d T) *T { + return &d +} + func ArrayMap[T, U any](data []T, f func(T) U) []U { res := make([]U, 0, len(data)) @@ -12,3 +17,11 @@ func ArrayMap[T, U any](data []T, f func(T) U) []U { return res } + +func StringsToInterface(slice []string) []interface{} { + args := make([]interface{}, len(slice)) + for i, v := range slice { + args[i] = v + } + return args +} diff --git a/internal/util/target.go b/internal/util/workspace.go similarity index 100% rename from internal/util/target.go rename to internal/util/workspace.go diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 8ebf68d8fc..d1fd3399a9 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -33,6 +33,11 @@ func (a *Agent) Start() error { a.startTime = time.Now() + err := a.ensureDefaultProfile() + if err != nil { + return err + } + if a.Config.Mode == agent_config.ModeWorkspace { err := a.startWorkspaceMode() if err != nil { @@ -47,6 +52,13 @@ func (a *Agent) Start() error { }() } + if a.Config.Mode == agent_config.ModeTarget { + err := a.startTargetMode() + if err != nil { + return err + } + } + go func() { err := a.Ssh.Start() if err != nil { @@ -65,12 +77,22 @@ func (a *Agent) Start() error { return <-errChan } -func (a *Agent) startWorkspaceMode() error { - err := a.ensureDefaultProfile() - if err != nil { - return err - } +func (a *Agent) startTargetMode() error { + go func() { + for { + err := a.updateTargetMetadata() + if err != nil { + log.Error(fmt.Sprintf("failed to update target state: %s", err)) + } + time.Sleep(2 * time.Second) + } + }() + + return nil +} + +func (a *Agent) startWorkspaceMode() error { if a.Config.SkipClone == "" { // Ignoring error because we don't want to fail if the git provider is not found gitProvider, _ := a.getGitProvider(a.Workspace.Repository.Url) @@ -140,7 +162,7 @@ func (a *Agent) startWorkspaceMode() error { go func() { for { - err := a.updateWorkspaceState() + err := a.updateWorkspaceMetadata() if err != nil { log.Error(fmt.Sprintf("failed to update workspace state: %s", err)) } @@ -221,7 +243,7 @@ func (a *Agent) uptime() int32 { return max(int32(time.Since(a.startTime).Seconds()), 1) } -func (a *Agent) updateWorkspaceState() error { +func (a *Agent) updateWorkspaceMetadata() error { apiClient, err := apiclient_util.GetAgentApiClient(a.Config.Server.ApiUrl, a.Config.Server.ApiKey, a.Config.ClientId, a.TelemetryEnabled) if err != nil { return err @@ -237,7 +259,7 @@ func (a *Agent) updateWorkspaceState() error { } uptime := a.uptime() - res, err := apiClient.WorkspaceAPI.SetWorkspaceState(context.Background(), a.Config.WorkspaceId).SetState(apiclient.SetWorkspaceState{ + res, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), a.Config.WorkspaceId).SetMetadata(apiclient.SetWorkspaceMetadata{ Uptime: uptime, GitStatus: conversion.ToGitStatusDTO(gitStatus), }).Execute() @@ -247,3 +269,20 @@ func (a *Agent) updateWorkspaceState() error { return nil } + +func (a *Agent) updateTargetMetadata() error { + apiClient, err := apiclient_util.GetAgentApiClient(a.Config.Server.ApiUrl, a.Config.Server.ApiKey, a.Config.ClientId, a.TelemetryEnabled) + if err != nil { + return err + } + + uptime := a.uptime() + res, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), a.Config.TargetId).SetMetadata(apiclient.SetTargetMetadata{ + Uptime: uptime, + }).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + return nil +} diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index ddfeeb7261..86cb4bb395 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -28,8 +28,7 @@ var workspace1 = &models.Workspace{ Name: "daytona", }, TargetId: "123", - State: &models.WorkspaceState{ - UpdatedAt: "123", + Metadata: &models.WorkspaceMetadata{ Uptime: 148, GitStatus: gitStatus1, }, @@ -108,13 +107,13 @@ func TestAgent(t *testing.T) { }) } -func TestAgentHostMode(t *testing.T) { +func TestAgentTargetMode(t *testing.T) { mockGitService := mock_git.NewMockGitService() mockSshServer := mocks.NewMockSshServer() mockTailscaleServer := mocks.NewMockTailscaleServer() mockConfig := *mockConfig - mockConfig.Mode = config.ModeHost + mockConfig.Mode = config.ModeTarget // Create a new Agent instance a := &agent.Agent{ @@ -124,8 +123,8 @@ func TestAgentHostMode(t *testing.T) { Tailscale: mockTailscaleServer, } - t.Run("Start agent in host mode", func(t *testing.T) { - mockConfig.Mode = config.ModeHost + t.Run("Start agent in target mode", func(t *testing.T) { + mockConfig.Mode = config.ModeTarget err := a.Start() require.Equal(t, err, mocks.SshServerStartError) diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index 6b3e285f3b..459ce9f574 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -35,7 +35,7 @@ type Config struct { type Mode string const ( - ModeHost Mode = "host" + ModeTarget Mode = "target" ModeWorkspace Mode = "workspace" ) diff --git a/pkg/api/controllers/job/job.go b/pkg/api/controllers/job/job.go new file mode 100644 index 0000000000..f5700b7d28 --- /dev/null +++ b/pkg/api/controllers/job/job.go @@ -0,0 +1,34 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package job + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// ListJobs godoc +// +// @Tags job +// @Summary List jobs +// @Description List jobs +// @Produce json +// @Success 200 {array} Job +// @Router /job [get] +// +// @id ListJobs +func ListJobs(ctx *gin.Context) { + server := server.GetInstance(nil) + + jobs, err := server.JobService.List(nil) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list jobs: %s", err.Error())) + return + } + + ctx.JSON(200, jobs) +} diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go index e66e59e04d..a8ccc8fa2f 100644 --- a/pkg/api/controllers/target/create.go +++ b/pkg/api/controllers/target/create.go @@ -4,13 +4,11 @@ package target import ( - "errors" "fmt" "net/http" "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/gin-gonic/gin" ) @@ -38,10 +36,6 @@ func CreateTarget(ctx *gin.Context) { t, err := server.TargetService.CreateTarget(ctx.Request.Context(), createTargetReq) if err != nil { - if errors.Is(err, targets.ErrTargetAlreadyExists) { - ctx.AbortWithError(http.StatusConflict, fmt.Errorf("target already exists: %w", err)) - return - } ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create target: %w", err)) return } diff --git a/pkg/api/controllers/target/dto/dto.go b/pkg/api/controllers/target/dto/dto.go index 28a8c45fe3..88b3b7003c 100644 --- a/pkg/api/controllers/target/dto/dto.go +++ b/pkg/api/controllers/target/dto/dto.go @@ -3,9 +3,6 @@ package dto -import "github.com/daytonaio/daytona/pkg/models" - -type SetWorkspaceState struct { - Uptime uint64 `json:"uptime" validate:"required"` - GitStatus *models.GitStatus `json:"gitStatus,omitempty" validate:"optional"` -} // @name SetWorkspaceState +type SetTargetMetadata struct { + Uptime uint64 `json:"uptime" validate:"required"` +} // @name SetTargetMetadata diff --git a/pkg/api/controllers/target/metadata.go b/pkg/api/controllers/target/metadata.go new file mode 100644 index 0000000000..d294b53c2d --- /dev/null +++ b/pkg/api/controllers/target/metadata.go @@ -0,0 +1,48 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// SetTargetMetadata godoc +// +// @Tags target +// @Summary Set target metadata +// @Description Set target metadata +// @Param targetId path string true "Target ID" +// @Param setMetadata body SetTargetMetadata true "Set Metadata" +// @Success 200 +// @Router /target/{targetId}/metadata [post] +// +// @id SetTargetMetadata +func SetTargetMetadata(ctx *gin.Context) { + targetId := ctx.Param("targetId") + + var setTargetMetadataDTO dto.SetTargetMetadata + err := ctx.BindJSON(&setTargetMetadataDTO) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + _, err = server.TargetService.SetTargetMetadata(targetId, &models.TargetMetadata{ + Uptime: setTargetMetadataDTO.Uptime, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target metadata for %s: %w", targetId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index ce3b333ba8..e2f0af7ad8 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -11,6 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -43,9 +44,13 @@ func GetTarget(ctx *gin.Context) { server := server.GetInstance(nil) - t, err := server.TargetService.GetTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, verbose) + t, err := server.TargetService.GetTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{Verbose: verbose}) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get target: %w", err)) + statusCode := http.StatusInternalServerError + if stores.IsTargetNotFound(err) || services.IsTargetDeleted(err) { + statusCode = http.StatusNotFound + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to find target: %w", err)) return } @@ -56,6 +61,8 @@ func GetTarget(ctx *gin.Context) { t.Options = maskedOptions } + util.HideDaytonaEnvVars(&t.EnvVars) + ctx.JSON(200, t) } @@ -85,7 +92,7 @@ func ListTargets(ctx *gin.Context) { server := server.GetInstance(nil) - targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), nil, verbose) + targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), nil, services.TargetRetrievalParams{Verbose: verbose}) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list targets: %w", err)) return @@ -99,6 +106,7 @@ func ListTargets(ctx *gin.Context) { } targetList[i].Options = maskedOptions + util.HideDaytonaEnvVars(&targetList[i].EnvVars) } ctx.JSON(200, targetList) diff --git a/pkg/api/controllers/workspace/dto/dto.go b/pkg/api/controllers/workspace/dto/dto.go index d2ad79480b..dfd11eb3fc 100644 --- a/pkg/api/controllers/workspace/dto/dto.go +++ b/pkg/api/controllers/workspace/dto/dto.go @@ -7,7 +7,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -type SetWorkspaceState struct { +type SetWorkspaceMetadata struct { Uptime uint64 `json:"uptime" validate:"required"` GitStatus *models.GitStatus `json:"gitStatus,omitempty" validate:"optional"` -} // @name SetWorkspaceState +} // @name SetWorkspaceMetadata diff --git a/pkg/api/controllers/workspace/metadata.go b/pkg/api/controllers/workspace/metadata.go new file mode 100644 index 0000000000..e26ed310e4 --- /dev/null +++ b/pkg/api/controllers/workspace/metadata.go @@ -0,0 +1,49 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/api/controllers/workspace/dto" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// SetWorkspaceMetadata godoc +// +// @Tags workspace +// @Summary Set workspace metadata +// @Description Set workspace metadata +// @Param workspaceId path string true "Workspace ID" +// @Param setMetadata body SetWorkspaceMetadata true "Set Metadata" +// @Success 200 +// @Router /workspace/{workspaceId}/metadata [post] +// +// @id SetWorkspaceMetadata +func SetWorkspaceMetadata(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + var setWorkspaceMetadataDTO dto.SetWorkspaceMetadata + err := ctx.BindJSON(&setWorkspaceMetadataDTO) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + _, err = server.WorkspaceService.SetWorkspaceMetadata(workspaceId, &models.WorkspaceMetadata{ + Uptime: setWorkspaceMetadataDTO.Uptime, + GitStatus: setWorkspaceMetadataDTO.GitStatus, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set workspace metadata for %s: %w", workspaceId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/workspace/state.go b/pkg/api/controllers/workspace/state.go deleted file mode 100644 index b86edee39b..0000000000 --- a/pkg/api/controllers/workspace/state.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspace - -import ( - "fmt" - "net/http" - "time" - - "github.com/daytonaio/daytona/pkg/api/controllers/target/dto" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// SetWorkspaceState godoc -// -// @Tags workspace -// @Summary Set workspace state -// @Description Set workspace state -// @Param workspaceId path string true "Workspace ID" -// @Param setState body SetWorkspaceState true "Set State" -// @Success 200 -// @Router /workspace/{workspaceId}/state [post] -// -// @id SetWorkspaceState -func SetWorkspaceState(ctx *gin.Context) { - workspaceId := ctx.Param("workspaceId") - - var setWorkspaceStateDTO dto.SetWorkspaceState - err := ctx.BindJSON(&setWorkspaceStateDTO) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - - _, err = server.WorkspaceService.SetWorkspaceState(workspaceId, &models.WorkspaceState{ - Uptime: setWorkspaceStateDTO.Uptime, - UpdatedAt: time.Now().Format(time.RFC1123), - GitStatus: setWorkspaceStateDTO.GitStatus, - }) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set workspace state for %s: %w", workspaceId, err)) - return - } - - ctx.Status(200) -} diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index 5e2bd97ff3..1030de1db6 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -5,7 +5,6 @@ package toolbox import ( "encoding/json" - "errors" "fmt" "io" "net" @@ -15,8 +14,10 @@ import ( "strings" "github.com/daytonaio/daytona/pkg/agent/toolbox/config" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) @@ -47,9 +48,9 @@ func forwardRequestToToolbox(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, true) + w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { - if errors.Is(err, workspaces.ErrWorkspaceNotFound) { + if stores.IsWorkspaceNotFound(err) { ctx.AbortWithError(http.StatusNotFound, err) return } @@ -60,7 +61,7 @@ func forwardRequestToToolbox(ctx *gin.Context) { var client *http.Client var websocketDialer *websocket.Dialer - workspaceHostname := w.Hostname() + workspaceHostname := common.GetWorkspaceHostname(w.Id) route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/toolbox/", workspaceId), "", 1) query := ctx.Request.URL.Query().Encode() diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go index 0e3e018595..6d17677aea 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/workspace/workspace.go @@ -9,7 +9,10 @@ import ( "net/http" "strconv" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -41,12 +44,18 @@ func GetWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, verbose) + w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{Verbose: verbose}) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace: %w", err)) + statusCode := http.StatusInternalServerError + if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { + statusCode = http.StatusNotFound + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to find workspace: %w", err)) return } + util.HideDaytonaEnvVars(&w.EnvVars) + ctx.JSON(200, w) } @@ -76,11 +85,15 @@ func ListWorkspaces(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), verbose) + workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), services.WorkspaceRetrievalParams{Verbose: verbose}) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspaces: %w", err)) return } + for i, _ := range workspaceList { + util.HideDaytonaEnvVars(&workspaceList[i].EnvVars) + } + ctx.JSON(200, workspaceList) } diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 973819ca35..39f2e87599 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -860,6 +860,30 @@ const docTemplate = `{ } } }, + "/job": { + "get": { + "description": "List jobs", + "produces": [ + "application/json" + ], + "tags": [ + "job" + ], + "summary": "List jobs", + "operationId": "ListJobs", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Job" + } + } + } + } + } + }, "/profile": { "get": { "description": "Get profile data", @@ -1352,6 +1376,39 @@ const docTemplate = `{ } } }, + "/target/{targetId}/metadata": { + "post": { + "description": "Set target metadata", + "tags": [ + "target" + ], + "summary": "Set target metadata", + "operationId": "SetTargetMetadata", + "parameters": [ + { + "type": "string", + "description": "Target ID", + "name": "targetId", + "in": "path", + "required": true + }, + { + "description": "Set Metadata", + "name": "setMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetTargetMetadata" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/set-default": { "patch": { "description": "Set target to be used by default", @@ -1908,21 +1965,30 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/start": { + "/workspace/{workspaceId}/metadata": { "post": { - "description": "Start workspace", + "description": "Set workspace metadata", "tags": [ "workspace" ], - "summary": "Start workspace", - "operationId": "StartWorkspace", + "summary": "Set workspace metadata", + "operationId": "SetWorkspaceMetadata", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", + "description": "Workspace ID", "name": "workspaceId", "in": "path", "required": true + }, + { + "description": "Set Metadata", + "name": "setMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetWorkspaceMetadata" + } } ], "responses": { @@ -1932,30 +1998,21 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/state": { + "/workspace/{workspaceId}/start": { "post": { - "description": "Set workspace state", + "description": "Start workspace", "tags": [ "workspace" ], - "summary": "Set workspace state", - "operationId": "SetWorkspaceState", + "summary": "Start workspace", + "operationId": "StartWorkspace", "parameters": [ { "type": "string", - "description": "Workspace ID", + "description": "Workspace ID or Name", "name": "workspaceId", "in": "path", "required": true - }, - { - "description": "Set State", - "name": "setState", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/SetWorkspaceState" - } } ], "responses": { @@ -4238,6 +4295,59 @@ const docTemplate = `{ } } }, + "Job": { + "type": "object", + "required": [ + "action", + "createdAt", + "id", + "resourceId", + "resourceType", + "state", + "updatedAt" + ], + "properties": { + "action": { + "$ref": "#/definitions/models.JobAction" + }, + "createdAt": { + "type": "string" + }, + "error": { + "type": "string" + }, + "id": { + "type": "string" + }, + "resourceId": { + "type": "string" + }, + "resourceType": { + "$ref": "#/definitions/ResourceType" + }, + "state": { + "$ref": "#/definitions/JobState" + }, + "updatedAt": { + "type": "string" + } + } + }, + "JobState": { + "type": "string", + "enum": [ + "pending", + "running", + "error", + "success" + ], + "x-enum-varnames": [ + "JobStatePending", + "JobStateRunning", + "JobStateError", + "JobStateSuccess" + ] + }, "ListBranchResponse": { "type": "object", "required": [ @@ -4595,6 +4705,35 @@ const docTemplate = `{ } } }, + "ResourceState": { + "type": "object", + "required": [ + "name", + "updatedAt" + ], + "properties": { + "error": { + "type": "string" + }, + "name": { + "$ref": "#/definitions/models.ResourceStateName" + }, + "updatedAt": { + "type": "string" + } + } + }, + "ResourceType": { + "type": "string", + "enum": [ + "workspace", + "target" + ], + "x-enum-varnames": [ + "ResourceTypeWorkspace", + "ResourceTypeTarget" + ] + }, "Sample": { "type": "object", "required": [ @@ -4779,7 +4918,18 @@ const docTemplate = `{ } } }, - "SetWorkspaceState": { + "SetTargetMetadata": { + "type": "object", + "required": [ + "uptime" + ], + "properties": { + "uptime": { + "type": "integer" + } + } + }, + "SetWorkspaceMetadata": { "type": "object", "required": [ "uptime" @@ -4831,6 +4981,7 @@ const docTemplate = `{ "type": "object", "required": [ "default", + "envVars", "id", "name", "options", @@ -4840,9 +4991,21 @@ const docTemplate = `{ "default": { "type": "boolean" }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "id": { "type": "string" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/TargetMetadata" + }, "name": { "type": "string" }, @@ -4928,21 +5091,35 @@ const docTemplate = `{ "type": "object", "required": [ "default", + "envVars", "id", "name", "options", - "providerInfo" + "providerInfo", + "state" ], "properties": { "default": { "type": "boolean" }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "id": { "type": "string" }, "info": { "$ref": "#/definitions/TargetInfo" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/TargetMetadata" + }, "name": { "type": "string" }, @@ -4953,6 +5130,9 @@ const docTemplate = `{ "providerInfo": { "$ref": "#/definitions/TargetProviderInfo" }, + "state": { + "$ref": "#/definitions/ResourceState" + }, "workspaces": { "type": "array", "items": { @@ -4975,6 +5155,25 @@ const docTemplate = `{ } } }, + "TargetMetadata": { + "type": "object", + "required": [ + "targetId", + "updatedAt", + "uptime" + ], + "properties": { + "targetId": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" + } + } + }, "TargetProviderInfo": { "type": "object", "required": [ @@ -5024,15 +5223,18 @@ const docTemplate = `{ "image": { "type": "string" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/WorkspaceMetadata" + }, "name": { "type": "string" }, "repository": { "$ref": "#/definitions/GitRepository" }, - "state": { - "$ref": "#/definitions/WorkspaceState" - }, "target": { "$ref": "#/definitions/Target" }, @@ -5098,6 +5300,7 @@ const docTemplate = `{ "image", "name", "repository", + "state", "target", "targetId", "user" @@ -5124,6 +5327,12 @@ const docTemplate = `{ "info": { "$ref": "#/definitions/WorkspaceInfo" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/WorkspaceMetadata" + }, "name": { "type": "string" }, @@ -5131,7 +5340,7 @@ const docTemplate = `{ "$ref": "#/definitions/GitRepository" }, "state": { - "$ref": "#/definitions/WorkspaceState" + "$ref": "#/definitions/ResourceState" }, "target": { "$ref": "#/definitions/Target" @@ -5178,11 +5387,12 @@ const docTemplate = `{ } } }, - "WorkspaceState": { + "WorkspaceMetadata": { "type": "object", "required": [ "updatedAt", - "uptime" + "uptime", + "workspaceId" ], "properties": { "gitStatus": { @@ -5193,6 +5403,9 @@ const docTemplate = `{ }, "uptime": { "type": "integer" + }, + "workspaceId": { + "type": "string" } } }, @@ -5232,6 +5445,64 @@ const docTemplate = `{ "BuildStateDeleting" ] }, + "models.JobAction": { + "type": "string", + "enum": [ + "create", + "start", + "stop", + "restart", + "delete", + "force-delete" + ], + "x-enum-varnames": [ + "JobActionCreate", + "JobActionStart", + "JobActionStop", + "JobActionRestart", + "JobActionDelete", + "JobActionForceDelete" + ] + }, + "models.ResourceStateName": { + "type": "string", + "enum": [ + "undefined", + "pending-create", + "creating", + "pending-start", + "starting", + "started", + "pending-stop", + "stopping", + "stopped", + "pending-restart", + "error", + "unresponsive", + "pending-delete", + "pending-forced-delete", + "deleting", + "deleted" + ], + "x-enum-varnames": [ + "ResourceStateNameUndefined", + "ResourceStateNamePendingCreate", + "ResourceStateNameCreating", + "ResourceStateNamePendingStart", + "ResourceStateNameStarting", + "ResourceStateNameStarted", + "ResourceStateNamePendingStop", + "ResourceStateNameStopping", + "ResourceStateNameStopped", + "ResourceStateNamePendingRestart", + "ResourceStateNameError", + "ResourceStateNameUnresponsive", + "ResourceStateNamePendingDelete", + "ResourceStateNamePendingForcedDelete", + "ResourceStateNameDeleting", + "ResourceStateNameDeleted" + ] + }, "provider.TargetConfigPropertyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index bb8f19e3fd..b86be7b410 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -857,6 +857,30 @@ } } }, + "/job": { + "get": { + "description": "List jobs", + "produces": [ + "application/json" + ], + "tags": [ + "job" + ], + "summary": "List jobs", + "operationId": "ListJobs", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Job" + } + } + } + } + } + }, "/profile": { "get": { "description": "Get profile data", @@ -1349,6 +1373,39 @@ } } }, + "/target/{targetId}/metadata": { + "post": { + "description": "Set target metadata", + "tags": [ + "target" + ], + "summary": "Set target metadata", + "operationId": "SetTargetMetadata", + "parameters": [ + { + "type": "string", + "description": "Target ID", + "name": "targetId", + "in": "path", + "required": true + }, + { + "description": "Set Metadata", + "name": "setMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetTargetMetadata" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/set-default": { "patch": { "description": "Set target to be used by default", @@ -1905,21 +1962,30 @@ } } }, - "/workspace/{workspaceId}/start": { + "/workspace/{workspaceId}/metadata": { "post": { - "description": "Start workspace", + "description": "Set workspace metadata", "tags": [ "workspace" ], - "summary": "Start workspace", - "operationId": "StartWorkspace", + "summary": "Set workspace metadata", + "operationId": "SetWorkspaceMetadata", "parameters": [ { "type": "string", - "description": "Workspace ID or Name", + "description": "Workspace ID", "name": "workspaceId", "in": "path", "required": true + }, + { + "description": "Set Metadata", + "name": "setMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SetWorkspaceMetadata" + } } ], "responses": { @@ -1929,30 +1995,21 @@ } } }, - "/workspace/{workspaceId}/state": { + "/workspace/{workspaceId}/start": { "post": { - "description": "Set workspace state", + "description": "Start workspace", "tags": [ "workspace" ], - "summary": "Set workspace state", - "operationId": "SetWorkspaceState", + "summary": "Start workspace", + "operationId": "StartWorkspace", "parameters": [ { "type": "string", - "description": "Workspace ID", + "description": "Workspace ID or Name", "name": "workspaceId", "in": "path", "required": true - }, - { - "description": "Set State", - "name": "setState", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/SetWorkspaceState" - } } ], "responses": { @@ -4235,6 +4292,59 @@ } } }, + "Job": { + "type": "object", + "required": [ + "action", + "createdAt", + "id", + "resourceId", + "resourceType", + "state", + "updatedAt" + ], + "properties": { + "action": { + "$ref": "#/definitions/models.JobAction" + }, + "createdAt": { + "type": "string" + }, + "error": { + "type": "string" + }, + "id": { + "type": "string" + }, + "resourceId": { + "type": "string" + }, + "resourceType": { + "$ref": "#/definitions/ResourceType" + }, + "state": { + "$ref": "#/definitions/JobState" + }, + "updatedAt": { + "type": "string" + } + } + }, + "JobState": { + "type": "string", + "enum": [ + "pending", + "running", + "error", + "success" + ], + "x-enum-varnames": [ + "JobStatePending", + "JobStateRunning", + "JobStateError", + "JobStateSuccess" + ] + }, "ListBranchResponse": { "type": "object", "required": [ @@ -4592,6 +4702,35 @@ } } }, + "ResourceState": { + "type": "object", + "required": [ + "name", + "updatedAt" + ], + "properties": { + "error": { + "type": "string" + }, + "name": { + "$ref": "#/definitions/models.ResourceStateName" + }, + "updatedAt": { + "type": "string" + } + } + }, + "ResourceType": { + "type": "string", + "enum": [ + "workspace", + "target" + ], + "x-enum-varnames": [ + "ResourceTypeWorkspace", + "ResourceTypeTarget" + ] + }, "Sample": { "type": "object", "required": [ @@ -4776,7 +4915,18 @@ } } }, - "SetWorkspaceState": { + "SetTargetMetadata": { + "type": "object", + "required": [ + "uptime" + ], + "properties": { + "uptime": { + "type": "integer" + } + } + }, + "SetWorkspaceMetadata": { "type": "object", "required": [ "uptime" @@ -4828,6 +4978,7 @@ "type": "object", "required": [ "default", + "envVars", "id", "name", "options", @@ -4837,9 +4988,21 @@ "default": { "type": "boolean" }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "id": { "type": "string" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/TargetMetadata" + }, "name": { "type": "string" }, @@ -4925,21 +5088,35 @@ "type": "object", "required": [ "default", + "envVars", "id", "name", "options", - "providerInfo" + "providerInfo", + "state" ], "properties": { "default": { "type": "boolean" }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "id": { "type": "string" }, "info": { "$ref": "#/definitions/TargetInfo" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/TargetMetadata" + }, "name": { "type": "string" }, @@ -4950,6 +5127,9 @@ "providerInfo": { "$ref": "#/definitions/TargetProviderInfo" }, + "state": { + "$ref": "#/definitions/ResourceState" + }, "workspaces": { "type": "array", "items": { @@ -4972,6 +5152,25 @@ } } }, + "TargetMetadata": { + "type": "object", + "required": [ + "targetId", + "updatedAt", + "uptime" + ], + "properties": { + "targetId": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" + } + } + }, "TargetProviderInfo": { "type": "object", "required": [ @@ -5021,15 +5220,18 @@ "image": { "type": "string" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/WorkspaceMetadata" + }, "name": { "type": "string" }, "repository": { "$ref": "#/definitions/GitRepository" }, - "state": { - "$ref": "#/definitions/WorkspaceState" - }, "target": { "$ref": "#/definitions/Target" }, @@ -5095,6 +5297,7 @@ "image", "name", "repository", + "state", "target", "targetId", "user" @@ -5121,6 +5324,12 @@ "info": { "$ref": "#/definitions/WorkspaceInfo" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, + "metadata": { + "$ref": "#/definitions/WorkspaceMetadata" + }, "name": { "type": "string" }, @@ -5128,7 +5337,7 @@ "$ref": "#/definitions/GitRepository" }, "state": { - "$ref": "#/definitions/WorkspaceState" + "$ref": "#/definitions/ResourceState" }, "target": { "$ref": "#/definitions/Target" @@ -5175,11 +5384,12 @@ } } }, - "WorkspaceState": { + "WorkspaceMetadata": { "type": "object", "required": [ "updatedAt", - "uptime" + "uptime", + "workspaceId" ], "properties": { "gitStatus": { @@ -5190,6 +5400,9 @@ }, "uptime": { "type": "integer" + }, + "workspaceId": { + "type": "string" } } }, @@ -5229,6 +5442,64 @@ "BuildStateDeleting" ] }, + "models.JobAction": { + "type": "string", + "enum": [ + "create", + "start", + "stop", + "restart", + "delete", + "force-delete" + ], + "x-enum-varnames": [ + "JobActionCreate", + "JobActionStart", + "JobActionStop", + "JobActionRestart", + "JobActionDelete", + "JobActionForceDelete" + ] + }, + "models.ResourceStateName": { + "type": "string", + "enum": [ + "undefined", + "pending-create", + "creating", + "pending-start", + "starting", + "started", + "pending-stop", + "stopping", + "stopped", + "pending-restart", + "error", + "unresponsive", + "pending-delete", + "pending-forced-delete", + "deleting", + "deleted" + ], + "x-enum-varnames": [ + "ResourceStateNameUndefined", + "ResourceStateNamePendingCreate", + "ResourceStateNameCreating", + "ResourceStateNamePendingStart", + "ResourceStateNameStarting", + "ResourceStateNameStarted", + "ResourceStateNamePendingStop", + "ResourceStateNameStopping", + "ResourceStateNameStopped", + "ResourceStateNamePendingRestart", + "ResourceStateNameError", + "ResourceStateNameUnresponsive", + "ResourceStateNamePendingDelete", + "ResourceStateNamePendingForcedDelete", + "ResourceStateNameDeleting", + "ResourceStateNameDeleted" + ] + }, "provider.TargetConfigPropertyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 4739285a9e..f13b15ba0f 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -623,6 +623,45 @@ definitions: - downloadUrls - name type: object + Job: + properties: + action: + $ref: '#/definitions/models.JobAction' + createdAt: + type: string + error: + type: string + id: + type: string + resourceId: + type: string + resourceType: + $ref: '#/definitions/ResourceType' + state: + $ref: '#/definitions/JobState' + updatedAt: + type: string + required: + - action + - createdAt + - id + - resourceId + - resourceType + - state + - updatedAt + type: object + JobState: + enum: + - pending + - running + - error + - success + type: string + x-enum-varnames: + - JobStatePending + - JobStateRunning + - JobStateError + - JobStateSuccess ListBranchResponse: properties: branches: @@ -864,6 +903,26 @@ definitions: required: - url type: object + ResourceState: + properties: + error: + type: string + name: + $ref: '#/definitions/models.ResourceStateName' + updatedAt: + type: string + required: + - name + - updatedAt + type: object + ResourceType: + enum: + - workspace + - target + type: string + x-enum-varnames: + - ResourceTypeWorkspace + - ResourceTypeTarget Sample: properties: description: @@ -990,7 +1049,14 @@ definitions: - providerId - token type: object - SetWorkspaceState: + SetTargetMetadata: + properties: + uptime: + type: integer + required: + - uptime + type: object + SetWorkspaceMetadata: properties: gitStatus: $ref: '#/definitions/GitStatus' @@ -1031,8 +1097,16 @@ definitions: properties: default: type: boolean + envVars: + additionalProperties: + type: string + type: object id: type: string + lastJob: + $ref: '#/definitions/Job' + metadata: + $ref: '#/definitions/TargetMetadata' name: type: string options: @@ -1046,6 +1120,7 @@ definitions: type: array required: - default + - envVars - id - name - options @@ -1105,10 +1180,18 @@ definitions: properties: default: type: boolean + envVars: + additionalProperties: + type: string + type: object id: type: string info: $ref: '#/definitions/TargetInfo' + lastJob: + $ref: '#/definitions/Job' + metadata: + $ref: '#/definitions/TargetMetadata' name: type: string options: @@ -1116,16 +1199,20 @@ definitions: type: string providerInfo: $ref: '#/definitions/TargetProviderInfo' + state: + $ref: '#/definitions/ResourceState' workspaces: items: $ref: '#/definitions/Workspace' type: array required: - default + - envVars - id - name - options - providerInfo + - state type: object TargetInfo: properties: @@ -1136,6 +1223,19 @@ definitions: required: - name type: object + TargetMetadata: + properties: + targetId: + type: string + updatedAt: + type: string + uptime: + type: integer + required: + - targetId + - updatedAt + - uptime + type: object TargetProviderInfo: properties: label: @@ -1162,12 +1262,14 @@ definitions: type: string image: type: string + lastJob: + $ref: '#/definitions/Job' + metadata: + $ref: '#/definitions/WorkspaceMetadata' name: type: string repository: $ref: '#/definitions/GitRepository' - state: - $ref: '#/definitions/WorkspaceState' target: $ref: '#/definitions/Target' targetId: @@ -1232,12 +1334,16 @@ definitions: type: string info: $ref: '#/definitions/WorkspaceInfo' + lastJob: + $ref: '#/definitions/Job' + metadata: + $ref: '#/definitions/WorkspaceMetadata' name: type: string repository: $ref: '#/definitions/GitRepository' state: - $ref: '#/definitions/WorkspaceState' + $ref: '#/definitions/ResourceState' target: $ref: '#/definitions/Target' targetId: @@ -1250,6 +1356,7 @@ definitions: - image - name - repository + - state - target - targetId - user @@ -1277,7 +1384,7 @@ definitions: - name - targetId type: object - WorkspaceState: + WorkspaceMetadata: properties: gitStatus: $ref: '#/definitions/GitStatus' @@ -1285,9 +1392,12 @@ definitions: type: string uptime: type: integer + workspaceId: + type: string required: - updatedAt - uptime + - workspaceId type: object models.ApiKeyType: enum: @@ -1319,6 +1429,58 @@ definitions: - BuildStatePendingDelete - BuildStatePendingForcedDelete - BuildStateDeleting + models.JobAction: + enum: + - create + - start + - stop + - restart + - delete + - force-delete + type: string + x-enum-varnames: + - JobActionCreate + - JobActionStart + - JobActionStop + - JobActionRestart + - JobActionDelete + - JobActionForceDelete + models.ResourceStateName: + enum: + - undefined + - pending-create + - creating + - pending-start + - starting + - started + - pending-stop + - stopping + - stopped + - pending-restart + - error + - unresponsive + - pending-delete + - pending-forced-delete + - deleting + - deleted + type: string + x-enum-varnames: + - ResourceStateNameUndefined + - ResourceStateNamePendingCreate + - ResourceStateNameCreating + - ResourceStateNamePendingStart + - ResourceStateNameStarting + - ResourceStateNameStarted + - ResourceStateNamePendingStop + - ResourceStateNameStopping + - ResourceStateNameStopped + - ResourceStateNamePendingRestart + - ResourceStateNameError + - ResourceStateNameUnresponsive + - ResourceStateNamePendingDelete + - ResourceStateNamePendingForcedDelete + - ResourceStateNameDeleting + - ResourceStateNameDeleted provider.TargetConfigPropertyType: enum: - string @@ -1908,6 +2070,22 @@ paths: type: string type: object summary: Health check + /job: + get: + description: List jobs + operationId: ListJobs + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/Job' + type: array + summary: List jobs + tags: + - job /profile: delete: description: Delete profile data @@ -2236,6 +2414,28 @@ paths: summary: Get target info tags: - target + /target/{targetId}/metadata: + post: + description: Set target metadata + operationId: SetTargetMetadata + parameters: + - description: Target ID + in: path + name: targetId + required: true + type: string + - description: Set Metadata + in: body + name: setMetadata + required: true + schema: + $ref: '#/definitions/SetTargetMetadata' + responses: + "200": + description: OK + summary: Set target metadata + tags: + - target /target/{targetId}/set-default: patch: description: Set target to be used by default @@ -2608,42 +2808,42 @@ paths: summary: Get workspace info tags: - workspace - /workspace/{workspaceId}/start: + /workspace/{workspaceId}/metadata: post: - description: Start workspace - operationId: StartWorkspace + description: Set workspace metadata + operationId: SetWorkspaceMetadata parameters: - - description: Workspace ID or Name + - description: Workspace ID in: path name: workspaceId required: true type: string + - description: Set Metadata + in: body + name: setMetadata + required: true + schema: + $ref: '#/definitions/SetWorkspaceMetadata' responses: "200": description: OK - summary: Start workspace + summary: Set workspace metadata tags: - workspace - /workspace/{workspaceId}/state: + /workspace/{workspaceId}/start: post: - description: Set workspace state - operationId: SetWorkspaceState + description: Start workspace + operationId: StartWorkspace parameters: - - description: Workspace ID + - description: Workspace ID or Name in: path name: workspaceId required: true type: string - - description: Set State - in: body - name: setState - required: true - schema: - $ref: '#/definitions/SetWorkspaceState' responses: "200": description: OK - summary: Set workspace state + summary: Start workspace tags: - workspace /workspace/{workspaceId}/stop: diff --git a/pkg/api/middlewares/telemetry.go b/pkg/api/middlewares/telemetry.go index c3edd209fe..c5049ccfee 100644 --- a/pkg/api/middlewares/telemetry.go +++ b/pkg/api/middlewares/telemetry.go @@ -17,9 +17,10 @@ import ( ) var ignorePaths = map[string]bool{ - "/health": true, - "/target/:targetId/:workspaceId/state": true, - "/server/network-key": true, + "/health": true, + "/target/:targetId/:metadata": true, + "/workspace/:workspaceId/:metadata": true, + "/server/network-key": true, } func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.HandlerFunc { diff --git a/pkg/api/server.go b/pkg/api/server.go index 25f49bb374..4e2784962c 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -38,6 +38,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/containerregistry" "github.com/daytonaio/daytona/pkg/api/controllers/gitprovider" "github.com/daytonaio/daytona/pkg/api/controllers/health" + "github.com/daytonaio/daytona/pkg/api/controllers/job" log_controller "github.com/daytonaio/daytona/pkg/api/controllers/log" "github.com/daytonaio/daytona/pkg/api/controllers/profiledata" "github.com/daytonaio/daytona/pkg/api/controllers/provider" @@ -224,6 +225,11 @@ func (a *ApiServer) Start() error { workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) } + jobController := protected.Group("/job") + { + jobController.GET("/", job.ListJobs) + } + workspaceConfigController := protected.Group("/workspace-config") { // Defining the prebuild routes first to avoid conflicts with the workspace config routes @@ -332,7 +338,8 @@ func (a *ApiServer) Start() error { workspaceGroup := protected.Group("/") workspaceGroup.Use(middlewares.WorkspaceAuthMiddleware()) { - workspaceGroup.POST(workspaceController.BasePath()+"/:workspaceId/state", workspace.SetWorkspaceState) + workspaceGroup.POST(workspaceController.BasePath()+"/:workspaceId/metadata", workspace.SetWorkspaceMetadata) + workspaceGroup.POST(targetController.BasePath()+"/:targetId/metadata", target.SetTargetMetadata) } a.httpServer = &http.Server{ diff --git a/pkg/api/util/hide.go b/pkg/api/util/hide.go new file mode 100644 index 0000000000..fe5439d4e8 --- /dev/null +++ b/pkg/api/util/hide.go @@ -0,0 +1,72 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "encoding/json" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/server/workspaces" +) + +func GetMaskedOptions(server *server.Server, providerName, options string) (string, error) { + p, err := server.ProviderManager.GetProvider(providerName) + if err != nil { + return "", err + } + + manifest, err := (*p).GetTargetConfigManifest() + if err != nil { + return "", err + } + + var opts map[string]interface{} + err = json.Unmarshal([]byte(options), &opts) + if err != nil { + return "", err + } + + for name, property := range *manifest { + if property.InputMasked { + delete(opts, name) + } + } + + updatedOptions, err := json.MarshalIndent(opts, "", " ") + if err != nil { + return "", err + } + + return string(updatedOptions), nil +} + +func HideDaytonaEnvVars(envVars *map[string]string) { + for _, daytonaEnvVarKey := range getDaytonaEnvVarKeys() { + delete(*envVars, daytonaEnvVarKey) + } +} + +func getDaytonaEnvVarKeys() []string { + var result []string + + wsEnvVars := workspaces.GetWorkspaceEnvVars(&models.Workspace{ + Repository: &gitprovider.GitRepository{}, + }, workspaces.WorkspaceEnvVarParams{ + TelemetryEnabled: true, + }) + + targetEnvVars := targets.GetTargetEnvVars(&models.Target{}, targets.TargetEnvVarParams{}) + + envVars := util.MergeEnvVars(wsEnvVars, targetEnvVars) + + for k := range envVars { + result = append(result, k) + } + + return result +} diff --git a/pkg/api/util/mask-options.go b/pkg/api/util/mask-options.go deleted file mode 100644 index 42f6f7178d..0000000000 --- a/pkg/api/util/mask-options.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package util - -import ( - "encoding/json" - - "github.com/daytonaio/daytona/pkg/server" -) - -func GetMaskedOptions(server *server.Server, providerName, options string) (string, error) { - p, err := server.ProviderManager.GetProvider(providerName) - if err != nil { - return "", err - } - - manifest, err := (*p).GetTargetConfigManifest() - if err != nil { - return "", err - } - - var opts map[string]interface{} - err = json.Unmarshal([]byte(options), &opts) - if err != nil { - return "", err - } - - for name, property := range *manifest { - if property.InputMasked { - delete(opts, name) - } - } - - updatedOptions, err := json.MarshalIndent(opts, "", " ") - if err != nil { - return "", err - } - - return string(updatedOptions), nil -} diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index bbb0792fa8..4ad0a37ac4 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -104,6 +104,7 @@ Class | Method | HTTP request | Description *GitProviderAPI* | [**ListGitProvidersForUrl**](docs/GitProviderAPI.md#listgitprovidersforurl) | **Get** /gitprovider/for-url/{url} | List Git providers for url *GitProviderAPI* | [**RemoveGitProvider**](docs/GitProviderAPI.md#removegitprovider) | **Delete** /gitprovider/{gitProviderId} | Remove Git provider *GitProviderAPI* | [**SetGitProvider**](docs/GitProviderAPI.md#setgitprovider) | **Put** /gitprovider | Set Git provider +*JobAPI* | [**ListJobs**](docs/JobAPI.md#listjobs) | **Get** /job | List jobs *PrebuildAPI* | [**DeletePrebuild**](docs/PrebuildAPI.md#deleteprebuild) | **Delete** /workspace-config/{configName}/prebuild/{prebuildId} | Delete prebuild *PrebuildAPI* | [**GetPrebuild**](docs/PrebuildAPI.md#getprebuild) | **Get** /workspace-config/{configName}/prebuild/{prebuildId} | Get prebuild *PrebuildAPI* | [**ListPrebuilds**](docs/PrebuildAPI.md#listprebuilds) | **Get** /workspace-config/prebuild | List prebuilds @@ -127,6 +128,7 @@ Class | Method | HTTP request | Description *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets *TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target *TargetAPI* | [**SetDefaultTarget**](docs/TargetAPI.md#setdefaulttarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default +*TargetAPI* | [**SetTargetMetadata**](docs/TargetAPI.md#settargetmetadata) | **Post** /target/{targetId}/metadata | Set target metadata *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs @@ -136,7 +138,7 @@ Class | Method | HTTP request | Description *WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info *WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces *WorkspaceAPI* | [**RemoveWorkspace**](docs/WorkspaceAPI.md#removeworkspace) | **Delete** /workspace/{workspaceId} | Remove workspace -*WorkspaceAPI* | [**SetWorkspaceState**](docs/WorkspaceAPI.md#setworkspacestate) | **Post** /workspace/{workspaceId}/state | Set workspace state +*WorkspaceAPI* | [**SetWorkspaceMetadata**](docs/WorkspaceAPI.md#setworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata *WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace *WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace *WorkspaceConfigAPI* | [**DeleteWorkspaceConfig**](docs/WorkspaceConfigAPI.md#deleteworkspaceconfig) | **Delete** /workspace-config/{configName} | Delete workspace config data @@ -224,6 +226,8 @@ Class | Method | HTTP request | Description - [GitStatus](docs/GitStatus.md) - [GitUser](docs/GitUser.md) - [InstallProviderRequest](docs/InstallProviderRequest.md) + - [Job](docs/Job.md) + - [JobState](docs/JobState.md) - [ListBranchResponse](docs/ListBranchResponse.md) - [LogFileConfig](docs/LogFileConfig.md) - [LspCompletionParams](docs/LspCompletionParams.md) @@ -236,6 +240,8 @@ Class | Method | HTTP request | Description - [Match](docs/Match.md) - [ModelsApiKeyType](docs/ModelsApiKeyType.md) - [ModelsBuildState](docs/ModelsBuildState.md) + - [ModelsJobAction](docs/ModelsJobAction.md) + - [ModelsResourceStateName](docs/ModelsResourceStateName.md) - [NetworkKey](docs/NetworkKey.md) - [Position](docs/Position.md) - [PrebuildConfig](docs/PrebuildConfig.md) @@ -246,6 +252,8 @@ Class | Method | HTTP request | Description - [ReplaceRequest](docs/ReplaceRequest.md) - [ReplaceResult](docs/ReplaceResult.md) - [RepositoryUrl](docs/RepositoryUrl.md) + - [ResourceState](docs/ResourceState.md) + - [ResourceType](docs/ResourceType.md) - [Sample](docs/Sample.md) - [SearchFilesResponse](docs/SearchFilesResponse.md) - [ServerConfig](docs/ServerConfig.md) @@ -253,7 +261,8 @@ Class | Method | HTTP request | Description - [SessionExecuteRequest](docs/SessionExecuteRequest.md) - [SessionExecuteResponse](docs/SessionExecuteResponse.md) - [SetGitProviderConfig](docs/SetGitProviderConfig.md) - - [SetWorkspaceState](docs/SetWorkspaceState.md) + - [SetTargetMetadata](docs/SetTargetMetadata.md) + - [SetWorkspaceMetadata](docs/SetWorkspaceMetadata.md) - [SigningMethod](docs/SigningMethod.md) - [Status](docs/Status.md) - [Target](docs/Target.md) @@ -261,13 +270,14 @@ Class | Method | HTTP request | Description - [TargetConfigProperty](docs/TargetConfigProperty.md) - [TargetDTO](docs/TargetDTO.md) - [TargetInfo](docs/TargetInfo.md) + - [TargetMetadata](docs/TargetMetadata.md) - [TargetProviderInfo](docs/TargetProviderInfo.md) - [Workspace](docs/Workspace.md) - [WorkspaceConfig](docs/WorkspaceConfig.md) - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) - [WorkspaceInfo](docs/WorkspaceInfo.md) - - [WorkspaceState](docs/WorkspaceState.md) + - [WorkspaceMetadata](docs/WorkspaceMetadata.md) ## Documentation For Authorization diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 947e26b745..a6d0617d33 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -618,6 +618,22 @@ paths: type: object description: OK summary: Health check + /job: + get: + description: List jobs + operationId: ListJobs + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/Job' + type: array + description: OK + summary: List jobs + tags: + - job /profile: delete: description: Delete profile data @@ -961,6 +977,32 @@ paths: summary: Get target info tags: - target + /target/{targetId}/metadata: + post: + description: Set target metadata + operationId: SetTargetMetadata + parameters: + - description: Target ID + in: path + name: targetId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/SetTargetMetadata' + description: Set Metadata + required: true + responses: + "200": + content: {} + description: OK + summary: Set target metadata + tags: + - target + x-codegen-request-body-name: setMetadata /target/{targetId}/set-default: patch: description: Set target to be used by default @@ -1363,50 +1405,50 @@ paths: summary: Get workspace info tags: - workspace - /workspace/{workspaceId}/start: + /workspace/{workspaceId}/metadata: post: - description: Start workspace - operationId: StartWorkspace + description: Set workspace metadata + operationId: SetWorkspaceMetadata parameters: - - description: Workspace ID or Name + - description: Workspace ID in: path name: workspaceId required: true schema: type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/SetWorkspaceMetadata' + description: Set Metadata + required: true responses: "200": content: {} description: OK - summary: Start workspace + summary: Set workspace metadata tags: - workspace - /workspace/{workspaceId}/state: + x-codegen-request-body-name: setMetadata + /workspace/{workspaceId}/start: post: - description: Set workspace state - operationId: SetWorkspaceState + description: Start workspace + operationId: StartWorkspace parameters: - - description: Workspace ID + - description: Workspace ID or Name in: path name: workspaceId required: true schema: type: string - requestBody: - content: - '*/*': - schema: - $ref: '#/components/schemas/SetWorkspaceState' - description: Set State - required: true responses: "200": content: {} description: OK - summary: Set workspace state + summary: Start workspace tags: - workspace - x-codegen-request-body-name: setState /workspace/{workspaceId}/stop: post: description: Stop workspace @@ -3257,7 +3299,7 @@ components: type: object GitStatus: example: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -3267,7 +3309,7 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch properties: @@ -3324,6 +3366,54 @@ components: - downloadUrls - name type: object + Job: + example: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + properties: + action: + $ref: '#/components/schemas/models.JobAction' + createdAt: + type: string + error: + type: string + id: + type: string + resourceId: + type: string + resourceType: + $ref: '#/components/schemas/ResourceType' + state: + $ref: '#/components/schemas/JobState' + updatedAt: + type: string + required: + - action + - createdAt + - id + - resourceId + - resourceType + - state + - updatedAt + type: object + JobState: + enum: + - pending + - running + - error + - success + type: string + x-enum-varnames: + - JobStatePending + - JobStateRunning + - JobStateError + - JobStateSuccess ListBranchResponse: example: branches: @@ -3670,6 +3760,30 @@ components: required: - url type: object + ResourceState: + example: + name: null + error: error + updatedAt: updatedAt + properties: + error: + type: string + name: + $ref: '#/components/schemas/models.ResourceStateName' + updatedAt: + type: string + required: + - name + - updatedAt + type: object + ResourceType: + enum: + - workspace + - target + type: string + x-enum-varnames: + - ResourceTypeWorkspace + - ResourceTypeTarget Sample: example: name: name @@ -3856,10 +3970,19 @@ components: - providerId - token type: object - SetWorkspaceState: + SetTargetMetadata: + example: + uptime: 0 + properties: + uptime: + type: integer + required: + - uptime + type: object + SetWorkspaceMetadata: example: gitStatus: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -3869,7 +3992,7 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch uptime: 0 @@ -3912,6 +4035,21 @@ components: Target: example: default: true + metadata: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars name: name options: options id: id @@ -3925,8 +4063,16 @@ components: properties: default: type: boolean + envVars: + additionalProperties: + type: string + type: object id: type: string + lastJob: + $ref: '#/components/schemas/Job' + metadata: + $ref: '#/components/schemas/TargetMetadata' name: type: string options: @@ -3940,6 +4086,7 @@ components: type: array required: - default + - envVars - id - name - options @@ -4005,9 +4152,28 @@ components: TargetDTO: example: default: true + metadata: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars name: name options: options id: id + state: + name: null + error: error + updatedAt: updatedAt workspaces: - buildConfig: cachedBuild: @@ -4017,14 +4183,9 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image - targetId: targetId - envVars: - key: envVars - name: name - id: id - state: + metadata: gitStatus: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -4034,11 +4195,26 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch updatedAt: updatedAt - uptime: 1 + uptime: 5 + workspaceId: workspaceId + targetId: targetId + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars + name: name + id: id repository: owner: owner path: path @@ -4053,6 +4229,21 @@ components: user: user target: default: true + metadata: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars name: name options: options id: id @@ -4071,14 +4262,9 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image - targetId: targetId - envVars: - key: envVars - name: name - id: id - state: + metadata: gitStatus: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -4088,11 +4274,26 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch updatedAt: updatedAt - uptime: 1 + uptime: 5 + workspaceId: workspaceId + targetId: targetId + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars + name: name + id: id repository: owner: owner path: path @@ -4107,6 +4308,21 @@ components: user: user target: default: true + metadata: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars name: name options: options id: id @@ -4127,10 +4343,18 @@ components: properties: default: type: boolean + envVars: + additionalProperties: + type: string + type: object id: type: string info: $ref: '#/components/schemas/TargetInfo' + lastJob: + $ref: '#/components/schemas/Job' + metadata: + $ref: '#/components/schemas/TargetMetadata' name: type: string options: @@ -4138,16 +4362,20 @@ components: type: string providerInfo: $ref: '#/components/schemas/TargetProviderInfo' + state: + $ref: '#/components/schemas/ResourceState' workspaces: items: $ref: '#/components/schemas/Workspace' type: array required: - default + - envVars - id - name - options - providerInfo + - state type: object TargetInfo: example: @@ -4161,6 +4389,23 @@ components: required: - name type: object + TargetMetadata: + example: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + properties: + targetId: + type: string + updatedAt: + type: string + uptime: + type: integer + required: + - targetId + - updatedAt + - uptime + type: object TargetProviderInfo: example: name: name @@ -4187,14 +4432,9 @@ components: filePath: filePath gitProviderConfigId: gitProviderConfigId image: image - targetId: targetId - envVars: - key: envVars - name: name - id: id - state: + metadata: gitStatus: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -4204,11 +4444,26 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch updatedAt: updatedAt - uptime: 1 + uptime: 5 + workspaceId: workspaceId + targetId: targetId + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars + name: name + id: id repository: owner: owner path: path @@ -4223,6 +4478,21 @@ components: user: user target: default: true + metadata: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars name: name options: options id: id @@ -4246,12 +4516,14 @@ components: type: string image: type: string + lastJob: + $ref: '#/components/schemas/Job' + metadata: + $ref: '#/components/schemas/WorkspaceMetadata' name: type: string repository: $ref: '#/components/schemas/GitRepository' - state: - $ref: '#/components/schemas/WorkspaceState' target: $ref: '#/components/schemas/Target' targetId: @@ -4332,22 +4604,11 @@ components: type: object WorkspaceDTO: example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath gitProviderConfigId: gitProviderConfigId image: image - targetId: targetId - envVars: - key: envVars - name: name - id: id - state: + metadata: gitStatus: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -4357,11 +4618,15 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch updatedAt: updatedAt - uptime: 1 + uptime: 5 + workspaceId: workspaceId + targetId: targetId + envVars: + key: envVars repository: owner: owner path: path @@ -4373,15 +4638,23 @@ components: cloneTarget: null sha: sha url: url - user: user - info: - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name target: default: true + metadata: + targetId: targetId + updatedAt: updatedAt + uptime: 0 + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + envVars: + key: envVars name: name options: options id: id @@ -4392,6 +4665,34 @@ components: name: name label: label version: version + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + name: name + id: id + state: + name: null + error: error + updatedAt: updatedAt + user: user + info: + providerMetadata: providerMetadata + targetId: targetId + isRunning: true + created: created + name: name properties: buildConfig: $ref: '#/components/schemas/BuildConfig' @@ -4407,12 +4708,16 @@ components: type: string info: $ref: '#/components/schemas/WorkspaceInfo' + lastJob: + $ref: '#/components/schemas/Job' + metadata: + $ref: '#/components/schemas/WorkspaceMetadata' name: type: string repository: $ref: '#/components/schemas/GitRepository' state: - $ref: '#/components/schemas/WorkspaceState' + $ref: '#/components/schemas/ResourceState' target: $ref: '#/components/schemas/Target' targetId: @@ -4425,6 +4730,7 @@ components: - image - name - repository + - state - target - targetId - user @@ -4460,10 +4766,10 @@ components: - name - targetId type: object - WorkspaceState: + WorkspaceMetadata: example: gitStatus: - behind: 6 + behind: 1 fileStatus: - extra: extra name: name @@ -4473,11 +4779,12 @@ components: name: name staging: null worktree: null - ahead: 0 + ahead: 6 branchPublished: true currentBranch: currentBranch updatedAt: updatedAt - uptime: 1 + uptime: 5 + workspaceId: workspaceId properties: gitStatus: $ref: '#/components/schemas/GitStatus' @@ -4485,9 +4792,12 @@ components: type: string uptime: type: integer + workspaceId: + type: string required: - updatedAt - uptime + - workspaceId type: object models.ApiKeyType: enum: @@ -4519,6 +4829,58 @@ components: - BuildStatePendingDelete - BuildStatePendingForcedDelete - BuildStateDeleting + models.JobAction: + enum: + - create + - start + - stop + - restart + - delete + - force-delete + type: string + x-enum-varnames: + - JobActionCreate + - JobActionStart + - JobActionStop + - JobActionRestart + - JobActionDelete + - JobActionForceDelete + models.ResourceStateName: + enum: + - undefined + - pending-create + - creating + - pending-start + - starting + - started + - pending-stop + - stopping + - stopped + - pending-restart + - error + - unresponsive + - pending-delete + - pending-forced-delete + - deleting + - deleted + type: string + x-enum-varnames: + - ResourceStateNameUndefined + - ResourceStateNamePendingCreate + - ResourceStateNameCreating + - ResourceStateNamePendingStart + - ResourceStateNameStarting + - ResourceStateNameStarted + - ResourceStateNamePendingStop + - ResourceStateNameStopping + - ResourceStateNameStopped + - ResourceStateNamePendingRestart + - ResourceStateNameError + - ResourceStateNameUnresponsive + - ResourceStateNamePendingDelete + - ResourceStateNamePendingForcedDelete + - ResourceStateNameDeleting + - ResourceStateNameDeleted provider.TargetConfigPropertyType: enum: - string diff --git a/pkg/apiclient/api_job.go b/pkg/apiclient/api_job.go new file mode 100644 index 0000000000..0f2a3b60b1 --- /dev/null +++ b/pkg/apiclient/api_job.go @@ -0,0 +1,136 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" +) + +// JobAPIService JobAPI service +type JobAPIService service + +type ApiListJobsRequest struct { + ctx context.Context + ApiService *JobAPIService +} + +func (r ApiListJobsRequest) Execute() ([]Job, *http.Response, error) { + return r.ApiService.ListJobsExecute(r) +} + +/* +ListJobs List jobs + +List jobs + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListJobsRequest +*/ +func (a *JobAPIService) ListJobs(ctx context.Context) ApiListJobsRequest { + return ApiListJobsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []Job +func (a *JobAPIService) ListJobsExecute(r ApiListJobsRequest) ([]Job, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []Job + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "JobAPIService.ListJobs") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/job" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index 3d096b0db0..5cacc61d1a 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -622,6 +622,124 @@ func (a *TargetAPIService) SetDefaultTargetExecute(r ApiSetDefaultTargetRequest) return localVarHTTPResponse, nil } +type ApiSetTargetMetadataRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + setMetadata *SetTargetMetadata +} + +// Set Metadata +func (r ApiSetTargetMetadataRequest) SetMetadata(setMetadata SetTargetMetadata) ApiSetTargetMetadataRequest { + r.setMetadata = &setMetadata + return r +} + +func (r ApiSetTargetMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.SetTargetMetadataExecute(r) +} + +/* +SetTargetMetadata Set target metadata + +Set target metadata + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param targetId Target ID + @return ApiSetTargetMetadataRequest +*/ +func (a *TargetAPIService) SetTargetMetadata(ctx context.Context, targetId string) ApiSetTargetMetadataRequest { + return ApiSetTargetMetadataRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + } +} + +// Execute executes the request +func (a *TargetAPIService) SetTargetMetadataExecute(r ApiSetTargetMetadataRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetTargetMetadata") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/target/{targetId}/metadata" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.setMetadata == nil { + return nil, reportError("setMetadata is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.setMetadata + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + type ApiStartTargetRequest struct { ctx context.Context ApiService *TargetAPIService diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index c19aaf9215..7f11fd32f7 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -516,34 +516,34 @@ func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest return localVarHTTPResponse, nil } -type ApiSetWorkspaceStateRequest struct { +type ApiSetWorkspaceMetadataRequest struct { ctx context.Context ApiService *WorkspaceAPIService workspaceId string - setState *SetWorkspaceState + setMetadata *SetWorkspaceMetadata } -// Set State -func (r ApiSetWorkspaceStateRequest) SetState(setState SetWorkspaceState) ApiSetWorkspaceStateRequest { - r.setState = &setState +// Set Metadata +func (r ApiSetWorkspaceMetadataRequest) SetMetadata(setMetadata SetWorkspaceMetadata) ApiSetWorkspaceMetadataRequest { + r.setMetadata = &setMetadata return r } -func (r ApiSetWorkspaceStateRequest) Execute() (*http.Response, error) { - return r.ApiService.SetWorkspaceStateExecute(r) +func (r ApiSetWorkspaceMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.SetWorkspaceMetadataExecute(r) } /* -SetWorkspaceState Set workspace state +SetWorkspaceMetadata Set workspace metadata -Set workspace state +Set workspace metadata @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID - @return ApiSetWorkspaceStateRequest + @return ApiSetWorkspaceMetadataRequest */ -func (a *WorkspaceAPIService) SetWorkspaceState(ctx context.Context, workspaceId string) ApiSetWorkspaceStateRequest { - return ApiSetWorkspaceStateRequest{ +func (a *WorkspaceAPIService) SetWorkspaceMetadata(ctx context.Context, workspaceId string) ApiSetWorkspaceMetadataRequest { + return ApiSetWorkspaceMetadataRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, @@ -551,26 +551,26 @@ func (a *WorkspaceAPIService) SetWorkspaceState(ctx context.Context, workspaceId } // Execute executes the request -func (a *WorkspaceAPIService) SetWorkspaceStateExecute(r ApiSetWorkspaceStateRequest) (*http.Response, error) { +func (a *WorkspaceAPIService) SetWorkspaceMetadataExecute(r ApiSetWorkspaceMetadataRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.SetWorkspaceState") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.SetWorkspaceMetadata") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/state" + localVarPath := localBasePath + "/workspace/{workspaceId}/metadata" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.setState == nil { - return nil, reportError("setState is required and must be specified") + if r.setMetadata == nil { + return nil, reportError("setMetadata is required and must be specified") } // to determine the Content-Type header @@ -591,7 +591,7 @@ func (a *WorkspaceAPIService) SetWorkspaceStateExecute(r ApiSetWorkspaceStateReq localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.setState + localVarPostBody = r.setMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index 13557afa24..b102b0f04c 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -58,6 +58,8 @@ type APIClient struct { GitProviderAPI *GitProviderAPIService + JobAPI *JobAPIService + PrebuildAPI *PrebuildAPIService ProfileAPI *ProfileAPIService @@ -100,6 +102,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.ContainerRegistryAPI = (*ContainerRegistryAPIService)(&c.common) c.DefaultAPI = (*DefaultAPIService)(&c.common) c.GitProviderAPI = (*GitProviderAPIService)(&c.common) + c.JobAPI = (*JobAPIService)(&c.common) c.PrebuildAPI = (*PrebuildAPIService)(&c.common) c.ProfileAPI = (*ProfileAPIService)(&c.common) c.ProviderAPI = (*ProviderAPIService)(&c.common) diff --git a/pkg/apiclient/docs/Job.md b/pkg/apiclient/docs/Job.md new file mode 100644 index 0000000000..f6a49470d7 --- /dev/null +++ b/pkg/apiclient/docs/Job.md @@ -0,0 +1,203 @@ +# Job + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Action** | [**ModelsJobAction**](ModelsJobAction.md) | | +**CreatedAt** | **string** | | +**Error** | Pointer to **string** | | [optional] +**Id** | **string** | | +**ResourceId** | **string** | | +**ResourceType** | [**ResourceType**](ResourceType.md) | | +**State** | [**JobState**](JobState.md) | | +**UpdatedAt** | **string** | | + +## Methods + +### NewJob + +`func NewJob(action ModelsJobAction, createdAt string, id string, resourceId string, resourceType ResourceType, state JobState, updatedAt string, ) *Job` + +NewJob instantiates a new Job object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewJobWithDefaults + +`func NewJobWithDefaults() *Job` + +NewJobWithDefaults instantiates a new Job object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAction + +`func (o *Job) GetAction() ModelsJobAction` + +GetAction returns the Action field if non-nil, zero value otherwise. + +### GetActionOk + +`func (o *Job) GetActionOk() (*ModelsJobAction, bool)` + +GetActionOk returns a tuple with the Action field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAction + +`func (o *Job) SetAction(v ModelsJobAction)` + +SetAction sets Action field to given value. + + +### GetCreatedAt + +`func (o *Job) GetCreatedAt() string` + +GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. + +### GetCreatedAtOk + +`func (o *Job) GetCreatedAtOk() (*string, bool)` + +GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetCreatedAt + +`func (o *Job) SetCreatedAt(v string)` + +SetCreatedAt sets CreatedAt field to given value. + + +### GetError + +`func (o *Job) GetError() string` + +GetError returns the Error field if non-nil, zero value otherwise. + +### GetErrorOk + +`func (o *Job) GetErrorOk() (*string, bool)` + +GetErrorOk returns a tuple with the Error field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetError + +`func (o *Job) SetError(v string)` + +SetError sets Error field to given value. + +### HasError + +`func (o *Job) HasError() bool` + +HasError returns a boolean if a field has been set. + +### GetId + +`func (o *Job) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *Job) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *Job) SetId(v string)` + +SetId sets Id field to given value. + + +### GetResourceId + +`func (o *Job) GetResourceId() string` + +GetResourceId returns the ResourceId field if non-nil, zero value otherwise. + +### GetResourceIdOk + +`func (o *Job) GetResourceIdOk() (*string, bool)` + +GetResourceIdOk returns a tuple with the ResourceId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetResourceId + +`func (o *Job) SetResourceId(v string)` + +SetResourceId sets ResourceId field to given value. + + +### GetResourceType + +`func (o *Job) GetResourceType() ResourceType` + +GetResourceType returns the ResourceType field if non-nil, zero value otherwise. + +### GetResourceTypeOk + +`func (o *Job) GetResourceTypeOk() (*ResourceType, bool)` + +GetResourceTypeOk returns a tuple with the ResourceType field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetResourceType + +`func (o *Job) SetResourceType(v ResourceType)` + +SetResourceType sets ResourceType field to given value. + + +### GetState + +`func (o *Job) GetState() JobState` + +GetState returns the State field if non-nil, zero value otherwise. + +### GetStateOk + +`func (o *Job) GetStateOk() (*JobState, bool)` + +GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetState + +`func (o *Job) SetState(v JobState)` + +SetState sets State field to given value. + + +### GetUpdatedAt + +`func (o *Job) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *Job) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *Job) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/JobAPI.md b/pkg/apiclient/docs/JobAPI.md new file mode 100644 index 0000000000..038ff50c2f --- /dev/null +++ b/pkg/apiclient/docs/JobAPI.md @@ -0,0 +1,70 @@ +# \JobAPI + +All URIs are relative to *http://localhost:3986* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**ListJobs**](JobAPI.md#ListJobs) | **Get** /job | List jobs + + + +## ListJobs + +> []Job ListJobs(ctx).Execute() + +List jobs + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.JobAPI.ListJobs(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `JobAPI.ListJobs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListJobs`: []Job + fmt.Fprintf(os.Stdout, "Response from `JobAPI.ListJobs`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiListJobsRequest struct via the builder pattern + + +### Return type + +[**[]Job**](Job.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/JobState.md b/pkg/apiclient/docs/JobState.md new file mode 100644 index 0000000000..3d2915aea3 --- /dev/null +++ b/pkg/apiclient/docs/JobState.md @@ -0,0 +1,17 @@ +# JobState + +## Enum + + +* `JobStatePending` (value: `"pending"`) + +* `JobStateRunning` (value: `"running"`) + +* `JobStateError` (value: `"error"`) + +* `JobStateSuccess` (value: `"success"`) + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ModelsJobAction.md b/pkg/apiclient/docs/ModelsJobAction.md new file mode 100644 index 0000000000..57efef5a40 --- /dev/null +++ b/pkg/apiclient/docs/ModelsJobAction.md @@ -0,0 +1,21 @@ +# ModelsJobAction + +## Enum + + +* `JobActionCreate` (value: `"create"`) + +* `JobActionStart` (value: `"start"`) + +* `JobActionStop` (value: `"stop"`) + +* `JobActionRestart` (value: `"restart"`) + +* `JobActionDelete` (value: `"delete"`) + +* `JobActionForceDelete` (value: `"force-delete"`) + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ModelsResourceStateName.md b/pkg/apiclient/docs/ModelsResourceStateName.md new file mode 100644 index 0000000000..e8b2354a95 --- /dev/null +++ b/pkg/apiclient/docs/ModelsResourceStateName.md @@ -0,0 +1,41 @@ +# ModelsResourceStateName + +## Enum + + +* `ResourceStateNameUndefined` (value: `"undefined"`) + +* `ResourceStateNamePendingCreate` (value: `"pending-create"`) + +* `ResourceStateNameCreating` (value: `"creating"`) + +* `ResourceStateNamePendingStart` (value: `"pending-start"`) + +* `ResourceStateNameStarting` (value: `"starting"`) + +* `ResourceStateNameStarted` (value: `"started"`) + +* `ResourceStateNamePendingStop` (value: `"pending-stop"`) + +* `ResourceStateNameStopping` (value: `"stopping"`) + +* `ResourceStateNameStopped` (value: `"stopped"`) + +* `ResourceStateNamePendingRestart` (value: `"pending-restart"`) + +* `ResourceStateNameError` (value: `"error"`) + +* `ResourceStateNameUnresponsive` (value: `"unresponsive"`) + +* `ResourceStateNamePendingDelete` (value: `"pending-delete"`) + +* `ResourceStateNamePendingForcedDelete` (value: `"pending-forced-delete"`) + +* `ResourceStateNameDeleting` (value: `"deleting"`) + +* `ResourceStateNameDeleted` (value: `"deleted"`) + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ResourceState.md b/pkg/apiclient/docs/ResourceState.md new file mode 100644 index 0000000000..dc3cd6b380 --- /dev/null +++ b/pkg/apiclient/docs/ResourceState.md @@ -0,0 +1,98 @@ +# ResourceState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Error** | Pointer to **string** | | [optional] +**Name** | [**ModelsResourceStateName**](ModelsResourceStateName.md) | | +**UpdatedAt** | **string** | | + +## Methods + +### NewResourceState + +`func NewResourceState(name ModelsResourceStateName, updatedAt string, ) *ResourceState` + +NewResourceState instantiates a new ResourceState object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewResourceStateWithDefaults + +`func NewResourceStateWithDefaults() *ResourceState` + +NewResourceStateWithDefaults instantiates a new ResourceState object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetError + +`func (o *ResourceState) GetError() string` + +GetError returns the Error field if non-nil, zero value otherwise. + +### GetErrorOk + +`func (o *ResourceState) GetErrorOk() (*string, bool)` + +GetErrorOk returns a tuple with the Error field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetError + +`func (o *ResourceState) SetError(v string)` + +SetError sets Error field to given value. + +### HasError + +`func (o *ResourceState) HasError() bool` + +HasError returns a boolean if a field has been set. + +### GetName + +`func (o *ResourceState) GetName() ModelsResourceStateName` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *ResourceState) GetNameOk() (*ModelsResourceStateName, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *ResourceState) SetName(v ModelsResourceStateName)` + +SetName sets Name field to given value. + + +### GetUpdatedAt + +`func (o *ResourceState) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *ResourceState) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *ResourceState) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ResourceType.md b/pkg/apiclient/docs/ResourceType.md new file mode 100644 index 0000000000..3acb2bb6b1 --- /dev/null +++ b/pkg/apiclient/docs/ResourceType.md @@ -0,0 +1,13 @@ +# ResourceType + +## Enum + + +* `ResourceTypeWorkspace` (value: `"workspace"`) + +* `ResourceTypeTarget` (value: `"target"`) + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/SetTargetMetadata.md b/pkg/apiclient/docs/SetTargetMetadata.md new file mode 100644 index 0000000000..3e6080311f --- /dev/null +++ b/pkg/apiclient/docs/SetTargetMetadata.md @@ -0,0 +1,51 @@ +# SetTargetMetadata + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Uptime** | **int32** | | + +## Methods + +### NewSetTargetMetadata + +`func NewSetTargetMetadata(uptime int32, ) *SetTargetMetadata` + +NewSetTargetMetadata instantiates a new SetTargetMetadata object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewSetTargetMetadataWithDefaults + +`func NewSetTargetMetadataWithDefaults() *SetTargetMetadata` + +NewSetTargetMetadataWithDefaults instantiates a new SetTargetMetadata object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetUptime + +`func (o *SetTargetMetadata) GetUptime() int32` + +GetUptime returns the Uptime field if non-nil, zero value otherwise. + +### GetUptimeOk + +`func (o *SetTargetMetadata) GetUptimeOk() (*int32, bool)` + +GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUptime + +`func (o *SetTargetMetadata) SetUptime(v int32)` + +SetUptime sets Uptime field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/SetWorkspaceState.md b/pkg/apiclient/docs/SetWorkspaceMetadata.md similarity index 65% rename from pkg/apiclient/docs/SetWorkspaceState.md rename to pkg/apiclient/docs/SetWorkspaceMetadata.md index d1592277de..b81ca44ddd 100644 --- a/pkg/apiclient/docs/SetWorkspaceState.md +++ b/pkg/apiclient/docs/SetWorkspaceMetadata.md @@ -1,4 +1,4 @@ -# SetWorkspaceState +# SetWorkspaceMetadata ## Properties @@ -9,64 +9,64 @@ Name | Type | Description | Notes ## Methods -### NewSetWorkspaceState +### NewSetWorkspaceMetadata -`func NewSetWorkspaceState(uptime int32, ) *SetWorkspaceState` +`func NewSetWorkspaceMetadata(uptime int32, ) *SetWorkspaceMetadata` -NewSetWorkspaceState instantiates a new SetWorkspaceState object +NewSetWorkspaceMetadata instantiates a new SetWorkspaceMetadata object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewSetWorkspaceStateWithDefaults +### NewSetWorkspaceMetadataWithDefaults -`func NewSetWorkspaceStateWithDefaults() *SetWorkspaceState` +`func NewSetWorkspaceMetadataWithDefaults() *SetWorkspaceMetadata` -NewSetWorkspaceStateWithDefaults instantiates a new SetWorkspaceState object +NewSetWorkspaceMetadataWithDefaults instantiates a new SetWorkspaceMetadata object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetGitStatus -`func (o *SetWorkspaceState) GetGitStatus() GitStatus` +`func (o *SetWorkspaceMetadata) GetGitStatus() GitStatus` GetGitStatus returns the GitStatus field if non-nil, zero value otherwise. ### GetGitStatusOk -`func (o *SetWorkspaceState) GetGitStatusOk() (*GitStatus, bool)` +`func (o *SetWorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool)` GetGitStatusOk returns a tuple with the GitStatus field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitStatus -`func (o *SetWorkspaceState) SetGitStatus(v GitStatus)` +`func (o *SetWorkspaceMetadata) SetGitStatus(v GitStatus)` SetGitStatus sets GitStatus field to given value. ### HasGitStatus -`func (o *SetWorkspaceState) HasGitStatus() bool` +`func (o *SetWorkspaceMetadata) HasGitStatus() bool` HasGitStatus returns a boolean if a field has been set. ### GetUptime -`func (o *SetWorkspaceState) GetUptime() int32` +`func (o *SetWorkspaceMetadata) GetUptime() int32` GetUptime returns the Uptime field if non-nil, zero value otherwise. ### GetUptimeOk -`func (o *SetWorkspaceState) GetUptimeOk() (*int32, bool)` +`func (o *SetWorkspaceMetadata) GetUptimeOk() (*int32, bool)` GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUptime -`func (o *SetWorkspaceState) SetUptime(v int32)` +`func (o *SetWorkspaceMetadata) SetUptime(v int32)` SetUptime sets Uptime field to given value. diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index e52538ca6b..8d01d15bc7 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -5,7 +5,10 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Default** | **bool** | | +**EnvVars** | **map[string]string** | | **Id** | **string** | | +**LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | **Options** | **string** | JSON encoded map of options | **ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | @@ -15,7 +18,7 @@ Name | Type | Description | Notes ### NewTarget -`func NewTarget(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, ) *Target` +`func NewTarget(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo, ) *Target` NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, @@ -50,6 +53,26 @@ and a boolean to check if the value has been set. SetDefault sets Default field to given value. +### GetEnvVars + +`func (o *Target) GetEnvVars() map[string]string` + +GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. + +### GetEnvVarsOk + +`func (o *Target) GetEnvVarsOk() (*map[string]string, bool)` + +GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEnvVars + +`func (o *Target) SetEnvVars(v map[string]string)` + +SetEnvVars sets EnvVars field to given value. + + ### GetId `func (o *Target) GetId() string` @@ -70,6 +93,56 @@ and a boolean to check if the value has been set. SetId sets Id field to given value. +### GetLastJob + +`func (o *Target) GetLastJob() Job` + +GetLastJob returns the LastJob field if non-nil, zero value otherwise. + +### GetLastJobOk + +`func (o *Target) GetLastJobOk() (*Job, bool)` + +GetLastJobOk returns a tuple with the LastJob field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJob + +`func (o *Target) SetLastJob(v Job)` + +SetLastJob sets LastJob field to given value. + +### HasLastJob + +`func (o *Target) HasLastJob() bool` + +HasLastJob returns a boolean if a field has been set. + +### GetMetadata + +`func (o *Target) GetMetadata() TargetMetadata` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *Target) GetMetadataOk() (*TargetMetadata, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *Target) SetMetadata(v TargetMetadata)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *Target) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + ### GetName `func (o *Target) GetName() string` diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index bacbdd15ef..94285097a4 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -9,6 +9,7 @@ Method | HTTP request | Description [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets [**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target [**SetDefaultTarget**](TargetAPI.md#SetDefaultTarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default +[**SetTargetMetadata**](TargetAPI.md#SetTargetMetadata) | **Post** /target/{targetId}/metadata | Set target metadata [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target @@ -356,6 +357,76 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## SetTargetMetadata + +> SetTargetMetadata(ctx, targetId).SetMetadata(setMetadata).Execute() + +Set target metadata + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + targetId := "targetId_example" // string | Target ID + setMetadata := *openapiclient.NewSetTargetMetadata(int32(123)) // SetTargetMetadata | Set Metadata + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), targetId).SetMetadata(setMetadata).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetTargetMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**targetId** | **string** | Target ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiSetTargetMetadataRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **setMetadata** | [**SetTargetMetadata**](SetTargetMetadata.md) | Set Metadata | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## StartTarget > StartTarget(ctx, targetId).Execute() diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index c07c23c39c..1f4302c90f 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -5,18 +5,22 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Default** | **bool** | | +**EnvVars** | **map[string]string** | | **Id** | **string** | | **Info** | Pointer to [**TargetInfo**](TargetInfo.md) | | [optional] +**LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | **Options** | **string** | JSON encoded map of options | **ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | +**State** | [**ResourceState**](ResourceState.md) | | **Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] ## Methods ### NewTargetDTO -`func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo, ) *TargetDTO` +`func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo, state ResourceState, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -51,6 +55,26 @@ and a boolean to check if the value has been set. SetDefault sets Default field to given value. +### GetEnvVars + +`func (o *TargetDTO) GetEnvVars() map[string]string` + +GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. + +### GetEnvVarsOk + +`func (o *TargetDTO) GetEnvVarsOk() (*map[string]string, bool)` + +GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetEnvVars + +`func (o *TargetDTO) SetEnvVars(v map[string]string)` + +SetEnvVars sets EnvVars field to given value. + + ### GetId `func (o *TargetDTO) GetId() string` @@ -96,6 +120,56 @@ SetInfo sets Info field to given value. HasInfo returns a boolean if a field has been set. +### GetLastJob + +`func (o *TargetDTO) GetLastJob() Job` + +GetLastJob returns the LastJob field if non-nil, zero value otherwise. + +### GetLastJobOk + +`func (o *TargetDTO) GetLastJobOk() (*Job, bool)` + +GetLastJobOk returns a tuple with the LastJob field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJob + +`func (o *TargetDTO) SetLastJob(v Job)` + +SetLastJob sets LastJob field to given value. + +### HasLastJob + +`func (o *TargetDTO) HasLastJob() bool` + +HasLastJob returns a boolean if a field has been set. + +### GetMetadata + +`func (o *TargetDTO) GetMetadata() TargetMetadata` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *TargetDTO) GetMetadataOk() (*TargetMetadata, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *TargetDTO) SetMetadata(v TargetMetadata)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *TargetDTO) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + ### GetName `func (o *TargetDTO) GetName() string` @@ -156,6 +230,26 @@ and a boolean to check if the value has been set. SetProviderInfo sets ProviderInfo field to given value. +### GetState + +`func (o *TargetDTO) GetState() ResourceState` + +GetState returns the State field if non-nil, zero value otherwise. + +### GetStateOk + +`func (o *TargetDTO) GetStateOk() (*ResourceState, bool)` + +GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetState + +`func (o *TargetDTO) SetState(v ResourceState)` + +SetState sets State field to given value. + + ### GetWorkspaces `func (o *TargetDTO) GetWorkspaces() []Workspace` diff --git a/pkg/apiclient/docs/TargetMetadata.md b/pkg/apiclient/docs/TargetMetadata.md new file mode 100644 index 0000000000..dca922a12b --- /dev/null +++ b/pkg/apiclient/docs/TargetMetadata.md @@ -0,0 +1,93 @@ +# TargetMetadata + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**TargetId** | **string** | | +**UpdatedAt** | **string** | | +**Uptime** | **int32** | | + +## Methods + +### NewTargetMetadata + +`func NewTargetMetadata(targetId string, updatedAt string, uptime int32, ) *TargetMetadata` + +NewTargetMetadata instantiates a new TargetMetadata object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewTargetMetadataWithDefaults + +`func NewTargetMetadataWithDefaults() *TargetMetadata` + +NewTargetMetadataWithDefaults instantiates a new TargetMetadata object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetTargetId + +`func (o *TargetMetadata) GetTargetId() string` + +GetTargetId returns the TargetId field if non-nil, zero value otherwise. + +### GetTargetIdOk + +`func (o *TargetMetadata) GetTargetIdOk() (*string, bool)` + +GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTargetId + +`func (o *TargetMetadata) SetTargetId(v string)` + +SetTargetId sets TargetId field to given value. + + +### GetUpdatedAt + +`func (o *TargetMetadata) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *TargetMetadata) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *TargetMetadata) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + + +### GetUptime + +`func (o *TargetMetadata) GetUptime() int32` + +GetUptime returns the Uptime field if non-nil, zero value otherwise. + +### GetUptimeOk + +`func (o *TargetMetadata) GetUptimeOk() (*int32, bool)` + +GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUptime + +`func (o *TargetMetadata) SetUptime(v int32)` + +SetUptime sets Uptime field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/Workspace.md index 2926f6d46f..acdee1e9b5 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/Workspace.md @@ -9,9 +9,10 @@ Name | Type | Description | Notes **GitProviderConfigId** | Pointer to **string** | | [optional] **Id** | **string** | | **Image** | **string** | | +**LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | -**State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] **Target** | [**Target**](Target.md) | | **TargetId** | **string** | | **User** | **string** | | @@ -145,6 +146,56 @@ and a boolean to check if the value has been set. SetImage sets Image field to given value. +### GetLastJob + +`func (o *Workspace) GetLastJob() Job` + +GetLastJob returns the LastJob field if non-nil, zero value otherwise. + +### GetLastJobOk + +`func (o *Workspace) GetLastJobOk() (*Job, bool)` + +GetLastJobOk returns a tuple with the LastJob field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJob + +`func (o *Workspace) SetLastJob(v Job)` + +SetLastJob sets LastJob field to given value. + +### HasLastJob + +`func (o *Workspace) HasLastJob() bool` + +HasLastJob returns a boolean if a field has been set. + +### GetMetadata + +`func (o *Workspace) GetMetadata() WorkspaceMetadata` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *Workspace) GetMetadataOk() (*WorkspaceMetadata, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *Workspace) SetMetadata(v WorkspaceMetadata)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *Workspace) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + ### GetName `func (o *Workspace) GetName() string` @@ -185,31 +236,6 @@ and a boolean to check if the value has been set. SetRepository sets Repository field to given value. -### GetState - -`func (o *Workspace) GetState() WorkspaceState` - -GetState returns the State field if non-nil, zero value otherwise. - -### GetStateOk - -`func (o *Workspace) GetStateOk() (*WorkspaceState, bool)` - -GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetState - -`func (o *Workspace) SetState(v WorkspaceState)` - -SetState sets State field to given value. - -### HasState - -`func (o *Workspace) HasState() bool` - -HasState returns a boolean if a field has been set. - ### GetTarget `func (o *Workspace) GetTarget() Target` diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index ebedbbff1a..3cdb2b3bf7 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -8,7 +8,7 @@ Method | HTTP request | Description [**GetWorkspace**](WorkspaceAPI.md#GetWorkspace) | **Get** /workspace/{workspaceId} | Get workspace info [**ListWorkspaces**](WorkspaceAPI.md#ListWorkspaces) | **Get** /workspace | List workspaces [**RemoveWorkspace**](WorkspaceAPI.md#RemoveWorkspace) | **Delete** /workspace/{workspaceId} | Remove workspace -[**SetWorkspaceState**](WorkspaceAPI.md#SetWorkspaceState) | **Post** /workspace/{workspaceId}/state | Set workspace state +[**SetWorkspaceMetadata**](WorkspaceAPI.md#SetWorkspaceMetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata [**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace [**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace @@ -288,11 +288,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetWorkspaceState +## SetWorkspaceMetadata -> SetWorkspaceState(ctx, workspaceId).SetState(setState).Execute() +> SetWorkspaceMetadata(ctx, workspaceId).SetMetadata(setMetadata).Execute() -Set workspace state +Set workspace metadata @@ -310,13 +310,13 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID - setState := *openapiclient.NewSetWorkspaceState(int32(123)) // SetWorkspaceState | Set State + setMetadata := *openapiclient.NewSetWorkspaceMetadata(int32(123)) // SetWorkspaceMetadata | Set Metadata configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.SetWorkspaceState(context.Background(), workspaceId).SetState(setState).Execute() + r, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), workspaceId).SetMetadata(setMetadata).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.SetWorkspaceState``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.SetWorkspaceMetadata``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -332,13 +332,13 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiSetWorkspaceStateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetWorkspaceMetadataRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **setState** | [**SetWorkspaceState**](SetWorkspaceState.md) | Set State | + **setMetadata** | [**SetWorkspaceMetadata**](SetWorkspaceMetadata.md) | Set Metadata | ### Return type diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md index 6167bddc2b..0ac7e19c8d 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -10,9 +10,11 @@ Name | Type | Description | Notes **Id** | **string** | | **Image** | **string** | | **Info** | Pointer to [**WorkspaceInfo**](WorkspaceInfo.md) | | [optional] +**LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] **Name** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | -**State** | Pointer to [**WorkspaceState**](WorkspaceState.md) | | [optional] +**State** | [**ResourceState**](ResourceState.md) | | **Target** | [**Target**](Target.md) | | **TargetId** | **string** | | **User** | **string** | | @@ -21,7 +23,7 @@ Name | Type | Description | Notes ### NewWorkspaceDTO -`func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string, ) *WorkspaceDTO` +`func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string, ) *WorkspaceDTO` NewWorkspaceDTO instantiates a new WorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -171,6 +173,56 @@ SetInfo sets Info field to given value. HasInfo returns a boolean if a field has been set. +### GetLastJob + +`func (o *WorkspaceDTO) GetLastJob() Job` + +GetLastJob returns the LastJob field if non-nil, zero value otherwise. + +### GetLastJobOk + +`func (o *WorkspaceDTO) GetLastJobOk() (*Job, bool)` + +GetLastJobOk returns a tuple with the LastJob field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJob + +`func (o *WorkspaceDTO) SetLastJob(v Job)` + +SetLastJob sets LastJob field to given value. + +### HasLastJob + +`func (o *WorkspaceDTO) HasLastJob() bool` + +HasLastJob returns a boolean if a field has been set. + +### GetMetadata + +`func (o *WorkspaceDTO) GetMetadata() WorkspaceMetadata` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *WorkspaceDTO) GetMetadataOk() (*WorkspaceMetadata, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *WorkspaceDTO) SetMetadata(v WorkspaceMetadata)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *WorkspaceDTO) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + ### GetName `func (o *WorkspaceDTO) GetName() string` @@ -213,28 +265,23 @@ SetRepository sets Repository field to given value. ### GetState -`func (o *WorkspaceDTO) GetState() WorkspaceState` +`func (o *WorkspaceDTO) GetState() ResourceState` GetState returns the State field if non-nil, zero value otherwise. ### GetStateOk -`func (o *WorkspaceDTO) GetStateOk() (*WorkspaceState, bool)` +`func (o *WorkspaceDTO) GetStateOk() (*ResourceState, bool)` GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetState -`func (o *WorkspaceDTO) SetState(v WorkspaceState)` +`func (o *WorkspaceDTO) SetState(v ResourceState)` SetState sets State field to given value. -### HasState - -`func (o *WorkspaceDTO) HasState() bool` - -HasState returns a boolean if a field has been set. ### GetTarget diff --git a/pkg/apiclient/docs/WorkspaceState.md b/pkg/apiclient/docs/WorkspaceMetadata.md similarity index 55% rename from pkg/apiclient/docs/WorkspaceState.md rename to pkg/apiclient/docs/WorkspaceMetadata.md index a08e533c69..afba834445 100644 --- a/pkg/apiclient/docs/WorkspaceState.md +++ b/pkg/apiclient/docs/WorkspaceMetadata.md @@ -1,4 +1,4 @@ -# WorkspaceState +# WorkspaceMetadata ## Properties @@ -7,91 +7,112 @@ Name | Type | Description | Notes **GitStatus** | Pointer to [**GitStatus**](GitStatus.md) | | [optional] **UpdatedAt** | **string** | | **Uptime** | **int32** | | +**WorkspaceId** | **string** | | ## Methods -### NewWorkspaceState +### NewWorkspaceMetadata -`func NewWorkspaceState(updatedAt string, uptime int32, ) *WorkspaceState` +`func NewWorkspaceMetadata(updatedAt string, uptime int32, workspaceId string, ) *WorkspaceMetadata` -NewWorkspaceState instantiates a new WorkspaceState object +NewWorkspaceMetadata instantiates a new WorkspaceMetadata object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceStateWithDefaults +### NewWorkspaceMetadataWithDefaults -`func NewWorkspaceStateWithDefaults() *WorkspaceState` +`func NewWorkspaceMetadataWithDefaults() *WorkspaceMetadata` -NewWorkspaceStateWithDefaults instantiates a new WorkspaceState object +NewWorkspaceMetadataWithDefaults instantiates a new WorkspaceMetadata object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetGitStatus -`func (o *WorkspaceState) GetGitStatus() GitStatus` +`func (o *WorkspaceMetadata) GetGitStatus() GitStatus` GetGitStatus returns the GitStatus field if non-nil, zero value otherwise. ### GetGitStatusOk -`func (o *WorkspaceState) GetGitStatusOk() (*GitStatus, bool)` +`func (o *WorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool)` GetGitStatusOk returns a tuple with the GitStatus field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitStatus -`func (o *WorkspaceState) SetGitStatus(v GitStatus)` +`func (o *WorkspaceMetadata) SetGitStatus(v GitStatus)` SetGitStatus sets GitStatus field to given value. ### HasGitStatus -`func (o *WorkspaceState) HasGitStatus() bool` +`func (o *WorkspaceMetadata) HasGitStatus() bool` HasGitStatus returns a boolean if a field has been set. ### GetUpdatedAt -`func (o *WorkspaceState) GetUpdatedAt() string` +`func (o *WorkspaceMetadata) GetUpdatedAt() string` GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. ### GetUpdatedAtOk -`func (o *WorkspaceState) GetUpdatedAtOk() (*string, bool)` +`func (o *WorkspaceMetadata) GetUpdatedAtOk() (*string, bool)` GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUpdatedAt -`func (o *WorkspaceState) SetUpdatedAt(v string)` +`func (o *WorkspaceMetadata) SetUpdatedAt(v string)` SetUpdatedAt sets UpdatedAt field to given value. ### GetUptime -`func (o *WorkspaceState) GetUptime() int32` +`func (o *WorkspaceMetadata) GetUptime() int32` GetUptime returns the Uptime field if non-nil, zero value otherwise. ### GetUptimeOk -`func (o *WorkspaceState) GetUptimeOk() (*int32, bool)` +`func (o *WorkspaceMetadata) GetUptimeOk() (*int32, bool)` GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUptime -`func (o *WorkspaceState) SetUptime(v int32)` +`func (o *WorkspaceMetadata) SetUptime(v int32)` SetUptime sets Uptime field to given value. +### GetWorkspaceId + +`func (o *WorkspaceMetadata) GetWorkspaceId() string` + +GetWorkspaceId returns the WorkspaceId field if non-nil, zero value otherwise. + +### GetWorkspaceIdOk + +`func (o *WorkspaceMetadata) GetWorkspaceIdOk() (*string, bool)` + +GetWorkspaceIdOk returns a tuple with the WorkspaceId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetWorkspaceId + +`func (o *WorkspaceMetadata) SetWorkspaceId(v string)` + +SetWorkspaceId sets WorkspaceId field to given value. + + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/model_job.go b/pkg/apiclient/model_job.go new file mode 100644 index 0000000000..6550dfe097 --- /dev/null +++ b/pkg/apiclient/model_job.go @@ -0,0 +1,360 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the Job type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Job{} + +// Job struct for Job +type Job struct { + Action ModelsJobAction `json:"action"` + CreatedAt string `json:"createdAt"` + Error *string `json:"error,omitempty"` + Id string `json:"id"` + ResourceId string `json:"resourceId"` + ResourceType ResourceType `json:"resourceType"` + State JobState `json:"state"` + UpdatedAt string `json:"updatedAt"` +} + +type _Job Job + +// NewJob instantiates a new Job object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewJob(action ModelsJobAction, createdAt string, id string, resourceId string, resourceType ResourceType, state JobState, updatedAt string) *Job { + this := Job{} + this.Action = action + this.CreatedAt = createdAt + this.Id = id + this.ResourceId = resourceId + this.ResourceType = resourceType + this.State = state + this.UpdatedAt = updatedAt + return &this +} + +// NewJobWithDefaults instantiates a new Job object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewJobWithDefaults() *Job { + this := Job{} + return &this +} + +// GetAction returns the Action field value +func (o *Job) GetAction() ModelsJobAction { + if o == nil { + var ret ModelsJobAction + return ret + } + + return o.Action +} + +// GetActionOk returns a tuple with the Action field value +// and a boolean to check if the value has been set. +func (o *Job) GetActionOk() (*ModelsJobAction, bool) { + if o == nil { + return nil, false + } + return &o.Action, true +} + +// SetAction sets field value +func (o *Job) SetAction(v ModelsJobAction) { + o.Action = v +} + +// GetCreatedAt returns the CreatedAt field value +func (o *Job) GetCreatedAt() string { + if o == nil { + var ret string + return ret + } + + return o.CreatedAt +} + +// GetCreatedAtOk returns a tuple with the CreatedAt field value +// and a boolean to check if the value has been set. +func (o *Job) GetCreatedAtOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.CreatedAt, true +} + +// SetCreatedAt sets field value +func (o *Job) SetCreatedAt(v string) { + o.CreatedAt = v +} + +// GetError returns the Error field value if set, zero value otherwise. +func (o *Job) GetError() string { + if o == nil || IsNil(o.Error) { + var ret string + return ret + } + return *o.Error +} + +// GetErrorOk returns a tuple with the Error field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Job) GetErrorOk() (*string, bool) { + if o == nil || IsNil(o.Error) { + return nil, false + } + return o.Error, true +} + +// HasError returns a boolean if a field has been set. +func (o *Job) HasError() bool { + if o != nil && !IsNil(o.Error) { + return true + } + + return false +} + +// SetError gets a reference to the given string and assigns it to the Error field. +func (o *Job) SetError(v string) { + o.Error = &v +} + +// GetId returns the Id field value +func (o *Job) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *Job) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *Job) SetId(v string) { + o.Id = v +} + +// GetResourceId returns the ResourceId field value +func (o *Job) GetResourceId() string { + if o == nil { + var ret string + return ret + } + + return o.ResourceId +} + +// GetResourceIdOk returns a tuple with the ResourceId field value +// and a boolean to check if the value has been set. +func (o *Job) GetResourceIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ResourceId, true +} + +// SetResourceId sets field value +func (o *Job) SetResourceId(v string) { + o.ResourceId = v +} + +// GetResourceType returns the ResourceType field value +func (o *Job) GetResourceType() ResourceType { + if o == nil { + var ret ResourceType + return ret + } + + return o.ResourceType +} + +// GetResourceTypeOk returns a tuple with the ResourceType field value +// and a boolean to check if the value has been set. +func (o *Job) GetResourceTypeOk() (*ResourceType, bool) { + if o == nil { + return nil, false + } + return &o.ResourceType, true +} + +// SetResourceType sets field value +func (o *Job) SetResourceType(v ResourceType) { + o.ResourceType = v +} + +// GetState returns the State field value +func (o *Job) GetState() JobState { + if o == nil { + var ret JobState + return ret + } + + return o.State +} + +// GetStateOk returns a tuple with the State field value +// and a boolean to check if the value has been set. +func (o *Job) GetStateOk() (*JobState, bool) { + if o == nil { + return nil, false + } + return &o.State, true +} + +// SetState sets field value +func (o *Job) SetState(v JobState) { + o.State = v +} + +// GetUpdatedAt returns the UpdatedAt field value +func (o *Job) GetUpdatedAt() string { + if o == nil { + var ret string + return ret + } + + return o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value +// and a boolean to check if the value has been set. +func (o *Job) GetUpdatedAtOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.UpdatedAt, true +} + +// SetUpdatedAt sets field value +func (o *Job) SetUpdatedAt(v string) { + o.UpdatedAt = v +} + +func (o Job) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Job) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["action"] = o.Action + toSerialize["createdAt"] = o.CreatedAt + if !IsNil(o.Error) { + toSerialize["error"] = o.Error + } + toSerialize["id"] = o.Id + toSerialize["resourceId"] = o.ResourceId + toSerialize["resourceType"] = o.ResourceType + toSerialize["state"] = o.State + toSerialize["updatedAt"] = o.UpdatedAt + return toSerialize, nil +} + +func (o *Job) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "action", + "createdAt", + "id", + "resourceId", + "resourceType", + "state", + "updatedAt", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varJob := _Job{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varJob) + + if err != nil { + return err + } + + *o = Job(varJob) + + return err +} + +type NullableJob struct { + value *Job + isSet bool +} + +func (v NullableJob) Get() *Job { + return v.value +} + +func (v *NullableJob) Set(val *Job) { + v.value = val + v.isSet = true +} + +func (v NullableJob) IsSet() bool { + return v.isSet +} + +func (v *NullableJob) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableJob(val *Job) *NullableJob { + return &NullableJob{value: val, isSet: true} +} + +func (v NullableJob) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableJob) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_job_state.go b/pkg/apiclient/model_job_state.go new file mode 100644 index 0000000000..198b95eb9f --- /dev/null +++ b/pkg/apiclient/model_job_state.go @@ -0,0 +1,114 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// JobState the model 'JobState' +type JobState string + +// List of JobState +const ( + JobStatePending JobState = "pending" + JobStateRunning JobState = "running" + JobStateError JobState = "error" + JobStateSuccess JobState = "success" +) + +// All allowed values of JobState enum +var AllowedJobStateEnumValues = []JobState{ + "pending", + "running", + "error", + "success", +} + +func (v *JobState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := JobState(value) + for _, existing := range AllowedJobStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid JobState", value) +} + +// NewJobStateFromValue returns a pointer to a valid JobState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewJobStateFromValue(v string) (*JobState, error) { + ev := JobState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for JobState: valid values are %v", v, AllowedJobStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v JobState) IsValid() bool { + for _, existing := range AllowedJobStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to JobState value +func (v JobState) Ptr() *JobState { + return &v +} + +type NullableJobState struct { + value *JobState + isSet bool +} + +func (v NullableJobState) Get() *JobState { + return v.value +} + +func (v *NullableJobState) Set(val *JobState) { + v.value = val + v.isSet = true +} + +func (v NullableJobState) IsSet() bool { + return v.isSet +} + +func (v *NullableJobState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableJobState(val *JobState) *NullableJobState { + return &NullableJobState{value: val, isSet: true} +} + +func (v NullableJobState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableJobState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_models_job_action.go b/pkg/apiclient/model_models_job_action.go new file mode 100644 index 0000000000..ec53817261 --- /dev/null +++ b/pkg/apiclient/model_models_job_action.go @@ -0,0 +1,118 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ModelsJobAction the model 'ModelsJobAction' +type ModelsJobAction string + +// List of models.JobAction +const ( + JobActionCreate ModelsJobAction = "create" + JobActionStart ModelsJobAction = "start" + JobActionStop ModelsJobAction = "stop" + JobActionRestart ModelsJobAction = "restart" + JobActionDelete ModelsJobAction = "delete" + JobActionForceDelete ModelsJobAction = "force-delete" +) + +// All allowed values of ModelsJobAction enum +var AllowedModelsJobActionEnumValues = []ModelsJobAction{ + "create", + "start", + "stop", + "restart", + "delete", + "force-delete", +} + +func (v *ModelsJobAction) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ModelsJobAction(value) + for _, existing := range AllowedModelsJobActionEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ModelsJobAction", value) +} + +// NewModelsJobActionFromValue returns a pointer to a valid ModelsJobAction +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewModelsJobActionFromValue(v string) (*ModelsJobAction, error) { + ev := ModelsJobAction(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ModelsJobAction: valid values are %v", v, AllowedModelsJobActionEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ModelsJobAction) IsValid() bool { + for _, existing := range AllowedModelsJobActionEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to models.JobAction value +func (v ModelsJobAction) Ptr() *ModelsJobAction { + return &v +} + +type NullableModelsJobAction struct { + value *ModelsJobAction + isSet bool +} + +func (v NullableModelsJobAction) Get() *ModelsJobAction { + return v.value +} + +func (v *NullableModelsJobAction) Set(val *ModelsJobAction) { + v.value = val + v.isSet = true +} + +func (v NullableModelsJobAction) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsJobAction) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsJobAction(val *ModelsJobAction) *NullableModelsJobAction { + return &NullableModelsJobAction{value: val, isSet: true} +} + +func (v NullableModelsJobAction) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsJobAction) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_models_resource_state_name.go b/pkg/apiclient/model_models_resource_state_name.go new file mode 100644 index 0000000000..1bfecd1405 --- /dev/null +++ b/pkg/apiclient/model_models_resource_state_name.go @@ -0,0 +1,138 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ModelsResourceStateName the model 'ModelsResourceStateName' +type ModelsResourceStateName string + +// List of models.ResourceStateName +const ( + ResourceStateNameUndefined ModelsResourceStateName = "undefined" + ResourceStateNamePendingCreate ModelsResourceStateName = "pending-create" + ResourceStateNameCreating ModelsResourceStateName = "creating" + ResourceStateNamePendingStart ModelsResourceStateName = "pending-start" + ResourceStateNameStarting ModelsResourceStateName = "starting" + ResourceStateNameStarted ModelsResourceStateName = "started" + ResourceStateNamePendingStop ModelsResourceStateName = "pending-stop" + ResourceStateNameStopping ModelsResourceStateName = "stopping" + ResourceStateNameStopped ModelsResourceStateName = "stopped" + ResourceStateNamePendingRestart ModelsResourceStateName = "pending-restart" + ResourceStateNameError ModelsResourceStateName = "error" + ResourceStateNameUnresponsive ModelsResourceStateName = "unresponsive" + ResourceStateNamePendingDelete ModelsResourceStateName = "pending-delete" + ResourceStateNamePendingForcedDelete ModelsResourceStateName = "pending-forced-delete" + ResourceStateNameDeleting ModelsResourceStateName = "deleting" + ResourceStateNameDeleted ModelsResourceStateName = "deleted" +) + +// All allowed values of ModelsResourceStateName enum +var AllowedModelsResourceStateNameEnumValues = []ModelsResourceStateName{ + "undefined", + "pending-create", + "creating", + "pending-start", + "starting", + "started", + "pending-stop", + "stopping", + "stopped", + "pending-restart", + "error", + "unresponsive", + "pending-delete", + "pending-forced-delete", + "deleting", + "deleted", +} + +func (v *ModelsResourceStateName) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ModelsResourceStateName(value) + for _, existing := range AllowedModelsResourceStateNameEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ModelsResourceStateName", value) +} + +// NewModelsResourceStateNameFromValue returns a pointer to a valid ModelsResourceStateName +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewModelsResourceStateNameFromValue(v string) (*ModelsResourceStateName, error) { + ev := ModelsResourceStateName(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ModelsResourceStateName: valid values are %v", v, AllowedModelsResourceStateNameEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ModelsResourceStateName) IsValid() bool { + for _, existing := range AllowedModelsResourceStateNameEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to models.ResourceStateName value +func (v ModelsResourceStateName) Ptr() *ModelsResourceStateName { + return &v +} + +type NullableModelsResourceStateName struct { + value *ModelsResourceStateName + isSet bool +} + +func (v NullableModelsResourceStateName) Get() *ModelsResourceStateName { + return v.value +} + +func (v *NullableModelsResourceStateName) Set(val *ModelsResourceStateName) { + v.value = val + v.isSet = true +} + +func (v NullableModelsResourceStateName) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsResourceStateName) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsResourceStateName(val *ModelsResourceStateName) *NullableModelsResourceStateName { + return &NullableModelsResourceStateName{value: val, isSet: true} +} + +func (v NullableModelsResourceStateName) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsResourceStateName) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_resource_state.go b/pkg/apiclient/model_resource_state.go new file mode 100644 index 0000000000..93a79407d9 --- /dev/null +++ b/pkg/apiclient/model_resource_state.go @@ -0,0 +1,220 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the ResourceState type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ResourceState{} + +// ResourceState struct for ResourceState +type ResourceState struct { + Error *string `json:"error,omitempty"` + Name ModelsResourceStateName `json:"name"` + UpdatedAt string `json:"updatedAt"` +} + +type _ResourceState ResourceState + +// NewResourceState instantiates a new ResourceState object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewResourceState(name ModelsResourceStateName, updatedAt string) *ResourceState { + this := ResourceState{} + this.Name = name + this.UpdatedAt = updatedAt + return &this +} + +// NewResourceStateWithDefaults instantiates a new ResourceState object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewResourceStateWithDefaults() *ResourceState { + this := ResourceState{} + return &this +} + +// GetError returns the Error field value if set, zero value otherwise. +func (o *ResourceState) GetError() string { + if o == nil || IsNil(o.Error) { + var ret string + return ret + } + return *o.Error +} + +// GetErrorOk returns a tuple with the Error field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ResourceState) GetErrorOk() (*string, bool) { + if o == nil || IsNil(o.Error) { + return nil, false + } + return o.Error, true +} + +// HasError returns a boolean if a field has been set. +func (o *ResourceState) HasError() bool { + if o != nil && !IsNil(o.Error) { + return true + } + + return false +} + +// SetError gets a reference to the given string and assigns it to the Error field. +func (o *ResourceState) SetError(v string) { + o.Error = &v +} + +// GetName returns the Name field value +func (o *ResourceState) GetName() ModelsResourceStateName { + if o == nil { + var ret ModelsResourceStateName + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *ResourceState) GetNameOk() (*ModelsResourceStateName, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *ResourceState) SetName(v ModelsResourceStateName) { + o.Name = v +} + +// GetUpdatedAt returns the UpdatedAt field value +func (o *ResourceState) GetUpdatedAt() string { + if o == nil { + var ret string + return ret + } + + return o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value +// and a boolean to check if the value has been set. +func (o *ResourceState) GetUpdatedAtOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.UpdatedAt, true +} + +// SetUpdatedAt sets field value +func (o *ResourceState) SetUpdatedAt(v string) { + o.UpdatedAt = v +} + +func (o ResourceState) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ResourceState) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Error) { + toSerialize["error"] = o.Error + } + toSerialize["name"] = o.Name + toSerialize["updatedAt"] = o.UpdatedAt + return toSerialize, nil +} + +func (o *ResourceState) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "name", + "updatedAt", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varResourceState := _ResourceState{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varResourceState) + + if err != nil { + return err + } + + *o = ResourceState(varResourceState) + + return err +} + +type NullableResourceState struct { + value *ResourceState + isSet bool +} + +func (v NullableResourceState) Get() *ResourceState { + return v.value +} + +func (v *NullableResourceState) Set(val *ResourceState) { + v.value = val + v.isSet = true +} + +func (v NullableResourceState) IsSet() bool { + return v.isSet +} + +func (v *NullableResourceState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableResourceState(val *ResourceState) *NullableResourceState { + return &NullableResourceState{value: val, isSet: true} +} + +func (v NullableResourceState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableResourceState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_resource_type.go b/pkg/apiclient/model_resource_type.go new file mode 100644 index 0000000000..47b9ccb927 --- /dev/null +++ b/pkg/apiclient/model_resource_type.go @@ -0,0 +1,110 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ResourceType the model 'ResourceType' +type ResourceType string + +// List of ResourceType +const ( + ResourceTypeWorkspace ResourceType = "workspace" + ResourceTypeTarget ResourceType = "target" +) + +// All allowed values of ResourceType enum +var AllowedResourceTypeEnumValues = []ResourceType{ + "workspace", + "target", +} + +func (v *ResourceType) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ResourceType(value) + for _, existing := range AllowedResourceTypeEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ResourceType", value) +} + +// NewResourceTypeFromValue returns a pointer to a valid ResourceType +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewResourceTypeFromValue(v string) (*ResourceType, error) { + ev := ResourceType(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ResourceType: valid values are %v", v, AllowedResourceTypeEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ResourceType) IsValid() bool { + for _, existing := range AllowedResourceTypeEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to ResourceType value +func (v ResourceType) Ptr() *ResourceType { + return &v +} + +type NullableResourceType struct { + value *ResourceType + isSet bool +} + +func (v NullableResourceType) Get() *ResourceType { + return v.value +} + +func (v *NullableResourceType) Set(val *ResourceType) { + v.value = val + v.isSet = true +} + +func (v NullableResourceType) IsSet() bool { + return v.isSet +} + +func (v *NullableResourceType) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableResourceType(val *ResourceType) *NullableResourceType { + return &NullableResourceType{value: val, isSet: true} +} + +func (v NullableResourceType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableResourceType) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_set_target_metadata.go b/pkg/apiclient/model_set_target_metadata.go new file mode 100644 index 0000000000..b608715103 --- /dev/null +++ b/pkg/apiclient/model_set_target_metadata.go @@ -0,0 +1,156 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the SetTargetMetadata type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &SetTargetMetadata{} + +// SetTargetMetadata struct for SetTargetMetadata +type SetTargetMetadata struct { + Uptime int32 `json:"uptime"` +} + +type _SetTargetMetadata SetTargetMetadata + +// NewSetTargetMetadata instantiates a new SetTargetMetadata object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewSetTargetMetadata(uptime int32) *SetTargetMetadata { + this := SetTargetMetadata{} + this.Uptime = uptime + return &this +} + +// NewSetTargetMetadataWithDefaults instantiates a new SetTargetMetadata object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewSetTargetMetadataWithDefaults() *SetTargetMetadata { + this := SetTargetMetadata{} + return &this +} + +// GetUptime returns the Uptime field value +func (o *SetTargetMetadata) GetUptime() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Uptime +} + +// GetUptimeOk returns a tuple with the Uptime field value +// and a boolean to check if the value has been set. +func (o *SetTargetMetadata) GetUptimeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Uptime, true +} + +// SetUptime sets field value +func (o *SetTargetMetadata) SetUptime(v int32) { + o.Uptime = v +} + +func (o SetTargetMetadata) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o SetTargetMetadata) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["uptime"] = o.Uptime + return toSerialize, nil +} + +func (o *SetTargetMetadata) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "uptime", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varSetTargetMetadata := _SetTargetMetadata{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varSetTargetMetadata) + + if err != nil { + return err + } + + *o = SetTargetMetadata(varSetTargetMetadata) + + return err +} + +type NullableSetTargetMetadata struct { + value *SetTargetMetadata + isSet bool +} + +func (v NullableSetTargetMetadata) Get() *SetTargetMetadata { + return v.value +} + +func (v *NullableSetTargetMetadata) Set(val *SetTargetMetadata) { + v.value = val + v.isSet = true +} + +func (v NullableSetTargetMetadata) IsSet() bool { + return v.isSet +} + +func (v *NullableSetTargetMetadata) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableSetTargetMetadata(val *SetTargetMetadata) *NullableSetTargetMetadata { + return &NullableSetTargetMetadata{value: val, isSet: true} +} + +func (v NullableSetTargetMetadata) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableSetTargetMetadata) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_set_workspace_state.go b/pkg/apiclient/model_set_workspace_metadata.go similarity index 59% rename from pkg/apiclient/model_set_workspace_state.go rename to pkg/apiclient/model_set_workspace_metadata.go index dbdebdf4c4..17f3968544 100644 --- a/pkg/apiclient/model_set_workspace_state.go +++ b/pkg/apiclient/model_set_workspace_metadata.go @@ -16,37 +16,37 @@ import ( "fmt" ) -// checks if the SetWorkspaceState type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &SetWorkspaceState{} +// checks if the SetWorkspaceMetadata type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &SetWorkspaceMetadata{} -// SetWorkspaceState struct for SetWorkspaceState -type SetWorkspaceState struct { +// SetWorkspaceMetadata struct for SetWorkspaceMetadata +type SetWorkspaceMetadata struct { GitStatus *GitStatus `json:"gitStatus,omitempty"` Uptime int32 `json:"uptime"` } -type _SetWorkspaceState SetWorkspaceState +type _SetWorkspaceMetadata SetWorkspaceMetadata -// NewSetWorkspaceState instantiates a new SetWorkspaceState object +// NewSetWorkspaceMetadata instantiates a new SetWorkspaceMetadata object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewSetWorkspaceState(uptime int32) *SetWorkspaceState { - this := SetWorkspaceState{} +func NewSetWorkspaceMetadata(uptime int32) *SetWorkspaceMetadata { + this := SetWorkspaceMetadata{} this.Uptime = uptime return &this } -// NewSetWorkspaceStateWithDefaults instantiates a new SetWorkspaceState object +// NewSetWorkspaceMetadataWithDefaults instantiates a new SetWorkspaceMetadata object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewSetWorkspaceStateWithDefaults() *SetWorkspaceState { - this := SetWorkspaceState{} +func NewSetWorkspaceMetadataWithDefaults() *SetWorkspaceMetadata { + this := SetWorkspaceMetadata{} return &this } // GetGitStatus returns the GitStatus field value if set, zero value otherwise. -func (o *SetWorkspaceState) GetGitStatus() GitStatus { +func (o *SetWorkspaceMetadata) GetGitStatus() GitStatus { if o == nil || IsNil(o.GitStatus) { var ret GitStatus return ret @@ -56,7 +56,7 @@ func (o *SetWorkspaceState) GetGitStatus() GitStatus { // GetGitStatusOk returns a tuple with the GitStatus field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *SetWorkspaceState) GetGitStatusOk() (*GitStatus, bool) { +func (o *SetWorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool) { if o == nil || IsNil(o.GitStatus) { return nil, false } @@ -64,7 +64,7 @@ func (o *SetWorkspaceState) GetGitStatusOk() (*GitStatus, bool) { } // HasGitStatus returns a boolean if a field has been set. -func (o *SetWorkspaceState) HasGitStatus() bool { +func (o *SetWorkspaceMetadata) HasGitStatus() bool { if o != nil && !IsNil(o.GitStatus) { return true } @@ -73,12 +73,12 @@ func (o *SetWorkspaceState) HasGitStatus() bool { } // SetGitStatus gets a reference to the given GitStatus and assigns it to the GitStatus field. -func (o *SetWorkspaceState) SetGitStatus(v GitStatus) { +func (o *SetWorkspaceMetadata) SetGitStatus(v GitStatus) { o.GitStatus = &v } // GetUptime returns the Uptime field value -func (o *SetWorkspaceState) GetUptime() int32 { +func (o *SetWorkspaceMetadata) GetUptime() int32 { if o == nil { var ret int32 return ret @@ -89,7 +89,7 @@ func (o *SetWorkspaceState) GetUptime() int32 { // GetUptimeOk returns a tuple with the Uptime field value // and a boolean to check if the value has been set. -func (o *SetWorkspaceState) GetUptimeOk() (*int32, bool) { +func (o *SetWorkspaceMetadata) GetUptimeOk() (*int32, bool) { if o == nil { return nil, false } @@ -97,11 +97,11 @@ func (o *SetWorkspaceState) GetUptimeOk() (*int32, bool) { } // SetUptime sets field value -func (o *SetWorkspaceState) SetUptime(v int32) { +func (o *SetWorkspaceMetadata) SetUptime(v int32) { o.Uptime = v } -func (o SetWorkspaceState) MarshalJSON() ([]byte, error) { +func (o SetWorkspaceMetadata) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -109,7 +109,7 @@ func (o SetWorkspaceState) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o SetWorkspaceState) ToMap() (map[string]interface{}, error) { +func (o SetWorkspaceMetadata) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.GitStatus) { toSerialize["gitStatus"] = o.GitStatus @@ -118,7 +118,7 @@ func (o SetWorkspaceState) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *SetWorkspaceState) UnmarshalJSON(data []byte) (err error) { +func (o *SetWorkspaceMetadata) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -140,53 +140,53 @@ func (o *SetWorkspaceState) UnmarshalJSON(data []byte) (err error) { } } - varSetWorkspaceState := _SetWorkspaceState{} + varSetWorkspaceMetadata := _SetWorkspaceMetadata{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varSetWorkspaceState) + err = decoder.Decode(&varSetWorkspaceMetadata) if err != nil { return err } - *o = SetWorkspaceState(varSetWorkspaceState) + *o = SetWorkspaceMetadata(varSetWorkspaceMetadata) return err } -type NullableSetWorkspaceState struct { - value *SetWorkspaceState +type NullableSetWorkspaceMetadata struct { + value *SetWorkspaceMetadata isSet bool } -func (v NullableSetWorkspaceState) Get() *SetWorkspaceState { +func (v NullableSetWorkspaceMetadata) Get() *SetWorkspaceMetadata { return v.value } -func (v *NullableSetWorkspaceState) Set(val *SetWorkspaceState) { +func (v *NullableSetWorkspaceMetadata) Set(val *SetWorkspaceMetadata) { v.value = val v.isSet = true } -func (v NullableSetWorkspaceState) IsSet() bool { +func (v NullableSetWorkspaceMetadata) IsSet() bool { return v.isSet } -func (v *NullableSetWorkspaceState) Unset() { +func (v *NullableSetWorkspaceMetadata) Unset() { v.value = nil v.isSet = false } -func NewNullableSetWorkspaceState(val *SetWorkspaceState) *NullableSetWorkspaceState { - return &NullableSetWorkspaceState{value: val, isSet: true} +func NewNullableSetWorkspaceMetadata(val *SetWorkspaceMetadata) *NullableSetWorkspaceMetadata { + return &NullableSetWorkspaceMetadata{value: val, isSet: true} } -func (v NullableSetWorkspaceState) MarshalJSON() ([]byte, error) { +func (v NullableSetWorkspaceMetadata) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableSetWorkspaceState) UnmarshalJSON(src []byte) error { +func (v *NullableSetWorkspaceMetadata) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index fc04b3ebe0..96e8abb256 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -21,9 +21,12 @@ var _ MappedNullable = &Target{} // Target struct for Target type Target struct { - Default bool `json:"default"` - Id string `json:"id"` - Name string `json:"name"` + Default bool `json:"default"` + EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *TargetMetadata `json:"metadata,omitempty"` + Name string `json:"name"` // JSON encoded map of options Options string `json:"options"` ProviderInfo TargetProviderInfo `json:"providerInfo"` @@ -36,9 +39,10 @@ type _Target Target // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTarget(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo) *Target { +func NewTarget(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo) *Target { this := Target{} this.Default = default_ + this.EnvVars = envVars this.Id = id this.Name = name this.Options = options @@ -78,6 +82,30 @@ func (o *Target) SetDefault(v bool) { o.Default = v } +// GetEnvVars returns the EnvVars field value +func (o *Target) GetEnvVars() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.EnvVars +} + +// GetEnvVarsOk returns a tuple with the EnvVars field value +// and a boolean to check if the value has been set. +func (o *Target) GetEnvVarsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.EnvVars, true +} + +// SetEnvVars sets field value +func (o *Target) SetEnvVars(v map[string]string) { + o.EnvVars = v +} + // GetId returns the Id field value func (o *Target) GetId() string { if o == nil { @@ -102,6 +130,70 @@ func (o *Target) SetId(v string) { o.Id = v } +// GetLastJob returns the LastJob field value if set, zero value otherwise. +func (o *Target) GetLastJob() Job { + if o == nil || IsNil(o.LastJob) { + var ret Job + return ret + } + return *o.LastJob +} + +// GetLastJobOk returns a tuple with the LastJob field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Target) GetLastJobOk() (*Job, bool) { + if o == nil || IsNil(o.LastJob) { + return nil, false + } + return o.LastJob, true +} + +// HasLastJob returns a boolean if a field has been set. +func (o *Target) HasLastJob() bool { + if o != nil && !IsNil(o.LastJob) { + return true + } + + return false +} + +// SetLastJob gets a reference to the given Job and assigns it to the LastJob field. +func (o *Target) SetLastJob(v Job) { + o.LastJob = &v +} + +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *Target) GetMetadata() TargetMetadata { + if o == nil || IsNil(o.Metadata) { + var ret TargetMetadata + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Target) GetMetadataOk() (*TargetMetadata, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *Target) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given TargetMetadata and assigns it to the Metadata field. +func (o *Target) SetMetadata(v TargetMetadata) { + o.Metadata = &v +} + // GetName returns the Name field value func (o *Target) GetName() string { if o == nil { @@ -217,7 +309,14 @@ func (o Target) MarshalJSON() ([]byte, error) { func (o Target) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["default"] = o.Default + toSerialize["envVars"] = o.EnvVars toSerialize["id"] = o.Id + if !IsNil(o.LastJob) { + toSerialize["lastJob"] = o.LastJob + } + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } toSerialize["name"] = o.Name toSerialize["options"] = o.Options toSerialize["providerInfo"] = o.ProviderInfo @@ -233,6 +332,7 @@ func (o *Target) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "default", + "envVars", "id", "name", "options", diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 64b78e829f..46bfc7ef6f 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -21,13 +21,17 @@ var _ MappedNullable = &TargetDTO{} // TargetDTO struct for TargetDTO type TargetDTO struct { - Default bool `json:"default"` - Id string `json:"id"` - Info *TargetInfo `json:"info,omitempty"` - Name string `json:"name"` + Default bool `json:"default"` + EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` + Info *TargetInfo `json:"info,omitempty"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *TargetMetadata `json:"metadata,omitempty"` + Name string `json:"name"` // JSON encoded map of options Options string `json:"options"` ProviderInfo TargetProviderInfo `json:"providerInfo"` + State ResourceState `json:"state"` Workspaces []Workspace `json:"workspaces,omitempty"` } @@ -37,13 +41,15 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(default_ bool, id string, name string, options string, providerInfo TargetProviderInfo) *TargetDTO { +func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo, state ResourceState) *TargetDTO { this := TargetDTO{} this.Default = default_ + this.EnvVars = envVars this.Id = id this.Name = name this.Options = options this.ProviderInfo = providerInfo + this.State = state return &this } @@ -79,6 +85,30 @@ func (o *TargetDTO) SetDefault(v bool) { o.Default = v } +// GetEnvVars returns the EnvVars field value +func (o *TargetDTO) GetEnvVars() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.EnvVars +} + +// GetEnvVarsOk returns a tuple with the EnvVars field value +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetEnvVarsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.EnvVars, true +} + +// SetEnvVars sets field value +func (o *TargetDTO) SetEnvVars(v map[string]string) { + o.EnvVars = v +} + // GetId returns the Id field value func (o *TargetDTO) GetId() string { if o == nil { @@ -135,6 +165,70 @@ func (o *TargetDTO) SetInfo(v TargetInfo) { o.Info = &v } +// GetLastJob returns the LastJob field value if set, zero value otherwise. +func (o *TargetDTO) GetLastJob() Job { + if o == nil || IsNil(o.LastJob) { + var ret Job + return ret + } + return *o.LastJob +} + +// GetLastJobOk returns a tuple with the LastJob field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetLastJobOk() (*Job, bool) { + if o == nil || IsNil(o.LastJob) { + return nil, false + } + return o.LastJob, true +} + +// HasLastJob returns a boolean if a field has been set. +func (o *TargetDTO) HasLastJob() bool { + if o != nil && !IsNil(o.LastJob) { + return true + } + + return false +} + +// SetLastJob gets a reference to the given Job and assigns it to the LastJob field. +func (o *TargetDTO) SetLastJob(v Job) { + o.LastJob = &v +} + +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *TargetDTO) GetMetadata() TargetMetadata { + if o == nil || IsNil(o.Metadata) { + var ret TargetMetadata + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetMetadataOk() (*TargetMetadata, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *TargetDTO) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given TargetMetadata and assigns it to the Metadata field. +func (o *TargetDTO) SetMetadata(v TargetMetadata) { + o.Metadata = &v +} + // GetName returns the Name field value func (o *TargetDTO) GetName() string { if o == nil { @@ -207,6 +301,30 @@ func (o *TargetDTO) SetProviderInfo(v TargetProviderInfo) { o.ProviderInfo = v } +// GetState returns the State field value +func (o *TargetDTO) GetState() ResourceState { + if o == nil { + var ret ResourceState + return ret + } + + return o.State +} + +// GetStateOk returns a tuple with the State field value +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetStateOk() (*ResourceState, bool) { + if o == nil { + return nil, false + } + return &o.State, true +} + +// SetState sets field value +func (o *TargetDTO) SetState(v ResourceState) { + o.State = v +} + // GetWorkspaces returns the Workspaces field value if set, zero value otherwise. func (o *TargetDTO) GetWorkspaces() []Workspace { if o == nil || IsNil(o.Workspaces) { @@ -250,13 +368,21 @@ func (o TargetDTO) MarshalJSON() ([]byte, error) { func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["default"] = o.Default + toSerialize["envVars"] = o.EnvVars toSerialize["id"] = o.Id if !IsNil(o.Info) { toSerialize["info"] = o.Info } + if !IsNil(o.LastJob) { + toSerialize["lastJob"] = o.LastJob + } + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } toSerialize["name"] = o.Name toSerialize["options"] = o.Options toSerialize["providerInfo"] = o.ProviderInfo + toSerialize["state"] = o.State if !IsNil(o.Workspaces) { toSerialize["workspaces"] = o.Workspaces } @@ -269,10 +395,12 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "default", + "envVars", "id", "name", "options", "providerInfo", + "state", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_metadata.go b/pkg/apiclient/model_target_metadata.go new file mode 100644 index 0000000000..446293be45 --- /dev/null +++ b/pkg/apiclient/model_target_metadata.go @@ -0,0 +1,212 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the TargetMetadata type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &TargetMetadata{} + +// TargetMetadata struct for TargetMetadata +type TargetMetadata struct { + TargetId string `json:"targetId"` + UpdatedAt string `json:"updatedAt"` + Uptime int32 `json:"uptime"` +} + +type _TargetMetadata TargetMetadata + +// NewTargetMetadata instantiates a new TargetMetadata object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewTargetMetadata(targetId string, updatedAt string, uptime int32) *TargetMetadata { + this := TargetMetadata{} + this.TargetId = targetId + this.UpdatedAt = updatedAt + this.Uptime = uptime + return &this +} + +// NewTargetMetadataWithDefaults instantiates a new TargetMetadata object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewTargetMetadataWithDefaults() *TargetMetadata { + this := TargetMetadata{} + return &this +} + +// GetTargetId returns the TargetId field value +func (o *TargetMetadata) GetTargetId() string { + if o == nil { + var ret string + return ret + } + + return o.TargetId +} + +// GetTargetIdOk returns a tuple with the TargetId field value +// and a boolean to check if the value has been set. +func (o *TargetMetadata) GetTargetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.TargetId, true +} + +// SetTargetId sets field value +func (o *TargetMetadata) SetTargetId(v string) { + o.TargetId = v +} + +// GetUpdatedAt returns the UpdatedAt field value +func (o *TargetMetadata) GetUpdatedAt() string { + if o == nil { + var ret string + return ret + } + + return o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value +// and a boolean to check if the value has been set. +func (o *TargetMetadata) GetUpdatedAtOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.UpdatedAt, true +} + +// SetUpdatedAt sets field value +func (o *TargetMetadata) SetUpdatedAt(v string) { + o.UpdatedAt = v +} + +// GetUptime returns the Uptime field value +func (o *TargetMetadata) GetUptime() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Uptime +} + +// GetUptimeOk returns a tuple with the Uptime field value +// and a boolean to check if the value has been set. +func (o *TargetMetadata) GetUptimeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Uptime, true +} + +// SetUptime sets field value +func (o *TargetMetadata) SetUptime(v int32) { + o.Uptime = v +} + +func (o TargetMetadata) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o TargetMetadata) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["targetId"] = o.TargetId + toSerialize["updatedAt"] = o.UpdatedAt + toSerialize["uptime"] = o.Uptime + return toSerialize, nil +} + +func (o *TargetMetadata) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "targetId", + "updatedAt", + "uptime", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varTargetMetadata := _TargetMetadata{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varTargetMetadata) + + if err != nil { + return err + } + + *o = TargetMetadata(varTargetMetadata) + + return err +} + +type NullableTargetMetadata struct { + value *TargetMetadata + isSet bool +} + +func (v NullableTargetMetadata) Get() *TargetMetadata { + return v.value +} + +func (v *NullableTargetMetadata) Set(val *TargetMetadata) { + v.value = val + v.isSet = true +} + +func (v NullableTargetMetadata) IsSet() bool { + return v.isSet +} + +func (v *NullableTargetMetadata) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTargetMetadata(val *TargetMetadata) *NullableTargetMetadata { + return &NullableTargetMetadata{value: val, isSet: true} +} + +func (v NullableTargetMetadata) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableTargetMetadata) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_workspace.go index de0cfb7a0d..9f9c374c76 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_workspace.go @@ -21,17 +21,18 @@ var _ MappedNullable = &Workspace{} // Workspace struct for Workspace type Workspace struct { - BuildConfig *BuildConfig `json:"buildConfig,omitempty"` - EnvVars map[string]string `json:"envVars"` - GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` - Id string `json:"id"` - Image string `json:"image"` - Name string `json:"name"` - Repository GitRepository `json:"repository"` - State *WorkspaceState `json:"state,omitempty"` - Target Target `json:"target"` - TargetId string `json:"targetId"` - User string `json:"user"` + BuildConfig *BuildConfig `json:"buildConfig,omitempty"` + EnvVars map[string]string `json:"envVars"` + GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` + Id string `json:"id"` + Image string `json:"image"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *WorkspaceMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + Repository GitRepository `json:"repository"` + Target Target `json:"target"` + TargetId string `json:"targetId"` + User string `json:"user"` } type _Workspace Workspace @@ -197,6 +198,70 @@ func (o *Workspace) SetImage(v string) { o.Image = v } +// GetLastJob returns the LastJob field value if set, zero value otherwise. +func (o *Workspace) GetLastJob() Job { + if o == nil || IsNil(o.LastJob) { + var ret Job + return ret + } + return *o.LastJob +} + +// GetLastJobOk returns a tuple with the LastJob field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Workspace) GetLastJobOk() (*Job, bool) { + if o == nil || IsNil(o.LastJob) { + return nil, false + } + return o.LastJob, true +} + +// HasLastJob returns a boolean if a field has been set. +func (o *Workspace) HasLastJob() bool { + if o != nil && !IsNil(o.LastJob) { + return true + } + + return false +} + +// SetLastJob gets a reference to the given Job and assigns it to the LastJob field. +func (o *Workspace) SetLastJob(v Job) { + o.LastJob = &v +} + +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *Workspace) GetMetadata() WorkspaceMetadata { + if o == nil || IsNil(o.Metadata) { + var ret WorkspaceMetadata + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Workspace) GetMetadataOk() (*WorkspaceMetadata, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *Workspace) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given WorkspaceMetadata and assigns it to the Metadata field. +func (o *Workspace) SetMetadata(v WorkspaceMetadata) { + o.Metadata = &v +} + // GetName returns the Name field value func (o *Workspace) GetName() string { if o == nil { @@ -245,38 +310,6 @@ func (o *Workspace) SetRepository(v GitRepository) { o.Repository = v } -// GetState returns the State field value if set, zero value otherwise. -func (o *Workspace) GetState() WorkspaceState { - if o == nil || IsNil(o.State) { - var ret WorkspaceState - return ret - } - return *o.State -} - -// GetStateOk returns a tuple with the State field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *Workspace) GetStateOk() (*WorkspaceState, bool) { - if o == nil || IsNil(o.State) { - return nil, false - } - return o.State, true -} - -// HasState returns a boolean if a field has been set. -func (o *Workspace) HasState() bool { - if o != nil && !IsNil(o.State) { - return true - } - - return false -} - -// SetState gets a reference to the given WorkspaceState and assigns it to the State field. -func (o *Workspace) SetState(v WorkspaceState) { - o.State = &v -} - // GetTarget returns the Target field value func (o *Workspace) GetTarget() Target { if o == nil { @@ -368,11 +401,14 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { } toSerialize["id"] = o.Id toSerialize["image"] = o.Image + if !IsNil(o.LastJob) { + toSerialize["lastJob"] = o.LastJob + } + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } toSerialize["name"] = o.Name toSerialize["repository"] = o.Repository - if !IsNil(o.State) { - toSerialize["state"] = o.State - } toSerialize["target"] = o.Target toSerialize["targetId"] = o.TargetId toSerialize["user"] = o.User diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go index 0e3f8ac924..72554fcb6c 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_workspace_dto.go @@ -21,18 +21,20 @@ var _ MappedNullable = &WorkspaceDTO{} // WorkspaceDTO struct for WorkspaceDTO type WorkspaceDTO struct { - BuildConfig *BuildConfig `json:"buildConfig,omitempty"` - EnvVars map[string]string `json:"envVars"` - GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` - Id string `json:"id"` - Image string `json:"image"` - Info *WorkspaceInfo `json:"info,omitempty"` - Name string `json:"name"` - Repository GitRepository `json:"repository"` - State *WorkspaceState `json:"state,omitempty"` - Target Target `json:"target"` - TargetId string `json:"targetId"` - User string `json:"user"` + BuildConfig *BuildConfig `json:"buildConfig,omitempty"` + EnvVars map[string]string `json:"envVars"` + GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` + Id string `json:"id"` + Image string `json:"image"` + Info *WorkspaceInfo `json:"info,omitempty"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *WorkspaceMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + Repository GitRepository `json:"repository"` + State ResourceState `json:"state"` + Target Target `json:"target"` + TargetId string `json:"targetId"` + User string `json:"user"` } type _WorkspaceDTO WorkspaceDTO @@ -41,13 +43,14 @@ type _WorkspaceDTO WorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string) *WorkspaceDTO { +func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string) *WorkspaceDTO { this := WorkspaceDTO{} this.EnvVars = envVars this.Id = id this.Image = image this.Name = name this.Repository = repository + this.State = state this.Target = target this.TargetId = targetId this.User = user @@ -230,6 +233,70 @@ func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo) { o.Info = &v } +// GetLastJob returns the LastJob field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetLastJob() Job { + if o == nil || IsNil(o.LastJob) { + var ret Job + return ret + } + return *o.LastJob +} + +// GetLastJobOk returns a tuple with the LastJob field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetLastJobOk() (*Job, bool) { + if o == nil || IsNil(o.LastJob) { + return nil, false + } + return o.LastJob, true +} + +// HasLastJob returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasLastJob() bool { + if o != nil && !IsNil(o.LastJob) { + return true + } + + return false +} + +// SetLastJob gets a reference to the given Job and assigns it to the LastJob field. +func (o *WorkspaceDTO) SetLastJob(v Job) { + o.LastJob = &v +} + +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetMetadata() WorkspaceMetadata { + if o == nil || IsNil(o.Metadata) { + var ret WorkspaceMetadata + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetMetadataOk() (*WorkspaceMetadata, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given WorkspaceMetadata and assigns it to the Metadata field. +func (o *WorkspaceDTO) SetMetadata(v WorkspaceMetadata) { + o.Metadata = &v +} + // GetName returns the Name field value func (o *WorkspaceDTO) GetName() string { if o == nil { @@ -278,36 +345,28 @@ func (o *WorkspaceDTO) SetRepository(v GitRepository) { o.Repository = v } -// GetState returns the State field value if set, zero value otherwise. -func (o *WorkspaceDTO) GetState() WorkspaceState { - if o == nil || IsNil(o.State) { - var ret WorkspaceState +// GetState returns the State field value +func (o *WorkspaceDTO) GetState() ResourceState { + if o == nil { + var ret ResourceState return ret } - return *o.State + + return o.State } -// GetStateOk returns a tuple with the State field value if set, nil otherwise +// GetStateOk returns a tuple with the State field value // and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetStateOk() (*WorkspaceState, bool) { - if o == nil || IsNil(o.State) { +func (o *WorkspaceDTO) GetStateOk() (*ResourceState, bool) { + if o == nil { return nil, false } - return o.State, true + return &o.State, true } -// HasState returns a boolean if a field has been set. -func (o *WorkspaceDTO) HasState() bool { - if o != nil && !IsNil(o.State) { - return true - } - - return false -} - -// SetState gets a reference to the given WorkspaceState and assigns it to the State field. -func (o *WorkspaceDTO) SetState(v WorkspaceState) { - o.State = &v +// SetState sets field value +func (o *WorkspaceDTO) SetState(v ResourceState) { + o.State = v } // GetTarget returns the Target field value @@ -404,11 +463,15 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.Info) { toSerialize["info"] = o.Info } + if !IsNil(o.LastJob) { + toSerialize["lastJob"] = o.LastJob + } + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } toSerialize["name"] = o.Name toSerialize["repository"] = o.Repository - if !IsNil(o.State) { - toSerialize["state"] = o.State - } + toSerialize["state"] = o.State toSerialize["target"] = o.Target toSerialize["targetId"] = o.TargetId toSerialize["user"] = o.User @@ -425,6 +488,7 @@ func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { "image", "name", "repository", + "state", "target", "targetId", "user", diff --git a/pkg/apiclient/model_workspace_state.go b/pkg/apiclient/model_workspace_metadata.go similarity index 53% rename from pkg/apiclient/model_workspace_state.go rename to pkg/apiclient/model_workspace_metadata.go index 9e08bd043d..de83af8623 100644 --- a/pkg/apiclient/model_workspace_state.go +++ b/pkg/apiclient/model_workspace_metadata.go @@ -16,39 +16,41 @@ import ( "fmt" ) -// checks if the WorkspaceState type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &WorkspaceState{} +// checks if the WorkspaceMetadata type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceMetadata{} -// WorkspaceState struct for WorkspaceState -type WorkspaceState struct { - GitStatus *GitStatus `json:"gitStatus,omitempty"` - UpdatedAt string `json:"updatedAt"` - Uptime int32 `json:"uptime"` +// WorkspaceMetadata struct for WorkspaceMetadata +type WorkspaceMetadata struct { + GitStatus *GitStatus `json:"gitStatus,omitempty"` + UpdatedAt string `json:"updatedAt"` + Uptime int32 `json:"uptime"` + WorkspaceId string `json:"workspaceId"` } -type _WorkspaceState WorkspaceState +type _WorkspaceMetadata WorkspaceMetadata -// NewWorkspaceState instantiates a new WorkspaceState object +// NewWorkspaceMetadata instantiates a new WorkspaceMetadata object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceState(updatedAt string, uptime int32) *WorkspaceState { - this := WorkspaceState{} +func NewWorkspaceMetadata(updatedAt string, uptime int32, workspaceId string) *WorkspaceMetadata { + this := WorkspaceMetadata{} this.UpdatedAt = updatedAt this.Uptime = uptime + this.WorkspaceId = workspaceId return &this } -// NewWorkspaceStateWithDefaults instantiates a new WorkspaceState object +// NewWorkspaceMetadataWithDefaults instantiates a new WorkspaceMetadata object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceStateWithDefaults() *WorkspaceState { - this := WorkspaceState{} +func NewWorkspaceMetadataWithDefaults() *WorkspaceMetadata { + this := WorkspaceMetadata{} return &this } // GetGitStatus returns the GitStatus field value if set, zero value otherwise. -func (o *WorkspaceState) GetGitStatus() GitStatus { +func (o *WorkspaceMetadata) GetGitStatus() GitStatus { if o == nil || IsNil(o.GitStatus) { var ret GitStatus return ret @@ -58,7 +60,7 @@ func (o *WorkspaceState) GetGitStatus() GitStatus { // GetGitStatusOk returns a tuple with the GitStatus field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceState) GetGitStatusOk() (*GitStatus, bool) { +func (o *WorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool) { if o == nil || IsNil(o.GitStatus) { return nil, false } @@ -66,7 +68,7 @@ func (o *WorkspaceState) GetGitStatusOk() (*GitStatus, bool) { } // HasGitStatus returns a boolean if a field has been set. -func (o *WorkspaceState) HasGitStatus() bool { +func (o *WorkspaceMetadata) HasGitStatus() bool { if o != nil && !IsNil(o.GitStatus) { return true } @@ -75,12 +77,12 @@ func (o *WorkspaceState) HasGitStatus() bool { } // SetGitStatus gets a reference to the given GitStatus and assigns it to the GitStatus field. -func (o *WorkspaceState) SetGitStatus(v GitStatus) { +func (o *WorkspaceMetadata) SetGitStatus(v GitStatus) { o.GitStatus = &v } // GetUpdatedAt returns the UpdatedAt field value -func (o *WorkspaceState) GetUpdatedAt() string { +func (o *WorkspaceMetadata) GetUpdatedAt() string { if o == nil { var ret string return ret @@ -91,7 +93,7 @@ func (o *WorkspaceState) GetUpdatedAt() string { // GetUpdatedAtOk returns a tuple with the UpdatedAt field value // and a boolean to check if the value has been set. -func (o *WorkspaceState) GetUpdatedAtOk() (*string, bool) { +func (o *WorkspaceMetadata) GetUpdatedAtOk() (*string, bool) { if o == nil { return nil, false } @@ -99,12 +101,12 @@ func (o *WorkspaceState) GetUpdatedAtOk() (*string, bool) { } // SetUpdatedAt sets field value -func (o *WorkspaceState) SetUpdatedAt(v string) { +func (o *WorkspaceMetadata) SetUpdatedAt(v string) { o.UpdatedAt = v } // GetUptime returns the Uptime field value -func (o *WorkspaceState) GetUptime() int32 { +func (o *WorkspaceMetadata) GetUptime() int32 { if o == nil { var ret int32 return ret @@ -115,7 +117,7 @@ func (o *WorkspaceState) GetUptime() int32 { // GetUptimeOk returns a tuple with the Uptime field value // and a boolean to check if the value has been set. -func (o *WorkspaceState) GetUptimeOk() (*int32, bool) { +func (o *WorkspaceMetadata) GetUptimeOk() (*int32, bool) { if o == nil { return nil, false } @@ -123,11 +125,35 @@ func (o *WorkspaceState) GetUptimeOk() (*int32, bool) { } // SetUptime sets field value -func (o *WorkspaceState) SetUptime(v int32) { +func (o *WorkspaceMetadata) SetUptime(v int32) { o.Uptime = v } -func (o WorkspaceState) MarshalJSON() ([]byte, error) { +// GetWorkspaceId returns the WorkspaceId field value +func (o *WorkspaceMetadata) GetWorkspaceId() string { + if o == nil { + var ret string + return ret + } + + return o.WorkspaceId +} + +// GetWorkspaceIdOk returns a tuple with the WorkspaceId field value +// and a boolean to check if the value has been set. +func (o *WorkspaceMetadata) GetWorkspaceIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.WorkspaceId, true +} + +// SetWorkspaceId sets field value +func (o *WorkspaceMetadata) SetWorkspaceId(v string) { + o.WorkspaceId = v +} + +func (o WorkspaceMetadata) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -135,23 +161,25 @@ func (o WorkspaceState) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o WorkspaceState) ToMap() (map[string]interface{}, error) { +func (o WorkspaceMetadata) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.GitStatus) { toSerialize["gitStatus"] = o.GitStatus } toSerialize["updatedAt"] = o.UpdatedAt toSerialize["uptime"] = o.Uptime + toSerialize["workspaceId"] = o.WorkspaceId return toSerialize, nil } -func (o *WorkspaceState) UnmarshalJSON(data []byte) (err error) { +func (o *WorkspaceMetadata) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ "updatedAt", "uptime", + "workspaceId", } allProperties := make(map[string]interface{}) @@ -168,53 +196,53 @@ func (o *WorkspaceState) UnmarshalJSON(data []byte) (err error) { } } - varWorkspaceState := _WorkspaceState{} + varWorkspaceMetadata := _WorkspaceMetadata{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspaceState) + err = decoder.Decode(&varWorkspaceMetadata) if err != nil { return err } - *o = WorkspaceState(varWorkspaceState) + *o = WorkspaceMetadata(varWorkspaceMetadata) return err } -type NullableWorkspaceState struct { - value *WorkspaceState +type NullableWorkspaceMetadata struct { + value *WorkspaceMetadata isSet bool } -func (v NullableWorkspaceState) Get() *WorkspaceState { +func (v NullableWorkspaceMetadata) Get() *WorkspaceMetadata { return v.value } -func (v *NullableWorkspaceState) Set(val *WorkspaceState) { +func (v *NullableWorkspaceMetadata) Set(val *WorkspaceMetadata) { v.value = val v.isSet = true } -func (v NullableWorkspaceState) IsSet() bool { +func (v NullableWorkspaceMetadata) IsSet() bool { return v.isSet } -func (v *NullableWorkspaceState) Unset() { +func (v *NullableWorkspaceMetadata) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspaceState(val *WorkspaceState) *NullableWorkspaceState { - return &NullableWorkspaceState{value: val, isSet: true} +func NewNullableWorkspaceMetadata(val *WorkspaceMetadata) *NullableWorkspaceMetadata { + return &NullableWorkspaceMetadata{value: val, isSet: true} } -func (v NullableWorkspaceState) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceMetadata) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspaceState) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceMetadata) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/build/runner_config.go b/pkg/build/runner_config.go index a505f44f55..7e81640634 100644 --- a/pkg/build/runner_config.go +++ b/pkg/build/runner_config.go @@ -15,7 +15,7 @@ import ( // TODO: add lock when running interval func // 10 second interval -const DEFAULT_POLL_INTERVAL = "*/10 * * * * *" +const DEFAULT_BUILD_POLL_INTERVAL = "*/10 * * * * *" type Config struct { Id string `json:"id" validate:"required"` @@ -107,7 +107,7 @@ func GetRunnerConfigDir() (string, error) { func getDefaultConfig() *Config { return &Config{ Id: uuid.NewString(), - Interval: DEFAULT_POLL_INTERVAL, + Interval: DEFAULT_BUILD_POLL_INTERVAL, TelemetryEnabled: false, } } diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index cf07f4e1ae..1a60ac6c43 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -28,7 +28,7 @@ import ( "github.com/spf13/cobra" ) -var hostModeFlag bool +var targetModeFlag bool var AgentCmd = &cobra.Command{ Use: "agent", @@ -39,8 +39,8 @@ var AgentCmd = &cobra.Command{ agentMode := agent_config.ModeWorkspace - if hostModeFlag { - agentMode = agent_config.ModeHost + if targetModeFlag { + agentMode = agent_config.ModeTarget } c, err := agent_config.GetConfig(agentMode) @@ -132,7 +132,7 @@ var AgentCmd = &cobra.Command{ } func init() { - AgentCmd.Flags().BoolVar(&hostModeFlag, "host", false, "Run the agent in host mode") + AgentCmd.Flags().BoolVar(&targetModeFlag, "target", false, "Run the agent in target mode") AgentCmd.AddCommand(logsCmd) } diff --git a/pkg/cmd/agentmode/info.go b/pkg/cmd/agentmode/info.go index dabe68d92a..105ea795d4 100644 --- a/pkg/cmd/agentmode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -21,7 +21,7 @@ var infoCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var target *apiclient.TargetDTO - target, err := apiclient_util.GetTarget(targetId, true) + target, _, err := apiclient_util.GetTarget(targetId, true) if err != nil { return err } diff --git a/pkg/cmd/common/await_state.go b/pkg/cmd/common/await_state.go new file mode 100644 index 0000000000..4432dae4b7 --- /dev/null +++ b/pkg/cmd/common/await_state.go @@ -0,0 +1,79 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "errors" + "net/http" + "time" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" +) + +func AwaitWorkspaceState(workspaceId string, stateName apiclient.ModelsResourceStateName) error { + for { + ws, _, err := apiclient_util.GetWorkspace(workspaceId, false) + if err != nil { + return err + } + if ws.State.Name == stateName { + return nil + } + if ws.State.Name == apiclient.ResourceStateNameError { + var errorMessage string + if ws.State.Error != nil { + errorMessage = *ws.State.Error + } + return errors.New(errorMessage) + } + time.Sleep(time.Second) + } +} + +func AwaitTargetState(targetId string, stateName apiclient.ModelsResourceStateName) error { + for { + t, _, err := apiclient_util.GetTarget(targetId, false) + if err != nil { + return err + } + if t.State.Name == stateName || t.State.Name == apiclient.ResourceStateNameUndefined { + return nil + } + if t.State.Name == apiclient.ResourceStateNameError { + var errorMessage string + if t.State.Error != nil { + errorMessage = *t.State.Error + } + return errors.New(errorMessage) + } + time.Sleep(time.Second) + } +} + +func AwaitWorkspaceDeleted(workspaceId string) error { + for { + _, statusCode, err := apiclient_util.GetWorkspace(workspaceId, false) + if err != nil { + if statusCode == http.StatusNotFound { + return nil + } + return err + } + time.Sleep(time.Second) + } +} + +func AwaitTargetDeleted(workspaceId string) error { + for { + _, statusCode, err := apiclient_util.GetTarget(workspaceId, false) + if err != nil { + if statusCode == http.StatusNotFound { + return nil + } + return err + } + time.Sleep(time.Second) + } +} diff --git a/pkg/cmd/workspace/common/configuration_flags.go b/pkg/cmd/common/configuration_flags.go similarity index 100% rename from pkg/cmd/workspace/common/configuration_flags.go rename to pkg/cmd/common/configuration_flags.go diff --git a/pkg/cmd/workspace/common/get_gpg_key.go b/pkg/cmd/common/get_gpg_key.go similarity index 100% rename from pkg/cmd/workspace/common/get_gpg_key.go rename to pkg/cmd/common/get_gpg_key.go diff --git a/pkg/cmd/workspace/common/open_ide.go b/pkg/cmd/common/open_ide.go similarity index 100% rename from pkg/cmd/workspace/common/open_ide.go rename to pkg/cmd/common/open_ide.go diff --git a/pkg/cmd/workspace/common/workspace_autocompletion.go b/pkg/cmd/common/workspace_autocompletion.go similarity index 77% rename from pkg/cmd/workspace/common/workspace_autocompletion.go rename to pkg/cmd/common/workspace_autocompletion.go index a2ea1aaea1..219dc35f1e 100644 --- a/pkg/cmd/workspace/common/workspace_autocompletion.go +++ b/pkg/cmd/common/workspace_autocompletion.go @@ -7,16 +7,10 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/spf13/cobra" ) -type workspaceState string - -const ( - WORKSPACE_STATE_RUNNING workspaceState = "Running" - WORKSPACE_STATE_STOPPED workspaceState = "Unavailable" -) - func GetWorkspaceNameCompletions() ([]string, cobra.ShellCompDirective) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -37,7 +31,7 @@ func GetWorkspaceNameCompletions() ([]string, cobra.ShellCompDirective) { return choices, cobra.ShellCompDirectiveNoFileComp } -func GetAllWorkspacesByState(state workspaceState) ([]string, cobra.ShellCompDirective) { +func GetAllWorkspacesByState(state apiclient.ModelsResourceStateName) ([]string, cobra.ShellCompDirective) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -51,11 +45,11 @@ func GetAllWorkspacesByState(state workspaceState) ([]string, cobra.ShellCompDir var choices []string for _, workspace := range workspaceList { - if state == WORKSPACE_STATE_RUNNING && workspace.State.Uptime != 0 { + if state == apiclient.ResourceStateNameStarted { choices = append(choices, workspace.Name) break } - if state == WORKSPACE_STATE_STOPPED && workspace.State.Uptime == 0 { + if state == apiclient.ResourceStateNameStopped { choices = append(choices, workspace.Name) break } diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index 6b3991906c..8d3e0887fa 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -43,7 +43,7 @@ var providerInstallCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{RegistryUrl: serverConfig.RegistryUrl}) + providerManager := manager.GetProviderManager(&manager.ProviderManagerConfig{RegistryUrl: serverConfig.RegistryUrl}) providersManifest, err := providerManager.GetProvidersManifest() if err != nil { diff --git a/pkg/cmd/provider/update.go b/pkg/cmd/provider/update.go index 822cbdc900..86b5edfea4 100644 --- a/pkg/cmd/provider/update.go +++ b/pkg/cmd/provider/update.go @@ -47,7 +47,7 @@ var providerUpdateCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{RegistryUrl: serverConfig.RegistryUrl}) + providerManager := manager.GetProviderManager(&manager.ProviderManagerConfig{RegistryUrl: serverConfig.RegistryUrl}) providersManifest, err := providerManager.GetProvidersManifest() if err != nil { diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 7ea4d5d38c..9a148fb300 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/build" - server_cmd "github.com/daytonaio/daytona/pkg/cmd/server" + "github.com/daytonaio/daytona/pkg/cmd/server/bootstrap" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/server" @@ -106,12 +106,17 @@ var purgeCmd = &cobra.Command{ defer telemetryService.Close() + err = bootstrap.InitProviderManager(serverConfig, serverConfigDir) + if err != nil { + return err + } + fmt.Println("Purging the server") - server, err := server_cmd.GetInstance(serverConfig, serverConfigDir, internal.Version, telemetryService) + server, err := bootstrap.GetInstance(serverConfig, serverConfigDir, internal.Version, telemetryService) if err != nil { return err } - buildRunner, err := server_cmd.GetBuildRunner(serverConfig, buildRunnerConfig, telemetryService) + buildRunner, err := bootstrap.GetBuildRunner(serverConfig, buildRunnerConfig, telemetryService) if err != nil { return err } diff --git a/pkg/cmd/server/bootstrap/get_build_runner.go b/pkg/cmd/server/bootstrap/get_build_runner.go new file mode 100644 index 0000000000..52453fda10 --- /dev/null +++ b/pkg/cmd/server/bootstrap/get_build_runner.go @@ -0,0 +1,111 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package bootstrap + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/db" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/scheduler" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetryService telemetry.TelemetryService) (*build.BuildRunner, error) { + logsDir, err := build.GetBuildLogsDir() + if err != nil { + return nil, err + } + loggerFactory := logs.NewLoggerFactory(nil, &logsDir) + + dbPath, err := getDbPath() + if err != nil { + return nil, err + } + + dbConnection := db.GetSQLiteConnection(dbPath) + + gitProviderConfigStore, err := db.NewGitProviderConfigStore(dbConnection) + if err != nil { + return nil, err + } + + gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ + ConfigStore: gitProviderConfigStore, + }) + + buildStore, err := db.NewBuildStore(dbConnection) + if err != nil { + return nil, err + } + + buildImageNamespace := c.BuildImageNamespace + if buildImageNamespace != "" { + buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) + } + buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") + + containerRegistryStore, err := db.NewContainerRegistryStore(dbConnection) + if err != nil { + return nil, err + } + + containerRegistryService := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ + Store: containerRegistryStore, + }) + + var builderRegistry *models.ContainerRegistry + + if c.BuilderRegistryServer != "local" { + builderRegistry, err = containerRegistryService.Find(c.BuilderRegistryServer) + if err != nil { + builderRegistry = &models.ContainerRegistry{ + Server: c.BuilderRegistryServer, + } + } + } + + cr, err := containerRegistryService.FindByImageName(c.BuilderImage) + if err != nil && !stores.IsContainerRegistryNotFound(err) { + return nil, err + } + + configDir, err := config.GetConfigDir() + if err != nil { + return nil, err + } + + builderFactory := build.NewBuilderFactory(build.BuilderFactoryConfig{ + Image: c.BuilderImage, + ContainerRegistry: cr, + BuildImageContainerRegistry: builderRegistry, + BuildStore: buildStore, + BuildImageNamespace: buildImageNamespace, + LoggerFactory: loggerFactory, + DefaultWorkspaceImage: c.DefaultWorkspaceImage, + DefaultWorkspaceUser: c.DefaultWorkspaceUser, + }) + + return build.NewBuildRunner(build.BuildRunnerInstanceConfig{ + Interval: buildRunnerConfig.Interval, + Scheduler: scheduler.NewCronScheduler(), + BuildRunnerId: buildRunnerConfig.Id, + ContainerRegistry: builderRegistry, + GitProviderStore: gitProviderService, + BuildStore: buildStore, + BuilderFactory: builderFactory, + LoggerFactory: loggerFactory, + BasePath: filepath.Join(configDir, "builds"), + TelemetryService: telemetryService, + }), nil +} diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go new file mode 100644 index 0000000000..08e01391d0 --- /dev/null +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -0,0 +1,148 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package bootstrap + +import ( + "context" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/jobs/target" + "github.com/daytonaio/daytona/pkg/jobs/workspace" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider/manager" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/runners" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + + "github.com/daytonaio/daytona/pkg/runners/runner" +) + +func GetJobRunner(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (runners.IJobRunner, error) { + jobService := server.GetInstance(nil).JobService + + workspaceJobFactory, err := GetWorkspaceJobFactory(c, configDir, version, telemetryService) + if err != nil { + return nil, err + } + + targetJobFactory, err := GetTargetJobFactory(c, configDir, version, telemetryService) + if err != nil { + return nil, err + } + + return runner.NewJobRunner(runner.JobRunnerConfig{ + ListPendingJobs: func(ctx context.Context) ([]*models.Job, error) { + return jobService.List(&stores.JobFilter{ + States: &[]models.JobState{models.JobStatePending}, + }) + }, + UpdateJobState: func(ctx context.Context, job *models.Job, state models.JobState, err *error) error { + job.State = state + if err != nil { + job.Error = util.Pointer((*err).Error()) + } + return jobService.Save(job) + }, + WorkspaceJobFactory: workspaceJobFactory, + TargetJobFactory: targetJobFactory, + }), nil +} + +func GetWorkspaceJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (workspace.IWorkspaceJobFactory, error) { + containerRegistryService := server.GetInstance(nil).ContainerRegistryService + + gitProviderService := server.GetInstance(nil).GitProviderService + + targetLogsDir, err := server.GetTargetLogsDir(configDir) + if err != nil { + return nil, err + } + buildLogsDir, err := build.GetBuildLogsDir() + if err != nil { + return nil, err + } + loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) + + providerManager := manager.GetProviderManager(nil) + + provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ + ProviderManager: providerManager, + }) + + targetService := server.GetInstance(nil).TargetService + + workspaceService := server.GetInstance(nil).WorkspaceService + + return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ + FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { + workspaceDto, err := workspaceService.GetWorkspace(ctx, workspaceId, services.WorkspaceRetrievalParams{Verbose: false}) + if err != nil { + return nil, err + } + return &workspaceDto.Workspace, nil + }, + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + if err != nil { + return nil, err + } + return &targetDto.Target, nil + }, + FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { + return containerRegistryService.Find(image) + }, + FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { + return gitProviderService.GetConfig(id) + }, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return telemetryService.TrackServerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + Provisioner: provisioner, + BuilderImage: c.BuilderImage, + }), nil +} + +func GetTargetJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (target.ITargetJobFactory, error) { + targetLogsDir, err := server.GetTargetLogsDir(configDir) + if err != nil { + return nil, err + } + buildLogsDir, err := build.GetBuildLogsDir() + if err != nil { + return nil, err + } + loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) + + providerManager := manager.GetProviderManager(nil) + + provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ + ProviderManager: providerManager, + }) + + targetService := server.GetInstance(nil).TargetService + + return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + if err != nil { + return nil, err + } + return &targetDto.Target, nil + }, + HandleSuccessfulCreation: func(ctx context.Context, targetId string) error { + return targetService.HandleSuccessfulCreation(ctx, targetId) + }, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return telemetryService.TrackServerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + Provisioner: provisioner, + }), nil +} diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go new file mode 100644 index 0000000000..b50bb4b7ee --- /dev/null +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -0,0 +1,427 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package bootstrap + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/constants" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/db" + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider/manager" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/apikeys" + "github.com/daytonaio/daytona/pkg/server/builds" + "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/server/gitproviders" + "github.com/daytonaio/daytona/pkg/server/headscale" + "github.com/daytonaio/daytona/pkg/server/jobs" + "github.com/daytonaio/daytona/pkg/server/profiledata" + "github.com/daytonaio/daytona/pkg/server/registry" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/server/targets" + "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + + log "github.com/sirupsen/logrus" +) + +func GetInstance(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (*server.Server, error) { + targetLogsDir, err := server.GetTargetLogsDir(configDir) + if err != nil { + return nil, err + } + buildLogsDir, err := build.GetBuildLogsDir() + if err != nil { + return nil, err + } + loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) + + dbPath, err := getDbPath() + if err != nil { + return nil, err + } + + dbConnection := db.GetSQLiteConnection(dbPath) + + apiKeyStore, err := db.NewApiKeyStore(dbConnection) + if err != nil { + return nil, err + } + containerRegistryStore, err := db.NewContainerRegistryStore(dbConnection) + if err != nil { + return nil, err + } + buildStore, err := db.NewBuildStore(dbConnection) + if err != nil { + return nil, err + } + workspaceConfigStore, err := db.NewWorkspaceConfigStore(dbConnection) + if err != nil { + return nil, err + } + gitProviderConfigStore, err := db.NewGitProviderConfigStore(dbConnection) + if err != nil { + return nil, err + } + targetConfigStore, err := db.NewTargetConfigStore(dbConnection) + if err != nil { + return nil, err + } + targetStore, err := db.NewTargetStore(dbConnection) + if err != nil { + return nil, err + } + targetMetadataStore, err := db.NewTargetMetadataStore(dbConnection) + if err != nil { + return nil, err + } + profileDataStore, err := db.NewProfileDataStore(dbConnection) + if err != nil { + return nil, err + } + workspaceStore, err := db.NewWorkspaceStore(dbConnection) + if err != nil { + return nil, err + } + workspaceMetadataStore, err := db.NewWorkspaceMetadataStore(dbConnection) + if err != nil { + return nil, err + } + jobStore, err := db.NewJobStore(dbConnection) + if err != nil { + return nil, err + } + + providerManager := manager.GetProviderManager(nil) + + headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ + ServerId: c.Id, + FrpsDomain: c.Frps.Domain, + FrpsProtocol: c.Frps.Protocol, + HeadscalePort: c.HeadscalePort, + ConfigDir: filepath.Join(configDir, "headscale"), + Frps: c.Frps, + }) + err = headscaleServer.Init() + if err != nil { + return nil, err + } + + containerRegistryService := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ + Store: containerRegistryStore, + }) + + gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ + ConfigStore: gitProviderConfigStore, + DetachWorkspaceConfigs: func(ctx context.Context, gitProviderConfigId string) error { + workspaceConfigs, err := workspaceConfigStore.List(&stores.WorkspaceConfigFilter{ + GitProviderConfigId: &gitProviderConfigId, + }) + + if err != nil { + return err + } + + for _, workspaceConfig := range workspaceConfigs { + workspaceConfig.GitProviderConfigId = nil + err = workspaceConfigStore.Save(workspaceConfig) + if err != nil { + return err + } + } + + return nil + }, + }) + + buildService := builds.NewBuildService(builds.BuildServiceConfig{ + BuildStore: buildStore, + FindWorkspaceConfig: func(ctx context.Context, name string) (*models.WorkspaceConfig, error) { + return workspaceConfigStore.Find(&stores.WorkspaceConfigFilter{ + Name: &name, + }) + }, + GetRepositoryContext: func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) { + gitProvider, _, err := gitProviderService.GetGitProviderForUrl(url) + if err != nil { + return nil, err + } + + repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ + Url: url, + }) + + return repo, err + }, + LoggerFactory: loggerFactory, + }) + + prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) + + workspaceConfigService := workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ + PrebuildWebhookEndpoint: prebuildWebhookEndpoint, + ConfigStore: workspaceConfigStore, + FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { + return buildService.Find(&stores.BuildFilter{ + PrebuildIds: &[]string{prebuildId}, + GetNewest: util.Pointer(true), + }) + }, + ListPublishedBuilds: func(ctx context.Context) ([]*models.Build, error) { + return buildService.List(&stores.BuildFilter{ + States: &[]models.BuildState{models.BuildStatePublished}, + }) + }, + CreateBuild: func(ctx context.Context, workspaceConfig *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error { + createBuildDto := services.CreateBuildDTO{ + WorkspaceConfigName: workspaceConfig.Name, + Branch: repo.Branch, + PrebuildId: &prebuildId, + EnvVars: workspaceConfig.EnvVars, + } + + _, err := buildService.Create(createBuildDto) + return err + }, + DeleteBuilds: func(ctx context.Context, id, prebuildId *string, force bool) []error { + var prebuildIds *[]string + if prebuildId != nil { + prebuildIds = &[]string{*prebuildId} + } + + return buildService.MarkForDeletion(&stores.BuildFilter{ + Id: id, + PrebuildIds: prebuildIds, + }, force) + }, + GetRepositoryContext: func(ctx context.Context, url string) (*gitprovider.GitRepository, string, error) { + gitProvider, gitProviderId, err := gitProviderService.GetGitProviderForUrl(url) + if err != nil { + return nil, "", err + } + + repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ + Url: url, + }) + + return repo, gitProviderId, err + }, + FindPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { + return gitProviderService.GetPrebuildWebhook(gitProviderId, repo, endpointUrl) + }, + UnregisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error { + return gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repo, id) + }, + RegisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { + return gitProviderService.RegisterPrebuildWebhook(gitProviderId, repo, endpointUrl) + }, + GetCommitsRange: func(ctx context.Context, repo *gitprovider.GitRepository, initialSha, currentSha string) (int, error) { + gitProvider, _, err := gitProviderService.GetGitProviderForUrl(repo.Url) + if err != nil { + return 0, err + } + + return gitProvider.GetCommitsRange(repo, initialSha, currentSha) + }, + }) + + err = workspaceConfigService.StartRetentionPoller() + if err != nil { + return nil, err + } + + var localContainerRegistry server.ILocalContainerRegistry + + if c.BuilderRegistryServer != "local" { + _, err := containerRegistryService.Find(c.BuilderRegistryServer) + if err != nil { + log.Errorf("Failed to find container registry credentials for builder registry server %s\n", c.BuilderRegistryServer) + log.Errorf("Defaulting to local container registry. To use %s as the builder registry, add credentials for the registry server with 'daytona container-registry set' and restart the server\n", c.BuilderRegistryServer) + c.BuilderRegistryServer = "local" + } + } + + if c.BuilderRegistryServer == "local" { + localContainerRegistry = registry.NewLocalContainerRegistry(®istry.LocalContainerRegistryConfig{ + DataPath: filepath.Join(configDir, "registry"), + Port: c.LocalBuilderRegistryPort, + Image: c.LocalBuilderRegistryImage, + Logger: log.StandardLogger().Writer(), + Frps: c.Frps, + ServerId: c.Id, + }) + c.BuilderRegistryServer = util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain) + } + + targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ + TargetConfigStore: targetConfigStore, + }) + + apiKeyService := apikeys.NewApiKeyService(apikeys.ApiKeyServiceConfig{ + ApiKeyStore: apiKeyStore, + }) + + headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) + + jobService := jobs.NewJobService(jobs.JobServiceConfig{ + JobStore: jobStore, + }) + + provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ + ProviderManager: providerManager, + }) + + targetService := targets.NewTargetService(targets.TargetServiceConfig{ + TargetStore: targetStore, + TargetMetadataStore: targetMetadataStore, + FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { + return targetConfigService.Find(&stores.TargetConfigFilter{Name: &name}) + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(models.ApiKeyTypeTarget, name) + }, + RevokeApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Revoke(name) + }, + CreateJob: func(ctx context.Context, targetId string, action models.JobAction) error { + return jobService.Save(&models.Job{ + ResourceId: targetId, + ResourceType: models.ResourceTypeTarget, + Action: action, + State: models.JobStatePending, + }) + }, + ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + ServerVersion: version, + ServerUrl: headscaleUrl, + Provisioner: provisioner, + LoggerFactory: loggerFactory, + TelemetryService: telemetryService, + }) + + workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ + WorkspaceStore: workspaceStore, + WorkspaceMetadataStore: workspaceMetadataStore, + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + t, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + if err != nil { + return nil, err + } + return &t.Target, nil + }, + FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { + return containerRegistryService.FindByImageName(image) + }, + FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { + validStates := &[]models.BuildState{ + models.BuildStatePublished, + } + + build, err := buildService.Find(&stores.BuildFilter{ + States: validStates, + RepositoryUrl: &w.Repository.Url, + Branch: &w.Repository.Branch, + EnvVars: &w.EnvVars, + BuildConfig: w.BuildConfig, + GetNewest: util.Pointer(true), + }) + if err != nil { + return nil, err + } + + if build.Image == nil || build.User == nil { + return nil, errors.New("cached build is missing image or user") + } + + return &models.CachedBuild{ + User: *build.User, + Image: *build.Image, + }, nil + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(models.ApiKeyTypeWorkspace, name) + }, + RevokeApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Revoke(name) + }, + ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { + return gitProviderService.ListConfigsForUrl(repoUrl) + }, + FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { + return gitProviderService.GetConfig(id) + }, + GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { + return gitProviderService.GetLastCommitSha(repo) + }, + CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { + return jobService.Save(&models.Job{ + ResourceId: workspaceId, + ResourceType: models.ResourceTypeWorkspace, + Action: action, + State: models.JobStatePending, + }) + }, + TrackTelemetryEvent: telemetryService.TrackServerEvent, + ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + ServerVersion: version, + ServerUrl: headscaleUrl, + DefaultWorkspaceImage: c.DefaultWorkspaceImage, + DefaultWorkspaceUser: c.DefaultWorkspaceUser, + Provisioner: provisioner, + LoggerFactory: loggerFactory, + }) + + profileDataService := profiledata.NewProfileDataService(profiledata.ProfileDataServiceConfig{ + ProfileDataStore: profileDataStore, + }) + + s := server.GetInstance(&server.ServerInstanceConfig{ + Config: *c, + Version: version, + TailscaleServer: headscaleServer, + TargetConfigService: targetConfigService, + ContainerRegistryService: containerRegistryService, + BuildService: buildService, + WorkspaceConfigService: workspaceConfigService, + WorkspaceService: workspaceService, + LocalContainerRegistry: localContainerRegistry, + ApiKeyService: apiKeyService, + TargetService: targetService, + GitProviderService: gitProviderService, + ProviderManager: providerManager, + ProfileDataService: profileDataService, + JobService: jobService, + TelemetryService: telemetryService, + }) + + return s, s.Initialize() +} + +func getDbPath() (string, error) { + configDir, err := config.GetConfigDir() + if err != nil { + return "", err + } + + err = os.MkdirAll(configDir, 0755) + if err != nil { + return "", err + } + + return filepath.Join(configDir, "db"), nil +} diff --git a/pkg/cmd/server/bootstrap/init_provider_manager.go b/pkg/cmd/server/bootstrap/init_provider_manager.go new file mode 100644 index 0000000000..f3a19cc649 --- /dev/null +++ b/pkg/cmd/server/bootstrap/init_provider_manager.go @@ -0,0 +1,87 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package bootstrap + +import ( + "context" + "net/url" + "path/filepath" + + "github.com/daytonaio/daytona/internal" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/db" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider/manager" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/headscale" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" +) + +func InitProviderManager(c *server.Config, configDir string) error { + targetLogsDir, err := server.GetTargetLogsDir(configDir) + if err != nil { + return err + } + + headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ + ServerId: c.Id, + FrpsDomain: c.Frps.Domain, + FrpsProtocol: c.Frps.Protocol, + HeadscalePort: c.HeadscalePort, + ConfigDir: filepath.Join(configDir, "headscale"), + Frps: c.Frps, + }) + err = headscaleServer.Init() + if err != nil { + return err + } + + headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) + + version := internal.Version + + dbPath, err := getDbPath() + if err != nil { + return err + } + + dbConnection := db.GetSQLiteConnection(dbPath) + + targetConfigStore, err := db.NewTargetConfigStore(dbConnection) + if err != nil { + return err + } + + targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ + TargetConfigStore: targetConfigStore, + }) + + _ = manager.GetProviderManager(&manager.ProviderManagerConfig{ + LogsDir: targetLogsDir, + ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + DaytonaDownloadUrl: getDaytonaScriptUrl(c), + ServerUrl: headscaleUrl, + ServerVersion: version, + RegistryUrl: c.RegistryUrl, + BaseDir: c.ProvidersDir, + CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { + return headscaleServer.CreateAuthKey() + }, + ServerPort: c.HeadscalePort, + ApiPort: c.ApiPort, + GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { + return targetConfigService.Map() + }, + CreateTargetConfig: func(ctx context.Context, targetConfig *models.TargetConfig) error { + return targetConfigService.Save(targetConfig) + }, + }) + + return nil +} + +func getDaytonaScriptUrl(config *server.Config) string { + url, _ := url.JoinPath(util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain), "binary", "script") + return url +} diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 46f943d84f..e7d8d0e97b 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -7,41 +7,20 @@ import ( "context" "errors" "fmt" - "net/url" "os" "os/signal" - "path/filepath" - "strings" "time" "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal" - "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/api" "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/db" - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/cmd/server/bootstrap" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" - "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/apikeys" - "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/server/headscale" - "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/registry" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" - "github.com/daytonaio/daytona/pkg/server/workspaces" - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -96,7 +75,12 @@ var ServeCmd = &cobra.Command{ Frps: c.Frps, }) - server, err := GetInstance(c, configDir, internal.Version, telemetryService) + err = bootstrap.InitProviderManager(c, configDir) + if err != nil { + return err + } + + server, err := bootstrap.GetInstance(c, configDir, internal.Version, telemetryService) if err != nil { return err } @@ -106,7 +90,7 @@ var ServeCmd = &cobra.Command{ return err } - buildRunner, err := GetBuildRunner(c, buildRunnerConfig, telemetryService) + buildRunner, err := bootstrap.GetBuildRunner(c, buildRunnerConfig, telemetryService) if err != nil { return err } @@ -116,6 +100,17 @@ var ServeCmd = &cobra.Command{ return err } + jobRunner, err := bootstrap.GetJobRunner(c, configDir, internal.Version, telemetryService) + if err != nil { + return err + } + + // TODO: context? + err = jobRunner.StartRunner(context.Background()) + if err != nil { + return err + } + apiServerErrChan := make(chan error) go func() { @@ -195,459 +190,6 @@ var ServeCmd = &cobra.Command{ }, } -func GetInstance(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (*server.Server, error) { - targetLogsDir, err := server.GetTargetLogsDir(configDir) - if err != nil { - return nil, err - } - buildLogsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) - - dbPath, err := getDbPath() - if err != nil { - return nil, err - } - - dbConnection := db.GetSQLiteConnection(dbPath) - - apiKeyStore, err := db.NewApiKeyStore(dbConnection) - if err != nil { - return nil, err - } - containerRegistryStore, err := db.NewContainerRegistryStore(dbConnection) - if err != nil { - return nil, err - } - buildStore, err := db.NewBuildStore(dbConnection) - if err != nil { - return nil, err - } - workspaceConfigStore, err := db.NewWorkspaceConfigStore(dbConnection) - if err != nil { - return nil, err - } - gitProviderConfigStore, err := db.NewGitProviderConfigStore(dbConnection) - if err != nil { - return nil, err - } - targetConfigStore, err := db.NewTargetConfigStore(dbConnection) - if err != nil { - return nil, err - } - targetStore, err := db.NewTargetStore(dbConnection) - if err != nil { - return nil, err - } - profileDataStore, err := db.NewProfileDataStore(dbConnection) - if err != nil { - return nil, err - } - workspaceStore, err := db.NewWorkspaceStore(dbConnection) - if err != nil { - return nil, err - } - - headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ - ServerId: c.Id, - FrpsDomain: c.Frps.Domain, - FrpsProtocol: c.Frps.Protocol, - HeadscalePort: c.HeadscalePort, - ConfigDir: filepath.Join(configDir, "headscale"), - Frps: c.Frps, - }) - err = headscaleServer.Init() - if err != nil { - return nil, err - } - - containerRegistryService := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ - Store: containerRegistryStore, - }) - - gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ - ConfigStore: gitProviderConfigStore, - DetachWorkspaceConfigs: func(ctx context.Context, gitProviderConfigId string) error { - workspaceConfigs, err := workspaceConfigStore.List(&stores.WorkspaceConfigFilter{ - GitProviderConfigId: &gitProviderConfigId, - }) - - if err != nil { - return err - } - - for _, workspaceConfig := range workspaceConfigs { - workspaceConfig.GitProviderConfigId = nil - err = workspaceConfigStore.Save(workspaceConfig) - if err != nil { - return err - } - } - - return nil - }, - }) - - buildService := builds.NewBuildService(builds.BuildServiceConfig{ - BuildStore: buildStore, - FindWorkspaceConfig: func(ctx context.Context, name string) (*models.WorkspaceConfig, error) { - return workspaceConfigStore.Find(&stores.WorkspaceConfigFilter{ - Name: &name, - }) - }, - GetRepositoryContext: func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) { - gitProvider, _, err := gitProviderService.GetGitProviderForUrl(url) - if err != nil { - return nil, err - } - - repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: url, - }) - - return repo, err - }, - LoggerFactory: loggerFactory, - }) - - prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) - - workspaceConfigService := workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ - PrebuildWebhookEndpoint: prebuildWebhookEndpoint, - ConfigStore: workspaceConfigStore, - FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { - return buildService.Find(&stores.BuildFilter{ - PrebuildIds: &[]string{prebuildId}, - GetNewest: util.Pointer(true), - }) - }, - ListPublishedBuilds: func(ctx context.Context) ([]*models.Build, error) { - return buildService.List(&stores.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePublished}, - }) - }, - CreateBuild: func(ctx context.Context, workspaceConfig *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error { - createBuildDto := services.CreateBuildDTO{ - WorkspaceConfigName: workspaceConfig.Name, - Branch: repo.Branch, - PrebuildId: &prebuildId, - EnvVars: workspaceConfig.EnvVars, - } - - _, err := buildService.Create(createBuildDto) - return err - }, - DeleteBuilds: func(ctx context.Context, id, prebuildId *string, force bool) []error { - var prebuildIds *[]string - if prebuildId != nil { - prebuildIds = &[]string{*prebuildId} - } - - return buildService.MarkForDeletion(&stores.BuildFilter{ - Id: id, - PrebuildIds: prebuildIds, - }, force) - }, - GetRepositoryContext: func(ctx context.Context, url string) (*gitprovider.GitRepository, string, error) { - gitProvider, gitProviderId, err := gitProviderService.GetGitProviderForUrl(url) - if err != nil { - return nil, "", err - } - - repo, err := gitProvider.GetRepositoryContext(gitprovider.GetRepositoryContext{ - Url: url, - }) - - return repo, gitProviderId, err - }, - FindPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { - return gitProviderService.GetPrebuildWebhook(gitProviderId, repo, endpointUrl) - }, - UnregisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error { - return gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repo, id) - }, - RegisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { - return gitProviderService.RegisterPrebuildWebhook(gitProviderId, repo, endpointUrl) - }, - GetCommitsRange: func(ctx context.Context, repo *gitprovider.GitRepository, initialSha, currentSha string) (int, error) { - gitProvider, _, err := gitProviderService.GetGitProviderForUrl(repo.Url) - if err != nil { - return 0, err - } - - return gitProvider.GetCommitsRange(repo, initialSha, currentSha) - }, - }) - - err = workspaceConfigService.StartRetentionPoller() - if err != nil { - return nil, err - } - - var localContainerRegistry server.ILocalContainerRegistry - - if c.BuilderRegistryServer != "local" { - _, err := containerRegistryService.Find(c.BuilderRegistryServer) - if err != nil { - log.Errorf("Failed to find container registry credentials for builder registry server %s\n", c.BuilderRegistryServer) - log.Errorf("Defaulting to local container registry. To use %s as the builder registry, add credentials for the registry server with 'daytona container-registry set' and restart the server\n", c.BuilderRegistryServer) - c.BuilderRegistryServer = "local" - } - } - - if c.BuilderRegistryServer == "local" { - cr, err := containerRegistryService.FindByImageName(c.LocalBuilderRegistryImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return nil, err - } - - localContainerRegistry = registry.NewLocalContainerRegistry(®istry.LocalContainerRegistryConfig{ - DataPath: filepath.Join(configDir, "registry"), - Port: c.LocalBuilderRegistryPort, - Image: c.LocalBuilderRegistryImage, - ContainerRegistry: cr, - Logger: log.StandardLogger().Writer(), - Frps: c.Frps, - ServerId: c.Id, - }) - c.BuilderRegistryServer = util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain) - } - - targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ - TargetConfigStore: targetConfigStore, - }) - - apiKeyService := apikeys.NewApiKeyService(apikeys.ApiKeyServiceConfig{ - ApiKeyStore: apiKeyStore, - }) - - headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) - - providerManager := manager.NewProviderManager(manager.ProviderManagerConfig{ - LogsDir: targetLogsDir, - ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - DaytonaDownloadUrl: getDaytonaScriptUrl(c), - ServerUrl: headscaleUrl, - ServerVersion: version, - RegistryUrl: c.RegistryUrl, - BaseDir: c.ProvidersDir, - CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { - return headscaleServer.CreateAuthKey() - }, - ServerPort: c.HeadscalePort, - ApiPort: c.ApiPort, - GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { - return targetConfigService.Map() - }, - CreateTargetConfig: func(ctx context.Context, targetConfig *models.TargetConfig) error { - return targetConfigService.Save(targetConfig) - }, - }) - - provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ - ProviderManager: providerManager, - }) - - targetService := targets.NewTargetService(targets.TargetServiceConfig{ - TargetStore: targetStore, - FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { - return targetConfigService.Find(&stores.TargetConfigFilter{Name: &name}) - }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(models.ApiKeyTypeTarget, name) - }, - RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(name) - }, - ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - ServerVersion: version, - ServerUrl: headscaleUrl, - Provisioner: provisioner, - LoggerFactory: loggerFactory, - TelemetryService: telemetryService, - }) - - workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ - BuilderImage: c.BuilderImage, - WorkspaceStore: workspaceStore, - FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - t, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, false) - if err != nil { - return nil, err - } - return &t.Target, nil - }, - FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { - return containerRegistryService.FindByImageName(image) - }, - FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { - validStates := &[]models.BuildState{ - models.BuildStatePublished, - } - - build, err := buildService.Find(&stores.BuildFilter{ - States: validStates, - RepositoryUrl: &w.Repository.Url, - Branch: &w.Repository.Branch, - EnvVars: &w.EnvVars, - BuildConfig: w.BuildConfig, - GetNewest: util.Pointer(true), - }) - if err != nil { - return nil, err - } - - if build.Image == nil || build.User == nil { - return nil, errors.New("cached build is missing image or user") - } - - return &models.CachedBuild{ - User: *build.User, - Image: *build.Image, - }, nil - }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(models.ApiKeyTypeWorkspace, name) - }, - RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(name) - }, - ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { - return gitProviderService.ListConfigsForUrl(repoUrl) - }, - FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(id) - }, - GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { - return gitProviderService.GetLastCommitSha(repo) - }, - TrackTelemetryEvent: telemetryService.TrackServerEvent, - ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - ServerVersion: version, - ServerUrl: headscaleUrl, - DefaultWorkspaceImage: c.DefaultWorkspaceImage, - DefaultWorkspaceUser: c.DefaultWorkspaceUser, - Provisioner: provisioner, - LoggerFactory: loggerFactory, - }) - - profileDataService := profiledata.NewProfileDataService(profiledata.ProfileDataServiceConfig{ - ProfileDataStore: profileDataStore, - }) - - s := server.GetInstance(&server.ServerInstanceConfig{ - Config: *c, - Version: version, - TailscaleServer: headscaleServer, - TargetConfigService: targetConfigService, - ContainerRegistryService: containerRegistryService, - BuildService: buildService, - WorkspaceConfigService: workspaceConfigService, - WorkspaceService: workspaceService, - LocalContainerRegistry: localContainerRegistry, - ApiKeyService: apiKeyService, - TargetService: targetService, - GitProviderService: gitProviderService, - ProviderManager: providerManager, - ProfileDataService: profileDataService, - TelemetryService: telemetryService, - }) - - return s, s.Initialize() -} - -func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetryService telemetry.TelemetryService) (*build.BuildRunner, error) { - logsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(nil, &logsDir) - - dbPath, err := getDbPath() - if err != nil { - return nil, err - } - - dbConnection := db.GetSQLiteConnection(dbPath) - - gitProviderConfigStore, err := db.NewGitProviderConfigStore(dbConnection) - if err != nil { - return nil, err - } - - gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ - ConfigStore: gitProviderConfigStore, - }) - - buildStore, err := db.NewBuildStore(dbConnection) - if err != nil { - return nil, err - } - - buildImageNamespace := c.BuildImageNamespace - if buildImageNamespace != "" { - buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) - } - buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") - - containerRegistryStore, err := db.NewContainerRegistryStore(dbConnection) - if err != nil { - return nil, err - } - - containerRegistryService := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ - Store: containerRegistryStore, - }) - - var builderRegistry *models.ContainerRegistry - - if c.BuilderRegistryServer != "local" { - builderRegistry, err = containerRegistryService.Find(c.BuilderRegistryServer) - if err != nil { - builderRegistry = &models.ContainerRegistry{ - Server: c.BuilderRegistryServer, - } - } - } - - cr, err := containerRegistryService.FindByImageName(c.BuilderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return nil, err - } - - configDir, err := config.GetConfigDir() - if err != nil { - return nil, err - } - - builderFactory := build.NewBuilderFactory(build.BuilderFactoryConfig{ - Image: c.BuilderImage, - ContainerRegistry: cr, - BuildImageContainerRegistry: builderRegistry, - BuildStore: buildStore, - BuildImageNamespace: buildImageNamespace, - LoggerFactory: loggerFactory, - DefaultWorkspaceImage: c.DefaultWorkspaceImage, - DefaultWorkspaceUser: c.DefaultWorkspaceUser, - }) - - return build.NewBuildRunner(build.BuildRunnerInstanceConfig{ - Interval: buildRunnerConfig.Interval, - Scheduler: build.NewCronScheduler(), - BuildRunnerId: buildRunnerConfig.Id, - ContainerRegistry: builderRegistry, - TelemetryEnabled: buildRunnerConfig.TelemetryEnabled, - GitProviderStore: gitProviderService, - BuildStore: buildStore, - BuilderFactory: builderFactory, - LoggerFactory: loggerFactory, - BasePath: filepath.Join(configDir, "builds"), - TelemetryService: telemetryService, - }), nil -} - func waitForApiServerToStart(apiServer *api.ApiServer) error { var err error for i := 0; i < 30; i++ { @@ -663,29 +205,10 @@ func waitForApiServerToStart(apiServer *api.ApiServer) error { return err } -func getDaytonaScriptUrl(config *server.Config) string { - url, _ := url.JoinPath(util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain), "binary", "script") - return url -} - func printServerStartedMessage(c *server.Config, runAsDaemon bool) { started_view.Render(c.ApiPort, util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), runAsDaemon) } -func getDbPath() (string, error) { - configDir, err := config.GetConfigDir() - if err != nil { - return "", err - } - - err = os.MkdirAll(configDir, 0755) - if err != nil { - return "", err - } - - return filepath.Join(configDir, "db"), nil -} - func ensureDefaultProfile(server *server.Server, apiPort uint32) error { existingConfig, err := config.GetConfig() if err != nil { diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index ea563cfec4..0d4f488a5d 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -11,6 +11,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/cmd/targetconfig" "github.com/daytonaio/daytona/pkg/common" @@ -80,6 +81,11 @@ var targetCreateCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } + err = cmd_common.AwaitTargetState(createTargetDto.Id, apiclient.ResourceStateNameStarted) + if err != nil { + return err + } + views.RenderInfoMessage(fmt.Sprintf("Target '%s' set successfully and will be used by default", createTargetDto.Name)) return nil }, diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index 1c5feac199..bbff2261fd 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -11,6 +11,7 @@ import ( "github.com/charmbracelet/huh" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -26,7 +27,6 @@ var deleteCmd = &cobra.Command{ Short: "Delete a target", Aliases: []string{"remove", "rm"}, RunE: func(cmd *cobra.Command, args []string) error { - ctx := context.Background() var targetDeleteList = []*apiclient.TargetDTO{} @@ -92,7 +92,7 @@ var deleteCmd = &cobra.Command{ } } else { for _, arg := range args { - target, err := apiclient_util.GetTarget(arg, false) + target, _, err := apiclient_util.GetTarget(arg, false) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -126,7 +126,7 @@ var deleteCmd = &cobra.Command{ fmt.Println("Operation canceled.") } else { for _, target := range targetDeleteList { - err := RemoveTarget(ctx, apiClient, target, workspaceList, forceFlag) + err := DeleteTarget(ctx, apiClient, target, workspaceList, forceFlag) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", target.Name, err)) } else { @@ -137,7 +137,7 @@ var deleteCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getTargetNameCompletions() + return getAllTargetsByState(nil) }, } @@ -160,7 +160,7 @@ func DeleteAllTargets(workspaceList []apiclient.WorkspaceDTO, force bool) error } for _, target := range targetList { - err := RemoveTarget(ctx, apiClient, &target, workspaceList, force) + err := DeleteTarget(ctx, apiClient, &target, workspaceList, force) if err != nil { log.Errorf("Failed to delete target %s: %v", target.Name, err) continue @@ -170,7 +170,7 @@ func DeleteAllTargets(workspaceList []apiclient.WorkspaceDTO, force bool) error return nil } -func RemoveTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO, workspaceList []apiclient.WorkspaceDTO, force bool) error { +func DeleteTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO, workspaceList []apiclient.WorkspaceDTO, force bool) error { for _, workspace := range workspaceList { if workspace.TargetId == target.Id { return fmt.Errorf("target '%s' is in use by workspace '%s', please remove workspaces before deleting their target", target.Name, workspace.Name) @@ -184,6 +184,11 @@ func RemoveTarget(ctx context.Context, apiClient *apiclient.APIClient, target *a return apiclient_util.HandleErrorResponse(res, err) } + err = cmd_common.AwaitTargetDeleted(target.Id) + if err != nil { + return err + } + return nil }) diff --git a/pkg/cmd/target/info.go b/pkg/cmd/target/info.go index 51c6442c95..ed1ed11c25 100644 --- a/pkg/cmd/target/info.go +++ b/pkg/cmd/target/info.go @@ -51,7 +51,7 @@ var infoCmd = &cobra.Command{ } } else { - target, err = apiclient_util.GetTarget(args[0], true) + target, _, err = apiclient_util.GetTarget(args[0], true) if err != nil { return err } @@ -71,7 +71,7 @@ var infoCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getTargetNameCompletions() + return getAllTargetsByState(nil) }, } diff --git a/pkg/cmd/target/logs.go b/pkg/cmd/target/logs.go index 593d46ab04..b9b7228b28 100644 --- a/pkg/cmd/target/logs.go +++ b/pkg/cmd/target/logs.go @@ -17,7 +17,7 @@ import ( var logsCmd = &cobra.Command{ Use: "logs [TARGET]", Short: "View the logs of a target", - Args: cobra.RangeArgs(0, 2), + Args: cobra.RangeArgs(0, 1), Aliases: []string{"lg", "log"}, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -51,7 +51,7 @@ var logsCmd = &cobra.Command{ return nil } } else { - target, err = apiclient_util.GetTarget(args[0], false) + target, _, err = apiclient_util.GetTarget(args[0], false) if err != nil { return err } @@ -66,10 +66,9 @@ var logsCmd = &cobra.Command{ return nil }, - // FIXME: add after adding state to targets - // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // return getAllTargetsByState(TARGET_STATE_RUNNING) - // }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getAllTargetsByState(nil) + }, } var followFlag bool diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index 2695d9e8bf..748f1736e1 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -7,6 +7,7 @@ import ( "context" "fmt" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" @@ -56,10 +57,9 @@ var restartCmd = &cobra.Command{ views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) return nil }, - // FIXME: add after adding state to targets - // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // return getAllTargetsByState(TARGET_STATE_RUNNING) - // }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getAllTargetsByState(util.Pointer(apiclient.ResourceStateNameStarted)) + }, } func RestartTarget(apiClient *apiclient.APIClient, targetId string) error { diff --git a/pkg/cmd/target/setdefault.go b/pkg/cmd/target/setdefault.go index f4d709c5f7..c2ed5e780b 100644 --- a/pkg/cmd/target/setdefault.go +++ b/pkg/cmd/target/setdefault.go @@ -42,7 +42,7 @@ var setDefaultCmd = &cobra.Command{ target = selection.GetTargetFromPrompt(targetList, false, "Set As Default") } else { - target, err = apiclient_util.GetTarget(args[0], true) + target, _, err = apiclient_util.GetTarget(args[0], true) if err != nil { return err } @@ -61,6 +61,6 @@ var setDefaultCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return getTargetNameCompletions() + return getAllTargetsByState(nil) }, } diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 955f787cfe..1099b40fcb 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -12,6 +12,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -20,13 +21,6 @@ import ( "github.com/spf13/cobra" ) -type TargetState string - -const ( - TARGET_STATE_RUNNING TargetState = "Running" - TARGET_STATE_STOPPED TargetState = "Unavailable" -) - var allFlag bool var startCmd = &cobra.Command{ @@ -86,10 +80,9 @@ var startCmd = &cobra.Command{ } return nil }, - // FIXME: add after adding state to targets - // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // return getAllTargetsByState(TARGET_STATE_STOPPED) - // }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getAllTargetsByState(util.Pointer(apiclient.ResourceStateNameStopped)) + }, } func init() { @@ -121,28 +114,7 @@ func startAllTargets() error { return nil } -// FIXME: add target completions -// func getWorkspaceNameCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { -// ctx := context.Background() -// apiClient, err := apiclient_util.GetApiClient(nil) -// if err != nil { -// return nil, cobra.ShellCompDirectiveDefault -// } - -// targetId := args[0] -// target, _, err := apiClient.TargetAPI.GetTarget(ctx, targetId).Execute() -// if err != nil { -// return nil, cobra.ShellCompDirectiveDefault -// } - -// var choices []string -// for _, workspace := range target.Workspaces { -// choices = append(choices, workspace.Name) -// } -// return choices, cobra.ShellCompDirectiveDefault -// } - -func getTargetNameCompletions() ([]string, cobra.ShellCompDirective) { +func getAllTargetsByState(state *apiclient.ModelsResourceStateName) ([]string, cobra.ShellCompDirective) { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -155,46 +127,25 @@ func getTargetNameCompletions() ([]string, cobra.ShellCompDirective) { } var choices []string - for _, v := range targetList { - choices = append(choices, v.Name) + for _, target := range targetList { + if state == nil { + choices = append(choices, target.Name) + break + } else { + if *state == apiclient.ResourceStateNameStarted { + choices = append(choices, target.Name) + break + } + if *state == apiclient.ResourceStateNameStopped { + choices = append(choices, target.Name) + break + } + } } return choices, cobra.ShellCompDirectiveNoFileComp } -// FIXME: fix this after adding state to targets -// func getAllTargetsByState(state TargetState) ([]string, cobra.ShellCompDirective) { -// ctx := context.Background() -// apiClient, err := apiclient_util.GetApiClient(nil) -// if err != nil { -// return nil, cobra.ShellCompDirectiveNoFileComp -// } - -// targetList, _, err := apiClient.TargetAPI.ListTargets(ctx).Execute() -// if err != nil { -// return nil, cobra.ShellCompDirectiveNoFileComp -// } - -// var choices []string -// for _, target := range targetList { -// for _, workspace := range target.Workspaces { -// if workspace.State == nil { -// continue -// } -// if state == TARGET_STATE_RUNNING && workspace.State.Uptime != 0 { -// choices = append(choices, target.Name) -// break -// } -// if state == TARGET_STATE_STOPPED && workspace.State.Uptime == 0 { -// choices = append(choices, target.Name) -// break -// } -// } -// } - -// return choices, cobra.ShellCompDirectiveNoFileComp -// } - func StartTarget(apiClient *apiclient.APIClient, targetId string) error { ctx := context.Background() timeFormat := time.Now().Format("2006-01-02 15:04:05") @@ -213,7 +164,7 @@ func StartTarget(apiClient *apiclient.APIClient, targetId string) error { return err } - target, err := apiclient_util.GetTarget(targetId, false) + target, _, err := apiclient_util.GetTarget(targetId, false) if err != nil { return err } @@ -226,12 +177,16 @@ func StartTarget(apiClient *apiclient.APIClient, targetId string) error { Follow: util.Pointer(true), From: &from, }) + res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) } + + err = cmd_common.AwaitTargetState(targetId, apiclient.ResourceStateNameStarted) + time.Sleep(100 * time.Millisecond) stopLogs() - return nil + return err } diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go index 3eee98a020..d359f1864b 100644 --- a/pkg/cmd/target/stop.go +++ b/pkg/cmd/target/stop.go @@ -12,6 +12,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" logs_view "github.com/daytonaio/daytona/pkg/views/logs" "github.com/daytonaio/daytona/pkg/views/target/selection" @@ -93,7 +94,7 @@ var stopCmd = &cobra.Command{ return err } - target, err := apiclient_util.GetTarget(targetId, false) + target, _, err := apiclient_util.GetTarget(targetId, false) if err != nil { return err } @@ -109,10 +110,9 @@ var stopCmd = &cobra.Command{ } return nil }, - // FIXME: add after adding state to targets - // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // return getAllTargetsByState(TARGET_STATE_RUNNING) - // }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return getAllTargetsByState(util.Pointer(apiclient.ResourceStateNameStarted)) + }, } func init() { @@ -162,7 +162,8 @@ func StopTarget(apiClient *apiclient.APIClient, targetId string) error { if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - return nil + + return cmd_common.AwaitTargetState(targetId, apiclient.ResourceStateNameStarted) }) if err != nil { return err diff --git a/pkg/cmd/targetconfig/set.go b/pkg/cmd/targetconfig/set.go index cbb7205a4e..4d5ec93ad5 100644 --- a/pkg/cmd/targetconfig/set.go +++ b/pkg/cmd/targetconfig/set.go @@ -91,7 +91,7 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, apiclient_util.HandleErrorResponse(res, err) } - providersManifest, err := manager.NewProviderManager(manager.ProviderManagerConfig{ + providersManifest, err := manager.GetProviderManager(&manager.ProviderManagerConfig{ RegistryUrl: serverConfig.RegistryUrl, }).GetProvidersManifest() if err != nil { diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go index 2fd916f33b..406f499299 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/workspace/code.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "net/http" "net/url" "strings" @@ -14,9 +15,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" - "github.com/daytonaio/daytona/pkg/server/workspaces" ide_views "github.com/daytonaio/daytona/pkg/views/ide" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -68,9 +68,10 @@ var CodeCmd = &cobra.Command{ return nil } } else { - ws, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]), true) + var statusCode int + ws, statusCode, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]), true) if err != nil { - if strings.Contains(err.Error(), workspaces.ErrWorkspaceNotFound.Error()) { + if statusCode == http.StatusNotFound { log.Debug(err) return errors.New("workspace not found. You can see all workspace names by running the command `daytona list`") } @@ -81,7 +82,7 @@ var CodeCmd = &cobra.Command{ ideId = create.IdeFlag } - if ws.State != nil || ws.State.Uptime < 1 { + if ws.State.Name == apiclient.ResourceStateNameStopped { wsRunningStatus, err := AutoStartWorkspace(*ws) if err != nil { return err diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 4891446bca..a018cbd44a 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -16,7 +16,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/views" @@ -185,6 +185,12 @@ var CreateCmd = &cobra.Command{ if err != nil { return apiclient_util.HandleErrorResponse(res, err) } + + err = cmd_common.AwaitTargetState(t.Id, apiclient.ResourceStateNameStarted) + if err != nil { + return err + } + target = &apiclient.TargetDTO{ Id: t.Id, Name: t.Name, @@ -217,12 +223,17 @@ var CreateCmd = &cobra.Command{ if err != nil { return apiclient_util.HandleErrorResponse(res, err) } + + err = cmd_common.AwaitWorkspaceState(createWorkspaceDtos[i].Id, apiclient.ResourceStateNameStarted) + if err != nil { + return err + } } if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - gpgKey, err := workspace_common.GetGitProviderGpgKey(apiClient, ctx, createWorkspaceDtos[0].GitProviderConfigId) + gpgKey, err := cmd_common.GetGitProviderGpgKey(apiClient, ctx, createWorkspaceDtos[0].GitProviderConfigId) if err != nil { log.Warn(err) } @@ -253,7 +264,7 @@ var CreateCmd = &cobra.Command{ fmt.Println() - ws, err := apiclient_util.GetWorkspace(createWorkspaceDtos[0].Id, true) + ws, _, err := apiclient_util.GetWorkspace(createWorkspaceDtos[0].Id, true) if err != nil { return err } @@ -267,7 +278,7 @@ var CreateCmd = &cobra.Command{ views.RenderCreationInfoMessage(fmt.Sprintf("Opening the workspace in %s ...", chosenIde.Name)) - return workspace_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *ws.Info.ProviderMetadata, YesFlag, gpgKey) + return cmd_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *ws.Info.ProviderMetadata, YesFlag, gpgKey) }, } @@ -278,7 +289,7 @@ var noIdeFlag bool var blankFlag bool var multiWorkspaceFlag bool -var workspaceConfigurationFlags = workspace_common.WorkspaceConfigurationFlags{ +var workspaceConfigurationFlags = cmd_common.WorkspaceConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -305,7 +316,7 @@ func init() { CreateCmd.Flags().BoolVarP(&YesFlag, "yes", "y", false, "Automatically confirm any prompts") CreateCmd.Flags().StringSliceVar(workspaceConfigurationFlags.Branches, "branch", []string{}, "Specify the Git branches to use in the workspaces") - workspace_common.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) + cmd_common.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) } func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { diff --git a/pkg/cmd/workspace/create/creation_data.go b/pkg/cmd/workspace/create/creation_data.go index be77ba4982..5050ab2788 100644 --- a/pkg/cmd/workspace/create/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -16,7 +16,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -250,7 +250,7 @@ func GetBranchFromWorkspaceConfig(ctx context.Context, workspaceConfig *apiclien }, nil } -func GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags) (*apiclient.CreateWorkspaceDTO, error) { +func GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags cmd_common.WorkspaceConfigurationFlags) (*apiclient.CreateWorkspaceDTO, error) { workspace := &apiclient.CreateWorkspaceDTO{ GitProviderConfigId: workspaceConfigurationFlags.GitProviderConfig, BuildConfig: &apiclient.BuildConfig{}, diff --git a/pkg/cmd/workspace/create/process_cmd_arguments.go b/pkg/cmd/workspace/create/process_cmd_arguments.go index afdedff50a..4c5e8ed4e0 100644 --- a/pkg/cmd/workspace/create/process_cmd_arguments.go +++ b/pkg/cmd/workspace/create/process_cmd_arguments.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -23,7 +23,7 @@ type ProcessCmdArgumentsParams struct { RepoUrls []string CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO ExistingWorkspaces *[]apiclient.WorkspaceDTO - WorkspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags + WorkspaceConfigurationFlags cmd_common.WorkspaceConfigurationFlags BlankFlag bool } @@ -31,7 +31,7 @@ type ProcessGitUrlParams struct { ApiClient *apiclient.APIClient RepoUrl string CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO - WorkspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags + WorkspaceConfigurationFlags cmd_common.WorkspaceConfigurationFlags Branch *string BlankFlag bool } @@ -41,7 +41,7 @@ func ProcessCmdArguments(ctx context.Context, params ProcessCmdArgumentsParams) return nil, fmt.Errorf("no repository URLs provided") } - if len(params.RepoUrls) > 1 && workspace_common.CheckAnyWorkspaceConfigurationFlagSet(params.WorkspaceConfigurationFlags) { + if len(params.RepoUrls) > 1 && cmd_common.CheckAnyWorkspaceConfigurationFlagSet(params.WorkspaceConfigurationFlags) { return nil, fmt.Errorf("can't set custom workspace configuration properties for multiple workspaces") } diff --git a/pkg/cmd/workspace/create/process_prompting.go b/pkg/cmd/workspace/create/process_prompting.go index 605530dead..7af322dca7 100644 --- a/pkg/cmd/workspace/create/process_prompting.go +++ b/pkg/cmd/workspace/create/process_prompting.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/create" ) @@ -19,7 +19,7 @@ type ProcessPromptingParams struct { ApiClient *apiclient.APIClient CreateWorkspaceDtos *[]apiclient.CreateWorkspaceDTO ExistingWorkspaces *[]apiclient.WorkspaceDTO - WorkspaceConfigurationFlags workspace_common.WorkspaceConfigurationFlags + WorkspaceConfigurationFlags cmd_common.WorkspaceConfigurationFlags MultiWorkspaceFlag bool BlankFlag bool TargetName string @@ -27,7 +27,7 @@ type ProcessPromptingParams struct { } func ProcessPrompting(ctx context.Context, params ProcessPromptingParams) error { - if workspace_common.CheckAnyWorkspaceConfigurationFlagSet(params.WorkspaceConfigurationFlags) || (params.WorkspaceConfigurationFlags.Branches != nil && len(*params.WorkspaceConfigurationFlags.Branches) > 0) { + if cmd_common.CheckAnyWorkspaceConfigurationFlagSet(params.WorkspaceConfigurationFlags) || (params.WorkspaceConfigurationFlags.Branches != nil && len(*params.WorkspaceConfigurationFlags.Branches) > 0) { return errors.New("please provide the repository URL in order to set up custom workspace details through the CLI") } diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index 868d2f306e..4e60a8ceff 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -13,7 +13,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -86,7 +87,7 @@ var DeleteCmd = &cobra.Command{ workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, "Delete") } else { for _, arg := range args { - workspace, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg, false) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -123,7 +124,7 @@ var DeleteCmd = &cobra.Command{ fmt.Println("Operation canceled.") } else { for _, workspace := range workspaceDeleteList { - err := RemoveWorkspace(ctx, apiClient, workspace, forceFlag) + err := DeleteWorkspace(ctx, apiClient, workspace, forceFlag) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", workspace.Name, err)) } @@ -156,7 +157,7 @@ func DeleteAllWorkspaces(force bool) error { } for _, workspace := range workspaceList { - err := RemoveWorkspace(ctx, apiClient, &workspace, force) + err := DeleteWorkspace(ctx, apiClient, &workspace, force) if err != nil { log.Errorf("Failed to delete workspace %s: %v", workspace.Name, err) continue @@ -166,7 +167,7 @@ func DeleteAllWorkspaces(force bool) error { return nil } -func RemoveWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspace *apiclient.WorkspaceDTO, force bool) error { +func DeleteWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspace *apiclient.WorkspaceDTO, force bool) error { message := fmt.Sprintf("Deleting workspace %s", workspace.Name) err := views_util.WithInlineSpinner(message, func() error { res, err := apiClient.WorkspaceAPI.RemoveWorkspace(ctx, workspace.Id).Force(force).Execute() @@ -187,6 +188,12 @@ func RemoveWorkspace(ctx context.Context, apiClient *apiclient.APIClient, worksp if err != nil { return err } + + err = cmd_common.AwaitWorkspaceDeleted(workspace.Id) + if err != nil { + return err + } + return nil }) diff --git a/pkg/cmd/workspace/info.go b/pkg/cmd/workspace/info.go index ccfbdf07da..51f98ed645 100644 --- a/pkg/cmd/workspace/info.go +++ b/pkg/cmd/workspace/info.go @@ -9,8 +9,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/info" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -54,7 +54,7 @@ var InfoCmd = &cobra.Command{ } } else { - ws, err = apiclient_util.GetWorkspace(args[0], true) + ws, _, err = apiclient_util.GetWorkspace(args[0], true) if err != nil { return err } diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 99bc106e54..6ec34124d0 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -32,7 +32,6 @@ var ListCmd = &cobra.Command{ } workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(verbose).Execute() - if err != nil { return apiclient.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/workspace/logs.go b/pkg/cmd/workspace/logs.go index 1ae7e2f3e7..662c1db57d 100644 --- a/pkg/cmd/workspace/logs.go +++ b/pkg/cmd/workspace/logs.go @@ -10,8 +10,8 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" "github.com/spf13/cobra" @@ -66,7 +66,7 @@ var LogsCmd = &cobra.Command{ } } else { - ws, err = apiclient_util.GetWorkspace(args[0], true) + ws, _, err = apiclient_util.GetWorkspace(args[0], true) if err != nil { return err } diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/workspace/restart.go index a41f8bd649..434a49ff78 100644 --- a/pkg/cmd/workspace/restart.go +++ b/pkg/cmd/workspace/restart.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -50,7 +50,7 @@ var RestartCmd = &cobra.Command{ } } else { for _, arg := range args { - workspace, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg, false) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -82,7 +82,7 @@ var RestartCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return common.GetAllWorkspacesByState(common.WORKSPACE_STATE_RUNNING) + return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStarted) }, } diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index 60f7eae530..a81a8a693c 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -44,12 +44,12 @@ var SshProxyCmd = &cobra.Command{ return err } - ws, err := apiclient_util.GetWorkspace(workspaceId, true) + ws, _, err := apiclient_util.GetWorkspace(workspaceId, true) if err != nil { return err } - target, err := apiclient_util.GetTarget(ws.TargetId, true) + target, _, err := apiclient_util.GetTarget(ws.TargetId, true) if err != nil { return err } diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index 64651d3aa5..dcfdd66f62 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -16,7 +16,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -70,7 +70,7 @@ var SshCmd = &cobra.Command{ return nil } } else { - ws, err = apiclient_util.GetWorkspace(args[0], true) + ws, _, err = apiclient_util.GetWorkspace(args[0], true) if err != nil { return err } @@ -83,7 +83,7 @@ var SshCmd = &cobra.Command{ } } - if ws.State == nil || ws.State.Uptime < 1 { + if ws.State.Name == apiclient.ResourceStateNameStopped { wsRunningStatus, err := AutoStartWorkspace(*ws) if err != nil { return err diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index adfe7ef967..adc99e9488 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" ide_views "github.com/daytonaio/daytona/pkg/views/ide" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -63,7 +63,7 @@ var StartCmd = &cobra.Command{ selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Start") } else { for _, arg := range args { - workspace, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg, false) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -130,7 +130,7 @@ var StartCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return common.GetAllWorkspacesByState(common.WORKSPACE_STATE_STOPPED) + return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStopped) }, } @@ -197,7 +197,15 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspac stopLogs() return apiclient_util.HandleErrorResponse(res, err) } + + err = common.AwaitWorkspaceState(workspace.Id, apiclient.ResourceStateNameStarted) + if err != nil { + stopLogs() + return err + } + time.Sleep(100 * time.Millisecond) + stopLogs() return nil } diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go index efc3de00c5..2f833f1436 100644 --- a/pkg/cmd/workspace/stop.go +++ b/pkg/cmd/workspace/stop.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -53,7 +53,7 @@ var StopCmd = &cobra.Command{ selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Stop") } else { for _, arg := range args { - workspace, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg, false) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -84,7 +84,7 @@ var StopCmd = &cobra.Command{ return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return common.GetAllWorkspacesByState(common.WORKSPACE_STATE_RUNNING) + return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStarted) }, } @@ -150,7 +150,15 @@ func StopWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspace stopLogs() return apiclient_util.HandleErrorResponse(res, err) } + + err = common.AwaitWorkspaceState(workspace.Id, apiclient.ResourceStateNameStopped) + if err != nil { + stopLogs() + return err + } + time.Sleep(100 * time.Millisecond) + stopLogs() return nil } diff --git a/pkg/cmd/workspaceconfig/add.go b/pkg/cmd/workspaceconfig/add.go index 6f66d6a37a..0d51138b78 100644 --- a/pkg/cmd/workspaceconfig/add.go +++ b/pkg/cmd/workspaceconfig/add.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - workspace_common "github.com/daytonaio/daytona/pkg/cmd/workspace/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" create_cmd "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" @@ -67,7 +67,7 @@ var workspaceConfigAddCmd = &cobra.Command{ } func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.WorkspaceConfig, error) { - if workspace_common.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { + if cmd_common.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { return nil, errors.New("please provide the repository URL in order to set up custom workspace config details through the CLI") } @@ -277,7 +277,7 @@ func getExistingWorkspaceConfigNames(apiClient *apiclient.APIClient) ([]string, var nameFlag string -var workspaceConfigurationFlags = workspace_common.WorkspaceConfigurationFlags{ +var workspaceConfigurationFlags = cmd_common.WorkspaceConfigurationFlags{ Builder: new(views_util.BuildChoice), CustomImage: new(string), CustomImageUser: new(string), @@ -290,5 +290,5 @@ var workspaceConfigurationFlags = workspace_common.WorkspaceConfigurationFlags{ func init() { workspaceConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace config name") - workspace_common.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) + cmd_common.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) } diff --git a/pkg/db/job_store.go b/pkg/db/job_store.go new file mode 100644 index 0000000000..a8eec4e5d7 --- /dev/null +++ b/pkg/db/job_store.go @@ -0,0 +1,104 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "fmt" + "strings" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" + "gorm.io/gorm" +) + +type JobStore struct { + db *gorm.DB +} + +func NewJobStore(db *gorm.DB) (*JobStore, error) { + err := db.AutoMigrate(&models.Job{}) + if err != nil { + return nil, err + } + + return &JobStore{db: db}, nil +} + +func (s *JobStore) List(filter *stores.JobFilter) ([]*models.Job, error) { + jobs := []*models.Job{} + tx := processJobFilters(s.db, filter).Find(&jobs) + + if tx.Error != nil { + return nil, tx.Error + } + + return jobs, nil +} + +func (s *JobStore) Find(filter *stores.JobFilter) (*models.Job, error) { + job := &models.Job{} + tx := processJobFilters(s.db, filter).First(&job) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, stores.ErrJobNotFound + } + return nil, tx.Error + } + + return job, nil + +} + +func (s *JobStore) Save(job *models.Job) error { + tx := s.db.Save(job) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *JobStore) Delete(job *models.Job) error { + tx := s.db.Delete(job) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrJobNotFound + } + + return nil +} + +func processJobFilters(tx *gorm.DB, filter *stores.JobFilter) *gorm.DB { + if filter != nil { + if filter.Id != nil { + tx = tx.Where("id = ?", *filter.Id) + } + if filter.ResourceType != nil { + tx = tx.Where("resource_type = ?", *filter.ResourceType) + } + if filter.States != nil && len(*filter.States) > 0 { + placeholders := strings.Repeat("?,", len(*filter.States)) + placeholders = placeholders[:len(placeholders)-1] + + tx = tx.Where(fmt.Sprintf("state IN (%s)", placeholders), filter.StatesToInterface()...) + } + if filter.Actions != nil && len(*filter.Actions) > 0 { + placeholders := strings.Repeat("?,", len(*filter.Actions)) + placeholders = placeholders[:len(placeholders)-1] + + tx = tx.Where(fmt.Sprintf("action IN (%s)", placeholders), filter.ActionsToInterface()...) + } + } + return tx +} + +func preloadLastJob(tx *gorm.DB) *gorm.DB { + return tx.Where("updated_at IN (?)", + tx.Model(&models.Job{}). + Select("MAX(updated_at)"). + Group("resource_id"), + ) +} diff --git a/pkg/db/target_metadata_store.go b/pkg/db/target_metadata_store.go new file mode 100644 index 0000000000..6bfce8d3e1 --- /dev/null +++ b/pkg/db/target_metadata_store.go @@ -0,0 +1,70 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type TargetMetadataStore struct { + db *gorm.DB +} + +func NewTargetMetadataStore(db *gorm.DB) (*TargetMetadataStore, error) { + err := db.AutoMigrate(&models.TargetMetadata{}) + if err != nil { + return nil, err + } + + return &TargetMetadataStore{db: db}, nil +} + +func (s *TargetMetadataStore) Find(filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { + targetMetadata := &models.TargetMetadata{} + tx := processTargetMetadataFilters(s.db, filter).First(&targetMetadata) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, stores.ErrTargetMetadataNotFound + } + return nil, tx.Error + } + + return targetMetadata, nil +} + +func (s *TargetMetadataStore) Save(targetMetadata *models.TargetMetadata) error { + tx := s.db.Save(targetMetadata) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *TargetMetadataStore) Delete(targetMetadata *models.TargetMetadata) error { + tx := s.db.Delete(targetMetadata) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrTargetMetadataNotFound + } + + return nil +} + +func processTargetMetadataFilters(tx *gorm.DB, filter *stores.TargetMetadataFilter) *gorm.DB { + if filter != nil { + if filter.Id != nil { + tx = tx.Where("id = ?", *filter.Id) + } + if filter.TargetId != nil { + tx = tx.Where("target_id = ?", *filter.TargetId) + } + } + return tx +} diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index f2d648125d..530cde4345 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -5,9 +5,9 @@ package db import ( "gorm.io/gorm" + "gorm.io/gorm/clause" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/stores" ) @@ -27,7 +27,7 @@ func NewTargetStore(db *gorm.DB) (stores.TargetStore, error) { func (s *TargetStore) List(filter *stores.TargetFilter) ([]*models.Target, error) { targets := []*models.Target{} - tx := processTargetFilters(s.db, filter).Preload("Workspaces").Find(&targets) + tx := preloadTargetEntities(processTargetFilters(s.db, filter)).Find(&targets) if tx.Error != nil { return nil, tx.Error } @@ -37,14 +37,14 @@ func (s *TargetStore) List(filter *stores.TargetFilter) ([]*models.Target, error func (s *TargetStore) Find(filter *stores.TargetFilter) (*models.Target, error) { tg := &models.Target{} - tx := processTargetFilters(s.db, filter).Preload("Workspaces").First(tg) + tx := preloadTargetEntities(processTargetFilters(s.db, filter)).First(tg) if tx.Error != nil { return nil, tx.Error } if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, targets.ErrTargetNotFound + return nil, stores.ErrTargetNotFound } return nil, tx.Error } @@ -66,7 +66,7 @@ func (s *TargetStore) Delete(t *models.Target) error { return tx.Error } if tx.RowsAffected == 0 { - return targets.ErrTargetNotFound + return stores.ErrTargetNotFound } return nil @@ -84,3 +84,7 @@ func processTargetFilters(tx *gorm.DB, filter *stores.TargetFilter) *gorm.DB { return tx } + +func preloadTargetEntities(tx *gorm.DB) *gorm.DB { + return tx.Preload(clause.Associations).Preload("Workspaces.LastJob", preloadLastJob).Preload("LastJob", preloadLastJob) +} diff --git a/pkg/db/workspace_metadata_store.go b/pkg/db/workspace_metadata_store.go new file mode 100644 index 0000000000..4ce2f626c1 --- /dev/null +++ b/pkg/db/workspace_metadata_store.go @@ -0,0 +1,70 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type WorkspaceMetadataStore struct { + db *gorm.DB +} + +func NewWorkspaceMetadataStore(db *gorm.DB) (*WorkspaceMetadataStore, error) { + err := db.AutoMigrate(&models.WorkspaceMetadata{}) + if err != nil { + return nil, err + } + + return &WorkspaceMetadataStore{db: db}, nil +} + +func (s *WorkspaceMetadataStore) Find(filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { + workspaceMetadata := &models.WorkspaceMetadata{} + tx := processWorkspaceMetadataFilters(s.db, filter).First(&workspaceMetadata) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, stores.ErrWorkspaceMetadataNotFound + } + return nil, tx.Error + } + + return workspaceMetadata, nil +} + +func (s *WorkspaceMetadataStore) Save(workspaceMetadata *models.WorkspaceMetadata) error { + tx := s.db.Save(workspaceMetadata) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *WorkspaceMetadataStore) Delete(workspaceMetadata *models.WorkspaceMetadata) error { + tx := s.db.Delete(workspaceMetadata) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrWorkspaceMetadataNotFound + } + + return nil +} + +func processWorkspaceMetadataFilters(tx *gorm.DB, filter *stores.WorkspaceMetadataFilter) *gorm.DB { + if filter != nil { + if filter.Id != nil { + tx = tx.Where("id = ?", *filter.Id) + } + if filter.WorkspaceId != nil { + tx = tx.Where("workspace_id = ?", *filter.WorkspaceId) + } + } + return tx +} diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go index 42bcba4d36..876e9abac4 100644 --- a/pkg/db/workspace_store.go +++ b/pkg/db/workspace_store.go @@ -8,7 +8,7 @@ import ( "gorm.io/gorm/clause" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/stores" ) type WorkspaceStore struct { @@ -24,9 +24,10 @@ func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { return &WorkspaceStore{db: db}, nil } -func (store *WorkspaceStore) List() ([]*models.Workspace, error) { +func (s *WorkspaceStore) List() ([]*models.Workspace, error) { workspaces := []*models.Workspace{} - tx := store.db.Preload(clause.Associations).Find(&workspaces) + // Order workspace jobs by created_at + tx := preloadWorkspaceEntities(s.db).Find(&workspaces) if tx.Error != nil { return nil, tx.Error } @@ -34,12 +35,12 @@ func (store *WorkspaceStore) List() ([]*models.Workspace, error) { return workspaces, nil } -func (w *WorkspaceStore) Find(idOrName string) (*models.Workspace, error) { +func (s *WorkspaceStore) Find(idOrName string) (*models.Workspace, error) { workspace := &models.Workspace{} - tx := w.db.Preload(clause.Associations).Where("id = ? OR name = ?", idOrName, idOrName).First(workspace) + tx := preloadWorkspaceEntities(s.db).Where("id = ? OR name = ?", idOrName, idOrName).First(workspace) if tx.Error != nil { if IsRecordNotFound(tx.Error) { - return nil, workspaces.ErrWorkspaceNotFound + return nil, stores.ErrWorkspaceNotFound } return nil, tx.Error } @@ -47,8 +48,8 @@ func (w *WorkspaceStore) Find(idOrName string) (*models.Workspace, error) { return workspace, nil } -func (w *WorkspaceStore) Save(workspace *models.Workspace) error { - tx := w.db.Save(workspace) +func (s *WorkspaceStore) Save(workspace *models.Workspace) error { + tx := s.db.Save(workspace) if tx.Error != nil { return tx.Error } @@ -56,14 +57,18 @@ func (w *WorkspaceStore) Save(workspace *models.Workspace) error { return nil } -func (w *WorkspaceStore) Delete(workspace *models.Workspace) error { - tx := w.db.Delete(workspace) +func (s *WorkspaceStore) Delete(workspace *models.Workspace) error { + tx := s.db.Delete(workspace) if tx.Error != nil { return tx.Error } if tx.RowsAffected == 0 { - return workspaces.ErrWorkspaceNotFound + return stores.ErrWorkspaceNotFound } return nil } + +func preloadWorkspaceEntities(tx *gorm.DB) *gorm.DB { + return tx.Preload(clause.Associations).Preload("LastJob", preloadLastJob) +} diff --git a/pkg/docker/client.go b/pkg/docker/client.go index e5a770155d..0578e4e8e1 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -68,18 +68,18 @@ type DockerClient struct { func (d *DockerClient) GetWorkspaceContainerName(workspace *models.Workspace) string { containers, err := d.apiClient.ContainerList(context.Background(), container.ListOptions{ - Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.target.id=%s", workspace.TargetId)), filters.Arg("label", fmt.Sprintf("daytona.workspace.name=%s", workspace.Name))), + Filters: filters.NewArgs(filters.Arg("label", fmt.Sprintf("daytona.target.id=%s", workspace.TargetId)), filters.Arg("label", fmt.Sprintf("daytona.workspace.id=%s", workspace.Id))), All: true, }) if err != nil || len(containers) == 0 { - return workspace.TargetId + "-" + workspace.Name + return workspace.TargetId + "-" + workspace.Id } return containers[0].ID } func (d *DockerClient) GetWorkspaceVolumeName(workspace *models.Workspace) string { - return workspace.TargetId + "-" + workspace.Name + return workspace.TargetId + "-" + workspace.Id } func (d *DockerClient) getComposeContainers(c types.ContainerJSON) (string, []types.Container, error) { diff --git a/pkg/docker/create.go b/pkg/docker/create.go index 26890d4e42..9c75cda246 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -212,8 +212,8 @@ func (d *DockerClient) toCreateDevcontainerOptions(opts *CreateWorkspaceOptions, BuilderContainerRegistry: opts.BuilderContainerRegistry, EnvVars: opts.Workspace.EnvVars, IdLabels: map[string]string{ - "daytona.target.id": opts.Workspace.TargetId, - "daytona.workspace.name": opts.Workspace.Name, + "daytona.target.id": opts.Workspace.TargetId, + "daytona.workspace.id": opts.Workspace.Id, }, Prebuild: prebuild, } diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index e437607fb6..ad6fff06c1 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -115,7 +115,7 @@ func GetContainerCreateConfig(workspace *models.Workspace, toolboxApiHostPort *u labels := map[string]string{ "daytona.target.id": workspace.TargetId, - "daytona.workspace.name": workspace.Name, + "daytona.workspace.id": workspace.Id, "daytona.workspace.repository.url": workspace.Repository.Url, } @@ -129,7 +129,7 @@ func GetContainerCreateConfig(workspace *models.Workspace, toolboxApiHostPort *u } return &container.Config{ - Hostname: workspace.Name, + Hostname: workspace.Id, Image: workspace.Image, Labels: labels, User: workspace.User, diff --git a/pkg/docker/start_devcontainer.go b/pkg/docker/start_devcontainer.go index 0d00a83d4f..3e598d6399 100644 --- a/pkg/docker/start_devcontainer.go +++ b/pkg/docker/start_devcontainer.go @@ -40,7 +40,7 @@ func (d *DockerClient) runDevcontainerUserCommands(opts *CreateWorkspaceOptions) "--config=" + paths.TargetConfigFilePath, "--override-config=" + path.Join(paths.OverridesTarget, "devcontainer.json"), "--id-label=daytona.target.id=" + opts.Workspace.TargetId, - "--id-label=daytona.workspace.name=" + opts.Workspace.Name, + "--id-label=daytona.workspace.id=" + opts.Workspace.Id, } cmd := strings.Join(devcontainerCmd, " ") diff --git a/pkg/jobs/jobs.go b/pkg/jobs/jobs.go new file mode 100644 index 0000000000..9501a84b48 --- /dev/null +++ b/pkg/jobs/jobs.go @@ -0,0 +1,12 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package jobs + +import ( + "context" +) + +type IJob interface { + Execute(ctx context.Context) error +} diff --git a/pkg/jobs/target/create.go b/pkg/jobs/target/create.go new file mode 100644 index 0000000000..9265ae27fe --- /dev/null +++ b/pkg/jobs/target/create.go @@ -0,0 +1,38 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/views" +) + +func (tj *TargetJob) create(ctx context.Context, j *models.Job) error { + tg, err := tj.findTarget(ctx, j.ResourceId) + if err != nil { + return err + } + + targetLogger := tj.loggerFactory.CreateTargetLogger(tg.Id, tg.Name, logs.LogSourceServer) + defer targetLogger.Close() + + targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", tg.Name, tg.Id))) + + err = tj.provisioner.CreateTarget(tg) + if err != nil { + return err + } + + err = tj.handleSuccessfulCreation(ctx, tg.Id) + if err != nil { + return err + } + + targetLogger.Write([]byte(views.GetPrettyLogLine("Target creation complete"))) + return tj.start(ctx, j) +} diff --git a/pkg/jobs/target/delete.go b/pkg/jobs/target/delete.go new file mode 100644 index 0000000000..ad5c05494b --- /dev/null +++ b/pkg/jobs/target/delete.go @@ -0,0 +1,42 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + log "github.com/sirupsen/logrus" +) + +func (tj *TargetJob) delete(ctx context.Context, j *models.Job, force bool) error { + t, err := tj.findTarget(ctx, j.ResourceId) + if err != nil { + return err + } + + targetLogger := tj.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) + + targetLogger.Write([]byte(fmt.Sprintf("Destroying target %s", t.Name))) + + err = tj.provisioner.DestroyTarget(t) + if err != nil { + if !force { + return err + } + log.Error(err) + } + + targetLogger.Write([]byte(fmt.Sprintf("Target %s destroyed", t.Name))) + + err = targetLogger.Cleanup() + if err != nil { + // Should not fail the whole operation if the target logger cannot be cleaned up + log.Error(err) + } + + return nil +} diff --git a/pkg/jobs/target/factory.go b/pkg/jobs/target/factory.go new file mode 100644 index 0000000000..912e288537 --- /dev/null +++ b/pkg/jobs/target/factory.go @@ -0,0 +1,50 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type ITargetJobFactory interface { + Create(job models.Job) jobs.IJob +} + +type TargetJobFactory struct { + config TargetJobFactoryConfig +} + +type TargetJobFactoryConfig struct { + FindTarget func(ctx context.Context, targetId string) (*models.Target, error) + HandleSuccessfulCreation func(ctx context.Context, targetId string) error + + TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + + LoggerFactory logs.LoggerFactory + Provisioner provisioner.IProvisioner +} + +func NewTargetJobFactory(config TargetJobFactoryConfig) ITargetJobFactory { + return &TargetJobFactory{ + config: config, + } +} + +func (f *TargetJobFactory) Create(job models.Job) jobs.IJob { + return &TargetJob{ + Job: job, + + findTarget: f.config.FindTarget, + handleSuccessfulCreation: f.config.HandleSuccessfulCreation, + trackTelemetryEvent: f.config.TrackTelemetryEvent, + loggerFactory: f.config.LoggerFactory, + provisioner: f.config.Provisioner, + } +} diff --git a/pkg/jobs/target/restart.go b/pkg/jobs/target/restart.go new file mode 100644 index 0000000000..c112d592fa --- /dev/null +++ b/pkg/jobs/target/restart.go @@ -0,0 +1,19 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" +) + +func (tj *TargetJob) restart(ctx context.Context, j *models.Job) error { + err := tj.stop(ctx, j) + if err != nil { + return err + } + + return tj.start(ctx, j) +} diff --git a/pkg/jobs/target/start.go b/pkg/jobs/target/start.go new file mode 100644 index 0000000000..096cbab22d --- /dev/null +++ b/pkg/jobs/target/start.go @@ -0,0 +1,33 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/views" +) + +func (tj *TargetJob) start(ctx context.Context, j *models.Job) error { + tg, err := tj.findTarget(ctx, j.ResourceId) + if err != nil { + return err + } + + targetLogger := tj.loggerFactory.CreateTargetLogger(tg.Id, tg.Name, logs.LogSourceServer) + defer targetLogger.Close() + + targetLogger.Write([]byte("Starting target\n")) + + err = tj.provisioner.StartTarget(tg) + if err != nil { + return err + } + + targetLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Target %s started", tg.Name)))) + return nil +} diff --git a/pkg/jobs/target/stop.go b/pkg/jobs/target/stop.go new file mode 100644 index 0000000000..4f2e3df56a --- /dev/null +++ b/pkg/jobs/target/stop.go @@ -0,0 +1,35 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/views" +) + +func (tj *TargetJob) stop(ctx context.Context, j *models.Job) error { + t, err := tj.findTarget(ctx, j.ResourceId) + if err != nil { + return err + } + + targetLogger := tj.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) + defer targetLogger.Close() + + targetLogger.Write([]byte(fmt.Sprintf("Stopping target %s\n", t.Name))) + + // todo: go routines + err = tj.provisioner.StopTarget(t) + if err != nil { + return err + } + + targetLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Target %s stopped", t.Name)))) + + return nil +} diff --git a/pkg/jobs/target/target.go b/pkg/jobs/target/target.go new file mode 100644 index 0000000000..b7461a0ce5 --- /dev/null +++ b/pkg/jobs/target/target.go @@ -0,0 +1,44 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type TargetJob struct { + models.Job + + findTarget func(ctx context.Context, targetId string) (*models.Target, error) + handleSuccessfulCreation func(ctx context.Context, targetId string) error + + trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + + loggerFactory logs.LoggerFactory + provisioner provisioner.IProvisioner +} + +func (tj *TargetJob) Execute(ctx context.Context) error { + switch tj.Action { + case models.JobActionCreate: + return tj.create(ctx, &tj.Job) + case models.JobActionStart: + return tj.start(ctx, &tj.Job) + case models.JobActionStop: + return tj.stop(ctx, &tj.Job) + case models.JobActionRestart: + return tj.restart(ctx, &tj.Job) + case models.JobActionDelete: + return tj.delete(ctx, &tj.Job, false) + case models.JobActionForceDelete: + return tj.delete(ctx, &tj.Job, true) + } + return errors.New("invalid job action") +} diff --git a/pkg/jobs/workspace/create.go b/pkg/jobs/workspace/create.go new file mode 100644 index 0000000000..be76ba3f7f --- /dev/null +++ b/pkg/jobs/workspace/create.go @@ -0,0 +1,60 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/views" +) + +func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { + w, err := wj.findWorkspace(ctx, j.ResourceId) + if err != nil { + return err + } + + workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + defer workspaceLogger.Close() + + workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) + + cr, err := wj.findContainerRegistry(ctx, w.Image) + if err != nil && !stores.IsContainerRegistryNotFound(err) { + return err + } + + builderCr, err := wj.findContainerRegistry(ctx, wj.builderImage) + if err != nil && !stores.IsContainerRegistryNotFound(err) { + return err + } + + var gc *models.GitProviderConfig + + if w.GitProviderConfigId != nil { + gc, err = wj.findGitProviderConfig(ctx, *w.GitProviderConfigId) + if err != nil && !stores.IsGitProviderNotFound(err) { + return err + } + } + + err = wj.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ + Workspace: w, + ContainerRegistry: cr, + GitProviderConfig: gc, + BuilderImage: wj.builderImage, + BuilderImageContainerRegistry: builderCr, + }) + if err != nil { + return err + } + + workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s created", w.Name)))) + return wj.start(ctx, j) +} diff --git a/pkg/jobs/workspace/delete.go b/pkg/jobs/workspace/delete.go new file mode 100644 index 0000000000..2f9ac4b8ff --- /dev/null +++ b/pkg/jobs/workspace/delete.go @@ -0,0 +1,42 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + log "github.com/sirupsen/logrus" +) + +func (wj *WorkspaceJob) delete(ctx context.Context, j *models.Job, force bool) error { + w, err := wj.findWorkspace(ctx, j.ResourceId) + if err != nil { + return err + } + + workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + + workspaceLogger.Write([]byte(fmt.Sprintf("Destroying workspace %s", w.Name))) + + err = wj.provisioner.DestroyWorkspace(w) + if err != nil { + if !force { + return err + } + log.Error(err) + } + + workspaceLogger.Write([]byte(fmt.Sprintf("Workspace %s destroyed", w.Name))) + + err = workspaceLogger.Cleanup() + if err != nil { + // Should not fail the whole operation if the workspace logger cannot be cleaned up + log.Error(err) + } + + return nil +} diff --git a/pkg/jobs/workspace/factory.go b/pkg/jobs/workspace/factory.go new file mode 100644 index 0000000000..1453d10f87 --- /dev/null +++ b/pkg/jobs/workspace/factory.go @@ -0,0 +1,55 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type IWorkspaceJobFactory interface { + Create(job models.Job) jobs.IJob +} + +type WorkspaceJobFactory struct { + config WorkspaceJobFactoryConfig +} + +type WorkspaceJobFactoryConfig struct { + FindWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) + FindTarget func(ctx context.Context, targetId string) (*models.Target, error) + FindContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) + FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + + LoggerFactory logs.LoggerFactory + Provisioner provisioner.IProvisioner + BuilderImage string +} + +func NewWorkspaceJobFactory(config WorkspaceJobFactoryConfig) IWorkspaceJobFactory { + return &WorkspaceJobFactory{ + config: config, + } +} + +func (f *WorkspaceJobFactory) Create(job models.Job) jobs.IJob { + return &WorkspaceJob{ + Job: job, + + findWorkspace: f.config.FindWorkspace, + findTarget: f.config.FindTarget, + findContainerRegistry: f.config.FindContainerRegistry, + findGitProviderConfig: f.config.FindGitProviderConfig, + trackTelemetryEvent: f.config.TrackTelemetryEvent, + loggerFactory: f.config.LoggerFactory, + provisioner: f.config.Provisioner, + builderImage: f.config.BuilderImage, + } +} diff --git a/pkg/jobs/workspace/restart.go b/pkg/jobs/workspace/restart.go new file mode 100644 index 0000000000..d2b5b884c7 --- /dev/null +++ b/pkg/jobs/workspace/restart.go @@ -0,0 +1,19 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" +) + +func (wj *WorkspaceJob) Restart(ctx context.Context, j *models.Job) error { + err := wj.stop(ctx, j) + if err != nil { + return err + } + + return wj.start(ctx, j) +} diff --git a/pkg/jobs/workspace/start.go b/pkg/jobs/workspace/start.go new file mode 100644 index 0000000000..90040c1730 --- /dev/null +++ b/pkg/jobs/workspace/start.go @@ -0,0 +1,60 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/views" +) + +func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { + w, err := wj.findWorkspace(ctx, j.ResourceId) + if err != nil { + return err + } + + workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + defer workspaceLogger.Close() + + workspaceLogger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) + + cr, err := wj.findContainerRegistry(ctx, w.Image) + if err != nil && !stores.IsContainerRegistryNotFound(err) { + return err + } + + builderCr, err := wj.findContainerRegistry(ctx, wj.builderImage) + if err != nil && !stores.IsContainerRegistryNotFound(err) { + return err + } + + var gc *models.GitProviderConfig + + if w.GitProviderConfigId != nil { + gc, err = wj.findGitProviderConfig(ctx, *w.GitProviderConfigId) + if err != nil && !stores.IsGitProviderNotFound(err) { + return err + } + } + + err = wj.provisioner.StartWorkspace(provisioner.WorkspaceParams{ + Workspace: w, + ContainerRegistry: cr, + GitProviderConfig: gc, + BuilderImage: wj.builderImage, + BuilderImageContainerRegistry: builderCr, + }) + if err != nil { + return err + } + + workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s started", w.Name)))) + return nil +} diff --git a/pkg/jobs/workspace/stop.go b/pkg/jobs/workspace/stop.go new file mode 100644 index 0000000000..1de4f6d887 --- /dev/null +++ b/pkg/jobs/workspace/stop.go @@ -0,0 +1,35 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/views" +) + +func (wj *WorkspaceJob) stop(ctx context.Context, j *models.Job) error { + w, err := wj.findWorkspace(ctx, j.ResourceId) + if err != nil { + return err + } + + workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + defer workspaceLogger.Close() + + workspaceLogger.Write([]byte(fmt.Sprintf("Stopping workspace %s\n", w.Name))) + + // todo: go routines + err = wj.provisioner.StopWorkspace(w) + if err != nil { + return err + } + + workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s stopped", w.Name)))) + + return nil +} diff --git a/pkg/jobs/workspace/workspace.go b/pkg/jobs/workspace/workspace.go new file mode 100644 index 0000000000..126e746278 --- /dev/null +++ b/pkg/jobs/workspace/workspace.go @@ -0,0 +1,44 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type WorkspaceJob struct { + models.Job + + findWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) + findTarget func(ctx context.Context, targetId string) (*models.Target, error) + findContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) + findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + + loggerFactory logs.LoggerFactory + provisioner provisioner.IProvisioner + builderImage string +} + +func (wj *WorkspaceJob) Execute(ctx context.Context) error { + switch wj.Action { + case models.JobActionCreate: + return wj.create(ctx, &wj.Job) + case models.JobActionStart: + return wj.start(ctx, &wj.Job) + case models.JobActionStop: + return wj.stop(ctx, &wj.Job) + case models.JobActionDelete: + return wj.delete(ctx, &wj.Job, false) + case models.JobActionForceDelete: + return wj.delete(ctx, &wj.Job, true) + } + return errors.New("invalid job action") +} diff --git a/pkg/models/job.go b/pkg/models/job.go new file mode 100644 index 0000000000..b51c4a3a4b --- /dev/null +++ b/pkg/models/job.go @@ -0,0 +1,95 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +import ( + "time" +) + +type Job struct { + Id string `json:"id" validate:"required" gorm:"primaryKey"` + ResourceId string `json:"resourceId" validate:"required"` + ResourceType ResourceType `json:"resourceType" validate:"required"` + State JobState `json:"state" validate:"required"` + Action JobAction `json:"action" validate:"required"` + Error *string `json:"error" validate:"optional"` + CreatedAt time.Time `json:"createdAt" validate:"required"` + UpdatedAt time.Time `json:"updatedAt" validate:"required"` +} // @name Job + +type ResourceType string // @name ResourceType + +const ( + ResourceTypeWorkspace ResourceType = "workspace" + ResourceTypeTarget ResourceType = "target" +) + +type JobState string // @name JobState + +const ( + JobStatePending JobState = "pending" + JobStateRunning JobState = "running" + JobStateError JobState = "error" + JobStateSuccess JobState = "success" +) + +type JobAction string + +const ( + JobActionCreate JobAction = "create" + JobActionStart JobAction = "start" + JobActionStop JobAction = "stop" + JobActionRestart JobAction = "restart" + JobActionDelete JobAction = "delete" + JobActionForceDelete JobAction = "force-delete" +) + +func getResourceStateFromJob(job *Job) ResourceState { + state := ResourceState{ + Name: ResourceStateNameUnresponsive, + UpdatedAt: time.Now(), + } + + if job == nil { + return state + } + + if job.State == JobStateSuccess { + switch job.Action { + case JobActionCreate: + state.Name = ResourceStateNameStarted + case JobActionStart: + state.Name = ResourceStateNameStarted + case JobActionStop: + state.Name = ResourceStateNameStopped + case JobActionRestart: + state.Name = ResourceStateNameStarted + case JobActionDelete: + state.Name = ResourceStateNameDeleted + case JobActionForceDelete: + state.Name = ResourceStateNameDeleted + } + } else if job.State == JobStateError { + state.Name = ResourceStateNameError + state.Error = job.Error + } else if job.State == JobStateRunning { + switch job.Action { + case JobActionCreate: + state.Name = ResourceStateNameCreating + case JobActionStart: + state.Name = ResourceStateNameStarting + case JobActionStop: + state.Name = ResourceStateNameStopping + case JobActionRestart: + state.Name = ResourceStateNameStarting + case JobActionDelete: + state.Name = ResourceStateNameDeleting + case JobActionForceDelete: + state.Name = ResourceStateNameDeleting + } + } + + state.UpdatedAt = job.UpdatedAt + return state +} diff --git a/pkg/models/target.go b/pkg/models/target.go index e6dedebe68..cebe16a219 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -3,18 +3,60 @@ package models +import ( + "slices" + "time" + + "github.com/daytonaio/daytona/internal/util" +) + +const AGENT_UNRESPONSIVE_THRESHOLD = 30 * time.Second + +var providersWithoutTargetMode = []string{"docker-provider"} + type Target struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - Name string `json:"name" validate:"required" gorm:"unique"` + Name string `json:"name" validate:"required"` ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json"` // JSON encoded map of options Options string `json:"options" validate:"required"` ApiKey string `json:"-"` - EnvVars map[string]string `json:"-" gorm:"serializer:json"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` IsDefault bool `json:"default" validate:"required"` Workspaces []Workspace `gorm:"foreignKey:TargetId;references:Id"` + Metadata *TargetMetadata `gorm:"foreignKey:TargetId;references:Id" validate:"optional"` + LastJob *Job `gorm:"foreignKey:ResourceId;references:Id" validate:"optional"` } // @name Target +type TargetMetadata struct { + TargetId string `json:"targetId" validate:"required" gorm:"primaryKey;foreignKey:TargetId;references:Id"` + UpdatedAt time.Time `json:"updatedAt" validate:"required"` + Uptime uint64 `json:"uptime" validate:"required"` +} // @name TargetMetadata + +func (t *Target) GetState() ResourceState { + state := getResourceStateFromJob(t.LastJob) + + // Some providers do not utilize agents in target mode + if state.Name != ResourceStateNameDeleted && slices.Contains(providersWithoutTargetMode, t.ProviderInfo.Name) { + return ResourceState{ + Name: ResourceStateNameUndefined, + UpdatedAt: time.Now(), + } + } + + // If the target should be running, check if it is unresponsive + if state.Name == ResourceStateNameStarted { + if t.Metadata != nil && time.Since(t.Metadata.UpdatedAt) > AGENT_UNRESPONSIVE_THRESHOLD { + state.Name = ResourceStateNameUnresponsive + state.Error = util.Pointer("Target is unresponsive") + state.UpdatedAt = t.Metadata.UpdatedAt + } + } + + return state +} + type TargetInfo struct { Name string `json:"name" validate:"required"` ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index 149afa52fb..912034e353 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -4,6 +4,9 @@ package models import ( + "time" + + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" ) @@ -18,10 +21,45 @@ type Workspace struct { TargetId string `json:"targetId" validate:"required" gorm:"foreignKey:TargetId;references:Id"` Target Target `json:"target" validate:"required" gorm:"foreignKey:TargetId"` ApiKey string `json:"-"` - State *WorkspaceState `json:"state,omitempty" validate:"optional" gorm:"serializer:json"` + Metadata *WorkspaceMetadata `gorm:"foreignKey:WorkspaceId;references:Id" validate:"optional"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` + LastJob *Job `gorm:"foreignKey:ResourceId;references:Id"` } // @name Workspace +type WorkspaceMetadata struct { + WorkspaceId string `json:"workspaceId" validate:"required" gorm:"primaryKey;foreignKey:WorkspaceId;references:Id"` + UpdatedAt time.Time `json:"updatedAt" validate:"required"` + Uptime uint64 `json:"uptime" validate:"required"` + GitStatus *GitStatus `json:"gitStatus" validate:"optional" gorm:"serializer:json"` +} // @name WorkspaceMetadata + +type ResourceState struct { + Name ResourceStateName `json:"name" validate:"required"` + Error *string `json:"error" validate:"optional"` + UpdatedAt time.Time `json:"updatedAt" validate:"required"` +} // @name ResourceState + +type ResourceStateName string + +const ( + ResourceStateNameUndefined ResourceStateName = "undefined" + ResourceStateNamePendingCreate ResourceStateName = "pending-create" + ResourceStateNameCreating ResourceStateName = "creating" + ResourceStateNamePendingStart ResourceStateName = "pending-start" + ResourceStateNameStarting ResourceStateName = "starting" + ResourceStateNameStarted ResourceStateName = "started" + ResourceStateNamePendingStop ResourceStateName = "pending-stop" + ResourceStateNameStopping ResourceStateName = "stopping" + ResourceStateNameStopped ResourceStateName = "stopped" + ResourceStateNamePendingRestart ResourceStateName = "pending-restart" + ResourceStateNameError ResourceStateName = "error" + ResourceStateNameUnresponsive ResourceStateName = "unresponsive" + ResourceStateNamePendingDelete ResourceStateName = "pending-delete" + ResourceStateNamePendingForcedDelete ResourceStateName = "pending-forced-delete" + ResourceStateNameDeleting ResourceStateName = "deleting" + ResourceStateNameDeleted ResourceStateName = "deleted" +) + func (w *Workspace) WorkspaceFolderName() string { if w.Repository != nil { return w.Repository.Name @@ -29,6 +67,21 @@ func (w *Workspace) WorkspaceFolderName() string { return w.Name } +func (w *Workspace) GetState() ResourceState { + state := getResourceStateFromJob(w.LastJob) + + // If the workspace should be running, check if it is unresponsive + if state.Name == ResourceStateNameStarted { + if w.Metadata != nil && time.Since(w.Metadata.UpdatedAt) > AGENT_UNRESPONSIVE_THRESHOLD { + state.Name = ResourceStateNameUnresponsive + state.Error = util.Pointer("Workspace is unresponsive") + state.UpdatedAt = w.Metadata.UpdatedAt + } + } + + return state +} + type BuildConfig struct { Devcontainer *DevcontainerConfig `json:"devcontainer,omitempty" validate:"optional"` CachedBuild *CachedBuild `json:"cachedBuild,omitempty" validate:"optional"` @@ -51,12 +104,6 @@ type WorkspaceInfo struct { TargetId string `json:"targetId" validate:"required"` } // @name WorkspaceInfo -type WorkspaceState struct { - UpdatedAt string `json:"updatedAt" validate:"required"` - Uptime uint64 `json:"uptime" validate:"required"` - GitStatus *GitStatus `json:"gitStatus" validate:"optional"` -} // @name WorkspaceState - type GitStatus struct { CurrentBranch string `json:"currentBranch" validate:"required"` Files []*FileStatus `json:"fileStatus" validate:"required"` diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index 8ed8d9f651..1c9d925da9 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -63,22 +63,36 @@ type ProviderManagerConfig struct { ApiPort uint32 } -func NewProviderManager(config ProviderManagerConfig) *ProviderManager { - return &ProviderManager{ - pluginRefs: make(map[string]*pluginRef), - daytonaDownloadUrl: config.DaytonaDownloadUrl, - serverUrl: config.ServerUrl, - serverVersion: config.ServerVersion, - apiUrl: config.ApiUrl, - logsDir: config.LogsDir, - getTargetConfigMap: config.GetTargetConfigMap, - createTargetConfig: config.CreateTargetConfig, - registryUrl: config.RegistryUrl, - baseDir: config.BaseDir, - createProviderNetworkKey: config.CreateProviderNetworkKey, - serverPort: config.ServerPort, - apiPort: config.ApiPort, +var providerManager *ProviderManager + +func GetProviderManager(config *ProviderManagerConfig) *ProviderManager { + if config != nil && providerManager != nil { + log.Fatal("Provider manager already initialized") } + + if providerManager == nil { + if config == nil { + log.Fatal("Provider manager not initialized") + } + + providerManager = &ProviderManager{ + pluginRefs: make(map[string]*pluginRef), + daytonaDownloadUrl: config.DaytonaDownloadUrl, + serverUrl: config.ServerUrl, + serverVersion: config.ServerVersion, + apiUrl: config.ApiUrl, + logsDir: config.LogsDir, + getTargetConfigMap: config.GetTargetConfigMap, + createTargetConfig: config.CreateTargetConfig, + registryUrl: config.RegistryUrl, + baseDir: config.BaseDir, + createProviderNetworkKey: config.CreateProviderNetworkKey, + serverPort: config.ServerPort, + apiPort: config.ApiPort, + } + } + + return providerManager } type ProviderManager struct { diff --git a/pkg/runners/runner.go b/pkg/runners/runner.go new file mode 100644 index 0000000000..bccfb75577 --- /dev/null +++ b/pkg/runners/runner.go @@ -0,0 +1,17 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runners + +import ( + "context" +) + +// TODO: add lock when running interval func +// 1 second interval +const DEFAULT_JOB_POLL_INTERVAL = "*/1 * * * * *" + +type IJobRunner interface { + StartRunner(ctx context.Context) error + CheckAndRunJobs(ctx context.Context) error +} diff --git a/pkg/runners/runner/runner.go b/pkg/runners/runner/runner.go new file mode 100644 index 0000000000..fbac634b6c --- /dev/null +++ b/pkg/runners/runner/runner.go @@ -0,0 +1,110 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "time" + + "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/jobs/target" + "github.com/daytonaio/daytona/pkg/jobs/workspace" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runners" + "github.com/daytonaio/daytona/pkg/scheduler" + log "github.com/sirupsen/logrus" +) + +type JobRunnerConfig struct { + ListPendingJobs func(ctx context.Context) ([]*models.Job, error) + UpdateJobState func(ctx context.Context, job *models.Job, state models.JobState, err *error) error + + WorkspaceJobFactory workspace.IWorkspaceJobFactory + TargetJobFactory target.ITargetJobFactory +} + +func NewJobRunner(config JobRunnerConfig) runners.IJobRunner { + return &JobRunner{ + listPendingJobs: config.ListPendingJobs, + updateJobState: config.UpdateJobState, + + workspaceJobFactory: config.WorkspaceJobFactory, + targetJobFactory: config.TargetJobFactory, + } +} + +type JobRunner struct { + listPendingJobs func(ctx context.Context) ([]*models.Job, error) + updateJobState func(ctx context.Context, job *models.Job, state models.JobState, err *error) error + + workspaceJobFactory workspace.IWorkspaceJobFactory + targetJobFactory target.ITargetJobFactory +} + +func (s *JobRunner) StartRunner(ctx context.Context) error { + scheduler := scheduler.NewCronScheduler() + + // Make sure the API is up + for { + _, err := apiclient.GetApiClient(nil) + if err != nil { + break + } + time.Sleep(500 * time.Millisecond) + } + + err := scheduler.AddFunc(runners.DEFAULT_JOB_POLL_INTERVAL, func() { + err := s.CheckAndRunJobs(ctx) + if err != nil { + log.Error(err) + } + }) + if err != nil { + return err + } + + scheduler.Start() + return nil +} + +func (s *JobRunner) CheckAndRunJobs(ctx context.Context) error { + jobs, err := s.listPendingJobs(ctx) + if err != nil { + return err + } + + // goroutines, sync group + for _, job := range jobs { + err = s.runJob(ctx, job) + if err != nil { + return err + } + } + + return nil +} + +func (s *JobRunner) runJob(ctx context.Context, j *models.Job) error { + var job jobs.IJob + + err := s.updateJobState(ctx, j, models.JobStateRunning, nil) + if err != nil { + return err + } + + switch j.ResourceType { + case models.ResourceTypeWorkspace: + job = s.workspaceJobFactory.Create(*j) + case models.ResourceTypeTarget: + job = s.targetJobFactory.Create(*j) + } + + err = job.Execute(ctx) + if err != nil { + return s.updateJobState(ctx, j, models.JobStateError, &err) + } + + return s.updateJobState(ctx, j, models.JobStateSuccess, nil) +} diff --git a/pkg/build/scheduler.go b/pkg/scheduler/cron.go similarity index 97% rename from pkg/build/scheduler.go rename to pkg/scheduler/cron.go index 6c17be9323..6c81156c04 100644 --- a/pkg/build/scheduler.go +++ b/pkg/scheduler/cron.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package build +package scheduler import ( "github.com/robfig/cron/v3" diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go new file mode 100644 index 0000000000..3ea88a2d52 --- /dev/null +++ b/pkg/server/jobs/service.go @@ -0,0 +1,46 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package jobs + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/docker/docker/pkg/stringid" +) + +type JobServiceConfig struct { + JobStore stores.JobStore +} + +type JobService struct { + jobStore stores.JobStore +} + +func NewJobService(config JobServiceConfig) services.IJobService { + return &JobService{ + jobStore: config.JobStore, + } +} + +func (s *JobService) List(filter *stores.JobFilter) ([]*models.Job, error) { + return s.jobStore.List(filter) +} + +func (s *JobService) Find(filter *stores.JobFilter) (*models.Job, error) { + return s.jobStore.Find(filter) +} + +func (s *JobService) Save(j *models.Job) error { + if j.Id == "" { + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + j.Id = id + } + return s.jobStore.Save(j) +} + +func (s *JobService) Delete(j *models.Job) error { + return s.jobStore.Delete(j) +} diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go new file mode 100644 index 0000000000..20f13f595f --- /dev/null +++ b/pkg/server/jobs/service_test.go @@ -0,0 +1,137 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package jobs_test + +import ( + "testing" + + job_internal "github.com/daytonaio/daytona/internal/testing/job" + "github.com/daytonaio/daytona/pkg/models" + jobs "github.com/daytonaio/daytona/pkg/server/jobs" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/stretchr/testify/suite" +) + +var expectedJobs []*models.Job +var expectedFilteredJobs []*models.Job + +var expectedJobsMap map[string]*models.Job +var expectedFilteredJobsMap map[string]*models.Job + +var job1 = &models.Job{ + Id: "1", + ResourceId: "1", + Action: models.JobActionStart, + State: models.JobStatePending, +} + +var job2 = &models.Job{ + Id: "2", + ResourceId: "2", + Action: models.JobActionStart, + State: models.JobStatePending, +} + +var job3 = &models.Job{ + Id: "3", + ResourceId: "3", + Action: models.JobActionStart, + State: models.JobStatePending, +} + +var job4 = &models.Job{ + Id: "4", + ResourceId: "4", + Action: models.JobActionStart, + State: models.JobStatePending, +} + +type JobServiceTestSuite struct { + suite.Suite + jobService services.IJobService + jobStore stores.JobStore +} + +func NewJobServiceTestSuite() *JobServiceTestSuite { + return &JobServiceTestSuite{} +} + +func (s *JobServiceTestSuite) SetupTest() { + expectedJobs = []*models.Job{ + job1, job2, job3, + } + + expectedJobsMap = map[string]*models.Job{ + job1.Id: job1, + job2.Id: job2, + job3.Id: job3, + } + + expectedFilteredJobs = []*models.Job{ + job1, job2, + } + + expectedFilteredJobsMap = map[string]*models.Job{ + job1.Id: job1, + job2.Id: job2, + } + + s.jobStore = job_internal.NewInMemoryJobStore() + s.jobService = jobs.NewJobService(jobs.JobServiceConfig{ + JobStore: s.jobStore, + }) + + for _, j := range expectedJobs { + _ = s.jobStore.Save(j) + } +} + +func TestJobService(t *testing.T) { + suite.Run(t, NewJobServiceTestSuite()) +} + +func (s *JobServiceTestSuite) TestList() { + require := s.Require() + + jobs, err := s.jobService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedJobs, jobs) +} + +func (s *JobServiceTestSuite) TestFind() { + require := s.Require() + + job, err := s.jobService.Find(&stores.JobFilter{ + Id: &job1.Id, + }) + require.Nil(err) + require.Equal(job1, job) +} + +func (s *JobServiceTestSuite) TestSave() { + expectedJobs = append(expectedJobs, job4) + + require := s.Require() + + err := s.jobService.Save(job4) + require.Nil(err) + + jobs, err := s.jobService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedJobs, jobs) +} + +func (s *JobServiceTestSuite) TestDelete() { + expectedJobs = expectedJobs[:2] + + require := s.Require() + + err := s.jobService.Delete(job3) + require.Nil(err) + + jobs, err := s.jobService.List(nil) + require.Nil(err) + require.ElementsMatch(expectedJobs, jobs) +} diff --git a/pkg/server/purge.go b/pkg/server/purge.go index 65306cb068..556663fc62 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -8,6 +8,7 @@ import ( "fmt" "time" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) @@ -36,7 +37,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { return []error{err} } - targets, err := s.TargetService.ListTargets(ctx, nil, false) + targets, err := s.TargetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) if err != nil { s.trackPurgeError(ctx, force, err) if !force { diff --git a/pkg/server/server.go b/pkg/server/server.go index 9f50f858b1..947f739819 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -30,6 +30,7 @@ type ServerInstanceConfig struct { GitProviderService services.IGitProviderService ProviderManager manager.IProviderManager ProfileDataService services.IProfileDataService + JobService services.IJobService TelemetryService telemetry.TelemetryService } @@ -60,6 +61,7 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { GitProviderService: serverConfig.GitProviderService, ProviderManager: serverConfig.ProviderManager, ProfileDataService: serverConfig.ProfileDataService, + JobService: serverConfig.JobService, TelemetryService: serverConfig.TelemetryService, } } @@ -83,6 +85,7 @@ type Server struct { GitProviderService services.IGitProviderService ProviderManager manager.IProviderManager ProfileDataService services.IProfileDataService + JobService services.IJobService TelemetryService telemetry.TelemetryService } diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index cde279459d..5c93973d9b 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -5,40 +5,21 @@ package targets import ( "context" - "fmt" "regexp" - "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" ) -func isValidTargetName(name string) bool { - // The repository name can only contain ASCII letters, digits, and the characters ., -, and _. - var validName = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) - - // Check if the name matches the basic regex - if !validName.MatchString(name) { - return false - } - - // Names starting with a period must have atleast one char appended to it. - if name == "." || name == "" { - return false - } - - return true -} - func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) { _, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &req.Id}) if err == nil { - return nil, ErrTargetAlreadyExists + return nil, services.ErrTargetAlreadyExists } tc, err := s.findTargetConfig(ctx, req.TargetConfigName) @@ -48,7 +29,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT // Repo name is taken as the name for target by default if !isValidTargetName(req.Name) { - return nil, ErrInvalidTargetName + return s.handleCreateError(ctx, nil, services.ErrInvalidTargetName) } tg := &models.Target{ @@ -64,50 +45,35 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT } tg.ApiKey = apiKey - err = s.targetStore.Save(tg) - if err != nil { - return s.handleCreateError(ctx, nil, err) - } - - targetLogger := s.loggerFactory.CreateTargetLogger(tg.Id, tg.Name, logs.LogSourceServer) - defer targetLogger.Close() - - targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", tg.Name, tg.Id))) - tg.EnvVars = GetTargetEnvVars(tg, TargetEnvVarParams{ - ApiUrl: s.serverApiUrl, - ServerUrl: s.serverUrl, - ServerVersion: s.serverVersion, - ClientId: telemetry.ClientId(ctx), - }, telemetry.TelemetryEnabled(ctx)) + ApiUrl: s.serverApiUrl, + ServerUrl: s.serverUrl, + ServerVersion: s.serverVersion, + ClientId: telemetry.ClientId(ctx), + TelemetryEnabled: telemetry.TelemetryEnabled(ctx), + }) - err = s.provisioner.CreateTarget(tg) + err = s.targetStore.Save(tg) if err != nil { - return s.handleCreateError(ctx, tg, err) + return s.handleCreateError(ctx, nil, err) } - targetLogger.Write([]byte(views.GetPrettyLogLine("Target creation complete"))) - - err = s.startTarget(tg, targetLogger) + err = s.targetMetadataStore.Save(&models.TargetMetadata{ + TargetId: tg.Id, + Uptime: 0, + }) if err != nil { return s.handleCreateError(ctx, tg, err) } - tg, err = s.handleCreateError(ctx, tg, err) - if err != nil { - return nil, err - } - - err = s.SetDefault(ctx, tg.Id) - if err != nil { - return nil, err - } - - tg.IsDefault = true - + err = s.createJob(ctx, tg.Id, models.JobActionCreate) return s.handleCreateError(ctx, tg, err) } +func (s *TargetService) HandleSuccessfulCreation(ctx context.Context, targetId string) error { + return s.SetDefault(ctx, targetId) +} + func (s *TargetService) handleCreateError(ctx context.Context, target *models.Target, err error) (*models.Target, error) { if !telemetry.TelemetryEnabled(ctx) { return target, err @@ -128,3 +94,20 @@ func (s *TargetService) handleCreateError(ctx context.Context, target *models.Ta return target, err } + +func isValidTargetName(name string) bool { + // The repository name can only contain ASCII letters, digits, and the characters ., -, and _. + var validName = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) + + // Check if the name matches the basic regex + if !validName.MatchString(name) { + return false + } + + // Names starting with a period must have atleast one char appended to it. + if name == "." || name == "" { + return false + } + + return true +} diff --git a/pkg/server/targets/dto/target.go b/pkg/server/targets/dto/target.go index f57c93d22b..135201e2f8 100644 --- a/pkg/server/targets/dto/target.go +++ b/pkg/server/targets/dto/target.go @@ -9,7 +9,8 @@ import ( type TargetDTO struct { models.Target - Info *models.TargetInfo `json:"info" validate:"optional"` + State models.ResourceState `json:"state" validate:"required"` + Info *models.TargetInfo `json:"info" validate:"optional"` } // @name TargetDTO type CreateTargetDTO struct { diff --git a/pkg/server/targets/env_vars.go b/pkg/server/targets/env_vars.go index 4464506f2f..3c868642f6 100644 --- a/pkg/server/targets/env_vars.go +++ b/pkg/server/targets/env_vars.go @@ -6,13 +6,14 @@ package targets import "github.com/daytonaio/daytona/pkg/models" type TargetEnvVarParams struct { - ApiUrl string - ServerUrl string - ServerVersion string - ClientId string + ApiUrl string + ServerUrl string + ServerVersion string + ClientId string + TelemetryEnabled bool } -func GetTargetEnvVars(target *models.Target, params TargetEnvVarParams, telemetryEnabled bool) map[string]string { +func GetTargetEnvVars(target *models.Target, params TargetEnvVarParams) map[string]string { envVars := map[string]string{ "DAYTONA_TARGET_ID": target.Id, "DAYTONA_SERVER_API_KEY": target.ApiKey, @@ -24,7 +25,7 @@ func GetTargetEnvVars(target *models.Target, params TargetEnvVarParams, telemetr "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", } - if telemetryEnabled { + if params.TelemetryEnabled { envVars["DAYTONA_TELEMETRY_ENABLED"] = "true" } diff --git a/pkg/server/targets/error.go b/pkg/server/targets/error.go deleted file mode 100644 index 19ecbabe30..0000000000 --- a/pkg/server/targets/error.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package targets - -import ( - "errors" -) - -var ( - ErrTargetAlreadyExists = errors.New("target already exists") - ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") - ErrTargetNotFound = errors.New("target not found") -) - -func IsTargetNotFound(err error) bool { - return err.Error() == ErrTargetNotFound.Error() -} diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 24f8814223..9f1420379c 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -9,23 +9,41 @@ import ( "fmt" "time" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, verbose bool) (*dto.TargetDTO, error) { +func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*dto.TargetDTO, error) { tg, err := s.targetStore.Find(filter) if err != nil { - return nil, ErrTargetNotFound + return nil, stores.ErrTargetNotFound } + state := tg.GetState() + + if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { + return nil, stores.ErrTargetNotFound + } + + var updatedWorkspaces []models.Workspace + for _, w := range tg.Workspaces { + wsState := w.GetState() + if wsState.Name != models.ResourceStateNameDeleted { + updatedWorkspaces = append(updatedWorkspaces, w) + } + } + tg.Workspaces = updatedWorkspaces + response := dto.TargetDTO{ Target: *tg, + State: state, } - if !verbose { + if !params.Verbose { return &response, nil } diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index b46796baab..d6967f734d 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -10,13 +10,15 @@ import ( "sync" "time" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, verbose bool) ([]dto.TargetDTO, error) { +func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]dto.TargetDTO, error) { targets, err := s.targetStore.List(filter) if err != nil { return nil, err @@ -26,8 +28,27 @@ func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFi response := []dto.TargetDTO{} for i, t := range targets { - response = append(response, dto.TargetDTO{Target: *t}) - if !verbose { + state := t.GetState() + + if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { + continue + } + + var updatedWorkspaces []models.Workspace + for _, w := range t.Workspaces { + wsState := w.GetState() + if wsState.Name != models.ResourceStateNameDeleted { + updatedWorkspaces = append(updatedWorkspaces, w) + } + } + t.Workspaces = updatedWorkspaces + + response = append(response, dto.TargetDTO{ + Target: *t, + State: state, + }) + + if !params.Verbose { continue } diff --git a/pkg/server/targets/metadata.go b/pkg/server/targets/metadata.go new file mode 100644 index 0000000000..d418f97656 --- /dev/null +++ b/pkg/server/targets/metadata.go @@ -0,0 +1,22 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +func (s *TargetService) SetTargetMetadata(targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { + m, err := s.targetMetadataStore.Find(&stores.TargetMetadataFilter{ + TargetId: &targetId, + }) + if err != nil { + return nil, stores.ErrTargetMetadataNotFound + } + + m.Uptime = metadata.Uptime + m.UpdatedAt = metadata.UpdatedAt + return m, s.targetMetadataStore.Save(m) +} diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index cec25ea88f..c13a419439 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -6,7 +6,7 @@ package targets import ( "context" - "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" @@ -14,58 +14,64 @@ import ( ) func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleRemoveError(ctx, target, ErrTargetNotFound) + return s.handleRemoveError(ctx, t, stores.ErrTargetNotFound) } - log.Infof("Destroying target %s", target.Id) + t.Name = util.AddDeletedToName(t.Name) - err = s.provisioner.DestroyTarget(target) + err = s.targetStore.Save(t) if err != nil { - return s.handleRemoveError(ctx, target, err) + return s.handleRemoveError(ctx, t, err) } - // Should not fail the whole operation if the API key cannot be revoked - err = s.revokeApiKey(ctx, target.Id) + err = s.createJob(ctx, t.Id, models.JobActionDelete) + return s.handleRemoveError(ctx, t, err) +} + +// ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. +func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { + t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { - log.Error(err) + return s.handleRemoveError(ctx, nil, stores.ErrTargetNotFound) } - logger := s.loggerFactory.CreateTargetLogger(target.Id, target.Name, logs.LogSourceServer) - err = logger.Cleanup() + t.Name = util.AddDeletedToName(t.Name) + + err = s.targetStore.Save(t) if err != nil { - // Should not fail the whole operation if the target logger cannot be cleaned up - log.Error(err) + return s.handleRemoveError(ctx, t, err) } - err = s.targetStore.Delete(target) - - return s.handleRemoveError(ctx, target, err) + err = s.createJob(ctx, t.Id, models.JobActionForceDelete) + return s.handleRemoveError(ctx, t, err) } -// ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. -func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) +func (s *TargetService) HandleSuccessfulRemoval(ctx context.Context, targetId string) error { + err := s.revokeApiKey(ctx, targetId) if err != nil { - return s.handleRemoveError(ctx, nil, ErrTargetNotFound) + // Should not fail the whole operation if the API key cannot be revoked + log.Error(err) } - log.Infof("Destroying target %s", target.Id) - - err = s.provisioner.DestroyTarget(target) + t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { - log.Error(err) + return s.handleRemoveError(ctx, t, stores.ErrTargetNotFound) } - err = s.revokeApiKey(ctx, target.Id) + metadata, err := s.targetMetadataStore.Find(&stores.TargetMetadataFilter{TargetId: &targetId}) if err != nil { - log.Error(err) + return s.handleRemoveError(ctx, t, err) } - err = s.targetStore.Delete(target) + err = s.targetMetadataStore.Delete(metadata) + if err != nil { + return s.handleRemoveError(ctx, t, err) + } - return s.handleRemoveError(ctx, target, err) + err = s.targetStore.Delete(t) + return s.handleRemoveError(ctx, t, err) } func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Target, err error) error { diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 836bd0b234..fc707ae2e5 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -16,11 +16,13 @@ import ( ) type TargetServiceConfig struct { - TargetStore stores.TargetStore + TargetStore stores.TargetStore + TargetMetadataStore stores.TargetMetadataStore FindTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) GenerateApiKey func(ctx context.Context, name string) (string, error) RevokeApiKey func(ctx context.Context, name string) error + CreateJob func(ctx context.Context, targetId string, action models.JobAction) error ServerApiUrl string ServerUrl string @@ -32,10 +34,14 @@ type TargetServiceConfig struct { func NewTargetService(config TargetServiceConfig) services.ITargetService { return &TargetService{ - targetStore: config.TargetStore, + targetStore: config.TargetStore, + targetMetadataStore: config.TargetMetadataStore, + findTargetConfig: config.FindTargetConfig, generateApiKey: config.GenerateApiKey, revokeApiKey: config.RevokeApiKey, + createJob: config.CreateJob, + serverApiUrl: config.ServerApiUrl, serverUrl: config.ServerUrl, serverVersion: config.ServerVersion, @@ -46,10 +52,13 @@ func NewTargetService(config TargetServiceConfig) services.ITargetService { } type TargetService struct { - targetStore stores.TargetStore + targetStore stores.TargetStore + targetMetadataStore stores.TargetMetadataStore + findTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) generateApiKey func(ctx context.Context, name string) (string, error) revokeApiKey func(ctx context.Context, name string) error + createJob func(ctx context.Context, targetId string, action models.JobAction) error provisioner provisioner.IProvisioner serverApiUrl string diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index fe19aadac0..c4cbb7681d 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -15,6 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/mock" @@ -60,12 +61,13 @@ func TestTargetService(t *testing.T) { ApiUrl: serverApiUrl, ServerUrl: serverUrl, ClientId: "test-client-id", - }, false) + }) ctx := context.Background() ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") targetStore := t_targets.NewInMemoryTargetStore() + targetMetadataStore := t_targets.NewInMemoryTargetMetadataStore() targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() err := targetConfigStore.Save(&tc) @@ -78,7 +80,8 @@ func TestTargetService(t *testing.T) { buildLogsDir := t.TempDir() service := targets.NewTargetService(targets.TargetServiceConfig{ - TargetStore: targetStore, + TargetStore: targetStore, + TargetMetadataStore: targetMetadataStore, FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { return targetConfigStore.Find(&stores.TargetConfigFilter{Name: &name}) }, @@ -117,13 +120,13 @@ func TestTargetService(t *testing.T) { t.Run("CreateTarget fails when target already exists", func(t *testing.T) { _, err := service.CreateTarget(ctx, createTargetDTO) require.NotNil(t, err) - require.Equal(t, targets.ErrTargetAlreadyExists, err) + require.Equal(t, services.ErrTargetAlreadyExists, err) }) t.Run("GetTarget", func(t *testing.T) { mockProvisioner.On("GetTargetInfo", mock.Anything, tg).Return(&targetInfo, nil) - target, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, true) + target, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{Verbose: true}) require.Nil(t, err) require.NotNil(t, target) @@ -132,14 +135,14 @@ func TestTargetService(t *testing.T) { }) t.Run("GetTarget fails when target not found", func(t *testing.T) { - _, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, true) + _, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{Verbose: true}) require.NotNil(t, err) - require.Equal(t, targets.ErrTargetNotFound, err) + require.Equal(t, stores.ErrTargetNotFound, err) }) t.Run("ListTargets", func(t *testing.T) { verbose := false - targets, err := service.ListTargets(ctx, nil, verbose) + targets, err := service.ListTargets(ctx, nil, services.TargetRetrievalParams{Verbose: verbose}) require.Nil(t, err) require.Len(t, targets, 1) @@ -152,7 +155,7 @@ func TestTargetService(t *testing.T) { t.Run("ListTargets - verbose", func(t *testing.T) { verbose := true - targets, err := service.ListTargets(ctx, nil, verbose) + targets, err := service.ListTargets(ctx, nil, services.TargetRetrievalParams{Verbose: verbose}) require.Nil(t, err) require.Len(t, targets, 1) @@ -167,7 +170,7 @@ func TestTargetService(t *testing.T) { ApiUrl: serverApiUrl, ServerUrl: serverUrl, ClientId: "test-client-id", - }, false) + }) err := service.StartTarget(ctx, createTargetDTO.Id) @@ -192,8 +195,8 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, true) - require.Equal(t, targets.ErrTargetNotFound, err) + _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{Verbose: true}) + require.Equal(t, stores.ErrTargetNotFound, err) }) t.Run("ForceRemoveTarget", func(t *testing.T) { @@ -207,8 +210,8 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, true) - require.Equal(t, targets.ErrTargetNotFound, err) + _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{Verbose: true}) + require.Equal(t, stores.ErrTargetNotFound, err) }) t.Run("CreateTarget fails name validation", func(t *testing.T) { @@ -217,7 +220,17 @@ func TestTargetService(t *testing.T) { _, err := service.CreateTarget(ctx, invalidTargetRequest) require.NotNil(t, err) - require.Equal(t, targets.ErrInvalidTargetName, err) + require.Equal(t, services.ErrInvalidTargetName, err) + }) + + t.Run("SetTargetMetadata", func(t *testing.T) { + err := targetStore.Save(tg) + require.Nil(t, err) + + _, err = service.SetTargetMetadata(tg.Id, &models.TargetMetadata{ + Uptime: 10, + }) + require.Nil(t, err) }) t.Cleanup(func() { diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index 9aebf60f34..90af77c01e 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -9,21 +9,22 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" ) func (s *TargetService) SetDefault(ctx context.Context, id string) error { currentTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ IdOrName: &id, - }, false) + }, services.TargetRetrievalParams{}) if err != nil || currentTarget == nil { return err } defaultTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ Default: util.Pointer(true), - }, false) - if err != nil && !IsTargetNotFound(err) { + }, services.TargetRetrievalParams{}) + if err != nil && !stores.IsTargetNotFound(err) { return err } diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index e9b4681b5b..a5a7a3a9de 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -5,58 +5,23 @@ package targets import ( "context" - "fmt" - "io" - "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" - - "github.com/daytonaio/daytona/internal/util" ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleStartError(ctx, nil, ErrTargetNotFound) - } - - targetLogger := s.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) - defer targetLogger.Close() - - logger := io.MultiWriter(&util.InfoLogWriter{}, targetLogger) - - t.EnvVars = GetTargetEnvVars(t, TargetEnvVarParams{ - ApiUrl: s.serverApiUrl, - ServerUrl: s.serverUrl, - ServerVersion: s.serverVersion, - ClientId: telemetry.ClientId(ctx), - }, telemetry.TelemetryEnabled(ctx)) - - err = s.startTarget(t, logger) - if err != nil { - return s.handleStartError(ctx, t, err) + return s.handleStartError(ctx, nil, stores.ErrTargetNotFound) } + err = s.createJob(ctx, t.Id, models.JobActionStart) return s.handleStartError(ctx, t, err) } -func (s *TargetService) startTarget(target *models.Target, targetLogger io.Writer) error { - targetLogger.Write([]byte("Starting target\n")) - - err := s.provisioner.StartTarget(target) - if err != nil { - return err - } - - targetLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Target %s started", target.Name)))) - - return err -} - func (s *TargetService) handleStartError(ctx context.Context, target *models.Target, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index 47afef24da..77d8f2b442 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -15,11 +15,10 @@ import ( func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleStopError(ctx, nil, ErrTargetNotFound) + return s.handleStopError(ctx, nil, stores.ErrTargetNotFound) } - err = s.provisioner.StopTarget(target) - + err = s.createJob(ctx, target.Id, models.JobActionStop) return s.handleStopError(ctx, target, err) } diff --git a/pkg/server/workspaceconfigs/prebuild.go b/pkg/server/workspaceconfigs/prebuild.go index a89371959d..01a594131b 100644 --- a/pkg/server/workspaceconfigs/prebuild.go +++ b/pkg/server/workspaceconfigs/prebuild.go @@ -12,6 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/scheduler" "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" @@ -334,9 +335,9 @@ func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { } func (s *WorkspaceConfigService) StartRetentionPoller() error { - scheduler := build.NewCronScheduler() + scheduler := scheduler.NewCronScheduler() - err := scheduler.AddFunc(build.DEFAULT_POLL_INTERVAL, func() { + err := scheduler.AddFunc(build.DEFAULT_BUILD_POLL_INTERVAL, func() { err := s.EnforceRetentionPolicy() if err != nil { log.Error(err) diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 57f6a281a8..a99d098ec7 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -10,38 +10,17 @@ import ( "regexp" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" ) -func isValidWorkspaceName(name string) bool { - // The repository name can only contain ASCII letters, digits, and the characters ., -, and _. - var validName = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) - - // Check if the name matches the basic regex - if !validName.MatchString(name) { - return false - } - - // Names starting with a period must have atleast one char appended to it. - if name == "." || name == "" { - return false - } - - return true -} - func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.CreateWorkspaceDTO) (*models.Workspace, error) { _, err := s.workspaceStore.Find(req.Name) if err == nil { - return s.handleCreateError(ctx, nil, ErrWorkspaceAlreadyExists) + return s.handleCreateError(ctx, nil, services.ErrWorkspaceAlreadyExists) } target, err := s.findTarget(ctx, req.TargetId) @@ -53,7 +32,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre w.Target = *target if !isValidWorkspaceName(w.Name) { - return s.handleCreateError(ctx, w, ErrInvalidWorkspaceName) + return s.handleCreateError(ctx, w, services.ErrInvalidWorkspaceName) } w.Repository.Url = util.CleanUpRepositoryUrl(w.Repository.Url) @@ -102,21 +81,14 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre w.ApiKey = apiKey - err = s.workspaceStore.Save(w) - if err != nil { - return s.handleCreateError(ctx, w, err) - } - - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) - defer workspaceLogger.Close() - workspaceWithEnv := *w workspaceWithEnv.EnvVars = GetWorkspaceEnvVars(w, WorkspaceEnvVarParams{ - ApiUrl: s.serverApiUrl, - ServerUrl: s.serverUrl, - ServerVersion: s.serverVersion, - ClientId: telemetry.ClientId(ctx), - }, telemetry.TelemetryEnabled(ctx)) + ApiUrl: s.serverApiUrl, + ServerUrl: s.serverUrl, + ServerVersion: s.serverVersion, + ClientId: telemetry.ClientId(ctx), + TelemetryEnabled: telemetry.TelemetryEnabled(ctx), + }) for k, v := range w.EnvVars { workspaceWithEnv.EnvVars[k] = v @@ -124,42 +96,21 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre w = &workspaceWithEnv - workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) - - cr, err := s.findContainerRegistry(ctx, w.Image) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return s.handleCreateError(ctx, w, err) - } - - builderCr, err := s.findContainerRegistry(ctx, s.builderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { + err = s.workspaceStore.Save(w) + if err != nil { return s.handleCreateError(ctx, w, err) } - var gc *models.GitProviderConfig - - if w.GitProviderConfigId != nil { - gc, err = s.findGitProviderConfig(ctx, *w.GitProviderConfigId) - if err != nil && !stores.IsGitProviderNotFound(err) { - return s.handleCreateError(ctx, w, err) - } - } - - err = s.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ - Workspace: w, - ContainerRegistry: cr, - GitProviderConfig: gc, - BuilderImage: s.builderImage, - BuilderImageContainerRegistry: builderCr, + err = s.workspaceMetadataStore.Save(&models.WorkspaceMetadata{ + WorkspaceId: w.Id, + Uptime: 0, + GitStatus: &models.GitStatus{}, }) if err != nil { return s.handleCreateError(ctx, w, err) } - workspaceLogger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s created", w.Name)))) - - err = s.startWorkspace(ctx, w, workspaceLogger) - + err = s.createJob(ctx, w.Id, models.JobActionCreate) return s.handleCreateError(ctx, w, err) } @@ -190,3 +141,20 @@ func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Work return w, err } + +func isValidWorkspaceName(name string) bool { + // The repository name can only contain ASCII letters, digits, and the characters ., -, and _. + var validName = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`) + + // Check if the name matches the basic regex + if !validName.MatchString(name) { + return false + } + + // Names starting with a period must have atleast one char appended to it. + if name == "." || name == "" { + return false + } + + return true +} diff --git a/pkg/server/workspaces/env_vars.go b/pkg/server/workspaces/env_vars.go index e6b7afe96f..cb5937a232 100644 --- a/pkg/server/workspaces/env_vars.go +++ b/pkg/server/workspaces/env_vars.go @@ -6,13 +6,14 @@ package workspaces import "github.com/daytonaio/daytona/pkg/models" type WorkspaceEnvVarParams struct { - ApiUrl string - ServerUrl string - ServerVersion string - ClientId string + ApiUrl string + ServerUrl string + ServerVersion string + ClientId string + TelemetryEnabled bool } -func GetWorkspaceEnvVars(workspace *models.Workspace, params WorkspaceEnvVarParams, telemetryEnabled bool) map[string]string { +func GetWorkspaceEnvVars(workspace *models.Workspace, params WorkspaceEnvVarParams) map[string]string { envVars := map[string]string{ "DAYTONA_TARGET_ID": workspace.TargetId, "DAYTONA_WORKSPACE_ID": workspace.Id, @@ -26,7 +27,7 @@ func GetWorkspaceEnvVars(workspace *models.Workspace, params WorkspaceEnvVarPara "DAYTONA_AGENT_LOG_FILE_PATH": "(HOME)/.daytona-agent.log", } - if telemetryEnabled { + if params.TelemetryEnabled { envVars["DAYTONA_TELEMETRY_ENABLED"] = "true" } diff --git a/pkg/server/workspaces/error.go b/pkg/server/workspaces/error.go deleted file mode 100644 index 68b212eec7..0000000000 --- a/pkg/server/workspaces/error.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaces - -import ( - "errors" -) - -var ( - ErrWorkspaceAlreadyExists = errors.New("workspace already exists") - ErrWorkspaceNotFound = errors.New("workspace not found") - ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") - ErrInvalidWorkspaceConfig = errors.New("workspace config is invalid") -) diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index 1f6c2e0352..5e3e28b979 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -9,22 +9,31 @@ import ( "fmt" "time" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*services.WorkspaceDTO, error) { +func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return nil, ErrWorkspaceNotFound + return nil, stores.ErrWorkspaceNotFound + } + + state := ws.GetState() + + if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { + return nil, services.ErrWorkspaceDeleted } response := &services.WorkspaceDTO{ Workspace: *ws, + State: state, } - if !verbose { + if !params.Verbose { return response, nil } diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index 6177b2e53f..5c9a3159ad 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -10,12 +10,13 @@ import ( "sync" "time" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([]services.WorkspaceDTO, error) { +func (s *WorkspaceService) ListWorkspaces(ctx context.Context, params services.WorkspaceRetrievalParams) ([]services.WorkspaceDTO, error) { workspaces, err := s.workspaceStore.List() if err != nil { return nil, err @@ -25,8 +26,18 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, verbose bool) ([] response := []services.WorkspaceDTO{} for i, ws := range workspaces { - response = append(response, services.WorkspaceDTO{Workspace: *ws}) - if !verbose { + state := ws.GetState() + + if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { + continue + } + + response = append(response, services.WorkspaceDTO{ + Workspace: *ws, + State: state, + }) + + if !params.Verbose { continue } diff --git a/pkg/server/workspaces/metadata.go b/pkg/server/workspaces/metadata.go new file mode 100644 index 0000000000..70be5271e3 --- /dev/null +++ b/pkg/server/workspaces/metadata.go @@ -0,0 +1,23 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +func (s *WorkspaceService) SetWorkspaceMetadata(workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { + m, err := s.workspaceMetadataStore.Find(&stores.WorkspaceMetadataFilter{ + WorkspaceId: &workspaceId, + }) + if err != nil { + return nil, stores.ErrWorkspaceMetadataNotFound + } + + m.GitStatus = metadata.GitStatus + m.Uptime = metadata.Uptime + m.UpdatedAt = metadata.UpdatedAt + return m, s.workspaceMetadataStore.Save(m) +} diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index 323bcc7399..78c6514076 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -7,8 +7,9 @@ import ( "context" "fmt" - "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) @@ -16,30 +17,17 @@ import ( func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleRemoveError(ctx, ws, ErrWorkspaceNotFound) + return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) } - log.Infof("Destroying workspace %s", ws.Name) + ws.Name = util.AddDeletedToName(ws.Name) - err = s.provisioner.DestroyWorkspace(ws) + err = s.workspaceStore.Save(ws) if err != nil { return s.handleRemoveError(ctx, ws, err) } - err = s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", ws.Id)) - if err != nil { - // Should not fail the whole operation if the API key cannot be revoked - log.Error(err) - } - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) - err = workspaceLogger.Cleanup() - if err != nil { - // Should not fail the whole operation if the workspace logger cannot be cleaned up - log.Error(err) - } - - err = s.workspaceStore.Delete(ws) - + err = s.createJob(ctx, ws.Id, models.JobActionDelete) return s.handleRemoveError(ctx, ws, err) } @@ -47,30 +35,43 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleRemoveError(ctx, ws, ErrWorkspaceNotFound) + return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) } - log.Infof("Destroying workspace %s", ws.Name) + ws.Name = util.AddDeletedToName(ws.Name) - err = s.provisioner.DestroyWorkspace(ws) + err = s.workspaceStore.Save(ws) if err != nil { - log.Error(err) + return s.handleRemoveError(ctx, ws, err) } - err = s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", ws.Id)) + err = s.createJob(ctx, ws.Id, models.JobActionForceDelete) + return s.handleRemoveError(ctx, ws, err) +} + +func (s *WorkspaceService) HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error { + err := s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", workspaceId)) if err != nil { // Should not fail the whole operation if the API key cannot be revoked log.Error(err) } - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) - err = workspaceLogger.Cleanup() + + ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - // Should not fail the whole operation if the workspace logger cannot be cleaned up - log.Error(err) + return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) } - err = s.workspaceStore.Delete(ws) + metadata, err := s.workspaceMetadataStore.Find(&stores.WorkspaceMetadataFilter{WorkspaceId: &workspaceId}) + if err != nil { + return s.handleRemoveError(ctx, ws, err) + } + + err = s.workspaceMetadataStore.Delete(metadata) + if err != nil { + return s.handleRemoveError(ctx, ws, err) + } + err = s.workspaceStore.Delete(ws) return s.handleRemoveError(ctx, ws, err) } diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index dc5623bf79..f5b4b03382 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -17,7 +17,8 @@ import ( ) type WorkspaceServiceConfig struct { - WorkspaceStore stores.WorkspaceStore + WorkspaceStore stores.WorkspaceStore + WorkspaceMetadataStore stores.WorkspaceMetadataStore FindTarget func(ctx context.Context, targetId string) (*models.Target, error) FindContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) @@ -27,6 +28,7 @@ type WorkspaceServiceConfig struct { ListGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) + CreateJob func(ctx context.Context, workspaceId string, action models.JobAction) error TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error LoggerFactory logs.LoggerFactory @@ -36,12 +38,13 @@ type WorkspaceServiceConfig struct { Provisioner provisioner.IProvisioner DefaultWorkspaceImage string DefaultWorkspaceUser string - BuilderImage string } func NewWorkspaceService(config WorkspaceServiceConfig) services.IWorkspaceService { return &WorkspaceService{ workspaceStore: config.WorkspaceStore, + workspaceMetadataStore: config.WorkspaceMetadataStore, + findTarget: config.FindTarget, findContainerRegistry: config.FindContainerRegistry, findCachedBuild: config.FindCachedBuild, @@ -50,6 +53,7 @@ func NewWorkspaceService(config WorkspaceServiceConfig) services.IWorkspaceServi listGitProviderConfigs: config.ListGitProviderConfigs, findGitProviderConfig: config.FindGitProviderConfig, getLastCommitSha: config.GetLastCommitSha, + createJob: config.CreateJob, trackTelemetryEvent: config.TrackTelemetryEvent, serverApiUrl: config.ServerApiUrl, @@ -59,12 +63,12 @@ func NewWorkspaceService(config WorkspaceServiceConfig) services.IWorkspaceServi defaultWorkspaceUser: config.DefaultWorkspaceUser, provisioner: config.Provisioner, loggerFactory: config.LoggerFactory, - builderImage: config.BuilderImage, } } type WorkspaceService struct { - workspaceStore stores.WorkspaceStore + workspaceStore stores.WorkspaceStore + workspaceMetadataStore stores.WorkspaceMetadataStore findTarget func(ctx context.Context, targetId string) (*models.Target, error) findContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) @@ -74,6 +78,7 @@ type WorkspaceService struct { listGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) getLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) + createJob func(ctx context.Context, workspaceId string, action models.JobAction) error trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error provisioner provisioner.IProvisioner @@ -83,17 +88,6 @@ type WorkspaceService struct { defaultWorkspaceImage string defaultWorkspaceUser string loggerFactory logs.LoggerFactory - builderImage string -} - -func (s *WorkspaceService) SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) { - ws, err := s.workspaceStore.Find(workspaceId) - if err != nil { - return nil, ErrWorkspaceNotFound - } - - ws.State = state - return ws, s.workspaceStore.Save(ws) } func (s *WorkspaceService) GetWorkspaceLogReader(workspaceId string) (io.Reader, error) { diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index b7331e4dca..9904d7b9e3 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -7,7 +7,6 @@ import ( "context" "fmt" "testing" - "time" t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" @@ -102,7 +101,7 @@ func TestTargetService(t *testing.T) { ApiUrl: serverApiUrl, ServerUrl: serverUrl, ClientId: "test-client-id", - }, false) + }) ctx := context.Background() ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") @@ -161,7 +160,6 @@ func TestTargetService(t *testing.T) { DefaultWorkspaceUser: defaultWorkspaceUser, Provisioner: mockProvisioner, LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), - BuilderImage: defaultWorkspaceImage, }) t.Run("CreateWorkspace", func(t *testing.T) { @@ -189,7 +187,7 @@ func TestTargetService(t *testing.T) { ServerUrl: serverUrl, ServerVersion: serverVersion, ClientId: "test", - }, false) + }) mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ Workspace: ws, @@ -223,7 +221,7 @@ func TestTargetService(t *testing.T) { t.Run("CreateWorkspace fails when workspace already exists", func(t *testing.T) { _, err := service.CreateWorkspace(ctx, createWorkspaceDTO) require.NotNil(t, err) - require.Equal(t, workspaces.ErrWorkspaceAlreadyExists, err) + require.Equal(t, services.ErrWorkspaceAlreadyExists, err) }) t.Run("CreateWorkspace fails name validation", func(t *testing.T) { @@ -232,13 +230,13 @@ func TestTargetService(t *testing.T) { _, err := service.CreateWorkspace(ctx, invalidWorkspaceRequest) require.NotNil(t, err) - require.Equal(t, workspaces.ErrInvalidWorkspaceName, err) + require.Equal(t, services.ErrInvalidWorkspaceName, err) }) t.Run("GetWorkspace", func(t *testing.T) { mockProvisioner.On("GetWorkspaceInfo", ws, tg).Return(&workspaceInfo, nil) - w, err := service.GetWorkspace(ctx, ws.Id, true) + w, err := service.GetWorkspace(ctx, ws.Id, services.WorkspaceRetrievalParams{Verbose: true}) require.Nil(t, err) require.NotNil(t, w) @@ -247,15 +245,15 @@ func TestTargetService(t *testing.T) { }) t.Run("GetWorkspace fails when workspace not found", func(t *testing.T) { - _, err := service.GetWorkspace(ctx, "invalid-id", true) + _, err := service.GetWorkspace(ctx, "invalid-id", services.WorkspaceRetrievalParams{Verbose: true}) require.NotNil(t, err) - require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + require.Equal(t, stores.ErrWorkspaceNotFound, err) }) t.Run("ListWorkspaces", func(t *testing.T) { verbose := false - workspaces, err := service.ListWorkspaces(ctx, verbose) + workspaces, err := service.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{Verbose: verbose}) require.Nil(t, err) require.Len(t, workspaces, 1) @@ -269,7 +267,7 @@ func TestTargetService(t *testing.T) { verbose := true mockProvisioner.On("GetWorkspaceInfo", ws, tg).Return(&workspaceInfo, nil) - workspaces, err := service.ListWorkspaces(ctx, verbose) + workspaces, err := service.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{Verbose: verbose}) require.Nil(t, err) require.Len(t, workspaces, 1) @@ -301,8 +299,8 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, true) - require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{Verbose: true}) + require.Equal(t, stores.ErrWorkspaceNotFound, err) }) t.Run("ForceRemoveWorkspace", func(t *testing.T) { @@ -316,18 +314,16 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, true) - require.Equal(t, workspaces.ErrWorkspaceNotFound, err) + _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{Verbose: true}) + require.Equal(t, stores.ErrWorkspaceNotFound, err) }) - t.Run("SetWorkspaceState", func(t *testing.T) { + t.Run("SetWorkspaceMetadata", func(t *testing.T) { err := workspaceStore.Save(ws) require.Nil(t, err) - updatedAt := time.Now().Format(time.RFC1123) - res, err := service.SetWorkspaceState(createWorkspaceDTO.Id, &models.WorkspaceState{ - UpdatedAt: updatedAt, - Uptime: 10, + res, err := service.SetWorkspaceMetadata(createWorkspaceDTO.Id, &models.WorkspaceMetadata{ + Uptime: 10, GitStatus: &models.GitStatus{ CurrentBranch: "main", }, @@ -335,7 +331,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.Nil(t, err) - require.Equal(t, "main", res.State.GitStatus.CurrentBranch) + require.Equal(t, "main", res.GitStatus.CurrentBranch) }) t.Cleanup(func() { diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index ed4af413f8..a491a42425 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -5,81 +5,23 @@ package workspaces import ( "context" - "fmt" - "io" - "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/daytonaio/daytona/pkg/views" log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleStartError(ctx, ws, ErrWorkspaceNotFound) - } - - workspaceLogger := s.loggerFactory.CreateWorkspaceLogger(ws.Id, ws.Name, logs.LogSourceServer) - defer workspaceLogger.Close() - - workspaceToStart := ws - workspaceToStart.EnvVars = GetWorkspaceEnvVars(ws, WorkspaceEnvVarParams{ - ApiUrl: s.serverApiUrl, - ServerUrl: s.serverUrl, - ServerVersion: s.serverVersion, - ClientId: telemetry.ClientId(ctx), - }, telemetry.TelemetryEnabled(ctx)) - - err = s.startWorkspace(ctx, workspaceToStart, workspaceLogger) - if err != nil { - return s.handleStartError(ctx, ws, err) + return s.handleStartError(ctx, ws, stores.ErrWorkspaceNotFound) } + err = s.createJob(ctx, ws.Id, models.JobActionStart) return s.handleStartError(ctx, ws, err) } -func (s *WorkspaceService) startWorkspace(ctx context.Context, w *models.Workspace, logger io.Writer) error { - logger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) - - cr, err := s.findContainerRegistry(ctx, w.Image) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return err - } - - builderCr, err := s.findContainerRegistry(ctx, s.builderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return err - } - - var gc *models.GitProviderConfig - - if w.GitProviderConfigId != nil { - gc, err = s.findGitProviderConfig(ctx, *w.GitProviderConfigId) - if err != nil && !stores.IsGitProviderNotFound(err) { - return err - } - } - - err = s.provisioner.StartWorkspace(provisioner.WorkspaceParams{ - Workspace: w, - ContainerRegistry: cr, - GitProviderConfig: gc, - BuilderImage: s.builderImage, - BuilderImageContainerRegistry: builderCr, - }) - if err != nil { - return err - } - - logger.Write([]byte(views.GetPrettyLogLine(fmt.Sprintf("Workspace %s started", w.Name)))) - - return nil -} - func (s *WorkspaceService) handleStartError(ctx context.Context, w *models.Workspace, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 19a95567f8..64a16055d0 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -5,9 +5,9 @@ package workspaces import ( "context" - "time" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) @@ -15,21 +15,10 @@ import ( func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { ws, err := s.workspaceStore.Find(workspaceId) if err != nil { - return s.handleStopError(ctx, ws, ErrWorkspaceNotFound) + return s.handleStopError(ctx, ws, stores.ErrWorkspaceNotFound) } - // todo: go routines - err = s.provisioner.StopWorkspace(ws) - if err != nil { - return s.handleStopError(ctx, ws, err) - } - if ws.State != nil { - ws.State.Uptime = 0 - ws.State.UpdatedAt = time.Now().Format(time.RFC1123) - } - - err = s.workspaceStore.Save(ws) - + err = s.createJob(ctx, ws.Id, models.JobActionStop) return s.handleStopError(ctx, ws, err) } diff --git a/pkg/services/job.go b/pkg/services/job.go new file mode 100644 index 0000000000..c1feae08dc --- /dev/null +++ b/pkg/services/job.go @@ -0,0 +1,16 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type IJobService interface { + Save(job *models.Job) error + Find(filter *stores.JobFilter) (*models.Job, error) + List(filter *stores.JobFilter) ([]*models.Job, error) + Delete(job *models.Job) error +} diff --git a/pkg/services/target.go b/pkg/services/target.go index 9a96c8068c..0ca9f9545d 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -5,6 +5,7 @@ package services import ( "context" + "errors" "io" "github.com/daytonaio/daytona/pkg/models" @@ -14,12 +15,31 @@ import ( type ITargetService interface { CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) - GetTarget(ctx context.Context, filter *stores.TargetFilter, verbose bool) (*dto.TargetDTO, error) + GetTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*dto.TargetDTO, error) GetTargetLogReader(targetId string) (io.Reader, error) - ListTargets(ctx context.Context, filter *stores.TargetFilter, verbose bool) ([]dto.TargetDTO, error) + ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]dto.TargetDTO, error) StartTarget(ctx context.Context, targetId string) error StopTarget(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error RemoveTarget(ctx context.Context, targetId string) error ForceRemoveTarget(ctx context.Context, targetId string) error + HandleSuccessfulCreation(ctx context.Context, targetId string) error + HandleSuccessfulRemoval(ctx context.Context, targetId string) error + + SetTargetMetadata(targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) +} + +type TargetRetrievalParams struct { + Verbose bool + ShowDeleted bool +} + +var ( + ErrTargetAlreadyExists = errors.New("target already exists") + ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") + ErrTargetDeleted = errors.New("target is deleted") +) + +func IsTargetDeleted(err error) bool { + return errors.Is(err, ErrTargetDeleted) } diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 9667b3411c..636d84f2e7 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -5,6 +5,7 @@ package services import ( "context" + "errors" "io" "github.com/daytonaio/daytona/pkg/gitprovider" @@ -13,22 +14,29 @@ import ( type IWorkspaceService interface { CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*models.Workspace, error) - GetWorkspace(ctx context.Context, workspaceId string, verbose bool) (*WorkspaceDTO, error) - ListWorkspaces(ctx context.Context, verbose bool) ([]WorkspaceDTO, error) + GetWorkspace(ctx context.Context, workspaceId string, params WorkspaceRetrievalParams) (*WorkspaceDTO, error) + ListWorkspaces(ctx context.Context, params WorkspaceRetrievalParams) ([]WorkspaceDTO, error) StartWorkspace(ctx context.Context, workspaceId string) error StopWorkspace(ctx context.Context, workspaceId string) error RemoveWorkspace(ctx context.Context, workspaceId string) error ForceRemoveWorkspace(ctx context.Context, workspaceId string) error + HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error GetWorkspaceLogReader(workspaceId string) (io.Reader, error) - SetWorkspaceState(workspaceId string, state *models.WorkspaceState) (*models.Workspace, error) + SetWorkspaceMetadata(workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) } type WorkspaceDTO struct { models.Workspace - Info *models.WorkspaceInfo `json:"info" validate:"optional"` + State models.ResourceState `json:"state" validate:"required"` + Info *models.WorkspaceInfo `json:"info" validate:"optional"` } // @name WorkspaceDTO +type WorkspaceRetrievalParams struct { + Verbose bool + ShowDeleted bool +} + type CreateWorkspaceDTO struct { Id string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` @@ -66,3 +74,14 @@ func (c *CreateWorkspaceDTO) ToWorkspace() *models.Workspace { type CreateWorkspaceSourceDTO struct { Repository *gitprovider.GitRepository `json:"repository" validate:"required"` } // @name CreateWorkspaceSourceDTO + +var ( + ErrWorkspaceAlreadyExists = errors.New("workspace already exists") + ErrWorkspaceDeleted = errors.New("workspace is deleted") + ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") + ErrInvalidWorkspaceConfig = errors.New("workspace config is invalid") +) + +func IsWorkspaceDeleted(err error) bool { + return errors.Is(err, ErrWorkspaceDeleted) +} diff --git a/pkg/stores/job_store.go b/pkg/stores/job_store.go new file mode 100644 index 0000000000..f00206ac65 --- /dev/null +++ b/pkg/stores/job_store.go @@ -0,0 +1,48 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type JobStore interface { + List(filter *JobFilter) ([]*models.Job, error) + Find(filter *JobFilter) (*models.Job, error) + Save(job *models.Job) error + Delete(job *models.Job) error +} + +type JobFilter struct { + Id *string + ResourceType *models.ResourceType + States *[]models.JobState + Actions *[]models.JobAction +} + +func (f *JobFilter) StatesToInterface() []interface{} { + args := make([]interface{}, len(*f.States)) + for i, v := range *f.States { + args[i] = v + } + return args +} + +func (f *JobFilter) ActionsToInterface() []interface{} { + args := make([]interface{}, len(*f.Actions)) + for i, v := range *f.Actions { + args[i] = v + } + return args +} + +var ( + ErrJobNotFound = errors.New("job not found") +) + +func IsJobNotFound(err error) bool { + return err.Error() == ErrJobNotFound.Error() +} diff --git a/pkg/stores/target.go b/pkg/stores/target.go index 46e70640ba..54b179dea3 100644 --- a/pkg/stores/target.go +++ b/pkg/stores/target.go @@ -4,6 +4,8 @@ package stores import ( + "errors" + "github.com/daytonaio/daytona/pkg/models" ) @@ -18,3 +20,11 @@ type TargetStore interface { Save(target *models.Target) error Delete(target *models.Target) error } + +var ( + ErrTargetNotFound = errors.New("target not found") +) + +func IsTargetNotFound(err error) bool { + return err.Error() == ErrTargetNotFound.Error() +} diff --git a/pkg/stores/target_metadata.go b/pkg/stores/target_metadata.go new file mode 100644 index 0000000000..6528243259 --- /dev/null +++ b/pkg/stores/target_metadata.go @@ -0,0 +1,29 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type TargetMetadataFilter struct { + Id *string + TargetId *string +} + +type TargetMetadataStore interface { + Find(filter *TargetMetadataFilter) (*models.TargetMetadata, error) + Save(metadata *models.TargetMetadata) error + Delete(metadata *models.TargetMetadata) error +} + +var ( + ErrTargetMetadataNotFound = errors.New("target metadata not found") +) + +func IsTargetMetadataNotFound(err error) bool { + return err.Error() == ErrTargetMetadataNotFound.Error() +} diff --git a/pkg/stores/workspace.go b/pkg/stores/workspace.go index cf9cc0958a..42ba8939b7 100644 --- a/pkg/stores/workspace.go +++ b/pkg/stores/workspace.go @@ -4,6 +4,8 @@ package stores import ( + "errors" + "github.com/daytonaio/daytona/pkg/models" ) @@ -13,3 +15,11 @@ type WorkspaceStore interface { Save(workspace *models.Workspace) error Delete(workspace *models.Workspace) error } + +var ( + ErrWorkspaceNotFound = errors.New("workspace not found") +) + +func IsWorkspaceNotFound(err error) bool { + return err.Error() == ErrWorkspaceNotFound.Error() +} diff --git a/pkg/stores/workspace_metadata.go b/pkg/stores/workspace_metadata.go new file mode 100644 index 0000000000..7d54fd6c16 --- /dev/null +++ b/pkg/stores/workspace_metadata.go @@ -0,0 +1,29 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type WorkspaceMetadataFilter struct { + Id *string + WorkspaceId *string +} + +type WorkspaceMetadataStore interface { + Find(filter *WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) + Save(metadata *models.WorkspaceMetadata) error + Delete(metadata *models.WorkspaceMetadata) error +} + +var ( + ErrWorkspaceMetadataNotFound = errors.New("workspace metadata not found") +) + +func IsWorkspaceMetadataNotFound(err error) bool { + return err.Error() == ErrWorkspaceMetadataNotFound.Error() +} diff --git a/pkg/views/common.go b/pkg/views/common.go index 912a5f983e..5a37fc12da 100644 --- a/pkg/views/common.go +++ b/pkg/views/common.go @@ -10,6 +10,7 @@ import ( "github.com/charmbracelet/huh" "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/apiclient" "golang.org/x/term" ) @@ -46,6 +47,26 @@ var ( widthBreakpoints = []int{60, 80, 100, 120, 140, 160} ) +// Resources that have actions being performed on them have a higher priority when listing +var ResourceListStatePriorities = map[apiclient.ModelsResourceStateName]int{ + apiclient.ResourceStateNamePendingCreate: 1, + apiclient.ResourceStateNamePendingStart: 1, + apiclient.ResourceStateNamePendingStop: 1, + apiclient.ResourceStateNamePendingRestart: 1, + apiclient.ResourceStateNamePendingDelete: 1, + apiclient.ResourceStateNamePendingForcedDelete: 1, + apiclient.ResourceStateNameCreating: 1, + apiclient.ResourceStateNameStarting: 1, + apiclient.ResourceStateNameStopping: 1, + apiclient.ResourceStateNameDeleting: 1, + apiclient.ResourceStateNameStarted: 2, + apiclient.ResourceStateNameUndefined: 2, + apiclient.ResourceStateNameError: 3, + apiclient.ResourceStateNameUnresponsive: 4, + apiclient.ResourceStateNameStopped: 5, + apiclient.ResourceStateNameDeleted: 6, +} + func RenderMainTitle(title string) { fmt.Println(lipgloss.NewStyle().Foreground(Green).Bold(true).Padding(1, 0, 1, 0).Render(title)) } @@ -184,3 +205,42 @@ func GetEnvVarsInput(envVars *map[string]string) *huh.Text { func GetPrettyLogLine(message string) string { return fmt.Sprintf("%s \033[1m%s\033[0m\n", lipgloss.NewStyle().Foreground(lipgloss.Color("42")).SetString("✓").String(), message) } + +func GetStateLabel(state apiclient.ModelsResourceStateName) string { + switch state { + case apiclient.ResourceStateNameUndefined: + return UndefinedStyle.Render("/") + case apiclient.ResourceStateNamePendingCreate: + return PendingStyle.Render("PENDING") + case apiclient.ResourceStateNameCreating: + return CreatingStyle.Render("CREATING") + case apiclient.ResourceStateNamePendingStart: + return PendingStyle.Render("STARTING") + case apiclient.ResourceStateNameStarting: + return StartingStyle.Render("STARTING") + case apiclient.ResourceStateNameStarted: + return StartedStyle.Render("STARTED") + case apiclient.ResourceStateNamePendingStop: + return PendingStyle.Render("STOPPING") + case apiclient.ResourceStateNameStopping: + return StoppingStyle.Render("STOPPING") + case apiclient.ResourceStateNameStopped: + return StoppedStyle.Render("STOPPED") + case apiclient.ResourceStateNamePendingRestart: + return DeletingStyle.Render("RESTARTING") + case apiclient.ResourceStateNamePendingDelete: + return DeletingStyle.Render("DELETING") + case apiclient.ResourceStateNamePendingForcedDelete: + return DeletingStyle.Render("DELETING") + case apiclient.ResourceStateNameDeleting: + return DeletingStyle.Render("DELETING") + case apiclient.ResourceStateNameDeleted: + return DeletedStyle.Render("DELETED") + case apiclient.ResourceStateNameError: + return ErrorStyle.Render("ERROR") + case apiclient.ResourceStateNameUnresponsive: + return UnresponsiveStyle.Render("UNRESPONSIVE") + } + + return "/" +} diff --git a/pkg/views/styles.go b/pkg/views/styles.go index 08c2310884..00a5f9c71d 100644 --- a/pkg/views/styles.go +++ b/pkg/views/styles.go @@ -31,6 +31,18 @@ var ( Red = lipgloss.AdaptiveColor{Light: "#FF4672", Dark: "#ED567A"} ) +var ( + ColorPending = lipgloss.AdaptiveColor{Light: "#cce046", Dark: "#cce046"} + ColorStarted = lipgloss.AdaptiveColor{Light: "#2ecc71", Dark: "#2ecc71"} + ColorStarting = ColorStarted + ColorStopped = lipgloss.AdaptiveColor{Light: "#a2a2a2", Dark: "#a2a2a2"} + ColorStopping = ColorStopped + ColorError = lipgloss.AdaptiveColor{Light: "#e74c3c", Dark: "#e74c3c"} + ColorDeleting = ColorStopped + ColorDeleted = ColorStopped + ColorUnresponsive = ColorError +) + var ( BaseTableStyleHorizontalPadding = 4 BaseTableStyle = lipgloss.NewStyle(). @@ -47,6 +59,20 @@ var ( TableHeaderStyle = BaseCellStyle.Foreground(LightGray).Bold(false).Padding(0).MarginRight(4) ) +var ( + UndefinedStyle = lipgloss.NewStyle().Foreground(ColorPending) + PendingStyle = lipgloss.NewStyle().Foreground(ColorPending) + CreatingStyle = lipgloss.NewStyle().Foreground(ColorPending) + StartedStyle = lipgloss.NewStyle().Foreground(ColorStarted) + StartingStyle = lipgloss.NewStyle().Foreground(ColorStarting) + StoppedStyle = lipgloss.NewStyle().Foreground(ColorStopped) + StoppingStyle = lipgloss.NewStyle().Foreground(ColorStopping) + ErrorStyle = lipgloss.NewStyle().Foreground(ColorError) + DeletingStyle = lipgloss.NewStyle().Foreground(ColorDeleting) + DeletedStyle = lipgloss.NewStyle().Foreground(ColorDeleted) + UnresponsiveStyle = lipgloss.NewStyle().Foreground(ColorUnresponsive) +) + var LogPrefixColors = []lipgloss.AdaptiveColor{ Blue, Orange, Cyan, Yellow, } diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index 1ce02c42fa..5e6a5bbda3 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -10,6 +10,7 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" "golang.org/x/term" ) @@ -42,6 +43,11 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("Default", "Yes") + "\n" } + output += getInfoLineState("State", target.State, target.Metadata) + "\n" + if target.State.Error != nil { + output += getInfoLine("Error", *target.State.Error) + "\n" + } + output += getInfoLine("Options", target.Options) + "\n" if target.Info != nil { @@ -78,3 +84,12 @@ func renderTUIView(output string, width int) { func getInfoLine(key, value string) string { return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + propertyValueStyle.Render(value) + "\n" } + +func getInfoLineState(key string, state apiclient.ResourceState, metadata *apiclient.TargetMetadata) string { + stateLabel := views.GetStateLabel(state.Name) + + if metadata != nil { + views_util.CheckAndAppendTimeLabel(&stateLabel, state, metadata.Uptime) + } + return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + stateLabel + propertyValueStyle.Foreground(views.Light).Render("\n") +} diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index c92666fa75..04c60ad7a7 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -18,9 +18,11 @@ import ( type RowData struct { Name string Provider string - Default bool WorkspaceCount string + Default bool + Status string Options string + Uptime string } func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileName string) { @@ -31,7 +33,7 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa SortTargets(&targetList) - headers := []string{"Target", "Provider", "Default", "# Workspaces", "Options"} + headers := []string{"Target", "Options", "# Workspaces", "Default", "Status"} data := util.ArrayMap(targetList, func(target apiclient.TargetDTO) []string { provider := target.ProviderInfo.Name @@ -42,9 +44,14 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa rowData := RowData{ Name: target.Name, Provider: provider, - Default: target.Default, - WorkspaceCount: fmt.Sprintf("%d", len(target.Workspaces)), Options: target.Options, + WorkspaceCount: fmt.Sprint(len(target.Workspaces)), + Default: target.Default, + Status: views.GetStateLabel(target.State.Name), + } + + if target.Metadata != nil { + views_util.CheckAndAppendTimeLabel(&rowData.Status, target.State, target.Metadata.Uptime) } return getRowFromRowData(rowData) @@ -59,6 +66,34 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa fmt.Println(table) } +func SortTargets(targetList *[]apiclient.TargetDTO) { + sort.Slice(*targetList, func(i, j int) bool { + // Sort the default target on top + if (*targetList)[i].Default && !(*targetList)[j].Default { + return true + } + if !(*targetList)[i].Default && (*targetList)[j].Default { + return false + } + + pi, ok := views.ResourceListStatePriorities[(*targetList)[i].State.Name] + if !ok { + pi = 99 + } + pj, ok2 := views.ResourceListStatePriorities[(*targetList)[j].State.Name] + if !ok2 { + pj = 99 + } + + if pi != pj { + return pi < pj + } + + // If two targets have the same state priority, compare the UpdatedAt property + return (*targetList)[i].State.UpdatedAt > (*targetList)[j].State.UpdatedAt + }) +} + func renderUnstyledList(targetList []apiclient.TargetDTO) { for _, target := range targetList { info_view.Render(&target, true) @@ -73,22 +108,16 @@ func getRowFromRowData(rowData RowData) []string { var isDefault string if rowData.Default { - isDefault = views.ActiveStyle.Render("Yes") + isDefault = "Yes" } else { - isDefault = views.InactiveStyle.Render("/") + isDefault = "/" } return []string{ - views.NameStyle.Render(rowData.Name), - views.DefaultRowDataStyle.Render(rowData.Provider), - isDefault, - views.DefaultRowDataStyle.Render(rowData.WorkspaceCount), + fmt.Sprintf("%s %s", views.NameStyle.Render(rowData.Name), views.DefaultRowDataStyle.Render(fmt.Sprintf("(%s)", rowData.Provider))), views.DefaultRowDataStyle.Render(rowData.Options), + views.DefaultRowDataStyle.Render(rowData.WorkspaceCount), + isDefault, + rowData.Status, } } - -func SortTargets(targetList *[]apiclient.TargetDTO) { - sort.Slice(*targetList, func(i, j int) bool { - return (*targetList)[i].Default && !(*targetList)[j].Default - }) -} diff --git a/pkg/views/target/selection/target.go b/pkg/views/target/selection/target.go index a74e4f3a73..679d6c8bb8 100644 --- a/pkg/views/target/selection/target.go +++ b/pkg/views/target/selection/target.go @@ -13,6 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" list_view "github.com/daytonaio/daytona/pkg/views/target/list" + views_util "github.com/daytonaio/daytona/pkg/views/util" ) var NewTargetIdentifier = "" @@ -31,10 +32,17 @@ func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, wi providerName = target.ProviderInfo.Name } + stateLabel := views.GetStateLabel(target.State.Name) + + if target.Metadata != nil { + views_util.CheckAndAppendTimeLabel(&stateLabel, target.State, target.Metadata.Uptime) + } + newItem := item[apiclient.TargetDTO]{ title: target.Name, id: target.Id, desc: providerName, + state: stateLabel, target: &target, choiceProperty: target, } diff --git a/pkg/views/target/selection/view.go b/pkg/views/target/selection/view.go index 514b043c02..e9d364a6f0 100644 --- a/pkg/views/target/selection/view.go +++ b/pkg/views/target/selection/view.go @@ -35,12 +35,12 @@ var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). Render type item[T any] struct { - id, title, desc string - target *apiclient.TargetDTO - choiceProperty T - isMarked bool - isMultipleSelect bool - action string + id, title, desc, state string + target *apiclient.TargetDTO + choiceProperty T + isMarked bool + isMultipleSelect bool + action string } func (i item[T]) Title() string { @@ -55,6 +55,7 @@ func (i item[T]) Title() string { func (i item[T]) Id() string { return i.id } func (i item[T]) Description() string { return i.desc } +func (i item[T]) State() string { return i.state } func (i item[T]) FilterValue() string { return i.title } type model[T any] struct { @@ -153,11 +154,11 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) title := baseStyles.Render(i.Title()) - idWithTargetConfigString := i.Id() + idLabel := i.Id() if i.Id() == NewTargetIdentifier { - idWithTargetConfigString = "" + idLabel = "" } - idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + id := baseStyles.Foreground(views.Gray).Render(idLabel) description := baseStyles.Render(i.Description()) // Add the created/updated time if it's available @@ -165,20 +166,23 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l timeStyles := lipgloss.NewStyle(). Align(lipgloss.Right). Width(timeWidth) - timeString := timeStyles.Render("") + stateLabel := timeStyles.Render("") + if i.State() != "" { + stateLabel = timeStyles.Render(i.State()) + } // Adjust styles as the user moves through the menu if isSelected { title = selectedStyles.Foreground(views.Green).Render(i.Title()) - idWithTargetConfig = selectedStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + id = selectedStyles.Foreground(views.Gray).Render(idLabel) description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) - timeString = timeStyles.Foreground(views.DimmedGreen).Render(timeString) + stateLabel = timeStyles.Foreground(views.DimmedGreen).Render(stateLabel) } // Render to the terminal - s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, timeString)) + s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, stateLabel)) s.WriteRune('\n') - s.WriteString(idWithTargetConfig) + s.WriteString(id) s.WriteRune('\n') s.WriteString(description) s.WriteRune('\n') diff --git a/pkg/views/util/state_time.go b/pkg/views/util/state_time.go new file mode 100644 index 0000000000..b9779590df --- /dev/null +++ b/pkg/views/util/state_time.go @@ -0,0 +1,19 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "fmt" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apiclient" +) + +func CheckAndAppendTimeLabel(stateLabel *string, state apiclient.ResourceState, uptime int32) { + if state.Name == apiclient.ResourceStateNameStarted && uptime != 0 { + *stateLabel = fmt.Sprintf("%s (%s)", *stateLabel, util.FormatUptime(uptime)) + } else if state.Name == apiclient.ResourceStateNameStopped || state.Name == apiclient.ResourceStateNameUnresponsive || state.Name == apiclient.ResourceStateNameError { + *stateLabel = fmt.Sprintf("%s (%s)", *stateLabel, util.FormatTimestamp(state.UpdatedAt)) + } +} diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go index 4bea836aff..57d79fab3f 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/workspace/info/view.go @@ -11,6 +11,7 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" "golang.org/x/term" ) @@ -82,6 +83,7 @@ func renderTUIView(output string, width int, isCreationView bool) { fmt.Println(content) } +// TODO: migrate to the target info view func getSingleWorkspaceOutput(workspace *apiclient.WorkspaceDTO, isCreationView bool) string { var output string var repositoryUrl string @@ -90,12 +92,16 @@ func getSingleWorkspaceOutput(workspace *apiclient.WorkspaceDTO, isCreationView repositoryUrl = strings.TrimPrefix(repositoryUrl, "https://") repositoryUrl = strings.TrimPrefix(repositoryUrl, "http://") - if workspace.State != nil { - output += getInfoLineState("State", workspace.State) + "\n" - output += getInfoLineGitStatus("Branch", workspace.State.GitStatus) + "\n" + output += getInfoLineState("State", workspace.State, workspace.Metadata) + "\n" + if workspace.State.Error != nil { + output += getInfoLine("Error", *workspace.State.Error) + "\n" } - output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.State) + if workspace.Metadata != nil && workspace.Metadata.GitStatus != nil { + output += getInfoLineGitStatus("Branch", workspace.Metadata.GitStatus) + "\n" + } + + output += getInfoLinePrNumber(workspace.Repository.PrNumber, workspace.Repository, workspace.Metadata) if !isCreationView { output += getInfoLine("Target", fmt.Sprintf("%s (%s)", workspace.Target.Name, workspace.TargetId)) + "\n" @@ -110,69 +116,67 @@ func getInfoLine(key, value string) string { return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + propertyValueStyle.Render(value) + "\n" } -func getInfoLineState(key string, state *apiclient.WorkspaceState) string { - var uptime int - var stateProperty string +func getInfoLineState(key string, state apiclient.ResourceState, metadata *apiclient.WorkspaceMetadata) string { + stateLabel := views.GetStateLabel(state.Name) - if state == nil { - uptime = 0 - } else { - uptime = int(state.Uptime) + if metadata != nil { + views_util.CheckAndAppendTimeLabel(&stateLabel, state, metadata.Uptime) } - if uptime == 0 { - stateProperty = propertyValueStyle.Foreground(views.Gray).Render("STOPPED") - } else { - stateProperty = propertyValueStyle.Foreground(views.Green).Render("RUNNING") - } - - return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + stateProperty + propertyValueStyle.Foreground(views.Light).Render("\n") + return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + stateLabel + propertyValueStyle.Foreground(views.Light).Render("\n") } func getInfoLineGitStatus(key string, status *apiclient.GitStatus) string { output := propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) - output += propertyNameStyle.Foreground(views.Gray).Render(fmt.Sprintf("%-*s", propertyNameWidth, status.CurrentBranch)) - changesOutput := "" + if status == nil { + return output + propertyValueStyle.Foreground(views.Light).Render("\n") + } + + currentBranch := status.CurrentBranch + if status.CurrentBranch == "" { + currentBranch = "/" + } + + output += propertyNameStyle.Foreground(views.Gray).Render(currentBranch) + + detailsOutput := "" if status.FileStatus != nil { filesNum := len(status.FileStatus) if filesNum == 1 { - changesOutput = " (1 uncommitted change)" + detailsOutput = " (1 uncommitted change)" } else if filesNum > 1 { - changesOutput = fmt.Sprintf(" (%d uncommitted changes)", filesNum) + detailsOutput = fmt.Sprintf(" (%d uncommitted changes)", filesNum) } } - unpushedOutput := "" - if status.Ahead != nil && *status.Ahead > 0 { if *status.Ahead == 1 { - unpushedOutput += " (1 commit ahead)" + detailsOutput += " (1 commit ahead)" } else { - unpushedOutput += fmt.Sprintf(" (%d commits ahead)", *status.Ahead) + detailsOutput += fmt.Sprintf(" (%d commits ahead)", *status.Ahead) } } if status.Behind != nil && *status.Behind > 0 { if *status.Behind == 1 { - unpushedOutput += " (1 commit behind)" + detailsOutput += " (1 commit behind)" } else { - unpushedOutput += fmt.Sprintf(" (%d commits behind)", *status.Behind) + detailsOutput += fmt.Sprintf(" (%d commits behind)", *status.Behind) } } - branchPublishedOutput := "" if !*status.BranchPublished { - branchPublishedOutput = " (branch not published)" + detailsOutput += " (branch not published)" } - output += changesOutput + unpushedOutput + branchPublishedOutput + propertyValueStyle.Foreground(views.Light).Render("\n") + output += detailsOutput + propertyValueStyle.Foreground(views.Light).Render("\n") return output } -func getInfoLinePrNumber(PrNumber *int32, repo apiclient.GitRepository, state *apiclient.WorkspaceState) string { - if PrNumber != nil && (state == nil || state.GitStatus.CurrentBranch == repo.Branch) { +func getInfoLinePrNumber(PrNumber *int32, repo apiclient.GitRepository, metadata *apiclient.WorkspaceMetadata) string { + if PrNumber != nil && (metadata == nil || metadata.GitStatus.CurrentBranch == repo.Branch) { return getInfoLine("PR Number", fmt.Sprintf("#%d", *PrNumber)) + "\n" } return "" diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index 9e7437cc52..327271b13d 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -22,6 +22,7 @@ type RowData struct { Status string Created string Branch string + Uptime string } func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { @@ -50,12 +51,6 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders for value := range data { data[value] = data[value][:len(data[value])-2] } - } else { - // Temporarily hiding the branch column - headers = headers[:len(headers)-1] - for value := range data { - data[value] = data[value][:len(data[value])-1] - } } footer := lipgloss.NewStyle().Foreground(views.LightGray).Render(views.GetListFooter(activeProfileName, &views.Padding{})) @@ -67,6 +62,46 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders fmt.Println(table) } +func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { + sort.Slice(*workspaceList, func(i, j int) bool { + pi, ok := views.ResourceListStatePriorities[(*workspaceList)[i].State.Name] + if !ok { + pi = 99 + } + pj, ok2 := views.ResourceListStatePriorities[(*workspaceList)[j].State.Name] + if !ok2 { + pj = 99 + } + + if pi != pj { + return pi < pj + } + + // If two workspaces have the same state priority, compare the UpdatedAt property + return (*workspaceList)[i].State.UpdatedAt > (*workspaceList)[j].State.UpdatedAt + }) +} + +func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) *RowData { + rowData := RowData{"", "", "", "", "", "", ""} + rowData.Name = workspace.Name + views_util.AdditionalPropertyPadding + rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) + rowData.Branch = workspace.Repository.Branch + rowData.Status = views.GetStateLabel(workspace.State.Name) + + rowData.TargetName = workspace.Target.Name + views_util.AdditionalPropertyPadding + + if workspace.Info != nil { + rowData.Created = util.FormatTimestamp(workspace.Info.Created) + } + + if workspace.Metadata != nil { + views_util.CheckAndAppendTimeLabel(&rowData.Status, workspace.State, workspace.Metadata.Uptime) + } + + return &rowData +} + func renderUnstyledList(workspaceList []apiclient.WorkspaceDTO) { for _, target := range workspaceList { info_view.Render(&target, "", true) @@ -79,13 +114,6 @@ func renderUnstyledList(workspaceList []apiclient.WorkspaceDTO) { } func getRowFromRowData(rowData RowData, isMultiWorkspaceAccordion bool) []string { - var state string - if rowData.Status == "" { - state = views.InactiveStyle.Render("STOPPED") - } else { - state = views.ActiveStyle.Render("RUNNING") - } - if isMultiWorkspaceAccordion { return []string{rowData.Name, "", "", "", "", ""} } @@ -94,54 +122,10 @@ func getRowFromRowData(rowData RowData, isMultiWorkspaceAccordion bool) []string views.NameStyle.Render(rowData.Name), views.DefaultRowDataStyle.Render(rowData.Repository), views.DefaultRowDataStyle.Render(rowData.TargetName), - state, + rowData.Status, views.DefaultRowDataStyle.Render(rowData.Created), views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(rowData.Branch)), } - if rowData.Status != "" { - row[3] = fmt.Sprintf("%s %s", state, views.DefaultRowDataStyle.Render(fmt.Sprintf("(%s)", rowData.Status))) - } - return row } - -func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { - if verbose { - sort.Slice(*workspaceList, func(i, j int) bool { - w1 := (*workspaceList)[i] - w2 := (*workspaceList)[j] - if w1.Info == nil || w2.Info == nil { - return true - } - return w1.Info.Created > w2.Info.Created - }) - return - } - - sort.Slice(*workspaceList, func(i, j int) bool { - w1 := (*workspaceList)[i] - w2 := (*workspaceList)[j] - if w1.State == nil || w2.State == nil { - return true - } - return w1.State.Uptime < w2.State.Uptime - }) -} - -func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) *RowData { - rowData := RowData{"", "", "", "", "", ""} - rowData.Name = workspace.Name + views_util.AdditionalPropertyPadding - rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) - rowData.Branch = workspace.Repository.Branch - - rowData.TargetName = workspace.Target.Name + views_util.AdditionalPropertyPadding - - if workspace.Info != nil { - rowData.Created = util.FormatTimestamp(workspace.Info.Created) - } - if workspace.State != nil && workspace.State.Uptime > 0 { - rowData.Status = util.FormatUptime(workspace.State.Uptime) - } - return &rowData -} diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/workspace/selection/view.go index b41396fd6c..b536cbdfd3 100644 --- a/pkg/views/workspace/selection/view.go +++ b/pkg/views/workspace/selection/view.go @@ -35,12 +35,12 @@ var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). Render type item[T any] struct { - id, title, desc, targetName, repository, createdTime, uptime string - workspace *apiclient.WorkspaceDTO - choiceProperty T - isMarked bool - isMultipleSelect bool - action string + id, title, desc, targetName, repository, createdTime, state string + workspace *apiclient.WorkspaceDTO + choiceProperty T + isMarked bool + isMultipleSelect bool + action string } func (i item[T]) Title() string { return i.title } @@ -49,7 +49,7 @@ func (i item[T]) Description() string { return i.desc } func (i item[T]) TargetName() string { return i.targetName } func (i item[T]) Repository() string { return i.repository } func (i item[T]) CreatedTime() string { return i.createdTime } -func (i item[T]) Uptime() string { return i.uptime } +func (i item[T]) State() string { return i.state } func (i item[T]) FilterValue() string { return i.title } type model[T any] struct { @@ -148,11 +148,11 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) title := baseStyles.Render(i.Title()) - idWithTargetConfigString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetName()) + idWithTargetString := fmt.Sprintf("%s (%s)", i.Id(), i.TargetName()) if i.Id() == NewWorkspaceIdentifier { - idWithTargetConfigString = "" + idWithTargetString = "" } - idWithTargetConfig := baseStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + idWithTarget := baseStyles.Foreground(views.Gray).Render(idWithTargetString) repository := baseStyles.Foreground(views.DimmedGreen).Render(i.Repository()) description := baseStyles.Render(i.Description()) @@ -161,26 +161,24 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l timeStyles := lipgloss.NewStyle(). Align(lipgloss.Right). Width(timeWidth) - timeString := timeStyles.Render("") - if i.Uptime() != "" { - timeString = timeStyles.Render(i.Uptime()) - } else if i.CreatedTime() != "" { - timeString = timeStyles.Render(fmt.Sprintf("created %s", i.CreatedTime())) + stateLabel := timeStyles.Render("") + if i.State() != "" { + stateLabel = timeStyles.Render(i.State()) } // Adjust styles as the user moves through the menu if isSelected { title = selectedStyles.Foreground(views.Green).Render(i.Title()) - idWithTargetConfig = selectedStyles.Foreground(views.Gray).Render(idWithTargetConfigString) + idWithTarget = selectedStyles.Foreground(views.Gray).Render(idWithTargetString) repository = selectedStyles.Foreground(views.DimmedGreen).Render(i.Repository()) description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) - timeString = timeStyles.Foreground(views.DimmedGreen).Render(timeString) + stateLabel = timeStyles.Foreground(views.DimmedGreen).Render(stateLabel) } // Render to the terminal - s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, timeString)) + s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, title, stateLabel)) s.WriteRune('\n') - s.WriteString(idWithTargetConfig) + s.WriteString(idWithTarget) s.WriteRune('\n') s.WriteString(repository) s.WriteRune('\n') diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go index 4ce5ddb217..bf09b87293 100644 --- a/pkg/views/workspace/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -13,6 +13,7 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + views_util "github.com/daytonaio/daytona/pkg/views/util" list_view "github.com/daytonaio/daytona/pkg/views/workspace/list" ) @@ -30,19 +31,16 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect } // Get the time if available - uptime := "" createdTime := "" if workspace.Info != nil { createdTime = util.FormatTimestamp(workspace.Info.Created) } - if workspace.State != nil { - if workspace.State.Uptime == 0 { - uptime = "STOPPED" - } else { - uptime = fmt.Sprintf("up %s", util.FormatUptime(workspace.State.Uptime)) - } + stateLabel := views.GetStateLabel(workspace.State.Name) + + if workspace.Metadata != nil { + views_util.CheckAndAppendTimeLabel(&stateLabel, workspace.State, workspace.Metadata.Uptime) } newItem := item[apiclient.WorkspaceDTO]{ @@ -52,7 +50,7 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect targetName: workspace.Target.Name, repository: workspace.Repository.Url, createdTime: createdTime, - uptime: uptime, + state: stateLabel, workspace: &workspace, choiceProperty: workspace, } From 56b87459147eae7cec592fa00dc9371151a3bf08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 28 Nov 2024 12:54:55 +0100 Subject: [PATCH 11/76] fix: implement correct multi-create output (#1368) Signed-off-by: Luka Brecic --- pkg/api/controllers/workspace/create.go | 2 +- pkg/api/docs/docs.go | 2 +- pkg/api/docs/swagger.json | 2 +- pkg/api/docs/swagger.yaml | 2 +- pkg/apiclient/api/openapi.yaml | 2 +- pkg/apiclient/api_workspace.go | 8 ++--- pkg/apiclient/docs/WorkspaceAPI.md | 6 ++-- pkg/cmd/workspace/create/cmd.go | 20 +++++++---- pkg/server/workspaces/create.go | 15 ++++++--- pkg/server/workspaces/service_test.go | 4 +-- pkg/services/workspace.go | 2 +- pkg/views/workspace/info/multi.go | 45 +++++++++++++++++++++++++ pkg/views/workspace/list/view.go | 6 ++-- 13 files changed, 88 insertions(+), 28 deletions(-) create mode 100644 pkg/views/workspace/info/multi.go diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go index 89ca5481ea..00fd241576 100644 --- a/pkg/api/controllers/workspace/create.go +++ b/pkg/api/controllers/workspace/create.go @@ -19,7 +19,7 @@ import ( // @Description Create a workspace // @Param workspace body CreateWorkspaceDTO true "Create workspace" // @Produce json -// @Success 200 {object} Workspace +// @Success 200 {object} WorkspaceDTO // @Router /workspace [post] // // @id CreateWorkspace diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 39f2e87599..d569de1e15 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1537,7 +1537,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/Workspace" + "$ref": "#/definitions/WorkspaceDTO" } } } diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index b86be7b410..954c2d1842 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1534,7 +1534,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/Workspace" + "$ref": "#/definitions/WorkspaceDTO" } } } diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index f13b15ba0f..b6a545364b 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -2521,7 +2521,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/Workspace' + $ref: '#/definitions/WorkspaceDTO' summary: Create a workspace tags: - workspace diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index a6d0617d33..550ffda70a 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -1094,7 +1094,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Workspace' + $ref: '#/components/schemas/WorkspaceDTO' description: OK summary: Create a workspace tags: diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index 7f11fd32f7..56f533a7a3 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -34,7 +34,7 @@ func (r ApiCreateWorkspaceRequest) Workspace(workspace CreateWorkspaceDTO) ApiCr return r } -func (r ApiCreateWorkspaceRequest) Execute() (*Workspace, *http.Response, error) { +func (r ApiCreateWorkspaceRequest) Execute() (*WorkspaceDTO, *http.Response, error) { return r.ApiService.CreateWorkspaceExecute(r) } @@ -55,13 +55,13 @@ func (a *WorkspaceAPIService) CreateWorkspace(ctx context.Context) ApiCreateWork // Execute executes the request // -// @return Workspace -func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest) (*Workspace, *http.Response, error) { +// @return WorkspaceDTO +func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest) (*WorkspaceDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile - localVarReturnValue *Workspace + localVarReturnValue *WorkspaceDTO ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.CreateWorkspace") diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 3cdb2b3bf7..8b6e6e494a 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -16,7 +16,7 @@ Method | HTTP request | Description ## CreateWorkspace -> Workspace CreateWorkspace(ctx).Workspace(workspace).Execute() +> WorkspaceDTO CreateWorkspace(ctx).Workspace(workspace).Execute() Create a workspace @@ -44,7 +44,7 @@ func main() { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.CreateWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `CreateWorkspace`: Workspace + // response from `CreateWorkspace`: WorkspaceDTO fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.CreateWorkspace`: %v\n", resp) } ``` @@ -64,7 +64,7 @@ Name | Type | Description | Notes ### Return type -[**Workspace**](Workspace.md) +[**WorkspaceDTO**](WorkspaceDTO.md) ### Authorization diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index a018cbd44a..59fc4f13a5 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -219,7 +219,7 @@ var CreateCmd = &cobra.Command{ SkipPrefixLengthSetup: true, }) - _, res, err = apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(createWorkspaceDtos[i]).Execute() + _, res, err := apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(createWorkspaceDtos[i]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -264,12 +264,20 @@ var CreateCmd = &cobra.Command{ fmt.Println() - ws, _, err := apiclient_util.GetWorkspace(createWorkspaceDtos[0].Id, true) - if err != nil { - return err + createdWorkspaces := []apiclient.WorkspaceDTO{} + for _, createWorkspaceDto := range createWorkspaceDtos { + ws, _, err := apiclient_util.GetWorkspace(createWorkspaceDto.Id, true) + if err != nil { + return err + } + createdWorkspaces = append(createdWorkspaces, *ws) } - info.Render(ws, chosenIde.Name, false) + if len(createdWorkspaces) > 1 { + info.RenderMulti(createdWorkspaces, chosenIde.Name, false) + } else { + info.Render(&createdWorkspaces[0], chosenIde.Name, false) + } if noIdeFlag { views.RenderCreationInfoMessage("Run 'daytona code' when you're ready to start developing") @@ -278,7 +286,7 @@ var CreateCmd = &cobra.Command{ views.RenderCreationInfoMessage(fmt.Sprintf("Opening the workspace in %s ...", chosenIde.Name)) - return cmd_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *ws.Info.ProviderMetadata, YesFlag, gpgKey) + return cmd_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *createdWorkspaces[0].Info.ProviderMetadata, YesFlag, gpgKey) }, } diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index a99d098ec7..7d4a294a9a 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -17,7 +17,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.CreateWorkspaceDTO) (*models.Workspace, error) { +func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.CreateWorkspaceDTO) (*services.WorkspaceDTO, error) { _, err := s.workspaceStore.Find(req.Name) if err == nil { return s.handleCreateError(ctx, nil, services.ErrWorkspaceAlreadyExists) @@ -111,15 +111,19 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre } err = s.createJob(ctx, w.Id, models.JobActionCreate) + return s.handleCreateError(ctx, w, err) } -func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Workspace, err error) (*models.Workspace, error) { +func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Workspace, err error) (*services.WorkspaceDTO, error) { if !telemetry.TelemetryEnabled(ctx) { if w == nil { return nil, err } - return w, err + return &services.WorkspaceDTO{ + Workspace: *w, + State: w.GetState(), + }, err } clientId := telemetry.ClientId(ctx) @@ -139,7 +143,10 @@ func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Work return nil, err } - return w, err + return &services.WorkspaceDTO{ + Workspace: *w, + State: w.GetState(), + }, err } func isValidWorkspaceName(name string) bool { diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 9904d7b9e3..a36f0b57cc 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -213,7 +213,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, workspace) - workspaceEquals(t, ws, workspace, defaultWorkspaceImage) + workspaceEquals(t, &services.WorkspaceDTO{Workspace: *ws}, workspace, defaultWorkspaceImage) ws.EnvVars = nil }) @@ -340,7 +340,7 @@ func TestTargetService(t *testing.T) { }) } -func workspaceEquals(t *testing.T, ws1, ws2 *models.Workspace, workspaceImage string) { +func workspaceEquals(t *testing.T, ws1, ws2 *services.WorkspaceDTO, workspaceImage string) { t.Helper() require.Equal(t, ws1.Id, ws2.Id) diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 636d84f2e7..389b3e9791 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -13,7 +13,7 @@ import ( ) type IWorkspaceService interface { - CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*models.Workspace, error) + CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*WorkspaceDTO, error) GetWorkspace(ctx context.Context, workspaceId string, params WorkspaceRetrievalParams) (*WorkspaceDTO, error) ListWorkspaces(ctx context.Context, params WorkspaceRetrievalParams) ([]WorkspaceDTO, error) StartWorkspace(ctx context.Context, workspaceId string) error diff --git a/pkg/views/workspace/info/multi.go b/pkg/views/workspace/info/multi.go new file mode 100644 index 0000000000..c0845ebf64 --- /dev/null +++ b/pkg/views/workspace/info/multi.go @@ -0,0 +1,45 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package info + +import ( + "fmt" + "os" + + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +func RenderMulti(workspaces []apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { + var output string + + output += "\n" + + output += getInfoLine("Using Target", workspaces[0].Target.Name) + "\n" + output += getInfoLine("Target ID", workspaces[0].TargetId) + "\n" + + output += getInfoLine("Editor", ide) + "\n" + + terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + fmt.Println(output) + return + } + if terminalWidth < views.TUITableMinimumWidth || forceUnstyled { + renderUnstyledInfo(output) + return + } + + output += fmt.Sprintf("%s\n\n", views.SeparatorString) + for index, workspace := range workspaces { + output += getInfoLine(fmt.Sprintf("Workspace #%d", index+1), fmt.Sprintf("%s (%s)", workspace.Name, workspace.Id)) + "\n" + output += getSingleWorkspaceOutput(&workspace, true) + if index < len(workspaces)-1 { + output += fmt.Sprintf("\n%s\n\n", views.SeparatorString) + } + } + + renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth), true) +} diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index 327271b13d..f567ed4709 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -103,10 +103,10 @@ func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) } func renderUnstyledList(workspaceList []apiclient.WorkspaceDTO) { - for _, target := range workspaceList { - info_view.Render(&target, "", true) + for _, workspace := range workspaceList { + info_view.Render(&workspace, "", true) - if target.Id != workspaceList[len(workspaceList)-1].Id { + if workspace.Id != workspaceList[len(workspaceList)-1].Id { fmt.Printf("\n%s\n\n", views.SeparatorString) } From 9aaaedb7644f6e22fa4a7ebaedb7fbed92675a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 28 Nov 2024 12:56:24 +0100 Subject: [PATCH 12/76] refactor: add workspace deletion option to target removal (#1333) Signed-off-by: Luka Brecic --- docs/daytona_target_delete.md | 2 +- hack/docs/daytona_target_delete.yaml | 2 +- pkg/cmd/common/delete_workspace.go | 51 ++++++++++ pkg/cmd/target/delete.go | 143 ++++++++++++++++----------- pkg/cmd/target/list.go | 3 +- pkg/cmd/workspace/delete.go | 44 +-------- 6 files changed, 145 insertions(+), 100 deletions(-) create mode 100644 pkg/cmd/common/delete_workspace.go diff --git a/docs/daytona_target_delete.md b/docs/daytona_target_delete.md index ebaef073a3..6400ed112b 100644 --- a/docs/daytona_target_delete.md +++ b/docs/daytona_target_delete.md @@ -3,7 +3,7 @@ Delete a target ``` -daytona target delete [TARGET] [flags] +daytona target delete [TARGET]... [flags] ``` ### Options diff --git a/hack/docs/daytona_target_delete.yaml b/hack/docs/daytona_target_delete.yaml index e077d4a81b..aae2fa1900 100644 --- a/hack/docs/daytona_target_delete.yaml +++ b/hack/docs/daytona_target_delete.yaml @@ -1,6 +1,6 @@ name: daytona target delete synopsis: Delete a target -usage: daytona target delete [TARGET] [flags] +usage: daytona target delete [TARGET]... [flags] options: - name: all shorthand: a diff --git a/pkg/cmd/common/delete_workspace.go b/pkg/cmd/common/delete_workspace.go new file mode 100644 index 0000000000..5d03a2dc36 --- /dev/null +++ b/pkg/cmd/common/delete_workspace.go @@ -0,0 +1,51 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "context" + "fmt" + + "github.com/daytonaio/daytona/cmd/daytona/config" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + views_util "github.com/daytonaio/daytona/pkg/views/util" +) + +func DeleteWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspaceId, workspaceName string, force bool) error { + message := fmt.Sprintf("Deleting workspace %s", workspaceName) + err := views_util.WithInlineSpinner(message, func() error { + res, err := apiClient.WorkspaceAPI.RemoveWorkspace(ctx, workspaceId).Force(force).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspaceId) + if err != nil { + return err + } + + err = AwaitWorkspaceDeleted(workspaceId) + if err != nil { + return err + } + + return nil + }) + + if err != nil { + return err + } + + return nil +} diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index bbff2261fd..c5a34a90a5 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -11,7 +11,7 @@ import ( "github.com/charmbracelet/huh" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -23,7 +23,7 @@ var yesFlag bool var forceFlag bool var deleteCmd = &cobra.Command{ - Use: "delete [TARGET]", + Use: "delete [TARGET]...", Short: "Delete a target", Aliases: []string{"remove", "rm"}, RunE: func(cmd *cobra.Command, args []string) error { @@ -36,43 +36,8 @@ var deleteCmd = &cobra.Command{ return err } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - if allFlag { - if yesFlag { - fmt.Println("Deleting all targets.") - err := DeleteAllTargets(workspaceList, forceFlag) - if err != nil { - return err - } - } else { - form := huh.NewForm( - huh.NewGroup( - huh.NewConfirm(). - Title("Delete all targets?"). - Description("Are you sure you want to delete all targets?"). - Value(&yesFlag), - ), - ).WithTheme(views.GetCustomTheme()) - - err := form.Run() - if err != nil { - return err - } - - if yesFlag { - err := DeleteAllTargets(workspaceList, forceFlag) - if err != nil { - return err - } - } else { - fmt.Println("Operation canceled.") - } - } - return nil + return deleteAllTargetsView(ctx, apiClient) } if len(args) == 0 { @@ -106,13 +71,15 @@ var deleteCmd = &cobra.Command{ return nil } + var deleteTargetsFlag bool + if !yesFlag { form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). Title(fmt.Sprintf("Delete target(s): [%s]?", strings.Join(targetDeleteListNames, ", "))). Description(fmt.Sprintf("Are you sure you want to delete the target(s): [%s]?", strings.Join(targetDeleteListNames, ", "))). - Value(&yesFlag), + Value(&deleteTargetsFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -122,11 +89,11 @@ var deleteCmd = &cobra.Command{ } } - if !yesFlag { + if !yesFlag && !deleteTargetsFlag { fmt.Println("Operation canceled.") } else { for _, target := range targetDeleteList { - err := DeleteTarget(ctx, apiClient, target, workspaceList, forceFlag) + err := deleteTarget(ctx, apiClient, target) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", target.Name, err)) } else { @@ -147,20 +114,51 @@ func init() { deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a target by force") } -func DeleteAllTargets(workspaceList []apiclient.WorkspaceDTO, force bool) error { - ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err +func deleteAllTargetsView(ctx context.Context, apiClient *apiclient.APIClient) error { + var deleteAllTargetsFlag bool + + if yesFlag { + fmt.Println("Deleting all targets.") + err := deleteAllTargets(ctx, apiClient) + if err != nil { + return err + } + } else { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Delete all targets?"). + Description("Are you sure you want to delete all targets?"). + Value(&deleteAllTargetsFlag), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + + if deleteAllTargetsFlag { + err := deleteAllTargets(ctx, apiClient) + if err != nil { + return err + } + } else { + fmt.Println("Operation canceled.") + } } + return nil +} + +func deleteAllTargets(ctx context.Context, apiClient *apiclient.APIClient) error { targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } for _, target := range targetList { - err := DeleteTarget(ctx, apiClient, &target, workspaceList, force) + err := deleteTarget(ctx, apiClient, &target) if err != nil { log.Errorf("Failed to delete target %s: %v", target.Name, err) continue @@ -170,21 +168,22 @@ func DeleteAllTargets(workspaceList []apiclient.WorkspaceDTO, force bool) error return nil } -func DeleteTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO, workspaceList []apiclient.WorkspaceDTO, force bool) error { - for _, workspace := range workspaceList { - if workspace.TargetId == target.Id { - return fmt.Errorf("target '%s' is in use by workspace '%s', please remove workspaces before deleting their target", target.Name, workspace.Name) +func deleteTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO) error { + if len(target.Workspaces) > 0 { + err := deleteWorkspacesForTarget(ctx, apiClient, target) + if err != nil { + return err } } message := fmt.Sprintf("Deleting target %s", target.Name) err := views_util.WithInlineSpinner(message, func() error { - res, err := apiClient.TargetAPI.RemoveTarget(ctx, target.Id).Force(force).Execute() + res, err := apiClient.TargetAPI.RemoveTarget(ctx, target.Id).Force(forceFlag).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - err = cmd_common.AwaitTargetDeleted(target.Id) + err = common.AwaitTargetDeleted(target.Id) if err != nil { return err } @@ -192,8 +191,42 @@ func DeleteTarget(ctx context.Context, apiClient *apiclient.APIClient, target *a return nil }) - if err != nil { - return err + return err +} + +func deleteWorkspacesForTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO) error { + var deleteWorkspacesFlag bool + + var targetWorkspacesNames []string + for _, workspace := range target.Workspaces { + targetWorkspacesNames = append(targetWorkspacesNames, workspace.Name) + } + + if !yesFlag { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title(fmt.Sprintf("Target '%s' is used by %d workspace(s). Delete workspaces: [%s]?", target.Name, len(target.Workspaces), strings.Join(targetWorkspacesNames, ", "))). + Description(fmt.Sprintf("Do you want to delete workspace(s): [%s]?", strings.Join(targetWorkspacesNames, ", "))). + Value(&deleteWorkspacesFlag), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + } + + if yesFlag || deleteWorkspacesFlag { + for _, workspace := range target.Workspaces { + err := common.DeleteWorkspace(ctx, apiClient, workspace.Id, workspace.Name, forceFlag) + if err != nil { + log.Errorf("Failed to delete workspace %s: %v", workspace.Name, err) + continue + } + views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully deleted", workspace.Name)) + } } return nil diff --git a/pkg/cmd/target/list.go b/pkg/cmd/target/list.go index b2b2662393..f7108bf637 100644 --- a/pkg/cmd/target/list.go +++ b/pkg/cmd/target/list.go @@ -8,7 +8,6 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util/apiclient" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" list_view "github.com/daytonaio/daytona/pkg/views/target/list" "github.com/spf13/cobra" @@ -24,7 +23,7 @@ var listCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) + apiClient, err := apiclient.GetApiClient(nil) if err != nil { return err } diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index 4e60a8ceff..3a1f589641 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -9,12 +9,10 @@ import ( "strings" "github.com/charmbracelet/huh" - "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" - cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -124,9 +122,10 @@ var DeleteCmd = &cobra.Command{ fmt.Println("Operation canceled.") } else { for _, workspace := range workspaceDeleteList { - err := DeleteWorkspace(ctx, apiClient, workspace, forceFlag) + err := common.DeleteWorkspace(ctx, apiClient, workspace.Id, workspace.Name, forceFlag) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", workspace.Name, err)) + continue } views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully deleted", workspace.Name)) } @@ -157,7 +156,7 @@ func DeleteAllWorkspaces(force bool) error { } for _, workspace := range workspaceList { - err := DeleteWorkspace(ctx, apiClient, &workspace, force) + err := common.DeleteWorkspace(ctx, apiClient, workspace.Id, workspace.Name, force) if err != nil { log.Errorf("Failed to delete workspace %s: %v", workspace.Name, err) continue @@ -166,40 +165,3 @@ func DeleteAllWorkspaces(force bool) error { } return nil } - -func DeleteWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspace *apiclient.WorkspaceDTO, force bool) error { - message := fmt.Sprintf("Deleting workspace %s", workspace.Name) - err := views_util.WithInlineSpinner(message, func() error { - res, err := apiClient.WorkspaceAPI.RemoveWorkspace(ctx, workspace.Id).Force(force).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspace.Id) - if err != nil { - return err - } - - err = cmd_common.AwaitWorkspaceDeleted(workspace.Id) - if err != nil { - return err - } - - return nil - }) - - if err != nil { - return err - } - - return nil -} From 8476d9cf52d6fb1d64466c8c44294bdfaf89065b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 28 Nov 2024 13:08:12 +0100 Subject: [PATCH 13/76] refactor: add target config reference to target (#1340) Signed-off-by: Luka Brecic --- docs/daytona_target-config.md | 2 +- ...ig_set.md => daytona_target-config_add.md} | 6 +- docs/daytona_target-config_remove.md | 2 +- hack/docs/daytona_target-config.yaml | 2 +- ...et.yaml => daytona_target-config_add.yaml} | 6 +- hack/docs/daytona_target-config_remove.yaml | 2 +- .../testing/server/targetconfigs/store.go | 45 +++-- .../apiclient/conversion/target_config.go | 17 -- pkg/agent/agent_test.go | 11 +- pkg/api/controllers/target/create.go | 6 +- pkg/api/controllers/target/target.go | 12 +- .../targetconfig/{set.go => add.go} | 21 +-- pkg/api/controllers/targetconfig/list.go | 2 +- pkg/api/controllers/targetconfig/remove.go | 17 +- pkg/api/docs/docs.go | 94 ++++----- pkg/api/docs/swagger.json | 94 ++++----- pkg/api/docs/swagger.yaml | 72 +++---- pkg/api/server.go | 2 +- pkg/apiclient/README.md | 6 +- pkg/apiclient/api/openapi.yaml | 178 +++++++++++------- pkg/apiclient/api_target_config.go | 174 ++++++++--------- ...rgetConfigDTO.md => AddTargetConfigDTO.md} | 32 ++-- pkg/apiclient/docs/Target.md | 42 ++--- pkg/apiclient/docs/TargetConfig.md | 44 ++++- pkg/apiclient/docs/TargetConfigAPI.md | 86 ++++----- pkg/apiclient/docs/TargetDTO.md | 60 +++--- ..._dto.go => model_add_target_config_dto.go} | 72 +++---- pkg/apiclient/model_target.go | 73 ++++--- pkg/apiclient/model_target_config.go | 60 +++++- pkg/apiclient/model_target_dto.go | 97 +++++----- pkg/cmd/cmd.go | 2 +- pkg/cmd/provider/install.go | 5 +- pkg/cmd/provider/list.go | 11 +- pkg/cmd/provider/uninstall.go | 5 +- .../server/bootstrap/get_server_instance.go | 2 +- .../server/bootstrap/init_provider_manager.go | 10 +- pkg/cmd/target/create.go | 4 +- pkg/cmd/targetconfig/{set.go => add.go} | 66 ++----- pkg/cmd/targetconfig/remove.go | 2 +- pkg/cmd/targetconfig/target_config.go | 2 +- pkg/cmd/workspace/create/cmd.go | 14 +- pkg/db/target_config_store.go | 28 +-- pkg/db/workspace_store.go | 3 +- pkg/docker/client_test.go | 11 +- pkg/docker/info_test.go | 13 +- pkg/models/target.go | 23 ++- pkg/models/target_config.go | 4 +- pkg/provider/manager/manager.go | 13 +- pkg/provisioner/create.go | 4 +- pkg/provisioner/destroy.go | 4 +- pkg/provisioner/info.go | 4 +- pkg/provisioner/start.go | 4 +- pkg/provisioner/stop.go | 4 +- pkg/server/targetconfigs/dto/target_config.go | 12 -- pkg/server/targetconfigs/service.go | 41 +++- pkg/server/targetconfigs/service_test.go | 38 ++-- pkg/server/targets/create.go | 8 +- pkg/server/targets/service_test.go | 34 ++-- pkg/server/targets/set-default.go | 10 +- pkg/server/workspaces/service_test.go | 17 +- pkg/services/target_config.go | 15 +- pkg/stores/target_config.go | 12 +- pkg/telemetry/server_events.go | 8 +- pkg/views/target/info/view.go | 13 +- pkg/views/target/list/view.go | 8 +- pkg/views/target/selection/target.go | 6 +- pkg/views/targetconfig/list.go | 5 + pkg/views/targetconfig/select.go | 1 + 68 files changed, 971 insertions(+), 832 deletions(-) rename docs/{daytona_target-config_set.md => daytona_target-config_add.md} (69%) rename hack/docs/{daytona_target-config_set.yaml => daytona_target-config_add.yaml} (60%) delete mode 100644 internal/util/apiclient/conversion/target_config.go rename pkg/api/controllers/targetconfig/{set.go => add.go} (65%) rename pkg/apiclient/docs/{CreateTargetConfigDTO.md => AddTargetConfigDTO.md} (63%) rename pkg/apiclient/{model_create_target_config_dto.go => model_add_target_config_dto.go} (58%) rename pkg/cmd/targetconfig/{set.go => add.go} (84%) delete mode 100644 pkg/server/targetconfigs/dto/target_config.go diff --git a/docs/daytona_target-config.md b/docs/daytona_target-config.md index 36cfd077a5..e5a6b3b900 100644 --- a/docs/daytona_target-config.md +++ b/docs/daytona_target-config.md @@ -11,7 +11,7 @@ Manage target configs ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona target-config add](daytona_target-config_add.md) - Add target config * [daytona target-config list](daytona_target-config_list.md) - List target configs * [daytona target-config remove](daytona_target-config_remove.md) - Remove target config -* [daytona target-config set](daytona_target-config_set.md) - Set target config diff --git a/docs/daytona_target-config_set.md b/docs/daytona_target-config_add.md similarity index 69% rename from docs/daytona_target-config_set.md rename to docs/daytona_target-config_add.md index fb453a3699..9d30d21acb 100644 --- a/docs/daytona_target-config_set.md +++ b/docs/daytona_target-config_add.md @@ -1,9 +1,9 @@ -## daytona target-config set +## daytona target-config add -Set target config +Add target config ``` -daytona target-config set [flags] +daytona target-config add [flags] ``` ### Options inherited from parent commands diff --git a/docs/daytona_target-config_remove.md b/docs/daytona_target-config_remove.md index aebe62cfb7..d21ed4565f 100644 --- a/docs/daytona_target-config_remove.md +++ b/docs/daytona_target-config_remove.md @@ -3,7 +3,7 @@ Remove target config ``` -daytona target-config remove [CONFIG_NAME] [flags] +daytona target-config remove [TARGET_CONFIG] [flags] ``` ### Options diff --git a/hack/docs/daytona_target-config.yaml b/hack/docs/daytona_target-config.yaml index cbbecaca5b..e62d7f6e63 100644 --- a/hack/docs/daytona_target-config.yaml +++ b/hack/docs/daytona_target-config.yaml @@ -6,6 +6,6 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager + - daytona target-config add - Add target config - daytona target-config list - List target configs - daytona target-config remove - Remove target config - - daytona target-config set - Set target config diff --git a/hack/docs/daytona_target-config_set.yaml b/hack/docs/daytona_target-config_add.yaml similarity index 60% rename from hack/docs/daytona_target-config_set.yaml rename to hack/docs/daytona_target-config_add.yaml index 21c4fa5447..6a7dee27aa 100644 --- a/hack/docs/daytona_target-config_set.yaml +++ b/hack/docs/daytona_target-config_add.yaml @@ -1,6 +1,6 @@ -name: daytona target-config set -synopsis: Set target config -usage: daytona target-config set [flags] +name: daytona target-config add +synopsis: Add target config +usage: daytona target-config add [flags] inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_target-config_remove.yaml b/hack/docs/daytona_target-config_remove.yaml index 8ee216a64d..99df880375 100644 --- a/hack/docs/daytona_target-config_remove.yaml +++ b/hack/docs/daytona_target-config_remove.yaml @@ -1,6 +1,6 @@ name: daytona target-config remove synopsis: Remove target config -usage: daytona target-config remove [CONFIG_NAME] [flags] +usage: daytona target-config remove [TARGET_CONFIG] [flags] options: - name: "yes" shorthand: "y" diff --git a/internal/testing/server/targetconfigs/store.go b/internal/testing/server/targetconfigs/store.go index 9dab10ce14..20088289de 100644 --- a/internal/testing/server/targetconfigs/store.go +++ b/internal/testing/server/targetconfigs/store.go @@ -6,8 +6,6 @@ package targetconfigs import ( - "fmt" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) @@ -22,12 +20,12 @@ func NewInMemoryTargetConfigStore() stores.TargetConfigStore { } } -func (s *InMemoryTargetConfigStore) List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { - return s.processFilters(filter) +func (s *InMemoryTargetConfigStore) List(allowDeleted bool) ([]*models.TargetConfig, error) { + return s.processFilters("", allowDeleted) } -func (s *InMemoryTargetConfigStore) Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) { - targets, err := s.processFilters(filter) +func (s *InMemoryTargetConfigStore) Find(idOrName string, allowDeleted bool) (*models.TargetConfig, error) { + targets, err := s.processFilters(idOrName, allowDeleted) if err != nil { return nil, err } @@ -40,31 +38,32 @@ func (s *InMemoryTargetConfigStore) Find(filter *stores.TargetConfigFilter) (*mo } func (s *InMemoryTargetConfigStore) Save(targetConfig *models.TargetConfig) error { - s.targetConfigs[targetConfig.Name] = targetConfig - return nil -} - -func (s *InMemoryTargetConfigStore) Delete(targetConfig *models.TargetConfig) error { - delete(s.targetConfigs, targetConfig.Name) + s.targetConfigs[targetConfig.Id] = targetConfig return nil } -func (s *InMemoryTargetConfigStore) processFilters(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) processFilters(idOrName string, allowDeleted bool) ([]*models.TargetConfig, error) { var result []*models.TargetConfig - if filter != nil { - if filter.Name != nil { - t, ok := s.targetConfigs[*filter.Name] - if ok { - return []*models.TargetConfig{t}, nil - } else { - return nil, fmt.Errorf("target config with id or name %s not found", *filter.Name) - } + if idOrName != "" { + t, ok := s.targetConfigs[idOrName] + if ok { + result = append(result, t) + } + } else { + for _, targetConfig := range s.targetConfigs { + result = append(result, targetConfig) } } - for _, targetConfig := range s.targetConfigs { - result = append(result, targetConfig) + if !allowDeleted { + notDeleted := []*models.TargetConfig{} + for _, targetConfig := range result { + if !targetConfig.Deleted { + notDeleted = append(notDeleted, targetConfig) + } + } + result = notDeleted } return result, nil diff --git a/internal/util/apiclient/conversion/target_config.go b/internal/util/apiclient/conversion/target_config.go deleted file mode 100644 index 91a9931e2c..0000000000 --- a/internal/util/apiclient/conversion/target_config.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package conversion - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" -) - -func ToTargetConfig(createTargetConfigDto dto.CreateTargetConfigDTO) *models.TargetConfig { - return &models.TargetConfig{ - Name: createTargetConfigDto.Name, - ProviderInfo: createTargetConfigDto.ProviderInfo, - Options: createTargetConfigDto.Options, - } -} diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 86cb4bb395..b0fed0e520 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -34,14 +34,21 @@ var workspace1 = &models.Workspace{ }, } -var target1 = &models.Target{ - Id: "123", +var targetConfig1 = &models.TargetConfig{ Name: "test", ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, Options: "test-options", + Deleted: false, +} + +var target1 = &models.Target{ + Id: "123", + Name: "test", + TargetConfigId: targetConfig1.Id, + TargetConfig: *targetConfig1, } var gitStatus1 = &models.GitStatus{ diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go index a8ccc8fa2f..0fde92ed95 100644 --- a/pkg/api/controllers/target/create.go +++ b/pkg/api/controllers/target/create.go @@ -40,11 +40,11 @@ func CreateTarget(ctx *gin.Context) { return } - maskedOptions, err := util.GetMaskedOptions(server, t.ProviderInfo.Name, t.Options) + maskedOptions, err := util.GetMaskedOptions(server, t.TargetConfig.ProviderInfo.Name, t.TargetConfig.Options) if err != nil { - t.Options = fmt.Sprintf("Error: %s", err.Error()) + t.TargetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) } else { - t.Options = maskedOptions + t.TargetConfig.Options = maskedOptions } ctx.JSON(200, t) diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index e2f0af7ad8..2cb77ee20c 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -54,11 +54,11 @@ func GetTarget(ctx *gin.Context) { return } - maskedOptions, err := util.GetMaskedOptions(server, t.ProviderInfo.Name, t.Options) + maskedOptions, err := util.GetMaskedOptions(server, t.TargetConfig.ProviderInfo.Name, t.TargetConfig.Options) if err != nil { - t.Options = fmt.Sprintf("Error: %s", err.Error()) + t.TargetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) } else { - t.Options = maskedOptions + t.TargetConfig.Options = maskedOptions } util.HideDaytonaEnvVars(&t.EnvVars) @@ -99,13 +99,13 @@ func ListTargets(ctx *gin.Context) { } for i, t := range targetList { - maskedOptions, err := util.GetMaskedOptions(server, t.ProviderInfo.Name, t.Options) + maskedOptions, err := util.GetMaskedOptions(server, t.TargetConfig.ProviderInfo.Name, t.TargetConfig.Options) if err != nil { - targetList[i].Options = fmt.Sprintf("Error: %s", err.Error()) + targetList[i].TargetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) continue } - targetList[i].Options = maskedOptions + targetList[i].TargetConfig.Options = maskedOptions util.HideDaytonaEnvVars(&targetList[i].EnvVars) } diff --git a/pkg/api/controllers/targetconfig/set.go b/pkg/api/controllers/targetconfig/add.go similarity index 65% rename from pkg/api/controllers/targetconfig/set.go rename to pkg/api/controllers/targetconfig/add.go index a58fff534c..65334e0e00 100644 --- a/pkg/api/controllers/targetconfig/set.go +++ b/pkg/api/controllers/targetconfig/add.go @@ -7,25 +7,24 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/targetconfigs/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" ) -// SetTargetConfig godoc +// AddTargetConfig godoc // // @Tags target-config -// @Summary Set a target config -// @Description Set a target config -// @Param targetConfig body CreateTargetConfigDTO true "Target config to set" +// @Summary Add a target config +// @Description Add a target config +// @Param targetConfig body AddTargetConfigDTO true "Target config to add" // @Success 200 {object} TargetConfig // @Router /target-config [put] // -// @id SetTargetConfig -func SetTargetConfig(ctx *gin.Context) { - var req dto.CreateTargetConfigDTO +// @id AddTargetConfig +func AddTargetConfig(ctx *gin.Context) { + var req services.AddTargetConfigDTO err := ctx.BindJSON(&req) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) @@ -34,9 +33,7 @@ func SetTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfig := conversion.ToTargetConfig(req) - - err = server.TargetConfigService.Save(targetConfig) + targetConfig, err := server.TargetConfigService.Add(req) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target config: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/list.go b/pkg/api/controllers/targetconfig/list.go index 17ac7c471a..dcfa271fd4 100644 --- a/pkg/api/controllers/targetconfig/list.go +++ b/pkg/api/controllers/targetconfig/list.go @@ -25,7 +25,7 @@ import ( func ListTargetConfigs(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfigs, err := server.TargetConfigService.List(nil) + targetConfigs, err := server.TargetConfigService.List() if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list target configs: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/remove.go index 000d6f54b8..0d0d22207d 100644 --- a/pkg/api/controllers/targetconfig/remove.go +++ b/pkg/api/controllers/targetconfig/remove.go @@ -8,7 +8,6 @@ import ( "net/http" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -17,25 +16,17 @@ import ( // @Tags target-config // @Summary Remove a target config // @Description Remove a target config -// @Param configName path string true "Target Config name" +// @Param configId path string true "Target Config Id" // @Success 204 -// @Router /target-config/{configName} [delete] +// @Router /target-config/{configId} [delete] // // @id RemoveTargetConfig func RemoveTargetConfig(ctx *gin.Context) { - configName := ctx.Param("configName") + configId := ctx.Param("configId") server := server.GetInstance(nil) - targetConfig, err := server.TargetConfigService.Find(&stores.TargetConfigFilter{ - Name: &configName, - }) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find target config: %w", err)) - return - } - - err = server.TargetConfigService.Delete(targetConfig) + err := server.TargetConfigService.Delete(configId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target config: %w", err)) return diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index d569de1e15..3b627ebdb6 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1261,20 +1261,20 @@ const docTemplate = `{ } }, "put": { - "description": "Set a target config", + "description": "Add a target config", "tags": [ "target-config" ], - "summary": "Set a target config", - "operationId": "SetTargetConfig", + "summary": "Add a target config", + "operationId": "AddTargetConfig", "parameters": [ { - "description": "Target config to set", + "description": "Target config to add", "name": "targetConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateTargetConfigDTO" + "$ref": "#/definitions/AddTargetConfigDTO" } } ], @@ -1288,7 +1288,7 @@ const docTemplate = `{ } } }, - "/target-config/{configName}": { + "/target-config/{configId}": { "delete": { "description": "Remove a target config", "tags": [ @@ -1299,8 +1299,8 @@ const docTemplate = `{ "parameters": [ { "type": "string", - "description": "Target Config name", - "name": "configName", + "description": "Target Config Id", + "name": "configId", "in": "path", "required": true } @@ -3380,6 +3380,25 @@ const docTemplate = `{ } }, "definitions": { + "AddTargetConfigDTO": { + "type": "object", + "required": [ + "name", + "options", + "providerInfo" + ], + "properties": { + "name": { + "type": "string" + }, + "options": { + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/TargetProviderInfo" + } + } + }, "ApiKey": { "type": "object", "required": [ @@ -3661,25 +3680,6 @@ const docTemplate = `{ } } }, - "CreateTargetConfigDTO": { - "type": "object", - "required": [ - "name", - "options", - "providerInfo" - ], - "properties": { - "name": { - "type": "string" - }, - "options": { - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" - } - } - }, "CreateTargetDTO": { "type": "object", "required": [ @@ -4984,8 +4984,8 @@ const docTemplate = `{ "envVars", "id", "name", - "options", - "providerInfo" + "targetConfig", + "targetConfigId" ], "properties": { "default": { @@ -5009,12 +5009,11 @@ const docTemplate = `{ "name": { "type": "string" }, - "options": { - "description": "JSON encoded map of options", - "type": "string" + "targetConfig": { + "$ref": "#/definitions/TargetConfig" }, - "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" + "targetConfigId": { + "type": "string" }, "workspaces": { "type": "array", @@ -5027,11 +5026,19 @@ const docTemplate = `{ "TargetConfig": { "type": "object", "required": [ + "deleted", + "id", "name", "options", "providerInfo" ], "properties": { + "deleted": { + "type": "boolean" + }, + "id": { + "type": "string" + }, "name": { "type": "string" }, @@ -5094,9 +5101,9 @@ const docTemplate = `{ "envVars", "id", "name", - "options", - "providerInfo", - "state" + "state", + "targetConfig", + "targetConfigId" ], "properties": { "default": { @@ -5123,16 +5130,15 @@ const docTemplate = `{ "name": { "type": "string" }, - "options": { - "description": "JSON encoded map of options", - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" - }, "state": { "$ref": "#/definitions/ResourceState" }, + "targetConfig": { + "$ref": "#/definitions/TargetConfig" + }, + "targetConfigId": { + "type": "string" + }, "workspaces": { "type": "array", "items": { diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 954c2d1842..5601effa38 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1258,20 +1258,20 @@ } }, "put": { - "description": "Set a target config", + "description": "Add a target config", "tags": [ "target-config" ], - "summary": "Set a target config", - "operationId": "SetTargetConfig", + "summary": "Add a target config", + "operationId": "AddTargetConfig", "parameters": [ { - "description": "Target config to set", + "description": "Target config to add", "name": "targetConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateTargetConfigDTO" + "$ref": "#/definitions/AddTargetConfigDTO" } } ], @@ -1285,7 +1285,7 @@ } } }, - "/target-config/{configName}": { + "/target-config/{configId}": { "delete": { "description": "Remove a target config", "tags": [ @@ -1296,8 +1296,8 @@ "parameters": [ { "type": "string", - "description": "Target Config name", - "name": "configName", + "description": "Target Config Id", + "name": "configId", "in": "path", "required": true } @@ -3377,6 +3377,25 @@ } }, "definitions": { + "AddTargetConfigDTO": { + "type": "object", + "required": [ + "name", + "options", + "providerInfo" + ], + "properties": { + "name": { + "type": "string" + }, + "options": { + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/TargetProviderInfo" + } + } + }, "ApiKey": { "type": "object", "required": [ @@ -3658,25 +3677,6 @@ } } }, - "CreateTargetConfigDTO": { - "type": "object", - "required": [ - "name", - "options", - "providerInfo" - ], - "properties": { - "name": { - "type": "string" - }, - "options": { - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" - } - } - }, "CreateTargetDTO": { "type": "object", "required": [ @@ -4981,8 +4981,8 @@ "envVars", "id", "name", - "options", - "providerInfo" + "targetConfig", + "targetConfigId" ], "properties": { "default": { @@ -5006,12 +5006,11 @@ "name": { "type": "string" }, - "options": { - "description": "JSON encoded map of options", - "type": "string" + "targetConfig": { + "$ref": "#/definitions/TargetConfig" }, - "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" + "targetConfigId": { + "type": "string" }, "workspaces": { "type": "array", @@ -5024,11 +5023,19 @@ "TargetConfig": { "type": "object", "required": [ + "deleted", + "id", "name", "options", "providerInfo" ], "properties": { + "deleted": { + "type": "boolean" + }, + "id": { + "type": "string" + }, "name": { "type": "string" }, @@ -5091,9 +5098,9 @@ "envVars", "id", "name", - "options", - "providerInfo", - "state" + "state", + "targetConfig", + "targetConfigId" ], "properties": { "default": { @@ -5120,16 +5127,15 @@ "name": { "type": "string" }, - "options": { - "description": "JSON encoded map of options", - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" - }, "state": { "$ref": "#/definitions/ResourceState" }, + "targetConfig": { + "$ref": "#/definitions/TargetConfig" + }, + "targetConfigId": { + "type": "string" + }, "workspaces": { "type": "array", "items": { diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index b6a545364b..85f40405e1 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -1,5 +1,18 @@ basePath: / definitions: + AddTargetConfigDTO: + properties: + name: + type: string + options: + type: string + providerInfo: + $ref: '#/definitions/TargetProviderInfo' + required: + - name + - options + - providerInfo + type: object ApiKey: properties: keyHash: @@ -190,19 +203,6 @@ definitions: required: - sessionId type: object - CreateTargetConfigDTO: - properties: - name: - type: string - options: - type: string - providerInfo: - $ref: '#/definitions/TargetProviderInfo' - required: - - name - - options - - providerInfo - type: object CreateTargetDTO: properties: id: @@ -1109,11 +1109,10 @@ definitions: $ref: '#/definitions/TargetMetadata' name: type: string - options: - description: JSON encoded map of options + targetConfig: + $ref: '#/definitions/TargetConfig' + targetConfigId: type: string - providerInfo: - $ref: '#/definitions/TargetProviderInfo' workspaces: items: $ref: '#/definitions/Workspace' @@ -1123,11 +1122,15 @@ definitions: - envVars - id - name - - options - - providerInfo + - targetConfig + - targetConfigId type: object TargetConfig: properties: + deleted: + type: boolean + id: + type: string name: type: string options: @@ -1136,6 +1139,8 @@ definitions: providerInfo: $ref: '#/definitions/TargetProviderInfo' required: + - deleted + - id - name - options - providerInfo @@ -1194,13 +1199,12 @@ definitions: $ref: '#/definitions/TargetMetadata' name: type: string - options: - description: JSON encoded map of options - type: string - providerInfo: - $ref: '#/definitions/TargetProviderInfo' state: $ref: '#/definitions/ResourceState' + targetConfig: + $ref: '#/definitions/TargetConfig' + targetConfigId: + type: string workspaces: items: $ref: '#/definitions/Workspace' @@ -1210,9 +1214,9 @@ definitions: - envVars - id - name - - options - - providerInfo - state + - targetConfig + - targetConfigId type: object TargetInfo: properties: @@ -2338,31 +2342,31 @@ paths: tags: - target-config put: - description: Set a target config - operationId: SetTargetConfig + description: Add a target config + operationId: AddTargetConfig parameters: - - description: Target config to set + - description: Target config to add in: body name: targetConfig required: true schema: - $ref: '#/definitions/CreateTargetConfigDTO' + $ref: '#/definitions/AddTargetConfigDTO' responses: "200": description: OK schema: $ref: '#/definitions/TargetConfig' - summary: Set a target config + summary: Add a target config tags: - target-config - /target-config/{configName}: + /target-config/{configId}: delete: description: Remove a target config operationId: RemoveTargetConfig parameters: - - description: Target Config name + - description: Target Config Id in: path - name: configName + name: configId required: true type: string responses: diff --git a/pkg/api/server.go b/pkg/api/server.go index 4e2784962c..4262d73be6 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -287,7 +287,7 @@ func (a *ApiServer) Start() error { targetConfigController := protected.Group("/target-config") { targetConfigController.GET("", targetconfig.ListTargetConfigs) - targetConfigController.PUT("", targetconfig.SetTargetConfig) + targetConfigController.PUT("", targetconfig.AddTargetConfig) targetConfigController.DELETE("/:configName", targetconfig.RemoveTargetConfig) } diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 4ad0a37ac4..cfe1931044 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -131,9 +131,9 @@ Class | Method | HTTP request | Description *TargetAPI* | [**SetTargetMetadata**](docs/TargetAPI.md#settargetmetadata) | **Post** /target/{targetId}/metadata | Set target metadata *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target +*TargetConfigAPI* | [**AddTargetConfig**](docs/TargetConfigAPI.md#addtargetconfig) | **Put** /target-config | Add a target config *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs -*TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configName} | Remove a target config -*TargetConfigAPI* | [**SetTargetConfig**](docs/TargetConfigAPI.md#settargetconfig) | **Put** /target-config | Set a target config +*TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configId} | Remove a target config *WorkspaceAPI* | [**CreateWorkspace**](docs/WorkspaceAPI.md#createworkspace) | **Post** /workspace | Create a workspace *WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info *WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces @@ -185,6 +185,7 @@ Class | Method | HTTP request | Description ## Documentation For Models + - [AddTargetConfigDTO](docs/AddTargetConfigDTO.md) - [ApiKey](docs/ApiKey.md) - [Build](docs/Build.md) - [BuildConfig](docs/BuildConfig.md) @@ -199,7 +200,6 @@ Class | Method | HTTP request | Description - [CreateBuildDTO](docs/CreateBuildDTO.md) - [CreatePrebuildDTO](docs/CreatePrebuildDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) - - [CreateTargetConfigDTO](docs/CreateTargetConfigDTO.md) - [CreateTargetDTO](docs/CreateTargetDTO.md) - [CreateWorkspaceConfigDTO](docs/CreateWorkspaceConfigDTO.md) - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 550ffda70a..dcdf6d36c8 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -891,14 +891,14 @@ paths: tags: - target-config put: - description: Set a target config - operationId: SetTargetConfig + description: Add a target config + operationId: AddTargetConfig requestBody: content: '*/*': schema: - $ref: '#/components/schemas/CreateTargetConfigDTO' - description: Target config to set + $ref: '#/components/schemas/AddTargetConfigDTO' + description: Target config to add required: true responses: "200": @@ -907,18 +907,18 @@ paths: schema: $ref: '#/components/schemas/TargetConfig' description: OK - summary: Set a target config + summary: Add a target config tags: - target-config x-codegen-request-body-name: targetConfig - /target-config/{configName}: + /target-config/{configId}: delete: description: Remove a target config operationId: RemoveTargetConfig parameters: - - description: Target Config name + - description: Target Config Id in: path - name: configName + name: configId required: true schema: type: string @@ -2455,6 +2455,26 @@ paths: - workspace toolbox components: schemas: + AddTargetConfigDTO: + example: + name: name + options: options + providerInfo: + name: name + label: label + version: version + properties: + name: + type: string + options: + type: string + providerInfo: + $ref: '#/components/schemas/TargetProviderInfo' + required: + - name + - options + - providerInfo + type: object ApiKey: example: keyHash: keyHash @@ -2744,26 +2764,6 @@ components: required: - sessionId type: object - CreateTargetConfigDTO: - example: - name: name - options: options - providerInfo: - name: name - label: label - version: version - properties: - name: - type: string - options: - type: string - providerInfo: - $ref: '#/components/schemas/TargetProviderInfo' - required: - - name - - options - - providerInfo - type: object CreateTargetDTO: example: targetConfigName: targetConfigName @@ -4039,6 +4039,15 @@ components: targetId: targetId updatedAt: updatedAt uptime: 0 + targetConfig: + deleted: true + name: name + options: options + id: id + providerInfo: + name: name + label: label + version: version lastJob: createdAt: createdAt resourceId: resourceId @@ -4051,15 +4060,11 @@ components: envVars: key: envVars name: name - options: options + targetConfigId: targetConfigId id: id workspaces: - null - null - providerInfo: - name: name - label: label - version: version properties: default: type: boolean @@ -4075,11 +4080,10 @@ components: $ref: '#/components/schemas/TargetMetadata' name: type: string - options: - description: JSON encoded map of options + targetConfig: + $ref: '#/components/schemas/TargetConfig' + targetConfigId: type: string - providerInfo: - $ref: '#/components/schemas/TargetProviderInfo' workspaces: items: $ref: '#/components/schemas/Workspace' @@ -4089,18 +4093,24 @@ components: - envVars - id - name - - options - - providerInfo + - targetConfig + - targetConfigId type: object TargetConfig: example: + deleted: true name: name options: options + id: id providerInfo: name: name label: label version: version properties: + deleted: + type: boolean + id: + type: string name: type: string options: @@ -4109,6 +4119,8 @@ components: providerInfo: $ref: '#/components/schemas/TargetProviderInfo' required: + - deleted + - id - name - options - providerInfo @@ -4156,6 +4168,15 @@ components: targetId: targetId updatedAt: updatedAt uptime: 0 + targetConfig: + deleted: true + name: name + options: options + id: id + providerInfo: + name: name + label: label + version: version lastJob: createdAt: createdAt resourceId: resourceId @@ -4168,7 +4189,7 @@ components: envVars: key: envVars name: name - options: options + targetConfigId: targetConfigId id: id state: name: null @@ -4233,6 +4254,15 @@ components: targetId: targetId updatedAt: updatedAt uptime: 0 + targetConfig: + deleted: true + name: name + options: options + id: id + providerInfo: + name: name + label: label + version: version lastJob: createdAt: createdAt resourceId: resourceId @@ -4245,15 +4275,11 @@ components: envVars: key: envVars name: name - options: options + targetConfigId: targetConfigId id: id workspaces: - null - null - providerInfo: - name: name - label: label - version: version - buildConfig: cachedBuild: image: image @@ -4312,6 +4338,15 @@ components: targetId: targetId updatedAt: updatedAt uptime: 0 + targetConfig: + deleted: true + name: name + options: options + id: id + providerInfo: + name: name + label: label + version: version lastJob: createdAt: createdAt resourceId: resourceId @@ -4324,22 +4359,14 @@ components: envVars: key: envVars name: name - options: options + targetConfigId: targetConfigId id: id workspaces: - null - null - providerInfo: - name: name - label: label - version: version info: providerMetadata: providerMetadata name: name - providerInfo: - name: name - label: label - version: version properties: default: type: boolean @@ -4357,13 +4384,12 @@ components: $ref: '#/components/schemas/TargetMetadata' name: type: string - options: - description: JSON encoded map of options - type: string - providerInfo: - $ref: '#/components/schemas/TargetProviderInfo' state: $ref: '#/components/schemas/ResourceState' + targetConfig: + $ref: '#/components/schemas/TargetConfig' + targetConfigId: + type: string workspaces: items: $ref: '#/components/schemas/Workspace' @@ -4373,9 +4399,9 @@ components: - envVars - id - name - - options - - providerInfo - state + - targetConfig + - targetConfigId type: object TargetInfo: example: @@ -4482,6 +4508,15 @@ components: targetId: targetId updatedAt: updatedAt uptime: 0 + targetConfig: + deleted: true + name: name + options: options + id: id + providerInfo: + name: name + label: label + version: version lastJob: createdAt: createdAt resourceId: resourceId @@ -4494,15 +4529,11 @@ components: envVars: key: envVars name: name - options: options + targetConfigId: targetConfigId id: id workspaces: - null - null - providerInfo: - name: name - label: label - version: version properties: buildConfig: $ref: '#/components/schemas/BuildConfig' @@ -4644,6 +4675,15 @@ components: targetId: targetId updatedAt: updatedAt uptime: 0 + targetConfig: + deleted: true + name: name + options: options + id: id + providerInfo: + name: name + label: label + version: version lastJob: createdAt: createdAt resourceId: resourceId @@ -4656,15 +4696,11 @@ components: envVars: key: envVars name: name - options: options + targetConfigId: targetConfigId id: id workspaces: - null - null - providerInfo: - name: name - label: label - version: version buildConfig: cachedBuild: image: image diff --git a/pkg/apiclient/api_target_config.go b/pkg/apiclient/api_target_config.go index b2555ee5e0..d67edc250c 100644 --- a/pkg/apiclient/api_target_config.go +++ b/pkg/apiclient/api_target_config.go @@ -22,25 +22,32 @@ import ( // TargetConfigAPIService TargetConfigAPI service type TargetConfigAPIService service -type ApiListTargetConfigsRequest struct { - ctx context.Context - ApiService *TargetConfigAPIService +type ApiAddTargetConfigRequest struct { + ctx context.Context + ApiService *TargetConfigAPIService + targetConfig *AddTargetConfigDTO } -func (r ApiListTargetConfigsRequest) Execute() ([]TargetConfig, *http.Response, error) { - return r.ApiService.ListTargetConfigsExecute(r) +// Target config to add +func (r ApiAddTargetConfigRequest) TargetConfig(targetConfig AddTargetConfigDTO) ApiAddTargetConfigRequest { + r.targetConfig = &targetConfig + return r +} + +func (r ApiAddTargetConfigRequest) Execute() (*TargetConfig, *http.Response, error) { + return r.ApiService.AddTargetConfigExecute(r) } /* -ListTargetConfigs List target configs +AddTargetConfig Add a target config -List target configs +Add a target config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListTargetConfigsRequest + @return ApiAddTargetConfigRequest */ -func (a *TargetConfigAPIService) ListTargetConfigs(ctx context.Context) ApiListTargetConfigsRequest { - return ApiListTargetConfigsRequest{ +func (a *TargetConfigAPIService) AddTargetConfig(ctx context.Context) ApiAddTargetConfigRequest { + return ApiAddTargetConfigRequest{ ApiService: a, ctx: ctx, } @@ -48,16 +55,16 @@ func (a *TargetConfigAPIService) ListTargetConfigs(ctx context.Context) ApiListT // Execute executes the request // -// @return []TargetConfig -func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigsRequest) ([]TargetConfig, *http.Response, error) { +// @return TargetConfig +func (a *TargetConfigAPIService) AddTargetConfigExecute(r ApiAddTargetConfigRequest) (*TargetConfig, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet + localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile - localVarReturnValue []TargetConfig + localVarReturnValue *TargetConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.ListTargetConfigs") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.AddTargetConfig") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -67,6 +74,9 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.targetConfig == nil { + return localVarReturnValue, nil, reportError("targetConfig is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -78,13 +88,15 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{"*/*"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.targetConfig if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -136,48 +148,47 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveTargetConfigRequest struct { +type ApiListTargetConfigsRequest struct { ctx context.Context ApiService *TargetConfigAPIService - configName string } -func (r ApiRemoveTargetConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveTargetConfigExecute(r) +func (r ApiListTargetConfigsRequest) Execute() ([]TargetConfig, *http.Response, error) { + return r.ApiService.ListTargetConfigsExecute(r) } /* -RemoveTargetConfig Remove a target config +ListTargetConfigs List target configs -Remove a target config +List target configs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Target Config name - @return ApiRemoveTargetConfigRequest + @return ApiListTargetConfigsRequest */ -func (a *TargetConfigAPIService) RemoveTargetConfig(ctx context.Context, configName string) ApiRemoveTargetConfigRequest { - return ApiRemoveTargetConfigRequest{ +func (a *TargetConfigAPIService) ListTargetConfigs(ctx context.Context) ApiListTargetConfigsRequest { + return ApiListTargetConfigsRequest{ ApiService: a, ctx: ctx, - configName: configName, } } // Execute executes the request -func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConfigRequest) (*http.Response, error) { +// +// @return []TargetConfig +func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigsRequest) ([]TargetConfig, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []TargetConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.RemoveTargetConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.ListTargetConfigs") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target-config/{configName}" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/target-config" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -193,7 +204,7 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -216,19 +227,19 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -236,67 +247,67 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil -} + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } -type ApiSetTargetConfigRequest struct { - ctx context.Context - ApiService *TargetConfigAPIService - targetConfig *CreateTargetConfigDTO + return localVarReturnValue, localVarHTTPResponse, nil } -// Target config to set -func (r ApiSetTargetConfigRequest) TargetConfig(targetConfig CreateTargetConfigDTO) ApiSetTargetConfigRequest { - r.targetConfig = &targetConfig - return r +type ApiRemoveTargetConfigRequest struct { + ctx context.Context + ApiService *TargetConfigAPIService + configId string } -func (r ApiSetTargetConfigRequest) Execute() (*TargetConfig, *http.Response, error) { - return r.ApiService.SetTargetConfigExecute(r) +func (r ApiRemoveTargetConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.RemoveTargetConfigExecute(r) } /* -SetTargetConfig Set a target config +RemoveTargetConfig Remove a target config -Set a target config +Remove a target config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetTargetConfigRequest + @param configId Target Config Id + @return ApiRemoveTargetConfigRequest */ -func (a *TargetConfigAPIService) SetTargetConfig(ctx context.Context) ApiSetTargetConfigRequest { - return ApiSetTargetConfigRequest{ +func (a *TargetConfigAPIService) RemoveTargetConfig(ctx context.Context, configId string) ApiRemoveTargetConfigRequest { + return ApiRemoveTargetConfigRequest{ ApiService: a, ctx: ctx, + configId: configId, } } // Execute executes the request -// -// @return TargetConfig -func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequest) (*TargetConfig, *http.Response, error) { +func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConfigRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *TargetConfig + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.SetTargetConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.RemoveTargetConfig") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target-config" + localVarPath := localBasePath + "/target-config/{configId}" + localVarPath = strings.Replace(localVarPath, "{"+"configId"+"}", url.PathEscape(parameterValueToString(r.configId, "configId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.targetConfig == nil { - return localVarReturnValue, nil, reportError("targetConfig is required and must be specified") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -308,15 +319,13 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"*/*"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.targetConfig if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -333,19 +342,19 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -353,17 +362,8 @@ func (a *TargetConfigAPIService) SetTargetConfigExecute(r ApiSetTargetConfigRequ body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } diff --git a/pkg/apiclient/docs/CreateTargetConfigDTO.md b/pkg/apiclient/docs/AddTargetConfigDTO.md similarity index 63% rename from pkg/apiclient/docs/CreateTargetConfigDTO.md rename to pkg/apiclient/docs/AddTargetConfigDTO.md index 0d4e7d7c65..2fa3915d71 100644 --- a/pkg/apiclient/docs/CreateTargetConfigDTO.md +++ b/pkg/apiclient/docs/AddTargetConfigDTO.md @@ -1,4 +1,4 @@ -# CreateTargetConfigDTO +# AddTargetConfigDTO ## Properties @@ -10,79 +10,79 @@ Name | Type | Description | Notes ## Methods -### NewCreateTargetConfigDTO +### NewAddTargetConfigDTO -`func NewCreateTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo, ) *CreateTargetConfigDTO` +`func NewAddTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo, ) *AddTargetConfigDTO` -NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object +NewAddTargetConfigDTO instantiates a new AddTargetConfigDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateTargetConfigDTOWithDefaults +### NewAddTargetConfigDTOWithDefaults -`func NewCreateTargetConfigDTOWithDefaults() *CreateTargetConfigDTO` +`func NewAddTargetConfigDTOWithDefaults() *AddTargetConfigDTO` -NewCreateTargetConfigDTOWithDefaults instantiates a new CreateTargetConfigDTO object +NewAddTargetConfigDTOWithDefaults instantiates a new AddTargetConfigDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetName -`func (o *CreateTargetConfigDTO) GetName() string` +`func (o *AddTargetConfigDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool)` +`func (o *AddTargetConfigDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *CreateTargetConfigDTO) SetName(v string)` +`func (o *AddTargetConfigDTO) SetName(v string)` SetName sets Name field to given value. ### GetOptions -`func (o *CreateTargetConfigDTO) GetOptions() string` +`func (o *AddTargetConfigDTO) GetOptions() string` GetOptions returns the Options field if non-nil, zero value otherwise. ### GetOptionsOk -`func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool)` +`func (o *AddTargetConfigDTO) GetOptionsOk() (*string, bool)` GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetOptions -`func (o *CreateTargetConfigDTO) SetOptions(v string)` +`func (o *AddTargetConfigDTO) SetOptions(v string)` SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *CreateTargetConfigDTO) GetProviderInfo() TargetProviderInfo` +`func (o *AddTargetConfigDTO) GetProviderInfo() TargetProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool)` +`func (o *AddTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *CreateTargetConfigDTO) SetProviderInfo(v TargetProviderInfo)` +`func (o *AddTargetConfigDTO) SetProviderInfo(v TargetProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index 8d01d15bc7..95d709455d 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -10,15 +10,15 @@ Name | Type | Description | Notes **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | -**Options** | **string** | JSON encoded map of options | -**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | +**TargetConfig** | [**TargetConfig**](TargetConfig.md) | | +**TargetConfigId** | **string** | | **Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] ## Methods ### NewTarget -`func NewTarget(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo, ) *Target` +`func NewTarget(default_ bool, envVars map[string]string, id string, name string, targetConfig TargetConfig, targetConfigId string, ) *Target` NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, @@ -163,44 +163,44 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetOptions +### GetTargetConfig -`func (o *Target) GetOptions() string` +`func (o *Target) GetTargetConfig() TargetConfig` -GetOptions returns the Options field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetOptionsOk +### GetTargetConfigOk -`func (o *Target) GetOptionsOk() (*string, bool)` +`func (o *Target) GetTargetConfigOk() (*TargetConfig, bool)` -GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetOptions +### SetTargetConfig -`func (o *Target) SetOptions(v string)` +`func (o *Target) SetTargetConfig(v TargetConfig)` -SetOptions sets Options field to given value. +SetTargetConfig sets TargetConfig field to given value. -### GetProviderInfo +### GetTargetConfigId -`func (o *Target) GetProviderInfo() TargetProviderInfo` +`func (o *Target) GetTargetConfigId() string` -GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. +GetTargetConfigId returns the TargetConfigId field if non-nil, zero value otherwise. -### GetProviderInfoOk +### GetTargetConfigIdOk -`func (o *Target) GetProviderInfoOk() (*TargetProviderInfo, bool)` +`func (o *Target) GetTargetConfigIdOk() (*string, bool)` -GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise +GetTargetConfigIdOk returns a tuple with the TargetConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProviderInfo +### SetTargetConfigId -`func (o *Target) SetProviderInfo(v TargetProviderInfo)` +`func (o *Target) SetTargetConfigId(v string)` -SetProviderInfo sets ProviderInfo field to given value. +SetTargetConfigId sets TargetConfigId field to given value. ### GetWorkspaces diff --git a/pkg/apiclient/docs/TargetConfig.md b/pkg/apiclient/docs/TargetConfig.md index 07dab01561..78c61cbbe2 100644 --- a/pkg/apiclient/docs/TargetConfig.md +++ b/pkg/apiclient/docs/TargetConfig.md @@ -4,6 +4,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**Deleted** | **bool** | | +**Id** | **string** | | **Name** | **string** | | **Options** | **string** | JSON encoded map of options | **ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | @@ -12,7 +14,7 @@ Name | Type | Description | Notes ### NewTargetConfig -`func NewTargetConfig(name string, options string, providerInfo TargetProviderInfo, ) *TargetConfig` +`func NewTargetConfig(deleted bool, id string, name string, options string, providerInfo TargetProviderInfo, ) *TargetConfig` NewTargetConfig instantiates a new TargetConfig object This constructor will assign default values to properties that have it defined, @@ -27,6 +29,46 @@ NewTargetConfigWithDefaults instantiates a new TargetConfig object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set +### GetDeleted + +`func (o *TargetConfig) GetDeleted() bool` + +GetDeleted returns the Deleted field if non-nil, zero value otherwise. + +### GetDeletedOk + +`func (o *TargetConfig) GetDeletedOk() (*bool, bool)` + +GetDeletedOk returns a tuple with the Deleted field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDeleted + +`func (o *TargetConfig) SetDeleted(v bool)` + +SetDeleted sets Deleted field to given value. + + +### GetId + +`func (o *TargetConfig) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *TargetConfig) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *TargetConfig) SetId(v string)` + +SetId sets Id field to given value. + + ### GetName `func (o *TargetConfig) GetName() string` diff --git a/pkg/apiclient/docs/TargetConfigAPI.md b/pkg/apiclient/docs/TargetConfigAPI.md index 52bf66380c..6696f26fd8 100644 --- a/pkg/apiclient/docs/TargetConfigAPI.md +++ b/pkg/apiclient/docs/TargetConfigAPI.md @@ -4,17 +4,17 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- +[**AddTargetConfig**](TargetConfigAPI.md#AddTargetConfig) | **Put** /target-config | Add a target config [**ListTargetConfigs**](TargetConfigAPI.md#ListTargetConfigs) | **Get** /target-config | List target configs -[**RemoveTargetConfig**](TargetConfigAPI.md#RemoveTargetConfig) | **Delete** /target-config/{configName} | Remove a target config -[**SetTargetConfig**](TargetConfigAPI.md#SetTargetConfig) | **Put** /target-config | Set a target config +[**RemoveTargetConfig**](TargetConfigAPI.md#RemoveTargetConfig) | **Delete** /target-config/{configId} | Remove a target config -## ListTargetConfigs +## AddTargetConfig -> []TargetConfig ListTargetConfigs(ctx).Execute() +> TargetConfig AddTargetConfig(ctx).TargetConfig(targetConfig).Execute() -List target configs +Add a target config @@ -31,31 +31,36 @@ import ( ) func main() { + targetConfig := *openapiclient.NewAddTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewTargetProviderInfo("Name_example", "Version_example")) // AddTargetConfigDTO | Target config to add configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).Execute() + resp, r, err := apiClient.TargetConfigAPI.AddTargetConfig(context.Background()).TargetConfig(targetConfig).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.ListTargetConfigs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.AddTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListTargetConfigs`: []TargetConfig - fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.ListTargetConfigs`: %v\n", resp) + // response from `AddTargetConfig`: TargetConfig + fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.AddTargetConfig`: %v\n", resp) } ``` ### Path Parameters -This endpoint does not need any parameter. + ### Other Parameters -Other parameters are passed through a pointer to a apiListTargetConfigsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiAddTargetConfigRequest struct via the builder pattern +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **targetConfig** | [**AddTargetConfigDTO**](AddTargetConfigDTO.md) | Target config to add | + ### Return type -[**[]TargetConfig**](TargetConfig.md) +[**TargetConfig**](TargetConfig.md) ### Authorization @@ -64,18 +69,18 @@ Other parameters are passed through a pointer to a apiListTargetConfigsRequest s ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: */* [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## RemoveTargetConfig +## ListTargetConfigs -> RemoveTargetConfig(ctx, configName).Execute() +> []TargetConfig ListTargetConfigs(ctx).Execute() -Remove a target config +List target configs @@ -92,38 +97,31 @@ import ( ) func main() { - configName := "configName_example" // string | Target Config name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetConfigAPI.RemoveTargetConfig(context.Background(), configName).Execute() + resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.RemoveTargetConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.ListTargetConfigs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListTargetConfigs`: []TargetConfig + fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.ListTargetConfigs`: %v\n", resp) } ``` ### Path Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Target Config name | +This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveTargetConfigRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- +Other parameters are passed through a pointer to a apiListTargetConfigsRequest struct via the builder pattern ### Return type - (empty response body) +[**[]TargetConfig**](TargetConfig.md) ### Authorization @@ -132,18 +130,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## SetTargetConfig +## RemoveTargetConfig -> TargetConfig SetTargetConfig(ctx).TargetConfig(targetConfig).Execute() +> RemoveTargetConfig(ctx, configId).Execute() -Set a target config +Remove a target config @@ -160,36 +158,38 @@ import ( ) func main() { - targetConfig := *openapiclient.NewCreateTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewTargetProviderInfo("Name_example", "Version_example")) // CreateTargetConfigDTO | Target config to set + configId := "configId_example" // string | Target Config Id configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfig).Execute() + r, err := apiClient.TargetConfigAPI.RemoveTargetConfig(context.Background(), configId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.SetTargetConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.RemoveTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `SetTargetConfig`: TargetConfig - fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.SetTargetConfig`: %v\n", resp) } ``` ### Path Parameters +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**configId** | **string** | Target Config Id | ### Other Parameters -Other parameters are passed through a pointer to a apiSetTargetConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiRemoveTargetConfigRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **targetConfig** | [**CreateTargetConfigDTO**](CreateTargetConfigDTO.md) | Target config to set | + ### Return type -[**TargetConfig**](TargetConfig.md) + (empty response body) ### Authorization @@ -198,7 +198,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: */* +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index 1f4302c90f..1a094c4b4f 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -11,16 +11,16 @@ Name | Type | Description | Notes **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | -**Options** | **string** | JSON encoded map of options | -**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | **State** | [**ResourceState**](ResourceState.md) | | +**TargetConfig** | [**TargetConfig**](TargetConfig.md) | | +**TargetConfigId** | **string** | | **Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] ## Methods ### NewTargetDTO -`func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo, state ResourceState, ) *TargetDTO` +`func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, state ResourceState, targetConfig TargetConfig, targetConfigId string, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -190,64 +190,64 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetOptions +### GetState -`func (o *TargetDTO) GetOptions() string` +`func (o *TargetDTO) GetState() ResourceState` -GetOptions returns the Options field if non-nil, zero value otherwise. +GetState returns the State field if non-nil, zero value otherwise. -### GetOptionsOk +### GetStateOk -`func (o *TargetDTO) GetOptionsOk() (*string, bool)` +`func (o *TargetDTO) GetStateOk() (*ResourceState, bool)` -GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise +GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetOptions +### SetState -`func (o *TargetDTO) SetOptions(v string)` +`func (o *TargetDTO) SetState(v ResourceState)` -SetOptions sets Options field to given value. +SetState sets State field to given value. -### GetProviderInfo +### GetTargetConfig -`func (o *TargetDTO) GetProviderInfo() TargetProviderInfo` +`func (o *TargetDTO) GetTargetConfig() TargetConfig` -GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. +GetTargetConfig returns the TargetConfig field if non-nil, zero value otherwise. -### GetProviderInfoOk +### GetTargetConfigOk -`func (o *TargetDTO) GetProviderInfoOk() (*TargetProviderInfo, bool)` +`func (o *TargetDTO) GetTargetConfigOk() (*TargetConfig, bool)` -GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise +GetTargetConfigOk returns a tuple with the TargetConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProviderInfo +### SetTargetConfig -`func (o *TargetDTO) SetProviderInfo(v TargetProviderInfo)` +`func (o *TargetDTO) SetTargetConfig(v TargetConfig)` -SetProviderInfo sets ProviderInfo field to given value. +SetTargetConfig sets TargetConfig field to given value. -### GetState +### GetTargetConfigId -`func (o *TargetDTO) GetState() ResourceState` +`func (o *TargetDTO) GetTargetConfigId() string` -GetState returns the State field if non-nil, zero value otherwise. +GetTargetConfigId returns the TargetConfigId field if non-nil, zero value otherwise. -### GetStateOk +### GetTargetConfigIdOk -`func (o *TargetDTO) GetStateOk() (*ResourceState, bool)` +`func (o *TargetDTO) GetTargetConfigIdOk() (*string, bool)` -GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise +GetTargetConfigIdOk returns a tuple with the TargetConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetState +### SetTargetConfigId -`func (o *TargetDTO) SetState(v ResourceState)` +`func (o *TargetDTO) SetTargetConfigId(v string)` -SetState sets State field to given value. +SetTargetConfigId sets TargetConfigId field to given value. ### GetWorkspaces diff --git a/pkg/apiclient/model_create_target_config_dto.go b/pkg/apiclient/model_add_target_config_dto.go similarity index 58% rename from pkg/apiclient/model_create_target_config_dto.go rename to pkg/apiclient/model_add_target_config_dto.go index 27d4617618..3947838597 100644 --- a/pkg/apiclient/model_create_target_config_dto.go +++ b/pkg/apiclient/model_add_target_config_dto.go @@ -16,40 +16,40 @@ import ( "fmt" ) -// checks if the CreateTargetConfigDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateTargetConfigDTO{} +// checks if the AddTargetConfigDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &AddTargetConfigDTO{} -// CreateTargetConfigDTO struct for CreateTargetConfigDTO -type CreateTargetConfigDTO struct { +// AddTargetConfigDTO struct for AddTargetConfigDTO +type AddTargetConfigDTO struct { Name string `json:"name"` Options string `json:"options"` ProviderInfo TargetProviderInfo `json:"providerInfo"` } -type _CreateTargetConfigDTO CreateTargetConfigDTO +type _AddTargetConfigDTO AddTargetConfigDTO -// NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object +// NewAddTargetConfigDTO instantiates a new AddTargetConfigDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo) *CreateTargetConfigDTO { - this := CreateTargetConfigDTO{} +func NewAddTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo) *AddTargetConfigDTO { + this := AddTargetConfigDTO{} this.Name = name this.Options = options this.ProviderInfo = providerInfo return &this } -// NewCreateTargetConfigDTOWithDefaults instantiates a new CreateTargetConfigDTO object +// NewAddTargetConfigDTOWithDefaults instantiates a new AddTargetConfigDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateTargetConfigDTOWithDefaults() *CreateTargetConfigDTO { - this := CreateTargetConfigDTO{} +func NewAddTargetConfigDTOWithDefaults() *AddTargetConfigDTO { + this := AddTargetConfigDTO{} return &this } // GetName returns the Name field value -func (o *CreateTargetConfigDTO) GetName() string { +func (o *AddTargetConfigDTO) GetName() string { if o == nil { var ret string return ret @@ -60,7 +60,7 @@ func (o *CreateTargetConfigDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool) { +func (o *AddTargetConfigDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -68,12 +68,12 @@ func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *CreateTargetConfigDTO) SetName(v string) { +func (o *AddTargetConfigDTO) SetName(v string) { o.Name = v } // GetOptions returns the Options field value -func (o *CreateTargetConfigDTO) GetOptions() string { +func (o *AddTargetConfigDTO) GetOptions() string { if o == nil { var ret string return ret @@ -84,7 +84,7 @@ func (o *CreateTargetConfigDTO) GetOptions() string { // GetOptionsOk returns a tuple with the Options field value // and a boolean to check if the value has been set. -func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool) { +func (o *AddTargetConfigDTO) GetOptionsOk() (*string, bool) { if o == nil { return nil, false } @@ -92,12 +92,12 @@ func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool) { } // SetOptions sets field value -func (o *CreateTargetConfigDTO) SetOptions(v string) { +func (o *AddTargetConfigDTO) SetOptions(v string) { o.Options = v } // GetProviderInfo returns the ProviderInfo field value -func (o *CreateTargetConfigDTO) GetProviderInfo() TargetProviderInfo { +func (o *AddTargetConfigDTO) GetProviderInfo() TargetProviderInfo { if o == nil { var ret TargetProviderInfo return ret @@ -108,7 +108,7 @@ func (o *CreateTargetConfigDTO) GetProviderInfo() TargetProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { +func (o *AddTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { if o == nil { return nil, false } @@ -116,11 +116,11 @@ func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) } // SetProviderInfo sets field value -func (o *CreateTargetConfigDTO) SetProviderInfo(v TargetProviderInfo) { +func (o *AddTargetConfigDTO) SetProviderInfo(v TargetProviderInfo) { o.ProviderInfo = v } -func (o CreateTargetConfigDTO) MarshalJSON() ([]byte, error) { +func (o AddTargetConfigDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -128,7 +128,7 @@ func (o CreateTargetConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateTargetConfigDTO) ToMap() (map[string]interface{}, error) { +func (o AddTargetConfigDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["name"] = o.Name toSerialize["options"] = o.Options @@ -136,7 +136,7 @@ func (o CreateTargetConfigDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *CreateTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { +func (o *AddTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -160,53 +160,53 @@ func (o *CreateTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateTargetConfigDTO := _CreateTargetConfigDTO{} + varAddTargetConfigDTO := _AddTargetConfigDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateTargetConfigDTO) + err = decoder.Decode(&varAddTargetConfigDTO) if err != nil { return err } - *o = CreateTargetConfigDTO(varCreateTargetConfigDTO) + *o = AddTargetConfigDTO(varAddTargetConfigDTO) return err } -type NullableCreateTargetConfigDTO struct { - value *CreateTargetConfigDTO +type NullableAddTargetConfigDTO struct { + value *AddTargetConfigDTO isSet bool } -func (v NullableCreateTargetConfigDTO) Get() *CreateTargetConfigDTO { +func (v NullableAddTargetConfigDTO) Get() *AddTargetConfigDTO { return v.value } -func (v *NullableCreateTargetConfigDTO) Set(val *CreateTargetConfigDTO) { +func (v *NullableAddTargetConfigDTO) Set(val *AddTargetConfigDTO) { v.value = val v.isSet = true } -func (v NullableCreateTargetConfigDTO) IsSet() bool { +func (v NullableAddTargetConfigDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateTargetConfigDTO) Unset() { +func (v *NullableAddTargetConfigDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateTargetConfigDTO(val *CreateTargetConfigDTO) *NullableCreateTargetConfigDTO { - return &NullableCreateTargetConfigDTO{value: val, isSet: true} +func NewNullableAddTargetConfigDTO(val *AddTargetConfigDTO) *NullableAddTargetConfigDTO { + return &NullableAddTargetConfigDTO{value: val, isSet: true} } -func (v NullableCreateTargetConfigDTO) MarshalJSON() ([]byte, error) { +func (v NullableAddTargetConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateTargetConfigDTO) UnmarshalJSON(src []byte) error { +func (v *NullableAddTargetConfigDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index 96e8abb256..0b30d56898 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -21,16 +21,15 @@ var _ MappedNullable = &Target{} // Target struct for Target type Target struct { - Default bool `json:"default"` - EnvVars map[string]string `json:"envVars"` - Id string `json:"id"` - LastJob *Job `json:"lastJob,omitempty"` - Metadata *TargetMetadata `json:"metadata,omitempty"` - Name string `json:"name"` - // JSON encoded map of options - Options string `json:"options"` - ProviderInfo TargetProviderInfo `json:"providerInfo"` - Workspaces []Workspace `json:"workspaces,omitempty"` + Default bool `json:"default"` + EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *TargetMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + TargetConfig TargetConfig `json:"targetConfig"` + TargetConfigId string `json:"targetConfigId"` + Workspaces []Workspace `json:"workspaces,omitempty"` } type _Target Target @@ -39,14 +38,14 @@ type _Target Target // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTarget(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo) *Target { +func NewTarget(default_ bool, envVars map[string]string, id string, name string, targetConfig TargetConfig, targetConfigId string) *Target { this := Target{} this.Default = default_ this.EnvVars = envVars this.Id = id this.Name = name - this.Options = options - this.ProviderInfo = providerInfo + this.TargetConfig = targetConfig + this.TargetConfigId = targetConfigId return &this } @@ -218,52 +217,52 @@ func (o *Target) SetName(v string) { o.Name = v } -// GetOptions returns the Options field value -func (o *Target) GetOptions() string { +// GetTargetConfig returns the TargetConfig field value +func (o *Target) GetTargetConfig() TargetConfig { if o == nil { - var ret string + var ret TargetConfig return ret } - return o.Options + return o.TargetConfig } -// GetOptionsOk returns a tuple with the Options field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *Target) GetOptionsOk() (*string, bool) { +func (o *Target) GetTargetConfigOk() (*TargetConfig, bool) { if o == nil { return nil, false } - return &o.Options, true + return &o.TargetConfig, true } -// SetOptions sets field value -func (o *Target) SetOptions(v string) { - o.Options = v +// SetTargetConfig sets field value +func (o *Target) SetTargetConfig(v TargetConfig) { + o.TargetConfig = v } -// GetProviderInfo returns the ProviderInfo field value -func (o *Target) GetProviderInfo() TargetProviderInfo { +// GetTargetConfigId returns the TargetConfigId field value +func (o *Target) GetTargetConfigId() string { if o == nil { - var ret TargetProviderInfo + var ret string return ret } - return o.ProviderInfo + return o.TargetConfigId } -// GetProviderInfoOk returns a tuple with the ProviderInfo field value +// GetTargetConfigIdOk returns a tuple with the TargetConfigId field value // and a boolean to check if the value has been set. -func (o *Target) GetProviderInfoOk() (*TargetProviderInfo, bool) { +func (o *Target) GetTargetConfigIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.ProviderInfo, true + return &o.TargetConfigId, true } -// SetProviderInfo sets field value -func (o *Target) SetProviderInfo(v TargetProviderInfo) { - o.ProviderInfo = v +// SetTargetConfigId sets field value +func (o *Target) SetTargetConfigId(v string) { + o.TargetConfigId = v } // GetWorkspaces returns the Workspaces field value if set, zero value otherwise. @@ -318,8 +317,8 @@ func (o Target) ToMap() (map[string]interface{}, error) { toSerialize["metadata"] = o.Metadata } toSerialize["name"] = o.Name - toSerialize["options"] = o.Options - toSerialize["providerInfo"] = o.ProviderInfo + toSerialize["targetConfig"] = o.TargetConfig + toSerialize["targetConfigId"] = o.TargetConfigId if !IsNil(o.Workspaces) { toSerialize["workspaces"] = o.Workspaces } @@ -335,8 +334,8 @@ func (o *Target) UnmarshalJSON(data []byte) (err error) { "envVars", "id", "name", - "options", - "providerInfo", + "targetConfig", + "targetConfigId", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_config.go b/pkg/apiclient/model_target_config.go index 3a0f45f701..40dff22f24 100644 --- a/pkg/apiclient/model_target_config.go +++ b/pkg/apiclient/model_target_config.go @@ -21,7 +21,9 @@ var _ MappedNullable = &TargetConfig{} // TargetConfig struct for TargetConfig type TargetConfig struct { - Name string `json:"name"` + Deleted bool `json:"deleted"` + Id string `json:"id"` + Name string `json:"name"` // JSON encoded map of options Options string `json:"options"` ProviderInfo TargetProviderInfo `json:"providerInfo"` @@ -33,8 +35,10 @@ type _TargetConfig TargetConfig // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetConfig(name string, options string, providerInfo TargetProviderInfo) *TargetConfig { +func NewTargetConfig(deleted bool, id string, name string, options string, providerInfo TargetProviderInfo) *TargetConfig { this := TargetConfig{} + this.Deleted = deleted + this.Id = id this.Name = name this.Options = options this.ProviderInfo = providerInfo @@ -49,6 +53,54 @@ func NewTargetConfigWithDefaults() *TargetConfig { return &this } +// GetDeleted returns the Deleted field value +func (o *TargetConfig) GetDeleted() bool { + if o == nil { + var ret bool + return ret + } + + return o.Deleted +} + +// GetDeletedOk returns a tuple with the Deleted field value +// and a boolean to check if the value has been set. +func (o *TargetConfig) GetDeletedOk() (*bool, bool) { + if o == nil { + return nil, false + } + return &o.Deleted, true +} + +// SetDeleted sets field value +func (o *TargetConfig) SetDeleted(v bool) { + o.Deleted = v +} + +// GetId returns the Id field value +func (o *TargetConfig) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *TargetConfig) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *TargetConfig) SetId(v string) { + o.Id = v +} + // GetName returns the Name field value func (o *TargetConfig) GetName() string { if o == nil { @@ -131,6 +183,8 @@ func (o TargetConfig) MarshalJSON() ([]byte, error) { func (o TargetConfig) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} + toSerialize["deleted"] = o.Deleted + toSerialize["id"] = o.Id toSerialize["name"] = o.Name toSerialize["options"] = o.Options toSerialize["providerInfo"] = o.ProviderInfo @@ -142,6 +196,8 @@ func (o *TargetConfig) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ + "deleted", + "id", "name", "options", "providerInfo", diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 46bfc7ef6f..40c984584e 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -21,18 +21,17 @@ var _ MappedNullable = &TargetDTO{} // TargetDTO struct for TargetDTO type TargetDTO struct { - Default bool `json:"default"` - EnvVars map[string]string `json:"envVars"` - Id string `json:"id"` - Info *TargetInfo `json:"info,omitempty"` - LastJob *Job `json:"lastJob,omitempty"` - Metadata *TargetMetadata `json:"metadata,omitempty"` - Name string `json:"name"` - // JSON encoded map of options - Options string `json:"options"` - ProviderInfo TargetProviderInfo `json:"providerInfo"` - State ResourceState `json:"state"` - Workspaces []Workspace `json:"workspaces,omitempty"` + Default bool `json:"default"` + EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` + Info *TargetInfo `json:"info,omitempty"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *TargetMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + State ResourceState `json:"state"` + TargetConfig TargetConfig `json:"targetConfig"` + TargetConfigId string `json:"targetConfigId"` + Workspaces []Workspace `json:"workspaces,omitempty"` } type _TargetDTO TargetDTO @@ -41,15 +40,15 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, options string, providerInfo TargetProviderInfo, state ResourceState) *TargetDTO { +func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, state ResourceState, targetConfig TargetConfig, targetConfigId string) *TargetDTO { this := TargetDTO{} this.Default = default_ this.EnvVars = envVars this.Id = id this.Name = name - this.Options = options - this.ProviderInfo = providerInfo this.State = state + this.TargetConfig = targetConfig + this.TargetConfigId = targetConfigId return &this } @@ -253,76 +252,76 @@ func (o *TargetDTO) SetName(v string) { o.Name = v } -// GetOptions returns the Options field value -func (o *TargetDTO) GetOptions() string { +// GetState returns the State field value +func (o *TargetDTO) GetState() ResourceState { if o == nil { - var ret string + var ret ResourceState return ret } - return o.Options + return o.State } -// GetOptionsOk returns a tuple with the Options field value +// GetStateOk returns a tuple with the State field value // and a boolean to check if the value has been set. -func (o *TargetDTO) GetOptionsOk() (*string, bool) { +func (o *TargetDTO) GetStateOk() (*ResourceState, bool) { if o == nil { return nil, false } - return &o.Options, true + return &o.State, true } -// SetOptions sets field value -func (o *TargetDTO) SetOptions(v string) { - o.Options = v +// SetState sets field value +func (o *TargetDTO) SetState(v ResourceState) { + o.State = v } -// GetProviderInfo returns the ProviderInfo field value -func (o *TargetDTO) GetProviderInfo() TargetProviderInfo { +// GetTargetConfig returns the TargetConfig field value +func (o *TargetDTO) GetTargetConfig() TargetConfig { if o == nil { - var ret TargetProviderInfo + var ret TargetConfig return ret } - return o.ProviderInfo + return o.TargetConfig } -// GetProviderInfoOk returns a tuple with the ProviderInfo field value +// GetTargetConfigOk returns a tuple with the TargetConfig field value // and a boolean to check if the value has been set. -func (o *TargetDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { +func (o *TargetDTO) GetTargetConfigOk() (*TargetConfig, bool) { if o == nil { return nil, false } - return &o.ProviderInfo, true + return &o.TargetConfig, true } -// SetProviderInfo sets field value -func (o *TargetDTO) SetProviderInfo(v TargetProviderInfo) { - o.ProviderInfo = v +// SetTargetConfig sets field value +func (o *TargetDTO) SetTargetConfig(v TargetConfig) { + o.TargetConfig = v } -// GetState returns the State field value -func (o *TargetDTO) GetState() ResourceState { +// GetTargetConfigId returns the TargetConfigId field value +func (o *TargetDTO) GetTargetConfigId() string { if o == nil { - var ret ResourceState + var ret string return ret } - return o.State + return o.TargetConfigId } -// GetStateOk returns a tuple with the State field value +// GetTargetConfigIdOk returns a tuple with the TargetConfigId field value // and a boolean to check if the value has been set. -func (o *TargetDTO) GetStateOk() (*ResourceState, bool) { +func (o *TargetDTO) GetTargetConfigIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.State, true + return &o.TargetConfigId, true } -// SetState sets field value -func (o *TargetDTO) SetState(v ResourceState) { - o.State = v +// SetTargetConfigId sets field value +func (o *TargetDTO) SetTargetConfigId(v string) { + o.TargetConfigId = v } // GetWorkspaces returns the Workspaces field value if set, zero value otherwise. @@ -380,9 +379,9 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["metadata"] = o.Metadata } toSerialize["name"] = o.Name - toSerialize["options"] = o.Options - toSerialize["providerInfo"] = o.ProviderInfo toSerialize["state"] = o.State + toSerialize["targetConfig"] = o.TargetConfig + toSerialize["targetConfigId"] = o.TargetConfigId if !IsNil(o.Workspaces) { toSerialize["workspaces"] = o.Workspaces } @@ -398,9 +397,9 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { "envVars", "id", "name", - "options", - "providerInfo", "state", + "targetConfig", + "targetConfigId", } allProperties := make(map[string]interface{}) diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index e934d03147..bd4845f877 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -194,7 +194,7 @@ func RunInitialScreenFlow(cmd *cobra.Command, args []string) error { case "git-provider add": return GitProviderAddCmd.RunE(cmd, []string{}) case "target-config set": - return TargetConfigSetCmd.RunE(cmd, []string{}) + return TargetConfigAddCmd.RunE(cmd, []string{}) case "docs": return DocsCmd.RunE(cmd, []string{}) case "help": diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index 8d3e0887fa..13c3ae0ada 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -18,7 +18,6 @@ import ( "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/provider" - provider_view "github.com/daytonaio/daytona/pkg/views/provider" "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/docker/docker/pkg/stringid" @@ -107,7 +106,7 @@ var providerInstallCmd = &cobra.Command{ } if slices.ContainsFunc(targets, func(t apiclient.TargetDTO) bool { - return t.ProviderInfo.Name == providerToInstall.Name + return t.TargetConfig.ProviderInfo.Name == providerToInstall.Name }) { return nil } @@ -207,7 +206,7 @@ func ConvertOSToStringMap(downloadUrls map[os.OperatingSystem]string) map[string return stringMap } -func InstallProvider(apiClient *apiclient.APIClient, providerToInstall provider_view.ProviderView, providersManifest *manager.ProvidersManifest) error { +func InstallProvider(apiClient *apiclient.APIClient, providerToInstall provider.ProviderView, providersManifest *manager.ProvidersManifest) error { downloadUrls := ConvertOSToStringMap((*providersManifest)[providerToInstall.Name].Versions[providerToInstall.Version].DownloadUrls) err := views_util.WithInlineSpinner("Installing", func() error { res, err := apiClient.ProviderAPI.InstallProviderExecute(apiclient.ApiInstallProviderRequest{}.Provider(apiclient.InstallProviderRequest{ diff --git a/pkg/cmd/provider/list.go b/pkg/cmd/provider/list.go index 1bac57a6d7..bce26c5394 100644 --- a/pkg/cmd/provider/list.go +++ b/pkg/cmd/provider/list.go @@ -11,7 +11,6 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/provider" - provider_view "github.com/daytonaio/daytona/pkg/views/provider" "github.com/spf13/cobra" ) @@ -44,18 +43,18 @@ var providerListCmd = &cobra.Command{ }, } -func GetProviderViewOptions(apiClient *apiclient.APIClient, latestProviders []apiclient.Provider, ctx context.Context) ([]provider_view.ProviderView, error) { - var result []provider_view.ProviderView +func GetProviderViewOptions(apiClient *apiclient.APIClient, latestProviders []apiclient.Provider, ctx context.Context) ([]provider.ProviderView, error) { + var result []provider.ProviderView installedProviders, res, err := apiClient.ProviderAPI.ListProviders(ctx).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - providerMap := make(map[string]provider_view.ProviderView) + providerMap := make(map[string]provider.ProviderView) for _, installedProvider := range installedProviders { - providerMap[installedProvider.Name] = provider_view.ProviderView{ + providerMap[installedProvider.Name] = provider.ProviderView{ Name: installedProvider.Name, Label: installedProvider.Label, Version: installedProvider.Version, @@ -65,7 +64,7 @@ func GetProviderViewOptions(apiClient *apiclient.APIClient, latestProviders []ap for _, latestProvider := range latestProviders { if _, exists := providerMap[latestProvider.Name]; !exists { - providerMap[latestProvider.Name] = provider_view.ProviderView{ + providerMap[latestProvider.Name] = provider.ProviderView{ Name: latestProvider.Name, Label: latestProvider.Label, Version: latestProvider.Version, diff --git a/pkg/cmd/provider/uninstall.go b/pkg/cmd/provider/uninstall.go index 08c153d4e8..01475c9176 100644 --- a/pkg/cmd/provider/uninstall.go +++ b/pkg/cmd/provider/uninstall.go @@ -8,7 +8,6 @@ import ( "fmt" "github.com/daytonaio/daytona/internal/util/apiclient" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/provider" @@ -24,14 +23,14 @@ var providerUninstallCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - apiClient, err := apiclient_util.GetApiClient(nil) + apiClient, err := apiclient.GetApiClient(nil) if err != nil { return err } providerList, res, err := apiClient.ProviderAPI.ListProviders(ctx).Execute() if err != nil { - return apiclient_util.HandleErrorResponse(res, err) + return apiclient.HandleErrorResponse(res, err) } if len(providerList) == 0 { diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index b50bb4b7ee..3cd6040ae7 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -290,7 +290,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe TargetStore: targetStore, TargetMetadataStore: targetMetadataStore, FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { - return targetConfigService.Find(&stores.TargetConfigFilter{Name: &name}) + return targetConfigService.Find(name) }, GenerateApiKey: func(ctx context.Context, name string) (string, error) { return apiKeyService.Generate(models.ApiKeyTypeTarget, name) diff --git a/pkg/cmd/server/bootstrap/init_provider_manager.go b/pkg/cmd/server/bootstrap/init_provider_manager.go index f3a19cc649..d0eefda6f0 100644 --- a/pkg/cmd/server/bootstrap/init_provider_manager.go +++ b/pkg/cmd/server/bootstrap/init_provider_manager.go @@ -16,6 +16,7 @@ import ( "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/services" ) func InitProviderManager(c *server.Config, configDir string) error { @@ -73,8 +74,13 @@ func InitProviderManager(c *server.Config, configDir string) error { GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { return targetConfigService.Map() }, - CreateTargetConfig: func(ctx context.Context, targetConfig *models.TargetConfig) error { - return targetConfigService.Save(targetConfig) + CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { + _, err := targetConfigService.Add(services.AddTargetConfigDTO{ + Name: name, + Options: options, + ProviderInfo: providerInfo, + }) + return err }, }) diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index 0d4f488a5d..f123ab0b6d 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -105,7 +105,7 @@ func CreateTargetDtoFlow(ctx context.Context, params TargetCreationParams) (*api } if len(targetConfigList) == 0 { - targetConfigView, err = targetconfig.TargetConfigCreationFlow(ctx, params.ApiClient, params.ActiveProfileName, false) + targetConfigView, err = targetconfig.TargetConfigCreationFlow(ctx, params.ApiClient, params.ActiveProfileName) if err != nil { return nil, err } @@ -124,7 +124,7 @@ func CreateTargetDtoFlow(ctx context.Context, params TargetCreationParams) (*api } if targetConfigView.Name == targetconfig_view.NewTargetConfigName { - targetConfigView, err = targetconfig.TargetConfigCreationFlow(ctx, params.ApiClient, params.ActiveProfileName, false) + targetConfigView, err = targetconfig.TargetConfigCreationFlow(ctx, params.ApiClient, params.ActiveProfileName) if err != nil { return nil, err } diff --git a/pkg/cmd/targetconfig/set.go b/pkg/cmd/targetconfig/add.go similarity index 84% rename from pkg/cmd/targetconfig/set.go rename to pkg/cmd/targetconfig/add.go index 4d5ec93ad5..0be3dc6d26 100644 --- a/pkg/cmd/targetconfig/set.go +++ b/pkg/cmd/targetconfig/add.go @@ -30,11 +30,11 @@ import ( var pipeFile string -var TargetConfigSetCmd = &cobra.Command{ - Use: "set", - Short: "Set target config", +var TargetConfigAddCmd = &cobra.Command{ + Use: "add", + Short: "Add target config", Args: cobra.NoArgs, - Aliases: []string{"s", "add", "update", "register", "edit", "new", "create"}, + Aliases: []string{"a", "set", "register", "new", "create"}, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var input []byte @@ -69,7 +69,7 @@ var TargetConfigSetCmd = &cobra.Command{ return err } - targetConfig, err := TargetConfigCreationFlow(ctx, apiClient, activeProfile.Name, true) + targetConfig, err := TargetConfigCreationFlow(ctx, apiClient, activeProfile.Name) if err != nil { return err } @@ -83,9 +83,7 @@ var TargetConfigSetCmd = &cobra.Command{ }, } -func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClient, activeProfileName string, allowUpdating bool) (*targetconfig.TargetConfigView, error) { - var isNewProvider bool - +func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClient, activeProfileName string) (*targetconfig.TargetConfigView, error) { serverConfig, res, err := apiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) @@ -136,7 +134,6 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien if err != nil { return nil, err } - isNewProvider = true } selectedTargetConfig := &targetconfig.TargetConfigView{ @@ -153,40 +150,12 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - - if allowUpdating { - filteredConfigs := []apiclient.TargetConfig{} - for _, t := range targetConfigs { - if t.ProviderInfo.Name == selectedProvider.Name { - filteredConfigs = append(filteredConfigs, t) - } - } - - if !isNewProvider || len(filteredConfigs) > 0 { - selectedTargetConfig, err = targetconfig.GetTargetConfigFromPrompt(filteredConfigs, activeProfileName, nil, true, "Set") - if err != nil { - if common.IsCtrlCAbort(err) { - return nil, nil - } else { - return nil, err - } - } - } else { - selectedTargetConfig = &targetconfig.TargetConfigView{ - Name: targetconfig.NewTargetConfigName, - Options: "{}", - } - } - } - - if !allowUpdating || selectedTargetConfig.Name == targetconfig.NewTargetConfigName { - selectedTargetConfig.Name = "" - err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, internal_util.ArrayMap(targetConfigs, func(t apiclient.TargetConfig) string { - return t.Name - })) - if err != nil { - return nil, err - } + selectedTargetConfig.Name = "" + err = targetconfig.NewTargetConfigNameInput(&selectedTargetConfig.Name, internal_util.ArrayMap(targetConfigs, func(t apiclient.TargetConfig) string { + return t.Name + })) + if err != nil { + return nil, err } targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedProvider.Name).Execute() @@ -199,7 +168,7 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, err } - targetConfigData := apiclient.CreateTargetConfigDTO{ + targetConfigData := apiclient.AddTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, ProviderInfo: apiclient.TargetProviderInfo{ @@ -209,12 +178,13 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien }, } - targetConfig, res, err := apiClient.TargetConfigAPI.SetTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() + targetConfig, res, err := apiClient.TargetConfigAPI.AddTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } return &targetconfig.TargetConfigView{ + Id: targetConfig.Id, Name: targetConfig.Name, Options: targetConfig.Options, ProviderInfo: targetconfig.ProviderInfo{ @@ -252,7 +222,7 @@ func handleTargetConfigJSON(data []byte) error { if err != nil { return err } - targetConfigData := apiclient.CreateTargetConfigDTO{ + targetConfigData := apiclient.AddTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, ProviderInfo: apiclient.TargetProviderInfo{ @@ -260,7 +230,7 @@ func handleTargetConfigJSON(data []byte) error { Version: selectedTargetConfig.ProviderInfo.Version, }, } - _, res, err = apiClient.TargetConfigAPI.SetTargetConfig(ctx).TargetConfig(targetConfigData).Execute() + _, res, err = apiClient.TargetConfigAPI.AddTargetConfig(ctx).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -365,5 +335,5 @@ func contains(slice []string, item interface{}) bool { } func init() { - TargetConfigSetCmd.Flags().StringVarP(&pipeFile, "file", "f", "", "Path to JSON file for target configuration, use '-' to read from stdin") + TargetConfigAddCmd.Flags().StringVarP(&pipeFile, "file", "f", "", "Path to JSON file for target configuration, use '-' to read from stdin") } diff --git a/pkg/cmd/targetconfig/remove.go b/pkg/cmd/targetconfig/remove.go index 1c0f5b2886..e6f119ef81 100644 --- a/pkg/cmd/targetconfig/remove.go +++ b/pkg/cmd/targetconfig/remove.go @@ -19,7 +19,7 @@ import ( var yesFlag bool var removeCmd = &cobra.Command{ - Use: "remove [CONFIG_NAME]", + Use: "remove [TARGET_CONFIG]", Short: "Remove target config", Args: cobra.RangeArgs(0, 1), Aliases: []string{"rm", "delete"}, diff --git a/pkg/cmd/targetconfig/target_config.go b/pkg/cmd/targetconfig/target_config.go index 827bf9a098..71f08b1f9b 100644 --- a/pkg/cmd/targetconfig/target_config.go +++ b/pkg/cmd/targetconfig/target_config.go @@ -17,6 +17,6 @@ var TargetConfigCmd = &cobra.Command{ func init() { TargetConfigCmd.AddCommand(listCmd) - TargetConfigCmd.AddCommand(TargetConfigSetCmd) + TargetConfigCmd.AddCommand(TargetConfigAddCmd) TargetConfigCmd.AddCommand(removeCmd) } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 59fc4f13a5..b318c78806 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -192,11 +192,11 @@ var CreateCmd = &cobra.Command{ } target = &apiclient.TargetDTO{ - Id: t.Id, - Name: t.Name, - Options: t.Options, - ProviderInfo: t.ProviderInfo, - Default: t.Default, + Id: t.Id, + Name: t.Name, + TargetConfig: t.TargetConfig, + TargetConfigId: t.TargetConfigId, + Default: t.Default, } } @@ -383,9 +383,9 @@ func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile } func IsLocalDockerTarget(target *apiclient.TargetDTO) bool { - if target.ProviderInfo.Name != "docker-provider" { + if target.TargetConfig.ProviderInfo.Name != "docker-provider" { return false } - return !strings.Contains(target.Options, "Remote Hostname") + return !strings.Contains(target.TargetConfig.Options, "Remote Hostname") } diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index 06ef717cb3..e8f4a9b393 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -23,9 +23,9 @@ func NewTargetConfigStore(db *gorm.DB) (stores.TargetConfigStore, error) { return &TargetConfigStore{db: db}, nil } -func (s *TargetConfigStore) List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { +func (s *TargetConfigStore) List(allowDeleted bool) ([]*models.TargetConfig, error) { targetConfigs := []*models.TargetConfig{} - tx := processTargetConfigFilters(s.db, filter).Find(&targetConfigs) + tx := processTargetConfigFilters(s.db, "", allowDeleted).Find(&targetConfigs) if tx.Error != nil { return nil, tx.Error @@ -34,9 +34,9 @@ func (s *TargetConfigStore) List(filter *stores.TargetConfigFilter) ([]*models.T return targetConfigs, nil } -func (s *TargetConfigStore) Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) { +func (s *TargetConfigStore) Find(idOrName string, allowDeleted bool) (*models.TargetConfig, error) { targetConfig := &models.TargetConfig{} - tx := processTargetConfigFilters(s.db, filter).First(targetConfig) + tx := processTargetConfigFilters(s.db, idOrName, allowDeleted).First(targetConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { @@ -57,23 +57,13 @@ func (s *TargetConfigStore) Save(targetConfig *models.TargetConfig) error { return nil } -func (s *TargetConfigStore) Delete(targetConfig *models.TargetConfig) error { - tx := s.db.Delete(targetConfig) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return stores.ErrTargetConfigNotFound +func processTargetConfigFilters(tx *gorm.DB, idOrName string, allowDeleted bool) *gorm.DB { + if idOrName != "" { + tx = tx.Where("id = ? OR name = ?", idOrName, idOrName) } - return nil -} - -func processTargetConfigFilters(tx *gorm.DB, filter *stores.TargetConfigFilter) *gorm.DB { - if filter != nil { - if filter.Name != nil { - tx = tx.Where("name = ?", *filter.Name) - } + if !allowDeleted { + tx = tx.Where("deleted = ?", false) } return tx diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go index 876e9abac4..92cb7cf373 100644 --- a/pkg/db/workspace_store.go +++ b/pkg/db/workspace_store.go @@ -26,7 +26,6 @@ func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { func (s *WorkspaceStore) List() ([]*models.Workspace, error) { workspaces := []*models.Workspace{} - // Order workspace jobs by created_at tx := preloadWorkspaceEntities(s.db).Find(&workspaces) if tx.Error != nil { return nil, tx.Error @@ -70,5 +69,5 @@ func (s *WorkspaceStore) Delete(workspace *models.Workspace) error { } func preloadWorkspaceEntities(tx *gorm.DB) *gorm.DB { - return tx.Preload(clause.Associations).Preload("LastJob", preloadLastJob) + return tx.Preload(clause.Associations).Preload("Target.TargetConfig").Preload("LastJob", preloadLastJob) } diff --git a/pkg/docker/client_test.go b/pkg/docker/client_test.go index d7ca1c6ad4..fd1b4f7865 100644 --- a/pkg/docker/client_test.go +++ b/pkg/docker/client_test.go @@ -26,14 +26,21 @@ var workspace1 = &models.Workspace{ BuildConfig: &models.BuildConfig{}, } -var target1 = &models.Target{ - Id: "123", +var targetConfig1 = &models.TargetConfig{ Name: "test", ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, Options: "test-options", + Deleted: false, +} + +var target1 = &models.Target{ + Id: "123", + Name: "test", + TargetConfigId: targetConfig1.Id, + TargetConfig: *targetConfig1, } type DockerClientTestSuiteConfig struct { diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go index 7af80e2437..b163a02e3d 100644 --- a/pkg/docker/info_test.go +++ b/pkg/docker/info_test.go @@ -45,14 +45,21 @@ func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { } func (s *DockerClientTestSuite) TestGetTargetInfo() { - targetWithoutWorkspaces := &models.Target{ - Id: "123", + var targetConfig = &models.TargetConfig{ Name: "test", ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, - Options: "", + Options: "test-options", + Deleted: false, + } + + targetWithoutWorkspaces := &models.Target{ + Id: "123", + Name: "test", + TargetConfigId: targetConfig.Id, + TargetConfig: *targetConfig, } targetInfo, err := s.dockerClient.GetTargetInfo(targetWithoutWorkspaces) diff --git a/pkg/models/target.go b/pkg/models/target.go index cebe16a219..2fabdd8118 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -15,17 +15,16 @@ const AGENT_UNRESPONSIVE_THRESHOLD = 30 * time.Second var providersWithoutTargetMode = []string{"docker-provider"} type Target struct { - Id string `json:"id" validate:"required" gorm:"primaryKey"` - Name string `json:"name" validate:"required"` - ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json"` - // JSON encoded map of options - Options string `json:"options" validate:"required"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` - IsDefault bool `json:"default" validate:"required"` - Workspaces []Workspace `gorm:"foreignKey:TargetId;references:Id"` - Metadata *TargetMetadata `gorm:"foreignKey:TargetId;references:Id" validate:"optional"` - LastJob *Job `gorm:"foreignKey:ResourceId;references:Id" validate:"optional"` + Id string `json:"id" validate:"required" gorm:"primaryKey"` + Name string `json:"name" validate:"required"` + TargetConfigId string `json:"targetConfigId" validate:"required" gorm:"foreignKey:TargetConfigId;references:Id"` + TargetConfig TargetConfig `json:"targetConfig" validate:"required" gorm:"foreignKey:TargetConfigId"` + ApiKey string `json:"-"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` + IsDefault bool `json:"default" validate:"required"` + Workspaces []Workspace `gorm:"foreignKey:TargetId;references:Id"` + Metadata *TargetMetadata `gorm:"foreignKey:TargetId;references:Id" validate:"optional"` + LastJob *Job `gorm:"foreignKey:ResourceId;references:Id" validate:"optional"` } // @name Target type TargetMetadata struct { @@ -38,7 +37,7 @@ func (t *Target) GetState() ResourceState { state := getResourceStateFromJob(t.LastJob) // Some providers do not utilize agents in target mode - if state.Name != ResourceStateNameDeleted && slices.Contains(providersWithoutTargetMode, t.ProviderInfo.Name) { + if state.Name != ResourceStateNameDeleted && slices.Contains(providersWithoutTargetMode, t.TargetConfig.ProviderInfo.Name) { return ResourceState{ Name: ResourceStateNameUndefined, UpdatedAt: time.Now(), diff --git a/pkg/models/target_config.go b/pkg/models/target_config.go index a6868bc51b..00af4d96c5 100644 --- a/pkg/models/target_config.go +++ b/pkg/models/target_config.go @@ -4,8 +4,10 @@ package models type TargetConfig struct { - Name string `json:"name" validate:"required" gorm:"primaryKey"` + Id string `json:"id" validate:"required" gorm:"primaryKey"` + Name string `json:"name" validate:"required"` ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json"` // JSON encoded map of options Options string `json:"options" validate:"required"` + Deleted bool `json:"deleted" validate:"required"` } // @name TargetConfig diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index 1c9d925da9..a16143de4f 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -50,7 +50,7 @@ type IProviderManager interface { type ProviderManagerConfig struct { GetTargetConfigMap func(ctx context.Context) (map[string]*models.TargetConfig, error) - CreateTargetConfig func(ctx context.Context, targetConfig *models.TargetConfig) error + CreateTargetConfig func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error CreateProviderNetworkKey func(ctx context.Context, providerName string) (string, error) DaytonaDownloadUrl string ServerUrl string @@ -98,7 +98,7 @@ func GetProviderManager(config *ProviderManagerConfig) *ProviderManager { type ProviderManager struct { pluginRefs map[string]*pluginRef getTargetConfigMap func(ctx context.Context) (map[string]*models.TargetConfig, error) - createTargetConfig func(ctx context.Context, targetConfig *models.TargetConfig) error + createTargetConfig func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error createProviderNetworkKey func(ctx context.Context, providerName string) (string, error) daytonaDownloadUrl string serverUrl string @@ -189,15 +189,12 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool continue } - err = m.createTargetConfig(ctx, &models.TargetConfig{ - Name: targetConfig.Name, - ProviderInfo: models.ProviderInfo{ + err = m.createTargetConfig(ctx, targetConfig.Name, targetConfig.Options, + models.ProviderInfo{ Name: providerInfo.Name, Version: providerInfo.Version, Label: providerInfo.Label, - }, - Options: targetConfig.Options, - }) + }) if err != nil { log.Errorf("Failed to set target config %s: %s", targetConfig.Name, err) } else { diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index da3bf7a795..eac2496e2a 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -9,7 +9,7 @@ import ( ) func (p *Provisioner) CreateTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) if err != nil { return err } @@ -22,7 +22,7 @@ func (p *Provisioner) CreateTarget(t *models.Target) error { } func (p *Provisioner) CreateWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.TargetConfig.ProviderInfo.Name) if err != nil { return err } diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go index dd23977a58..2d774a3d3d 100644 --- a/pkg/provisioner/destroy.go +++ b/pkg/provisioner/destroy.go @@ -9,7 +9,7 @@ import ( ) func (p *Provisioner) DestroyTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) if err != nil { return err } @@ -22,7 +22,7 @@ func (p *Provisioner) DestroyTarget(t *models.Target) error { } func (p *Provisioner) DestroyWorkspace(ws *models.Workspace) error { - targetProvider, err := p.providerManager.GetProvider(ws.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(ws.Target.TargetConfig.ProviderInfo.Name) if err != nil { return err } diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go index d64f20c66e..feda44c526 100644 --- a/pkg/provisioner/info.go +++ b/pkg/provisioner/info.go @@ -20,7 +20,7 @@ func (p *Provisioner) GetTargetInfo(ctx context.Context, t *models.Target) (*mod ch := make(chan TargetInfoResult, 1) go func() { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) if err != nil { ch <- TargetInfoResult{nil, err} return @@ -51,7 +51,7 @@ func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *models.Wo ch := make(chan WorkspaceInfoResult, 1) go func() { - targetProvider, err := p.providerManager.GetProvider(workspace.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(workspace.Target.TargetConfig.ProviderInfo.Name) if err != nil { ch <- WorkspaceInfoResult{nil, err} return diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index 9e018b4e26..37065a0b2b 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -9,7 +9,7 @@ import ( ) func (p *Provisioner) StartTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) if err != nil { return err } @@ -22,7 +22,7 @@ func (p *Provisioner) StartTarget(t *models.Target) error { } func (p *Provisioner) StartWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.TargetConfig.ProviderInfo.Name) if err != nil { return err } diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go index f1e1dcb7b7..e372f2403e 100644 --- a/pkg/provisioner/stop.go +++ b/pkg/provisioner/stop.go @@ -9,7 +9,7 @@ import ( ) func (p *Provisioner) StopTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) if err != nil { return err } @@ -22,7 +22,7 @@ func (p *Provisioner) StopTarget(t *models.Target) error { } func (p *Provisioner) StopWorkspace(ws *models.Workspace) error { - targetProvider, err := p.providerManager.GetProvider(ws.Target.ProviderInfo.Name) + targetProvider, err := p.providerManager.GetProvider(ws.Target.TargetConfig.ProviderInfo.Name) if err != nil { return err } diff --git a/pkg/server/targetconfigs/dto/target_config.go b/pkg/server/targetconfigs/dto/target_config.go deleted file mode 100644 index 7c1918fbf2..0000000000 --- a/pkg/server/targetconfigs/dto/target_config.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import "github.com/daytonaio/daytona/pkg/models" - -type CreateTargetConfigDTO struct { - Name string `json:"name" validate:"required"` - ProviderInfo models.ProviderInfo `json:"providerInfo" validate:"required"` - Options string `json:"options" validate:"required"` -} // @name CreateTargetConfigDTO diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index f4af8f801c..41985d4ce9 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -7,6 +7,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/docker/docker/pkg/stringid" ) type TargetConfigServiceConfig struct { @@ -23,12 +24,12 @@ func NewTargetConfigService(config TargetConfigServiceConfig) services.ITargetCo } } -func (s *TargetConfigService) List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) { - return s.targetConfigStore.List(filter) +func (s *TargetConfigService) List() ([]*models.TargetConfig, error) { + return s.targetConfigStore.List(false) } func (s *TargetConfigService) Map() (map[string]*models.TargetConfig, error) { - list, err := s.targetConfigStore.List(nil) + list, err := s.targetConfigStore.List(false) if err != nil { return nil, err } @@ -41,14 +42,36 @@ func (s *TargetConfigService) Map() (map[string]*models.TargetConfig, error) { return targetConfigs, nil } -func (s *TargetConfigService) Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) { - return s.targetConfigStore.Find(filter) +func (s *TargetConfigService) Find(idOrName string) (*models.TargetConfig, error) { + return s.targetConfigStore.Find(idOrName, false) } -func (s *TargetConfigService) Save(targetConfig *models.TargetConfig) error { - return s.targetConfigStore.Save(targetConfig) +func (s *TargetConfigService) Add(addTargetConfig services.AddTargetConfigDTO) (*models.TargetConfig, error) { + persistedTargetConfig, err := s.targetConfigStore.Find(addTargetConfig.Name, false) + if err != nil && !stores.IsTargetConfigNotFound(err) { + return nil, err + } + if persistedTargetConfig != nil && !persistedTargetConfig.Deleted { + return nil, stores.ErrTargetConfigAlreadyExists + } + + targetConfig := &models.TargetConfig{ + Id: stringid.GenerateRandomID(), + Name: addTargetConfig.Name, + ProviderInfo: addTargetConfig.ProviderInfo, + Options: addTargetConfig.Options, + Deleted: false, + } + + return targetConfig, s.targetConfigStore.Save(targetConfig) } -func (s *TargetConfigService) Delete(targetConfig *models.TargetConfig) error { - return s.targetConfigStore.Delete(targetConfig) +func (s *TargetConfigService) Delete(targetConfigId string) error { + targetConfig, err := s.targetConfigStore.Find(targetConfigId, false) + if err != nil { + return err + } + targetConfig.Deleted = true + + return s.targetConfigStore.Save(targetConfig) } diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go index 05298f0f73..ca995e1351 100644 --- a/pkg/server/targetconfigs/service_test.go +++ b/pkg/server/targetconfigs/service_test.go @@ -80,7 +80,15 @@ func (s *TargetConfigServiceTestSuite) SetupTest() { }) for _, targetConfig := range expectedConfigs { - _ = s.targetConfigService.Save(targetConfig) + tc, err := s.targetConfigService.Add(services.AddTargetConfigDTO{ + Name: targetConfig.Name, + ProviderInfo: targetConfig.ProviderInfo, + Options: targetConfig.Options, + }) + if err != nil { + panic(err) + } + targetConfig.Id = tc.Id } } @@ -91,7 +99,7 @@ func TestTargetConfigService(t *testing.T) { func (s *TargetConfigServiceTestSuite) TestList() { require := s.Require() - targetConfigs, err := s.targetConfigService.List(nil) + targetConfigs, err := s.targetConfigService.List() require.Nil(err) require.ElementsMatch(expectedConfigs, targetConfigs) } @@ -107,35 +115,39 @@ func (s *TargetConfigServiceTestSuite) TestMap() { func (s *TargetConfigServiceTestSuite) TestFind() { require := s.Require() - targetConfig, err := s.targetConfigService.Find(&stores.TargetConfigFilter{ - Name: &targetConfig1.Name, - }) + targetConfig, err := s.targetConfigService.Find(targetConfig1.Id) require.Nil(err) require.Equal(targetConfig1, targetConfig) } func (s *TargetConfigServiceTestSuite) TestSave() { - expectedConfigs = append(expectedConfigs, targetConfig4) - require := s.Require() - err := s.targetConfigService.Save(targetConfig4) + tc, err := s.targetConfigService.Add(services.AddTargetConfigDTO{ + Name: targetConfig4.Name, + ProviderInfo: targetConfig4.ProviderInfo, + Options: targetConfig4.Options, + }) require.Nil(err) - targetConfigs, err := s.targetConfigService.List(nil) + targetConfig4.Id = tc.Id + expectedConfigs = append(expectedConfigs, targetConfig4) + + targetConfigs, err := s.targetConfigService.List() require.Nil(err) require.ElementsMatch(expectedConfigs, targetConfigs) } func (s *TargetConfigServiceTestSuite) TestDelete() { - expectedConfigs = expectedConfigs[:2] + expected := expectedConfigs[:2] require := s.Require() - err := s.targetConfigService.Delete(targetConfig3) + err := s.targetConfigService.Delete(targetConfig3.Id) require.Nil(err) - targetConfigs, err := s.targetConfigService.List(nil) + targetConfigs, err := s.targetConfigService.List() require.Nil(err) - require.ElementsMatch(expectedConfigs, targetConfigs) + + require.ElementsMatch(expected, targetConfigs) } diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index 5c93973d9b..b569740554 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -33,10 +33,10 @@ func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDT } tg := &models.Target{ - Id: req.Id, - Name: req.Name, - ProviderInfo: tc.ProviderInfo, - Options: tc.Options, + Id: req.Id, + Name: req.Name, + TargetConfigId: tc.Id, + TargetConfig: *tc, } apiKey, err := s.generateApiKey(ctx, tg.Id) diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index c4cbb7681d..4da77e12bc 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -25,15 +25,22 @@ import ( const serverApiUrl = "http://localhost:3986" const serverUrl = "http://localhost:3987" -var tg = &models.Target{ - Id: "test", - Name: "test", - ApiKey: "test", +var tc = models.TargetConfig{ + Name: "test", ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, Options: "test-options", + Deleted: false, +} + +var tg = &models.Target{ + Id: "test", + Name: "test", + ApiKey: "test", + TargetConfigId: tc.Id, + TargetConfig: tc, } var createTargetDTO = dto.CreateTargetDTO{ @@ -42,15 +49,6 @@ var createTargetDTO = dto.CreateTargetDTO{ TargetConfigName: "test", } -var tc = models.TargetConfig{ - Name: "test", - ProviderInfo: models.ProviderInfo{ - Name: "test-provider", - Version: "test", - }, - Options: "test-options", -} - var targetInfo = models.TargetInfo{ Name: createTargetDTO.Name, ProviderMetadata: "provider-metadata-test", @@ -83,7 +81,7 @@ func TestTargetService(t *testing.T) { TargetStore: targetStore, TargetMetadataStore: targetMetadataStore, FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { - return targetConfigStore.Find(&stores.TargetConfigFilter{Name: &name}) + return targetConfigStore.Find(name, false) }, GenerateApiKey: func(ctx context.Context, name string) (string, error) { return apiKeyService.Generate(models.ApiKeyTypeTarget, name) @@ -244,8 +242,8 @@ func targetEquals(t *testing.T, t1, t2 *models.Target) { require.Equal(t, t1.Id, t2.Id) require.Equal(t, t1.Name, t2.Name) - require.Equal(t, t1.ProviderInfo, t2.ProviderInfo) - require.Equal(t, t1.Options, t2.Options) + require.Equal(t, t1.TargetConfig.ProviderInfo, t2.TargetConfig.ProviderInfo) + require.Equal(t, t1.TargetConfig.Options, t2.TargetConfig.Options) require.Equal(t, t1.IsDefault, t2.IsDefault) } @@ -254,8 +252,8 @@ func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO require.Equal(t, req.Id, target.Id) require.Equal(t, req.Name, target.Name) - require.Equal(t, tc.ProviderInfo, target.ProviderInfo) - require.Equal(t, tc.Options, target.Options) + require.Equal(t, tc.ProviderInfo, target.TargetConfig.ProviderInfo) + require.Equal(t, tc.Options, target.TargetConfig.Options) if verbose { require.Equal(t, target.Info.Name, targetInfo.Name) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index 90af77c01e..65c725d7e1 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -42,10 +42,10 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { func TargetDtoToTarget(targetDto dto.TargetDTO) *models.Target { return &models.Target{ - Id: targetDto.Id, - Name: targetDto.Name, - ProviderInfo: targetDto.ProviderInfo, - Options: targetDto.Options, - IsDefault: targetDto.IsDefault, + Id: targetDto.Id, + Name: targetDto.Name, + TargetConfigId: targetDto.TargetConfigId, + TargetConfig: targetDto.TargetConfig, + IsDefault: targetDto.IsDefault, } } diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index a36f0b57cc..aaed9c0fbe 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -43,14 +43,21 @@ var gitProviderConfig = models.GitProviderConfig{ BaseApiUrl: &baseApiUrl, } -var tg = &models.Target{ - Id: "123", - Name: "test", +var tc = &models.TargetConfig{ + Name: "tc-test", ProviderInfo: models.ProviderInfo{ Name: "test-provider", Version: "test", }, Options: "test-options", + Deleted: false, +} + +var tg = &models.Target{ + Id: "123", + Name: "test", + TargetConfigId: tc.Id, + TargetConfig: *tc, } var createWorkspaceDTO = services.CreateWorkspaceDTO{ @@ -213,7 +220,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, workspace) - workspaceEquals(t, &services.WorkspaceDTO{Workspace: *ws}, workspace, defaultWorkspaceImage) + workspaceEquals(t, &services.WorkspaceDTO{Workspace: *ws}, workspace) ws.EnvVars = nil }) @@ -340,7 +347,7 @@ func TestTargetService(t *testing.T) { }) } -func workspaceEquals(t *testing.T, ws1, ws2 *services.WorkspaceDTO, workspaceImage string) { +func workspaceEquals(t *testing.T, ws1, ws2 *services.WorkspaceDTO) { t.Helper() require.Equal(t, ws1.Id, ws2.Id) diff --git a/pkg/services/target_config.go b/pkg/services/target_config.go index 9235208888..d14043d93a 100644 --- a/pkg/services/target_config.go +++ b/pkg/services/target_config.go @@ -5,13 +5,18 @@ package services import ( "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" ) +type AddTargetConfigDTO struct { + Name string `json:"name" validate:"required"` + ProviderInfo models.ProviderInfo `json:"providerInfo" validate:"required"` + Options string `json:"options" validate:"required"` +} // @name AddTargetConfigDTO + type ITargetConfigService interface { - Delete(targetConfig *models.TargetConfig) error - Find(filter *stores.TargetConfigFilter) (*models.TargetConfig, error) - List(filter *stores.TargetConfigFilter) ([]*models.TargetConfig, error) + Add(targetConfig AddTargetConfigDTO) (*models.TargetConfig, error) + Find(idOrName string) (*models.TargetConfig, error) + List() ([]*models.TargetConfig, error) Map() (map[string]*models.TargetConfig, error) - Save(targetConfig *models.TargetConfig) error + Delete(targetConfigId string) error } diff --git a/pkg/stores/target_config.go b/pkg/stores/target_config.go index 4601688855..7fb4bcca75 100644 --- a/pkg/stores/target_config.go +++ b/pkg/stores/target_config.go @@ -9,19 +9,15 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -type TargetConfigFilter struct { - Name *string -} - type TargetConfigStore interface { - List(filter *TargetConfigFilter) ([]*models.TargetConfig, error) - Find(filter *TargetConfigFilter) (*models.TargetConfig, error) + List(allowDeleted bool) ([]*models.TargetConfig, error) + Find(idOrName string, allowDeleted bool) (*models.TargetConfig, error) Save(targetConfig *models.TargetConfig) error - Delete(targetConfig *models.TargetConfig) error } var ( - ErrTargetConfigNotFound = errors.New("target config not found") + ErrTargetConfigNotFound = errors.New("target config not found") + ErrTargetConfigAlreadyExists = errors.New("target config with the same name already exists") ) func IsTargetConfigNotFound(err error) bool { diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go index b969e4390a..344763f2e1 100644 --- a/pkg/telemetry/server_events.go +++ b/pkg/telemetry/server_events.go @@ -54,8 +54,8 @@ func NewTargetEventProps(ctx context.Context, target *models.Target) map[string] if target != nil { props["target_id"] = target.Id props["target_name"] = target.Name - props["target_provider"] = target.ProviderInfo.Name - props["target_provider_version"] = target.ProviderInfo.Version + props["target_provider"] = target.TargetConfig.ProviderInfo.Name + props["target_provider_version"] = target.TargetConfig.ProviderInfo.Version } return props @@ -68,8 +68,8 @@ func NewWorkspaceEventProps(ctx context.Context, workspace *models.Workspace) ma return props } - props["workspace_provider"] = workspace.Target.ProviderInfo.Name - props["workspace_provider_version"] = workspace.Target.ProviderInfo.Version + props["workspace_provider"] = workspace.Target.TargetConfig.ProviderInfo.Name + props["workspace_provider_version"] = workspace.Target.TargetConfig.ProviderInfo.Version if isImagePublic(workspace.Image) { props["workspace_image"] = workspace.Image diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index 5e6a5bbda3..eca5b5f33f 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -32,9 +32,9 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("ID", target.Id) + "\n" - providerLabel := target.ProviderInfo.Name - if target.ProviderInfo.Label != nil { - providerLabel = *target.ProviderInfo.Label + providerLabel := target.TargetConfig.ProviderInfo.Name + if target.TargetConfig.ProviderInfo.Label != nil { + providerLabel = *target.TargetConfig.ProviderInfo.Label } output += getInfoLine("Provider", providerLabel) + "\n" @@ -48,7 +48,12 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("Error", *target.State.Error) + "\n" } - output += getInfoLine("Options", target.Options) + "\n" + output += getInfoLineState("State", target.State, target.Metadata) + "\n" + if target.State.Error != nil { + output += getInfoLine("Error", *target.State.Error) + "\n" + } + + output += getInfoLine("Options", target.TargetConfig.Options) + "\n" if target.Info != nil { output += getInfoLine("Metadata", *target.Info.ProviderMetadata) + "\n" diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index 04c60ad7a7..5f3ee36a32 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -36,15 +36,15 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa headers := []string{"Target", "Options", "# Workspaces", "Default", "Status"} data := util.ArrayMap(targetList, func(target apiclient.TargetDTO) []string { - provider := target.ProviderInfo.Name - if target.ProviderInfo.Label != nil { - provider = *target.ProviderInfo.Label + provider := target.TargetConfig.ProviderInfo.Name + if target.TargetConfig.ProviderInfo.Label != nil { + provider = *target.TargetConfig.ProviderInfo.Label } rowData := RowData{ Name: target.Name, Provider: provider, - Options: target.Options, + Options: target.TargetConfig.Options, WorkspaceCount: fmt.Sprint(len(target.Workspaces)), Default: target.Default, Status: views.GetStateLabel(target.State.Name), diff --git a/pkg/views/target/selection/target.go b/pkg/views/target/selection/target.go index 679d6c8bb8..919994e162 100644 --- a/pkg/views/target/selection/target.go +++ b/pkg/views/target/selection/target.go @@ -26,10 +26,10 @@ func generateTargetList(targets []apiclient.TargetDTO, isMultipleSelect bool, wi for _, target := range targets { var providerName string - if target.ProviderInfo.Label != nil { - providerName = *target.ProviderInfo.Label + if target.TargetConfig.ProviderInfo.Label != nil { + providerName = *target.TargetConfig.ProviderInfo.Label } else { - providerName = target.ProviderInfo.Name + providerName = target.TargetConfig.ProviderInfo.Name } stateLabel := views.GetStateLabel(target.State.Name) diff --git a/pkg/views/targetconfig/list.go b/pkg/views/targetconfig/list.go index 675e30fd78..70b52d5352 100644 --- a/pkg/views/targetconfig/list.go +++ b/pkg/views/targetconfig/list.go @@ -19,6 +19,11 @@ type rowData struct { } func ListTargetConfigs(targetConfigs []apiclient.TargetConfig) { + if len(targetConfigs) == 0 { + util.NotifyEmptyTargetConfigList(true) + return + } + sortTargetConfigs(&targetConfigs) data := [][]string{} diff --git a/pkg/views/targetconfig/select.go b/pkg/views/targetconfig/select.go index 26693a4a3e..d65e2be33e 100644 --- a/pkg/views/targetconfig/select.go +++ b/pkg/views/targetconfig/select.go @@ -18,6 +18,7 @@ import ( const NewTargetConfigName = "+ New Target Config" type TargetConfigView struct { + Id string Name string Options string ProviderInfo ProviderInfo From 431c8450be44329a9b1d37f588b7a66ac5c3779b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 28 Nov 2024 13:15:44 +0100 Subject: [PATCH 14/76] refactor: change profile data to server env vars (#1361) Signed-off-by: Luka Brecic --- docs/daytona.md | 2 +- docs/daytona_env.md | 7 +- docs/daytona_env_list.md | 4 +- docs/daytona_env_remove.md | 18 ++ docs/daytona_env_set.md | 4 +- hack/docs/daytona.yaml | 2 +- hack/docs/daytona_env.yaml | 7 +- hack/docs/daytona_env_list.yaml | 4 +- hack/docs/daytona_env_remove.yaml | 9 + hack/docs/daytona_env_set.yaml | 4 +- internal/testing/server/env/store.go | 44 ++++ internal/testing/server/profiledata/store.go | 39 ---- internal/util/apiclient/conversion/env.go | 16 ++ pkg/api/controllers/env/env.go | 96 +++++++++ .../controllers/profiledata/profile_data.go | 92 -------- pkg/api/docs/docs.go | 169 ++++++++------- pkg/api/docs/swagger.json | 169 ++++++++------- pkg/api/docs/swagger.yaml | 113 +++++----- pkg/api/server.go | 10 +- pkg/apiclient/README.md | 8 +- pkg/apiclient/api/openapi.yaml | 123 ++++++----- .../{api_profile.go => api_env_var.go} | 103 ++++----- pkg/apiclient/client.go | 6 +- pkg/apiclient/docs/EnvVarAPI.md | 204 ++++++++++++++++++ pkg/apiclient/docs/EnvironmentVariable.md | 72 +++++++ pkg/apiclient/docs/ProfileAPI.md | 195 ----------------- pkg/apiclient/docs/ProfileData.md | 72 ------- pkg/apiclient/model_environment_variable.go | 184 ++++++++++++++++ pkg/apiclient/model_profile_data.go | 184 ---------------- pkg/cmd/build/run.go | 7 +- pkg/cmd/cmd.go | 2 +- pkg/cmd/env/delete.go | 54 +++++ pkg/cmd/{profiledata => }/env/env.go | 5 +- pkg/cmd/{profiledata => }/env/list.go | 19 +- pkg/cmd/env/set.go | 62 ++++++ pkg/cmd/profiledata/env/set.go | 66 ------ .../server/bootstrap/get_server_instance.go | 40 ++-- pkg/cmd/workspace/create/cmd.go | 7 +- pkg/db/env.go | 57 +++++ pkg/db/profile_data_store.go | 57 ----- pkg/models/env.go | 9 + pkg/models/profile_data.go | 9 - pkg/server/env/service.go | 36 ++++ pkg/server/env/service_test.go | 74 +++++++ pkg/server/profiledata/service.go | 48 ----- pkg/server/profiledata/service_test.go | 76 ------- pkg/server/server.go | 100 ++++----- pkg/services/env.go | 12 ++ pkg/services/profile_data.go | 12 -- pkg/stores/env.go | 24 +++ pkg/stores/profile_data.go | 26 --- pkg/views/env/add.go | 53 +++++ pkg/views/env/delete.go | 23 ++ pkg/views/env/list.go | 15 +- pkg/views/env/selection/env.go | 108 ++++++++++ pkg/views/env/selection/view.go | 203 +++++++++++++++++ pkg/views/util/empty_list.go | 4 +- 57 files changed, 1849 insertions(+), 1319 deletions(-) create mode 100644 docs/daytona_env_remove.md create mode 100644 hack/docs/daytona_env_remove.yaml create mode 100644 internal/testing/server/env/store.go delete mode 100644 internal/testing/server/profiledata/store.go create mode 100644 internal/util/apiclient/conversion/env.go create mode 100644 pkg/api/controllers/env/env.go delete mode 100644 pkg/api/controllers/profiledata/profile_data.go rename pkg/apiclient/{api_profile.go => api_env_var.go} (72%) create mode 100644 pkg/apiclient/docs/EnvVarAPI.md create mode 100644 pkg/apiclient/docs/EnvironmentVariable.md delete mode 100644 pkg/apiclient/docs/ProfileAPI.md delete mode 100644 pkg/apiclient/docs/ProfileData.md create mode 100644 pkg/apiclient/model_environment_variable.go delete mode 100644 pkg/apiclient/model_profile_data.go create mode 100644 pkg/cmd/env/delete.go rename pkg/cmd/{profiledata => }/env/env.go (66%) rename pkg/cmd/{profiledata => }/env/list.go (55%) create mode 100644 pkg/cmd/env/set.go delete mode 100644 pkg/cmd/profiledata/env/set.go create mode 100644 pkg/db/env.go delete mode 100644 pkg/db/profile_data_store.go create mode 100644 pkg/models/env.go delete mode 100644 pkg/models/profile_data.go create mode 100644 pkg/server/env/service.go create mode 100644 pkg/server/env/service_test.go delete mode 100644 pkg/server/profiledata/service.go delete mode 100644 pkg/server/profiledata/service_test.go create mode 100644 pkg/services/env.go delete mode 100644 pkg/services/profile_data.go create mode 100644 pkg/stores/env.go delete mode 100644 pkg/stores/profile_data.go create mode 100644 pkg/views/env/add.go create mode 100644 pkg/views/env/delete.go create mode 100644 pkg/views/env/selection/env.go create mode 100644 pkg/views/env/selection/view.go diff --git a/docs/daytona.md b/docs/daytona.md index ba2b8af73d..036ea6f451 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -28,7 +28,7 @@ daytona [flags] * [daytona create](daytona_create.md) - Create a workspace * [daytona delete](daytona_delete.md) - Delete a workspace * [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces +* [daytona env](daytona_env.md) - Manage server environment variables that are added to all targets and workspaces * [daytona forward](daytona_forward.md) - Forward a port from a workspace to your local machine * [daytona git-providers](daytona_git-providers.md) - Manage Git providers * [daytona ide](daytona_ide.md) - Choose the default IDE diff --git a/docs/daytona_env.md b/docs/daytona_env.md index 575d1bb82b..3f73927e40 100644 --- a/docs/daytona_env.md +++ b/docs/daytona_env.md @@ -1,6 +1,6 @@ ## daytona env -Manage profile environment variables that are added to all targets and workspaces +Manage server environment variables that are added to all targets and workspaces ### Options inherited from parent commands @@ -11,6 +11,7 @@ Manage profile environment variables that are added to all targets and workspace ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona env list](daytona_env_list.md) - List profile environment variables -* [daytona env set](daytona_env_set.md) - Set profile environment variables +* [daytona env list](daytona_env_list.md) - List server environment variables +* [daytona env remove](daytona_env_remove.md) - Remove server environment variables +* [daytona env set](daytona_env_set.md) - Set server environment variables diff --git a/docs/daytona_env_list.md b/docs/daytona_env_list.md index f0691768b5..8b19de8360 100644 --- a/docs/daytona_env_list.md +++ b/docs/daytona_env_list.md @@ -1,6 +1,6 @@ ## daytona env list -List profile environment variables +List server environment variables ``` daytona env list [flags] @@ -20,5 +20,5 @@ daytona env list [flags] ### SEE ALSO -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces +* [daytona env](daytona_env.md) - Manage server environment variables that are added to all targets and workspaces diff --git a/docs/daytona_env_remove.md b/docs/daytona_env_remove.md new file mode 100644 index 0000000000..05348f409d --- /dev/null +++ b/docs/daytona_env_remove.md @@ -0,0 +1,18 @@ +## daytona env remove + +Remove server environment variables + +``` +daytona env remove [KEY]... [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona env](daytona_env.md) - Manage server environment variables that are added to all targets and workspaces + diff --git a/docs/daytona_env_set.md b/docs/daytona_env_set.md index 8016ad9d39..b5f3be05e7 100644 --- a/docs/daytona_env_set.md +++ b/docs/daytona_env_set.md @@ -1,6 +1,6 @@ ## daytona env set -Set profile environment variables +Set server environment variables ``` daytona env set [KEY=VALUE]... [flags] @@ -14,5 +14,5 @@ daytona env set [KEY=VALUE]... [flags] ### SEE ALSO -* [daytona env](daytona_env.md) - Manage profile environment variables that are added to all targets and workspaces +* [daytona env](daytona_env.md) - Manage server environment variables that are added to all targets and workspaces diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index b919bbcef9..ee30f505a7 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -20,7 +20,7 @@ see_also: - daytona create - Create a workspace - daytona delete - Delete a workspace - daytona docs - Opens the Daytona documentation in your default browser. - - daytona env - Manage profile environment variables that are added to all targets and workspaces + - daytona env - Manage server environment variables that are added to all targets and workspaces - daytona forward - Forward a port from a workspace to your local machine - daytona git-providers - Manage Git providers - daytona ide - Choose the default IDE diff --git a/hack/docs/daytona_env.yaml b/hack/docs/daytona_env.yaml index 6f4d207d35..9108319e9d 100644 --- a/hack/docs/daytona_env.yaml +++ b/hack/docs/daytona_env.yaml @@ -1,11 +1,12 @@ name: daytona env synopsis: | - Manage profile environment variables that are added to all targets and workspaces + Manage server environment variables that are added to all targets and workspaces inherited_options: - name: help default_value: "false" usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager - - daytona env list - List profile environment variables - - daytona env set - Set profile environment variables + - daytona env list - List server environment variables + - daytona env remove - Remove server environment variables + - daytona env set - Set server environment variables diff --git a/hack/docs/daytona_env_list.yaml b/hack/docs/daytona_env_list.yaml index 383a0495d4..7b84540475 100644 --- a/hack/docs/daytona_env_list.yaml +++ b/hack/docs/daytona_env_list.yaml @@ -1,5 +1,5 @@ name: daytona env list -synopsis: List profile environment variables +synopsis: List server environment variables usage: daytona env list [flags] options: - name: format @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona env - Manage profile environment variables that are added to all targets and workspaces + - daytona env - Manage server environment variables that are added to all targets and workspaces diff --git a/hack/docs/daytona_env_remove.yaml b/hack/docs/daytona_env_remove.yaml new file mode 100644 index 0000000000..5798051dea --- /dev/null +++ b/hack/docs/daytona_env_remove.yaml @@ -0,0 +1,9 @@ +name: daytona env remove +synopsis: Remove server environment variables +usage: daytona env remove [KEY]... [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona env - Manage server environment variables that are added to all targets and workspaces diff --git a/hack/docs/daytona_env_set.yaml b/hack/docs/daytona_env_set.yaml index 99893fdbc0..2dd1cb0ccb 100644 --- a/hack/docs/daytona_env_set.yaml +++ b/hack/docs/daytona_env_set.yaml @@ -1,9 +1,9 @@ name: daytona env set -synopsis: Set profile environment variables +synopsis: Set server environment variables usage: daytona env set [KEY=VALUE]... [flags] inherited_options: - name: help default_value: "false" usage: help for daytona see_also: - - daytona env - Manage profile environment variables that are added to all targets and workspaces + - daytona env - Manage server environment variables that are added to all targets and workspaces diff --git a/internal/testing/server/env/store.go b/internal/testing/server/env/store.go new file mode 100644 index 0000000000..a6c30a2395 --- /dev/null +++ b/internal/testing/server/env/store.go @@ -0,0 +1,44 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type InMemoryEnvironmentVariableStore struct { + envVars map[string]*models.EnvironmentVariable +} + +func NewInMemoryEnvironmentVariableStore() stores.EnvironmentVariableStore { + return &InMemoryEnvironmentVariableStore{ + envVars: make(map[string]*models.EnvironmentVariable), + } +} + +func (s *InMemoryEnvironmentVariableStore) List() ([]*models.EnvironmentVariable, error) { + envVars := []*models.EnvironmentVariable{} + for _, envVar := range s.envVars { + envVars = append(envVars, envVar) + } + + return envVars, nil +} + +func (s *InMemoryEnvironmentVariableStore) Save(environmentVariable *models.EnvironmentVariable) error { + s.envVars[environmentVariable.Key] = environmentVariable + return nil +} + +func (s *InMemoryEnvironmentVariableStore) Delete(key string) error { + _, ok := s.envVars[key] + if !ok { + return stores.ErrEnvironmentVariableNotFound + } + delete(s.envVars, key) + return nil +} diff --git a/internal/testing/server/profiledata/store.go b/internal/testing/server/profiledata/store.go deleted file mode 100644 index 2427224224..0000000000 --- a/internal/testing/server/profiledata/store.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package profiledata - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" -) - -type InMemoryProfileDataStore struct { - profileData *models.ProfileData -} - -func NewInMemoryProfileDataStore() stores.ProfileDataStore { - return &InMemoryProfileDataStore{ - profileData: nil, - } -} - -func (s *InMemoryProfileDataStore) Get(id string) (*models.ProfileData, error) { - if s.profileData == nil { - return nil, stores.ErrProfileDataNotFound - } - - return s.profileData, nil -} - -func (s *InMemoryProfileDataStore) Save(profileData *models.ProfileData) error { - s.profileData = profileData - return nil -} - -func (s *InMemoryProfileDataStore) Delete(id string) error { - s.profileData = nil - return nil -} diff --git a/internal/util/apiclient/conversion/env.go b/internal/util/apiclient/conversion/env.go new file mode 100644 index 0000000000..fa63e63bcd --- /dev/null +++ b/internal/util/apiclient/conversion/env.go @@ -0,0 +1,16 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package conversion + +import "github.com/daytonaio/daytona/pkg/apiclient" + +func ToEnvVarsMap(envVars []apiclient.EnvironmentVariable) map[string]string { + envVarsMap := map[string]string{} + + for _, envVar := range envVars { + envVarsMap[envVar.Key] = envVar.Value + } + + return envVarsMap +} diff --git a/pkg/api/controllers/env/env.go b/pkg/api/controllers/env/env.go new file mode 100644 index 0000000000..3e0dd43efa --- /dev/null +++ b/pkg/api/controllers/env/env.go @@ -0,0 +1,96 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" +) + +// ListEnvironmentVariables godoc +// +// @Tags envVar +// @Summary List environment variables +// @Description List environment variables +// @Produce json +// @Success 200 {array} models.EnvironmentVariable +// @Router /env [get] +// +// @id ListEnvironmentVariables +func ListEnvironmentVariables(ctx *gin.Context) { + server := server.GetInstance(nil) + envVars, err := server.EnvironmentVariableService.List() + if err != nil { + if stores.IsEnvironmentVariableNotFound(err) { + ctx.JSON(200, []*models.EnvironmentVariable{}) + return + } + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list environment variables: %w", err)) + return + } + + ctx.JSON(200, envVars) +} + +// SetEnvironmentVariable godoc +// +// @Tags envVar +// @Summary Set environment variable +// @Description Set environment variable +// @Accept json +// @Param environmentVariable body models.EnvironmentVariable true "Environment Variable" +// @Success 201 +// @Router /env [put] +// +// @id SetEnvironmentVariable +func SetEnvironmentVariable(ctx *gin.Context) { + var req models.EnvironmentVariable + err := ctx.BindJSON(&req) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + err = server.EnvironmentVariableService.Save(&req) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save environment variable: %w", err)) + return + } + + ctx.Status(201) +} + +// DeleteEnvironmentVariable godoc +// +// @Tags envVar +// @Summary Delete environment variable +// @Description Delete environment variable +// @Param key path string true "Environment Variable Key" +// @Success 204 +// @Router /env/{key} [delete] +// +// @id DeleteEnvironmentVariable +func DeleteEnvironmentVariable(ctx *gin.Context) { + envVarKey := ctx.Param("key") + + server := server.GetInstance(nil) + + err := server.EnvironmentVariableService.Delete(envVarKey) + if err != nil { + if stores.IsEnvironmentVariableNotFound(err) { + ctx.Status(204) + return + } + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove environment variable: %w", err)) + return + } + + ctx.Status(204) +} diff --git a/pkg/api/controllers/profiledata/profile_data.go b/pkg/api/controllers/profiledata/profile_data.go deleted file mode 100644 index 15b7a0ade4..0000000000 --- a/pkg/api/controllers/profiledata/profile_data.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package profiledata - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/gin-gonic/gin" -) - -// GetProfileData godoc -// -// @Tags profile -// @Summary Get profile data -// @Description Get profile data -// @Accept json -// @Success 200 {object} models.ProfileData -// @Router /profile [get] -// -// @id GetProfileData -func GetProfileData(ctx *gin.Context) { - server := server.GetInstance(nil) - profileData, err := server.ProfileDataService.Get("") - if err != nil { - if stores.IsProfileDataNotFound(err) { - ctx.JSON(200, &models.ProfileData{}) - return - } - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get profile data: %w", err)) - return - } - - ctx.JSON(200, profileData) -} - -// SetProfileData godoc -// -// @Tags profile -// @Summary Set profile data -// @Description Set profile data -// @Accept json -// @Param profileData body models.ProfileData true "Profile data" -// @Success 201 -// @Router /profile [put] -// -// @id SetProfileData -func SetProfileData(ctx *gin.Context) { - var req models.ProfileData - err := ctx.BindJSON(&req) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - err = server.ProfileDataService.Save(&req) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save profile data: %w", err)) - return - } - - ctx.Status(201) -} - -// DeleteProfileData godoc -// -// @Tags profile -// @Summary Delete profile data -// @Description Delete profile data -// @Success 204 -// @Router /profile [delete] -// -// @id DeleteProfileData -func DeleteProfileData(ctx *gin.Context) { - server := server.GetInstance(nil) - err := server.ProfileDataService.Delete("") - if err != nil { - if stores.IsProfileDataNotFound(err) { - ctx.Status(204) - return - } - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get profile data: %w", err)) - return - } - - ctx.Status(204) -} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 3b627ebdb6..a351bbe210 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -361,6 +361,81 @@ const docTemplate = `{ } } }, + "/env": { + "get": { + "description": "List environment variables", + "produces": [ + "application/json" + ], + "tags": [ + "envVar" + ], + "summary": "List environment variables", + "operationId": "ListEnvironmentVariables", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/EnvironmentVariable" + } + } + } + } + }, + "put": { + "description": "Set environment variable", + "consumes": [ + "application/json" + ], + "tags": [ + "envVar" + ], + "summary": "Set environment variable", + "operationId": "SetEnvironmentVariable", + "parameters": [ + { + "description": "Environment Variable", + "name": "environmentVariable", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EnvironmentVariable" + } + } + ], + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/env/{key}": { + "delete": { + "description": "Delete environment variable", + "tags": [ + "envVar" + ], + "summary": "Delete environment variable", + "operationId": "DeleteEnvironmentVariable", + "parameters": [ + { + "type": "string", + "description": "Environment Variable Key", + "name": "key", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/gitprovider": { "get": { "description": "List Git providers", @@ -884,67 +959,6 @@ const docTemplate = `{ } } }, - "/profile": { - "get": { - "description": "Get profile data", - "consumes": [ - "application/json" - ], - "tags": [ - "profile" - ], - "summary": "Get profile data", - "operationId": "GetProfileData", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ProfileData" - } - } - } - }, - "put": { - "description": "Set profile data", - "consumes": [ - "application/json" - ], - "tags": [ - "profile" - ], - "summary": "Set profile data", - "operationId": "SetProfileData", - "parameters": [ - { - "description": "Profile data", - "name": "profileData", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/ProfileData" - } - } - ], - "responses": { - "201": { - "description": "Created" - } - } - }, - "delete": { - "description": "Delete profile data", - "tags": [ - "profile" - ], - "summary": "Delete profile data", - "operationId": "DeleteProfileData", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/provider": { "get": { "description": "List providers", @@ -3797,6 +3811,21 @@ const docTemplate = `{ } } }, + "EnvironmentVariable": { + "type": "object", + "required": [ + "key", + "value" + ], + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "ExecuteRequest": { "type": "object", "required": [ @@ -4622,24 +4651,6 @@ const docTemplate = `{ } } }, - "ProfileData": { - "type": "object", - "required": [ - "envVars", - "id" - ], - "properties": { - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "id": { - "type": "string" - } - } - }, "Provider": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 5601effa38..3a3ee6b208 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -358,6 +358,81 @@ } } }, + "/env": { + "get": { + "description": "List environment variables", + "produces": [ + "application/json" + ], + "tags": [ + "envVar" + ], + "summary": "List environment variables", + "operationId": "ListEnvironmentVariables", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/EnvironmentVariable" + } + } + } + } + }, + "put": { + "description": "Set environment variable", + "consumes": [ + "application/json" + ], + "tags": [ + "envVar" + ], + "summary": "Set environment variable", + "operationId": "SetEnvironmentVariable", + "parameters": [ + { + "description": "Environment Variable", + "name": "environmentVariable", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EnvironmentVariable" + } + } + ], + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/env/{key}": { + "delete": { + "description": "Delete environment variable", + "tags": [ + "envVar" + ], + "summary": "Delete environment variable", + "operationId": "DeleteEnvironmentVariable", + "parameters": [ + { + "type": "string", + "description": "Environment Variable Key", + "name": "key", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, "/gitprovider": { "get": { "description": "List Git providers", @@ -881,67 +956,6 @@ } } }, - "/profile": { - "get": { - "description": "Get profile data", - "consumes": [ - "application/json" - ], - "tags": [ - "profile" - ], - "summary": "Get profile data", - "operationId": "GetProfileData", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ProfileData" - } - } - } - }, - "put": { - "description": "Set profile data", - "consumes": [ - "application/json" - ], - "tags": [ - "profile" - ], - "summary": "Set profile data", - "operationId": "SetProfileData", - "parameters": [ - { - "description": "Profile data", - "name": "profileData", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/ProfileData" - } - } - ], - "responses": { - "201": { - "description": "Created" - } - } - }, - "delete": { - "description": "Delete profile data", - "tags": [ - "profile" - ], - "summary": "Delete profile data", - "operationId": "DeleteProfileData", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/provider": { "get": { "description": "List providers", @@ -3794,6 +3808,21 @@ } } }, + "EnvironmentVariable": { + "type": "object", + "required": [ + "key", + "value" + ], + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "ExecuteRequest": { "type": "object", "required": [ @@ -4619,24 +4648,6 @@ } } }, - "ProfileData": { - "type": "object", - "required": [ - "envVars", - "id" - ], - "properties": { - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "id": { - "type": "string" - } - } - }, "Provider": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 85f40405e1..817517a2ca 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -282,6 +282,16 @@ definitions: required: - filePath type: object + EnvironmentVariable: + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object ExecuteRequest: properties: command: @@ -848,18 +858,6 @@ definitions: - retention - workspaceConfigName type: object - ProfileData: - properties: - envVars: - additionalProperties: - type: string - type: object - id: - type: string - required: - - envVars - - id - type: object Provider: properties: label: @@ -1740,6 +1738,56 @@ paths: summary: Set container registry credentials tags: - container-registry + /env: + get: + description: List environment variables + operationId: ListEnvironmentVariables + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/EnvironmentVariable' + type: array + summary: List environment variables + tags: + - envVar + put: + consumes: + - application/json + description: Set environment variable + operationId: SetEnvironmentVariable + parameters: + - description: Environment Variable + in: body + name: environmentVariable + required: true + schema: + $ref: '#/definitions/EnvironmentVariable' + responses: + "201": + description: Created + summary: Set environment variable + tags: + - envVar + /env/{key}: + delete: + description: Delete environment variable + operationId: DeleteEnvironmentVariable + parameters: + - description: Environment Variable Key + in: path + name: key + required: true + type: string + responses: + "204": + description: No Content + summary: Delete environment variable + tags: + - envVar /gitprovider: get: description: List Git providers @@ -2090,47 +2138,6 @@ paths: summary: List jobs tags: - job - /profile: - delete: - description: Delete profile data - operationId: DeleteProfileData - responses: - "204": - description: No Content - summary: Delete profile data - tags: - - profile - get: - consumes: - - application/json - description: Get profile data - operationId: GetProfileData - responses: - "200": - description: OK - schema: - $ref: '#/definitions/ProfileData' - summary: Get profile data - tags: - - profile - put: - consumes: - - application/json - description: Set profile data - operationId: SetProfileData - parameters: - - description: Profile data - in: body - name: profileData - required: true - schema: - $ref: '#/definitions/ProfileData' - responses: - "201": - description: Created - summary: Set profile data - tags: - - profile /provider: get: description: List providers diff --git a/pkg/api/server.go b/pkg/api/server.go index 4262d73be6..9b4e6f834d 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -36,11 +36,11 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/binary" "github.com/daytonaio/daytona/pkg/api/controllers/build" "github.com/daytonaio/daytona/pkg/api/controllers/containerregistry" + "github.com/daytonaio/daytona/pkg/api/controllers/env" "github.com/daytonaio/daytona/pkg/api/controllers/gitprovider" "github.com/daytonaio/daytona/pkg/api/controllers/health" "github.com/daytonaio/daytona/pkg/api/controllers/job" log_controller "github.com/daytonaio/daytona/pkg/api/controllers/log" - "github.com/daytonaio/daytona/pkg/api/controllers/profiledata" "github.com/daytonaio/daytona/pkg/api/controllers/provider" "github.com/daytonaio/daytona/pkg/api/controllers/sample" "github.com/daytonaio/daytona/pkg/api/controllers/server" @@ -323,11 +323,11 @@ func (a *ApiServer) Start() error { apiKeyController.DELETE("/:apiKeyName", apikey.RevokeApiKey) } - profileDataController := protected.Group("/profile") + envVarController := protected.Group("/env") { - profileDataController.GET("", profiledata.GetProfileData) - profileDataController.PUT("", profiledata.SetProfileData) - profileDataController.DELETE("", profiledata.DeleteProfileData) + envVarController.GET("", env.ListEnvironmentVariables) + envVarController.PUT("", env.SetEnvironmentVariable) + envVarController.DELETE("/:key", env.DeleteEnvironmentVariable) } samplesController := protected.Group("/sample") diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index cfe1931044..e325d1bfd1 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -91,6 +91,9 @@ Class | Method | HTTP request | Description *ContainerRegistryAPI* | [**RemoveContainerRegistry**](docs/ContainerRegistryAPI.md#removecontainerregistry) | **Delete** /container-registry/{server} | Remove a container registry credentials *ContainerRegistryAPI* | [**SetContainerRegistry**](docs/ContainerRegistryAPI.md#setcontainerregistry) | **Put** /container-registry/{server} | Set container registry credentials *DefaultAPI* | [**HealthCheck**](docs/DefaultAPI.md#healthcheck) | **Get** /health | Health check +*EnvVarAPI* | [**DeleteEnvironmentVariable**](docs/EnvVarAPI.md#deleteenvironmentvariable) | **Delete** /env/{key} | Delete environment variable +*EnvVarAPI* | [**ListEnvironmentVariables**](docs/EnvVarAPI.md#listenvironmentvariables) | **Get** /env | List environment variables +*EnvVarAPI* | [**SetEnvironmentVariable**](docs/EnvVarAPI.md#setenvironmentvariable) | **Put** /env | Set environment variable *GitProviderAPI* | [**GetGitContext**](docs/GitProviderAPI.md#getgitcontext) | **Post** /gitprovider/context | Get Git context *GitProviderAPI* | [**GetGitProvider**](docs/GitProviderAPI.md#getgitprovider) | **Get** /gitprovider/{gitProviderId} | Get Git provider *GitProviderAPI* | [**GetGitProviderIdForUrl**](docs/GitProviderAPI.md#getgitprovideridforurl) | **Get** /gitprovider/id-for-url/{url} | Get Git provider ID @@ -111,9 +114,6 @@ Class | Method | HTTP request | Description *PrebuildAPI* | [**ListPrebuildsForWorkspaceConfig**](docs/PrebuildAPI.md#listprebuildsforworkspaceconfig) | **Get** /workspace-config/{configName}/prebuild | List prebuilds for workspace config *PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /workspace-config/prebuild/process-git-event | ProcessGitEvent *PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /workspace-config/{configName}/prebuild | Set prebuild -*ProfileAPI* | [**DeleteProfileData**](docs/ProfileAPI.md#deleteprofiledata) | **Delete** /profile | Delete profile data -*ProfileAPI* | [**GetProfileData**](docs/ProfileAPI.md#getprofiledata) | **Get** /profile | Get profile data -*ProfileAPI* | [**SetProfileData**](docs/ProfileAPI.md#setprofiledata) | **Put** /profile | Set profile data *ProviderAPI* | [**GetTargetConfigManifest**](docs/ProviderAPI.md#gettargetconfigmanifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest *ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /provider/install | Install a provider *ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /provider | List providers @@ -205,6 +205,7 @@ Class | Method | HTTP request | Description - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) - [CreateWorkspaceSourceDTO](docs/CreateWorkspaceSourceDTO.md) - [DevcontainerConfig](docs/DevcontainerConfig.md) + - [EnvironmentVariable](docs/EnvironmentVariable.md) - [ExecuteRequest](docs/ExecuteRequest.md) - [ExecuteResponse](docs/ExecuteResponse.md) - [FRPSConfig](docs/FRPSConfig.md) @@ -246,7 +247,6 @@ Class | Method | HTTP request | Description - [Position](docs/Position.md) - [PrebuildConfig](docs/PrebuildConfig.md) - [PrebuildDTO](docs/PrebuildDTO.md) - - [ProfileData](docs/ProfileData.md) - [Provider](docs/Provider.md) - [ProviderTargetConfigPropertyType](docs/ProviderTargetConfigPropertyType.md) - [ReplaceRequest](docs/ReplaceRequest.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index dcdf6d36c8..5acc5f0d93 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -261,6 +261,58 @@ paths: tags: - container-registry x-codegen-request-body-name: containerRegistry + /env: + get: + description: List environment variables + operationId: ListEnvironmentVariables + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/EnvironmentVariable' + type: array + description: OK + summary: List environment variables + tags: + - envVar + put: + description: Set environment variable + operationId: SetEnvironmentVariable + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/EnvironmentVariable' + description: Environment Variable + required: true + responses: + "201": + content: {} + description: Created + summary: Set environment variable + tags: + - envVar + x-codegen-request-body-name: environmentVariable + /env/{key}: + delete: + description: Delete environment variable + operationId: DeleteEnvironmentVariable + parameters: + - description: Environment Variable Key + in: path + name: key + required: true + schema: + type: string + responses: + "204": + content: {} + description: No Content + summary: Delete environment variable + tags: + - envVar /gitprovider: get: description: List Git providers @@ -634,48 +686,6 @@ paths: summary: List jobs tags: - job - /profile: - delete: - description: Delete profile data - operationId: DeleteProfileData - responses: - "204": - content: {} - description: No Content - summary: Delete profile data - tags: - - profile - get: - description: Get profile data - operationId: GetProfileData - responses: - "200": - content: - '*/*': - schema: - $ref: '#/components/schemas/ProfileData' - description: OK - summary: Get profile data - tags: - - profile - put: - description: Set profile data - operationId: SetProfileData - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/ProfileData' - description: Profile data - required: true - responses: - "201": - content: {} - description: Created - summary: Set profile data - tags: - - profile - x-codegen-request-body-name: profileData /provider: get: description: List providers @@ -2902,6 +2912,19 @@ components: required: - filePath type: object + EnvironmentVariable: + example: + value: value + key: key + properties: + key: + type: string + value: + type: string + required: + - key + - value + type: object ExecuteRequest: example: command: command @@ -3685,22 +3708,6 @@ components: - retention - workspaceConfigName type: object - ProfileData: - example: - envVars: - key: envVars - id: id - properties: - envVars: - additionalProperties: - type: string - type: object - id: - type: string - required: - - envVars - - id - type: object Provider: example: name: name diff --git a/pkg/apiclient/api_profile.go b/pkg/apiclient/api_env_var.go similarity index 72% rename from pkg/apiclient/api_profile.go rename to pkg/apiclient/api_env_var.go index 02a872a256..507044403c 100644 --- a/pkg/apiclient/api_profile.go +++ b/pkg/apiclient/api_env_var.go @@ -16,49 +16,54 @@ import ( "io" "net/http" "net/url" + "strings" ) -// ProfileAPIService ProfileAPI service -type ProfileAPIService service +// EnvVarAPIService EnvVarAPI service +type EnvVarAPIService service -type ApiDeleteProfileDataRequest struct { +type ApiDeleteEnvironmentVariableRequest struct { ctx context.Context - ApiService *ProfileAPIService + ApiService *EnvVarAPIService + key string } -func (r ApiDeleteProfileDataRequest) Execute() (*http.Response, error) { - return r.ApiService.DeleteProfileDataExecute(r) +func (r ApiDeleteEnvironmentVariableRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteEnvironmentVariableExecute(r) } /* -DeleteProfileData Delete profile data +DeleteEnvironmentVariable Delete environment variable -Delete profile data +Delete environment variable @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiDeleteProfileDataRequest + @param key Environment Variable Key + @return ApiDeleteEnvironmentVariableRequest */ -func (a *ProfileAPIService) DeleteProfileData(ctx context.Context) ApiDeleteProfileDataRequest { - return ApiDeleteProfileDataRequest{ +func (a *EnvVarAPIService) DeleteEnvironmentVariable(ctx context.Context, key string) ApiDeleteEnvironmentVariableRequest { + return ApiDeleteEnvironmentVariableRequest{ ApiService: a, ctx: ctx, + key: key, } } // Execute executes the request -func (a *ProfileAPIService) DeleteProfileDataExecute(r ApiDeleteProfileDataRequest) (*http.Response, error) { +func (a *EnvVarAPIService) DeleteEnvironmentVariableExecute(r ApiDeleteEnvironmentVariableRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodDelete localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProfileAPIService.DeleteProfileData") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "EnvVarAPIService.DeleteEnvironmentVariable") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/profile" + localVarPath := localBasePath + "/env/{key}" + localVarPath = strings.Replace(localVarPath, "{"+"key"+"}", url.PathEscape(parameterValueToString(r.key, "key")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -123,25 +128,25 @@ func (a *ProfileAPIService) DeleteProfileDataExecute(r ApiDeleteProfileDataReque return localVarHTTPResponse, nil } -type ApiGetProfileDataRequest struct { +type ApiListEnvironmentVariablesRequest struct { ctx context.Context - ApiService *ProfileAPIService + ApiService *EnvVarAPIService } -func (r ApiGetProfileDataRequest) Execute() (*ProfileData, *http.Response, error) { - return r.ApiService.GetProfileDataExecute(r) +func (r ApiListEnvironmentVariablesRequest) Execute() ([]EnvironmentVariable, *http.Response, error) { + return r.ApiService.ListEnvironmentVariablesExecute(r) } /* -GetProfileData Get profile data +ListEnvironmentVariables List environment variables -Get profile data +List environment variables @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiGetProfileDataRequest + @return ApiListEnvironmentVariablesRequest */ -func (a *ProfileAPIService) GetProfileData(ctx context.Context) ApiGetProfileDataRequest { - return ApiGetProfileDataRequest{ +func (a *EnvVarAPIService) ListEnvironmentVariables(ctx context.Context) ApiListEnvironmentVariablesRequest { + return ApiListEnvironmentVariablesRequest{ ApiService: a, ctx: ctx, } @@ -149,21 +154,21 @@ func (a *ProfileAPIService) GetProfileData(ctx context.Context) ApiGetProfileDat // Execute executes the request // -// @return ProfileData -func (a *ProfileAPIService) GetProfileDataExecute(r ApiGetProfileDataRequest) (*ProfileData, *http.Response, error) { +// @return []EnvironmentVariable +func (a *EnvVarAPIService) ListEnvironmentVariablesExecute(r ApiListEnvironmentVariablesRequest) ([]EnvironmentVariable, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *ProfileData + localVarReturnValue []EnvironmentVariable ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProfileAPIService.GetProfileData") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "EnvVarAPIService.ListEnvironmentVariables") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/profile" + localVarPath := localBasePath + "/env" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -179,7 +184,7 @@ func (a *ProfileAPIService) GetProfileDataExecute(r ApiGetProfileDataRequest) (* } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"*/*"} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -237,57 +242,57 @@ func (a *ProfileAPIService) GetProfileDataExecute(r ApiGetProfileDataRequest) (* return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetProfileDataRequest struct { - ctx context.Context - ApiService *ProfileAPIService - profileData *ProfileData +type ApiSetEnvironmentVariableRequest struct { + ctx context.Context + ApiService *EnvVarAPIService + environmentVariable *EnvironmentVariable } -// Profile data -func (r ApiSetProfileDataRequest) ProfileData(profileData ProfileData) ApiSetProfileDataRequest { - r.profileData = &profileData +// Environment Variable +func (r ApiSetEnvironmentVariableRequest) EnvironmentVariable(environmentVariable EnvironmentVariable) ApiSetEnvironmentVariableRequest { + r.environmentVariable = &environmentVariable return r } -func (r ApiSetProfileDataRequest) Execute() (*http.Response, error) { - return r.ApiService.SetProfileDataExecute(r) +func (r ApiSetEnvironmentVariableRequest) Execute() (*http.Response, error) { + return r.ApiService.SetEnvironmentVariableExecute(r) } /* -SetProfileData Set profile data +SetEnvironmentVariable Set environment variable -Set profile data +Set environment variable @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetProfileDataRequest + @return ApiSetEnvironmentVariableRequest */ -func (a *ProfileAPIService) SetProfileData(ctx context.Context) ApiSetProfileDataRequest { - return ApiSetProfileDataRequest{ +func (a *EnvVarAPIService) SetEnvironmentVariable(ctx context.Context) ApiSetEnvironmentVariableRequest { + return ApiSetEnvironmentVariableRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *ProfileAPIService) SetProfileDataExecute(r ApiSetProfileDataRequest) (*http.Response, error) { +func (a *EnvVarAPIService) SetEnvironmentVariableExecute(r ApiSetEnvironmentVariableRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProfileAPIService.SetProfileData") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "EnvVarAPIService.SetEnvironmentVariable") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/profile" + localVarPath := localBasePath + "/env" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.profileData == nil { - return nil, reportError("profileData is required and must be specified") + if r.environmentVariable == nil { + return nil, reportError("environmentVariable is required and must be specified") } // to determine the Content-Type header @@ -308,7 +313,7 @@ func (a *ProfileAPIService) SetProfileDataExecute(r ApiSetProfileDataRequest) (* localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.profileData + localVarPostBody = r.environmentVariable if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index b102b0f04c..5a566b2c54 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -56,14 +56,14 @@ type APIClient struct { DefaultAPI *DefaultAPIService + EnvVarAPI *EnvVarAPIService + GitProviderAPI *GitProviderAPIService JobAPI *JobAPIService PrebuildAPI *PrebuildAPIService - ProfileAPI *ProfileAPIService - ProviderAPI *ProviderAPIService SampleAPI *SampleAPIService @@ -101,10 +101,10 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.BuildAPI = (*BuildAPIService)(&c.common) c.ContainerRegistryAPI = (*ContainerRegistryAPIService)(&c.common) c.DefaultAPI = (*DefaultAPIService)(&c.common) + c.EnvVarAPI = (*EnvVarAPIService)(&c.common) c.GitProviderAPI = (*GitProviderAPIService)(&c.common) c.JobAPI = (*JobAPIService)(&c.common) c.PrebuildAPI = (*PrebuildAPIService)(&c.common) - c.ProfileAPI = (*ProfileAPIService)(&c.common) c.ProviderAPI = (*ProviderAPIService)(&c.common) c.SampleAPI = (*SampleAPIService)(&c.common) c.ServerAPI = (*ServerAPIService)(&c.common) diff --git a/pkg/apiclient/docs/EnvVarAPI.md b/pkg/apiclient/docs/EnvVarAPI.md new file mode 100644 index 0000000000..f926ad9026 --- /dev/null +++ b/pkg/apiclient/docs/EnvVarAPI.md @@ -0,0 +1,204 @@ +# \EnvVarAPI + +All URIs are relative to *http://localhost:3986* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**DeleteEnvironmentVariable**](EnvVarAPI.md#DeleteEnvironmentVariable) | **Delete** /env/{key} | Delete environment variable +[**ListEnvironmentVariables**](EnvVarAPI.md#ListEnvironmentVariables) | **Get** /env | List environment variables +[**SetEnvironmentVariable**](EnvVarAPI.md#SetEnvironmentVariable) | **Put** /env | Set environment variable + + + +## DeleteEnvironmentVariable + +> DeleteEnvironmentVariable(ctx, key).Execute() + +Delete environment variable + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + key := "key_example" // string | Environment Variable Key + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.EnvVarAPI.DeleteEnvironmentVariable(context.Background(), key).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `EnvVarAPI.DeleteEnvironmentVariable``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**key** | **string** | Environment Variable Key | + +### Other Parameters + +Other parameters are passed through a pointer to a apiDeleteEnvironmentVariableRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListEnvironmentVariables + +> []EnvironmentVariable ListEnvironmentVariables(ctx).Execute() + +List environment variables + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.EnvVarAPI.ListEnvironmentVariables(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `EnvVarAPI.ListEnvironmentVariables``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListEnvironmentVariables`: []EnvironmentVariable + fmt.Fprintf(os.Stdout, "Response from `EnvVarAPI.ListEnvironmentVariables`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiListEnvironmentVariablesRequest struct via the builder pattern + + +### Return type + +[**[]EnvironmentVariable**](EnvironmentVariable.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## SetEnvironmentVariable + +> SetEnvironmentVariable(ctx).EnvironmentVariable(environmentVariable).Execute() + +Set environment variable + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + environmentVariable := *openapiclient.NewEnvironmentVariable("Key_example", "Value_example") // EnvironmentVariable | Environment Variable + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.EnvVarAPI.SetEnvironmentVariable(context.Background()).EnvironmentVariable(environmentVariable).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `EnvVarAPI.SetEnvironmentVariable``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiSetEnvironmentVariableRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **environmentVariable** | [**EnvironmentVariable**](EnvironmentVariable.md) | Environment Variable | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/EnvironmentVariable.md b/pkg/apiclient/docs/EnvironmentVariable.md new file mode 100644 index 0000000000..5fa727d4f2 --- /dev/null +++ b/pkg/apiclient/docs/EnvironmentVariable.md @@ -0,0 +1,72 @@ +# EnvironmentVariable + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Key** | **string** | | +**Value** | **string** | | + +## Methods + +### NewEnvironmentVariable + +`func NewEnvironmentVariable(key string, value string, ) *EnvironmentVariable` + +NewEnvironmentVariable instantiates a new EnvironmentVariable object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewEnvironmentVariableWithDefaults + +`func NewEnvironmentVariableWithDefaults() *EnvironmentVariable` + +NewEnvironmentVariableWithDefaults instantiates a new EnvironmentVariable object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetKey + +`func (o *EnvironmentVariable) GetKey() string` + +GetKey returns the Key field if non-nil, zero value otherwise. + +### GetKeyOk + +`func (o *EnvironmentVariable) GetKeyOk() (*string, bool)` + +GetKeyOk returns a tuple with the Key field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetKey + +`func (o *EnvironmentVariable) SetKey(v string)` + +SetKey sets Key field to given value. + + +### GetValue + +`func (o *EnvironmentVariable) GetValue() string` + +GetValue returns the Value field if non-nil, zero value otherwise. + +### GetValueOk + +`func (o *EnvironmentVariable) GetValueOk() (*string, bool)` + +GetValueOk returns a tuple with the Value field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetValue + +`func (o *EnvironmentVariable) SetValue(v string)` + +SetValue sets Value field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ProfileAPI.md b/pkg/apiclient/docs/ProfileAPI.md deleted file mode 100644 index d28d60ab8e..0000000000 --- a/pkg/apiclient/docs/ProfileAPI.md +++ /dev/null @@ -1,195 +0,0 @@ -# \ProfileAPI - -All URIs are relative to *http://localhost:3986* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**DeleteProfileData**](ProfileAPI.md#DeleteProfileData) | **Delete** /profile | Delete profile data -[**GetProfileData**](ProfileAPI.md#GetProfileData) | **Get** /profile | Get profile data -[**SetProfileData**](ProfileAPI.md#SetProfileData) | **Put** /profile | Set profile data - - - -## DeleteProfileData - -> DeleteProfileData(ctx).Execute() - -Delete profile data - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProfileAPI.DeleteProfileData(context.Background()).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProfileAPI.DeleteProfileData``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - -This endpoint does not need any parameter. - -### Other Parameters - -Other parameters are passed through a pointer to a apiDeleteProfileDataRequest struct via the builder pattern - - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## GetProfileData - -> ProfileData GetProfileData(ctx).Execute() - -Get profile data - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProfileAPI.GetProfileData(context.Background()).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProfileAPI.GetProfileData``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } - // response from `GetProfileData`: ProfileData - fmt.Fprintf(os.Stdout, "Response from `ProfileAPI.GetProfileData`: %v\n", resp) -} -``` - -### Path Parameters - -This endpoint does not need any parameter. - -### Other Parameters - -Other parameters are passed through a pointer to a apiGetProfileDataRequest struct via the builder pattern - - -### Return type - -[**ProfileData**](ProfileData.md) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: */* - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## SetProfileData - -> SetProfileData(ctx).ProfileData(profileData).Execute() - -Set profile data - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - profileData := *openapiclient.NewProfileData(map[string]string{"key": "Inner_example"}, "Id_example") // ProfileData | Profile data - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProfileAPI.SetProfileData(context.Background()).ProfileData(profileData).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProfileAPI.SetProfileData``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - - -### Other Parameters - -Other parameters are passed through a pointer to a apiSetProfileDataRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **profileData** | [**ProfileData**](ProfileData.md) | Profile data | - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: application/json -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - diff --git a/pkg/apiclient/docs/ProfileData.md b/pkg/apiclient/docs/ProfileData.md deleted file mode 100644 index 89f13e8b1e..0000000000 --- a/pkg/apiclient/docs/ProfileData.md +++ /dev/null @@ -1,72 +0,0 @@ -# ProfileData - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**EnvVars** | **map[string]string** | | -**Id** | **string** | | - -## Methods - -### NewProfileData - -`func NewProfileData(envVars map[string]string, id string, ) *ProfileData` - -NewProfileData instantiates a new ProfileData object -This constructor will assign default values to properties that have it defined, -and makes sure properties required by API are set, but the set of arguments -will change when the set of required properties is changed - -### NewProfileDataWithDefaults - -`func NewProfileDataWithDefaults() *ProfileData` - -NewProfileDataWithDefaults instantiates a new ProfileData object -This constructor will only assign default values to properties that have it defined, -but it doesn't guarantee that properties required by API are set - -### GetEnvVars - -`func (o *ProfileData) GetEnvVars() map[string]string` - -GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. - -### GetEnvVarsOk - -`func (o *ProfileData) GetEnvVarsOk() (*map[string]string, bool)` - -GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetEnvVars - -`func (o *ProfileData) SetEnvVars(v map[string]string)` - -SetEnvVars sets EnvVars field to given value. - - -### GetId - -`func (o *ProfileData) GetId() string` - -GetId returns the Id field if non-nil, zero value otherwise. - -### GetIdOk - -`func (o *ProfileData) GetIdOk() (*string, bool)` - -GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetId - -`func (o *ProfileData) SetId(v string)` - -SetId sets Id field to given value. - - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/model_environment_variable.go b/pkg/apiclient/model_environment_variable.go new file mode 100644 index 0000000000..305fed9e85 --- /dev/null +++ b/pkg/apiclient/model_environment_variable.go @@ -0,0 +1,184 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the EnvironmentVariable type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &EnvironmentVariable{} + +// EnvironmentVariable struct for EnvironmentVariable +type EnvironmentVariable struct { + Key string `json:"key"` + Value string `json:"value"` +} + +type _EnvironmentVariable EnvironmentVariable + +// NewEnvironmentVariable instantiates a new EnvironmentVariable object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewEnvironmentVariable(key string, value string) *EnvironmentVariable { + this := EnvironmentVariable{} + this.Key = key + this.Value = value + return &this +} + +// NewEnvironmentVariableWithDefaults instantiates a new EnvironmentVariable object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewEnvironmentVariableWithDefaults() *EnvironmentVariable { + this := EnvironmentVariable{} + return &this +} + +// GetKey returns the Key field value +func (o *EnvironmentVariable) GetKey() string { + if o == nil { + var ret string + return ret + } + + return o.Key +} + +// GetKeyOk returns a tuple with the Key field value +// and a boolean to check if the value has been set. +func (o *EnvironmentVariable) GetKeyOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Key, true +} + +// SetKey sets field value +func (o *EnvironmentVariable) SetKey(v string) { + o.Key = v +} + +// GetValue returns the Value field value +func (o *EnvironmentVariable) GetValue() string { + if o == nil { + var ret string + return ret + } + + return o.Value +} + +// GetValueOk returns a tuple with the Value field value +// and a boolean to check if the value has been set. +func (o *EnvironmentVariable) GetValueOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Value, true +} + +// SetValue sets field value +func (o *EnvironmentVariable) SetValue(v string) { + o.Value = v +} + +func (o EnvironmentVariable) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o EnvironmentVariable) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["key"] = o.Key + toSerialize["value"] = o.Value + return toSerialize, nil +} + +func (o *EnvironmentVariable) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "key", + "value", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varEnvironmentVariable := _EnvironmentVariable{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varEnvironmentVariable) + + if err != nil { + return err + } + + *o = EnvironmentVariable(varEnvironmentVariable) + + return err +} + +type NullableEnvironmentVariable struct { + value *EnvironmentVariable + isSet bool +} + +func (v NullableEnvironmentVariable) Get() *EnvironmentVariable { + return v.value +} + +func (v *NullableEnvironmentVariable) Set(val *EnvironmentVariable) { + v.value = val + v.isSet = true +} + +func (v NullableEnvironmentVariable) IsSet() bool { + return v.isSet +} + +func (v *NullableEnvironmentVariable) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableEnvironmentVariable(val *EnvironmentVariable) *NullableEnvironmentVariable { + return &NullableEnvironmentVariable{value: val, isSet: true} +} + +func (v NullableEnvironmentVariable) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableEnvironmentVariable) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_profile_data.go b/pkg/apiclient/model_profile_data.go deleted file mode 100644 index 94859c102d..0000000000 --- a/pkg/apiclient/model_profile_data.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "encoding/json" - "fmt" -) - -// checks if the ProfileData type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ProfileData{} - -// ProfileData struct for ProfileData -type ProfileData struct { - EnvVars map[string]string `json:"envVars"` - Id string `json:"id"` -} - -type _ProfileData ProfileData - -// NewProfileData instantiates a new ProfileData object -// This constructor will assign default values to properties that have it defined, -// and makes sure properties required by API are set, but the set of arguments -// will change when the set of required properties is changed -func NewProfileData(envVars map[string]string, id string) *ProfileData { - this := ProfileData{} - this.EnvVars = envVars - this.Id = id - return &this -} - -// NewProfileDataWithDefaults instantiates a new ProfileData object -// This constructor will only assign default values to properties that have it defined, -// but it doesn't guarantee that properties required by API are set -func NewProfileDataWithDefaults() *ProfileData { - this := ProfileData{} - return &this -} - -// GetEnvVars returns the EnvVars field value -func (o *ProfileData) GetEnvVars() map[string]string { - if o == nil { - var ret map[string]string - return ret - } - - return o.EnvVars -} - -// GetEnvVarsOk returns a tuple with the EnvVars field value -// and a boolean to check if the value has been set. -func (o *ProfileData) GetEnvVarsOk() (*map[string]string, bool) { - if o == nil { - return nil, false - } - return &o.EnvVars, true -} - -// SetEnvVars sets field value -func (o *ProfileData) SetEnvVars(v map[string]string) { - o.EnvVars = v -} - -// GetId returns the Id field value -func (o *ProfileData) GetId() string { - if o == nil { - var ret string - return ret - } - - return o.Id -} - -// GetIdOk returns a tuple with the Id field value -// and a boolean to check if the value has been set. -func (o *ProfileData) GetIdOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Id, true -} - -// SetId sets field value -func (o *ProfileData) SetId(v string) { - o.Id = v -} - -func (o ProfileData) MarshalJSON() ([]byte, error) { - toSerialize, err := o.ToMap() - if err != nil { - return []byte{}, err - } - return json.Marshal(toSerialize) -} - -func (o ProfileData) ToMap() (map[string]interface{}, error) { - toSerialize := map[string]interface{}{} - toSerialize["envVars"] = o.EnvVars - toSerialize["id"] = o.Id - return toSerialize, nil -} - -func (o *ProfileData) UnmarshalJSON(data []byte) (err error) { - // This validates that all required properties are included in the JSON object - // by unmarshalling the object into a generic map with string keys and checking - // that every required field exists as a key in the generic map. - requiredProperties := []string{ - "envVars", - "id", - } - - allProperties := make(map[string]interface{}) - - err = json.Unmarshal(data, &allProperties) - - if err != nil { - return err - } - - for _, requiredProperty := range requiredProperties { - if _, exists := allProperties[requiredProperty]; !exists { - return fmt.Errorf("no value given for required property %v", requiredProperty) - } - } - - varProfileData := _ProfileData{} - - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(&varProfileData) - - if err != nil { - return err - } - - *o = ProfileData(varProfileData) - - return err -} - -type NullableProfileData struct { - value *ProfileData - isSet bool -} - -func (v NullableProfileData) Get() *ProfileData { - return v.value -} - -func (v *NullableProfileData) Set(val *ProfileData) { - v.value = val - v.isSet = true -} - -func (v NullableProfileData) IsSet() bool { - return v.isSet -} - -func (v *NullableProfileData) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableProfileData(val *ProfileData) *NullableProfileData { - return &NullableProfileData{value: val, isSet: true} -} - -func (v NullableProfileData) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableProfileData) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index e8a5fdddcf..a9be310565 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -10,6 +10,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/views" @@ -68,7 +69,7 @@ var buildRunCmd = &cobra.Command{ func CreateBuild(apiClient *apiclient.APIClient, workspaceConfig *apiclient.WorkspaceConfig, branch string, prebuildId *string) (string, error) { ctx := context.Background() - profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() + envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() if err != nil { return "", apiclient_util.HandleErrorResponse(res, err) } @@ -83,8 +84,8 @@ func CreateBuild(apiClient *apiclient.APIClient, workspaceConfig *apiclient.Work PrebuildId: prebuildId, } - if profileData != nil { - createBuildDto.EnvVars = util.MergeEnvVars(profileData.EnvVars, workspaceConfig.EnvVars) + if envVars != nil { + createBuildDto.EnvVars = util.MergeEnvVars(conversion.ToEnvVarsMap(envVars), workspaceConfig.EnvVars) } else { createBuildDto.EnvVars = util.MergeEnvVars(workspaceConfig.EnvVars) } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index bd4845f877..954b9c9132 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -18,11 +18,11 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/autocomplete" . "github.com/daytonaio/daytona/pkg/cmd/build" . "github.com/daytonaio/daytona/pkg/cmd/containerregistry" + . "github.com/daytonaio/daytona/pkg/cmd/env" . "github.com/daytonaio/daytona/pkg/cmd/gitprovider" . "github.com/daytonaio/daytona/pkg/cmd/ports" . "github.com/daytonaio/daytona/pkg/cmd/prebuild" . "github.com/daytonaio/daytona/pkg/cmd/profile" - . "github.com/daytonaio/daytona/pkg/cmd/profiledata/env" . "github.com/daytonaio/daytona/pkg/cmd/provider" . "github.com/daytonaio/daytona/pkg/cmd/server" . "github.com/daytonaio/daytona/pkg/cmd/target" diff --git a/pkg/cmd/env/delete.go b/pkg/cmd/env/delete.go new file mode 100644 index 0000000000..3d74c4373c --- /dev/null +++ b/pkg/cmd/env/delete.go @@ -0,0 +1,54 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "context" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/env" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var deleteCmd = &cobra.Command{ + Use: "remove [KEY]...", + Short: "Remove server environment variables", + Aliases: []string{"r", "rm", "d", "delete"}, + RunE: func(cmd *cobra.Command, args []string) error { + keys := []string{} + + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if len(args) > 0 { + keys = args + } else { + selectedEnvVars, err := env.RemoveEnvVarsView(ctx, *apiClient) + if err != nil { + return err + } + + for _, envVar := range selectedEnvVars { + keys = append(keys, envVar.Key) + } + } + + for _, key := range keys { + res, err := apiClient.EnvVarAPI.DeleteEnvironmentVariable(ctx, key).Execute() + if err != nil { + log.Error(apiclient_util.HandleErrorResponse(res, err)) + } + } + + views.RenderInfoMessageBold("Server environment variables have been successfully removed") + + return nil + }, +} diff --git a/pkg/cmd/profiledata/env/env.go b/pkg/cmd/env/env.go similarity index 66% rename from pkg/cmd/profiledata/env/env.go rename to pkg/cmd/env/env.go index 0b77d8aead..00d98fa445 100644 --- a/pkg/cmd/profiledata/env/env.go +++ b/pkg/cmd/env/env.go @@ -10,11 +10,12 @@ import ( var EnvCmd = &cobra.Command{ Use: "env", - Short: "Manage profile environment variables that are added to all targets and workspaces", - GroupID: util.PROFILE_GROUP, + Short: "Manage server environment variables that are added to all targets and workspaces", + GroupID: util.SERVER_GROUP, } func init() { EnvCmd.AddCommand(setCmd) EnvCmd.AddCommand(listCmd) + EnvCmd.AddCommand(deleteCmd) } diff --git a/pkg/cmd/profiledata/env/list.go b/pkg/cmd/env/list.go similarity index 55% rename from pkg/cmd/profiledata/env/list.go rename to pkg/cmd/env/list.go index 644124d102..2743c31557 100644 --- a/pkg/cmd/profiledata/env/list.go +++ b/pkg/cmd/env/list.go @@ -6,7 +6,8 @@ package env import ( "context" - "github.com/daytonaio/daytona/internal/util/apiclient" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/env" "github.com/spf13/cobra" @@ -14,30 +15,30 @@ import ( var listCmd = &cobra.Command{ Use: "list", - Short: "List profile environment variables", + Short: "List server environment variables", Aliases: []string{"ls"}, RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := apiclient.GetApiClient(nil) + apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } ctx := context.Background() - profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() + envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() if err != nil { - return apiclient.HandleErrorResponse(res, err) + return apiclient_util.HandleErrorResponse(res, err) } if format.FormatFlag != "" { - if profileData.EnvVars == nil { - profileData.EnvVars = map[string]string{} + if envVars == nil { + envVars = []apiclient.EnvironmentVariable{} } - formattedData := format.NewFormatter(profileData.EnvVars) + formattedData := format.NewFormatter(envVars) formattedData.Print() return nil } - env.List(profileData.EnvVars) + env.List(envVars) return nil }, } diff --git a/pkg/cmd/env/set.go b/pkg/cmd/env/set.go new file mode 100644 index 0000000000..50a5332570 --- /dev/null +++ b/pkg/cmd/env/set.go @@ -0,0 +1,62 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "context" + "fmt" + "strings" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/env" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var setCmd = &cobra.Command{ + Use: "set [KEY=VALUE]...", + Short: "Set server environment variables", + Aliases: []string{"s", "add", "new"}, + RunE: func(cmd *cobra.Command, args []string) error { + envVarsMap := make(map[string]string) + + if len(args) > 0 { + for _, arg := range args { + kv := strings.Split(arg, "=") + if len(kv) != 2 { + return fmt.Errorf("invalid key-value pair: %s", arg) + } + envVarsMap[kv[0]] = kv[1] + } + } else { + err := env.AddEnvVarsView(&envVarsMap) + if err != nil { + return err + } + } + + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + for key, value := range envVarsMap { + res, err := apiClient.EnvVarAPI.SetEnvironmentVariable(ctx).EnvironmentVariable(apiclient.EnvironmentVariable{ + Key: key, + Value: value, + }).Execute() + if err != nil { + log.Error(apiclient_util.HandleErrorResponse(res, err)) + } + } + + views.RenderInfoMessageBold("Server environment variables have been set successfully") + + return nil + }, +} diff --git a/pkg/cmd/profiledata/env/set.go b/pkg/cmd/profiledata/env/set.go deleted file mode 100644 index d05b8bb12a..0000000000 --- a/pkg/cmd/profiledata/env/set.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package env - -import ( - "context" - "fmt" - "strings" - - "github.com/charmbracelet/huh" - "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/spf13/cobra" -) - -var setCmd = &cobra.Command{ - Use: "set [KEY=VALUE]...", - Short: "Set profile environment variables", - Aliases: []string{"s", "update", "add", "delete", "rm"}, - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := apiclient.GetApiClient(nil) - if err != nil { - return err - } - ctx := context.Background() - - profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() - if err != nil { - return apiclient.HandleErrorResponse(res, err) - } - - if profileData.EnvVars == nil { - profileData.EnvVars = map[string]string{} - } - - if len(args) > 0 { - for _, arg := range args { - kv := strings.Split(arg, "=") - if len(kv) != 2 { - return fmt.Errorf("invalid key-value pair: %s", arg) - } - (profileData.EnvVars)[kv[0]] = kv[1] - } - } else { - form := huh.NewForm( - huh.NewGroup( - views.GetEnvVarsInput(&profileData.EnvVars), - ), - ).WithTheme(views.GetCustomTheme()).WithHeight(12) - - err = form.Run() - if err != nil { - return err - } - } - - res, err = apiClient.ProfileAPI.SetProfileData(ctx).ProfileData(*profileData).Execute() - if err != nil { - return apiclient.HandleErrorResponse(res, err) - } - - views.RenderInfoMessageBold("Profile environment variables have been successfully set") - return nil - }, -} diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index 3cd6040ae7..2715b1dad8 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -24,10 +24,10 @@ import ( "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/server/containerregistries" + "github.com/daytonaio/daytona/pkg/server/env" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/jobs" - "github.com/daytonaio/daytona/pkg/server/profiledata" "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" @@ -90,7 +90,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - profileDataStore, err := db.NewProfileDataStore(dbConnection) + envVarStore, err := db.NewEnvironmentVariableStore(dbConnection) if err != nil { return nil, err } @@ -386,27 +386,27 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe LoggerFactory: loggerFactory, }) - profileDataService := profiledata.NewProfileDataService(profiledata.ProfileDataServiceConfig{ - ProfileDataStore: profileDataStore, + envVarService := env.NewEnvironmentVariableService(env.EnvironmentVariableServiceConfig{ + EnvironmentVariableStore: envVarStore, }) s := server.GetInstance(&server.ServerInstanceConfig{ - Config: *c, - Version: version, - TailscaleServer: headscaleServer, - TargetConfigService: targetConfigService, - ContainerRegistryService: containerRegistryService, - BuildService: buildService, - WorkspaceConfigService: workspaceConfigService, - WorkspaceService: workspaceService, - LocalContainerRegistry: localContainerRegistry, - ApiKeyService: apiKeyService, - TargetService: targetService, - GitProviderService: gitProviderService, - ProviderManager: providerManager, - ProfileDataService: profileDataService, - JobService: jobService, - TelemetryService: telemetryService, + Config: *c, + Version: version, + TailscaleServer: headscaleServer, + TargetConfigService: targetConfigService, + ContainerRegistryService: containerRegistryService, + BuildService: buildService, + WorkspaceConfigService: workspaceConfigService, + WorkspaceService: workspaceService, + LocalContainerRegistry: localContainerRegistry, + ApiKeyService: apiKeyService, + TargetService: targetService, + GitProviderService: gitProviderService, + ProviderManager: providerManager, + EnvironmentVariableService: envVarService, + JobService: jobService, + TelemetryService: telemetryService, }) return s, s.Initialize() diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index b318c78806..fba06b829b 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -14,6 +14,7 @@ import ( "github.com/daytonaio/daytona/internal/cmd/tailscale" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" @@ -57,7 +58,7 @@ var CreateCmd = &cobra.Command{ return err } - profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute() + envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -120,8 +121,8 @@ var CreateCmd = &cobra.Command{ workspaceNames := []string{} for i := range createWorkspaceDtos { - if profileData != nil && profileData.EnvVars != nil { - createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(profileData.EnvVars, createWorkspaceDtos[i].EnvVars) + if envVars != nil { + createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(conversion.ToEnvVarsMap(envVars), createWorkspaceDtos[i].EnvVars) } else { createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(createWorkspaceDtos[i].EnvVars) } diff --git a/pkg/db/env.go b/pkg/db/env.go new file mode 100644 index 0000000000..c7f08a3c7d --- /dev/null +++ b/pkg/db/env.go @@ -0,0 +1,57 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" + "gorm.io/gorm" +) + +type EnvironmentVariableStore struct { + db *gorm.DB +} + +func NewEnvironmentVariableStore(db *gorm.DB) (*EnvironmentVariableStore, error) { + err := db.AutoMigrate(&models.EnvironmentVariable{}) + if err != nil { + return nil, err + } + + return &EnvironmentVariableStore{db: db}, nil +} + +func (store *EnvironmentVariableStore) List() ([]*models.EnvironmentVariable, error) { + environmentVariables := []*models.EnvironmentVariable{} + tx := store.db.Find(&environmentVariables) + if tx.Error != nil { + if tx.Error == gorm.ErrRecordNotFound { + return nil, stores.ErrEnvironmentVariableNotFound + } + return nil, tx.Error + } + + return environmentVariables, nil +} + +func (store *EnvironmentVariableStore) Save(environmentVariable *models.EnvironmentVariable) error { + tx := store.db.Save(environmentVariable) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (store *EnvironmentVariableStore) Delete(key string) error { + tx := store.db.Where("key = ?", key).Delete(&models.EnvironmentVariable{}) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrEnvironmentVariableNotFound + } + + return nil +} diff --git a/pkg/db/profile_data_store.go b/pkg/db/profile_data_store.go deleted file mode 100644 index 768a02f148..0000000000 --- a/pkg/db/profile_data_store.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" - "gorm.io/gorm" -) - -type ProfileDataStore struct { - db *gorm.DB -} - -func NewProfileDataStore(db *gorm.DB) (*ProfileDataStore, error) { - err := db.AutoMigrate(&models.ProfileData{}) - if err != nil { - return nil, err - } - - return &ProfileDataStore{db: db}, nil -} - -func (p *ProfileDataStore) Get(id string) (*models.ProfileData, error) { - profileData := &models.ProfileData{} - tx := p.db.Where("id = ?", id).First(profileData) - if tx.Error != nil { - if tx.Error == gorm.ErrRecordNotFound { - return nil, stores.ErrProfileDataNotFound - } - return nil, tx.Error - } - - return profileData, nil -} - -func (p *ProfileDataStore) Save(profileData *models.ProfileData) error { - tx := p.db.Save(profileData) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (p *ProfileDataStore) Delete(id string) error { - tx := p.db.Where("id = ?", id).Delete(&models.ProfileData{}) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return stores.ErrProfileDataNotFound - } - - return nil -} diff --git a/pkg/models/env.go b/pkg/models/env.go new file mode 100644 index 0000000000..ccfa8e3242 --- /dev/null +++ b/pkg/models/env.go @@ -0,0 +1,9 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +type EnvironmentVariable struct { + Key string `json:"key" validate:"required" gorm:"primaryKey"` + Value string `json:"value" validate:"required"` +} // @name EnvironmentVariable diff --git a/pkg/models/profile_data.go b/pkg/models/profile_data.go deleted file mode 100644 index 1f2c6105a5..0000000000 --- a/pkg/models/profile_data.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package models - -type ProfileData struct { - Id string `json:"id" validate:"required" gorm:"primaryKey"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` -} // @name ProfileData diff --git a/pkg/server/env/service.go b/pkg/server/env/service.go new file mode 100644 index 0000000000..84a1b7e62a --- /dev/null +++ b/pkg/server/env/service.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" +) + +type EnvironmentVariableServiceConfig struct { + EnvironmentVariableStore stores.EnvironmentVariableStore +} + +func NewEnvironmentVariableService(config EnvironmentVariableServiceConfig) services.IEnvironmentVariableService { + return &EnvironmentVariableService{ + environmentVariableStore: config.EnvironmentVariableStore, + } +} + +type EnvironmentVariableService struct { + environmentVariableStore stores.EnvironmentVariableStore +} + +func (s *EnvironmentVariableService) List() ([]*models.EnvironmentVariable, error) { + return s.environmentVariableStore.List() +} + +func (s *EnvironmentVariableService) Save(environmentVariable *models.EnvironmentVariable) error { + return s.environmentVariableStore.Save(environmentVariable) +} + +func (s *EnvironmentVariableService) Delete(key string) error { + return s.environmentVariableStore.Delete(key) +} diff --git a/pkg/server/env/service_test.go b/pkg/server/env/service_test.go new file mode 100644 index 0000000000..acefc91a51 --- /dev/null +++ b/pkg/server/env/service_test.go @@ -0,0 +1,74 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env_test + +import ( + "testing" + + t_envvar "github.com/daytonaio/daytona/internal/testing/server/env" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/env" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/stretchr/testify/suite" +) + +type EnvironmentVariableServiceTestSuite struct { + suite.Suite + environmentVariableService services.IEnvironmentVariableService + environmentVariableStore stores.EnvironmentVariableStore +} + +func NewEnvironmentVariableTestSuite() *EnvironmentVariableServiceTestSuite { + return &EnvironmentVariableServiceTestSuite{} +} + +func (s *EnvironmentVariableServiceTestSuite) SetupTest() { + s.environmentVariableStore = t_envvar.NewInMemoryEnvironmentVariableStore() + s.environmentVariableService = env.NewEnvironmentVariableService(env.EnvironmentVariableServiceConfig{ + EnvironmentVariableStore: s.environmentVariableStore, + }) +} + +func TestEnvironmentVariableService(t *testing.T) { + suite.Run(t, NewEnvironmentVariableTestSuite()) +} + +func (s *EnvironmentVariableServiceTestSuite) TestReturnsEnvironmentVariableNotFound() { + envVar, err := s.environmentVariableService.List() + s.Require().Nil(envVar) + s.Require().True(stores.IsEnvironmentVariableNotFound(err)) +} + +func (s *EnvironmentVariableServiceTestSuite) TestSaveEnvironmentVariable() { + envVar := &models.EnvironmentVariable{ + Key: "key1", + Value: "value1", + } + + err := s.environmentVariableService.Save(envVar) + s.Require().Nil(err) + + envVarsFromStore, err := s.environmentVariableStore.List() + s.Require().Nil(err) + s.Require().NotNil(envVarsFromStore) + s.Require().Equal(envVar, envVarsFromStore) +} + +func (s *EnvironmentVariableServiceTestSuite) TestDeleteEnvironmentVariable() { + envVar := &models.EnvironmentVariable{ + Key: "key1", + Value: "value1", + } + + err := s.environmentVariableService.Save(envVar) + s.Require().Nil(err) + + err = s.environmentVariableService.Delete(envVar.Key) + s.Require().Nil(err) + + EnvVarsFromStore, err := s.environmentVariableStore.List() + s.Require().Nil(EnvVarsFromStore) + s.Require().True(stores.IsEnvironmentVariableNotFound(err)) +} diff --git a/pkg/server/profiledata/service.go b/pkg/server/profiledata/service.go deleted file mode 100644 index 926d7b23fd..0000000000 --- a/pkg/server/profiledata/service.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package profiledata - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" -) - -type ProfileDataServiceConfig struct { - ProfileDataStore stores.ProfileDataStore -} - -func NewProfileDataService(config ProfileDataServiceConfig) services.IProfileDataService { - return &ProfileDataService{ - profileDataStore: config.ProfileDataStore, - } -} - -type ProfileDataService struct { - profileDataStore stores.ProfileDataStore -} - -func (s *ProfileDataService) Get(id string) (*models.ProfileData, error) { - if id == "" { - id = stores.ProfileDataId - } - - return s.profileDataStore.Get(id) -} - -func (s *ProfileDataService) Save(profileData *models.ProfileData) error { - if profileData.Id == "" { - profileData.Id = stores.ProfileDataId - } - - return s.profileDataStore.Save(profileData) -} - -func (s *ProfileDataService) Delete(id string) error { - if id == "" { - id = stores.ProfileDataId - } - - return s.profileDataStore.Delete(id) -} diff --git a/pkg/server/profiledata/service_test.go b/pkg/server/profiledata/service_test.go deleted file mode 100644 index df523162e0..0000000000 --- a/pkg/server/profiledata/service_test.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package profiledata_test - -import ( - "testing" - - t_profiledata "github.com/daytonaio/daytona/internal/testing/server/profiledata" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/profiledata" - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/stretchr/testify/suite" -) - -type ProfileDataServiceTestSuite struct { - suite.Suite - profileDataService services.IProfileDataService - profileDataStore stores.ProfileDataStore -} - -func NewApiKeyServiceTestSuite() *ProfileDataServiceTestSuite { - return &ProfileDataServiceTestSuite{} -} - -func (s *ProfileDataServiceTestSuite) SetupTest() { - s.profileDataStore = t_profiledata.NewInMemoryProfileDataStore() - s.profileDataService = profiledata.NewProfileDataService(profiledata.ProfileDataServiceConfig{ - ProfileDataStore: s.profileDataStore, - }) -} - -func TestApiKeyService(t *testing.T) { - suite.Run(t, NewApiKeyServiceTestSuite()) -} - -func (s *ProfileDataServiceTestSuite) TestReturnsProfileDataNotFound() { - profileData, err := s.profileDataService.Get("") - s.Require().Nil(profileData) - s.Require().True(stores.IsProfileDataNotFound(err)) -} - -func (s *ProfileDataServiceTestSuite) TestSaveProfileData() { - profileData := &models.ProfileData{ - EnvVars: map[string]string{ - "key1": "value1", - }, - } - - err := s.profileDataService.Save(profileData) - s.Require().Nil(err) - - profileDataFromStore, err := s.profileDataStore.Get("") - s.Require().Nil(err) - s.Require().NotNil(profileDataFromStore) - s.Require().Equal(profileData, profileDataFromStore) -} - -func (s *ProfileDataServiceTestSuite) TestDeleteProfileData() { - profileData := &models.ProfileData{ - EnvVars: map[string]string{ - "key1": "value1", - }, - } - - err := s.profileDataService.Save(profileData) - s.Require().Nil(err) - - err = s.profileDataService.Delete("") - s.Require().Nil(err) - - profileDataFromStore, err := s.profileDataStore.Get("") - s.Require().Nil(profileDataFromStore) - s.Require().True(stores.IsProfileDataNotFound(err)) -} diff --git a/pkg/server/server.go b/pkg/server/server.go index 947f739819..e85e720aab 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -16,22 +16,22 @@ import ( ) type ServerInstanceConfig struct { - Config Config - Version string - TailscaleServer TailscaleServer - TargetConfigService services.ITargetConfigService - ContainerRegistryService services.IContainerRegistryService - BuildService services.IBuildService - WorkspaceConfigService services.IWorkspaceConfigService - WorkspaceService services.IWorkspaceService - LocalContainerRegistry ILocalContainerRegistry - TargetService services.ITargetService - ApiKeyService services.IApiKeyService - GitProviderService services.IGitProviderService - ProviderManager manager.IProviderManager - ProfileDataService services.IProfileDataService - JobService services.IJobService - TelemetryService telemetry.TelemetryService + Config Config + Version string + TailscaleServer TailscaleServer + TargetConfigService services.ITargetConfigService + ContainerRegistryService services.IContainerRegistryService + BuildService services.IBuildService + WorkspaceConfigService services.IWorkspaceConfigService + WorkspaceService services.IWorkspaceService + LocalContainerRegistry ILocalContainerRegistry + TargetService services.ITargetService + ApiKeyService services.IApiKeyService + GitProviderService services.IGitProviderService + ProviderManager manager.IProviderManager + EnvironmentVariableService services.IEnvironmentVariableService + JobService services.IJobService + TelemetryService telemetry.TelemetryService } var server *Server @@ -46,23 +46,23 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { log.Fatal("Server not initialized") } server = &Server{ - Id: serverConfig.Config.Id, - config: serverConfig.Config, - Version: serverConfig.Version, - TailscaleServer: serverConfig.TailscaleServer, - TargetConfigService: serverConfig.TargetConfigService, - ContainerRegistryService: serverConfig.ContainerRegistryService, - BuildService: serverConfig.BuildService, - WorkspaceConfigService: serverConfig.WorkspaceConfigService, - WorkspaceService: serverConfig.WorkspaceService, - LocalContainerRegistry: serverConfig.LocalContainerRegistry, - TargetService: serverConfig.TargetService, - ApiKeyService: serverConfig.ApiKeyService, - GitProviderService: serverConfig.GitProviderService, - ProviderManager: serverConfig.ProviderManager, - ProfileDataService: serverConfig.ProfileDataService, - JobService: serverConfig.JobService, - TelemetryService: serverConfig.TelemetryService, + Id: serverConfig.Config.Id, + config: serverConfig.Config, + Version: serverConfig.Version, + TailscaleServer: serverConfig.TailscaleServer, + TargetConfigService: serverConfig.TargetConfigService, + ContainerRegistryService: serverConfig.ContainerRegistryService, + BuildService: serverConfig.BuildService, + WorkspaceConfigService: serverConfig.WorkspaceConfigService, + WorkspaceService: serverConfig.WorkspaceService, + LocalContainerRegistry: serverConfig.LocalContainerRegistry, + TargetService: serverConfig.TargetService, + ApiKeyService: serverConfig.ApiKeyService, + GitProviderService: serverConfig.GitProviderService, + ProviderManager: serverConfig.ProviderManager, + EnvironmentVariableService: serverConfig.EnvironmentVariableService, + JobService: serverConfig.JobService, + TelemetryService: serverConfig.TelemetryService, } } @@ -70,23 +70,23 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { } type Server struct { - Id string - config Config - Version string - TailscaleServer TailscaleServer - TargetConfigService services.ITargetConfigService - ContainerRegistryService services.IContainerRegistryService - BuildService services.IBuildService - WorkspaceConfigService services.IWorkspaceConfigService - WorkspaceService services.IWorkspaceService - LocalContainerRegistry ILocalContainerRegistry - TargetService services.ITargetService - ApiKeyService services.IApiKeyService - GitProviderService services.IGitProviderService - ProviderManager manager.IProviderManager - ProfileDataService services.IProfileDataService - JobService services.IJobService - TelemetryService telemetry.TelemetryService + Id string + config Config + Version string + TailscaleServer TailscaleServer + TargetConfigService services.ITargetConfigService + ContainerRegistryService services.IContainerRegistryService + BuildService services.IBuildService + WorkspaceConfigService services.IWorkspaceConfigService + WorkspaceService services.IWorkspaceService + LocalContainerRegistry ILocalContainerRegistry + TargetService services.ITargetService + ApiKeyService services.IApiKeyService + GitProviderService services.IGitProviderService + ProviderManager manager.IProviderManager + EnvironmentVariableService services.IEnvironmentVariableService + JobService services.IJobService + TelemetryService telemetry.TelemetryService } func (s *Server) Initialize() error { diff --git a/pkg/services/env.go b/pkg/services/env.go new file mode 100644 index 0000000000..96aa56ba4b --- /dev/null +++ b/pkg/services/env.go @@ -0,0 +1,12 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import "github.com/daytonaio/daytona/pkg/models" + +type IEnvironmentVariableService interface { + List() ([]*models.EnvironmentVariable, error) + Save(environmentVariable *models.EnvironmentVariable) error + Delete(key string) error +} diff --git a/pkg/services/profile_data.go b/pkg/services/profile_data.go deleted file mode 100644 index e5e181b332..0000000000 --- a/pkg/services/profile_data.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package services - -import "github.com/daytonaio/daytona/pkg/models" - -type IProfileDataService interface { - Get(id string) (*models.ProfileData, error) - Save(profileData *models.ProfileData) error - Delete(id string) error -} diff --git a/pkg/stores/env.go b/pkg/stores/env.go new file mode 100644 index 0000000000..b8482b44f6 --- /dev/null +++ b/pkg/stores/env.go @@ -0,0 +1,24 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type EnvironmentVariableStore interface { + List() ([]*models.EnvironmentVariable, error) + Save(environmentVariable *models.EnvironmentVariable) error + Delete(key string) error +} + +var ( + ErrEnvironmentVariableNotFound = errors.New("environment variable not found") +) + +func IsEnvironmentVariableNotFound(err error) bool { + return err.Error() == ErrEnvironmentVariableNotFound.Error() +} diff --git a/pkg/stores/profile_data.go b/pkg/stores/profile_data.go deleted file mode 100644 index a947016670..0000000000 --- a/pkg/stores/profile_data.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package stores - -import ( - "errors" - - "github.com/daytonaio/daytona/pkg/models" -) - -type ProfileDataStore interface { - Get(id string) (*models.ProfileData, error) - Save(profileData *models.ProfileData) error - Delete(id string) error -} - -const ProfileDataId = "profile_data" - -var ( - ErrProfileDataNotFound = errors.New("profile data not found") -) - -func IsProfileDataNotFound(err error) bool { - return err.Error() == ErrProfileDataNotFound.Error() -} diff --git a/pkg/views/env/add.go b/pkg/views/env/add.go new file mode 100644 index 0000000000..c5064400ef --- /dev/null +++ b/pkg/views/env/add.go @@ -0,0 +1,53 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/pkg/views" +) + +func AddEnvVarsView(envVarsMap *map[string]string) error { + var addAntoher bool + + var key string + var value string + + form := huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("Key"). + Value(&key), + huh.NewInput(). + Title("Value"). + Value(&value), + ), + ).WithTheme(views.GetCustomTheme()).WithHeight(12) + + err := form.Run() + if err != nil { + return err + } + + (*envVarsMap)[key] = value + + form = huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Add another environment variable?"). + Value(&addAntoher), + ), + ).WithTheme(views.GetCustomTheme()).WithHeight(12) + + err = form.Run() + if err != nil { + return err + } + + if addAntoher { + return AddEnvVarsView(envVarsMap) + } + + return nil +} diff --git a/pkg/views/env/delete.go b/pkg/views/env/delete.go new file mode 100644 index 0000000000..6bc978e57c --- /dev/null +++ b/pkg/views/env/delete.go @@ -0,0 +1,23 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "context" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views/env/selection" +) + +func RemoveEnvVarsView(ctx context.Context, apiClient apiclient.APIClient) ([]*apiclient.EnvironmentVariable, error) { + envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + selectedEnvVars := selection.GetEnvironmentVariablesFromPrompt(envVars, "Remove") + + return selectedEnvVars, nil +} diff --git a/pkg/views/env/list.go b/pkg/views/env/list.go index 47bd314af0..20938b9144 100644 --- a/pkg/views/env/list.go +++ b/pkg/views/env/list.go @@ -8,6 +8,7 @@ import ( "os" "strings" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" "github.com/charmbracelet/lipgloss" @@ -34,7 +35,7 @@ func getRowData(key, value string) *RowData { return &RowData{key, value} } -func List(envVars map[string]string) { +func List(envVars []apiclient.EnvironmentVariable) { if len(envVars) == 0 { views_util.NotifyEmptyEnvVarList(true) return @@ -46,11 +47,11 @@ func List(envVars map[string]string) { data := [][]string{} - for k, v := range envVars { + for _, envVar := range envVars { var rowData *RowData var row []string - rowData = getRowData(k, v) + rowData = getRowData(envVar.Key, envVar.Value) if rowData == nil { continue } @@ -86,12 +87,12 @@ func List(envVars map[string]string) { fmt.Println(views.BaseTableStyle.Render(t.String())) } -func renderUnstyledList(envVars map[string]string) { +func renderUnstyledList(envVars []apiclient.EnvironmentVariable) { output := "\n" - for k, v := range envVars { - output += fmt.Sprintf("%s\t%s", views.GetPropertyKey("Key:"), k) + "\n" - output += fmt.Sprintf("%s\t%s", views.GetPropertyKey("Value:"), v) + "\n" + for _, envVar := range envVars { + output += fmt.Sprintf("%s\t%s", views.GetPropertyKey("Key:"), envVar.Key) + "\n" + output += fmt.Sprintf("%s\t%s", views.GetPropertyKey("Value:"), envVar.Value) + "\n" output += "\n\n" } diff --git a/pkg/views/env/selection/env.go b/pkg/views/env/selection/env.go new file mode 100644 index 0000000000..aa9eef528c --- /dev/null +++ b/pkg/views/env/selection/env.go @@ -0,0 +1,108 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package selection + +import ( + "fmt" + "os" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" +) + +func generateEnvVarsList(envVars []apiclient.EnvironmentVariable, isMultipleSelect bool, action string) []list.Item { + // Initialize an empty list of items. + items := []list.Item{} + + // Populate items with titles and descriptions from envVars. + for _, envVar := range envVars { + newItem := item[apiclient.EnvironmentVariable]{ + key: envVar.Key, + desc: envVar.Value, + envVar: &envVar, + choiceProperty: envVar, + } + + if isMultipleSelect { + newItem.isMultipleSelect = true + newItem.action = action + } + + items = append(items, newItem) + } + + return items +} + +func getEnvVarsProgramEssentials(modelTitle string, actionVerb string, envVars []apiclient.EnvironmentVariable, footerText string, isMultipleSelect bool) tea.Model { + + items := generateEnvVarsList(envVars, isMultipleSelect, actionVerb) + + d := ItemDelegate[apiclient.EnvironmentVariable]{} + + l := list.New(items, d, 0, 0) + + l.Styles.FilterPrompt = lipgloss.NewStyle().Foreground(views.Green) + l.Styles.FilterCursor = lipgloss.NewStyle().Foreground(views.Green) + + l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) + l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) + + m := model[apiclient.EnvironmentVariable]{list: l} + + m.list.Title = views.GetStyledMainTitle(modelTitle + actionVerb) + m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) + m.footer = footerText + + p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() + + if err != nil { + fmt.Println("Error running program:", err) + os.Exit(1) + } + + return p +} + +func selectEnvironmentVariablePrompt(envVars []apiclient.EnvironmentVariable, actionVerb string, choiceChan chan<- *apiclient.EnvironmentVariable) { + p := getEnvVarsProgramEssentials("Select an Environment Variable To ", actionVerb, envVars, "", false) + if m, ok := p.(model[apiclient.EnvironmentVariable]); ok && m.choice != nil { + choiceChan <- m.choice + } else { + choiceChan <- nil + } +} + +func GetEnvironmentVariableFromPrompt(envVars []apiclient.EnvironmentVariable, actionVerb string) *apiclient.EnvironmentVariable { + choiceChan := make(chan *apiclient.EnvironmentVariable) + + go selectEnvironmentVariablePrompt(envVars, actionVerb, choiceChan) + + return <-choiceChan +} + +func selectEnvironmentVariablesFromPrompt(envVars []apiclient.EnvironmentVariable, actionVerb string, choiceChan chan<- []*apiclient.EnvironmentVariable) { + footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark a server environment variable.\nPress 'enter' to %s the current/marked server environment variables.", actionVerb)) + p := getEnvVarsProgramEssentials("Select Server Environment Variables To ", actionVerb, envVars, footerText, true) + + m, ok := p.(model[apiclient.EnvironmentVariable]) + if ok && m.choices != nil { + choiceChan <- m.choices + } else if ok && m.choice != nil { + choiceChan <- []*apiclient.EnvironmentVariable{m.choice} + } else { + choiceChan <- nil + } +} + +func GetEnvironmentVariablesFromPrompt(envVars []apiclient.EnvironmentVariable, actionVerb string) []*apiclient.EnvironmentVariable { + choiceChan := make(chan []*apiclient.EnvironmentVariable) + + go selectEnvironmentVariablesFromPrompt(envVars, actionVerb, choiceChan) + + return <-choiceChan +} diff --git a/pkg/views/env/selection/view.go b/pkg/views/env/selection/view.go new file mode 100644 index 0000000000..88d71ceb49 --- /dev/null +++ b/pkg/views/env/selection/view.go @@ -0,0 +1,203 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package selection + +import ( + "fmt" + "io" + "log" + "os" + "strings" + "time" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +var selectedStyles = lipgloss.NewStyle(). + Border(lipgloss.NormalBorder(), false, false, false, true). + BorderForeground(views.Green). + Bold(true). + Padding(0, 0, 0, 1) + +var statusMessageGreenStyle = lipgloss.NewStyle().Bold(true). + Foreground(lipgloss.AdaptiveColor{Light: "#04B575", Dark: "#04B575"}). + Render + +var statusMessageDangerStyle = lipgloss.NewStyle().Bold(true). + Foreground(lipgloss.AdaptiveColor{Light: "#FF474C", Dark: "#FF474C"}). + Render + +type item[T any] struct { + key, desc string + envVar *apiclient.EnvironmentVariable + choiceProperty T + isMarked bool + isMultipleSelect bool + action string +} + +func (i item[T]) Key() string { return i.key } +func (i item[T]) Description() string { return i.desc } +func (i item[T]) FilterValue() string { return i.key } + +type model[T any] struct { + list list.Model + choice *T + choices []*T + footer string + initialWidthSet bool +} + +func (m model[T]) Init() tea.Cmd { + return nil +} + +func (m model[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + if !m.initialWidthSet { + _, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + m.list.SetWidth(150) + } + } + + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "ctrl+c": + return m, tea.Quit + + case "enter": + i, ok := m.list.SelectedItem().(item[T]) + if ok { + m.choice = &i.choiceProperty + } + envVarList := m.list.Items() + var choices []*T + for _, envVar := range envVarList { + if envVar.(item[T]).isMarked { + envVarItem, ok := envVar.(item[T]) + if !ok { + continue + } + choices = append(choices, &envVarItem.choiceProperty) + } + + } + m.choices = choices + return m, tea.Quit + } + + case tea.WindowSizeMsg: + h, v := views.DocStyle.GetFrameSize() + m.list.SetSize(msg.Width-h, msg.Height-v) + } + + var cmd tea.Cmd + m.list, cmd = m.list.Update(msg) + return m, cmd +} + +func (m model[T]) View() string { + if m.footer == "" { + c, err := config.GetConfig() + if err != nil { + log.Fatal(err) + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + log.Fatal(err) + } + + m.footer = views.GetListFooter(activeProfile.Name, views.DefaultListFooterPadding) + } + + terminalWidth, terminalHeight, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + return "" + } + + if m.list.FilterState() == list.Filtering { + return views.DocStyle.MaxWidth(terminalWidth - 4).MaxHeight(terminalHeight - 4).Render(m.list.View() + m.footer) + } + + return views.DocStyle.MaxWidth(terminalWidth - 4).Height(terminalHeight - 2).Render(m.list.View() + m.footer) +} + +type ItemDelegate[T any] struct { +} + +func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem list.Item) { + i, _ := listItem.(item[T]) // Cast the listItem to your custom item type + s := strings.Builder{} + + var isSelected = index == m.Index() + + baseStyles := lipgloss.NewStyle().Padding(0, 0, 0, 2) + + key := baseStyles.Render(i.Key()) + description := baseStyles.Render(i.Description()) + + // Adjust styles as the user moves through the menu + if isSelected { + key = selectedStyles.Foreground(views.Green).Render(i.Key()) + description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) + } + + // Render to the terminal + s.WriteString(lipgloss.JoinHorizontal(lipgloss.Bottom, key)) + s.WriteRune('\n') + s.WriteString(description) + s.WriteRune('\n') + + fmt.Fprint(w, s.String()) +} + +func (d ItemDelegate[T]) Height() int { + height := lipgloss.NewStyle().GetVerticalFrameSize() + 4 + return height +} + +func (d ItemDelegate[T]) Spacing() int { + return 0 +} + +func (d ItemDelegate[T]) Update(msg tea.Msg, m *list.Model) tea.Cmd { + i, ok := m.SelectedItem().(item[T]) + if !ok { + return nil + } + + m.StatusMessageLifetime = time.Millisecond * 2000 + + var title string + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "x": + if !i.isMultipleSelect { + return nil + } + if i.isMarked { + i.key = strings.TrimPrefix(i.key, statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action))) + i.isMarked = false + m.SetItem(m.Index(), i) + return m.NewStatusMessage(statusMessageGreenStyle("Removed environment variable from list: ") + statusMessageGreenStyle(i.key)) + } + + title = i.key + i.key = statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action)) + statusMessageGreenStyle(i.key) + i.isMarked = true + m.SetItem(m.Index(), i) + return m.NewStatusMessage(statusMessageDangerStyle("Added envrionment variable to list: ") + statusMessageGreenStyle(title)) + } + } + return nil +} diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index 62ab403553..e50eee081e 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -83,9 +83,9 @@ func NotifyEmptyBuildList(tip bool) { } func NotifyEmptyEnvVarList(tip bool) { - views.RenderInfoMessageBold("No environment variables found") + views.RenderInfoMessageBold("No server environment variables found") if tip { - views.RenderTip("Use 'daytona env set' to set environment variables") + views.RenderTip("Use 'daytona env set' to add new server environment variables") } } From e91fdecfc9f352f6fcae8e815801a08bed7831de Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Fri, 29 Nov 2024 10:37:10 +0100 Subject: [PATCH 15/76] refactor: rename workspace config to workspace template (#1389) Signed-off-by: Ivan Dagelic --- docs/daytona.md | 2 +- docs/daytona_build.md | 2 +- docs/daytona_build_run.md | 2 +- docs/daytona_create.md | 2 +- docs/daytona_template.md | 20 ++ ...-config_add.md => daytona_template_add.md} | 10 +- docs/daytona_template_delete.md | 26 ++ ...onfig_list.md => daytona_template_info.md} | 8 +- ...onfig_info.md => daytona_template_list.md} | 8 +- docs/daytona_template_set-default.md | 18 + docs/daytona_template_update.md | 18 + docs/daytona_workspace-config.md | 20 -- docs/daytona_workspace-config_delete.md | 26 -- docs/daytona_workspace-config_set-default.md | 18 - docs/daytona_workspace-config_update.md | 18 - hack/docs/daytona.yaml | 2 +- hack/docs/daytona_build.yaml | 2 +- hack/docs/daytona_build_run.yaml | 2 +- hack/docs/daytona_create.yaml | 3 +- hack/docs/daytona_template.yaml | 14 + ...fig_add.yaml => daytona_template_add.yaml} | 10 +- ...lete.yaml => daytona_template_delete.yaml} | 10 +- ...g_list.yaml => daytona_template_info.yaml} | 8 +- ...g_info.yaml => daytona_template_list.yaml} | 8 +- hack/docs/daytona_template_set-default.yaml | 9 + hack/docs/daytona_template_update.yaml | 9 + hack/docs/daytona_workspace-config.yaml | 14 - .../daytona_workspace-config_set-default.yaml | 9 - .../docs/daytona_workspace-config_update.yaml | 9 - .../testing/server/targets/mocks/builder.go | 4 +- .../targets/mocks/workspace_config_service.go | 82 ----- ...kspace_config.go => workspace_template.go} | 2 +- .../mocks/workspace_template_service.go | 82 +++++ .../testing/server/workspaceconfig/store.go | 95 ------ .../testing/server/workspacetemplate/store.go | 95 ++++++ .../util/apiclient/conversion/workspace.go | 24 +- pkg/api/controllers/build/build.go | 2 +- .../workspaceconfig/workspace_config.go | 218 ------------ .../prebuild/prebuild.go | 72 ++-- .../prebuild/process_git_event.go | 4 +- .../workspacetemplate/workspace_template.go | 218 ++++++++++++ pkg/api/docs/docs.go | 260 +++++++------- pkg/api/docs/swagger.json | 260 +++++++------- pkg/api/docs/swagger.yaml | 220 ++++++------ pkg/api/server.go | 36 +- pkg/apiclient/README.md | 28 +- pkg/apiclient/api/openapi.yaml | 320 +++++++++--------- pkg/apiclient/api_prebuild.go | 114 +++---- ...ce_config.go => api_workspace_template.go} | 224 ++++++------ pkg/apiclient/client.go | 4 +- pkg/apiclient/docs/BuildAPI.md | 2 +- pkg/apiclient/docs/CreateBuildDTO.md | 22 +- ...igDTO.md => CreateWorkspaceTemplateDTO.md} | 64 ++-- pkg/apiclient/docs/PrebuildAPI.md | 56 +-- pkg/apiclient/docs/PrebuildDTO.md | 22 +- ...orkspaceConfig.md => WorkspaceTemplate.md} | 74 ++-- ...ceConfigAPI.md => WorkspaceTemplateAPI.md} | 120 +++---- pkg/apiclient/model_create_build_dto.go | 34 +- ...=> model_create_workspace_template_dto.go} | 104 +++--- pkg/apiclient/model_prebuild_dto.go | 38 +-- ..._config.go => model_workspace_template.go} | 114 +++---- pkg/cmd/build/run.go | 34 +- pkg/cmd/cmd.go | 4 +- pkg/cmd/prebuild/add.go | 46 +-- pkg/cmd/prebuild/delete.go | 12 +- pkg/cmd/prebuild/info.go | 6 +- pkg/cmd/prebuild/update.go | 30 +- .../server/bootstrap/get_server_instance.go | 36 +- pkg/cmd/workspace/create/add_from_config.go | 61 ---- pkg/cmd/workspace/create/add_from_template.go | 61 ++++ pkg/cmd/workspace/create/cmd.go | 26 +- pkg/cmd/workspace/create/creation_data.go | 54 +-- .../workspace/create/process_cmd_arguments.go | 50 +-- pkg/cmd/workspace/create/process_prompting.go | 18 +- pkg/cmd/workspaceconfig/delete.go | 116 ------- pkg/cmd/workspaceconfig/workspaceconfig.go | 27 -- .../add.go | 106 +++--- pkg/cmd/workspacetemplate/delete.go | 116 +++++++ .../export.go | 24 +- .../import.go | 40 +-- .../info.go | 28 +- .../list.go | 16 +- .../setdefault.go | 26 +- .../update.go | 54 +-- .../workspacetemplate/workspacetemplate.go | 27 ++ pkg/db/workspace_config_store.go | 89 ----- pkg/db/workspace_template_store.go | 89 +++++ ...kspace_config.go => workspace_template.go} | 36 +- pkg/server/builds/service.go | 34 +- pkg/server/builds/service_test.go | 8 +- pkg/server/gitproviders/remove.go | 2 +- pkg/server/gitproviders/service.go | 10 +- pkg/server/server.go | 6 +- .../dto/workspacetemplate.go} | 16 +- .../prebuild.go | 120 +++---- .../prebuild_test.go | 72 ++-- .../service.go | 70 ++-- .../service_test.go | 146 ++++---- pkg/services/build.go | 8 +- pkg/services/workspace.go | 8 +- pkg/services/workspace_config.go | 28 -- pkg/services/workspace_template.go | 28 ++ pkg/stores/workspace_config.go | 46 --- pkg/stores/workspace_template.go | 46 +++ pkg/views/build/info/view.go | 6 +- pkg/views/prebuild/add/add.go | 12 +- pkg/views/prebuild/info/view.go | 2 +- pkg/views/prebuild/list/view.go | 22 +- pkg/views/selection/prebuild.go | 2 +- ...orkspaceconfig.go => workspacetemplate.go} | 34 +- pkg/views/util/build_choice.go | 4 +- pkg/views/util/empty_list.go | 6 +- pkg/views/workspace/create/configuration.go | 4 +- pkg/views/workspace/create/summary.go | 8 +- .../info/view.go | 40 +-- .../list/view.go | 38 +-- 116 files changed, 2689 insertions(+), 2690 deletions(-) create mode 100644 docs/daytona_template.md rename docs/{daytona_workspace-config_add.md => daytona_template_add.md} (79%) create mode 100644 docs/daytona_template_delete.md rename docs/{daytona_workspace-config_list.md => daytona_template_info.md} (52%) rename docs/{daytona_workspace-config_info.md => daytona_template_list.md} (52%) create mode 100644 docs/daytona_template_set-default.md create mode 100644 docs/daytona_template_update.md delete mode 100644 docs/daytona_workspace-config.md delete mode 100644 docs/daytona_workspace-config_delete.md delete mode 100644 docs/daytona_workspace-config_set-default.md delete mode 100644 docs/daytona_workspace-config_update.md create mode 100644 hack/docs/daytona_template.yaml rename hack/docs/{daytona_workspace-config_add.yaml => daytona_template_add.yaml} (82%) rename hack/docs/{daytona_workspace-config_delete.yaml => daytona_template_delete.yaml} (63%) rename hack/docs/{daytona_workspace-config_list.yaml => daytona_template_info.yaml} (54%) rename hack/docs/{daytona_workspace-config_info.yaml => daytona_template_list.yaml} (54%) create mode 100644 hack/docs/daytona_template_set-default.yaml create mode 100644 hack/docs/daytona_template_update.yaml delete mode 100644 hack/docs/daytona_workspace-config.yaml delete mode 100644 hack/docs/daytona_workspace-config_set-default.yaml delete mode 100644 hack/docs/daytona_workspace-config_update.yaml delete mode 100644 internal/testing/server/targets/mocks/workspace_config_service.go rename internal/testing/server/targets/mocks/{workspace_config.go => workspace_template.go} (87%) create mode 100644 internal/testing/server/targets/mocks/workspace_template_service.go delete mode 100644 internal/testing/server/workspaceconfig/store.go create mode 100644 internal/testing/server/workspacetemplate/store.go delete mode 100644 pkg/api/controllers/workspaceconfig/workspace_config.go rename pkg/api/controllers/{workspaceconfig => workspacetemplate}/prebuild/prebuild.go (59%) rename pkg/api/controllers/{workspaceconfig => workspacetemplate}/prebuild/process_git_event.go (89%) create mode 100644 pkg/api/controllers/workspacetemplate/workspace_template.go rename pkg/apiclient/{api_workspace_config.go => api_workspace_template.go} (70%) rename pkg/apiclient/docs/{CreateWorkspaceConfigDTO.md => CreateWorkspaceTemplateDTO.md} (63%) rename pkg/apiclient/docs/{WorkspaceConfig.md => WorkspaceTemplate.md} (66%) rename pkg/apiclient/docs/{WorkspaceConfigAPI.md => WorkspaceTemplateAPI.md} (58%) rename pkg/apiclient/{model_create_workspace_config_dto.go => model_create_workspace_template_dto.go} (64%) rename pkg/apiclient/{model_workspace_config.go => model_workspace_template.go} (68%) delete mode 100644 pkg/cmd/workspace/create/add_from_config.go create mode 100644 pkg/cmd/workspace/create/add_from_template.go delete mode 100644 pkg/cmd/workspaceconfig/delete.go delete mode 100644 pkg/cmd/workspaceconfig/workspaceconfig.go rename pkg/cmd/{workspaceconfig => workspacetemplate}/add.go (64%) create mode 100644 pkg/cmd/workspacetemplate/delete.go rename pkg/cmd/{workspaceconfig => workspacetemplate}/export.go (76%) rename pkg/cmd/{workspaceconfig => workspacetemplate}/import.go (81%) rename pkg/cmd/{workspaceconfig => workspacetemplate}/info.go (61%) rename pkg/cmd/{workspaceconfig => workspacetemplate}/list.go (67%) rename pkg/cmd/{workspaceconfig => workspacetemplate}/setdefault.go (51%) rename pkg/cmd/{workspaceconfig => workspacetemplate}/update.go (58%) create mode 100644 pkg/cmd/workspacetemplate/workspacetemplate.go delete mode 100644 pkg/db/workspace_config_store.go create mode 100644 pkg/db/workspace_template_store.go rename pkg/models/{workspace_config.go => workspace_template.go} (79%) rename pkg/server/{workspaceconfigs/dto/workspaceconfig.go => workspacetemplates/dto/workspacetemplate.go} (69%) rename pkg/server/{workspaceconfigs => workspacetemplates}/prebuild.go (63%) rename pkg/server/{workspaceconfigs => workspacetemplates}/prebuild_test.go (69%) rename pkg/server/{workspaceconfigs => workspacetemplates}/service.go (61%) rename pkg/server/{workspaceconfigs => workspacetemplates}/service_test.go (50%) delete mode 100644 pkg/services/workspace_config.go create mode 100644 pkg/services/workspace_template.go delete mode 100644 pkg/stores/workspace_config.go create mode 100644 pkg/stores/workspace_template.go rename pkg/views/selection/{workspaceconfig.go => workspacetemplate.go} (51%) rename pkg/views/{workspaceconfig => workspacetemplate}/info/view.go (70%) rename pkg/views/{workspaceconfig => workspacetemplate}/list/view.go (50%) diff --git a/docs/daytona.md b/docs/daytona.md index 036ea6f451..770c63c336 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -48,8 +48,8 @@ daytona [flags] * [daytona target](daytona_target.md) - Manage targets * [daytona target-config](daytona_target-config.md) - Manage target configs * [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection +* [daytona template](daytona_template.md) - Manage workspace templates * [daytona use](daytona_use.md) - Use profile [PROFILE_NAME] * [daytona version](daytona_version.md) - Print the version number * [daytona whoami](daytona_whoami.md) - Display information about the active user -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs diff --git a/docs/daytona_build.md b/docs/daytona_build.md index 498d794854..b92a3b7ee7 100644 --- a/docs/daytona_build.md +++ b/docs/daytona_build.md @@ -15,5 +15,5 @@ Manage builds * [daytona build info](daytona_build_info.md) - Show build info * [daytona build list](daytona_build_list.md) - List all builds * [daytona build logs](daytona_build_logs.md) - View logs for build -* [daytona build run](daytona_build_run.md) - Run a build from a workspace config +* [daytona build run](daytona_build_run.md) - Run a build from a workspace template diff --git a/docs/daytona_build_run.md b/docs/daytona_build_run.md index 8d7f3ab13a..f8067724a2 100644 --- a/docs/daytona_build_run.md +++ b/docs/daytona_build_run.md @@ -1,6 +1,6 @@ ## daytona build run -Run a build from a workspace config +Run a build from a workspace template ``` daytona build run [flags] diff --git a/docs/daytona_create.md b/docs/daytona_create.md index 88850a9655..b5b0c57083 100644 --- a/docs/daytona_create.md +++ b/docs/daytona_create.md @@ -9,7 +9,7 @@ daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] ### Options ``` - --blank Create a blank workspace without using existing configurations + --blank Create a blank workspace without using existing templates --branch strings Specify the Git branches to use in the workspaces --builder BuildChoice Specify the builder (currently auto/devcontainer/none) --custom-image string Create the workspace with the custom image passed as the flag value; Requires setting --custom-image-user flag as well diff --git a/docs/daytona_template.md b/docs/daytona_template.md new file mode 100644 index 0000000000..8986a48c58 --- /dev/null +++ b/docs/daytona_template.md @@ -0,0 +1,20 @@ +## daytona template + +Manage workspace templates + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona template add](daytona_template_add.md) - Add a workspace template +* [daytona template delete](daytona_template_delete.md) - Delete a workspace template +* [daytona template info](daytona_template_info.md) - Show workspace template info +* [daytona template list](daytona_template_list.md) - Lists workspace templates +* [daytona template set-default](daytona_template_set-default.md) - Set workspace template info +* [daytona template update](daytona_template_update.md) - Update a workspace template + diff --git a/docs/daytona_workspace-config_add.md b/docs/daytona_template_add.md similarity index 79% rename from docs/daytona_workspace-config_add.md rename to docs/daytona_template_add.md index 64d30511d9..a74b5ae4c5 100644 --- a/docs/daytona_workspace-config_add.md +++ b/docs/daytona_template_add.md @@ -1,9 +1,9 @@ -## daytona workspace-config add +## daytona template add -Add a workspace config +Add a workspace template ``` -daytona workspace-config add [flags] +daytona template add [flags] ``` ### Options @@ -16,7 +16,7 @@ daytona workspace-config add [flags] --env stringArray Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') --git-provider-config string Specify the Git provider configuration ID or alias --manual Manually enter the Git repository - --name string Specify the workspace config name + --name string Specify the workspace template name ``` ### Options inherited from parent commands @@ -27,5 +27,5 @@ daytona workspace-config add [flags] ### SEE ALSO -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs +* [daytona template](daytona_template.md) - Manage workspace templates diff --git a/docs/daytona_template_delete.md b/docs/daytona_template_delete.md new file mode 100644 index 0000000000..c4559a3ee0 --- /dev/null +++ b/docs/daytona_template_delete.md @@ -0,0 +1,26 @@ +## daytona template delete + +Delete a workspace template + +``` +daytona template delete [flags] +``` + +### Options + +``` + -a, --all Delete all workspace templates + -f, --force Force delete prebuild + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona template](daytona_template.md) - Manage workspace templates + diff --git a/docs/daytona_workspace-config_list.md b/docs/daytona_template_info.md similarity index 52% rename from docs/daytona_workspace-config_list.md rename to docs/daytona_template_info.md index aa183e5661..d1e74a373d 100644 --- a/docs/daytona_workspace-config_list.md +++ b/docs/daytona_template_info.md @@ -1,9 +1,9 @@ -## daytona workspace-config list +## daytona template info -Lists workspace configs +Show workspace template info ``` -daytona workspace-config list [flags] +daytona template info [flags] ``` ### Options @@ -20,5 +20,5 @@ daytona workspace-config list [flags] ### SEE ALSO -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs +* [daytona template](daytona_template.md) - Manage workspace templates diff --git a/docs/daytona_workspace-config_info.md b/docs/daytona_template_list.md similarity index 52% rename from docs/daytona_workspace-config_info.md rename to docs/daytona_template_list.md index 71c0f4e022..d9516930f4 100644 --- a/docs/daytona_workspace-config_info.md +++ b/docs/daytona_template_list.md @@ -1,9 +1,9 @@ -## daytona workspace-config info +## daytona template list -Show workspace config info +Lists workspace templates ``` -daytona workspace-config info [flags] +daytona template list [flags] ``` ### Options @@ -20,5 +20,5 @@ daytona workspace-config info [flags] ### SEE ALSO -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs +* [daytona template](daytona_template.md) - Manage workspace templates diff --git a/docs/daytona_template_set-default.md b/docs/daytona_template_set-default.md new file mode 100644 index 0000000000..42be561c23 --- /dev/null +++ b/docs/daytona_template_set-default.md @@ -0,0 +1,18 @@ +## daytona template set-default + +Set workspace template info + +``` +daytona template set-default [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona template](daytona_template.md) - Manage workspace templates + diff --git a/docs/daytona_template_update.md b/docs/daytona_template_update.md new file mode 100644 index 0000000000..c6602fd52c --- /dev/null +++ b/docs/daytona_template_update.md @@ -0,0 +1,18 @@ +## daytona template update + +Update a workspace template + +``` +daytona template update [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona template](daytona_template.md) - Manage workspace templates + diff --git a/docs/daytona_workspace-config.md b/docs/daytona_workspace-config.md deleted file mode 100644 index 375c80a6ab..0000000000 --- a/docs/daytona_workspace-config.md +++ /dev/null @@ -1,20 +0,0 @@ -## daytona workspace-config - -Manage workspace configs - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona workspace-config add](daytona_workspace-config_add.md) - Add a workspace config -* [daytona workspace-config delete](daytona_workspace-config_delete.md) - Delete a workspace config -* [daytona workspace-config info](daytona_workspace-config_info.md) - Show workspace config info -* [daytona workspace-config list](daytona_workspace-config_list.md) - Lists workspace configs -* [daytona workspace-config set-default](daytona_workspace-config_set-default.md) - Set workspace config info -* [daytona workspace-config update](daytona_workspace-config_update.md) - Update a workspace config - diff --git a/docs/daytona_workspace-config_delete.md b/docs/daytona_workspace-config_delete.md deleted file mode 100644 index 876865722c..0000000000 --- a/docs/daytona_workspace-config_delete.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona workspace-config delete - -Delete a workspace config - -``` -daytona workspace-config delete [flags] -``` - -### Options - -``` - -a, --all Delete all workspace configs - -f, --force Force delete prebuild - -y, --yes Confirm deletion without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs - diff --git a/docs/daytona_workspace-config_set-default.md b/docs/daytona_workspace-config_set-default.md deleted file mode 100644 index 564daabf3f..0000000000 --- a/docs/daytona_workspace-config_set-default.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona workspace-config set-default - -Set workspace config info - -``` -daytona workspace-config set-default [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs - diff --git a/docs/daytona_workspace-config_update.md b/docs/daytona_workspace-config_update.md deleted file mode 100644 index 734a480160..0000000000 --- a/docs/daytona_workspace-config_update.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona workspace-config update - -Update a workspace config - -``` -daytona workspace-config update [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona workspace-config](daytona_workspace-config.md) - Manage workspace configs - diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index ee30f505a7..7f008b6c22 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -40,7 +40,7 @@ see_also: - daytona target - Manage targets - daytona target-config - Manage target configs - daytona telemetry - Manage telemetry collection + - daytona template - Manage workspace templates - daytona use - Use profile [PROFILE_NAME] - daytona version - Print the version number - daytona whoami - Display information about the active user - - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_build.yaml b/hack/docs/daytona_build.yaml index 972e9c42de..eefad4b949 100644 --- a/hack/docs/daytona_build.yaml +++ b/hack/docs/daytona_build.yaml @@ -10,4 +10,4 @@ see_also: - daytona build info - Show build info - daytona build list - List all builds - daytona build logs - View logs for build - - daytona build run - Run a build from a workspace config + - daytona build run - Run a build from a workspace template diff --git a/hack/docs/daytona_build_run.yaml b/hack/docs/daytona_build_run.yaml index 71dc903ecf..ab0c7a394f 100644 --- a/hack/docs/daytona_build_run.yaml +++ b/hack/docs/daytona_build_run.yaml @@ -1,5 +1,5 @@ name: daytona build run -synopsis: Run a build from a workspace config +synopsis: Run a build from a workspace template usage: daytona build run [flags] inherited_options: - name: help diff --git a/hack/docs/daytona_create.yaml b/hack/docs/daytona_create.yaml index bc3a691be4..9236cb7115 100644 --- a/hack/docs/daytona_create.yaml +++ b/hack/docs/daytona_create.yaml @@ -4,8 +4,7 @@ usage: daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] options: - name: blank default_value: "false" - usage: | - Create a blank workspace without using existing configurations + usage: Create a blank workspace without using existing templates - name: branch default_value: '[]' usage: Specify the Git branches to use in the workspaces diff --git a/hack/docs/daytona_template.yaml b/hack/docs/daytona_template.yaml new file mode 100644 index 0000000000..96a55556d8 --- /dev/null +++ b/hack/docs/daytona_template.yaml @@ -0,0 +1,14 @@ +name: daytona template +synopsis: Manage workspace templates +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona template add - Add a workspace template + - daytona template delete - Delete a workspace template + - daytona template info - Show workspace template info + - daytona template list - Lists workspace templates + - daytona template set-default - Set workspace template info + - daytona template update - Update a workspace template diff --git a/hack/docs/daytona_workspace-config_add.yaml b/hack/docs/daytona_template_add.yaml similarity index 82% rename from hack/docs/daytona_workspace-config_add.yaml rename to hack/docs/daytona_template_add.yaml index 60c7e5dd2a..283a3d606c 100644 --- a/hack/docs/daytona_workspace-config_add.yaml +++ b/hack/docs/daytona_template_add.yaml @@ -1,6 +1,6 @@ -name: daytona workspace-config add -synopsis: Add a workspace config -usage: daytona workspace-config add [flags] +name: daytona template add +synopsis: Add a workspace template +usage: daytona template add [flags] options: - name: builder usage: Specify the builder (currently auto/devcontainer/none) @@ -23,10 +23,10 @@ options: default_value: "false" usage: Manually enter the Git repository - name: name - usage: Specify the workspace config name + usage: Specify the workspace template name inherited_options: - name: help default_value: "false" usage: help for daytona see_also: - - daytona workspace-config - Manage workspace configs + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_workspace-config_delete.yaml b/hack/docs/daytona_template_delete.yaml similarity index 63% rename from hack/docs/daytona_workspace-config_delete.yaml rename to hack/docs/daytona_template_delete.yaml index cd1d8ca487..483ea8ab43 100644 --- a/hack/docs/daytona_workspace-config_delete.yaml +++ b/hack/docs/daytona_template_delete.yaml @@ -1,11 +1,11 @@ -name: daytona workspace-config delete -synopsis: Delete a workspace config -usage: daytona workspace-config delete [flags] +name: daytona template delete +synopsis: Delete a workspace template +usage: daytona template delete [flags] options: - name: all shorthand: a default_value: "false" - usage: Delete all workspace configs + usage: Delete all workspace templates - name: force shorthand: f default_value: "false" @@ -19,4 +19,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona workspace-config - Manage workspace configs + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_workspace-config_list.yaml b/hack/docs/daytona_template_info.yaml similarity index 54% rename from hack/docs/daytona_workspace-config_list.yaml rename to hack/docs/daytona_template_info.yaml index 4e90b3054d..393928089f 100644 --- a/hack/docs/daytona_workspace-config_list.yaml +++ b/hack/docs/daytona_template_info.yaml @@ -1,6 +1,6 @@ -name: daytona workspace-config list -synopsis: Lists workspace configs -usage: daytona workspace-config list [flags] +name: daytona template info +synopsis: Show workspace template info +usage: daytona template info [flags] options: - name: format shorthand: f @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona workspace-config - Manage workspace configs + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_workspace-config_info.yaml b/hack/docs/daytona_template_list.yaml similarity index 54% rename from hack/docs/daytona_workspace-config_info.yaml rename to hack/docs/daytona_template_list.yaml index 3957065c22..a59659bbd4 100644 --- a/hack/docs/daytona_workspace-config_info.yaml +++ b/hack/docs/daytona_template_list.yaml @@ -1,6 +1,6 @@ -name: daytona workspace-config info -synopsis: Show workspace config info -usage: daytona workspace-config info [flags] +name: daytona template list +synopsis: Lists workspace templates +usage: daytona template list [flags] options: - name: format shorthand: f @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona workspace-config - Manage workspace configs + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_template_set-default.yaml b/hack/docs/daytona_template_set-default.yaml new file mode 100644 index 0000000000..675b94e95a --- /dev/null +++ b/hack/docs/daytona_template_set-default.yaml @@ -0,0 +1,9 @@ +name: daytona template set-default +synopsis: Set workspace template info +usage: daytona template set-default [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_template_update.yaml b/hack/docs/daytona_template_update.yaml new file mode 100644 index 0000000000..ed459341f7 --- /dev/null +++ b/hack/docs/daytona_template_update.yaml @@ -0,0 +1,9 @@ +name: daytona template update +synopsis: Update a workspace template +usage: daytona template update [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_workspace-config.yaml b/hack/docs/daytona_workspace-config.yaml deleted file mode 100644 index 9cfdaccbfc..0000000000 --- a/hack/docs/daytona_workspace-config.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona workspace-config -synopsis: Manage workspace configs -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona workspace-config add - Add a workspace config - - daytona workspace-config delete - Delete a workspace config - - daytona workspace-config info - Show workspace config info - - daytona workspace-config list - Lists workspace configs - - daytona workspace-config set-default - Set workspace config info - - daytona workspace-config update - Update a workspace config diff --git a/hack/docs/daytona_workspace-config_set-default.yaml b/hack/docs/daytona_workspace-config_set-default.yaml deleted file mode 100644 index 022dfb9c11..0000000000 --- a/hack/docs/daytona_workspace-config_set-default.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona workspace-config set-default -synopsis: Set workspace config info -usage: daytona workspace-config set-default [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona workspace-config - Manage workspace configs diff --git a/hack/docs/daytona_workspace-config_update.yaml b/hack/docs/daytona_workspace-config_update.yaml deleted file mode 100644 index 04f4d07cb7..0000000000 --- a/hack/docs/daytona_workspace-config_update.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona workspace-config update -synopsis: Update a workspace config -usage: daytona workspace-config update [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona workspace-config - Manage workspace configs diff --git a/internal/testing/server/targets/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go index 40e98387f1..06be3f5157 100644 --- a/internal/testing/server/targets/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -23,10 +23,10 @@ var MockBuild = &models.Build{ User: "test", }, BuildConfig: &models.BuildConfig{ - Devcontainer: MockWorkspaceConfig.BuildConfig.Devcontainer, + Devcontainer: MockWorkspaceTemplate.BuildConfig.Devcontainer, }, Repository: &gitprovider.GitRepository{ - Url: MockWorkspaceConfig.RepositoryUrl, + Url: MockWorkspaceTemplate.RepositoryUrl, }, EnvVars: map[string]string{}, } diff --git a/internal/testing/server/targets/mocks/workspace_config_service.go b/internal/testing/server/targets/mocks/workspace_config_service.go deleted file mode 100644 index a21cb30da6..0000000000 --- a/internal/testing/server/targets/mocks/workspace_config_service.go +++ /dev/null @@ -1,82 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package mocks - -import ( - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/stretchr/testify/mock" -) - -type mockWorkspaceConfigService struct { - mock.Mock -} - -func NewMockWorkspaceConfigService() *mockWorkspaceConfigService { - return &mockWorkspaceConfigService{} -} - -func (m *mockWorkspaceConfigService) Delete(name string, force bool) []error { - args := m.Called(name, force) - return args.Get(0).([]error) -} - -func (m *mockWorkspaceConfigService) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { - args := m.Called(filter) - return args.Get(0).(*models.WorkspaceConfig), args.Error(1) -} - -func (m *mockWorkspaceConfigService) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { - args := m.Called(filter) - return args.Get(0).([]*models.WorkspaceConfig), args.Error(1) -} - -func (m *mockWorkspaceConfigService) SetDefault(name string) error { - args := m.Called(name) - return args.Error(0) -} - -func (m *mockWorkspaceConfigService) Save(wc *models.WorkspaceConfig) error { - args := m.Called(wc) - return args.Error(0) -} - -func (m *mockWorkspaceConfigService) SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { - args := m.Called(workspaceConfigName, createPrebuildDto) - return args.Get(0).(*dto.PrebuildDTO), args.Error(1) -} - -func (m *mockWorkspaceConfigService) FindPrebuild(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { - args := m.Called(workspaceConfigFilter, prebuildFilter) - return args.Get(0).(*dto.PrebuildDTO), args.Error(1) -} - -func (m *mockWorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { - args := m.Called(workspaceConfigFilter, prebuildFilter) - return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) -} - -func (m *mockWorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id string, force bool) []error { - args := m.Called(workspaceConfigName, id, force) - return args.Get(0).([]error) -} - -func (m *mockWorkspaceConfigService) StartRetentionPoller() error { - args := m.Called() - return args.Error(0) -} - -func (m *mockWorkspaceConfigService) EnforceRetentionPolicy() error { - args := m.Called() - return args.Error(0) -} - -func (m *mockWorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { - args := m.Called(data) - return args.Error(0) -} diff --git a/internal/testing/server/targets/mocks/workspace_config.go b/internal/testing/server/targets/mocks/workspace_template.go similarity index 87% rename from internal/testing/server/targets/mocks/workspace_config.go rename to internal/testing/server/targets/mocks/workspace_template.go index fad49d0e7e..2486c54e47 100644 --- a/internal/testing/server/targets/mocks/workspace_config.go +++ b/internal/testing/server/targets/mocks/workspace_template.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -var MockWorkspaceConfig = models.WorkspaceConfig{ +var MockWorkspaceTemplate = models.WorkspaceTemplate{ BuildConfig: &models.BuildConfig{ Devcontainer: &models.DevcontainerConfig{ FilePath: ".devcontainer/devcontainer.json", diff --git a/internal/testing/server/targets/mocks/workspace_template_service.go b/internal/testing/server/targets/mocks/workspace_template_service.go new file mode 100644 index 0000000000..ff0cc4780c --- /dev/null +++ b/internal/testing/server/targets/mocks/workspace_template_service.go @@ -0,0 +1,82 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package mocks + +import ( + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/stretchr/testify/mock" +) + +type mockWorkspaceTemplateService struct { + mock.Mock +} + +func NewMockWorkspaceTemplateService() *mockWorkspaceTemplateService { + return &mockWorkspaceTemplateService{} +} + +func (m *mockWorkspaceTemplateService) Delete(name string, force bool) []error { + args := m.Called(name, force) + return args.Get(0).([]error) +} + +func (m *mockWorkspaceTemplateService) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { + args := m.Called(filter) + return args.Get(0).(*models.WorkspaceTemplate), args.Error(1) +} + +func (m *mockWorkspaceTemplateService) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + args := m.Called(filter) + return args.Get(0).([]*models.WorkspaceTemplate), args.Error(1) +} + +func (m *mockWorkspaceTemplateService) SetDefault(name string) error { + args := m.Called(name) + return args.Error(0) +} + +func (m *mockWorkspaceTemplateService) Save(wt *models.WorkspaceTemplate) error { + args := m.Called(wt) + return args.Error(0) +} + +func (m *mockWorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { + args := m.Called(workspaceTemplateName, createPrebuildDto) + return args.Get(0).(*dto.PrebuildDTO), args.Error(1) +} + +func (m *mockWorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { + args := m.Called(workspaceTemplateFilter, prebuildFilter) + return args.Get(0).(*dto.PrebuildDTO), args.Error(1) +} + +func (m *mockWorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { + args := m.Called(workspaceTemplateFilter, prebuildFilter) + return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) +} + +func (m *mockWorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, id string, force bool) []error { + args := m.Called(workspaceTemplateName, id, force) + return args.Get(0).([]error) +} + +func (m *mockWorkspaceTemplateService) StartRetentionPoller() error { + args := m.Called() + return args.Error(0) +} + +func (m *mockWorkspaceTemplateService) EnforceRetentionPolicy() error { + args := m.Called() + return args.Error(0) +} + +func (m *mockWorkspaceTemplateService) ProcessGitEvent(data gitprovider.GitEventData) error { + args := m.Called(data) + return args.Error(0) +} diff --git a/internal/testing/server/workspaceconfig/store.go b/internal/testing/server/workspaceconfig/store.go deleted file mode 100644 index 3b103b57fc..0000000000 --- a/internal/testing/server/workspaceconfig/store.go +++ /dev/null @@ -1,95 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaceconfig - -import ( - "fmt" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" -) - -type InMemoryWorkspaceConfigStore struct { - workspaceConfigs map[string]*models.WorkspaceConfig -} - -func NewInMemoryWorkspaceConfigStore() stores.WorkspaceConfigStore { - return &InMemoryWorkspaceConfigStore{ - workspaceConfigs: make(map[string]*models.WorkspaceConfig), - } -} - -func (s *InMemoryWorkspaceConfigStore) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { - return s.processFilters(filter) -} - -func (s *InMemoryWorkspaceConfigStore) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { - workspaceConfigs, err := s.processFilters(filter) - if err != nil { - return nil, err - } - if len(workspaceConfigs) == 0 { - return nil, stores.ErrWorkspaceConfigNotFound - } - - return workspaceConfigs[0], nil -} - -func (s *InMemoryWorkspaceConfigStore) Save(workspaceConfig *models.WorkspaceConfig) error { - s.workspaceConfigs[workspaceConfig.Name] = workspaceConfig - return nil -} - -func (s *InMemoryWorkspaceConfigStore) Delete(workspaceConfig *models.WorkspaceConfig) error { - delete(s.workspaceConfigs, workspaceConfig.Name) - return nil -} - -func (s *InMemoryWorkspaceConfigStore) processFilters(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { - var result []*models.WorkspaceConfig - filteredWorkspaceConfigs := make(map[string]*models.WorkspaceConfig) - for k, v := range s.workspaceConfigs { - filteredWorkspaceConfigs[k] = v - } - - if filter != nil { - if filter.Name != nil { - workspaceConfig, ok := s.workspaceConfigs[*filter.Name] - if ok { - return []*models.WorkspaceConfig{workspaceConfig}, nil - } else { - return []*models.WorkspaceConfig{}, fmt.Errorf("workspace config with name %s not found", *filter.Name) - } - } - if filter.Url != nil { - for _, workspaceConfig := range filteredWorkspaceConfigs { - if workspaceConfig.RepositoryUrl != *filter.Url { - delete(filteredWorkspaceConfigs, workspaceConfig.Name) - } - } - } - if filter.Default != nil { - for _, workspaceConfig := range filteredWorkspaceConfigs { - if workspaceConfig.IsDefault != *filter.Default { - delete(filteredWorkspaceConfigs, workspaceConfig.Name) - } - } - } - if filter.GitProviderConfigId != nil { - for _, workspaceConfig := range filteredWorkspaceConfigs { - if workspaceConfig.GitProviderConfigId != nil && *workspaceConfig.GitProviderConfigId != *filter.GitProviderConfigId { - delete(filteredWorkspaceConfigs, workspaceConfig.Name) - } - } - } - } - - for _, workspaceConfig := range filteredWorkspaceConfigs { - result = append(result, workspaceConfig) - } - - return result, nil -} diff --git a/internal/testing/server/workspacetemplate/store.go b/internal/testing/server/workspacetemplate/store.go new file mode 100644 index 0000000000..9381ed6dd8 --- /dev/null +++ b/internal/testing/server/workspacetemplate/store.go @@ -0,0 +1,95 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspacetemplate + +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type InMemoryWorkspaceTemplateStore struct { + workspaceTemplates map[string]*models.WorkspaceTemplate +} + +func NewInMemoryWorkspaceTemplateStore() stores.WorkspaceTemplateStore { + return &InMemoryWorkspaceTemplateStore{ + workspaceTemplates: make(map[string]*models.WorkspaceTemplate), + } +} + +func (s *InMemoryWorkspaceTemplateStore) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + return s.processFilters(filter) +} + +func (s *InMemoryWorkspaceTemplateStore) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { + workspaceTemplates, err := s.processFilters(filter) + if err != nil { + return nil, err + } + if len(workspaceTemplates) == 0 { + return nil, stores.ErrWorkspaceTemplateNotFound + } + + return workspaceTemplates[0], nil +} + +func (s *InMemoryWorkspaceTemplateStore) Save(workspaceTemplate *models.WorkspaceTemplate) error { + s.workspaceTemplates[workspaceTemplate.Name] = workspaceTemplate + return nil +} + +func (s *InMemoryWorkspaceTemplateStore) Delete(workspaceTemplate *models.WorkspaceTemplate) error { + delete(s.workspaceTemplates, workspaceTemplate.Name) + return nil +} + +func (s *InMemoryWorkspaceTemplateStore) processFilters(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + var result []*models.WorkspaceTemplate + filteredWorkspaceTemplates := make(map[string]*models.WorkspaceTemplate) + for k, v := range s.workspaceTemplates { + filteredWorkspaceTemplates[k] = v + } + + if filter != nil { + if filter.Name != nil { + workspaceTemplate, ok := s.workspaceTemplates[*filter.Name] + if ok { + return []*models.WorkspaceTemplate{workspaceTemplate}, nil + } else { + return []*models.WorkspaceTemplate{}, fmt.Errorf("workspace template with name %s not found", *filter.Name) + } + } + if filter.Url != nil { + for _, workspaceTemplate := range filteredWorkspaceTemplates { + if workspaceTemplate.RepositoryUrl != *filter.Url { + delete(filteredWorkspaceTemplates, workspaceTemplate.Name) + } + } + } + if filter.Default != nil { + for _, workspaceTemplate := range filteredWorkspaceTemplates { + if workspaceTemplate.IsDefault != *filter.Default { + delete(filteredWorkspaceTemplates, workspaceTemplate.Name) + } + } + } + if filter.GitProviderConfigId != nil { + for _, workspaceTemplate := range filteredWorkspaceTemplates { + if workspaceTemplate.GitProviderConfigId != nil && *workspaceTemplate.GitProviderConfigId != *filter.GitProviderConfigId { + delete(filteredWorkspaceTemplates, workspaceTemplate.Name) + } + } + } + } + + for _, workspaceTemplate := range filteredWorkspaceTemplates { + result = append(result, workspaceTemplate) + } + + return result, nil +} diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go index 4b7d278e8b..dc1ef66198 100644 --- a/internal/util/apiclient/conversion/workspace.go +++ b/internal/util/apiclient/conversion/workspace.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - wc_dto "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + wt_dto "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" ) func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { @@ -154,22 +154,22 @@ func ToGitStatusDTO(gitStatus *models.GitStatus) *apiclient.GitStatus { } } -func ToWorkspaceConfig(createWorkspaceConfigDto wc_dto.CreateWorkspaceConfigDTO) *models.WorkspaceConfig { - result := &models.WorkspaceConfig{ - Name: createWorkspaceConfigDto.Name, - BuildConfig: createWorkspaceConfigDto.BuildConfig, - EnvVars: createWorkspaceConfigDto.EnvVars, - GitProviderConfigId: createWorkspaceConfigDto.GitProviderConfigId, +func ToWorkspaceTemplate(createWorkspaceTemplateDto wt_dto.CreateWorkspaceTemplateDTO) *models.WorkspaceTemplate { + result := &models.WorkspaceTemplate{ + Name: createWorkspaceTemplateDto.Name, + BuildConfig: createWorkspaceTemplateDto.BuildConfig, + EnvVars: createWorkspaceTemplateDto.EnvVars, + GitProviderConfigId: createWorkspaceTemplateDto.GitProviderConfigId, } - result.RepositoryUrl = createWorkspaceConfigDto.RepositoryUrl + result.RepositoryUrl = createWorkspaceTemplateDto.RepositoryUrl - if createWorkspaceConfigDto.Image != nil { - result.Image = *createWorkspaceConfigDto.Image + if createWorkspaceTemplateDto.Image != nil { + result.Image = *createWorkspaceTemplateDto.Image } - if createWorkspaceConfigDto.User != nil { - result.User = *createWorkspaceConfigDto.User + if createWorkspaceTemplateDto.User != nil { + result.User = *createWorkspaceTemplateDto.User } return result diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index b0cac8bb34..1963852b10 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -204,7 +204,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { server := server.GetInstance(nil) // Fail if prebuild does not exist - _, err = server.WorkspaceConfigService.FindPrebuild(nil, &stores.PrebuildFilter{ + _, err = server.WorkspaceTemplateService.FindPrebuild(nil, &stores.PrebuildFilter{ Id: &prebuildId, }) if err != nil { diff --git a/pkg/api/controllers/workspaceconfig/workspace_config.go b/pkg/api/controllers/workspaceconfig/workspace_config.go deleted file mode 100644 index 04a6626b64..0000000000 --- a/pkg/api/controllers/workspaceconfig/workspace_config.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaceconfig - -import ( - "errors" - "fmt" - "net/http" - "net/url" - "strconv" - - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/gin-gonic/gin" - log "github.com/sirupsen/logrus" -) - -// GetWorkspaceConfig godoc -// -// @Tags workspace-config -// @Summary Get workspace config data -// @Description Get workspace config data -// @Accept json -// @Param configName path string true "Config name" -// @Success 200 {object} WorkspaceConfig -// @Router /workspace-config/{configName} [get] -// -// @id GetWorkspaceConfig -func GetWorkspaceConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - - server := server.GetInstance(nil) - - workspaceConfig, err := server.WorkspaceConfigService.Find(&stores.WorkspaceConfigFilter{ - Name: &configName, - }) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace config: %s", err.Error())) - return - } - - ctx.JSON(200, workspaceConfig) -} - -// GetDefaultWorkspaceConfig godoc -// -// @Tags workspace-config -// @Summary Get workspace configs by git url -// @Description Get workspace configs by git url -// @Produce json -// @Param gitUrl path string true "Git URL" -// @Success 200 {object} WorkspaceConfig -// @Router /workspace-config/default/{gitUrl} [get] -// -// @id GetDefaultWorkspaceConfig -func GetDefaultWorkspaceConfig(ctx *gin.Context) { - gitUrl := ctx.Param("gitUrl") - - decodedURLParam, err := url.QueryUnescape(gitUrl) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode query param: %s", err.Error())) - return - } - - server := server.GetInstance(nil) - - workspaceConfigs, err := server.WorkspaceConfigService.Find(&stores.WorkspaceConfigFilter{ - Url: &decodedURLParam, - Default: util.Pointer(true), - }) - if err != nil { - statusCode := http.StatusInternalServerError - if stores.IsWorkspaceConfigNotFound(err) { - statusCode = http.StatusNotFound - ctx.AbortWithStatus(statusCode) - log.Debugf("Workspace config not added for git url: %s", decodedURLParam) - return - } - ctx.AbortWithError(statusCode, fmt.Errorf("failed to find workspace config by git url: %s", err.Error())) - return - } - - ctx.JSON(200, workspaceConfigs) -} - -// ListWorkspaceConfigs godoc -// -// @Tags workspace-config -// @Summary List workspace configs -// @Description List workspace configs -// @Produce json -// @Success 200 {array} WorkspaceConfig -// @Router /workspace-config [get] -// -// @id ListWorkspaceConfigs -func ListWorkspaceConfigs(ctx *gin.Context) { - server := server.GetInstance(nil) - - workspaceConfigs, err := server.WorkspaceConfigService.List(nil) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspace configs: %s", err.Error())) - return - } - - ctx.JSON(200, workspaceConfigs) -} - -// SetWorkspaceConfig godoc -// -// @Tags workspace-config -// @Summary Set workspace config data -// @Description Set workspace config data -// @Accept json -// @Param workspaceConfig body CreateWorkspaceConfigDTO true "Workspace config" -// @Success 201 -// @Router /workspace-config [put] -// -// @id SetWorkspaceConfig -func SetWorkspaceConfig(ctx *gin.Context) { - var req dto.CreateWorkspaceConfigDTO - err := ctx.BindJSON(&req) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) - return - } - - s := server.GetInstance(nil) - - workspaceConfig := conversion.ToWorkspaceConfig(req) - - err = s.WorkspaceConfigService.Save(workspaceConfig) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save workspace config: %s", err.Error())) - return - } - - ctx.Status(201) -} - -// SetDefaultWorkspaceConfig godoc -// -// @Tags workspace-config -// @Summary Set workspace config to default -// @Description Set workspace config to default -// @Param configName path string true "Config name" -// @Success 200 -// @Router /workspace-config/{configName}/set-default [patch] -// -// @id SetDefaultWorkspaceConfig -func SetDefaultWorkspaceConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - - server := server.GetInstance(nil) - - err := server.WorkspaceConfigService.SetDefault(configName) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set workspace config to default: %s", err.Error())) - return - } - - ctx.Status(200) -} - -// DeleteWorkspaceConfig godoc -// -// @Tags workspace-config -// @Summary Delete workspace config data -// @Description Delete workspace config data -// @Param configName path string true "Config name" -// @Param force query bool false "Force" -// @Success 204 -// @Router /workspace-config/{configName} [delete] -// -// @id DeleteWorkspaceConfig -func DeleteWorkspaceConfig(ctx *gin.Context) { - configName := ctx.Param("configName") - forceQuery := ctx.Query("force") - - var err error - var force bool - - if forceQuery != "" { - force, err = strconv.ParseBool(forceQuery) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) - return - } - } - - server := server.GetInstance(nil) - - workspaceConfig, err := server.WorkspaceConfigService.Find(&stores.WorkspaceConfigFilter{ - Name: &configName, - }) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find workspace config: %s", err.Error())) - return - } - - errs := server.WorkspaceConfigService.Delete(workspaceConfig.Name, force) - if len(errs) > 0 { - if stores.IsWorkspaceConfigNotFound(errs[0]) { - ctx.AbortWithError(http.StatusNotFound, errors.New("workspace config not found")) - return - } - for _, err := range errs { - _ = ctx.Error(err) - } - ctx.AbortWithStatus(http.StatusInternalServerError) - return - } - - ctx.Status(204) -} diff --git a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go similarity index 59% rename from pkg/api/controllers/workspaceconfig/prebuild/prebuild.go rename to pkg/api/controllers/workspacetemplate/prebuild/prebuild.go index c3ad48944d..c55c62ed17 100644 --- a/pkg/api/controllers/workspaceconfig/prebuild/prebuild.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go @@ -10,7 +10,7 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -21,19 +21,19 @@ import ( // @Summary Get prebuild // @Description Get prebuild // @Accept json -// @Param configName path string true "Workspace config name" -// @Param prebuildId path string true "Prebuild ID" -// @Success 200 {object} PrebuildDTO -// @Router /workspace-config/{configName}/prebuild/{prebuildId} [get] +// @Param templateName path string true "Workspace template name" +// @Param prebuildId path string true "Prebuild ID" +// @Success 200 {object} PrebuildDTO +// @Router /workspace-template/{templateName}/prebuild/{prebuildId} [get] // // @id GetPrebuild func GetPrebuild(ctx *gin.Context) { - configName := ctx.Param("configName") + templateName := ctx.Param("templateName") prebuildId := ctx.Param("prebuildId") server := server.GetInstance(nil) - res, err := server.WorkspaceConfigService.FindPrebuild(&stores.WorkspaceConfigFilter{ - Name: &configName, + res, err := server.WorkspaceTemplateService.FindPrebuild(&stores.WorkspaceTemplateFilter{ + Name: &templateName, }, &stores.PrebuildFilter{ Id: &prebuildId, }) @@ -55,14 +55,14 @@ func GetPrebuild(ctx *gin.Context) { // @Summary Set prebuild // @Description Set prebuild // @Accept json -// @Param configName path string true "Config name" -// @Param prebuild body CreatePrebuildDTO true "Prebuild" -// @Success 201 {string} prebuildId -// @Router /workspace-config/{configName}/prebuild [put] +// @Param templateName path string true "Template name" +// @Param prebuild body CreatePrebuildDTO true "Prebuild" +// @Success 201 {string} prebuildId +// @Router /workspace-template/{templateName}/prebuild [put] // // @id SetPrebuild func SetPrebuild(ctx *gin.Context) { - configName := ctx.Param("configName") + templateName := ctx.Param("templateName") var dto dto.CreatePrebuildDTO err := ctx.BindJSON(&dto) @@ -72,7 +72,7 @@ func SetPrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - prebuild, err := server.WorkspaceConfigService.SetPrebuild(configName, dto) + prebuild, err := server.WorkspaceTemplateService.SetPrebuild(templateName, dto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set prebuild: %s", err.Error())) return @@ -88,12 +88,12 @@ func SetPrebuild(ctx *gin.Context) { // @Description List prebuilds // @Accept json // @Success 200 {array} PrebuildDTO -// @Router /workspace-config/prebuild [get] +// @Router /workspace-template/prebuild [get] // // @id ListPrebuilds func ListPrebuilds(ctx *gin.Context) { server := server.GetInstance(nil) - res, err := server.WorkspaceConfigService.ListPrebuilds(nil, nil) + res, err := server.WorkspaceTemplateService.ListPrebuilds(nil, nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get prebuilds: %s", err.Error())) return @@ -102,30 +102,30 @@ func ListPrebuilds(ctx *gin.Context) { ctx.JSON(200, res) } -// ListPrebuildsForWorkspaceConfig godoc +// ListPrebuildsForWorkspaceTemplate godoc // @Tags prebuild -// @Summary List prebuilds for workspace config -// @Description List prebuilds for workspace config +// @Summary List prebuilds for workspace template +// @Description List prebuilds for workspace template // @Accept json -// @Param configName path string true "Config name" -// @Success 200 {array} PrebuildDTO -// @Router /workspace-config/{configName}/prebuild [get] +// @Param templateName path string true "Template name" +// @Success 200 {array} PrebuildDTO +// @Router /workspace-template/{templateName}/prebuild [get] // -// @id ListPrebuildsForWorkspaceConfig -func ListPrebuildsForWorkspaceConfig(ctx *gin.Context) { - configName := ctx.Param("configName") +// @id ListPrebuildsForWorkspaceTemplate +func ListPrebuildsForWorkspaceTemplate(ctx *gin.Context) { + templateName := ctx.Param("templateName") - var workspaceConfigFilter *stores.WorkspaceConfigFilter + var workspaceTemplateFilter *stores.WorkspaceTemplateFilter - if configName != "" { - workspaceConfigFilter = &stores.WorkspaceConfigFilter{ - Name: &configName, + if templateName != "" { + workspaceTemplateFilter = &stores.WorkspaceTemplateFilter{ + Name: &templateName, } } server := server.GetInstance(nil) - res, err := server.WorkspaceConfigService.ListPrebuilds(workspaceConfigFilter, nil) + res, err := server.WorkspaceTemplateService.ListPrebuilds(workspaceTemplateFilter, nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get prebuilds: %s", err.Error())) return @@ -140,15 +140,15 @@ func ListPrebuildsForWorkspaceConfig(ctx *gin.Context) { // @Summary Delete prebuild // @Description Delete prebuild // @Accept json -// @Param configName path string true "Workspace config name" -// @Param prebuildId path string true "Prebuild ID" -// @Param force query bool false "Force" +// @Param templateName path string true "Workspace template name" +// @Param prebuildId path string true "Prebuild ID" +// @Param force query bool false "Force" // @Success 204 -// @Router /workspace-config/{configName}/prebuild/{prebuildId} [delete] +// @Router /workspace-template/{templateName}/prebuild/{prebuildId} [delete] // // @id DeletePrebuild func DeletePrebuild(ctx *gin.Context) { - configName := ctx.Param("configName") + templateName := ctx.Param("templateName") prebuildId := ctx.Param("prebuildId") forceQuery := ctx.Query("force") @@ -164,7 +164,7 @@ func DeletePrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - errs := server.WorkspaceConfigService.DeletePrebuild(configName, prebuildId, force) + errs := server.WorkspaceTemplateService.DeletePrebuild(templateName, prebuildId, force) if len(errs) > 0 { if stores.IsPrebuildNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) diff --git a/pkg/api/controllers/workspaceconfig/prebuild/process_git_event.go b/pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go similarity index 89% rename from pkg/api/controllers/workspaceconfig/prebuild/process_git_event.go rename to pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go index b8259f8649..86d27c7159 100644 --- a/pkg/api/controllers/workspaceconfig/prebuild/process_git_event.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go @@ -19,7 +19,7 @@ import ( // @Description ProcessGitEvent // @Param body body interface{} true "Webhook event" // @Success 200 -// @Router /workspace-config/prebuild/process-git-event [post] +// @Router /workspace-template/prebuild/process-git-event [post] // // @id ProcessGitEvent func ProcessGitEvent(ctx *gin.Context) { @@ -41,7 +41,7 @@ func ProcessGitEvent(ctx *gin.Context) { return } - err = server.WorkspaceConfigService.ProcessGitEvent(*gitEventData) + err = server.WorkspaceTemplateService.ProcessGitEvent(*gitEventData) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to process git event: %s", err.Error())) return diff --git a/pkg/api/controllers/workspacetemplate/workspace_template.go b/pkg/api/controllers/workspacetemplate/workspace_template.go new file mode 100644 index 0000000000..d5a7577eb1 --- /dev/null +++ b/pkg/api/controllers/workspacetemplate/workspace_template.go @@ -0,0 +1,218 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspacetemplate + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "strconv" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" +) + +// GetWorkspaceTemplate godoc +// +// @Tags workspace-template +// @Summary Get workspace template data +// @Description Get workspace template data +// @Accept json +// @Param templateName path string true "Template name" +// @Success 200 {object} WorkspaceTemplate +// @Router /workspace-template/{templateName} [get] +// +// @id GetWorkspaceTemplate +func GetWorkspaceTemplate(ctx *gin.Context) { + templateName := ctx.Param("templateName") + + server := server.GetInstance(nil) + + workspaceTemplate, err := server.WorkspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + Name: &templateName, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace template: %s", err.Error())) + return + } + + ctx.JSON(200, workspaceTemplate) +} + +// GetDefaultWorkspaceTemplate godoc +// +// @Tags workspace-template +// @Summary Get workspace templates by git url +// @Description Get workspace templates by git url +// @Produce json +// @Param gitUrl path string true "Git URL" +// @Success 200 {object} WorkspaceTemplate +// @Router /workspace-template/default/{gitUrl} [get] +// +// @id GetDefaultWorkspaceTemplate +func GetDefaultWorkspaceTemplate(ctx *gin.Context) { + gitUrl := ctx.Param("gitUrl") + + decodedURLParam, err := url.QueryUnescape(gitUrl) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode query param: %s", err.Error())) + return + } + + server := server.GetInstance(nil) + + workspaceTemplates, err := server.WorkspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + Url: &decodedURLParam, + Default: util.Pointer(true), + }) + if err != nil { + statusCode := http.StatusInternalServerError + if stores.IsWorkspaceTemplateNotFound(err) { + statusCode = http.StatusNotFound + ctx.AbortWithStatus(statusCode) + log.Debugf("Workspace template not added for git url: %s", decodedURLParam) + return + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to find workspace template by git url: %s", err.Error())) + return + } + + ctx.JSON(200, workspaceTemplates) +} + +// ListWorkspaceTemplates godoc +// +// @Tags workspace-template +// @Summary List workspace templates +// @Description List workspace templates +// @Produce json +// @Success 200 {array} WorkspaceTemplate +// @Router /workspace-template [get] +// +// @id ListWorkspaceTemplates +func ListWorkspaceTemplates(ctx *gin.Context) { + server := server.GetInstance(nil) + + workspaceTemplates, err := server.WorkspaceTemplateService.List(nil) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspace templates: %s", err.Error())) + return + } + + ctx.JSON(200, workspaceTemplates) +} + +// SetWorkspaceTemplate godoc +// +// @Tags workspace-template +// @Summary Set workspace template data +// @Description Set workspace template data +// @Accept json +// @Param workspaceTemplate body CreateWorkspaceTemplateDTO true "Workspace template" +// @Success 201 +// @Router /workspace-template [put] +// +// @id SetWorkspaceTemplate +func SetWorkspaceTemplate(ctx *gin.Context) { + var req dto.CreateWorkspaceTemplateDTO + err := ctx.BindJSON(&req) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) + return + } + + s := server.GetInstance(nil) + + workspaceTemplate := conversion.ToWorkspaceTemplate(req) + + err = s.WorkspaceTemplateService.Save(workspaceTemplate) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save workspace template: %s", err.Error())) + return + } + + ctx.Status(201) +} + +// SetDefaultWorkspaceTemplate godoc +// +// @Tags workspace-template +// @Summary Set workspace template to default +// @Description Set workspace template to default +// @Param templateName path string true "Template name" +// @Success 200 +// @Router /workspace-template/{templateName}/set-default [patch] +// +// @id SetDefaultWorkspaceTemplate +func SetDefaultWorkspaceTemplate(ctx *gin.Context) { + templateName := ctx.Param("templateName") + + server := server.GetInstance(nil) + + err := server.WorkspaceTemplateService.SetDefault(templateName) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set workspace template to default: %s", err.Error())) + return + } + + ctx.Status(200) +} + +// DeleteWorkspaceTemplate godoc +// +// @Tags workspace-template +// @Summary Delete workspace template data +// @Description Delete workspace template data +// @Param templateName path string true "Template name" +// @Param force query bool false "Force" +// @Success 204 +// @Router /workspace-template/{templateName} [delete] +// +// @id DeleteWorkspaceTemplate +func DeleteWorkspaceTemplate(ctx *gin.Context) { + templateName := ctx.Param("templateName") + forceQuery := ctx.Query("force") + + var err error + var force bool + + if forceQuery != "" { + force, err = strconv.ParseBool(forceQuery) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for force flag")) + return + } + } + + server := server.GetInstance(nil) + + workspaceTemplate, err := server.WorkspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + Name: &templateName, + }) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find workspace template: %s", err.Error())) + return + } + + errs := server.WorkspaceTemplateService.Delete(workspaceTemplate.Name, force) + if len(errs) > 0 { + if stores.IsWorkspaceTemplateNotFound(errs[0]) { + ctx.AbortWithError(http.StatusNotFound, errors.New("workspace template not found")) + return + } + for _, err := range errs { + _ = ctx.Error(err) + } + ctx.AbortWithStatus(http.StatusInternalServerError) + return + } + + ctx.Status(204) +} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index a351bbe210..4cced0b453 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1557,47 +1557,47 @@ const docTemplate = `{ } } }, - "/workspace-config": { + "/workspace-template": { "get": { - "description": "List workspace configs", + "description": "List workspace templates", "produces": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "List workspace configs", - "operationId": "ListWorkspaceConfigs", + "summary": "List workspace templates", + "operationId": "ListWorkspaceTemplates", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/WorkspaceConfig" + "$ref": "#/definitions/WorkspaceTemplate" } } } } }, "put": { - "description": "Set workspace config data", + "description": "Set workspace template data", "consumes": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Set workspace config data", - "operationId": "SetWorkspaceConfig", + "summary": "Set workspace template data", + "operationId": "SetWorkspaceTemplate", "parameters": [ { - "description": "Workspace config", - "name": "workspaceConfig", + "description": "Workspace template", + "name": "workspaceTemplate", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateWorkspaceConfigDTO" + "$ref": "#/definitions/CreateWorkspaceTemplateDTO" } } ], @@ -1608,17 +1608,17 @@ const docTemplate = `{ } } }, - "/workspace-config/default/{gitUrl}": { + "/workspace-template/default/{gitUrl}": { "get": { - "description": "Get workspace configs by git url", + "description": "Get workspace templates by git url", "produces": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Get workspace configs by git url", - "operationId": "GetDefaultWorkspaceConfig", + "summary": "Get workspace templates by git url", + "operationId": "GetDefaultWorkspaceTemplate", "parameters": [ { "type": "string", @@ -1632,13 +1632,13 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceConfig" + "$ref": "#/definitions/WorkspaceTemplate" } } } } }, - "/workspace-config/prebuild": { + "/workspace-template/prebuild": { "get": { "description": "List prebuilds", "consumes": [ @@ -1662,7 +1662,7 @@ const docTemplate = `{ } } }, - "/workspace-config/prebuild/process-git-event": { + "/workspace-template/prebuild/process-git-event": { "post": { "description": "ProcessGitEvent", "tags": [ @@ -1688,22 +1688,22 @@ const docTemplate = `{ } } }, - "/workspace-config/{configName}": { + "/workspace-template/{templateName}": { "get": { - "description": "Get workspace config data", + "description": "Get workspace template data", "consumes": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Get workspace config data", - "operationId": "GetWorkspaceConfig", + "summary": "Get workspace template data", + "operationId": "GetWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true } @@ -1712,23 +1712,23 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceConfig" + "$ref": "#/definitions/WorkspaceTemplate" } } } }, "delete": { - "description": "Delete workspace config data", + "description": "Delete workspace template data", "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Delete workspace config data", - "operationId": "DeleteWorkspaceConfig", + "summary": "Delete workspace template data", + "operationId": "DeleteWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true }, @@ -1746,22 +1746,22 @@ const docTemplate = `{ } } }, - "/workspace-config/{configName}/prebuild": { + "/workspace-template/{templateName}/prebuild": { "get": { - "description": "List prebuilds for workspace config", + "description": "List prebuilds for workspace template", "consumes": [ "application/json" ], "tags": [ "prebuild" ], - "summary": "List prebuilds for workspace config", - "operationId": "ListPrebuildsForWorkspaceConfig", + "summary": "List prebuilds for workspace template", + "operationId": "ListPrebuildsForWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true } @@ -1791,8 +1791,8 @@ const docTemplate = `{ "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true }, @@ -1816,7 +1816,7 @@ const docTemplate = `{ } } }, - "/workspace-config/{configName}/prebuild/{prebuildId}": { + "/workspace-template/{templateName}/prebuild/{prebuildId}": { "get": { "description": "Get prebuild", "consumes": [ @@ -1830,8 +1830,8 @@ const docTemplate = `{ "parameters": [ { "type": "string", - "description": "Workspace config name", - "name": "configName", + "description": "Workspace template name", + "name": "templateName", "in": "path", "required": true }, @@ -1865,8 +1865,8 @@ const docTemplate = `{ "parameters": [ { "type": "string", - "description": "Workspace config name", - "name": "configName", + "description": "Workspace template name", + "name": "templateName", "in": "path", "required": true }, @@ -1891,19 +1891,19 @@ const docTemplate = `{ } } }, - "/workspace-config/{configName}/set-default": { + "/workspace-template/{templateName}/set-default": { "patch": { - "description": "Set workspace config to default", + "description": "Set workspace template to default", "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Set workspace config to default", - "operationId": "SetDefaultWorkspaceConfig", + "summary": "Set workspace template to default", + "operationId": "SetDefaultWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true } @@ -3637,7 +3637,7 @@ const docTemplate = `{ "required": [ "branch", "envVars", - "workspaceConfigName" + "workspaceTemplateName" ], "properties": { "branch": { @@ -3652,7 +3652,7 @@ const docTemplate = `{ "prebuildId": { "type": "string" }, - "workspaceConfigName": { + "workspaceTemplateName": { "type": "string" } } @@ -3713,12 +3713,14 @@ const docTemplate = `{ } } }, - "CreateWorkspaceConfigDTO": { + "CreateWorkspaceDTO": { "type": "object", "required": [ "envVars", + "id", "name", - "repositoryUrl" + "source", + "targetId" ], "properties": { "buildConfig": { @@ -3733,13 +3735,19 @@ const docTemplate = `{ "gitProviderConfigId": { "type": "string" }, + "id": { + "type": "string" + }, "image": { "type": "string" }, "name": { "type": "string" }, - "repositoryUrl": { + "source": { + "$ref": "#/definitions/CreateWorkspaceSourceDTO" + }, + "targetId": { "type": "string" }, "user": { @@ -3747,14 +3755,23 @@ const docTemplate = `{ } } }, - "CreateWorkspaceDTO": { + "CreateWorkspaceSourceDTO": { + "type": "object", + "required": [ + "repository" + ], + "properties": { + "repository": { + "$ref": "#/definitions/GitRepository" + } + } + }, + "CreateWorkspaceTemplateDTO": { "type": "object", "required": [ "envVars", - "id", "name", - "source", - "targetId" + "repositoryUrl" ], "properties": { "buildConfig": { @@ -3769,19 +3786,13 @@ const docTemplate = `{ "gitProviderConfigId": { "type": "string" }, - "id": { - "type": "string" - }, "image": { "type": "string" }, "name": { "type": "string" }, - "source": { - "$ref": "#/definitions/CreateWorkspaceSourceDTO" - }, - "targetId": { + "repositoryUrl": { "type": "string" }, "user": { @@ -3789,17 +3800,6 @@ const docTemplate = `{ } } }, - "CreateWorkspaceSourceDTO": { - "type": "object", - "required": [ - "repository" - ], - "properties": { - "repository": { - "$ref": "#/definitions/GitRepository" - } - } - }, "DevcontainerConfig": { "type": "object", "required": [ @@ -4625,7 +4625,7 @@ const docTemplate = `{ "branch", "id", "retention", - "workspaceConfigName" + "workspaceTemplateName" ], "properties": { "branch": { @@ -4646,7 +4646,7 @@ const docTemplate = `{ "type": "string" } }, - "workspaceConfigName": { + "workspaceTemplateName": { "type": "string" } } @@ -5263,52 +5263,6 @@ const docTemplate = `{ } } }, - "WorkspaceConfig": { - "type": "object", - "required": [ - "default", - "envVars", - "image", - "name", - "repositoryUrl", - "user" - ], - "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "default": { - "type": "boolean" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { - "type": "string" - }, - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "prebuilds": { - "type": "array", - "items": { - "$ref": "#/definitions/PrebuildConfig" - } - }, - "repositoryUrl": { - "type": "string" - }, - "user": { - "type": "string" - } - } - }, "WorkspaceDTO": { "type": "object", "required": [ @@ -5426,6 +5380,52 @@ const docTemplate = `{ } } }, + "WorkspaceTemplate": { + "type": "object", + "required": [ + "default", + "envVars", + "image", + "name", + "repositoryUrl", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "default": { + "type": "boolean" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prebuilds": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildConfig" + } + }, + "repositoryUrl": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, "models.ApiKeyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 3a3ee6b208..4f6ba77bde 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1554,47 +1554,47 @@ } } }, - "/workspace-config": { + "/workspace-template": { "get": { - "description": "List workspace configs", + "description": "List workspace templates", "produces": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "List workspace configs", - "operationId": "ListWorkspaceConfigs", + "summary": "List workspace templates", + "operationId": "ListWorkspaceTemplates", "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/WorkspaceConfig" + "$ref": "#/definitions/WorkspaceTemplate" } } } } }, "put": { - "description": "Set workspace config data", + "description": "Set workspace template data", "consumes": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Set workspace config data", - "operationId": "SetWorkspaceConfig", + "summary": "Set workspace template data", + "operationId": "SetWorkspaceTemplate", "parameters": [ { - "description": "Workspace config", - "name": "workspaceConfig", + "description": "Workspace template", + "name": "workspaceTemplate", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/CreateWorkspaceConfigDTO" + "$ref": "#/definitions/CreateWorkspaceTemplateDTO" } } ], @@ -1605,17 +1605,17 @@ } } }, - "/workspace-config/default/{gitUrl}": { + "/workspace-template/default/{gitUrl}": { "get": { - "description": "Get workspace configs by git url", + "description": "Get workspace templates by git url", "produces": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Get workspace configs by git url", - "operationId": "GetDefaultWorkspaceConfig", + "summary": "Get workspace templates by git url", + "operationId": "GetDefaultWorkspaceTemplate", "parameters": [ { "type": "string", @@ -1629,13 +1629,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceConfig" + "$ref": "#/definitions/WorkspaceTemplate" } } } } }, - "/workspace-config/prebuild": { + "/workspace-template/prebuild": { "get": { "description": "List prebuilds", "consumes": [ @@ -1659,7 +1659,7 @@ } } }, - "/workspace-config/prebuild/process-git-event": { + "/workspace-template/prebuild/process-git-event": { "post": { "description": "ProcessGitEvent", "tags": [ @@ -1685,22 +1685,22 @@ } } }, - "/workspace-config/{configName}": { + "/workspace-template/{templateName}": { "get": { - "description": "Get workspace config data", + "description": "Get workspace template data", "consumes": [ "application/json" ], "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Get workspace config data", - "operationId": "GetWorkspaceConfig", + "summary": "Get workspace template data", + "operationId": "GetWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true } @@ -1709,23 +1709,23 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/WorkspaceConfig" + "$ref": "#/definitions/WorkspaceTemplate" } } } }, "delete": { - "description": "Delete workspace config data", + "description": "Delete workspace template data", "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Delete workspace config data", - "operationId": "DeleteWorkspaceConfig", + "summary": "Delete workspace template data", + "operationId": "DeleteWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true }, @@ -1743,22 +1743,22 @@ } } }, - "/workspace-config/{configName}/prebuild": { + "/workspace-template/{templateName}/prebuild": { "get": { - "description": "List prebuilds for workspace config", + "description": "List prebuilds for workspace template", "consumes": [ "application/json" ], "tags": [ "prebuild" ], - "summary": "List prebuilds for workspace config", - "operationId": "ListPrebuildsForWorkspaceConfig", + "summary": "List prebuilds for workspace template", + "operationId": "ListPrebuildsForWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true } @@ -1788,8 +1788,8 @@ "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true }, @@ -1813,7 +1813,7 @@ } } }, - "/workspace-config/{configName}/prebuild/{prebuildId}": { + "/workspace-template/{templateName}/prebuild/{prebuildId}": { "get": { "description": "Get prebuild", "consumes": [ @@ -1827,8 +1827,8 @@ "parameters": [ { "type": "string", - "description": "Workspace config name", - "name": "configName", + "description": "Workspace template name", + "name": "templateName", "in": "path", "required": true }, @@ -1862,8 +1862,8 @@ "parameters": [ { "type": "string", - "description": "Workspace config name", - "name": "configName", + "description": "Workspace template name", + "name": "templateName", "in": "path", "required": true }, @@ -1888,19 +1888,19 @@ } } }, - "/workspace-config/{configName}/set-default": { + "/workspace-template/{templateName}/set-default": { "patch": { - "description": "Set workspace config to default", + "description": "Set workspace template to default", "tags": [ - "workspace-config" + "workspace-template" ], - "summary": "Set workspace config to default", - "operationId": "SetDefaultWorkspaceConfig", + "summary": "Set workspace template to default", + "operationId": "SetDefaultWorkspaceTemplate", "parameters": [ { "type": "string", - "description": "Config name", - "name": "configName", + "description": "Template name", + "name": "templateName", "in": "path", "required": true } @@ -3634,7 +3634,7 @@ "required": [ "branch", "envVars", - "workspaceConfigName" + "workspaceTemplateName" ], "properties": { "branch": { @@ -3649,7 +3649,7 @@ "prebuildId": { "type": "string" }, - "workspaceConfigName": { + "workspaceTemplateName": { "type": "string" } } @@ -3710,12 +3710,14 @@ } } }, - "CreateWorkspaceConfigDTO": { + "CreateWorkspaceDTO": { "type": "object", "required": [ "envVars", + "id", "name", - "repositoryUrl" + "source", + "targetId" ], "properties": { "buildConfig": { @@ -3730,13 +3732,19 @@ "gitProviderConfigId": { "type": "string" }, + "id": { + "type": "string" + }, "image": { "type": "string" }, "name": { "type": "string" }, - "repositoryUrl": { + "source": { + "$ref": "#/definitions/CreateWorkspaceSourceDTO" + }, + "targetId": { "type": "string" }, "user": { @@ -3744,14 +3752,23 @@ } } }, - "CreateWorkspaceDTO": { + "CreateWorkspaceSourceDTO": { + "type": "object", + "required": [ + "repository" + ], + "properties": { + "repository": { + "$ref": "#/definitions/GitRepository" + } + } + }, + "CreateWorkspaceTemplateDTO": { "type": "object", "required": [ "envVars", - "id", "name", - "source", - "targetId" + "repositoryUrl" ], "properties": { "buildConfig": { @@ -3766,19 +3783,13 @@ "gitProviderConfigId": { "type": "string" }, - "id": { - "type": "string" - }, "image": { "type": "string" }, "name": { "type": "string" }, - "source": { - "$ref": "#/definitions/CreateWorkspaceSourceDTO" - }, - "targetId": { + "repositoryUrl": { "type": "string" }, "user": { @@ -3786,17 +3797,6 @@ } } }, - "CreateWorkspaceSourceDTO": { - "type": "object", - "required": [ - "repository" - ], - "properties": { - "repository": { - "$ref": "#/definitions/GitRepository" - } - } - }, "DevcontainerConfig": { "type": "object", "required": [ @@ -4622,7 +4622,7 @@ "branch", "id", "retention", - "workspaceConfigName" + "workspaceTemplateName" ], "properties": { "branch": { @@ -4643,7 +4643,7 @@ "type": "string" } }, - "workspaceConfigName": { + "workspaceTemplateName": { "type": "string" } } @@ -5260,52 +5260,6 @@ } } }, - "WorkspaceConfig": { - "type": "object", - "required": [ - "default", - "envVars", - "image", - "name", - "repositoryUrl", - "user" - ], - "properties": { - "buildConfig": { - "$ref": "#/definitions/BuildConfig" - }, - "default": { - "type": "boolean" - }, - "envVars": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "gitProviderConfigId": { - "type": "string" - }, - "image": { - "type": "string" - }, - "name": { - "type": "string" - }, - "prebuilds": { - "type": "array", - "items": { - "$ref": "#/definitions/PrebuildConfig" - } - }, - "repositoryUrl": { - "type": "string" - }, - "user": { - "type": "string" - } - } - }, "WorkspaceDTO": { "type": "object", "required": [ @@ -5423,6 +5377,52 @@ } } }, + "WorkspaceTemplate": { + "type": "object", + "required": [ + "default", + "envVars", + "image", + "name", + "repositoryUrl", + "user" + ], + "properties": { + "buildConfig": { + "$ref": "#/definitions/BuildConfig" + }, + "default": { + "type": "boolean" + }, + "envVars": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "gitProviderConfigId": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prebuilds": { + "type": "array", + "items": { + "$ref": "#/definitions/PrebuildConfig" + } + }, + "repositoryUrl": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, "models.ApiKeyType": { "type": "string", "enum": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 817517a2ca..a6e2d213bd 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -172,12 +172,12 @@ definitions: type: object prebuildId: type: string - workspaceConfigName: + workspaceTemplateName: type: string required: - branch - envVars - - workspaceConfigName + - workspaceTemplateName type: object CreatePrebuildDTO: properties: @@ -216,7 +216,7 @@ definitions: - name - targetConfigName type: object - CreateWorkspaceConfigDTO: + CreateWorkspaceDTO: properties: buildConfig: $ref: '#/definitions/BuildConfig' @@ -226,20 +226,33 @@ definitions: type: object gitProviderConfigId: type: string + id: + type: string image: type: string name: type: string - repositoryUrl: + source: + $ref: '#/definitions/CreateWorkspaceSourceDTO' + targetId: type: string user: type: string required: - envVars + - id - name - - repositoryUrl + - source + - targetId type: object - CreateWorkspaceDTO: + CreateWorkspaceSourceDTO: + properties: + repository: + $ref: '#/definitions/GitRepository' + required: + - repository + type: object + CreateWorkspaceTemplateDTO: properties: buildConfig: $ref: '#/definitions/BuildConfig' @@ -249,31 +262,18 @@ definitions: type: object gitProviderConfigId: type: string - id: - type: string image: type: string name: type: string - source: - $ref: '#/definitions/CreateWorkspaceSourceDTO' - targetId: + repositoryUrl: type: string user: type: string required: - envVars - - id - name - - source - - targetId - type: object - CreateWorkspaceSourceDTO: - properties: - repository: - $ref: '#/definitions/GitRepository' - required: - - repository + - repositoryUrl type: object DevcontainerConfig: properties: @@ -850,13 +850,13 @@ definitions: items: type: string type: array - workspaceConfigName: + workspaceTemplateName: type: string required: - branch - id - retention - - workspaceConfigName + - workspaceTemplateName type: object Provider: properties: @@ -1288,38 +1288,6 @@ definitions: - targetId - user type: object - WorkspaceConfig: - properties: - buildConfig: - $ref: '#/definitions/BuildConfig' - default: - type: boolean - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - prebuilds: - items: - $ref: '#/definitions/PrebuildConfig' - type: array - repositoryUrl: - type: string - user: - type: string - required: - - default - - envVars - - image - - name - - repositoryUrl - - user - type: object WorkspaceDTO: properties: buildConfig: @@ -1401,6 +1369,38 @@ definitions: - uptime - workspaceId type: object + WorkspaceTemplate: + properties: + buildConfig: + $ref: '#/definitions/BuildConfig' + default: + type: boolean + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + prebuilds: + items: + $ref: '#/definitions/PrebuildConfig' + type: array + repositoryUrl: + type: string + user: + type: string + required: + - default + - envVars + - image + - name + - repositoryUrl + - user + type: object models.ApiKeyType: enum: - client @@ -2536,10 +2536,10 @@ paths: summary: Create a workspace tags: - workspace - /workspace-config: + /workspace-template: get: - description: List workspace configs - operationId: ListWorkspaceConfigs + description: List workspace templates + operationId: ListWorkspaceTemplates produces: - application/json responses: @@ -2547,37 +2547,37 @@ paths: description: OK schema: items: - $ref: '#/definitions/WorkspaceConfig' + $ref: '#/definitions/WorkspaceTemplate' type: array - summary: List workspace configs + summary: List workspace templates tags: - - workspace-config + - workspace-template put: consumes: - application/json - description: Set workspace config data - operationId: SetWorkspaceConfig + description: Set workspace template data + operationId: SetWorkspaceTemplate parameters: - - description: Workspace config + - description: Workspace template in: body - name: workspaceConfig + name: workspaceTemplate required: true schema: - $ref: '#/definitions/CreateWorkspaceConfigDTO' + $ref: '#/definitions/CreateWorkspaceTemplateDTO' responses: "201": description: Created - summary: Set workspace config data + summary: Set workspace template data tags: - - workspace-config - /workspace-config/{configName}: + - workspace-template + /workspace-template/{templateName}: delete: - description: Delete workspace config data - operationId: DeleteWorkspaceConfig + description: Delete workspace template data + operationId: DeleteWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true type: string - description: Force @@ -2587,38 +2587,38 @@ paths: responses: "204": description: No Content - summary: Delete workspace config data + summary: Delete workspace template data tags: - - workspace-config + - workspace-template get: consumes: - application/json - description: Get workspace config data - operationId: GetWorkspaceConfig + description: Get workspace template data + operationId: GetWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true type: string responses: "200": description: OK schema: - $ref: '#/definitions/WorkspaceConfig' - summary: Get workspace config data + $ref: '#/definitions/WorkspaceTemplate' + summary: Get workspace template data tags: - - workspace-config - /workspace-config/{configName}/prebuild: + - workspace-template + /workspace-template/{templateName}/prebuild: get: consumes: - application/json - description: List prebuilds for workspace config - operationId: ListPrebuildsForWorkspaceConfig + description: List prebuilds for workspace template + operationId: ListPrebuildsForWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true type: string responses: @@ -2628,7 +2628,7 @@ paths: items: $ref: '#/definitions/PrebuildDTO' type: array - summary: List prebuilds for workspace config + summary: List prebuilds for workspace template tags: - prebuild put: @@ -2637,9 +2637,9 @@ paths: description: Set prebuild operationId: SetPrebuild parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true type: string - description: Prebuild @@ -2656,16 +2656,16 @@ paths: summary: Set prebuild tags: - prebuild - /workspace-config/{configName}/prebuild/{prebuildId}: + /workspace-template/{templateName}/prebuild/{prebuildId}: delete: consumes: - application/json description: Delete prebuild operationId: DeletePrebuild parameters: - - description: Workspace config name + - description: Workspace template name in: path - name: configName + name: templateName required: true type: string - description: Prebuild ID @@ -2689,9 +2689,9 @@ paths: description: Get prebuild operationId: GetPrebuild parameters: - - description: Workspace config name + - description: Workspace template name in: path - name: configName + name: templateName required: true type: string - description: Prebuild ID @@ -2707,26 +2707,26 @@ paths: summary: Get prebuild tags: - prebuild - /workspace-config/{configName}/set-default: + /workspace-template/{templateName}/set-default: patch: - description: Set workspace config to default - operationId: SetDefaultWorkspaceConfig + description: Set workspace template to default + operationId: SetDefaultWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true type: string responses: "200": description: OK - summary: Set workspace config to default + summary: Set workspace template to default tags: - - workspace-config - /workspace-config/default/{gitUrl}: + - workspace-template + /workspace-template/default/{gitUrl}: get: - description: Get workspace configs by git url - operationId: GetDefaultWorkspaceConfig + description: Get workspace templates by git url + operationId: GetDefaultWorkspaceTemplate parameters: - description: Git URL in: path @@ -2739,11 +2739,11 @@ paths: "200": description: OK schema: - $ref: '#/definitions/WorkspaceConfig' - summary: Get workspace configs by git url + $ref: '#/definitions/WorkspaceTemplate' + summary: Get workspace templates by git url tags: - - workspace-config - /workspace-config/prebuild: + - workspace-template + /workspace-template/prebuild: get: consumes: - application/json @@ -2759,7 +2759,7 @@ paths: summary: List prebuilds tags: - prebuild - /workspace-config/prebuild/process-git-event: + /workspace-template/prebuild/process-git-event: post: description: ProcessGitEvent operationId: ProcessGitEvent diff --git a/pkg/api/server.go b/pkg/api/server.go index 9b4e6f834d..73159e4f60 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -48,8 +48,8 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/targetconfig" "github.com/daytonaio/daytona/pkg/api/controllers/workspace" "github.com/daytonaio/daytona/pkg/api/controllers/workspace/toolbox" - "github.com/daytonaio/daytona/pkg/api/controllers/workspaceconfig" - "github.com/daytonaio/daytona/pkg/api/controllers/workspaceconfig/prebuild" + "github.com/daytonaio/daytona/pkg/api/controllers/workspacetemplate" + "github.com/daytonaio/daytona/pkg/api/controllers/workspacetemplate/prebuild" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" @@ -230,30 +230,30 @@ func (a *ApiServer) Start() error { jobController.GET("/", job.ListJobs) } - workspaceConfigController := protected.Group("/workspace-config") + workspaceTemplateController := protected.Group("/workspace-template") { - // Defining the prebuild routes first to avoid conflicts with the workspace config routes + // Defining the prebuild routes first to avoid conflicts with the workspace template routes prebuildRoutePath := "/prebuild" - workspaceConfigPrebuildsGroup := workspaceConfigController.Group(prebuildRoutePath) + workspaceTemplatePrebuildsGroup := workspaceTemplateController.Group(prebuildRoutePath) { - workspaceConfigPrebuildsGroup.GET("", prebuild.ListPrebuilds) + workspaceTemplatePrebuildsGroup.GET("", prebuild.ListPrebuilds) } - workspaceConfigNameGroup := workspaceConfigController.Group(":configName") + workspaceTemplateNameGroup := workspaceTemplateController.Group(":templateName") { - workspaceConfigNameGroup.PUT(prebuildRoutePath, prebuild.SetPrebuild) - workspaceConfigNameGroup.GET(prebuildRoutePath, prebuild.ListPrebuildsForWorkspaceConfig) - workspaceConfigNameGroup.GET(prebuildRoutePath+"/:prebuildId", prebuild.GetPrebuild) - workspaceConfigNameGroup.DELETE(prebuildRoutePath+"/:prebuildId", prebuild.DeletePrebuild) - - workspaceConfigNameGroup.GET("", workspaceconfig.GetWorkspaceConfig) - workspaceConfigNameGroup.PATCH("/set-default", workspaceconfig.SetDefaultWorkspaceConfig) - workspaceConfigNameGroup.DELETE("", workspaceconfig.DeleteWorkspaceConfig) + workspaceTemplateNameGroup.PUT(prebuildRoutePath, prebuild.SetPrebuild) + workspaceTemplateNameGroup.GET(prebuildRoutePath, prebuild.ListPrebuildsForWorkspaceTemplate) + workspaceTemplateNameGroup.GET(prebuildRoutePath+"/:prebuildId", prebuild.GetPrebuild) + workspaceTemplateNameGroup.DELETE(prebuildRoutePath+"/:prebuildId", prebuild.DeletePrebuild) + + workspaceTemplateNameGroup.GET("", workspacetemplate.GetWorkspaceTemplate) + workspaceTemplateNameGroup.PATCH("/set-default", workspacetemplate.SetDefaultWorkspaceTemplate) + workspaceTemplateNameGroup.DELETE("", workspacetemplate.DeleteWorkspaceTemplate) } - workspaceConfigController.GET("", workspaceconfig.ListWorkspaceConfigs) - workspaceConfigController.PUT("", workspaceconfig.SetWorkspaceConfig) - workspaceConfigController.GET("/default/:gitUrl", workspaceconfig.GetDefaultWorkspaceConfig) + workspaceTemplateController.GET("", workspacetemplate.ListWorkspaceTemplates) + workspaceTemplateController.PUT("", workspacetemplate.SetWorkspaceTemplate) + workspaceTemplateController.GET("/default/:gitUrl", workspacetemplate.GetDefaultWorkspaceTemplate) } public.POST(constants.WEBHOOK_EVENT_ROUTE, prebuild.ProcessGitEvent) diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index e325d1bfd1..bd086ce3bc 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -108,12 +108,12 @@ Class | Method | HTTP request | Description *GitProviderAPI* | [**RemoveGitProvider**](docs/GitProviderAPI.md#removegitprovider) | **Delete** /gitprovider/{gitProviderId} | Remove Git provider *GitProviderAPI* | [**SetGitProvider**](docs/GitProviderAPI.md#setgitprovider) | **Put** /gitprovider | Set Git provider *JobAPI* | [**ListJobs**](docs/JobAPI.md#listjobs) | **Get** /job | List jobs -*PrebuildAPI* | [**DeletePrebuild**](docs/PrebuildAPI.md#deleteprebuild) | **Delete** /workspace-config/{configName}/prebuild/{prebuildId} | Delete prebuild -*PrebuildAPI* | [**GetPrebuild**](docs/PrebuildAPI.md#getprebuild) | **Get** /workspace-config/{configName}/prebuild/{prebuildId} | Get prebuild -*PrebuildAPI* | [**ListPrebuilds**](docs/PrebuildAPI.md#listprebuilds) | **Get** /workspace-config/prebuild | List prebuilds -*PrebuildAPI* | [**ListPrebuildsForWorkspaceConfig**](docs/PrebuildAPI.md#listprebuildsforworkspaceconfig) | **Get** /workspace-config/{configName}/prebuild | List prebuilds for workspace config -*PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /workspace-config/prebuild/process-git-event | ProcessGitEvent -*PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /workspace-config/{configName}/prebuild | Set prebuild +*PrebuildAPI* | [**DeletePrebuild**](docs/PrebuildAPI.md#deleteprebuild) | **Delete** /workspace-template/{templateName}/prebuild/{prebuildId} | Delete prebuild +*PrebuildAPI* | [**GetPrebuild**](docs/PrebuildAPI.md#getprebuild) | **Get** /workspace-template/{templateName}/prebuild/{prebuildId} | Get prebuild +*PrebuildAPI* | [**ListPrebuilds**](docs/PrebuildAPI.md#listprebuilds) | **Get** /workspace-template/prebuild | List prebuilds +*PrebuildAPI* | [**ListPrebuildsForWorkspaceTemplate**](docs/PrebuildAPI.md#listprebuildsforworkspacetemplate) | **Get** /workspace-template/{templateName}/prebuild | List prebuilds for workspace template +*PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /workspace-template/prebuild/process-git-event | ProcessGitEvent +*PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /workspace-template/{templateName}/prebuild | Set prebuild *ProviderAPI* | [**GetTargetConfigManifest**](docs/ProviderAPI.md#gettargetconfigmanifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest *ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /provider/install | Install a provider *ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /provider | List providers @@ -141,12 +141,12 @@ Class | Method | HTTP request | Description *WorkspaceAPI* | [**SetWorkspaceMetadata**](docs/WorkspaceAPI.md#setworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata *WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace *WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace -*WorkspaceConfigAPI* | [**DeleteWorkspaceConfig**](docs/WorkspaceConfigAPI.md#deleteworkspaceconfig) | **Delete** /workspace-config/{configName} | Delete workspace config data -*WorkspaceConfigAPI* | [**GetDefaultWorkspaceConfig**](docs/WorkspaceConfigAPI.md#getdefaultworkspaceconfig) | **Get** /workspace-config/default/{gitUrl} | Get workspace configs by git url -*WorkspaceConfigAPI* | [**GetWorkspaceConfig**](docs/WorkspaceConfigAPI.md#getworkspaceconfig) | **Get** /workspace-config/{configName} | Get workspace config data -*WorkspaceConfigAPI* | [**ListWorkspaceConfigs**](docs/WorkspaceConfigAPI.md#listworkspaceconfigs) | **Get** /workspace-config | List workspace configs -*WorkspaceConfigAPI* | [**SetDefaultWorkspaceConfig**](docs/WorkspaceConfigAPI.md#setdefaultworkspaceconfig) | **Patch** /workspace-config/{configName}/set-default | Set workspace config to default -*WorkspaceConfigAPI* | [**SetWorkspaceConfig**](docs/WorkspaceConfigAPI.md#setworkspaceconfig) | **Put** /workspace-config | Set workspace config data +*WorkspaceTemplateAPI* | [**DeleteWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#deleteworkspacetemplate) | **Delete** /workspace-template/{templateName} | Delete workspace template data +*WorkspaceTemplateAPI* | [**GetDefaultWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getdefaultworkspacetemplate) | **Get** /workspace-template/default/{gitUrl} | Get workspace templates by git url +*WorkspaceTemplateAPI* | [**GetWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getworkspacetemplate) | **Get** /workspace-template/{templateName} | Get workspace template data +*WorkspaceTemplateAPI* | [**ListWorkspaceTemplates**](docs/WorkspaceTemplateAPI.md#listworkspacetemplates) | **Get** /workspace-template | List workspace templates +*WorkspaceTemplateAPI* | [**SetDefaultWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#setdefaultworkspacetemplate) | **Patch** /workspace-template/{templateName}/set-default | Set workspace template to default +*WorkspaceTemplateAPI* | [**SetWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#setworkspacetemplate) | **Put** /workspace-template | Set workspace template data *WorkspaceToolboxAPI* | [**CreateSession**](docs/WorkspaceToolboxAPI.md#createsession) | **Post** /workspace/{workspaceId}/toolbox/process/session | Create exec session *WorkspaceToolboxAPI* | [**DeleteSession**](docs/WorkspaceToolboxAPI.md#deletesession) | **Delete** /workspace/{workspaceId}/toolbox/process/session/{sessionId} | Delete session *WorkspaceToolboxAPI* | [**FsCreateFolder**](docs/WorkspaceToolboxAPI.md#fscreatefolder) | **Post** /workspace/{workspaceId}/toolbox/files/folder | Create folder @@ -201,9 +201,9 @@ Class | Method | HTTP request | Description - [CreatePrebuildDTO](docs/CreatePrebuildDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) - [CreateTargetDTO](docs/CreateTargetDTO.md) - - [CreateWorkspaceConfigDTO](docs/CreateWorkspaceConfigDTO.md) - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) - [CreateWorkspaceSourceDTO](docs/CreateWorkspaceSourceDTO.md) + - [CreateWorkspaceTemplateDTO](docs/CreateWorkspaceTemplateDTO.md) - [DevcontainerConfig](docs/DevcontainerConfig.md) - [EnvironmentVariable](docs/EnvironmentVariable.md) - [ExecuteRequest](docs/ExecuteRequest.md) @@ -273,11 +273,11 @@ Class | Method | HTTP request | Description - [TargetMetadata](docs/TargetMetadata.md) - [TargetProviderInfo](docs/TargetProviderInfo.md) - [Workspace](docs/Workspace.md) - - [WorkspaceConfig](docs/WorkspaceConfig.md) - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) - [WorkspaceInfo](docs/WorkspaceInfo.md) - [WorkspaceMetadata](docs/WorkspaceMetadata.md) + - [WorkspaceTemplate](docs/WorkspaceTemplate.md) ## Documentation For Authorization diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 5acc5f0d93..65f047ac08 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -1110,44 +1110,44 @@ paths: tags: - workspace x-codegen-request-body-name: workspace - /workspace-config: + /workspace-template: get: - description: List workspace configs - operationId: ListWorkspaceConfigs + description: List workspace templates + operationId: ListWorkspaceTemplates responses: "200": content: application/json: schema: items: - $ref: '#/components/schemas/WorkspaceConfig' + $ref: '#/components/schemas/WorkspaceTemplate' type: array description: OK - summary: List workspace configs + summary: List workspace templates tags: - - workspace-config + - workspace-template put: - description: Set workspace config data - operationId: SetWorkspaceConfig + description: Set workspace template data + operationId: SetWorkspaceTemplate requestBody: content: application/json: schema: - $ref: '#/components/schemas/CreateWorkspaceConfigDTO' - description: Workspace config + $ref: '#/components/schemas/CreateWorkspaceTemplateDTO' + description: Workspace template required: true responses: "201": content: {} description: Created - summary: Set workspace config data + summary: Set workspace template data tags: - - workspace-config - x-codegen-request-body-name: workspaceConfig - /workspace-config/default/{gitUrl}: + - workspace-template + x-codegen-request-body-name: workspaceTemplate + /workspace-template/default/{gitUrl}: get: - description: Get workspace configs by git url - operationId: GetDefaultWorkspaceConfig + description: Get workspace templates by git url + operationId: GetDefaultWorkspaceTemplate parameters: - description: Git URL in: path @@ -1160,12 +1160,12 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/WorkspaceConfig' + $ref: '#/components/schemas/WorkspaceTemplate' description: OK - summary: Get workspace configs by git url + summary: Get workspace templates by git url tags: - - workspace-config - /workspace-config/prebuild: + - workspace-template + /workspace-template/prebuild: get: description: List prebuilds operationId: ListPrebuilds @@ -1181,7 +1181,7 @@ paths: summary: List prebuilds tags: - prebuild - /workspace-config/prebuild/process-git-event: + /workspace-template/prebuild/process-git-event: post: description: ProcessGitEvent operationId: ProcessGitEvent @@ -1200,14 +1200,14 @@ paths: tags: - prebuild x-codegen-request-body-name: body - /workspace-config/{configName}: + /workspace-template/{templateName}: delete: - description: Delete workspace config data - operationId: DeleteWorkspaceConfig + description: Delete workspace template data + operationId: DeleteWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1220,16 +1220,16 @@ paths: "204": content: {} description: No Content - summary: Delete workspace config data + summary: Delete workspace template data tags: - - workspace-config + - workspace-template get: - description: Get workspace config data - operationId: GetWorkspaceConfig + description: Get workspace template data + operationId: GetWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1238,19 +1238,19 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/WorkspaceConfig' + $ref: '#/components/schemas/WorkspaceTemplate' description: OK - summary: Get workspace config data + summary: Get workspace template data tags: - - workspace-config - /workspace-config/{configName}/prebuild: + - workspace-template + /workspace-template/{templateName}/prebuild: get: - description: List prebuilds for workspace config - operationId: ListPrebuildsForWorkspaceConfig + description: List prebuilds for workspace template + operationId: ListPrebuildsForWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1263,16 +1263,16 @@ paths: $ref: '#/components/schemas/PrebuildDTO' type: array description: OK - summary: List prebuilds for workspace config + summary: List prebuilds for workspace template tags: - prebuild put: description: Set prebuild operationId: SetPrebuild parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1294,14 +1294,14 @@ paths: tags: - prebuild x-codegen-request-body-name: prebuild - /workspace-config/{configName}/prebuild/{prebuildId}: + /workspace-template/{templateName}/prebuild/{prebuildId}: delete: description: Delete prebuild operationId: DeletePrebuild parameters: - - description: Workspace config name + - description: Workspace template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1327,9 +1327,9 @@ paths: description: Get prebuild operationId: GetPrebuild parameters: - - description: Workspace config name + - description: Workspace template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1349,14 +1349,14 @@ paths: summary: Get prebuild tags: - prebuild - /workspace-config/{configName}/set-default: + /workspace-template/{templateName}/set-default: patch: - description: Set workspace config to default - operationId: SetDefaultWorkspaceConfig + description: Set workspace template to default + operationId: SetDefaultWorkspaceTemplate parameters: - - description: Config name + - description: Template name in: path - name: configName + name: templateName required: true schema: type: string @@ -1364,9 +1364,9 @@ paths: "200": content: {} description: OK - summary: Set workspace config to default + summary: Set workspace template to default tags: - - workspace-config + - workspace-template /workspace/{workspaceId}: delete: description: Remove workspace @@ -2722,8 +2722,8 @@ components: prebuildId: prebuildId envVars: key: envVars - workspaceConfigName: workspaceConfigName branch: branch + workspaceTemplateName: workspaceTemplateName properties: branch: type: string @@ -2733,12 +2733,12 @@ components: type: object prebuildId: type: string - workspaceConfigName: + workspaceTemplateName: type: string required: - branch - envVars - - workspaceConfigName + - workspaceTemplateName type: object CreatePrebuildDTO: example: @@ -2791,43 +2791,6 @@ components: - name - targetConfigName type: object - CreateWorkspaceConfigDTO: - example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - envVars: - key: envVars - name: name - user: user - repositoryUrl: repositoryUrl - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - repositoryUrl: - type: string - user: - type: string - required: - - envVars - - name - - repositoryUrl - type: object CreateWorkspaceDTO: example: buildConfig: @@ -2903,6 +2866,43 @@ components: required: - repository type: object + CreateWorkspaceTemplateDTO: + example: + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + envVars: + key: envVars + name: name + user: user + repositoryUrl: repositoryUrl + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + repositoryUrl: + type: string + user: + type: string + required: + - envVars + - name + - repositoryUrl + type: object DevcontainerConfig: example: filePath: filePath @@ -3680,13 +3680,13 @@ components: PrebuildDTO: example: commitInterval: 0 - workspaceConfigName: workspaceConfigName id: id branch: branch retention: 6 triggerFiles: - triggerFiles - triggerFiles + workspaceTemplateName: workspaceTemplateName properties: branch: type: string @@ -3700,13 +3700,13 @@ components: items: type: string type: array - workspaceConfigName: + workspaceTemplateName: type: string required: - branch - id - retention - - workspaceConfigName + - workspaceTemplateName type: object Provider: example: @@ -4578,68 +4578,6 @@ components: - targetId - user type: object - WorkspaceConfig: - example: - prebuilds: - - commitInterval: 0 - id: id - branch: branch - retention: 6 - triggerFiles: - - triggerFiles - - triggerFiles - - commitInterval: 0 - id: id - branch: branch - retention: 6 - triggerFiles: - - triggerFiles - - triggerFiles - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId - image: image - default: true - envVars: - key: envVars - name: name - user: user - repositoryUrl: repositoryUrl - properties: - buildConfig: - $ref: '#/components/schemas/BuildConfig' - default: - type: boolean - envVars: - additionalProperties: - type: string - type: object - gitProviderConfigId: - type: string - image: - type: string - name: - type: string - prebuilds: - items: - $ref: '#/components/schemas/PrebuildConfig' - type: array - repositoryUrl: - type: string - user: - type: string - required: - - default - - envVars - - image - - name - - repositoryUrl - - user - type: object WorkspaceDTO: example: gitProviderConfigId: gitProviderConfigId @@ -4842,6 +4780,68 @@ components: - uptime - workspaceId type: object + WorkspaceTemplate: + example: + prebuilds: + - commitInterval: 0 + id: id + branch: branch + retention: 6 + triggerFiles: + - triggerFiles + - triggerFiles + - commitInterval: 0 + id: id + branch: branch + retention: 6 + triggerFiles: + - triggerFiles + - triggerFiles + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + gitProviderConfigId: gitProviderConfigId + image: image + default: true + envVars: + key: envVars + name: name + user: user + repositoryUrl: repositoryUrl + properties: + buildConfig: + $ref: '#/components/schemas/BuildConfig' + default: + type: boolean + envVars: + additionalProperties: + type: string + type: object + gitProviderConfigId: + type: string + image: + type: string + name: + type: string + prebuilds: + items: + $ref: '#/components/schemas/PrebuildConfig' + type: array + repositoryUrl: + type: string + user: + type: string + required: + - default + - envVars + - image + - name + - repositoryUrl + - user + type: object models.ApiKeyType: enum: - client diff --git a/pkg/apiclient/api_prebuild.go b/pkg/apiclient/api_prebuild.go index 7168d1b499..cf9be91f0a 100644 --- a/pkg/apiclient/api_prebuild.go +++ b/pkg/apiclient/api_prebuild.go @@ -23,11 +23,11 @@ import ( type PrebuildAPIService service type ApiDeletePrebuildRequest struct { - ctx context.Context - ApiService *PrebuildAPIService - configName string - prebuildId string - force *bool + ctx context.Context + ApiService *PrebuildAPIService + templateName string + prebuildId string + force *bool } // Force @@ -46,16 +46,16 @@ DeletePrebuild Delete prebuild Delete prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Workspace config name + @param templateName Workspace template name @param prebuildId Prebuild ID @return ApiDeletePrebuildRequest */ -func (a *PrebuildAPIService) DeletePrebuild(ctx context.Context, configName string, prebuildId string) ApiDeletePrebuildRequest { +func (a *PrebuildAPIService) DeletePrebuild(ctx context.Context, templateName string, prebuildId string) ApiDeletePrebuildRequest { return ApiDeletePrebuildRequest{ - ApiService: a, - ctx: ctx, - configName: configName, - prebuildId: prebuildId, + ApiService: a, + ctx: ctx, + templateName: templateName, + prebuildId: prebuildId, } } @@ -72,8 +72,8 @@ func (a *PrebuildAPIService) DeletePrebuildExecute(r ApiDeletePrebuildRequest) ( return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}/prebuild/{prebuildId}" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}/prebuild/{prebuildId}" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarPath = strings.Replace(localVarPath, "{"+"prebuildId"+"}", url.PathEscape(parameterValueToString(r.prebuildId, "prebuildId")), -1) localVarHeaderParams := make(map[string]string) @@ -143,10 +143,10 @@ func (a *PrebuildAPIService) DeletePrebuildExecute(r ApiDeletePrebuildRequest) ( } type ApiGetPrebuildRequest struct { - ctx context.Context - ApiService *PrebuildAPIService - configName string - prebuildId string + ctx context.Context + ApiService *PrebuildAPIService + templateName string + prebuildId string } func (r ApiGetPrebuildRequest) Execute() (*PrebuildDTO, *http.Response, error) { @@ -159,16 +159,16 @@ GetPrebuild Get prebuild Get prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Workspace config name + @param templateName Workspace template name @param prebuildId Prebuild ID @return ApiGetPrebuildRequest */ -func (a *PrebuildAPIService) GetPrebuild(ctx context.Context, configName string, prebuildId string) ApiGetPrebuildRequest { +func (a *PrebuildAPIService) GetPrebuild(ctx context.Context, templateName string, prebuildId string) ApiGetPrebuildRequest { return ApiGetPrebuildRequest{ - ApiService: a, - ctx: ctx, - configName: configName, - prebuildId: prebuildId, + ApiService: a, + ctx: ctx, + templateName: templateName, + prebuildId: prebuildId, } } @@ -188,8 +188,8 @@ func (a *PrebuildAPIService) GetPrebuildExecute(r ApiGetPrebuildRequest) (*Prebu return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}/prebuild/{prebuildId}" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}/prebuild/{prebuildId}" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarPath = strings.Replace(localVarPath, "{"+"prebuildId"+"}", url.PathEscape(parameterValueToString(r.prebuildId, "prebuildId")), -1) localVarHeaderParams := make(map[string]string) @@ -304,7 +304,7 @@ func (a *PrebuildAPIService) ListPrebuildsExecute(r ApiListPrebuildsRequest) ([] return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/prebuild" + localVarPath := localBasePath + "/workspace-template/prebuild" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -378,37 +378,37 @@ func (a *PrebuildAPIService) ListPrebuildsExecute(r ApiListPrebuildsRequest) ([] return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListPrebuildsForWorkspaceConfigRequest struct { - ctx context.Context - ApiService *PrebuildAPIService - configName string +type ApiListPrebuildsForWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *PrebuildAPIService + templateName string } -func (r ApiListPrebuildsForWorkspaceConfigRequest) Execute() ([]PrebuildDTO, *http.Response, error) { - return r.ApiService.ListPrebuildsForWorkspaceConfigExecute(r) +func (r ApiListPrebuildsForWorkspaceTemplateRequest) Execute() ([]PrebuildDTO, *http.Response, error) { + return r.ApiService.ListPrebuildsForWorkspaceTemplateExecute(r) } /* -ListPrebuildsForWorkspaceConfig List prebuilds for workspace config +ListPrebuildsForWorkspaceTemplate List prebuilds for workspace template -List prebuilds for workspace config +List prebuilds for workspace template @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Config name - @return ApiListPrebuildsForWorkspaceConfigRequest + @param templateName Template name + @return ApiListPrebuildsForWorkspaceTemplateRequest */ -func (a *PrebuildAPIService) ListPrebuildsForWorkspaceConfig(ctx context.Context, configName string) ApiListPrebuildsForWorkspaceConfigRequest { - return ApiListPrebuildsForWorkspaceConfigRequest{ - ApiService: a, - ctx: ctx, - configName: configName, +func (a *PrebuildAPIService) ListPrebuildsForWorkspaceTemplate(ctx context.Context, templateName string) ApiListPrebuildsForWorkspaceTemplateRequest { + return ApiListPrebuildsForWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + templateName: templateName, } } // Execute executes the request // // @return []PrebuildDTO -func (a *PrebuildAPIService) ListPrebuildsForWorkspaceConfigExecute(r ApiListPrebuildsForWorkspaceConfigRequest) ([]PrebuildDTO, *http.Response, error) { +func (a *PrebuildAPIService) ListPrebuildsForWorkspaceTemplateExecute(r ApiListPrebuildsForWorkspaceTemplateRequest) ([]PrebuildDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -416,13 +416,13 @@ func (a *PrebuildAPIService) ListPrebuildsForWorkspaceConfigExecute(r ApiListPre localVarReturnValue []PrebuildDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.ListPrebuildsForWorkspaceConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.ListPrebuildsForWorkspaceTemplate") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}/prebuild" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}/prebuild" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -540,7 +540,7 @@ func (a *PrebuildAPIService) ProcessGitEventExecute(r ApiProcessGitEventRequest) return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/prebuild/process-git-event" + localVarPath := localBasePath + "/workspace-template/prebuild/process-git-event" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -611,10 +611,10 @@ func (a *PrebuildAPIService) ProcessGitEventExecute(r ApiProcessGitEventRequest) } type ApiSetPrebuildRequest struct { - ctx context.Context - ApiService *PrebuildAPIService - configName string - prebuild *CreatePrebuildDTO + ctx context.Context + ApiService *PrebuildAPIService + templateName string + prebuild *CreatePrebuildDTO } // Prebuild @@ -633,14 +633,14 @@ SetPrebuild Set prebuild Set prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Config name + @param templateName Template name @return ApiSetPrebuildRequest */ -func (a *PrebuildAPIService) SetPrebuild(ctx context.Context, configName string) ApiSetPrebuildRequest { +func (a *PrebuildAPIService) SetPrebuild(ctx context.Context, templateName string) ApiSetPrebuildRequest { return ApiSetPrebuildRequest{ - ApiService: a, - ctx: ctx, - configName: configName, + ApiService: a, + ctx: ctx, + templateName: templateName, } } @@ -660,8 +660,8 @@ func (a *PrebuildAPIService) SetPrebuildExecute(r ApiSetPrebuildRequest) (string return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}/prebuild" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}/prebuild" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} diff --git a/pkg/apiclient/api_workspace_config.go b/pkg/apiclient/api_workspace_template.go similarity index 70% rename from pkg/apiclient/api_workspace_config.go rename to pkg/apiclient/api_workspace_template.go index 6cb66b47f7..eee695d509 100644 --- a/pkg/apiclient/api_workspace_config.go +++ b/pkg/apiclient/api_workspace_template.go @@ -19,58 +19,58 @@ import ( "strings" ) -// WorkspaceConfigAPIService WorkspaceConfigAPI service -type WorkspaceConfigAPIService service - -type ApiDeleteWorkspaceConfigRequest struct { - ctx context.Context - ApiService *WorkspaceConfigAPIService - configName string - force *bool +// WorkspaceTemplateAPIService WorkspaceTemplateAPI service +type WorkspaceTemplateAPIService service + +type ApiDeleteWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + templateName string + force *bool } // Force -func (r ApiDeleteWorkspaceConfigRequest) Force(force bool) ApiDeleteWorkspaceConfigRequest { +func (r ApiDeleteWorkspaceTemplateRequest) Force(force bool) ApiDeleteWorkspaceTemplateRequest { r.force = &force return r } -func (r ApiDeleteWorkspaceConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.DeleteWorkspaceConfigExecute(r) +func (r ApiDeleteWorkspaceTemplateRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteWorkspaceTemplateExecute(r) } /* -DeleteWorkspaceConfig Delete workspace config data +DeleteWorkspaceTemplate Delete workspace template data -Delete workspace config data +Delete workspace template data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Config name - @return ApiDeleteWorkspaceConfigRequest + @param templateName Template name + @return ApiDeleteWorkspaceTemplateRequest */ -func (a *WorkspaceConfigAPIService) DeleteWorkspaceConfig(ctx context.Context, configName string) ApiDeleteWorkspaceConfigRequest { - return ApiDeleteWorkspaceConfigRequest{ - ApiService: a, - ctx: ctx, - configName: configName, +func (a *WorkspaceTemplateAPIService) DeleteWorkspaceTemplate(ctx context.Context, templateName string) ApiDeleteWorkspaceTemplateRequest { + return ApiDeleteWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + templateName: templateName, } } // Execute executes the request -func (a *WorkspaceConfigAPIService) DeleteWorkspaceConfigExecute(r ApiDeleteWorkspaceConfigRequest) (*http.Response, error) { +func (a *WorkspaceTemplateAPIService) DeleteWorkspaceTemplateExecute(r ApiDeleteWorkspaceTemplateRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodDelete localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.DeleteWorkspaceConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.DeleteWorkspaceTemplate") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -138,27 +138,27 @@ func (a *WorkspaceConfigAPIService) DeleteWorkspaceConfigExecute(r ApiDeleteWork return localVarHTTPResponse, nil } -type ApiGetDefaultWorkspaceConfigRequest struct { +type ApiGetDefaultWorkspaceTemplateRequest struct { ctx context.Context - ApiService *WorkspaceConfigAPIService + ApiService *WorkspaceTemplateAPIService gitUrl string } -func (r ApiGetDefaultWorkspaceConfigRequest) Execute() (*WorkspaceConfig, *http.Response, error) { - return r.ApiService.GetDefaultWorkspaceConfigExecute(r) +func (r ApiGetDefaultWorkspaceTemplateRequest) Execute() (*WorkspaceTemplate, *http.Response, error) { + return r.ApiService.GetDefaultWorkspaceTemplateExecute(r) } /* -GetDefaultWorkspaceConfig Get workspace configs by git url +GetDefaultWorkspaceTemplate Get workspace templates by git url -Get workspace configs by git url +Get workspace templates by git url @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param gitUrl Git URL - @return ApiGetDefaultWorkspaceConfigRequest + @return ApiGetDefaultWorkspaceTemplateRequest */ -func (a *WorkspaceConfigAPIService) GetDefaultWorkspaceConfig(ctx context.Context, gitUrl string) ApiGetDefaultWorkspaceConfigRequest { - return ApiGetDefaultWorkspaceConfigRequest{ +func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplate(ctx context.Context, gitUrl string) ApiGetDefaultWorkspaceTemplateRequest { + return ApiGetDefaultWorkspaceTemplateRequest{ ApiService: a, ctx: ctx, gitUrl: gitUrl, @@ -167,21 +167,21 @@ func (a *WorkspaceConfigAPIService) GetDefaultWorkspaceConfig(ctx context.Contex // Execute executes the request // -// @return WorkspaceConfig -func (a *WorkspaceConfigAPIService) GetDefaultWorkspaceConfigExecute(r ApiGetDefaultWorkspaceConfigRequest) (*WorkspaceConfig, *http.Response, error) { +// @return WorkspaceTemplate +func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplateExecute(r ApiGetDefaultWorkspaceTemplateRequest) (*WorkspaceTemplate, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *WorkspaceConfig + localVarReturnValue *WorkspaceTemplate ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.GetDefaultWorkspaceConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.GetDefaultWorkspaceTemplate") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/default/{gitUrl}" + localVarPath := localBasePath + "/workspace-template/default/{gitUrl}" localVarPath = strings.Replace(localVarPath, "{"+"gitUrl"+"}", url.PathEscape(parameterValueToString(r.gitUrl, "gitUrl")), -1) localVarHeaderParams := make(map[string]string) @@ -256,51 +256,51 @@ func (a *WorkspaceConfigAPIService) GetDefaultWorkspaceConfigExecute(r ApiGetDef return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetWorkspaceConfigRequest struct { - ctx context.Context - ApiService *WorkspaceConfigAPIService - configName string +type ApiGetWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + templateName string } -func (r ApiGetWorkspaceConfigRequest) Execute() (*WorkspaceConfig, *http.Response, error) { - return r.ApiService.GetWorkspaceConfigExecute(r) +func (r ApiGetWorkspaceTemplateRequest) Execute() (*WorkspaceTemplate, *http.Response, error) { + return r.ApiService.GetWorkspaceTemplateExecute(r) } /* -GetWorkspaceConfig Get workspace config data +GetWorkspaceTemplate Get workspace template data -Get workspace config data +Get workspace template data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Config name - @return ApiGetWorkspaceConfigRequest + @param templateName Template name + @return ApiGetWorkspaceTemplateRequest */ -func (a *WorkspaceConfigAPIService) GetWorkspaceConfig(ctx context.Context, configName string) ApiGetWorkspaceConfigRequest { - return ApiGetWorkspaceConfigRequest{ - ApiService: a, - ctx: ctx, - configName: configName, +func (a *WorkspaceTemplateAPIService) GetWorkspaceTemplate(ctx context.Context, templateName string) ApiGetWorkspaceTemplateRequest { + return ApiGetWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + templateName: templateName, } } // Execute executes the request // -// @return WorkspaceConfig -func (a *WorkspaceConfigAPIService) GetWorkspaceConfigExecute(r ApiGetWorkspaceConfigRequest) (*WorkspaceConfig, *http.Response, error) { +// @return WorkspaceTemplate +func (a *WorkspaceTemplateAPIService) GetWorkspaceTemplateExecute(r ApiGetWorkspaceTemplateRequest) (*WorkspaceTemplate, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *WorkspaceConfig + localVarReturnValue *WorkspaceTemplate ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.GetWorkspaceConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.GetWorkspaceTemplate") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -374,25 +374,25 @@ func (a *WorkspaceConfigAPIService) GetWorkspaceConfigExecute(r ApiGetWorkspaceC return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListWorkspaceConfigsRequest struct { +type ApiListWorkspaceTemplatesRequest struct { ctx context.Context - ApiService *WorkspaceConfigAPIService + ApiService *WorkspaceTemplateAPIService } -func (r ApiListWorkspaceConfigsRequest) Execute() ([]WorkspaceConfig, *http.Response, error) { - return r.ApiService.ListWorkspaceConfigsExecute(r) +func (r ApiListWorkspaceTemplatesRequest) Execute() ([]WorkspaceTemplate, *http.Response, error) { + return r.ApiService.ListWorkspaceTemplatesExecute(r) } /* -ListWorkspaceConfigs List workspace configs +ListWorkspaceTemplates List workspace templates -List workspace configs +List workspace templates @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListWorkspaceConfigsRequest + @return ApiListWorkspaceTemplatesRequest */ -func (a *WorkspaceConfigAPIService) ListWorkspaceConfigs(ctx context.Context) ApiListWorkspaceConfigsRequest { - return ApiListWorkspaceConfigsRequest{ +func (a *WorkspaceTemplateAPIService) ListWorkspaceTemplates(ctx context.Context) ApiListWorkspaceTemplatesRequest { + return ApiListWorkspaceTemplatesRequest{ ApiService: a, ctx: ctx, } @@ -400,21 +400,21 @@ func (a *WorkspaceConfigAPIService) ListWorkspaceConfigs(ctx context.Context) Ap // Execute executes the request // -// @return []WorkspaceConfig -func (a *WorkspaceConfigAPIService) ListWorkspaceConfigsExecute(r ApiListWorkspaceConfigsRequest) ([]WorkspaceConfig, *http.Response, error) { +// @return []WorkspaceTemplate +func (a *WorkspaceTemplateAPIService) ListWorkspaceTemplatesExecute(r ApiListWorkspaceTemplatesRequest) ([]WorkspaceTemplate, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []WorkspaceConfig + localVarReturnValue []WorkspaceTemplate ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.ListWorkspaceConfigs") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.ListWorkspaceTemplates") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config" + localVarPath := localBasePath + "/workspace-template" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -488,48 +488,48 @@ func (a *WorkspaceConfigAPIService) ListWorkspaceConfigsExecute(r ApiListWorkspa return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetDefaultWorkspaceConfigRequest struct { - ctx context.Context - ApiService *WorkspaceConfigAPIService - configName string +type ApiSetDefaultWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + templateName string } -func (r ApiSetDefaultWorkspaceConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.SetDefaultWorkspaceConfigExecute(r) +func (r ApiSetDefaultWorkspaceTemplateRequest) Execute() (*http.Response, error) { + return r.ApiService.SetDefaultWorkspaceTemplateExecute(r) } /* -SetDefaultWorkspaceConfig Set workspace config to default +SetDefaultWorkspaceTemplate Set workspace template to default -Set workspace config to default +Set workspace template to default @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configName Config name - @return ApiSetDefaultWorkspaceConfigRequest + @param templateName Template name + @return ApiSetDefaultWorkspaceTemplateRequest */ -func (a *WorkspaceConfigAPIService) SetDefaultWorkspaceConfig(ctx context.Context, configName string) ApiSetDefaultWorkspaceConfigRequest { - return ApiSetDefaultWorkspaceConfigRequest{ - ApiService: a, - ctx: ctx, - configName: configName, +func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplate(ctx context.Context, templateName string) ApiSetDefaultWorkspaceTemplateRequest { + return ApiSetDefaultWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + templateName: templateName, } } // Execute executes the request -func (a *WorkspaceConfigAPIService) SetDefaultWorkspaceConfigExecute(r ApiSetDefaultWorkspaceConfigRequest) (*http.Response, error) { +func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplateExecute(r ApiSetDefaultWorkspaceTemplateRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPatch localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.SetDefaultWorkspaceConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.SetDefaultWorkspaceTemplate") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config/{configName}/set-default" - localVarPath = strings.Replace(localVarPath, "{"+"configName"+"}", url.PathEscape(parameterValueToString(r.configName, "configName")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}/set-default" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -594,57 +594,57 @@ func (a *WorkspaceConfigAPIService) SetDefaultWorkspaceConfigExecute(r ApiSetDef return localVarHTTPResponse, nil } -type ApiSetWorkspaceConfigRequest struct { - ctx context.Context - ApiService *WorkspaceConfigAPIService - workspaceConfig *CreateWorkspaceConfigDTO +type ApiSetWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + workspaceTemplate *CreateWorkspaceTemplateDTO } -// Workspace config -func (r ApiSetWorkspaceConfigRequest) WorkspaceConfig(workspaceConfig CreateWorkspaceConfigDTO) ApiSetWorkspaceConfigRequest { - r.workspaceConfig = &workspaceConfig +// Workspace template +func (r ApiSetWorkspaceTemplateRequest) WorkspaceTemplate(workspaceTemplate CreateWorkspaceTemplateDTO) ApiSetWorkspaceTemplateRequest { + r.workspaceTemplate = &workspaceTemplate return r } -func (r ApiSetWorkspaceConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.SetWorkspaceConfigExecute(r) +func (r ApiSetWorkspaceTemplateRequest) Execute() (*http.Response, error) { + return r.ApiService.SetWorkspaceTemplateExecute(r) } /* -SetWorkspaceConfig Set workspace config data +SetWorkspaceTemplate Set workspace template data -Set workspace config data +Set workspace template data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetWorkspaceConfigRequest + @return ApiSetWorkspaceTemplateRequest */ -func (a *WorkspaceConfigAPIService) SetWorkspaceConfig(ctx context.Context) ApiSetWorkspaceConfigRequest { - return ApiSetWorkspaceConfigRequest{ +func (a *WorkspaceTemplateAPIService) SetWorkspaceTemplate(ctx context.Context) ApiSetWorkspaceTemplateRequest { + return ApiSetWorkspaceTemplateRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *WorkspaceConfigAPIService) SetWorkspaceConfigExecute(r ApiSetWorkspaceConfigRequest) (*http.Response, error) { +func (a *WorkspaceTemplateAPIService) SetWorkspaceTemplateExecute(r ApiSetWorkspaceTemplateRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceConfigAPIService.SetWorkspaceConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.SetWorkspaceTemplate") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-config" + localVarPath := localBasePath + "/workspace-template" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.workspaceConfig == nil { - return nil, reportError("workspaceConfig is required and must be specified") + if r.workspaceTemplate == nil { + return nil, reportError("workspaceTemplate is required and must be specified") } // to determine the Content-Type header @@ -665,7 +665,7 @@ func (a *WorkspaceConfigAPIService) SetWorkspaceConfigExecute(r ApiSetWorkspaceC localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.workspaceConfig + localVarPostBody = r.workspaceTemplate if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index 5a566b2c54..fccca57914 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -76,7 +76,7 @@ type APIClient struct { WorkspaceAPI *WorkspaceAPIService - WorkspaceConfigAPI *WorkspaceConfigAPIService + WorkspaceTemplateAPI *WorkspaceTemplateAPIService WorkspaceToolboxAPI *WorkspaceToolboxAPIService } @@ -111,7 +111,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.TargetAPI = (*TargetAPIService)(&c.common) c.TargetConfigAPI = (*TargetConfigAPIService)(&c.common) c.WorkspaceAPI = (*WorkspaceAPIService)(&c.common) - c.WorkspaceConfigAPI = (*WorkspaceConfigAPIService)(&c.common) + c.WorkspaceTemplateAPI = (*WorkspaceTemplateAPIService)(&c.common) c.WorkspaceToolboxAPI = (*WorkspaceToolboxAPIService)(&c.common) return c diff --git a/pkg/apiclient/docs/BuildAPI.md b/pkg/apiclient/docs/BuildAPI.md index 86215d58bd..e1a5cd3bdc 100644 --- a/pkg/apiclient/docs/BuildAPI.md +++ b/pkg/apiclient/docs/BuildAPI.md @@ -34,7 +34,7 @@ import ( ) func main() { - createBuildDto := *openapiclient.NewCreateBuildDTO("Branch_example", map[string]string{"key": "Inner_example"}, "WorkspaceConfigName_example") // CreateBuildDTO | Create Build DTO + createBuildDto := *openapiclient.NewCreateBuildDTO("Branch_example", map[string]string{"key": "Inner_example"}, "WorkspaceTemplateName_example") // CreateBuildDTO | Create Build DTO configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/docs/CreateBuildDTO.md b/pkg/apiclient/docs/CreateBuildDTO.md index ac78a8948e..584888702e 100644 --- a/pkg/apiclient/docs/CreateBuildDTO.md +++ b/pkg/apiclient/docs/CreateBuildDTO.md @@ -7,13 +7,13 @@ Name | Type | Description | Notes **Branch** | **string** | | **EnvVars** | **map[string]string** | | **PrebuildId** | Pointer to **string** | | [optional] -**WorkspaceConfigName** | **string** | | +**WorkspaceTemplateName** | **string** | | ## Methods ### NewCreateBuildDTO -`func NewCreateBuildDTO(branch string, envVars map[string]string, workspaceConfigName string, ) *CreateBuildDTO` +`func NewCreateBuildDTO(branch string, envVars map[string]string, workspaceTemplateName string, ) *CreateBuildDTO` NewCreateBuildDTO instantiates a new CreateBuildDTO object This constructor will assign default values to properties that have it defined, @@ -93,24 +93,24 @@ SetPrebuildId sets PrebuildId field to given value. HasPrebuildId returns a boolean if a field has been set. -### GetWorkspaceConfigName +### GetWorkspaceTemplateName -`func (o *CreateBuildDTO) GetWorkspaceConfigName() string` +`func (o *CreateBuildDTO) GetWorkspaceTemplateName() string` -GetWorkspaceConfigName returns the WorkspaceConfigName field if non-nil, zero value otherwise. +GetWorkspaceTemplateName returns the WorkspaceTemplateName field if non-nil, zero value otherwise. -### GetWorkspaceConfigNameOk +### GetWorkspaceTemplateNameOk -`func (o *CreateBuildDTO) GetWorkspaceConfigNameOk() (*string, bool)` +`func (o *CreateBuildDTO) GetWorkspaceTemplateNameOk() (*string, bool)` -GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field if it's non-nil, zero value otherwise +GetWorkspaceTemplateNameOk returns a tuple with the WorkspaceTemplateName field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetWorkspaceConfigName +### SetWorkspaceTemplateName -`func (o *CreateBuildDTO) SetWorkspaceConfigName(v string)` +`func (o *CreateBuildDTO) SetWorkspaceTemplateName(v string)` -SetWorkspaceConfigName sets WorkspaceConfigName field to given value. +SetWorkspaceTemplateName sets WorkspaceTemplateName field to given value. diff --git a/pkg/apiclient/docs/CreateWorkspaceConfigDTO.md b/pkg/apiclient/docs/CreateWorkspaceTemplateDTO.md similarity index 63% rename from pkg/apiclient/docs/CreateWorkspaceConfigDTO.md rename to pkg/apiclient/docs/CreateWorkspaceTemplateDTO.md index 09697612e0..4e29f37042 100644 --- a/pkg/apiclient/docs/CreateWorkspaceConfigDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceTemplateDTO.md @@ -1,4 +1,4 @@ -# CreateWorkspaceConfigDTO +# CreateWorkspaceTemplateDTO ## Properties @@ -14,180 +14,180 @@ Name | Type | Description | Notes ## Methods -### NewCreateWorkspaceConfigDTO +### NewCreateWorkspaceTemplateDTO -`func NewCreateWorkspaceConfigDTO(envVars map[string]string, name string, repositoryUrl string, ) *CreateWorkspaceConfigDTO` +`func NewCreateWorkspaceTemplateDTO(envVars map[string]string, name string, repositoryUrl string, ) *CreateWorkspaceTemplateDTO` -NewCreateWorkspaceConfigDTO instantiates a new CreateWorkspaceConfigDTO object +NewCreateWorkspaceTemplateDTO instantiates a new CreateWorkspaceTemplateDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewCreateWorkspaceConfigDTOWithDefaults +### NewCreateWorkspaceTemplateDTOWithDefaults -`func NewCreateWorkspaceConfigDTOWithDefaults() *CreateWorkspaceConfigDTO` +`func NewCreateWorkspaceTemplateDTOWithDefaults() *CreateWorkspaceTemplateDTO` -NewCreateWorkspaceConfigDTOWithDefaults instantiates a new CreateWorkspaceConfigDTO object +NewCreateWorkspaceTemplateDTOWithDefaults instantiates a new CreateWorkspaceTemplateDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *CreateWorkspaceConfigDTO) GetBuildConfig() BuildConfig` +`func (o *CreateWorkspaceTemplateDTO) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *CreateWorkspaceConfigDTO) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *CreateWorkspaceConfigDTO) SetBuildConfig(v BuildConfig)` +`func (o *CreateWorkspaceTemplateDTO) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *CreateWorkspaceConfigDTO) HasBuildConfig() bool` +`func (o *CreateWorkspaceTemplateDTO) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetEnvVars -`func (o *CreateWorkspaceConfigDTO) GetEnvVars() map[string]string` +`func (o *CreateWorkspaceTemplateDTO) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *CreateWorkspaceConfigDTO) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *CreateWorkspaceConfigDTO) SetEnvVars(v map[string]string)` +`func (o *CreateWorkspaceTemplateDTO) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigId() string` +`func (o *CreateWorkspaceTemplateDTO) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *CreateWorkspaceConfigDTO) SetGitProviderConfigId(v string)` +`func (o *CreateWorkspaceTemplateDTO) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *CreateWorkspaceConfigDTO) HasGitProviderConfigId() bool` +`func (o *CreateWorkspaceTemplateDTO) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetImage -`func (o *CreateWorkspaceConfigDTO) GetImage() string` +`func (o *CreateWorkspaceTemplateDTO) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *CreateWorkspaceConfigDTO) GetImageOk() (*string, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *CreateWorkspaceConfigDTO) SetImage(v string)` +`func (o *CreateWorkspaceTemplateDTO) SetImage(v string)` SetImage sets Image field to given value. ### HasImage -`func (o *CreateWorkspaceConfigDTO) HasImage() bool` +`func (o *CreateWorkspaceTemplateDTO) HasImage() bool` HasImage returns a boolean if a field has been set. ### GetName -`func (o *CreateWorkspaceConfigDTO) GetName() string` +`func (o *CreateWorkspaceTemplateDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *CreateWorkspaceConfigDTO) GetNameOk() (*string, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *CreateWorkspaceConfigDTO) SetName(v string)` +`func (o *CreateWorkspaceTemplateDTO) SetName(v string)` SetName sets Name field to given value. ### GetRepositoryUrl -`func (o *CreateWorkspaceConfigDTO) GetRepositoryUrl() string` +`func (o *CreateWorkspaceTemplateDTO) GetRepositoryUrl() string` GetRepositoryUrl returns the RepositoryUrl field if non-nil, zero value otherwise. ### GetRepositoryUrlOk -`func (o *CreateWorkspaceConfigDTO) GetRepositoryUrlOk() (*string, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetRepositoryUrlOk() (*string, bool)` GetRepositoryUrlOk returns a tuple with the RepositoryUrl field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepositoryUrl -`func (o *CreateWorkspaceConfigDTO) SetRepositoryUrl(v string)` +`func (o *CreateWorkspaceTemplateDTO) SetRepositoryUrl(v string)` SetRepositoryUrl sets RepositoryUrl field to given value. ### GetUser -`func (o *CreateWorkspaceConfigDTO) GetUser() string` +`func (o *CreateWorkspaceTemplateDTO) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *CreateWorkspaceConfigDTO) GetUserOk() (*string, bool)` +`func (o *CreateWorkspaceTemplateDTO) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *CreateWorkspaceConfigDTO) SetUser(v string)` +`func (o *CreateWorkspaceTemplateDTO) SetUser(v string)` SetUser sets User field to given value. ### HasUser -`func (o *CreateWorkspaceConfigDTO) HasUser() bool` +`func (o *CreateWorkspaceTemplateDTO) HasUser() bool` HasUser returns a boolean if a field has been set. diff --git a/pkg/apiclient/docs/PrebuildAPI.md b/pkg/apiclient/docs/PrebuildAPI.md index 04eef269ce..51c8eac206 100644 --- a/pkg/apiclient/docs/PrebuildAPI.md +++ b/pkg/apiclient/docs/PrebuildAPI.md @@ -4,18 +4,18 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**DeletePrebuild**](PrebuildAPI.md#DeletePrebuild) | **Delete** /workspace-config/{configName}/prebuild/{prebuildId} | Delete prebuild -[**GetPrebuild**](PrebuildAPI.md#GetPrebuild) | **Get** /workspace-config/{configName}/prebuild/{prebuildId} | Get prebuild -[**ListPrebuilds**](PrebuildAPI.md#ListPrebuilds) | **Get** /workspace-config/prebuild | List prebuilds -[**ListPrebuildsForWorkspaceConfig**](PrebuildAPI.md#ListPrebuildsForWorkspaceConfig) | **Get** /workspace-config/{configName}/prebuild | List prebuilds for workspace config -[**ProcessGitEvent**](PrebuildAPI.md#ProcessGitEvent) | **Post** /workspace-config/prebuild/process-git-event | ProcessGitEvent -[**SetPrebuild**](PrebuildAPI.md#SetPrebuild) | **Put** /workspace-config/{configName}/prebuild | Set prebuild +[**DeletePrebuild**](PrebuildAPI.md#DeletePrebuild) | **Delete** /workspace-template/{templateName}/prebuild/{prebuildId} | Delete prebuild +[**GetPrebuild**](PrebuildAPI.md#GetPrebuild) | **Get** /workspace-template/{templateName}/prebuild/{prebuildId} | Get prebuild +[**ListPrebuilds**](PrebuildAPI.md#ListPrebuilds) | **Get** /workspace-template/prebuild | List prebuilds +[**ListPrebuildsForWorkspaceTemplate**](PrebuildAPI.md#ListPrebuildsForWorkspaceTemplate) | **Get** /workspace-template/{templateName}/prebuild | List prebuilds for workspace template +[**ProcessGitEvent**](PrebuildAPI.md#ProcessGitEvent) | **Post** /workspace-template/prebuild/process-git-event | ProcessGitEvent +[**SetPrebuild**](PrebuildAPI.md#SetPrebuild) | **Put** /workspace-template/{templateName}/prebuild | Set prebuild ## DeletePrebuild -> DeletePrebuild(ctx, configName, prebuildId).Force(force).Execute() +> DeletePrebuild(ctx, templateName, prebuildId).Force(force).Execute() Delete prebuild @@ -34,13 +34,13 @@ import ( ) func main() { - configName := "configName_example" // string | Workspace config name + templateName := "templateName_example" // string | Workspace template name prebuildId := "prebuildId_example" // string | Prebuild ID force := true // bool | Force (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.PrebuildAPI.DeletePrebuild(context.Background(), configName, prebuildId).Force(force).Execute() + r, err := apiClient.PrebuildAPI.DeletePrebuild(context.Background(), templateName, prebuildId).Force(force).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.DeletePrebuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -54,7 +54,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Workspace config name | +**templateName** | **string** | Workspace template name | **prebuildId** | **string** | Prebuild ID | ### Other Parameters @@ -88,7 +88,7 @@ Name | Type | Description | Notes ## GetPrebuild -> PrebuildDTO GetPrebuild(ctx, configName, prebuildId).Execute() +> PrebuildDTO GetPrebuild(ctx, templateName, prebuildId).Execute() Get prebuild @@ -107,12 +107,12 @@ import ( ) func main() { - configName := "configName_example" // string | Workspace config name + templateName := "templateName_example" // string | Workspace template name prebuildId := "prebuildId_example" // string | Prebuild ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.PrebuildAPI.GetPrebuild(context.Background(), configName, prebuildId).Execute() + resp, r, err := apiClient.PrebuildAPI.GetPrebuild(context.Background(), templateName, prebuildId).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.GetPrebuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -128,7 +128,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Workspace config name | +**templateName** | **string** | Workspace template name | **prebuildId** | **string** | Prebuild ID | ### Other Parameters @@ -220,11 +220,11 @@ Other parameters are passed through a pointer to a apiListPrebuildsRequest struc [[Back to README]](../README.md) -## ListPrebuildsForWorkspaceConfig +## ListPrebuildsForWorkspaceTemplate -> []PrebuildDTO ListPrebuildsForWorkspaceConfig(ctx, configName).Execute() +> []PrebuildDTO ListPrebuildsForWorkspaceTemplate(ctx, templateName).Execute() -List prebuilds for workspace config +List prebuilds for workspace template @@ -241,17 +241,17 @@ import ( ) func main() { - configName := "configName_example" // string | Config name + templateName := "templateName_example" // string | Template name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(context.Background(), configName).Execute() + resp, r, err := apiClient.PrebuildAPI.ListPrebuildsForWorkspaceTemplate(context.Background(), templateName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.ListPrebuildsForWorkspaceConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.ListPrebuildsForWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListPrebuildsForWorkspaceConfig`: []PrebuildDTO - fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.ListPrebuildsForWorkspaceConfig`: %v\n", resp) + // response from `ListPrebuildsForWorkspaceTemplate`: []PrebuildDTO + fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.ListPrebuildsForWorkspaceTemplate`: %v\n", resp) } ``` @@ -261,11 +261,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Config name | +**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiListPrebuildsForWorkspaceConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListPrebuildsForWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -356,7 +356,7 @@ Name | Type | Description | Notes ## SetPrebuild -> string SetPrebuild(ctx, configName).Prebuild(prebuild).Execute() +> string SetPrebuild(ctx, templateName).Prebuild(prebuild).Execute() Set prebuild @@ -375,12 +375,12 @@ import ( ) func main() { - configName := "configName_example" // string | Config name + templateName := "templateName_example" // string | Template name prebuild := *openapiclient.NewCreatePrebuildDTO(int32(123)) // CreatePrebuildDTO | Prebuild configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.PrebuildAPI.SetPrebuild(context.Background(), configName).Prebuild(prebuild).Execute() + resp, r, err := apiClient.PrebuildAPI.SetPrebuild(context.Background(), templateName).Prebuild(prebuild).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.SetPrebuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -396,7 +396,7 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Config name | +**templateName** | **string** | Template name | ### Other Parameters diff --git a/pkg/apiclient/docs/PrebuildDTO.md b/pkg/apiclient/docs/PrebuildDTO.md index 649f5c2534..47e79879c2 100644 --- a/pkg/apiclient/docs/PrebuildDTO.md +++ b/pkg/apiclient/docs/PrebuildDTO.md @@ -9,13 +9,13 @@ Name | Type | Description | Notes **Id** | **string** | | **Retention** | **int32** | | **TriggerFiles** | Pointer to **[]string** | | [optional] -**WorkspaceConfigName** | **string** | | +**WorkspaceTemplateName** | **string** | | ## Methods ### NewPrebuildDTO -`func NewPrebuildDTO(branch string, id string, retention int32, workspaceConfigName string, ) *PrebuildDTO` +`func NewPrebuildDTO(branch string, id string, retention int32, workspaceTemplateName string, ) *PrebuildDTO` NewPrebuildDTO instantiates a new PrebuildDTO object This constructor will assign default values to properties that have it defined, @@ -140,24 +140,24 @@ SetTriggerFiles sets TriggerFiles field to given value. HasTriggerFiles returns a boolean if a field has been set. -### GetWorkspaceConfigName +### GetWorkspaceTemplateName -`func (o *PrebuildDTO) GetWorkspaceConfigName() string` +`func (o *PrebuildDTO) GetWorkspaceTemplateName() string` -GetWorkspaceConfigName returns the WorkspaceConfigName field if non-nil, zero value otherwise. +GetWorkspaceTemplateName returns the WorkspaceTemplateName field if non-nil, zero value otherwise. -### GetWorkspaceConfigNameOk +### GetWorkspaceTemplateNameOk -`func (o *PrebuildDTO) GetWorkspaceConfigNameOk() (*string, bool)` +`func (o *PrebuildDTO) GetWorkspaceTemplateNameOk() (*string, bool)` -GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field if it's non-nil, zero value otherwise +GetWorkspaceTemplateNameOk returns a tuple with the WorkspaceTemplateName field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetWorkspaceConfigName +### SetWorkspaceTemplateName -`func (o *PrebuildDTO) SetWorkspaceConfigName(v string)` +`func (o *PrebuildDTO) SetWorkspaceTemplateName(v string)` -SetWorkspaceConfigName sets WorkspaceConfigName field to given value. +SetWorkspaceTemplateName sets WorkspaceTemplateName field to given value. diff --git a/pkg/apiclient/docs/WorkspaceConfig.md b/pkg/apiclient/docs/WorkspaceTemplate.md similarity index 66% rename from pkg/apiclient/docs/WorkspaceConfig.md rename to pkg/apiclient/docs/WorkspaceTemplate.md index 69529b4181..d126fd661e 100644 --- a/pkg/apiclient/docs/WorkspaceConfig.md +++ b/pkg/apiclient/docs/WorkspaceTemplate.md @@ -1,4 +1,4 @@ -# WorkspaceConfig +# WorkspaceTemplate ## Properties @@ -16,214 +16,214 @@ Name | Type | Description | Notes ## Methods -### NewWorkspaceConfig +### NewWorkspaceTemplate -`func NewWorkspaceConfig(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string, ) *WorkspaceConfig` +`func NewWorkspaceTemplate(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string, ) *WorkspaceTemplate` -NewWorkspaceConfig instantiates a new WorkspaceConfig object +NewWorkspaceTemplate instantiates a new WorkspaceTemplate object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewWorkspaceConfigWithDefaults +### NewWorkspaceTemplateWithDefaults -`func NewWorkspaceConfigWithDefaults() *WorkspaceConfig` +`func NewWorkspaceTemplateWithDefaults() *WorkspaceTemplate` -NewWorkspaceConfigWithDefaults instantiates a new WorkspaceConfig object +NewWorkspaceTemplateWithDefaults instantiates a new WorkspaceTemplate object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *WorkspaceConfig) GetBuildConfig() BuildConfig` +`func (o *WorkspaceTemplate) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *WorkspaceConfig) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *WorkspaceTemplate) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *WorkspaceConfig) SetBuildConfig(v BuildConfig)` +`func (o *WorkspaceTemplate) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *WorkspaceConfig) HasBuildConfig() bool` +`func (o *WorkspaceTemplate) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetDefault -`func (o *WorkspaceConfig) GetDefault() bool` +`func (o *WorkspaceTemplate) GetDefault() bool` GetDefault returns the Default field if non-nil, zero value otherwise. ### GetDefaultOk -`func (o *WorkspaceConfig) GetDefaultOk() (*bool, bool)` +`func (o *WorkspaceTemplate) GetDefaultOk() (*bool, bool)` GetDefaultOk returns a tuple with the Default field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDefault -`func (o *WorkspaceConfig) SetDefault(v bool)` +`func (o *WorkspaceTemplate) SetDefault(v bool)` SetDefault sets Default field to given value. ### GetEnvVars -`func (o *WorkspaceConfig) GetEnvVars() map[string]string` +`func (o *WorkspaceTemplate) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *WorkspaceConfig) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *WorkspaceTemplate) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *WorkspaceConfig) SetEnvVars(v map[string]string)` +`func (o *WorkspaceTemplate) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetGitProviderConfigId -`func (o *WorkspaceConfig) GetGitProviderConfigId() string` +`func (o *WorkspaceTemplate) GetGitProviderConfigId() string` GetGitProviderConfigId returns the GitProviderConfigId field if non-nil, zero value otherwise. ### GetGitProviderConfigIdOk -`func (o *WorkspaceConfig) GetGitProviderConfigIdOk() (*string, bool)` +`func (o *WorkspaceTemplate) GetGitProviderConfigIdOk() (*string, bool)` GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitProviderConfigId -`func (o *WorkspaceConfig) SetGitProviderConfigId(v string)` +`func (o *WorkspaceTemplate) SetGitProviderConfigId(v string)` SetGitProviderConfigId sets GitProviderConfigId field to given value. ### HasGitProviderConfigId -`func (o *WorkspaceConfig) HasGitProviderConfigId() bool` +`func (o *WorkspaceTemplate) HasGitProviderConfigId() bool` HasGitProviderConfigId returns a boolean if a field has been set. ### GetImage -`func (o *WorkspaceConfig) GetImage() string` +`func (o *WorkspaceTemplate) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *WorkspaceConfig) GetImageOk() (*string, bool)` +`func (o *WorkspaceTemplate) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *WorkspaceConfig) SetImage(v string)` +`func (o *WorkspaceTemplate) SetImage(v string)` SetImage sets Image field to given value. ### GetName -`func (o *WorkspaceConfig) GetName() string` +`func (o *WorkspaceTemplate) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *WorkspaceConfig) GetNameOk() (*string, bool)` +`func (o *WorkspaceTemplate) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *WorkspaceConfig) SetName(v string)` +`func (o *WorkspaceTemplate) SetName(v string)` SetName sets Name field to given value. ### GetPrebuilds -`func (o *WorkspaceConfig) GetPrebuilds() []PrebuildConfig` +`func (o *WorkspaceTemplate) GetPrebuilds() []PrebuildConfig` GetPrebuilds returns the Prebuilds field if non-nil, zero value otherwise. ### GetPrebuildsOk -`func (o *WorkspaceConfig) GetPrebuildsOk() (*[]PrebuildConfig, bool)` +`func (o *WorkspaceTemplate) GetPrebuildsOk() (*[]PrebuildConfig, bool)` GetPrebuildsOk returns a tuple with the Prebuilds field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetPrebuilds -`func (o *WorkspaceConfig) SetPrebuilds(v []PrebuildConfig)` +`func (o *WorkspaceTemplate) SetPrebuilds(v []PrebuildConfig)` SetPrebuilds sets Prebuilds field to given value. ### HasPrebuilds -`func (o *WorkspaceConfig) HasPrebuilds() bool` +`func (o *WorkspaceTemplate) HasPrebuilds() bool` HasPrebuilds returns a boolean if a field has been set. ### GetRepositoryUrl -`func (o *WorkspaceConfig) GetRepositoryUrl() string` +`func (o *WorkspaceTemplate) GetRepositoryUrl() string` GetRepositoryUrl returns the RepositoryUrl field if non-nil, zero value otherwise. ### GetRepositoryUrlOk -`func (o *WorkspaceConfig) GetRepositoryUrlOk() (*string, bool)` +`func (o *WorkspaceTemplate) GetRepositoryUrlOk() (*string, bool)` GetRepositoryUrlOk returns a tuple with the RepositoryUrl field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepositoryUrl -`func (o *WorkspaceConfig) SetRepositoryUrl(v string)` +`func (o *WorkspaceTemplate) SetRepositoryUrl(v string)` SetRepositoryUrl sets RepositoryUrl field to given value. ### GetUser -`func (o *WorkspaceConfig) GetUser() string` +`func (o *WorkspaceTemplate) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *WorkspaceConfig) GetUserOk() (*string, bool)` +`func (o *WorkspaceTemplate) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *WorkspaceConfig) SetUser(v string)` +`func (o *WorkspaceTemplate) SetUser(v string)` SetUser sets User field to given value. diff --git a/pkg/apiclient/docs/WorkspaceConfigAPI.md b/pkg/apiclient/docs/WorkspaceTemplateAPI.md similarity index 58% rename from pkg/apiclient/docs/WorkspaceConfigAPI.md rename to pkg/apiclient/docs/WorkspaceTemplateAPI.md index 5b55822205..a3b70abf65 100644 --- a/pkg/apiclient/docs/WorkspaceConfigAPI.md +++ b/pkg/apiclient/docs/WorkspaceTemplateAPI.md @@ -1,23 +1,23 @@ -# \WorkspaceConfigAPI +# \WorkspaceTemplateAPI All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**DeleteWorkspaceConfig**](WorkspaceConfigAPI.md#DeleteWorkspaceConfig) | **Delete** /workspace-config/{configName} | Delete workspace config data -[**GetDefaultWorkspaceConfig**](WorkspaceConfigAPI.md#GetDefaultWorkspaceConfig) | **Get** /workspace-config/default/{gitUrl} | Get workspace configs by git url -[**GetWorkspaceConfig**](WorkspaceConfigAPI.md#GetWorkspaceConfig) | **Get** /workspace-config/{configName} | Get workspace config data -[**ListWorkspaceConfigs**](WorkspaceConfigAPI.md#ListWorkspaceConfigs) | **Get** /workspace-config | List workspace configs -[**SetDefaultWorkspaceConfig**](WorkspaceConfigAPI.md#SetDefaultWorkspaceConfig) | **Patch** /workspace-config/{configName}/set-default | Set workspace config to default -[**SetWorkspaceConfig**](WorkspaceConfigAPI.md#SetWorkspaceConfig) | **Put** /workspace-config | Set workspace config data +[**DeleteWorkspaceTemplate**](WorkspaceTemplateAPI.md#DeleteWorkspaceTemplate) | **Delete** /workspace-template/{templateName} | Delete workspace template data +[**GetDefaultWorkspaceTemplate**](WorkspaceTemplateAPI.md#GetDefaultWorkspaceTemplate) | **Get** /workspace-template/default/{gitUrl} | Get workspace templates by git url +[**GetWorkspaceTemplate**](WorkspaceTemplateAPI.md#GetWorkspaceTemplate) | **Get** /workspace-template/{templateName} | Get workspace template data +[**ListWorkspaceTemplates**](WorkspaceTemplateAPI.md#ListWorkspaceTemplates) | **Get** /workspace-template | List workspace templates +[**SetDefaultWorkspaceTemplate**](WorkspaceTemplateAPI.md#SetDefaultWorkspaceTemplate) | **Patch** /workspace-template/{templateName}/set-default | Set workspace template to default +[**SetWorkspaceTemplate**](WorkspaceTemplateAPI.md#SetWorkspaceTemplate) | **Put** /workspace-template | Set workspace template data -## DeleteWorkspaceConfig +## DeleteWorkspaceTemplate -> DeleteWorkspaceConfig(ctx, configName).Force(force).Execute() +> DeleteWorkspaceTemplate(ctx, templateName).Force(force).Execute() -Delete workspace config data +Delete workspace template data @@ -34,14 +34,14 @@ import ( ) func main() { - configName := "configName_example" // string | Config name + templateName := "templateName_example" // string | Template name force := true // bool | Force (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceConfigAPI.DeleteWorkspaceConfig(context.Background(), configName).Force(force).Execute() + r, err := apiClient.WorkspaceTemplateAPI.DeleteWorkspaceTemplate(context.Background(), templateName).Force(force).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.DeleteWorkspaceConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.DeleteWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -53,11 +53,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Config name | +**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiDeleteWorkspaceConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -83,11 +83,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetDefaultWorkspaceConfig +## GetDefaultWorkspaceTemplate -> WorkspaceConfig GetDefaultWorkspaceConfig(ctx, gitUrl).Execute() +> WorkspaceTemplate GetDefaultWorkspaceTemplate(ctx, gitUrl).Execute() -Get workspace configs by git url +Get workspace templates by git url @@ -108,13 +108,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(context.Background(), gitUrl).Execute() + resp, r, err := apiClient.WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate(context.Background(), gitUrl).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.GetDefaultWorkspaceConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetDefaultWorkspaceConfig`: WorkspaceConfig - fmt.Fprintf(os.Stdout, "Response from `WorkspaceConfigAPI.GetDefaultWorkspaceConfig`: %v\n", resp) + // response from `GetDefaultWorkspaceTemplate`: WorkspaceTemplate + fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate`: %v\n", resp) } ``` @@ -128,7 +128,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetDefaultWorkspaceConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetDefaultWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -137,7 +137,7 @@ Name | Type | Description | Notes ### Return type -[**WorkspaceConfig**](WorkspaceConfig.md) +[**WorkspaceTemplate**](WorkspaceTemplate.md) ### Authorization @@ -153,11 +153,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetWorkspaceConfig +## GetWorkspaceTemplate -> WorkspaceConfig GetWorkspaceConfig(ctx, configName).Execute() +> WorkspaceTemplate GetWorkspaceTemplate(ctx, templateName).Execute() -Get workspace config data +Get workspace template data @@ -174,17 +174,17 @@ import ( ) func main() { - configName := "configName_example" // string | Config name + templateName := "templateName_example" // string | Template name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(context.Background(), configName).Execute() + resp, r, err := apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(context.Background(), templateName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.GetWorkspaceConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.GetWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetWorkspaceConfig`: WorkspaceConfig - fmt.Fprintf(os.Stdout, "Response from `WorkspaceConfigAPI.GetWorkspaceConfig`: %v\n", resp) + // response from `GetWorkspaceTemplate`: WorkspaceTemplate + fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.GetWorkspaceTemplate`: %v\n", resp) } ``` @@ -194,11 +194,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Config name | +**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiGetWorkspaceConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -207,7 +207,7 @@ Name | Type | Description | Notes ### Return type -[**WorkspaceConfig**](WorkspaceConfig.md) +[**WorkspaceTemplate**](WorkspaceTemplate.md) ### Authorization @@ -223,11 +223,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## ListWorkspaceConfigs +## ListWorkspaceTemplates -> []WorkspaceConfig ListWorkspaceConfigs(ctx).Execute() +> []WorkspaceTemplate ListWorkspaceTemplates(ctx).Execute() -List workspace configs +List workspace templates @@ -247,13 +247,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() + resp, r, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.ListWorkspaceConfigs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.ListWorkspaceTemplates``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListWorkspaceConfigs`: []WorkspaceConfig - fmt.Fprintf(os.Stdout, "Response from `WorkspaceConfigAPI.ListWorkspaceConfigs`: %v\n", resp) + // response from `ListWorkspaceTemplates`: []WorkspaceTemplate + fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.ListWorkspaceTemplates`: %v\n", resp) } ``` @@ -263,12 +263,12 @@ This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiListWorkspaceConfigsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListWorkspaceTemplatesRequest struct via the builder pattern ### Return type -[**[]WorkspaceConfig**](WorkspaceConfig.md) +[**[]WorkspaceTemplate**](WorkspaceTemplate.md) ### Authorization @@ -284,11 +284,11 @@ Other parameters are passed through a pointer to a apiListWorkspaceConfigsReques [[Back to README]](../README.md) -## SetDefaultWorkspaceConfig +## SetDefaultWorkspaceTemplate -> SetDefaultWorkspaceConfig(ctx, configName).Execute() +> SetDefaultWorkspaceTemplate(ctx, templateName).Execute() -Set workspace config to default +Set workspace template to default @@ -305,13 +305,13 @@ import ( ) func main() { - configName := "configName_example" // string | Config name + templateName := "templateName_example" // string | Template name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceConfigAPI.SetDefaultWorkspaceConfig(context.Background(), configName).Execute() + r, err := apiClient.WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate(context.Background(), templateName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.SetDefaultWorkspaceConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -323,11 +323,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configName** | **string** | Config name | +**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiSetDefaultWorkspaceConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetDefaultWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -352,11 +352,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetWorkspaceConfig +## SetWorkspaceTemplate -> SetWorkspaceConfig(ctx).WorkspaceConfig(workspaceConfig).Execute() +> SetWorkspaceTemplate(ctx).WorkspaceTemplate(workspaceTemplate).Execute() -Set workspace config data +Set workspace template data @@ -373,13 +373,13 @@ import ( ) func main() { - workspaceConfig := *openapiclient.NewCreateWorkspaceConfigDTO(map[string]string{"key": "Inner_example"}, "Name_example", "RepositoryUrl_example") // CreateWorkspaceConfigDTO | Workspace config + workspaceTemplate := *openapiclient.NewCreateWorkspaceTemplateDTO(map[string]string{"key": "Inner_example"}, "Name_example", "RepositoryUrl_example") // CreateWorkspaceTemplateDTO | Workspace template configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(context.Background()).WorkspaceConfig(workspaceConfig).Execute() + r, err := apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(context.Background()).WorkspaceTemplate(workspaceTemplate).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceConfigAPI.SetWorkspaceConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.SetWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -391,12 +391,12 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiSetWorkspaceConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **workspaceConfig** | [**CreateWorkspaceConfigDTO**](CreateWorkspaceConfigDTO.md) | Workspace config | + **workspaceTemplate** | [**CreateWorkspaceTemplateDTO**](CreateWorkspaceTemplateDTO.md) | Workspace template | ### Return type diff --git a/pkg/apiclient/model_create_build_dto.go b/pkg/apiclient/model_create_build_dto.go index e855e4adc7..26a45a09b0 100644 --- a/pkg/apiclient/model_create_build_dto.go +++ b/pkg/apiclient/model_create_build_dto.go @@ -21,10 +21,10 @@ var _ MappedNullable = &CreateBuildDTO{} // CreateBuildDTO struct for CreateBuildDTO type CreateBuildDTO struct { - Branch string `json:"branch"` - EnvVars map[string]string `json:"envVars"` - PrebuildId *string `json:"prebuildId,omitempty"` - WorkspaceConfigName string `json:"workspaceConfigName"` + Branch string `json:"branch"` + EnvVars map[string]string `json:"envVars"` + PrebuildId *string `json:"prebuildId,omitempty"` + WorkspaceTemplateName string `json:"workspaceTemplateName"` } type _CreateBuildDTO CreateBuildDTO @@ -33,11 +33,11 @@ type _CreateBuildDTO CreateBuildDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateBuildDTO(branch string, envVars map[string]string, workspaceConfigName string) *CreateBuildDTO { +func NewCreateBuildDTO(branch string, envVars map[string]string, workspaceTemplateName string) *CreateBuildDTO { this := CreateBuildDTO{} this.Branch = branch this.EnvVars = envVars - this.WorkspaceConfigName = workspaceConfigName + this.WorkspaceTemplateName = workspaceTemplateName return &this } @@ -129,28 +129,28 @@ func (o *CreateBuildDTO) SetPrebuildId(v string) { o.PrebuildId = &v } -// GetWorkspaceConfigName returns the WorkspaceConfigName field value -func (o *CreateBuildDTO) GetWorkspaceConfigName() string { +// GetWorkspaceTemplateName returns the WorkspaceTemplateName field value +func (o *CreateBuildDTO) GetWorkspaceTemplateName() string { if o == nil { var ret string return ret } - return o.WorkspaceConfigName + return o.WorkspaceTemplateName } -// GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field value +// GetWorkspaceTemplateNameOk returns a tuple with the WorkspaceTemplateName field value // and a boolean to check if the value has been set. -func (o *CreateBuildDTO) GetWorkspaceConfigNameOk() (*string, bool) { +func (o *CreateBuildDTO) GetWorkspaceTemplateNameOk() (*string, bool) { if o == nil { return nil, false } - return &o.WorkspaceConfigName, true + return &o.WorkspaceTemplateName, true } -// SetWorkspaceConfigName sets field value -func (o *CreateBuildDTO) SetWorkspaceConfigName(v string) { - o.WorkspaceConfigName = v +// SetWorkspaceTemplateName sets field value +func (o *CreateBuildDTO) SetWorkspaceTemplateName(v string) { + o.WorkspaceTemplateName = v } func (o CreateBuildDTO) MarshalJSON() ([]byte, error) { @@ -168,7 +168,7 @@ func (o CreateBuildDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.PrebuildId) { toSerialize["prebuildId"] = o.PrebuildId } - toSerialize["workspaceConfigName"] = o.WorkspaceConfigName + toSerialize["workspaceTemplateName"] = o.WorkspaceTemplateName return toSerialize, nil } @@ -179,7 +179,7 @@ func (o *CreateBuildDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "branch", "envVars", - "workspaceConfigName", + "workspaceTemplateName", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_create_workspace_config_dto.go b/pkg/apiclient/model_create_workspace_template_dto.go similarity index 64% rename from pkg/apiclient/model_create_workspace_config_dto.go rename to pkg/apiclient/model_create_workspace_template_dto.go index 66d5daea1a..6ffeb9b780 100644 --- a/pkg/apiclient/model_create_workspace_config_dto.go +++ b/pkg/apiclient/model_create_workspace_template_dto.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the CreateWorkspaceConfigDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &CreateWorkspaceConfigDTO{} +// checks if the CreateWorkspaceTemplateDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateWorkspaceTemplateDTO{} -// CreateWorkspaceConfigDTO struct for CreateWorkspaceConfigDTO -type CreateWorkspaceConfigDTO struct { +// CreateWorkspaceTemplateDTO struct for CreateWorkspaceTemplateDTO +type CreateWorkspaceTemplateDTO struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` @@ -30,30 +30,30 @@ type CreateWorkspaceConfigDTO struct { User *string `json:"user,omitempty"` } -type _CreateWorkspaceConfigDTO CreateWorkspaceConfigDTO +type _CreateWorkspaceTemplateDTO CreateWorkspaceTemplateDTO -// NewCreateWorkspaceConfigDTO instantiates a new CreateWorkspaceConfigDTO object +// NewCreateWorkspaceTemplateDTO instantiates a new CreateWorkspaceTemplateDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateWorkspaceConfigDTO(envVars map[string]string, name string, repositoryUrl string) *CreateWorkspaceConfigDTO { - this := CreateWorkspaceConfigDTO{} +func NewCreateWorkspaceTemplateDTO(envVars map[string]string, name string, repositoryUrl string) *CreateWorkspaceTemplateDTO { + this := CreateWorkspaceTemplateDTO{} this.EnvVars = envVars this.Name = name this.RepositoryUrl = repositoryUrl return &this } -// NewCreateWorkspaceConfigDTOWithDefaults instantiates a new CreateWorkspaceConfigDTO object +// NewCreateWorkspaceTemplateDTOWithDefaults instantiates a new CreateWorkspaceTemplateDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewCreateWorkspaceConfigDTOWithDefaults() *CreateWorkspaceConfigDTO { - this := CreateWorkspaceConfigDTO{} +func NewCreateWorkspaceTemplateDTOWithDefaults() *CreateWorkspaceTemplateDTO { + this := CreateWorkspaceTemplateDTO{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *CreateWorkspaceConfigDTO) GetBuildConfig() BuildConfig { +func (o *CreateWorkspaceTemplateDTO) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -63,7 +63,7 @@ func (o *CreateWorkspaceConfigDTO) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *CreateWorkspaceTemplateDTO) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -71,7 +71,7 @@ func (o *CreateWorkspaceConfigDTO) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *CreateWorkspaceConfigDTO) HasBuildConfig() bool { +func (o *CreateWorkspaceTemplateDTO) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -80,12 +80,12 @@ func (o *CreateWorkspaceConfigDTO) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *CreateWorkspaceConfigDTO) SetBuildConfig(v BuildConfig) { +func (o *CreateWorkspaceTemplateDTO) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetEnvVars returns the EnvVars field value -func (o *CreateWorkspaceConfigDTO) GetEnvVars() map[string]string { +func (o *CreateWorkspaceTemplateDTO) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -96,7 +96,7 @@ func (o *CreateWorkspaceConfigDTO) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetEnvVarsOk() (*map[string]string, bool) { +func (o *CreateWorkspaceTemplateDTO) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -104,12 +104,12 @@ func (o *CreateWorkspaceConfigDTO) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *CreateWorkspaceConfigDTO) SetEnvVars(v map[string]string) { +func (o *CreateWorkspaceTemplateDTO) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigId() string { +func (o *CreateWorkspaceTemplateDTO) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -119,7 +119,7 @@ func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigIdOk() (*string, bool) { +func (o *CreateWorkspaceTemplateDTO) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -127,7 +127,7 @@ func (o *CreateWorkspaceConfigDTO) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *CreateWorkspaceConfigDTO) HasGitProviderConfigId() bool { +func (o *CreateWorkspaceTemplateDTO) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -136,12 +136,12 @@ func (o *CreateWorkspaceConfigDTO) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *CreateWorkspaceConfigDTO) SetGitProviderConfigId(v string) { +func (o *CreateWorkspaceTemplateDTO) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetImage returns the Image field value if set, zero value otherwise. -func (o *CreateWorkspaceConfigDTO) GetImage() string { +func (o *CreateWorkspaceTemplateDTO) GetImage() string { if o == nil || IsNil(o.Image) { var ret string return ret @@ -151,7 +151,7 @@ func (o *CreateWorkspaceConfigDTO) GetImage() string { // GetImageOk returns a tuple with the Image field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetImageOk() (*string, bool) { +func (o *CreateWorkspaceTemplateDTO) GetImageOk() (*string, bool) { if o == nil || IsNil(o.Image) { return nil, false } @@ -159,7 +159,7 @@ func (o *CreateWorkspaceConfigDTO) GetImageOk() (*string, bool) { } // HasImage returns a boolean if a field has been set. -func (o *CreateWorkspaceConfigDTO) HasImage() bool { +func (o *CreateWorkspaceTemplateDTO) HasImage() bool { if o != nil && !IsNil(o.Image) { return true } @@ -168,12 +168,12 @@ func (o *CreateWorkspaceConfigDTO) HasImage() bool { } // SetImage gets a reference to the given string and assigns it to the Image field. -func (o *CreateWorkspaceConfigDTO) SetImage(v string) { +func (o *CreateWorkspaceTemplateDTO) SetImage(v string) { o.Image = &v } // GetName returns the Name field value -func (o *CreateWorkspaceConfigDTO) GetName() string { +func (o *CreateWorkspaceTemplateDTO) GetName() string { if o == nil { var ret string return ret @@ -184,7 +184,7 @@ func (o *CreateWorkspaceConfigDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetNameOk() (*string, bool) { +func (o *CreateWorkspaceTemplateDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -192,12 +192,12 @@ func (o *CreateWorkspaceConfigDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *CreateWorkspaceConfigDTO) SetName(v string) { +func (o *CreateWorkspaceTemplateDTO) SetName(v string) { o.Name = v } // GetRepositoryUrl returns the RepositoryUrl field value -func (o *CreateWorkspaceConfigDTO) GetRepositoryUrl() string { +func (o *CreateWorkspaceTemplateDTO) GetRepositoryUrl() string { if o == nil { var ret string return ret @@ -208,7 +208,7 @@ func (o *CreateWorkspaceConfigDTO) GetRepositoryUrl() string { // GetRepositoryUrlOk returns a tuple with the RepositoryUrl field value // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetRepositoryUrlOk() (*string, bool) { +func (o *CreateWorkspaceTemplateDTO) GetRepositoryUrlOk() (*string, bool) { if o == nil { return nil, false } @@ -216,12 +216,12 @@ func (o *CreateWorkspaceConfigDTO) GetRepositoryUrlOk() (*string, bool) { } // SetRepositoryUrl sets field value -func (o *CreateWorkspaceConfigDTO) SetRepositoryUrl(v string) { +func (o *CreateWorkspaceTemplateDTO) SetRepositoryUrl(v string) { o.RepositoryUrl = v } // GetUser returns the User field value if set, zero value otherwise. -func (o *CreateWorkspaceConfigDTO) GetUser() string { +func (o *CreateWorkspaceTemplateDTO) GetUser() string { if o == nil || IsNil(o.User) { var ret string return ret @@ -231,7 +231,7 @@ func (o *CreateWorkspaceConfigDTO) GetUser() string { // GetUserOk returns a tuple with the User field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *CreateWorkspaceConfigDTO) GetUserOk() (*string, bool) { +func (o *CreateWorkspaceTemplateDTO) GetUserOk() (*string, bool) { if o == nil || IsNil(o.User) { return nil, false } @@ -239,7 +239,7 @@ func (o *CreateWorkspaceConfigDTO) GetUserOk() (*string, bool) { } // HasUser returns a boolean if a field has been set. -func (o *CreateWorkspaceConfigDTO) HasUser() bool { +func (o *CreateWorkspaceTemplateDTO) HasUser() bool { if o != nil && !IsNil(o.User) { return true } @@ -248,11 +248,11 @@ func (o *CreateWorkspaceConfigDTO) HasUser() bool { } // SetUser gets a reference to the given string and assigns it to the User field. -func (o *CreateWorkspaceConfigDTO) SetUser(v string) { +func (o *CreateWorkspaceTemplateDTO) SetUser(v string) { o.User = &v } -func (o CreateWorkspaceConfigDTO) MarshalJSON() ([]byte, error) { +func (o CreateWorkspaceTemplateDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -260,7 +260,7 @@ func (o CreateWorkspaceConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o CreateWorkspaceConfigDTO) ToMap() (map[string]interface{}, error) { +func (o CreateWorkspaceTemplateDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -280,7 +280,7 @@ func (o CreateWorkspaceConfigDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *CreateWorkspaceConfigDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateWorkspaceTemplateDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -304,53 +304,53 @@ func (o *CreateWorkspaceConfigDTO) UnmarshalJSON(data []byte) (err error) { } } - varCreateWorkspaceConfigDTO := _CreateWorkspaceConfigDTO{} + varCreateWorkspaceTemplateDTO := _CreateWorkspaceTemplateDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varCreateWorkspaceConfigDTO) + err = decoder.Decode(&varCreateWorkspaceTemplateDTO) if err != nil { return err } - *o = CreateWorkspaceConfigDTO(varCreateWorkspaceConfigDTO) + *o = CreateWorkspaceTemplateDTO(varCreateWorkspaceTemplateDTO) return err } -type NullableCreateWorkspaceConfigDTO struct { - value *CreateWorkspaceConfigDTO +type NullableCreateWorkspaceTemplateDTO struct { + value *CreateWorkspaceTemplateDTO isSet bool } -func (v NullableCreateWorkspaceConfigDTO) Get() *CreateWorkspaceConfigDTO { +func (v NullableCreateWorkspaceTemplateDTO) Get() *CreateWorkspaceTemplateDTO { return v.value } -func (v *NullableCreateWorkspaceConfigDTO) Set(val *CreateWorkspaceConfigDTO) { +func (v *NullableCreateWorkspaceTemplateDTO) Set(val *CreateWorkspaceTemplateDTO) { v.value = val v.isSet = true } -func (v NullableCreateWorkspaceConfigDTO) IsSet() bool { +func (v NullableCreateWorkspaceTemplateDTO) IsSet() bool { return v.isSet } -func (v *NullableCreateWorkspaceConfigDTO) Unset() { +func (v *NullableCreateWorkspaceTemplateDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableCreateWorkspaceConfigDTO(val *CreateWorkspaceConfigDTO) *NullableCreateWorkspaceConfigDTO { - return &NullableCreateWorkspaceConfigDTO{value: val, isSet: true} +func NewNullableCreateWorkspaceTemplateDTO(val *CreateWorkspaceTemplateDTO) *NullableCreateWorkspaceTemplateDTO { + return &NullableCreateWorkspaceTemplateDTO{value: val, isSet: true} } -func (v NullableCreateWorkspaceConfigDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateWorkspaceTemplateDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableCreateWorkspaceConfigDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateWorkspaceTemplateDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_prebuild_dto.go b/pkg/apiclient/model_prebuild_dto.go index 306a955fc6..8cf33c5c3b 100644 --- a/pkg/apiclient/model_prebuild_dto.go +++ b/pkg/apiclient/model_prebuild_dto.go @@ -21,12 +21,12 @@ var _ MappedNullable = &PrebuildDTO{} // PrebuildDTO struct for PrebuildDTO type PrebuildDTO struct { - Branch string `json:"branch"` - CommitInterval *int32 `json:"commitInterval,omitempty"` - Id string `json:"id"` - Retention int32 `json:"retention"` - TriggerFiles []string `json:"triggerFiles,omitempty"` - WorkspaceConfigName string `json:"workspaceConfigName"` + Branch string `json:"branch"` + CommitInterval *int32 `json:"commitInterval,omitempty"` + Id string `json:"id"` + Retention int32 `json:"retention"` + TriggerFiles []string `json:"triggerFiles,omitempty"` + WorkspaceTemplateName string `json:"workspaceTemplateName"` } type _PrebuildDTO PrebuildDTO @@ -35,12 +35,12 @@ type _PrebuildDTO PrebuildDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewPrebuildDTO(branch string, id string, retention int32, workspaceConfigName string) *PrebuildDTO { +func NewPrebuildDTO(branch string, id string, retention int32, workspaceTemplateName string) *PrebuildDTO { this := PrebuildDTO{} this.Branch = branch this.Id = id this.Retention = retention - this.WorkspaceConfigName = workspaceConfigName + this.WorkspaceTemplateName = workspaceTemplateName return &this } @@ -188,28 +188,28 @@ func (o *PrebuildDTO) SetTriggerFiles(v []string) { o.TriggerFiles = v } -// GetWorkspaceConfigName returns the WorkspaceConfigName field value -func (o *PrebuildDTO) GetWorkspaceConfigName() string { +// GetWorkspaceTemplateName returns the WorkspaceTemplateName field value +func (o *PrebuildDTO) GetWorkspaceTemplateName() string { if o == nil { var ret string return ret } - return o.WorkspaceConfigName + return o.WorkspaceTemplateName } -// GetWorkspaceConfigNameOk returns a tuple with the WorkspaceConfigName field value +// GetWorkspaceTemplateNameOk returns a tuple with the WorkspaceTemplateName field value // and a boolean to check if the value has been set. -func (o *PrebuildDTO) GetWorkspaceConfigNameOk() (*string, bool) { +func (o *PrebuildDTO) GetWorkspaceTemplateNameOk() (*string, bool) { if o == nil { return nil, false } - return &o.WorkspaceConfigName, true + return &o.WorkspaceTemplateName, true } -// SetWorkspaceConfigName sets field value -func (o *PrebuildDTO) SetWorkspaceConfigName(v string) { - o.WorkspaceConfigName = v +// SetWorkspaceTemplateName sets field value +func (o *PrebuildDTO) SetWorkspaceTemplateName(v string) { + o.WorkspaceTemplateName = v } func (o PrebuildDTO) MarshalJSON() ([]byte, error) { @@ -231,7 +231,7 @@ func (o PrebuildDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.TriggerFiles) { toSerialize["triggerFiles"] = o.TriggerFiles } - toSerialize["workspaceConfigName"] = o.WorkspaceConfigName + toSerialize["workspaceTemplateName"] = o.WorkspaceTemplateName return toSerialize, nil } @@ -243,7 +243,7 @@ func (o *PrebuildDTO) UnmarshalJSON(data []byte) (err error) { "branch", "id", "retention", - "workspaceConfigName", + "workspaceTemplateName", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_workspace_config.go b/pkg/apiclient/model_workspace_template.go similarity index 68% rename from pkg/apiclient/model_workspace_config.go rename to pkg/apiclient/model_workspace_template.go index 36ad409edc..4f3b19f28d 100644 --- a/pkg/apiclient/model_workspace_config.go +++ b/pkg/apiclient/model_workspace_template.go @@ -16,11 +16,11 @@ import ( "fmt" ) -// checks if the WorkspaceConfig type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &WorkspaceConfig{} +// checks if the WorkspaceTemplate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &WorkspaceTemplate{} -// WorkspaceConfig struct for WorkspaceConfig -type WorkspaceConfig struct { +// WorkspaceTemplate struct for WorkspaceTemplate +type WorkspaceTemplate struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` Default bool `json:"default"` EnvVars map[string]string `json:"envVars"` @@ -32,14 +32,14 @@ type WorkspaceConfig struct { User string `json:"user"` } -type _WorkspaceConfig WorkspaceConfig +type _WorkspaceTemplate WorkspaceTemplate -// NewWorkspaceConfig instantiates a new WorkspaceConfig object +// NewWorkspaceTemplate instantiates a new WorkspaceTemplate object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceConfig(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string) *WorkspaceConfig { - this := WorkspaceConfig{} +func NewWorkspaceTemplate(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string) *WorkspaceTemplate { + this := WorkspaceTemplate{} this.Default = default_ this.EnvVars = envVars this.Image = image @@ -49,16 +49,16 @@ func NewWorkspaceConfig(default_ bool, envVars map[string]string, image string, return &this } -// NewWorkspaceConfigWithDefaults instantiates a new WorkspaceConfig object +// NewWorkspaceTemplateWithDefaults instantiates a new WorkspaceTemplate object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewWorkspaceConfigWithDefaults() *WorkspaceConfig { - this := WorkspaceConfig{} +func NewWorkspaceTemplateWithDefaults() *WorkspaceTemplate { + this := WorkspaceTemplate{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *WorkspaceConfig) GetBuildConfig() BuildConfig { +func (o *WorkspaceTemplate) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -68,7 +68,7 @@ func (o *WorkspaceConfig) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *WorkspaceTemplate) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -76,7 +76,7 @@ func (o *WorkspaceConfig) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *WorkspaceConfig) HasBuildConfig() bool { +func (o *WorkspaceTemplate) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -85,12 +85,12 @@ func (o *WorkspaceConfig) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *WorkspaceConfig) SetBuildConfig(v BuildConfig) { +func (o *WorkspaceTemplate) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetDefault returns the Default field value -func (o *WorkspaceConfig) GetDefault() bool { +func (o *WorkspaceTemplate) GetDefault() bool { if o == nil { var ret bool return ret @@ -101,7 +101,7 @@ func (o *WorkspaceConfig) GetDefault() bool { // GetDefaultOk returns a tuple with the Default field value // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetDefaultOk() (*bool, bool) { +func (o *WorkspaceTemplate) GetDefaultOk() (*bool, bool) { if o == nil { return nil, false } @@ -109,12 +109,12 @@ func (o *WorkspaceConfig) GetDefaultOk() (*bool, bool) { } // SetDefault sets field value -func (o *WorkspaceConfig) SetDefault(v bool) { +func (o *WorkspaceTemplate) SetDefault(v bool) { o.Default = v } // GetEnvVars returns the EnvVars field value -func (o *WorkspaceConfig) GetEnvVars() map[string]string { +func (o *WorkspaceTemplate) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -125,7 +125,7 @@ func (o *WorkspaceConfig) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetEnvVarsOk() (*map[string]string, bool) { +func (o *WorkspaceTemplate) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -133,12 +133,12 @@ func (o *WorkspaceConfig) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *WorkspaceConfig) SetEnvVars(v map[string]string) { +func (o *WorkspaceTemplate) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetGitProviderConfigId returns the GitProviderConfigId field value if set, zero value otherwise. -func (o *WorkspaceConfig) GetGitProviderConfigId() string { +func (o *WorkspaceTemplate) GetGitProviderConfigId() string { if o == nil || IsNil(o.GitProviderConfigId) { var ret string return ret @@ -148,7 +148,7 @@ func (o *WorkspaceConfig) GetGitProviderConfigId() string { // GetGitProviderConfigIdOk returns a tuple with the GitProviderConfigId field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetGitProviderConfigIdOk() (*string, bool) { +func (o *WorkspaceTemplate) GetGitProviderConfigIdOk() (*string, bool) { if o == nil || IsNil(o.GitProviderConfigId) { return nil, false } @@ -156,7 +156,7 @@ func (o *WorkspaceConfig) GetGitProviderConfigIdOk() (*string, bool) { } // HasGitProviderConfigId returns a boolean if a field has been set. -func (o *WorkspaceConfig) HasGitProviderConfigId() bool { +func (o *WorkspaceTemplate) HasGitProviderConfigId() bool { if o != nil && !IsNil(o.GitProviderConfigId) { return true } @@ -165,12 +165,12 @@ func (o *WorkspaceConfig) HasGitProviderConfigId() bool { } // SetGitProviderConfigId gets a reference to the given string and assigns it to the GitProviderConfigId field. -func (o *WorkspaceConfig) SetGitProviderConfigId(v string) { +func (o *WorkspaceTemplate) SetGitProviderConfigId(v string) { o.GitProviderConfigId = &v } // GetImage returns the Image field value -func (o *WorkspaceConfig) GetImage() string { +func (o *WorkspaceTemplate) GetImage() string { if o == nil { var ret string return ret @@ -181,7 +181,7 @@ func (o *WorkspaceConfig) GetImage() string { // GetImageOk returns a tuple with the Image field value // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetImageOk() (*string, bool) { +func (o *WorkspaceTemplate) GetImageOk() (*string, bool) { if o == nil { return nil, false } @@ -189,12 +189,12 @@ func (o *WorkspaceConfig) GetImageOk() (*string, bool) { } // SetImage sets field value -func (o *WorkspaceConfig) SetImage(v string) { +func (o *WorkspaceTemplate) SetImage(v string) { o.Image = v } // GetName returns the Name field value -func (o *WorkspaceConfig) GetName() string { +func (o *WorkspaceTemplate) GetName() string { if o == nil { var ret string return ret @@ -205,7 +205,7 @@ func (o *WorkspaceConfig) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetNameOk() (*string, bool) { +func (o *WorkspaceTemplate) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -213,12 +213,12 @@ func (o *WorkspaceConfig) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *WorkspaceConfig) SetName(v string) { +func (o *WorkspaceTemplate) SetName(v string) { o.Name = v } // GetPrebuilds returns the Prebuilds field value if set, zero value otherwise. -func (o *WorkspaceConfig) GetPrebuilds() []PrebuildConfig { +func (o *WorkspaceTemplate) GetPrebuilds() []PrebuildConfig { if o == nil || IsNil(o.Prebuilds) { var ret []PrebuildConfig return ret @@ -228,7 +228,7 @@ func (o *WorkspaceConfig) GetPrebuilds() []PrebuildConfig { // GetPrebuildsOk returns a tuple with the Prebuilds field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetPrebuildsOk() ([]PrebuildConfig, bool) { +func (o *WorkspaceTemplate) GetPrebuildsOk() ([]PrebuildConfig, bool) { if o == nil || IsNil(o.Prebuilds) { return nil, false } @@ -236,7 +236,7 @@ func (o *WorkspaceConfig) GetPrebuildsOk() ([]PrebuildConfig, bool) { } // HasPrebuilds returns a boolean if a field has been set. -func (o *WorkspaceConfig) HasPrebuilds() bool { +func (o *WorkspaceTemplate) HasPrebuilds() bool { if o != nil && !IsNil(o.Prebuilds) { return true } @@ -245,12 +245,12 @@ func (o *WorkspaceConfig) HasPrebuilds() bool { } // SetPrebuilds gets a reference to the given []PrebuildConfig and assigns it to the Prebuilds field. -func (o *WorkspaceConfig) SetPrebuilds(v []PrebuildConfig) { +func (o *WorkspaceTemplate) SetPrebuilds(v []PrebuildConfig) { o.Prebuilds = v } // GetRepositoryUrl returns the RepositoryUrl field value -func (o *WorkspaceConfig) GetRepositoryUrl() string { +func (o *WorkspaceTemplate) GetRepositoryUrl() string { if o == nil { var ret string return ret @@ -261,7 +261,7 @@ func (o *WorkspaceConfig) GetRepositoryUrl() string { // GetRepositoryUrlOk returns a tuple with the RepositoryUrl field value // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetRepositoryUrlOk() (*string, bool) { +func (o *WorkspaceTemplate) GetRepositoryUrlOk() (*string, bool) { if o == nil { return nil, false } @@ -269,12 +269,12 @@ func (o *WorkspaceConfig) GetRepositoryUrlOk() (*string, bool) { } // SetRepositoryUrl sets field value -func (o *WorkspaceConfig) SetRepositoryUrl(v string) { +func (o *WorkspaceTemplate) SetRepositoryUrl(v string) { o.RepositoryUrl = v } // GetUser returns the User field value -func (o *WorkspaceConfig) GetUser() string { +func (o *WorkspaceTemplate) GetUser() string { if o == nil { var ret string return ret @@ -285,7 +285,7 @@ func (o *WorkspaceConfig) GetUser() string { // GetUserOk returns a tuple with the User field value // and a boolean to check if the value has been set. -func (o *WorkspaceConfig) GetUserOk() (*string, bool) { +func (o *WorkspaceTemplate) GetUserOk() (*string, bool) { if o == nil { return nil, false } @@ -293,11 +293,11 @@ func (o *WorkspaceConfig) GetUserOk() (*string, bool) { } // SetUser sets field value -func (o *WorkspaceConfig) SetUser(v string) { +func (o *WorkspaceTemplate) SetUser(v string) { o.User = v } -func (o WorkspaceConfig) MarshalJSON() ([]byte, error) { +func (o WorkspaceTemplate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -305,7 +305,7 @@ func (o WorkspaceConfig) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o WorkspaceConfig) ToMap() (map[string]interface{}, error) { +func (o WorkspaceTemplate) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -325,7 +325,7 @@ func (o WorkspaceConfig) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *WorkspaceConfig) UnmarshalJSON(data []byte) (err error) { +func (o *WorkspaceTemplate) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -352,53 +352,53 @@ func (o *WorkspaceConfig) UnmarshalJSON(data []byte) (err error) { } } - varWorkspaceConfig := _WorkspaceConfig{} + varWorkspaceTemplate := _WorkspaceTemplate{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspaceConfig) + err = decoder.Decode(&varWorkspaceTemplate) if err != nil { return err } - *o = WorkspaceConfig(varWorkspaceConfig) + *o = WorkspaceTemplate(varWorkspaceTemplate) return err } -type NullableWorkspaceConfig struct { - value *WorkspaceConfig +type NullableWorkspaceTemplate struct { + value *WorkspaceTemplate isSet bool } -func (v NullableWorkspaceConfig) Get() *WorkspaceConfig { +func (v NullableWorkspaceTemplate) Get() *WorkspaceTemplate { return v.value } -func (v *NullableWorkspaceConfig) Set(val *WorkspaceConfig) { +func (v *NullableWorkspaceTemplate) Set(val *WorkspaceTemplate) { v.value = val v.isSet = true } -func (v NullableWorkspaceConfig) IsSet() bool { +func (v NullableWorkspaceTemplate) IsSet() bool { return v.isSet } -func (v *NullableWorkspaceConfig) Unset() { +func (v *NullableWorkspaceTemplate) Unset() { v.value = nil v.isSet = false } -func NewNullableWorkspaceConfig(val *WorkspaceConfig) *NullableWorkspaceConfig { - return &NullableWorkspaceConfig{value: val, isSet: true} +func NewNullableWorkspaceTemplate(val *WorkspaceTemplate) *NullableWorkspaceTemplate { + return &NullableWorkspaceTemplate{value: val, isSet: true} } -func (v NullableWorkspaceConfig) MarshalJSON() ([]byte, error) { +func (v NullableWorkspaceTemplate) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableWorkspaceConfig) UnmarshalJSON(src []byte) error { +func (v *NullableWorkspaceTemplate) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index a9be310565..8489c12631 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -20,11 +20,11 @@ import ( var buildRunCmd = &cobra.Command{ Use: "run", - Short: "Run a build from a workspace config", + Short: "Run a build from a workspace template", Aliases: []string{"create"}, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - var workspaceConfig *apiclient.WorkspaceConfig + var workspaceTemplate *apiclient.WorkspaceTemplate ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -32,21 +32,21 @@ var buildRunCmd = &cobra.Command{ return err } - workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceTemplateList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "Build") - if workspaceConfig == nil { + workspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceTemplateList, 0, false, false, "Build") + if workspaceTemplate == nil { return nil } - if workspaceConfig.BuildConfig == nil { - return errors.New("The chosen workspace config does not have a build configuration") + if workspaceTemplate.BuildConfig == nil { + return errors.New("The chosen workspace template does not have a build configuration") } - chosenBranch, err := create.GetBranchFromWorkspaceConfig(ctx, workspaceConfig, apiClient, 0) + chosenBranch, err := create.GetBranchFromWorkspaceTemplate(ctx, workspaceTemplate, apiClient, 0) if err != nil { return err } @@ -56,7 +56,7 @@ var buildRunCmd = &cobra.Command{ return nil } - buildId, err := CreateBuild(apiClient, workspaceConfig, chosenBranch.Name, nil) + buildId, err := CreateBuild(apiClient, workspaceTemplate, chosenBranch.Name, nil) if err != nil { return err } @@ -66,7 +66,7 @@ var buildRunCmd = &cobra.Command{ }, } -func CreateBuild(apiClient *apiclient.APIClient, workspaceConfig *apiclient.WorkspaceConfig, branch string, prebuildId *string) (string, error) { +func CreateBuild(apiClient *apiclient.APIClient, workspaceTemplate *apiclient.WorkspaceTemplate, branch string, prebuildId *string) (string, error) { ctx := context.Background() envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() @@ -74,20 +74,20 @@ func CreateBuild(apiClient *apiclient.APIClient, workspaceConfig *apiclient.Work return "", apiclient_util.HandleErrorResponse(res, err) } - if workspaceConfig.BuildConfig == nil { - return "", errors.New("the chosen workspace config does not have a build configuration") + if workspaceTemplate.BuildConfig == nil { + return "", errors.New("the chosen workspace template does not have a build configuration") } createBuildDto := apiclient.CreateBuildDTO{ - WorkspaceConfigName: workspaceConfig.Name, - Branch: branch, - PrebuildId: prebuildId, + WorkspaceTemplateName: workspaceTemplate.Name, + Branch: branch, + PrebuildId: prebuildId, } if envVars != nil { - createBuildDto.EnvVars = util.MergeEnvVars(conversion.ToEnvVarsMap(envVars), workspaceConfig.EnvVars) + createBuildDto.EnvVars = util.MergeEnvVars(conversion.ToEnvVarsMap(envVars), workspaceTemplate.EnvVars) } else { - createBuildDto.EnvVars = util.MergeEnvVars(workspaceConfig.EnvVars) + createBuildDto.EnvVars = util.MergeEnvVars(workspaceTemplate.EnvVars) } buildId, res, err := apiClient.BuildAPI.CreateBuild(ctx).CreateBuildDto(createBuildDto).Execute() diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 954b9c9132..bcbb5fd13a 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -30,7 +30,7 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/telemetry" . "github.com/daytonaio/daytona/pkg/cmd/workspace" . "github.com/daytonaio/daytona/pkg/cmd/workspace/create" - . "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" + . "github.com/daytonaio/daytona/pkg/cmd/workspacetemplate" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/telemetry" @@ -60,7 +60,7 @@ func Execute() error { rootCmd.AddCommand(SshProxyCmd) rootCmd.AddCommand(CreateCmd) rootCmd.AddCommand(DeleteCmd) - rootCmd.AddCommand(WorkspaceConfigCmd) + rootCmd.AddCommand(WorkspaceTemplateCmd) rootCmd.AddCommand(ServeCmd) rootCmd.AddCommand(DaemonServeCmd) rootCmd.AddCommand(ServerCmd) diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/add.go index 1ac47caecf..a090d6bda2 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/add.go @@ -14,7 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" - "github.com/daytonaio/daytona/pkg/cmd/workspaceconfig" + "github.com/daytonaio/daytona/pkg/cmd/workspacetemplate" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/prebuild/add" "github.com/daytonaio/daytona/pkg/views/selection" @@ -28,7 +28,7 @@ var prebuildAddCmd = &cobra.Command{ Aliases: []string{"new", "create"}, RunE: func(cmd *cobra.Command, args []string) error { var prebuildAddView add.PrebuildAddView - var workspaceConfig *apiclient.WorkspaceConfig + var workspaceTemplate *apiclient.WorkspaceTemplate ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -50,32 +50,32 @@ var prebuildAddCmd = &cobra.Command{ commitIntervalFlag == 0 && triggerFilesFlag == nil { // Interactive CLI logic - workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceTemplateList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, true, "Prebuild") - if workspaceConfig == nil { - return errors.New("No workspace config selected") + workspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceTemplateList, 0, false, true, "Prebuild") + if workspaceTemplate == nil { + return errors.New("No workspace template selected") } - if workspaceConfig.Name == selection.NewWorkspaceConfigIdentifier { - workspaceConfig, err = workspaceconfig.RunWorkspaceConfigAddFlow(apiClient, gitProviders, ctx) + if workspaceTemplate.Name == selection.NewWorkspaceTemplateIdentifier { + workspaceTemplate, err = workspacetemplate.RunWorkspaceTemplateAddFlow(apiClient, gitProviders, ctx) if err != nil { return err } - if workspaceConfig == nil { + if workspaceTemplate == nil { return nil } } - prebuildAddView.WorkspaceConfigName = workspaceConfig.Name - if workspaceConfig.BuildConfig == nil { - return errors.New("The chosen workspace config does not have a build configuration") + prebuildAddView.WorkspaceTemplateName = workspaceTemplate.Name + if workspaceTemplate.BuildConfig == nil { + return errors.New("The chosen workspace template does not have a build configuration") } - chosenBranch, err := create.GetBranchFromWorkspaceConfig(ctx, workspaceConfig, apiClient, 0) + chosenBranch, err := create.GetBranchFromWorkspaceTemplate(ctx, workspaceTemplate, apiClient, 0) if err != nil { return err } @@ -90,22 +90,22 @@ var prebuildAddCmd = &cobra.Command{ } else { // Non-interactive mode: use provided arguments and flags if len(args) > 0 { - prebuildAddView.WorkspaceConfigName = args[0] + prebuildAddView.WorkspaceTemplateName = args[0] - // Fetch the workspace configuration based on the provided argument - workspaceConfigTemp, res, err := apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, prebuildAddView.WorkspaceConfigName).Execute() + // Fetch the workspace template based on the provided argument + workspaceTemplateTemp, res, err := apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, prebuildAddView.WorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if workspaceConfigTemp == nil { - return errors.New("Invalid workspace config specified") + if workspaceTemplateTemp == nil { + return errors.New("Invalid workspace template specified") } - prebuildAddView.WorkspaceConfigName = workspaceConfigTemp.Name - workspaceConfig = workspaceConfigTemp + prebuildAddView.WorkspaceTemplateName = workspaceTemplateTemp.Name + workspaceTemplate = workspaceTemplateTemp } else { - return errors.New("Workspace config must be specified when using flags") + return errors.New("Workspace template must be specified when using flags") } // Validate and handle required flags @@ -157,7 +157,7 @@ var prebuildAddCmd = &cobra.Command{ newPrebuild.TriggerFiles = prebuildAddView.TriggerFiles } - prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceConfigName).Prebuild(newPrebuild).Execute() + prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceTemplateName).Prebuild(newPrebuild).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -165,7 +165,7 @@ var prebuildAddCmd = &cobra.Command{ views.RenderInfoMessage("Prebuild added successfully") if prebuildAddView.RunBuildOnAdd { - buildId, err := build.CreateBuild(apiClient, workspaceConfig, prebuildAddView.Branch, &prebuildId) + buildId, err := build.CreateBuild(apiClient, workspaceTemplate, prebuildAddView.Branch, &prebuildId) if err != nil { return err } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index e51be1a8e1..ab098c6c15 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -25,7 +25,7 @@ var prebuildDeleteCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var selectedPrebuild *apiclient.PrebuildDTO var selectedPrebuildId string - var selectedWorkspaceConfigName string + var selectedWorkspaceTemplateName string apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { @@ -37,8 +37,8 @@ var prebuildDeleteCmd = &cobra.Command{ var res *http.Response if len(args) == 1 { - selectedWorkspaceConfigName = args[0] - prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Execute() + selectedWorkspaceTemplateName = args[0] + prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceTemplate(context.Background(), selectedWorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -59,13 +59,13 @@ var prebuildDeleteCmd = &cobra.Command{ return nil } selectedPrebuildId = selectedPrebuild.Id - selectedWorkspaceConfigName = selectedPrebuild.WorkspaceConfigName + selectedWorkspaceTemplateName = selectedPrebuild.WorkspaceTemplateName } else { - selectedWorkspaceConfigName = args[0] + selectedWorkspaceTemplateName = args[0] selectedPrebuildId = args[1] } - res, err := apiClient.PrebuildAPI.DeletePrebuild(context.Background(), selectedWorkspaceConfigName, selectedPrebuildId).Force(forceFlag).Execute() + res, err := apiClient.PrebuildAPI.DeletePrebuild(context.Background(), selectedWorkspaceTemplateName, selectedPrebuildId).Force(forceFlag).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index 874a61bc6c..708a47e259 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -33,11 +33,11 @@ var prebuildInfoCmd = &cobra.Command{ if len(args) < 2 { var prebuilds []apiclient.PrebuildDTO - var selectedWorkspaceConfigName string + var selectedWorkspaceTemplateName string if len(args) == 1 { - selectedWorkspaceConfigName = args[0] - prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Execute() + selectedWorkspaceTemplateName = args[0] + prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceTemplate(context.Background(), selectedWorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index 1358f62533..a85e3465ca 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -26,7 +26,7 @@ var prebuildUpdateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var prebuildAddView add.PrebuildAddView var prebuild *apiclient.PrebuildDTO - var workspaceConfigRecieved string + var workspaceTemplateRecieved string var retention int ctx := context.Background() @@ -50,13 +50,13 @@ var prebuildUpdateCmd = &cobra.Command{ if len(args) == 2 || (branchFlag != "" || retentionFlag != 0 || commitIntervalFlag != 0 || len(triggerFilesFlag) > 0) { // Non-interactive mode: use provided arguments and flags if len(args) < 2 { - return errors.New("Both workspace config name and prebuild ID must be specified when using flags") + return errors.New("Both workspace template name and prebuild ID must be specified when using flags") } - workspaceConfigRecieved = args[0] + workspaceTemplateRecieved = args[0] prebuildID := args[1] - prebuild, res, err = apiClient.PrebuildAPI.GetPrebuild(ctx, workspaceConfigRecieved, prebuildID).Execute() + prebuild, res, err = apiClient.PrebuildAPI.GetPrebuild(ctx, workspaceTemplateRecieved, prebuildID).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -79,18 +79,18 @@ var prebuildUpdateCmd = &cobra.Command{ } prebuildAddView.Branch = prebuild.Branch prebuildAddView.Retention = strconv.Itoa(int(prebuild.Retention)) - prebuildAddView.WorkspaceConfigName = workspaceConfigRecieved + prebuildAddView.WorkspaceTemplateName = workspaceTemplateRecieved prebuildAddView.TriggerFiles = prebuild.TriggerFiles prebuildAddView.CommitInterval = strconv.Itoa(int(*prebuild.CommitInterval)) retention = int(prebuild.Retention) } else { // Interactive mode: Prompt for details var prebuilds []apiclient.PrebuildDTO - var selectedWorkspaceConfigName string + var selectedWorkspaceTemplateName string if len(args) == 1 { - selectedWorkspaceConfigName = args[0] - prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceConfig(ctx, selectedWorkspaceConfigName).Execute() + selectedWorkspaceTemplateName = args[0] + prebuilds, res, err = apiClient.PrebuildAPI.ListPrebuildsForWorkspaceTemplate(ctx, selectedWorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -111,11 +111,11 @@ var prebuildUpdateCmd = &cobra.Command{ return nil } - workspaceConfigRecieved = prebuild.WorkspaceConfigName + workspaceTemplateRecieved = prebuild.WorkspaceTemplateName prebuildAddView = add.PrebuildAddView{ - Branch: prebuild.Branch, - Retention: strconv.Itoa(int(prebuild.Retention)), - WorkspaceConfigName: workspaceConfigRecieved, + Branch: prebuild.Branch, + Retention: strconv.Itoa(int(prebuild.Retention)), + WorkspaceTemplateName: workspaceTemplateRecieved, } retention, err = strconv.Atoi(prebuildAddView.Retention) if err != nil { @@ -155,7 +155,7 @@ var prebuildUpdateCmd = &cobra.Command{ newPrebuild.TriggerFiles = prebuildAddView.TriggerFiles } - prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceConfigName).Prebuild(newPrebuild).Execute() + prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceTemplateName).Prebuild(newPrebuild).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -163,12 +163,12 @@ var prebuildUpdateCmd = &cobra.Command{ views.RenderInfoMessage("Prebuild updated successfully") if prebuildAddView.RunBuildOnAdd { - workspaceConfig, res, err := apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, prebuildAddView.WorkspaceConfigName).Execute() + workspaceTemplate, res, err := apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, prebuildAddView.WorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - buildId, err := build.CreateBuild(apiClient, workspaceConfig, *newPrebuild.Branch, &prebuildId) + buildId, err := build.CreateBuild(apiClient, workspaceTemplate, *newPrebuild.Branch, &prebuildId) if err != nil { return err } diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index 2715b1dad8..d82ec5eb20 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -31,8 +31,8 @@ import ( "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" "github.com/daytonaio/daytona/pkg/server/workspaces" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" @@ -70,7 +70,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - workspaceConfigStore, err := db.NewWorkspaceConfigStore(dbConnection) + workspaceTemplateStore, err := db.NewWorkspaceTemplateStore(dbConnection) if err != nil { return nil, err } @@ -128,8 +128,8 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ ConfigStore: gitProviderConfigStore, - DetachWorkspaceConfigs: func(ctx context.Context, gitProviderConfigId string) error { - workspaceConfigs, err := workspaceConfigStore.List(&stores.WorkspaceConfigFilter{ + DetachWorkspaceTemplates: func(ctx context.Context, gitProviderConfigId string) error { + workspaceTemplates, err := workspaceTemplateStore.List(&stores.WorkspaceTemplateFilter{ GitProviderConfigId: &gitProviderConfigId, }) @@ -137,9 +137,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return err } - for _, workspaceConfig := range workspaceConfigs { - workspaceConfig.GitProviderConfigId = nil - err = workspaceConfigStore.Save(workspaceConfig) + for _, workspaceTemplate := range workspaceTemplates { + workspaceTemplate.GitProviderConfigId = nil + err = workspaceTemplateStore.Save(workspaceTemplate) if err != nil { return err } @@ -151,8 +151,8 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe buildService := builds.NewBuildService(builds.BuildServiceConfig{ BuildStore: buildStore, - FindWorkspaceConfig: func(ctx context.Context, name string) (*models.WorkspaceConfig, error) { - return workspaceConfigStore.Find(&stores.WorkspaceConfigFilter{ + FindWorkspaceTemplate: func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) { + return workspaceTemplateStore.Find(&stores.WorkspaceTemplateFilter{ Name: &name, }) }, @@ -173,9 +173,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) - workspaceConfigService := workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ + workspaceTemplateService := workspacetemplates.NewWorkspaceTemplateService(workspacetemplates.WorkspaceTemplateServiceConfig{ PrebuildWebhookEndpoint: prebuildWebhookEndpoint, - ConfigStore: workspaceConfigStore, + ConfigStore: workspaceTemplateStore, FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { return buildService.Find(&stores.BuildFilter{ PrebuildIds: &[]string{prebuildId}, @@ -187,12 +187,12 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe States: &[]models.BuildState{models.BuildStatePublished}, }) }, - CreateBuild: func(ctx context.Context, workspaceConfig *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error { + CreateBuild: func(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error { createBuildDto := services.CreateBuildDTO{ - WorkspaceConfigName: workspaceConfig.Name, - Branch: repo.Branch, - PrebuildId: &prebuildId, - EnvVars: workspaceConfig.EnvVars, + WorkspaceTemplateName: workspaceTemplate.Name, + Branch: repo.Branch, + PrebuildId: &prebuildId, + EnvVars: workspaceTemplate.EnvVars, } _, err := buildService.Create(createBuildDto) @@ -240,7 +240,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }, }) - err = workspaceConfigService.StartRetentionPoller() + err = workspaceTemplateService.StartRetentionPoller() if err != nil { return nil, err } @@ -397,7 +397,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe TargetConfigService: targetConfigService, ContainerRegistryService: containerRegistryService, BuildService: buildService, - WorkspaceConfigService: workspaceConfigService, + WorkspaceTemplateService: workspaceTemplateService, WorkspaceService: workspaceService, LocalContainerRegistry: localContainerRegistry, ApiKeyService: apiKeyService, diff --git a/pkg/cmd/workspace/create/add_from_config.go b/pkg/cmd/workspace/create/add_from_config.go deleted file mode 100644 index f742e03b38..0000000000 --- a/pkg/cmd/workspace/create/add_from_config.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package create - -import ( - "context" - - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/common" -) - -type AddWorkspaceFromConfigParams struct { - WorkspaceConfig *apiclient.WorkspaceConfig - ApiClient *apiclient.APIClient - Workspaces *[]apiclient.CreateWorkspaceDTO - BranchFlag *string -} - -func AddWorkspaceFromConfig(ctx context.Context, params AddWorkspaceFromConfigParams) (*string, error) { - chosenBranchName := "" - if params.BranchFlag != nil { - chosenBranchName = *params.BranchFlag - } - - if chosenBranchName == "" { - chosenBranch, err := GetBranchFromWorkspaceConfig(ctx, params.WorkspaceConfig, params.ApiClient, 0) - if err != nil { - return nil, err - } - if chosenBranch == nil { - return nil, common.ErrCtrlCAbort - } - - chosenBranchName = chosenBranch.Name - } - - configRepo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: params.WorkspaceConfig.RepositoryUrl, - Branch: &chosenBranchName, - }).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - workspace := &apiclient.CreateWorkspaceDTO{ - Name: params.WorkspaceConfig.Name, - GitProviderConfigId: params.WorkspaceConfig.GitProviderConfigId, - Source: apiclient.CreateWorkspaceSourceDTO{ - Repository: *configRepo, - }, - BuildConfig: params.WorkspaceConfig.BuildConfig, - Image: ¶ms.WorkspaceConfig.Image, - User: ¶ms.WorkspaceConfig.User, - EnvVars: params.WorkspaceConfig.EnvVars, - } - *params.Workspaces = append(*params.Workspaces, *workspace) - - return ¶ms.WorkspaceConfig.Name, nil -} diff --git a/pkg/cmd/workspace/create/add_from_template.go b/pkg/cmd/workspace/create/add_from_template.go new file mode 100644 index 0000000000..d02fc0e053 --- /dev/null +++ b/pkg/cmd/workspace/create/add_from_template.go @@ -0,0 +1,61 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package create + +import ( + "context" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/common" +) + +type AddWorkspaceFromTemplateParams struct { + WorkspaceTemplate *apiclient.WorkspaceTemplate + ApiClient *apiclient.APIClient + Workspaces *[]apiclient.CreateWorkspaceDTO + BranchFlag *string +} + +func AddWorkspaceFromTemplate(ctx context.Context, params AddWorkspaceFromTemplateParams) (*string, error) { + chosenBranchName := "" + if params.BranchFlag != nil { + chosenBranchName = *params.BranchFlag + } + + if chosenBranchName == "" { + chosenBranch, err := GetBranchFromWorkspaceTemplate(ctx, params.WorkspaceTemplate, params.ApiClient, 0) + if err != nil { + return nil, err + } + if chosenBranch == nil { + return nil, common.ErrCtrlCAbort + } + + chosenBranchName = chosenBranch.Name + } + + templateRepo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ + Url: params.WorkspaceTemplate.RepositoryUrl, + Branch: &chosenBranchName, + }).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + workspace := &apiclient.CreateWorkspaceDTO{ + Name: params.WorkspaceTemplate.Name, + GitProviderConfigId: params.WorkspaceTemplate.GitProviderConfigId, + Source: apiclient.CreateWorkspaceSourceDTO{ + Repository: *templateRepo, + }, + BuildConfig: params.WorkspaceTemplate.BuildConfig, + Image: ¶ms.WorkspaceTemplate.Image, + User: ¶ms.WorkspaceTemplate.User, + EnvVars: params.WorkspaceTemplate.EnvVars, + } + *params.Workspaces = append(*params.Workspaces, *workspace) + + return ¶ms.WorkspaceTemplate.Name, nil +} diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index fba06b829b..e12007035a 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -39,7 +39,7 @@ var CreateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var createWorkspaceDtos []apiclient.CreateWorkspaceDTO - var existingWorkspaceConfigNames []string + var existingWorkspaceTemplateNames []string var targetId string promptUsingTUI := len(args) == 0 @@ -106,7 +106,7 @@ var CreateCmd = &cobra.Command{ } } } else { - existingWorkspaceConfigNames, err = ProcessCmdArguments(ctx, ProcessCmdArgumentsParams{ + existingWorkspaceTemplateNames, err = ProcessCmdArguments(ctx, ProcessCmdArgumentsParams{ ApiClient: apiClient, RepoUrls: args, CreateWorkspaceDtos: &createWorkspaceDtos, @@ -133,16 +133,6 @@ var CreateCmd = &cobra.Command{ logs_view.SetupLongestPrefixLength(names) - for i, workspaceConfigName := range existingWorkspaceConfigNames { - if workspaceConfigName == "" { - continue - } - logs_view.DisplayLogEntry(logs.LogEntry{ - WorkspaceName: &createWorkspaceDtos[i].Name, - Msg: fmt.Sprintf("Using detected workspace config '%s'\n", workspaceConfigName), - }, i) - } - requestLogEntry := logs.LogEntry{ Msg: views.GetPrettyLogLine("Request submitted"), } @@ -155,6 +145,16 @@ var CreateCmd = &cobra.Command{ logs_view.DisplayLogEntry(requestLogEntry, logs_view.STATIC_INDEX) + for i, workspaceTemplateName := range existingWorkspaceTemplateNames { + if workspaceTemplateName == "" { + continue + } + logs_view.DisplayLogEntry(logs.LogEntry{ + WorkspaceName: &createWorkspaceDtos[i].Name, + Msg: fmt.Sprintf("Using detected workspace template '%s'\n", workspaceTemplateName), + }, i) + } + activeProfile, err = c.GetActiveProfile() if err != nil { return err @@ -319,7 +319,7 @@ func init() { CreateCmd.Flags().StringVarP(&IdeFlag, "ide", "i", "", fmt.Sprintf("Specify the IDE (%s)", ideListStr)) CreateCmd.Flags().StringVarP(&targetNameFlag, "target", "t", "", "Specify the target (e.g. 'local')") - CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank workspace without using existing configurations") + CreateCmd.Flags().BoolVar(&blankFlag, "blank", false, "Create a blank workspace without using existing templates") CreateCmd.Flags().BoolVarP(&noIdeFlag, "no-ide", "n", false, "Do not open the target in the IDE after target creation") CreateCmd.Flags().BoolVar(&multiWorkspaceFlag, "multi-workspace", false, "Target with multiple workspaces/repos") CreateCmd.Flags().BoolVarP(&YesFlag, "yes", "y", false, "Automatically confirm any prompts") diff --git a/pkg/cmd/workspace/create/creation_data.go b/pkg/cmd/workspace/create/creation_data.go index 5050ab2788..88684d80d6 100644 --- a/pkg/cmd/workspace/create/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -26,13 +26,13 @@ import ( type WorkspacesDataPromptParams struct { UserGitProviders []apiclient.GitProvider - WorkspaceConfigs []apiclient.WorkspaceConfig + WorkspaceTemplates []apiclient.WorkspaceTemplate Manual bool SkipBranchSelection bool MultiWorkspace bool BlankWorkspace bool ApiClient *apiclient.APIClient - Defaults *views_util.WorkspaceConfigDefaults + Defaults *views_util.WorkspaceTemplateDefaults } func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesDataPromptParams) ([]apiclient.CreateWorkspaceDTO, error) { @@ -54,9 +54,9 @@ func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesD } } - if len(params.WorkspaceConfigs) > 0 && !params.BlankWorkspace { - workspaceConfig := selection.GetWorkspaceConfigFromPrompt(params.WorkspaceConfigs, i, true, false, "Use") - if workspaceConfig == nil { + if len(params.WorkspaceTemplates) > 0 && !params.BlankWorkspace { + workspaceTemplate := selection.GetWorkspaceTemplateFromPrompt(params.WorkspaceTemplates, i, true, false, "Use") + if workspaceTemplate == nil { return nil, common.ErrCtrlCAbort } @@ -66,19 +66,19 @@ func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesD } // Append occurence number to keep duplicate entries unique - repoUrl := workspaceConfig.RepositoryUrl + repoUrl := workspaceTemplate.RepositoryUrl if len(selectedRepos) > 0 && selectedRepos[repoUrl] > 1 { - workspaceConfig.Name += strconv.Itoa(selectedRepos[repoUrl]) + workspaceTemplate.Name += strconv.Itoa(selectedRepos[repoUrl]) } - if workspaceConfig.Name != selection.BlankWorkspaceIdentifier { - workspaceName := GetSuggestedName(workspaceConfig.Name, workspaceNames) + if workspaceTemplate.Name != selection.BlankWorkspaceIdentifier { + workspaceName := GetSuggestedName(workspaceTemplate.Name, workspaceNames) getRepoContext := apiclient.GetRepositoryContext{ - Url: workspaceConfig.RepositoryUrl, + Url: workspaceTemplate.RepositoryUrl, } - branch, err := GetBranchFromWorkspaceConfig(ctx, workspaceConfig, params.ApiClient, i) + branch, err := GetBranchFromWorkspaceTemplate(ctx, workspaceTemplate, params.ApiClient, i) if err != nil { return nil, err } @@ -88,33 +88,33 @@ func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesD getRepoContext.Sha = &branch.Sha } - configRepo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(getRepoContext).Execute() + templateRepo, res, err := params.ApiClient.GitProviderAPI.GetGitContext(ctx).Repository(getRepoContext).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } createWorkspaceDto := apiclient.CreateWorkspaceDTO{ Name: workspaceName, - GitProviderConfigId: workspaceConfig.GitProviderConfigId, + GitProviderConfigId: workspaceTemplate.GitProviderConfigId, Source: apiclient.CreateWorkspaceSourceDTO{ - Repository: *configRepo, + Repository: *templateRepo, }, - BuildConfig: workspaceConfig.BuildConfig, + BuildConfig: workspaceTemplate.BuildConfig, Image: params.Defaults.Image, User: params.Defaults.ImageUser, - EnvVars: workspaceConfig.EnvVars, + EnvVars: workspaceTemplate.EnvVars, } - if workspaceConfig.Image != "" { - createWorkspaceDto.Image = &workspaceConfig.Image + if workspaceTemplate.Image != "" { + createWorkspaceDto.Image = &workspaceTemplate.Image } - if workspaceConfig.User != "" { - createWorkspaceDto.User = &workspaceConfig.User + if workspaceTemplate.User != "" { + createWorkspaceDto.User = &workspaceTemplate.User } - if workspaceConfig.GitProviderConfigId == nil || *workspaceConfig.GitProviderConfigId == "" { - gitProviderConfigId, res, err := params.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(workspaceConfig.RepositoryUrl)).Execute() + if workspaceTemplate.GitProviderConfigId == nil || *workspaceTemplate.GitProviderConfigId == "" { + gitProviderConfigId, res, err := params.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(workspaceTemplate.RepositoryUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -174,7 +174,7 @@ func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesD return nil, err } - workspaceList = append(workspaceList, newCreateWorkspaceConfigDTO(params, providerRepo, providerRepoName, gitProviderConfigId)) + workspaceList = append(workspaceList, newCreateWorkspaceTemplateDTO(params, providerRepo, providerRepoName, gitProviderConfigId)) } return workspaceList, nil @@ -212,11 +212,11 @@ func GetSanitizedWorkspaceName(workspaceName string) (string, error) { return workspaceName, nil } -func GetBranchFromWorkspaceConfig(ctx context.Context, workspaceConfig *apiclient.WorkspaceConfig, apiClient *apiclient.APIClient, workspaceOrder int) (*apiclient.GitBranch, error) { - encodedURLParam := url.QueryEscape(workspaceConfig.RepositoryUrl) +func GetBranchFromWorkspaceTemplate(ctx context.Context, workspaceTemplate *apiclient.WorkspaceTemplate, apiClient *apiclient.APIClient, workspaceOrder int) (*apiclient.GitBranch, error) { + encodedURLParam := url.QueryEscape(workspaceTemplate.RepositoryUrl) repoResponse, res, err := apiClient.GitProviderAPI.GetGitContext(ctx).Repository(apiclient.GetRepositoryContext{ - Url: workspaceConfig.RepositoryUrl, + Url: workspaceTemplate.RepositoryUrl, }).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) @@ -313,7 +313,7 @@ func GetGitProviderConfigIdFromFlag(ctx context.Context, apiClient *apiclient.AP return nil, fmt.Errorf("git provider config '%s' not found", *gitProviderConfigFlag) } -func newCreateWorkspaceConfigDTO(params WorkspacesDataPromptParams, providerRepo *apiclient.GitRepository, providerRepoName string, gitProviderConfigId string) apiclient.CreateWorkspaceDTO { +func newCreateWorkspaceTemplateDTO(params WorkspacesDataPromptParams, providerRepo *apiclient.GitRepository, providerRepoName string, gitProviderConfigId string) apiclient.CreateWorkspaceDTO { workspace := apiclient.CreateWorkspaceDTO{ Name: providerRepoName, GitProviderConfigId: &gitProviderConfigId, diff --git a/pkg/cmd/workspace/create/process_cmd_arguments.go b/pkg/cmd/workspace/create/process_cmd_arguments.go index 4c5e8ed4e0..7a1eb46cd4 100644 --- a/pkg/cmd/workspace/create/process_cmd_arguments.go +++ b/pkg/cmd/workspace/create/process_cmd_arguments.go @@ -49,9 +49,9 @@ func ProcessCmdArguments(ctx context.Context, params ProcessCmdArgumentsParams) return nil, fmt.Errorf("can't set devcontainer file path if builder is not set to %s", views_util.DEVCONTAINER) } - var workspaceConfig *apiclient.WorkspaceConfig + var workspaceTemplate *apiclient.WorkspaceTemplate - existingWorkspaceConfigNames := []string{} + existingWorkspaceTemplateNames := []string{} for i, repoUrl := range params.RepoUrls { var branch *string @@ -62,7 +62,7 @@ func ProcessCmdArguments(ctx context.Context, params ProcessCmdArgumentsParams) validatedUrl, err := util.GetValidatedUrl(repoUrl) if err == nil { // The argument is a Git URL - existingWorkspaceConfigName, err := processGitURL(ctx, ProcessGitUrlParams{ + existingWorkspaceTemplateName, err := processGitURL(ctx, ProcessGitUrlParams{ ApiClient: params.ApiClient, RepoUrl: validatedUrl, CreateWorkspaceDtos: params.CreateWorkspaceDtos, @@ -73,55 +73,55 @@ func ProcessCmdArguments(ctx context.Context, params ProcessCmdArgumentsParams) if err != nil { return nil, err } - if existingWorkspaceConfigName != nil { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) + if existingWorkspaceTemplateName != nil { + existingWorkspaceTemplateNames = append(existingWorkspaceTemplateNames, *existingWorkspaceTemplateName) } else { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") + existingWorkspaceTemplateNames = append(existingWorkspaceTemplateNames, "") } continue } - // The argument is not a Git URL - try getting the workspace config - workspaceConfig, _, err = params.ApiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, repoUrl).Execute() + // The argument is not a Git URL - try getting the workspace template + workspaceTemplate, _, err = params.ApiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, repoUrl).Execute() if err != nil { - return nil, fmt.Errorf("failed to parse the URL or fetch the workspace config for '%s'", repoUrl) + return nil, fmt.Errorf("failed to parse the URL or fetch the workspace template for '%s'", repoUrl) } - existingWorkspaceConfigName, err := AddWorkspaceFromConfig(ctx, AddWorkspaceFromConfigParams{ - WorkspaceConfig: workspaceConfig, - ApiClient: params.ApiClient, - Workspaces: params.CreateWorkspaceDtos, - BranchFlag: branch, + existingWorkspaceTemplateName, err := AddWorkspaceFromTemplate(ctx, AddWorkspaceFromTemplateParams{ + WorkspaceTemplate: workspaceTemplate, + ApiClient: params.ApiClient, + Workspaces: params.CreateWorkspaceDtos, + BranchFlag: branch, }) if err != nil { return nil, err } - if existingWorkspaceConfigName != nil { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, *existingWorkspaceConfigName) + if existingWorkspaceTemplateName != nil { + existingWorkspaceTemplateNames = append(existingWorkspaceTemplateNames, *existingWorkspaceTemplateName) } else { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, "") + existingWorkspaceTemplateNames = append(existingWorkspaceTemplateNames, "") } } generateWorkspaceIds(params.CreateWorkspaceDtos) setInitialWorkspaceNames(params.CreateWorkspaceDtos, *params.ExistingWorkspaces) - return existingWorkspaceConfigNames, nil + return existingWorkspaceTemplateNames, nil } func processGitURL(ctx context.Context, params ProcessGitUrlParams) (*string, error) { encodedURLParam := url.QueryEscape(params.RepoUrl) if !params.BlankFlag { - workspaceConfig, res, err := params.ApiClient.WorkspaceConfigAPI.GetDefaultWorkspaceConfig(ctx, encodedURLParam).Execute() + workspaceTemplate, res, err := params.ApiClient.WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate(ctx, encodedURLParam).Execute() if err == nil { - workspaceConfig.GitProviderConfigId = params.WorkspaceConfigurationFlags.GitProviderConfig - return AddWorkspaceFromConfig(ctx, AddWorkspaceFromConfigParams{ - WorkspaceConfig: workspaceConfig, - ApiClient: params.ApiClient, - Workspaces: params.CreateWorkspaceDtos, - BranchFlag: params.Branch, + workspaceTemplate.GitProviderConfigId = params.WorkspaceConfigurationFlags.GitProviderConfig + return AddWorkspaceFromTemplate(ctx, AddWorkspaceFromTemplateParams{ + WorkspaceTemplate: workspaceTemplate, + ApiClient: params.ApiClient, + Workspaces: params.CreateWorkspaceDtos, + BranchFlag: params.Branch, }) } diff --git a/pkg/cmd/workspace/create/process_prompting.go b/pkg/cmd/workspace/create/process_prompting.go index 7af322dca7..df5efe64fb 100644 --- a/pkg/cmd/workspace/create/process_prompting.go +++ b/pkg/cmd/workspace/create/process_prompting.go @@ -36,7 +36,7 @@ func ProcessPrompting(ctx context.Context, params ProcessPromptingParams) error return apiclient_util.HandleErrorResponse(res, err) } - workspaceConfigs, res, err := params.ApiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceTemplates, res, err := params.ApiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -46,7 +46,7 @@ func ProcessPrompting(ctx context.Context, params ProcessPromptingParams) error return apiclient_util.HandleErrorResponse(res, err) } - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ BuildChoice: views_util.AUTOMATIC, Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, @@ -54,13 +54,13 @@ func ProcessPrompting(ctx context.Context, params ProcessPromptingParams) error } *params.CreateWorkspaceDtos, err = GetWorkspacesCreationDataFromPrompt(ctx, WorkspacesDataPromptParams{ - UserGitProviders: gitProviders, - WorkspaceConfigs: workspaceConfigs, - Manual: *params.WorkspaceConfigurationFlags.Manual, - MultiWorkspace: params.MultiWorkspaceFlag, - BlankWorkspace: params.BlankFlag, - ApiClient: params.ApiClient, - Defaults: workspaceDefaults, + UserGitProviders: gitProviders, + WorkspaceTemplates: workspaceTemplates, + Manual: *params.WorkspaceConfigurationFlags.Manual, + MultiWorkspace: params.MultiWorkspaceFlag, + BlankWorkspace: params.BlankFlag, + ApiClient: params.ApiClient, + Defaults: workspaceDefaults, }) if err != nil { diff --git a/pkg/cmd/workspaceconfig/delete.go b/pkg/cmd/workspaceconfig/delete.go deleted file mode 100644 index 42cd96fb0f..0000000000 --- a/pkg/cmd/workspaceconfig/delete.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaceconfig - -import ( - "context" - "fmt" - - "github.com/charmbracelet/huh" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/selection" - views_util "github.com/daytonaio/daytona/pkg/views/util" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -var allFlag bool -var yesFlag bool -var forceFlag bool - -var workspaceConfigDeleteCmd = &cobra.Command{ - Use: "delete", - Aliases: []string{"remove", "rm"}, - Short: "Delete a workspace config", - Args: cobra.MaximumNArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - var selectedWorkspaceConfig *apiclient.WorkspaceConfig - var selectedWorkspaceConfigName string - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - if allFlag { - if !yesFlag { - form := huh.NewForm( - huh.NewGroup( - huh.NewConfirm(). - Title("Delete all workspace configs?"). - Description("Are you sure you want to delete all workspace configs?"). - Value(&yesFlag), - ), - ).WithTheme(views.GetCustomTheme()) - - err := form.Run() - if err != nil { - return err - } - - if !yesFlag { - fmt.Println("Operation canceled.") - return nil - } - } - - workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(workspaceConfigs) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(false) - return nil - } - - for _, workspaceConfig := range workspaceConfigs { - selectedWorkspaceConfigName = workspaceConfig.Name - res, err := apiClient.WorkspaceConfigAPI.DeleteWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Execute() - if err != nil { - log.Error(apiclient_util.HandleErrorResponse(res, err)) - continue - } - views.RenderInfoMessage("Deleted workspace config: " + selectedWorkspaceConfigName) - } - return nil - } - - if len(args) == 0 { - workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(workspaceConfigs) == 0 { - views.RenderInfoMessage("No workspace configs found") - return nil - } - - selectedWorkspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigs, 0, false, false, "Delete") - if selectedWorkspaceConfig == nil { - return nil - } - selectedWorkspaceConfigName = selectedWorkspaceConfig.Name - } else { - selectedWorkspaceConfigName = args[0] - } - - res, err := apiClient.WorkspaceConfigAPI.DeleteWorkspaceConfig(context.Background(), selectedWorkspaceConfigName).Force(forceFlag).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - views.RenderInfoMessage("Workspace config deleted successfully") - return nil - }, -} - -func init() { - workspaceConfigDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspace configs") - workspaceConfigDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") - workspaceConfigDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") -} diff --git a/pkg/cmd/workspaceconfig/workspaceconfig.go b/pkg/cmd/workspaceconfig/workspaceconfig.go deleted file mode 100644 index 1a8dd79267..0000000000 --- a/pkg/cmd/workspaceconfig/workspaceconfig.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package workspaceconfig - -import ( - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var WorkspaceConfigCmd = &cobra.Command{ - Use: "workspace-config", - Short: "Manage workspace configs", - Aliases: []string{"wc"}, - GroupID: util.TARGET_GROUP, -} - -func init() { - WorkspaceConfigCmd.AddCommand(workspaceConfigListCmd) - WorkspaceConfigCmd.AddCommand(workspaceConfigInfoCmd) - WorkspaceConfigCmd.AddCommand(workspaceConfigAddCmd) - WorkspaceConfigCmd.AddCommand(workspaceConfigUpdateCmd) - WorkspaceConfigCmd.AddCommand(workspaceConfigSetDefaultCmd) - WorkspaceConfigCmd.AddCommand(workspaceConfigDeleteCmd) - WorkspaceConfigCmd.AddCommand(workspaceTemplateExportCmd) - WorkspaceConfigCmd.AddCommand(workspaceTemplateImportCmd) -} diff --git a/pkg/cmd/workspaceconfig/add.go b/pkg/cmd/workspacetemplate/add.go similarity index 64% rename from pkg/cmd/workspaceconfig/add.go rename to pkg/cmd/workspacetemplate/add.go index 0d51138b78..2d5b2ff5ed 100644 --- a/pkg/cmd/workspaceconfig/add.go +++ b/pkg/cmd/workspacetemplate/add.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" @@ -21,14 +21,14 @@ import ( "github.com/spf13/cobra" ) -var workspaceConfigAddCmd = &cobra.Command{ +var workspaceTemplateAddCmd = &cobra.Command{ Use: "add", Aliases: []string{"new", "create"}, - Short: "Add a workspace config", + Short: "Add a workspace template", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var workspaceConfig *apiclient.WorkspaceConfig - var workspaceConfigName *string + var workspaceTemplate *apiclient.WorkspaceTemplate + var workspaceTemplateName *string ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -42,37 +42,37 @@ var workspaceConfigAddCmd = &cobra.Command{ } if len(args) == 0 { - workspaceConfig, err = RunWorkspaceConfigAddFlow(apiClient, gitProviders, ctx) + workspaceTemplate, err = RunWorkspaceTemplateAddFlow(apiClient, gitProviders, ctx) if err != nil { return err } - if workspaceConfig == nil { + if workspaceTemplate == nil { return nil } - workspaceConfigName = &workspaceConfig.Name + workspaceTemplateName = &workspaceTemplate.Name } else { - workspaceConfigName, err = processCmdArgument(args[0], apiClient, ctx) + workspaceTemplateName, err = processCmdArgument(args[0], apiClient, ctx) if err != nil { return err } } - if workspaceConfigName == nil { - return errors.New("workspace config name is required") + if workspaceTemplateName == nil { + return errors.New("workspace template name is required") } - views.RenderInfoMessage(fmt.Sprintf("Workspace config %s added successfully", *workspaceConfigName)) + views.RenderInfoMessage(fmt.Sprintf("Workspace template %s added successfully", *workspaceTemplateName)) return nil }, } -func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.WorkspaceConfig, error) { +func RunWorkspaceTemplateAddFlow(apiClient *apiclient.APIClient, gitProviders []apiclient.GitProvider, ctx context.Context) (*apiclient.WorkspaceTemplate, error) { if cmd_common.CheckAnyWorkspaceConfigurationFlagSet(workspaceConfigurationFlags) { - return nil, errors.New("please provide the repository URL in order to set up custom workspace config details through the CLI") + return nil, errors.New("please provide the repository URL in order to set up custom workspace template details through the CLI") } var createDtos []apiclient.CreateWorkspaceDTO - existingWorkspaceConfigNames, err := getExistingWorkspaceConfigNames(apiClient) + existingWorkspaceTemplateNames, err := getExistingWorkspaceTemplateNames(apiClient) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap return nil, apiclient_util.HandleErrorResponse(res, err) } - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ BuildChoice: views_util.AUTOMATIC, Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, @@ -116,19 +116,19 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap } if createDtos[0].Name == "" { - return nil, errors.New("workspace config name is required") + return nil, errors.New("workspace template name is required") } initialSuggestion := createDtos[0].Name - chosenName := create_cmd.GetSuggestedName(initialSuggestion, existingWorkspaceConfigNames) + chosenName := create_cmd.GetSuggestedName(initialSuggestion, existingWorkspaceTemplateNames) submissionFormConfig := create.SubmissionFormParams{ ChosenName: &chosenName, SuggestedName: chosenName, - ExistingWorkspaceNames: existingWorkspaceConfigNames, + ExistingWorkspaceNames: existingWorkspaceTemplateNames, WorkspaceList: &createDtos, - NameLabel: "Workspace config", + NameLabel: "Workspace Template", Defaults: workspaceDefaults, } @@ -137,7 +137,7 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap return nil, err } - createWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ + createWorkspaceTemplate := apiclient.CreateWorkspaceTemplateDTO{ Name: chosenName, BuildConfig: createDtos[0].BuildConfig, Image: createDtos[0].Image, @@ -147,38 +147,38 @@ func RunWorkspaceConfigAddFlow(apiClient *apiclient.APIClient, gitProviders []ap GitProviderConfigId: createDtos[0].GitProviderConfigId, } - res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(createWorkspaceConfig).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(createWorkspaceTemplate).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - workspaceConfig := apiclient.WorkspaceConfig{ - BuildConfig: createWorkspaceConfig.BuildConfig, + workspaceTemplate := apiclient.WorkspaceTemplate{ + BuildConfig: createWorkspaceTemplate.BuildConfig, Default: false, - EnvVars: createWorkspaceConfig.EnvVars, - Name: createWorkspaceConfig.Name, + EnvVars: createWorkspaceTemplate.EnvVars, + Name: createWorkspaceTemplate.Name, Prebuilds: nil, - RepositoryUrl: createWorkspaceConfig.RepositoryUrl, - GitProviderConfigId: createWorkspaceConfig.GitProviderConfigId, + RepositoryUrl: createWorkspaceTemplate.RepositoryUrl, + GitProviderConfigId: createWorkspaceTemplate.GitProviderConfigId, } - if createWorkspaceConfig.Image != nil { - workspaceConfig.Image = *createWorkspaceConfig.Image + if createWorkspaceTemplate.Image != nil { + workspaceTemplate.Image = *createWorkspaceTemplate.Image } - if createWorkspaceConfig.User != nil { - workspaceConfig.User = *createWorkspaceConfig.User + if createWorkspaceTemplate.User != nil { + workspaceTemplate.User = *createWorkspaceTemplate.User } - if createWorkspaceConfig.GitProviderConfigId == nil && *createWorkspaceConfig.GitProviderConfigId == "" { - gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(createWorkspaceConfig.RepositoryUrl)).Execute() + if createWorkspaceTemplate.GitProviderConfigId == nil && *createWorkspaceTemplate.GitProviderConfigId == "" { + gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(createWorkspaceTemplate.RepositoryUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - workspaceConfig.GitProviderConfigId = &gitProviderConfigId + workspaceTemplate.GitProviderConfigId = &gitProviderConfigId } - return &workspaceConfig, nil + return &workspaceTemplate, nil } func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx context.Context) (*string, error) { @@ -191,7 +191,7 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con return nil, apiclient_util.HandleErrorResponse(res, err) } - existingWorkspaceConfigNames, err := getExistingWorkspaceConfigNames(apiClient) + existingWorkspaceTemplateNames, err := getExistingWorkspaceTemplateNames(apiClient) if err != nil { return nil, err } @@ -223,7 +223,7 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con name = nameFlag } else { workspaceName := create_cmd.GetWorkspaceNameFromRepo(repoUrl) - name = create_cmd.GetSuggestedName(workspaceName, existingWorkspaceConfigNames) + name = create_cmd.GetSuggestedName(workspaceName, existingWorkspaceTemplateNames) } if workspace.GitProviderConfigId == nil || *workspace.GitProviderConfigId == "" { @@ -234,7 +234,7 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con *workspace.GitProviderConfigId = gitProviderConfigId } - newWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ + newWorkspaceTemplate := apiclient.CreateWorkspaceTemplateDTO{ Name: name, BuildConfig: workspace.BuildConfig, Image: workspace.Image, @@ -244,35 +244,35 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con GitProviderConfigId: workspace.GitProviderConfigId, } - if newWorkspaceConfig.Image == nil { - newWorkspaceConfig.Image = &apiServerConfig.DefaultWorkspaceImage + if newWorkspaceTemplate.Image == nil { + newWorkspaceTemplate.Image = &apiServerConfig.DefaultWorkspaceImage } - if newWorkspaceConfig.User == nil { - newWorkspaceConfig.User = &apiServerConfig.DefaultWorkspaceUser + if newWorkspaceTemplate.User == nil { + newWorkspaceTemplate.User = &apiServerConfig.DefaultWorkspaceUser } - res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - return &newWorkspaceConfig.Name, nil + return &newWorkspaceTemplate.Name, nil } -func getExistingWorkspaceConfigNames(apiClient *apiclient.APIClient) ([]string, error) { - var existingWorkspaceConfigNames []string +func getExistingWorkspaceTemplateNames(apiClient *apiclient.APIClient) ([]string, error) { + var existingWorkspaceTemplateNames []string - existingWorkspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() + existingWorkspaceTemplates, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(context.Background()).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - for _, wc := range existingWorkspaceConfigs { - existingWorkspaceConfigNames = append(existingWorkspaceConfigNames, wc.Name) + for _, wt := range existingWorkspaceTemplates { + existingWorkspaceTemplateNames = append(existingWorkspaceTemplateNames, wt.Name) } - return existingWorkspaceConfigNames, nil + return existingWorkspaceTemplateNames, nil } var nameFlag string @@ -289,6 +289,6 @@ var workspaceConfigurationFlags = cmd_common.WorkspaceConfigurationFlags{ } func init() { - workspaceConfigAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace config name") - cmd_common.AddWorkspaceConfigurationFlags(workspaceConfigAddCmd, workspaceConfigurationFlags, false) + workspaceTemplateAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace template name") + cmd_common.AddWorkspaceConfigurationFlags(workspaceTemplateAddCmd, workspaceConfigurationFlags, false) } diff --git a/pkg/cmd/workspacetemplate/delete.go b/pkg/cmd/workspacetemplate/delete.go new file mode 100644 index 0000000000..2f644e9f11 --- /dev/null +++ b/pkg/cmd/workspacetemplate/delete.go @@ -0,0 +1,116 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspacetemplate + +import ( + "context" + "fmt" + + "github.com/charmbracelet/huh" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var allFlag bool +var yesFlag bool +var forceFlag bool + +var workspaceTemplateDeleteCmd = &cobra.Command{ + Use: "delete", + Aliases: []string{"remove", "rm"}, + Short: "Delete a workspace template", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + var selectedWorkspaceTemplate *apiclient.WorkspaceTemplate + var selectedWorkspaceTemplateName string + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + if allFlag { + if !yesFlag { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Delete all workspace templates?"). + Description("Are you sure you want to delete all workspace templates?"). + Value(&yesFlag), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + + if !yesFlag { + fmt.Println("Operation canceled.") + return nil + } + } + + workspaceTemplates, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceTemplates) == 0 { + views_util.NotifyEmptyWorkspaceTemplateList(false) + return nil + } + + for _, workspaceTemplate := range workspaceTemplates { + selectedWorkspaceTemplateName = workspaceTemplate.Name + res, err := apiClient.WorkspaceTemplateAPI.DeleteWorkspaceTemplate(context.Background(), selectedWorkspaceTemplateName).Execute() + if err != nil { + log.Error(apiclient_util.HandleErrorResponse(res, err)) + continue + } + views.RenderInfoMessage("Deleted workspace template: " + selectedWorkspaceTemplateName) + } + return nil + } + + if len(args) == 0 { + workspaceTemplates, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(workspaceTemplates) == 0 { + views.RenderInfoMessage("No workspace templates found") + return nil + } + + selectedWorkspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceTemplates, 0, false, false, "Delete") + if selectedWorkspaceTemplate == nil { + return nil + } + selectedWorkspaceTemplateName = selectedWorkspaceTemplate.Name + } else { + selectedWorkspaceTemplateName = args[0] + } + + res, err := apiClient.WorkspaceTemplateAPI.DeleteWorkspaceTemplate(context.Background(), selectedWorkspaceTemplateName).Force(forceFlag).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + views.RenderInfoMessage("Workspace template deleted successfully") + return nil + }, +} + +func init() { + workspaceTemplateDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspace templates") + workspaceTemplateDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + workspaceTemplateDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") +} diff --git a/pkg/cmd/workspaceconfig/export.go b/pkg/cmd/workspacetemplate/export.go similarity index 76% rename from pkg/cmd/workspaceconfig/export.go rename to pkg/cmd/workspacetemplate/export.go index 0e6c1467e9..230503edd7 100644 --- a/pkg/cmd/workspaceconfig/export.go +++ b/pkg/cmd/workspacetemplate/export.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" @@ -25,7 +25,7 @@ var workspaceTemplateExportCmd = &cobra.Command{ Short: "Export a workspace template", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var selectedWorkspaceConfig *apiclient.WorkspaceConfig + var selectedWorkspaceTemplate *apiclient.WorkspaceTemplate ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -34,27 +34,27 @@ var workspaceTemplateExportCmd = &cobra.Command{ } if allFlag { - workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceConfigs, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } if len(workspaceConfigs) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(true) + views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } - return exportWorkspaceConfigs(workspaceConfigs) + return exportWorkspaceTemplates(workspaceConfigs) } if len(args) == 0 { - workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceConfigs, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } if len(workspaceConfigs) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(true) + views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } @@ -62,8 +62,8 @@ var workspaceTemplateExportCmd = &cobra.Command{ format.UnblockStdOut() } - selectedWorkspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigs, 0, false, false, "Export") - if selectedWorkspaceConfig == nil { + selectedWorkspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceConfigs, 0, false, false, "Export") + if selectedWorkspaceTemplate == nil { return nil } @@ -72,13 +72,13 @@ var workspaceTemplateExportCmd = &cobra.Command{ } } else { var res *http.Response - selectedWorkspaceConfig, res, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, args[0]).Execute() + selectedWorkspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } } - return exportWorkspaceConfigs([]apiclient.WorkspaceConfig{*selectedWorkspaceConfig}) + return exportWorkspaceTemplates([]apiclient.WorkspaceTemplate{*selectedWorkspaceTemplate}) }, } @@ -87,7 +87,7 @@ func init() { format.RegisterFormatFlag(workspaceTemplateExportCmd) } -func exportWorkspaceConfigs(workspaceConfigs []apiclient.WorkspaceConfig) error { +func exportWorkspaceTemplates(workspaceConfigs []apiclient.WorkspaceTemplate) error { if len(workspaceConfigs) == 0 { return nil } diff --git a/pkg/cmd/workspaceconfig/import.go b/pkg/cmd/workspacetemplate/import.go similarity index 81% rename from pkg/cmd/workspaceconfig/import.go rename to pkg/cmd/workspacetemplate/import.go index 49cc7c835b..b32fe7cb0d 100644 --- a/pkg/cmd/workspaceconfig/import.go +++ b/pkg/cmd/workspacetemplate/import.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" @@ -38,7 +38,7 @@ var workspaceTemplateImportCmd = &cobra.Command{ return err } - workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceConfigList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -74,22 +74,22 @@ var workspaceTemplateImportCmd = &cobra.Command{ } } - var config apiclient.WorkspaceConfig + var config apiclient.WorkspaceTemplate err = json.Unmarshal([]byte(inputText), &config) if err == nil { - err = importWorkspaceConfig(ctx, apiClient, config, &workspaceConfigList) + err = importWorkspaceTemplate(ctx, apiClient, config, &workspaceConfigList) if err != nil { return fmt.Errorf("error importing workspace config: %v", err) } } else { - var configs []apiclient.WorkspaceConfig + var configs []apiclient.WorkspaceTemplate err = json.Unmarshal([]byte(inputText), &configs) if err != nil { return fmt.Errorf("invalid JSON input: %v", err) } for _, config := range configs { - err = importWorkspaceConfig(ctx, apiClient, config, &workspaceConfigList) + err = importWorkspaceTemplate(ctx, apiClient, config, &workspaceConfigList) if err != nil { return fmt.Errorf("error importing workspace config: %v", err) } @@ -103,7 +103,7 @@ func init() { workspaceTemplateImportCmd.Flags().StringVarP(&filePath, "file", "f", "", "Import workspace template from a JSON file. Use '-' to read from stdin.") } -func isWorkspaceConfigAlreadyExists(configName string, workspaceConfigList *[]apiclient.WorkspaceConfig) bool { +func isWorkspaceTemplateAlreadyExists(configName string, workspaceConfigList *[]apiclient.WorkspaceTemplate) bool { for _, workspaceConfig := range *workspaceConfigList { if workspaceConfig.Name == configName { return true @@ -112,8 +112,8 @@ func isWorkspaceConfigAlreadyExists(configName string, workspaceConfigList *[]ap return false } -func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, config apiclient.WorkspaceConfig, workspaceConfigList *[]apiclient.WorkspaceConfig) error { - if isWorkspaceConfigAlreadyExists(config.Name, workspaceConfigList) { +func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient, config apiclient.WorkspaceTemplate, workspaceConfigList *[]apiclient.WorkspaceTemplate) error { + if isWorkspaceTemplateAlreadyExists(config.Name, workspaceConfigList) { return fmt.Errorf("workspace config already present with name \"%s\"", config.Name) } @@ -158,7 +158,7 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, return apiclient_util.HandleErrorResponse(res, err) } - newWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ + newWorkspaceTemplate := apiclient.CreateWorkspaceTemplateDTO{ Name: config.Name, BuildConfig: config.BuildConfig, Image: &config.Image, @@ -168,15 +168,15 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, GitProviderConfigId: config.GitProviderConfigId, } - if newWorkspaceConfig.Image == nil { - newWorkspaceConfig.Image = &apiServerConfig.DefaultWorkspaceImage + if newWorkspaceTemplate.Image == nil { + newWorkspaceTemplate.Image = &apiServerConfig.DefaultWorkspaceImage } - if newWorkspaceConfig.User == nil { - newWorkspaceConfig.User = &apiServerConfig.DefaultWorkspaceUser + if newWorkspaceTemplate.User == nil { + newWorkspaceTemplate.User = &apiServerConfig.DefaultWorkspaceUser } - existingWorkspaceConfigNames, err := getExistingWorkspaceConfigNames(apiClient) + existingWorkspaceTemplateNames, err := getExistingWorkspaceTemplateNames(apiClient) if err != nil { return err } @@ -186,7 +186,7 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, return apiclient_util.HandleErrorResponse(res, err) } - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ BuildChoice: views_util.AUTOMATIC, Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, @@ -215,7 +215,7 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, submissionFormConfig := create.SubmissionFormParams{ ChosenName: &config.Name, SuggestedName: config.Name, - ExistingWorkspaceNames: existingWorkspaceConfigNames, + ExistingWorkspaceNames: existingWorkspaceTemplateNames, WorkspaceList: &createDto, NameLabel: "Workspace config", Defaults: workspaceDefaults, @@ -228,16 +228,16 @@ func importWorkspaceConfig(ctx context.Context, apiClient *apiclient.APIClient, } if submissionFormConfig.ImportConfirmation != nil && *submissionFormConfig.ImportConfirmation { - res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } *workspaceConfigList = append(*workspaceConfigList, config) - views.RenderInfoMessage(fmt.Sprintf("Workspace config %s imported successfully", newWorkspaceConfig.Name)) + views.RenderInfoMessage(fmt.Sprintf("Workspace config %s imported successfully", newWorkspaceTemplate.Name)) return nil } - views.RenderInfoMessage(fmt.Sprintf("Workspace config %s import cancelled", newWorkspaceConfig.Name)) + views.RenderInfoMessage(fmt.Sprintf("Workspace config %s import cancelled", newWorkspaceTemplate.Name)) return nil } diff --git a/pkg/cmd/workspaceconfig/info.go b/pkg/cmd/workspacetemplate/info.go similarity index 61% rename from pkg/cmd/workspaceconfig/info.go rename to pkg/cmd/workspacetemplate/info.go index 04b786222b..491d5b8476 100644 --- a/pkg/cmd/workspaceconfig/info.go +++ b/pkg/cmd/workspacetemplate/info.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" @@ -12,13 +12,13 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" + "github.com/daytonaio/daytona/pkg/views/workspacetemplate/info" "github.com/spf13/cobra" ) -var workspaceConfigInfoCmd = &cobra.Command{ +var workspaceTemplateInfoCmd = &cobra.Command{ Use: "info", - Short: "Show workspace config info", + Short: "Show workspace template info", Aliases: []string{"view", "inspect"}, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { @@ -34,16 +34,16 @@ var workspaceConfigInfoCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - var workspaceConfig *apiclient.WorkspaceConfig + var workspaceTemplate *apiclient.WorkspaceTemplate if len(args) == 0 { - workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceTemplateList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceConfigList) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(true) + if len(workspaceTemplateList) == 0 { + views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } @@ -51,34 +51,34 @@ var workspaceConfigInfoCmd = &cobra.Command{ format.UnblockStdOut() } - workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "View") + workspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceTemplateList, 0, false, false, "View") if format.FormatFlag != "" { format.BlockStdOut() } } else { var res *http.Response - workspaceConfig, res, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, args[0]).Execute() + workspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } } - if workspaceConfig == nil { + if workspaceTemplate == nil { return nil } if format.FormatFlag != "" { - formattedData := format.NewFormatter(workspaceConfig) + formattedData := format.NewFormatter(workspaceTemplate) formattedData.Print() return nil } - info.Render(workspaceConfig, apiServerConfig, false) + info.Render(workspaceTemplate, apiServerConfig, false) return nil }, } func init() { - format.RegisterFormatFlag(workspaceConfigInfoCmd) + format.RegisterFormatFlag(workspaceTemplateInfoCmd) } diff --git a/pkg/cmd/workspaceconfig/list.go b/pkg/cmd/workspacetemplate/list.go similarity index 67% rename from pkg/cmd/workspaceconfig/list.go rename to pkg/cmd/workspacetemplate/list.go index af4f3f036b..9fb22148a1 100644 --- a/pkg/cmd/workspaceconfig/list.go +++ b/pkg/cmd/workspacetemplate/list.go @@ -1,20 +1,20 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - workspaceconfig_view "github.com/daytonaio/daytona/pkg/views/workspaceconfig/list" + workspacetemplate_view "github.com/daytonaio/daytona/pkg/views/workspacetemplate/list" "github.com/spf13/cobra" ) -var workspaceConfigListCmd = &cobra.Command{ +var workspaceTemplateListCmd = &cobra.Command{ Use: "list", - Short: "Lists workspace configs", + Short: "Lists workspace templates", Aliases: []string{"ls"}, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { @@ -40,22 +40,22 @@ var workspaceConfigListCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - workspaceConfigs, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(context.Background()).Execute() + workspaceTemplates, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(context.Background()).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } if format.FormatFlag != "" { - formattedData := format.NewFormatter(workspaceConfigs) + formattedData := format.NewFormatter(workspaceTemplates) formattedData.Print() return nil } - workspaceconfig_view.ListWorkspaceConfigs(workspaceConfigs, apiServerConfig, specifyGitProviders) + workspacetemplate_view.ListWorkspaceTemplates(workspaceTemplates, apiServerConfig, specifyGitProviders) return nil }, } func init() { - format.RegisterFormatFlag(workspaceConfigListCmd) + format.RegisterFormatFlag(workspaceTemplateListCmd) } diff --git a/pkg/cmd/workspaceconfig/setdefault.go b/pkg/cmd/workspacetemplate/setdefault.go similarity index 51% rename from pkg/cmd/workspaceconfig/setdefault.go rename to pkg/cmd/workspacetemplate/setdefault.go index c56fcd372b..d40f673d29 100644 --- a/pkg/cmd/workspaceconfig/setdefault.go +++ b/pkg/cmd/workspacetemplate/setdefault.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" @@ -14,12 +14,12 @@ import ( "github.com/spf13/cobra" ) -var workspaceConfigSetDefaultCmd = &cobra.Command{ +var workspaceTemplateSetDefaultCmd = &cobra.Command{ Use: "set-default", - Short: "Set workspace config info", + Short: "Set workspace template info", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var workspaceConfigName string + var workspaceTemplateName string ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -28,31 +28,31 @@ var workspaceConfigSetDefaultCmd = &cobra.Command{ } if len(args) == 0 { - workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceTemplateList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceConfigList) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(true) + if len(workspaceTemplateList) == 0 { + views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } - workspaceConfig := selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "Make Default") - if workspaceConfig == nil { + workspaceTemplate := selection.GetWorkspaceTemplateFromPrompt(workspaceTemplateList, 0, false, false, "Make Default") + if workspaceTemplate == nil { return nil } - workspaceConfigName = workspaceConfig.Name + workspaceTemplateName = workspaceTemplate.Name } else { - workspaceConfigName = args[0] + workspaceTemplateName = args[0] } - res, err := apiClient.WorkspaceConfigAPI.SetDefaultWorkspaceConfig(ctx, workspaceConfigName).Execute() + res, err := apiClient.WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate(ctx, workspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage(fmt.Sprintf("Workspace config '%s' set as default", workspaceConfigName)) + views.RenderInfoMessage(fmt.Sprintf("Workspace template '%s' set as default", workspaceTemplateName)) return nil }, } diff --git a/pkg/cmd/workspaceconfig/update.go b/pkg/cmd/workspacetemplate/update.go similarity index 58% rename from pkg/cmd/workspaceconfig/update.go rename to pkg/cmd/workspacetemplate/update.go index 1a2f4209ea..29e7382e7c 100644 --- a/pkg/cmd/workspaceconfig/update.go +++ b/pkg/cmd/workspacetemplate/update.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfig +package workspacetemplate import ( "context" @@ -17,12 +17,12 @@ import ( "github.com/spf13/cobra" ) -var workspaceConfigUpdateCmd = &cobra.Command{ +var workspaceTemplateUpdateCmd = &cobra.Command{ Use: "update", - Short: "Update a workspace config", + Short: "Update a workspace template", Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - var workspaceConfig *apiclient.WorkspaceConfig + var workspaceTemplate *apiclient.WorkspaceTemplate var res *http.Response ctx := context.Background() @@ -32,53 +32,53 @@ var workspaceConfigUpdateCmd = &cobra.Command{ } if len(args) == 0 { - workspaceConfigList, res, err := apiClient.WorkspaceConfigAPI.ListWorkspaceConfigs(ctx).Execute() + workspaceTemplateList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceConfigList) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(true) + if len(workspaceTemplateList) == 0 { + views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } - workspaceConfig = selection.GetWorkspaceConfigFromPrompt(workspaceConfigList, 0, false, false, "Update") - if workspaceConfig == nil { + workspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceTemplateList, 0, false, false, "Update") + if workspaceTemplate == nil { return nil } } else { - workspaceConfig, res, err = apiClient.WorkspaceConfigAPI.GetWorkspaceConfig(ctx, args[0]).Execute() + workspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } } - if workspaceConfig == nil { + if workspaceTemplate == nil { return nil } createDto := []apiclient.CreateWorkspaceDTO{ { - Name: workspaceConfig.Name, + Name: workspaceTemplate.Name, Source: apiclient.CreateWorkspaceSourceDTO{ Repository: apiclient.GitRepository{ - Url: workspaceConfig.RepositoryUrl, + Url: workspaceTemplate.RepositoryUrl, }, }, - BuildConfig: workspaceConfig.BuildConfig, - EnvVars: workspaceConfig.EnvVars, - GitProviderConfigId: workspaceConfig.GitProviderConfigId, + BuildConfig: workspaceTemplate.BuildConfig, + EnvVars: workspaceTemplate.EnvVars, + GitProviderConfigId: workspaceTemplate.GitProviderConfigId, }, } - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ BuildChoice: views_util.AUTOMATIC, - Image: &workspaceConfig.Image, - ImageUser: &workspaceConfig.User, + Image: &workspaceTemplate.Image, + ImageUser: &workspaceTemplate.User, } - if workspaceConfig.BuildConfig != nil && workspaceConfig.BuildConfig.Devcontainer != nil { - workspaceDefaults.DevcontainerFilePath = workspaceConfig.BuildConfig.Devcontainer.FilePath + if workspaceTemplate.BuildConfig != nil && workspaceTemplate.BuildConfig.Devcontainer != nil { + workspaceDefaults.DevcontainerFilePath = workspaceTemplate.BuildConfig.Devcontainer.FilePath } _, err = create.RunWorkspaceConfiguration(&createDto, *workspaceDefaults, false) @@ -86,7 +86,7 @@ var workspaceConfigUpdateCmd = &cobra.Command{ return err } - eligibleGitProviders, res, err := apiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(workspaceConfig.RepositoryUrl)).Execute() + eligibleGitProviders, res, err := apiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(workspaceTemplate.RepositoryUrl)).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -96,7 +96,7 @@ var workspaceConfigUpdateCmd = &cobra.Command{ GitProviderConfigs: eligibleGitProviders, ActionVerb: "Use", WithNoneOption: true, - PreselectedGitProviderId: workspaceConfig.GitProviderConfigId, + PreselectedGitProviderId: workspaceTemplate.GitProviderConfigId, }) if selectedGitProvider == nil { @@ -110,8 +110,8 @@ var workspaceConfigUpdateCmd = &cobra.Command{ } } - newWorkspaceConfig := apiclient.CreateWorkspaceConfigDTO{ - Name: workspaceConfig.Name, + newWorkspaceTemplate := apiclient.CreateWorkspaceTemplateDTO{ + Name: workspaceTemplate.Name, BuildConfig: createDto[0].BuildConfig, Image: createDto[0].Image, User: createDto[0].User, @@ -120,12 +120,12 @@ var workspaceConfigUpdateCmd = &cobra.Command{ GitProviderConfigId: createDto[0].GitProviderConfigId, } - res, err = apiClient.WorkspaceConfigAPI.SetWorkspaceConfig(ctx).WorkspaceConfig(newWorkspaceConfig).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage("Workspace config updated successfully") + views.RenderInfoMessage("Workspace template updated successfully") return nil }, } diff --git a/pkg/cmd/workspacetemplate/workspacetemplate.go b/pkg/cmd/workspacetemplate/workspacetemplate.go new file mode 100644 index 0000000000..1fe22b7c67 --- /dev/null +++ b/pkg/cmd/workspacetemplate/workspacetemplate.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspacetemplate + +import ( + "github.com/daytonaio/daytona/internal/util" + "github.com/spf13/cobra" +) + +var WorkspaceTemplateCmd = &cobra.Command{ + Use: "template", + Short: "Manage workspace templates", + Aliases: []string{"templates", "workspace-template", "workspace-templates", "wt"}, + GroupID: util.TARGET_GROUP, +} + +func init() { + WorkspaceTemplateCmd.AddCommand(workspaceTemplateListCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateInfoCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateAddCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateUpdateCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateSetDefaultCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateDeleteCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateExportCmd) + WorkspaceTemplateCmd.AddCommand(workspaceTemplateImportCmd) +} diff --git a/pkg/db/workspace_config_store.go b/pkg/db/workspace_config_store.go deleted file mode 100644 index d8c0fec894..0000000000 --- a/pkg/db/workspace_config_store.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "gorm.io/gorm" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" -) - -type WorkspaceConfigStore struct { - db *gorm.DB -} - -func NewWorkspaceConfigStore(db *gorm.DB) (*WorkspaceConfigStore, error) { - err := db.AutoMigrate(&models.WorkspaceConfig{}) - if err != nil { - return nil, err - } - - return &WorkspaceConfigStore{db: db}, nil -} - -func (s *WorkspaceConfigStore) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { - workspaceConfigs := []*models.WorkspaceConfig{} - tx := processWorkspaceConfigFilters(s.db, filter).Find(&workspaceConfigs) - - if tx.Error != nil { - return nil, tx.Error - } - - return workspaceConfigs, nil -} - -func (s *WorkspaceConfigStore) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { - workspaceConfig := &models.WorkspaceConfig{} - tx := processWorkspaceConfigFilters(s.db, filter).First(workspaceConfig) - - if tx.Error != nil { - if IsRecordNotFound(tx.Error) { - return nil, stores.ErrWorkspaceConfigNotFound - } - return nil, tx.Error - } - - return workspaceConfig, nil -} - -func (s *WorkspaceConfigStore) Save(workspaceConfig *models.WorkspaceConfig) error { - tx := s.db.Save(workspaceConfig) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (s *WorkspaceConfigStore) Delete(workspaceConfig *models.WorkspaceConfig) error { - tx := s.db.Delete(workspaceConfig) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return stores.ErrWorkspaceConfigNotFound - } - - return nil -} - -func processWorkspaceConfigFilters(tx *gorm.DB, filter *stores.WorkspaceConfigFilter) *gorm.DB { - if filter != nil { - if filter.Name != nil { - tx = tx.Where("name = ?", *filter.Name) - } - if filter.Url != nil { - tx = tx.Where("repository_url = ?", *filter.Url) - } - if filter.Default != nil { - tx = tx.Where("is_default = ?", *filter.Default) - } - if filter.GitProviderConfigId != nil { - tx = tx.Where("git_provider_config_id = ?", *filter.GitProviderConfigId) - } - } - - return tx -} diff --git a/pkg/db/workspace_template_store.go b/pkg/db/workspace_template_store.go new file mode 100644 index 0000000000..0931cea723 --- /dev/null +++ b/pkg/db/workspace_template_store.go @@ -0,0 +1,89 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "gorm.io/gorm" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type WorkspaceTemplateStore struct { + db *gorm.DB +} + +func NewWorkspaceTemplateStore(db *gorm.DB) (*WorkspaceTemplateStore, error) { + err := db.AutoMigrate(&models.WorkspaceTemplate{}) + if err != nil { + return nil, err + } + + return &WorkspaceTemplateStore{db: db}, nil +} + +func (s *WorkspaceTemplateStore) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + workspaceTemplates := []*models.WorkspaceTemplate{} + tx := processWorkspaceTemplateFilters(s.db, filter).Find(&workspaceTemplates) + + if tx.Error != nil { + return nil, tx.Error + } + + return workspaceTemplates, nil +} + +func (s *WorkspaceTemplateStore) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { + workspaceTemplate := &models.WorkspaceTemplate{} + tx := processWorkspaceTemplateFilters(s.db, filter).First(workspaceTemplate) + + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, stores.ErrWorkspaceTemplateNotFound + } + return nil, tx.Error + } + + return workspaceTemplate, nil +} + +func (s *WorkspaceTemplateStore) Save(workspaceTemplate *models.WorkspaceTemplate) error { + tx := s.db.Save(workspaceTemplate) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *WorkspaceTemplateStore) Delete(workspaceTemplate *models.WorkspaceTemplate) error { + tx := s.db.Delete(workspaceTemplate) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrWorkspaceTemplateNotFound + } + + return nil +} + +func processWorkspaceTemplateFilters(tx *gorm.DB, filter *stores.WorkspaceTemplateFilter) *gorm.DB { + if filter != nil { + if filter.Name != nil { + tx = tx.Where("name = ?", *filter.Name) + } + if filter.Url != nil { + tx = tx.Where("repository_url = ?", *filter.Url) + } + if filter.Default != nil { + tx = tx.Where("is_default = ?", *filter.Default) + } + if filter.GitProviderConfigId != nil { + tx = tx.Where("git_provider_config_id = ?", *filter.GitProviderConfigId) + } + } + + return tx +} diff --git a/pkg/models/workspace_config.go b/pkg/models/workspace_template.go similarity index 79% rename from pkg/models/workspace_config.go rename to pkg/models/workspace_template.go index 30ae43b46e..a167331844 100644 --- a/pkg/models/workspace_config.go +++ b/pkg/models/workspace_template.go @@ -11,7 +11,7 @@ import ( "github.com/docker/docker/pkg/stringid" ) -type WorkspaceConfig struct { +type WorkspaceTemplate struct { Name string `json:"name" validate:"required" gorm:"primaryKey"` Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` @@ -21,9 +21,9 @@ type WorkspaceConfig struct { IsDefault bool `json:"default" validate:"required"` Prebuilds []*PrebuildConfig `json:"prebuilds" validate:"optional" gorm:"serializer:json"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name WorkspaceConfig +} // @name WorkspaceTemplate -func (wc *WorkspaceConfig) SetPrebuild(p *PrebuildConfig) error { +func (wt *WorkspaceTemplate) SetPrebuild(p *PrebuildConfig) error { newPrebuild := PrebuildConfig{ Id: p.Id, Branch: p.Branch, @@ -32,19 +32,19 @@ func (wc *WorkspaceConfig) SetPrebuild(p *PrebuildConfig) error { Retention: p.Retention, } - for _, pb := range wc.Prebuilds { + for _, pb := range wt.Prebuilds { if pb.Id == p.Id { *pb = newPrebuild return nil } } - wc.Prebuilds = append(wc.Prebuilds, &newPrebuild) + wt.Prebuilds = append(wt.Prebuilds, &newPrebuild) return nil } -func (wc *WorkspaceConfig) FindPrebuild(filter *MatchParams) (*PrebuildConfig, error) { - for _, pb := range wc.Prebuilds { +func (wt *WorkspaceTemplate) FindPrebuild(filter *MatchParams) (*PrebuildConfig, error) { + for _, pb := range wt.Prebuilds { if pb.Match(filter) { return pb, nil } @@ -53,14 +53,14 @@ func (wc *WorkspaceConfig) FindPrebuild(filter *MatchParams) (*PrebuildConfig, e return nil, errors.New("prebuild not found") } -func (wc *WorkspaceConfig) ListPrebuilds(filter *MatchParams) ([]*PrebuildConfig, error) { +func (wt *WorkspaceTemplate) ListPrebuilds(filter *MatchParams) ([]*PrebuildConfig, error) { if filter == nil { - return wc.Prebuilds, nil + return wt.Prebuilds, nil } prebuilds := []*PrebuildConfig{} - for _, pb := range wc.Prebuilds { + for _, pb := range wt.Prebuilds { if pb.Match(filter) { prebuilds = append(prebuilds, pb) } @@ -69,16 +69,16 @@ func (wc *WorkspaceConfig) ListPrebuilds(filter *MatchParams) ([]*PrebuildConfig return prebuilds, nil } -func (wc *WorkspaceConfig) RemovePrebuild(id string) error { +func (wt *WorkspaceTemplate) RemovePrebuild(id string) error { newPrebuilds := []*PrebuildConfig{} - for _, pb := range wc.Prebuilds { + for _, pb := range wt.Prebuilds { if pb.Id != id { newPrebuilds = append(newPrebuilds, pb) } } - wc.Prebuilds = newPrebuilds + wt.Prebuilds = newPrebuilds return nil } @@ -100,11 +100,11 @@ func (p *PrebuildConfig) GenerateId() error { } type MatchParams struct { - WorkspaceConfigName *string - Id *string - Branch *string - CommitInterval *int - TriggerFiles *[]string + WorkspaceTemplateName *string + Id *string + Branch *string + CommitInterval *int + TriggerFiles *[]string } func (p *PrebuildConfig) Match(params *MatchParams) bool { diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index d6c2390cdd..66f30f56b7 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -18,25 +18,25 @@ import ( ) type BuildServiceConfig struct { - BuildStore stores.BuildStore - FindWorkspaceConfig func(ctx context.Context, name string) (*models.WorkspaceConfig, error) - GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) - LoggerFactory logs.LoggerFactory + BuildStore stores.BuildStore + FindWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) + GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) + LoggerFactory logs.LoggerFactory } type BuildService struct { - buildStore stores.BuildStore - findWorkspaceConfig func(ctx context.Context, name string) (*models.WorkspaceConfig, error) - getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) - loggerFactory logs.LoggerFactory + buildStore stores.BuildStore + findWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) + getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) + loggerFactory logs.LoggerFactory } func NewBuildService(config BuildServiceConfig) services.IBuildService { return &BuildService{ - buildStore: config.BuildStore, - findWorkspaceConfig: config.FindWorkspaceConfig, - getRepositoryContext: config.GetRepositoryContext, - loggerFactory: config.LoggerFactory, + buildStore: config.BuildStore, + findWorkspaceTemplate: config.FindWorkspaceTemplate, + getRepositoryContext: config.GetRepositoryContext, + loggerFactory: config.LoggerFactory, } } @@ -45,12 +45,12 @@ func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { id = stringid.TruncateID(id) ctx := context.Background() - workspaceConfig, err := s.findWorkspaceConfig(ctx, b.WorkspaceConfigName) + workspaceTemplate, err := s.findWorkspaceTemplate(ctx, b.WorkspaceTemplateName) if err != nil { return "", err } - repo, err := s.getRepositoryContext(ctx, workspaceConfig.RepositoryUrl, b.Branch) + repo, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl, b.Branch) if err != nil { return "", err } @@ -59,10 +59,10 @@ func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { Id: id, State: models.BuildStatePendingRun, ContainerConfig: models.ContainerConfig{ - Image: workspaceConfig.Image, - User: workspaceConfig.User, + Image: workspaceTemplate.Image, + User: workspaceTemplate.User, }, - BuildConfig: workspaceConfig.BuildConfig, + BuildConfig: workspaceTemplate.BuildConfig, Repository: repo, EnvVars: b.EnvVars, } diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 74b3502510..80e9da6a8d 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -145,10 +145,10 @@ func (s *BuildServiceTestSuite) TestSave() { // FIXME: fix me createBuildDto := services.CreateBuildDTO{ - WorkspaceConfigName: "workspaceConfigName", - Branch: "branch", - PrebuildId: &build4.PrebuildId, - EnvVars: build4.EnvVars, + WorkspaceTemplateName: "workspaceTemplateName", + Branch: "branch", + PrebuildId: &build4.PrebuildId, + EnvVars: build4.EnvVars, } _, err := s.buildService.Create(createBuildDto) diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index 83ef4eba30..76d2af0929 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -13,7 +13,7 @@ func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { return err } - err = s.detachWorkspaceConfigs(ctx, gitProvider.Id) + err = s.detachWorkspaceTemplates(ctx, gitProvider.Id) if err != nil { return err } diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index 3b131dd13e..e78c6dce48 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -18,18 +18,18 @@ import ( type GitProviderServiceConfig struct { ConfigStore stores.GitProviderConfigStore - DetachWorkspaceConfigs func(ctx context.Context, gitProviderConfigId string) error + DetachWorkspaceTemplates func(ctx context.Context, gitProviderConfigId string) error } type GitProviderService struct { - configStore stores.GitProviderConfigStore - detachWorkspaceConfigs func(ctx context.Context, gitProviderConfigId string) error + configStore stores.GitProviderConfigStore + detachWorkspaceTemplates func(ctx context.Context, gitProviderConfigId string) error } func NewGitProviderService(config GitProviderServiceConfig) services.IGitProviderService { return &GitProviderService{ - configStore: config.ConfigStore, - detachWorkspaceConfigs: config.DetachWorkspaceConfigs, + configStore: config.ConfigStore, + detachWorkspaceTemplates: config.DetachWorkspaceTemplates, } } diff --git a/pkg/server/server.go b/pkg/server/server.go index e85e720aab..014443bdd0 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -22,7 +22,7 @@ type ServerInstanceConfig struct { TargetConfigService services.ITargetConfigService ContainerRegistryService services.IContainerRegistryService BuildService services.IBuildService - WorkspaceConfigService services.IWorkspaceConfigService + WorkspaceTemplateService services.IWorkspaceTemplateService WorkspaceService services.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry TargetService services.ITargetService @@ -53,7 +53,7 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { TargetConfigService: serverConfig.TargetConfigService, ContainerRegistryService: serverConfig.ContainerRegistryService, BuildService: serverConfig.BuildService, - WorkspaceConfigService: serverConfig.WorkspaceConfigService, + WorkspaceTemplateService: serverConfig.WorkspaceTemplateService, WorkspaceService: serverConfig.WorkspaceService, LocalContainerRegistry: serverConfig.LocalContainerRegistry, TargetService: serverConfig.TargetService, @@ -77,7 +77,7 @@ type Server struct { TargetConfigService services.ITargetConfigService ContainerRegistryService services.IContainerRegistryService BuildService services.IBuildService - WorkspaceConfigService services.IWorkspaceConfigService + WorkspaceTemplateService services.IWorkspaceTemplateService WorkspaceService services.IWorkspaceService LocalContainerRegistry ILocalContainerRegistry TargetService services.ITargetService diff --git a/pkg/server/workspaceconfigs/dto/workspaceconfig.go b/pkg/server/workspacetemplates/dto/workspacetemplate.go similarity index 69% rename from pkg/server/workspaceconfigs/dto/workspaceconfig.go rename to pkg/server/workspacetemplates/dto/workspacetemplate.go index 2762223438..572447dd90 100644 --- a/pkg/server/workspaceconfigs/dto/workspaceconfig.go +++ b/pkg/server/workspacetemplates/dto/workspacetemplate.go @@ -5,7 +5,7 @@ package dto import "github.com/daytonaio/daytona/pkg/models" -type CreateWorkspaceConfigDTO struct { +type CreateWorkspaceTemplateDTO struct { Name string `json:"name" validate:"required"` Image *string `json:"image,omitempty" validate:"optional"` User *string `json:"user,omitempty" validate:"optional"` @@ -13,15 +13,15 @@ type CreateWorkspaceConfigDTO struct { RepositoryUrl string `json:"repositoryUrl" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name CreateWorkspaceConfigDTO +} // @name CreateWorkspaceTemplateDTO type PrebuildDTO struct { - Id string `json:"id" validate:"required"` - WorkspaceConfigName string `json:"workspaceConfigName" validate:"required"` - Branch string `json:"branch" validate:"required"` - CommitInterval *int `json:"commitInterval" validate:"optional"` - TriggerFiles []string `json:"triggerFiles" validate:"optional"` - Retention int `json:"retention" validate:"required"` + Id string `json:"id" validate:"required"` + WorkspaceTemplateName string `json:"workspaceTemplateName" validate:"required"` + Branch string `json:"branch" validate:"required"` + CommitInterval *int `json:"commitInterval" validate:"optional"` + TriggerFiles []string `json:"triggerFiles" validate:"optional"` + Retention int `json:"retention" validate:"required"` } // @name PrebuildDTO type CreatePrebuildDTO struct { diff --git a/pkg/server/workspaceconfigs/prebuild.go b/pkg/server/workspacetemplates/prebuild.go similarity index 63% rename from pkg/server/workspaceconfigs/prebuild.go rename to pkg/server/workspacetemplates/prebuild.go index 01a594131b..6f802ddcbe 100644 --- a/pkg/server/workspaceconfigs/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfigs +package workspacetemplates import ( "context" @@ -13,34 +13,34 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/scheduler" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { +func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { ctx := context.Background() - workspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfigName, + workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplateName, }) if err != nil { return nil, err } - existingPrebuild, _ := workspaceConfig.FindPrebuild(&models.MatchParams{ + existingPrebuild, _ := workspaceTemplate.FindPrebuild(&models.MatchParams{ Branch: &createPrebuildDto.Branch, }) if existingPrebuild != nil && createPrebuildDto.Id == nil { - return nil, errors.New("prebuild for the specified workspace config and branch already exists") + return nil, errors.New("prebuild for the specified workspace template and branch already exists") } if createPrebuildDto.CommitInterval == nil && len(createPrebuildDto.TriggerFiles) == 0 { return nil, errors.New("either the commit interval or trigger files must be specified") } - repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceConfig.RepositoryUrl) + repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl) if err != nil { return nil, err } @@ -61,7 +61,7 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP } } - err = workspaceConfig.SetPrebuild(prebuild) + err = workspaceTemplate.SetPrebuild(prebuild) if err != nil { return nil, err } @@ -81,7 +81,7 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP } } - err = s.configStore.Save(workspaceConfig) + err = s.templateStore.Save(workspaceTemplate) if err != nil { if newWebhookId != "" { err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, newWebhookId) @@ -94,58 +94,58 @@ func (s *WorkspaceConfigService) SetPrebuild(workspaceConfigName string, createP } return &dto.PrebuildDTO{ - Id: prebuild.Id, - WorkspaceConfigName: workspaceConfig.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, + Id: prebuild.Id, + WorkspaceTemplateName: workspaceTemplate.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, }, nil } -func (s *WorkspaceConfigService) FindPrebuild(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { - wc, err := s.configStore.Find(workspaceConfigFilter) +func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { + wt, err := s.templateStore.Find(workspaceTemplateFilter) if err != nil { - return nil, stores.ErrWorkspaceConfigNotFound + return nil, stores.ErrWorkspaceTemplateNotFound } - prebuild, err := wc.FindPrebuild(&models.MatchParams{ - Id: prebuildFilter.Id, - Branch: prebuildFilter.Branch, - CommitInterval: prebuildFilter.CommitInterval, - TriggerFiles: prebuildFilter.TriggerFiles, - WorkspaceConfigName: prebuildFilter.WorkspaceConfigName, + prebuild, err := wt.FindPrebuild(&models.MatchParams{ + Id: prebuildFilter.Id, + Branch: prebuildFilter.Branch, + CommitInterval: prebuildFilter.CommitInterval, + TriggerFiles: prebuildFilter.TriggerFiles, + WorkspaceTemplateName: prebuildFilter.WorkspaceTemplateName, }) if err != nil { return nil, err } return &dto.PrebuildDTO{ - Id: prebuild.Id, - WorkspaceConfigName: wc.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, + Id: prebuild.Id, + WorkspaceTemplateName: wt.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, }, nil } -func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (s *WorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { var result []*dto.PrebuildDTO - wcs, err := s.configStore.List(workspaceConfigFilter) + wts, err := s.templateStore.List(workspaceTemplateFilter) if err != nil { - return nil, stores.ErrWorkspaceConfigNotFound + return nil, stores.ErrWorkspaceTemplateNotFound } - for _, wc := range wcs { - for _, prebuild := range wc.Prebuilds { + for _, wt := range wts { + for _, prebuild := range wt.Prebuilds { result = append(result, &dto.PrebuildDTO{ - Id: prebuild.Id, - WorkspaceConfigName: wc.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, + Id: prebuild.Id, + WorkspaceTemplateName: wt.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, }) } } @@ -153,27 +153,27 @@ func (s *WorkspaceConfigService) ListPrebuilds(workspaceConfigFilter *stores.Wor return result, nil } -func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id string, force bool) []error { +func (s *WorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, id string, force bool) []error { ctx := context.Background() - workspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfigName, + workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplateName, }) if err != nil { return []error{err} } - // Get all prebuilds for this workspace config's repository URL and + // Get all prebuilds for this workspace template's repository URL and // if this is the last prebuild, unregister the Git provider webhook - prebuilds, err := s.ListPrebuilds(&stores.WorkspaceConfigFilter{ - Url: &workspaceConfig.RepositoryUrl, + prebuilds, err := s.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + Url: &workspaceTemplate.RepositoryUrl, }, nil) if err != nil { return []error{err} } if len(prebuilds) == 1 { - repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceConfig.RepositoryUrl) + repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl) if err != nil { return []error{err} } @@ -210,12 +210,12 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s } } - err = workspaceConfig.RemovePrebuild(id) + err = workspaceTemplate.RemovePrebuild(id) if err != nil { return []error{err} } - err = s.configStore.Save(workspaceConfig) + err = s.templateStore.Save(workspaceTemplate) if err != nil { return []error{err} } @@ -225,10 +225,10 @@ func (s *WorkspaceConfigService) DeletePrebuild(workspaceConfigName string, id s // TODO: revise build trigger strategy // We should discuss if the function should throw if the build can not be created or move on to the next one -func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) error { +func (s *WorkspaceTemplateService) ProcessGitEvent(data gitprovider.GitEventData) error { ctx := context.Background() - workspaceConfigs, err := s.List(&stores.WorkspaceConfigFilter{ + workspaceTemplates, err := s.List(&stores.WorkspaceTemplateFilter{ Url: &data.Url, }) if err != nil { @@ -240,8 +240,8 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) return fmt.Errorf("failed to get repository context: %s", err) } - for _, workspaceConfig := range workspaceConfigs { - prebuild, err := workspaceConfig.FindPrebuild(&models.MatchParams{ + for _, workspaceTemplate := range workspaceTemplates { + prebuild, err := workspaceTemplate.FindPrebuild(&models.MatchParams{ Branch: &data.Branch, }) if err != nil || prebuild == nil { @@ -251,7 +251,7 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) // Check if the commit's affected files and prebuild config's trigger files have any overlap if len(prebuild.TriggerFiles) > 0 { if slicesHaveCommonEntry(prebuild.TriggerFiles, data.AffectedFiles) { - err := s.createBuild(ctx, workspaceConfig, repo, prebuild.Id) + err := s.createBuild(ctx, workspaceTemplate, repo, prebuild.Id) if err != nil { return fmt.Errorf("failed to create build: %s", err) } @@ -261,7 +261,7 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) newestBuild, err := s.findNewestBuild(ctx, prebuild.Id) if err != nil { - err := s.createBuild(ctx, workspaceConfig, repo, prebuild.Id) + err := s.createBuild(ctx, workspaceTemplate, repo, prebuild.Id) if err != nil { return fmt.Errorf("failed to create build: %s", err) } @@ -275,7 +275,7 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) // Check if the commit interval has been reached if prebuild.CommitInterval != nil && commitsRange >= *prebuild.CommitInterval { - err := s.createBuild(ctx, workspaceConfig, repo, prebuild.Id) + err := s.createBuild(ctx, workspaceTemplate, repo, prebuild.Id) if err != nil { return fmt.Errorf("failed to create build: %s", err) } @@ -286,7 +286,7 @@ func (s *WorkspaceConfigService) ProcessGitEvent(data gitprovider.GitEventData) } // Marks the [retention] oldest published builds for deletion for each prebuild -func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { +func (s *WorkspaceTemplateService) EnforceRetentionPolicy() error { ctx := context.Background() prebuilds, err := s.ListPrebuilds(nil, nil) @@ -334,7 +334,7 @@ func (s *WorkspaceConfigService) EnforceRetentionPolicy() error { return nil } -func (s *WorkspaceConfigService) StartRetentionPoller() error { +func (s *WorkspaceTemplateService) StartRetentionPoller() error { scheduler := scheduler.NewCronScheduler() err := scheduler.AddFunc(build.DEFAULT_BUILD_POLL_INTERVAL, func() { diff --git a/pkg/server/workspaceconfigs/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go similarity index 69% rename from pkg/server/workspaceconfigs/prebuild_test.go rename to pkg/server/workspacetemplates/prebuild_test.go index a74509341e..d83df0f3b1 100644 --- a/pkg/server/workspaceconfigs/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfigs_test +package workspacetemplates_test import ( "time" @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" ) @@ -39,12 +39,12 @@ var prebuild3 = &models.PrebuildConfig{ } var prebuild1Dto = &dto.PrebuildDTO{ - WorkspaceConfigName: workspaceConfig1.Name, - Id: prebuild1.Id, - Branch: prebuild1.Branch, - CommitInterval: prebuild1.CommitInterval, - Retention: prebuild1.Retention, - TriggerFiles: prebuild1.TriggerFiles, + WorkspaceTemplateName: workspaceTemplate1.Name, + Id: prebuild1.Id, + Branch: prebuild1.Branch, + CommitInterval: prebuild1.CommitInterval, + Retention: prebuild1.Retention, + TriggerFiles: prebuild1.TriggerFiles, } var repository1 *gitprovider.GitRepository = &gitprovider.GitRepository{ @@ -59,7 +59,7 @@ var expectedFilteredPrebuilds []*models.PrebuildConfig var expectedPrebuildsMap map[string]*models.PrebuildConfig var expectedFilteredPrebuildsMap map[string]*models.PrebuildConfig -func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { +func (s *WorkspaceTemplateServiceTestSuite) TestSetPrebuild() { require := s.Require() s.gitProviderService.On("GetGitProviderForUrl", repository1.Url).Return(&s.gitProvider, "github", nil) @@ -68,7 +68,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { }).Return(repository1, nil) s.gitProviderService.On("GetPrebuildWebhook", "github", repository1, "").Return(util.Pointer("webhook-id"), nil) - newPrebuildDto, err := s.workspaceConfigService.SetPrebuild(workspaceConfig1.Name, dto.CreatePrebuildDTO{ + newPrebuildDto, err := s.workspaceTemplateService.SetPrebuild(workspaceTemplate1.Name, dto.CreatePrebuildDTO{ Id: &prebuild3.Id, Branch: prebuild3.Branch, CommitInterval: prebuild3.CommitInterval, @@ -77,36 +77,36 @@ func (s *WorkspaceConfigServiceTestSuite) TestSetPrebuild() { }) require.Nil(err) - prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfig1.Name, + prebuildDtos, err := s.workspaceTemplateService.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplate1.Name, }, nil) require.Nil(err) require.Contains(prebuildDtos, newPrebuildDto) } -func (s *WorkspaceConfigServiceTestSuite) TestFindPrebuild() { +func (s *WorkspaceTemplateServiceTestSuite) TestFindPrebuild() { require := s.Require() - prebuild, err := s.workspaceConfigService.FindPrebuild(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfig1.Name, + prebuild, err := s.workspaceTemplateService.FindPrebuild(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplate1.Name, }, &stores.PrebuildFilter{ Id: &prebuild1.Id, }) require.Nil(err) require.Equal(prebuild1Dto, prebuild) } -func (s *WorkspaceConfigServiceTestSuite) TestListPrebuilds() { +func (s *WorkspaceTemplateServiceTestSuite) TestListPrebuilds() { require := s.Require() - prebuildDtos, err := s.workspaceConfigService.ListPrebuilds(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfig1.Name, + prebuildDtos, err := s.workspaceTemplateService.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplate1.Name, }, nil) require.Nil(err) require.Contains(prebuildDtos, prebuild1Dto) } -func (s *WorkspaceConfigServiceTestSuite) TestDeletePrebuild() { +func (s *WorkspaceTemplateServiceTestSuite) TestDeletePrebuild() { expectedPrebuilds = expectedPrebuilds[:1] require := s.Require() @@ -115,11 +115,11 @@ func (s *WorkspaceConfigServiceTestSuite) TestDeletePrebuild() { PrebuildIds: &[]string{prebuild2.Id}, }, false).Return([]error{}) - err := s.workspaceConfigService.DeletePrebuild(workspaceConfig1.Name, prebuild2.Id, false) + err := s.workspaceTemplateService.DeletePrebuild(workspaceTemplate1.Name, prebuild2.Id, false) require.Nil(err) - prebuildDtos, errs := s.workspaceConfigService.ListPrebuilds(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfig1.Name, + prebuildDtos, errs := s.workspaceTemplateService.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplate1.Name, }, nil) require.Nil(errs) require.ElementsMatch([]*dto.PrebuildDTO{ @@ -127,7 +127,7 @@ func (s *WorkspaceConfigServiceTestSuite) TestDeletePrebuild() { }, prebuildDtos) } -func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventCommitInterval() { +func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventCommitInterval() { require := s.Require() s.gitProviderService.On("GetGitProviderForUrl", repository1.Url).Return(&s.gitProvider, "github", nil) @@ -136,10 +136,10 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventCommitInterval() { }).Return(repository1, nil) s.buildService.On("Create", services.CreateBuildDTO{ - PrebuildId: &prebuild1.Id, - Branch: repository1.Branch, - WorkspaceConfigName: workspaceConfig1.Name, - EnvVars: workspaceConfig1.EnvVars, + PrebuildId: &prebuild1.Id, + Branch: repository1.Branch, + WorkspaceTemplateName: workspaceTemplate1.Name, + EnvVars: workspaceTemplate1.EnvVars, }).Return("", nil) s.buildService.On("Find", &stores.BuildFilter{ @@ -161,11 +161,11 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventCommitInterval() { s.gitProvider.On("GetCommitsRange", repository1, repository1.Sha, data.Sha).Return(3, nil) - err := s.workspaceConfigService.ProcessGitEvent(data) + err := s.workspaceTemplateService.ProcessGitEvent(data) require.Nil(err) } -func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { +func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventTriggerFiles() { require := s.Require() s.gitProviderService.On("GetGitProviderForUrl", repository1.Url).Return(&s.gitProvider, "github", nil) @@ -174,10 +174,10 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { }).Return(repository1, nil) s.buildService.On("Create", services.CreateBuildDTO{ - PrebuildId: &prebuild1.Id, - Branch: repository1.Branch, - WorkspaceConfigName: workspaceConfig1.Name, - EnvVars: workspaceConfig1.EnvVars, + PrebuildId: &prebuild1.Id, + Branch: repository1.Branch, + WorkspaceTemplateName: workspaceTemplate1.Name, + EnvVars: workspaceTemplate1.EnvVars, }).Return("", nil) data := gitprovider.GitEventData{ @@ -190,11 +190,11 @@ func (s *WorkspaceConfigServiceTestSuite) TestProcessGitEventTriggerFiles() { }, } - err := s.workspaceConfigService.ProcessGitEvent(data) + err := s.workspaceTemplateService.ProcessGitEvent(data) require.Nil(err) } -func (s *WorkspaceConfigServiceTestSuite) TestEnforceRetentionPolicy() { +func (s *WorkspaceTemplateServiceTestSuite) TestEnforceRetentionPolicy() { require := s.Require() s.buildService.On("List", &stores.BuildFilter{ @@ -230,6 +230,6 @@ func (s *WorkspaceConfigServiceTestSuite) TestEnforceRetentionPolicy() { Id: util.Pointer("1"), }, false).Return([]error{}) - err := s.workspaceConfigService.EnforceRetentionPolicy() + err := s.workspaceTemplateService.EnforceRetentionPolicy() require.Nil(err) } diff --git a/pkg/server/workspaceconfigs/service.go b/pkg/server/workspacetemplates/service.go similarity index 61% rename from pkg/server/workspaceconfigs/service.go rename to pkg/server/workspacetemplates/service.go index 3ebe41bf3e..2cdbe5f9de 100644 --- a/pkg/server/workspaceconfigs/service.go +++ b/pkg/server/workspacetemplates/service.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfigs +package workspacetemplates import ( "context" @@ -14,13 +14,13 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -type WorkspaceConfigServiceConfig struct { +type WorkspaceTemplateServiceConfig struct { PrebuildWebhookEndpoint string - ConfigStore stores.WorkspaceConfigStore + ConfigStore stores.WorkspaceTemplateStore FindNewestBuild func(ctx context.Context, prebuildId string) (*models.Build, error) ListPublishedBuilds func(ctx context.Context) ([]*models.Build, error) - CreateBuild func(ctx context.Context, wc *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error + CreateBuild func(ctx context.Context, wt *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error DeleteBuilds func(ctx context.Context, id, prebuildId *string, force bool) []error GetRepositoryContext func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) FindPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) @@ -29,13 +29,13 @@ type WorkspaceConfigServiceConfig struct { GetCommitsRange func(ctx context.Context, repo *gitprovider.GitRepository, initialSha string, currentSha string) (int, error) } -type WorkspaceConfigService struct { +type WorkspaceTemplateService struct { prebuildWebhookEndpoint string - configStore stores.WorkspaceConfigStore + templateStore stores.WorkspaceTemplateStore findNewestBuild func(ctx context.Context, prebuildId string) (*models.Build, error) listPublishedBuilds func(ctx context.Context) ([]*models.Build, error) - createBuild func(ctx context.Context, wc *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error + createBuild func(ctx context.Context, wt *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error deleteBuilds func(ctx context.Context, id, prebuildId *string, force bool) []error getRepositoryContext func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) getCommitsRange func(ctx context.Context, repo *gitprovider.GitRepository, initialSha string, currentSha string) (int, error) @@ -44,10 +44,10 @@ type WorkspaceConfigService struct { registerPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) } -func NewWorkspaceConfigService(config WorkspaceConfigServiceConfig) services.IWorkspaceConfigService { - return &WorkspaceConfigService{ +func NewWorkspaceTemplateService(config WorkspaceTemplateServiceConfig) services.IWorkspaceTemplateService { + return &WorkspaceTemplateService{ prebuildWebhookEndpoint: config.PrebuildWebhookEndpoint, - configStore: config.ConfigStore, + templateStore: config.ConfigStore, findNewestBuild: config.FindNewestBuild, listPublishedBuilds: config.ListPublishedBuilds, createBuild: config.CreateBuild, @@ -60,39 +60,39 @@ func NewWorkspaceConfigService(config WorkspaceConfigServiceConfig) services.IWo } } -func (s *WorkspaceConfigService) List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) { - return s.configStore.List(filter) +func (s *WorkspaceTemplateService) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + return s.templateStore.List(filter) } -func (s *WorkspaceConfigService) SetDefault(workspaceConfigName string) error { - workspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfigName, +func (s *WorkspaceTemplateService) SetDefault(workspaceTemplateName string) error { + workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplateName, }) if err != nil { return err } - defaultWorkspaceConfig, err := s.Find(&stores.WorkspaceConfigFilter{ - Url: &workspaceConfig.RepositoryUrl, + defaultWorkspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ + Url: &workspaceTemplate.RepositoryUrl, Default: util.Pointer(true), }) - if err != nil && !stores.IsWorkspaceConfigNotFound(err) { + if err != nil && !stores.IsWorkspaceTemplateNotFound(err) { return err } - if defaultWorkspaceConfig != nil { - defaultWorkspaceConfig.IsDefault = false - err := s.configStore.Save(defaultWorkspaceConfig) + if defaultWorkspaceTemplate != nil { + defaultWorkspaceTemplate.IsDefault = false + err := s.templateStore.Save(defaultWorkspaceTemplate) if err != nil { return err } } - workspaceConfig.IsDefault = true - return s.configStore.Save(workspaceConfig) + workspaceTemplate.IsDefault = true + return s.templateStore.Save(workspaceTemplate) } -func (s *WorkspaceConfigService) Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) { +func (s *WorkspaceTemplateService) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { if filter != nil && filter.Url != nil { cleanedUrl := util.CleanUpRepositoryUrl(*filter.Url) if !strings.HasSuffix(cleanedUrl, ".git") { @@ -100,37 +100,37 @@ func (s *WorkspaceConfigService) Find(filter *stores.WorkspaceConfigFilter) (*mo } filter.Url = util.Pointer(cleanedUrl) } - return s.configStore.Find(filter) + return s.templateStore.Find(filter) } -func (s *WorkspaceConfigService) Save(workspaceConfig *models.WorkspaceConfig) error { - workspaceConfig.RepositoryUrl = util.CleanUpRepositoryUrl(workspaceConfig.RepositoryUrl) +func (s *WorkspaceTemplateService) Save(workspaceTemplate *models.WorkspaceTemplate) error { + workspaceTemplate.RepositoryUrl = util.CleanUpRepositoryUrl(workspaceTemplate.RepositoryUrl) - err := s.configStore.Save(workspaceConfig) + err := s.templateStore.Save(workspaceTemplate) if err != nil { return err } - return s.SetDefault(workspaceConfig.Name) + return s.SetDefault(workspaceTemplate.Name) } -func (s *WorkspaceConfigService) Delete(workspaceConfigName string, force bool) []error { - wc, err := s.Find(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfigName, +func (s *WorkspaceTemplateService) Delete(workspaceTemplateName string, force bool) []error { + wt, err := s.Find(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplateName, }) if err != nil { return []error{err} } // DeletePrebuild handles deleting the builds and removing the webhook - for _, prebuild := range wc.Prebuilds { - errs := s.DeletePrebuild(wc.Name, prebuild.Id, force) + for _, prebuild := range wt.Prebuilds { + errs := s.DeletePrebuild(wt.Name, prebuild.Id, force) if len(errs) > 0 { return errs } } - err = s.configStore.Delete(wc) + err = s.templateStore.Delete(wt) if err != nil { return []error{err} } diff --git a/pkg/server/workspaceconfigs/service_test.go b/pkg/server/workspacetemplates/service_test.go similarity index 50% rename from pkg/server/workspaceconfigs/service_test.go rename to pkg/server/workspacetemplates/service_test.go index 7b00caf581..5e59291e85 100644 --- a/pkg/server/workspaceconfigs/service_test.go +++ b/pkg/server/workspacetemplates/service_test.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package workspaceconfigs_test +package workspacetemplates_test import ( "context" @@ -9,23 +9,23 @@ import ( git_provider_mock "github.com/daytonaio/daytona/internal/testing/gitprovider/mocks" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" - workspaceconfig_internal "github.com/daytonaio/daytona/internal/testing/server/workspaceconfig" + workspacetemplate_internal "github.com/daytonaio/daytona/internal/testing/server/workspacetemplate" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/suite" ) -var workspaceConfig1Image = "image1" -var workspaceConfig1User = "user1" +var workspaceTemplate1Image = "image1" +var workspaceTemplate1User = "user1" -var workspaceConfig1 = &models.WorkspaceConfig{ - Name: "wc1", - Image: workspaceConfig1Image, - User: workspaceConfig1User, +var workspaceTemplate1 = &models.WorkspaceTemplate{ + Name: "wt1", + Image: workspaceTemplate1Image, + User: workspaceTemplate1User, BuildConfig: nil, RepositoryUrl: repository1.Url, IsDefault: true, @@ -35,62 +35,62 @@ var workspaceConfig1 = &models.WorkspaceConfig{ }, } -var workspaceConfig2 = &models.WorkspaceConfig{ - Name: "wc2", +var workspaceTemplate2 = &models.WorkspaceTemplate{ + Name: "wt2", Image: "image2", User: "user2", BuildConfig: nil, RepositoryUrl: "https://github.com/daytonaio/daytona.git", } -var workspaceConfig3 = &models.WorkspaceConfig{ - Name: "wc3", +var workspaceTemplate3 = &models.WorkspaceTemplate{ + Name: "wt3", Image: "image3", User: "user3", BuildConfig: nil, RepositoryUrl: "https://github.com/daytonaio/daytona3.git", } -var workspaceConfig4 = &models.WorkspaceConfig{ - Name: "wc4", +var workspaceTemplate4 = &models.WorkspaceTemplate{ + Name: "wt4", Image: "image4", User: "user4", BuildConfig: nil, RepositoryUrl: "https://github.com/daytonaio/daytona4.git", } -var expectedWorkspaceConfigs []*models.WorkspaceConfig -var expectedFilteredWorkspaceConfigs []*models.WorkspaceConfig +var expectedWorkspaceTemplates []*models.WorkspaceTemplate +var expectedFilteredWorkspaceTemplates []*models.WorkspaceTemplate -var expectedWorkspaceConfigsMap map[string]*models.WorkspaceConfig -var expectedFilteredWorkspaceConfigsMap map[string]*models.WorkspaceConfig +var expectedWorkspaceTemplatesMap map[string]*models.WorkspaceTemplate +var expectedFilteredWorkspaceTemplatesMap map[string]*models.WorkspaceTemplate -type WorkspaceConfigServiceTestSuite struct { +type WorkspaceTemplateServiceTestSuite struct { suite.Suite - workspaceConfigService services.IWorkspaceConfigService - workspaceConfigStore stores.WorkspaceConfigStore - gitProviderService mocks.MockGitProviderService - buildService mocks.MockBuildService - gitProvider git_provider_mock.MockGitProvider + workspaceTemplateService services.IWorkspaceTemplateService + workspaceTemplateStore stores.WorkspaceTemplateStore + gitProviderService mocks.MockGitProviderService + buildService mocks.MockBuildService + gitProvider git_provider_mock.MockGitProvider } -func NewConfigServiceTestSuite() *WorkspaceConfigServiceTestSuite { - return &WorkspaceConfigServiceTestSuite{} +func NewConfigServiceTestSuite() *WorkspaceTemplateServiceTestSuite { + return &WorkspaceTemplateServiceTestSuite{} } -func (s *WorkspaceConfigServiceTestSuite) SetupTest() { - expectedWorkspaceConfigs = []*models.WorkspaceConfig{ - workspaceConfig1, workspaceConfig2, workspaceConfig3, +func (s *WorkspaceTemplateServiceTestSuite) SetupTest() { + expectedWorkspaceTemplates = []*models.WorkspaceTemplate{ + workspaceTemplate1, workspaceTemplate2, workspaceTemplate3, } expectedPrebuilds = []*models.PrebuildConfig{ prebuild1, prebuild2, } - expectedWorkspaceConfigsMap = map[string]*models.WorkspaceConfig{ - workspaceConfig1.Name: workspaceConfig1, - workspaceConfig2.Name: workspaceConfig2, - workspaceConfig3.Name: workspaceConfig3, + expectedWorkspaceTemplatesMap = map[string]*models.WorkspaceTemplate{ + workspaceTemplate1.Name: workspaceTemplate1, + workspaceTemplate2.Name: workspaceTemplate2, + workspaceTemplate3.Name: workspaceTemplate3, } expectedPrebuildsMap = map[string]*models.PrebuildConfig{ @@ -98,26 +98,26 @@ func (s *WorkspaceConfigServiceTestSuite) SetupTest() { prebuild2.Id: prebuild2, } - expectedFilteredWorkspaceConfigs = []*models.WorkspaceConfig{ - workspaceConfig1, workspaceConfig2, + expectedFilteredWorkspaceTemplates = []*models.WorkspaceTemplate{ + workspaceTemplate1, workspaceTemplate2, } expectedFilteredPrebuilds = []*models.PrebuildConfig{ prebuild1, } - expectedFilteredWorkspaceConfigsMap = map[string]*models.WorkspaceConfig{ - workspaceConfig1.Name: workspaceConfig1, - workspaceConfig2.Name: workspaceConfig2, + expectedFilteredWorkspaceTemplatesMap = map[string]*models.WorkspaceTemplate{ + workspaceTemplate1.Name: workspaceTemplate1, + workspaceTemplate2.Name: workspaceTemplate2, } expectedFilteredPrebuildsMap = map[string]*models.PrebuildConfig{ prebuild1.Id: prebuild1, } - s.workspaceConfigStore = workspaceconfig_internal.NewInMemoryWorkspaceConfigStore() - s.workspaceConfigService = workspaceconfigs.NewWorkspaceConfigService(workspaceconfigs.WorkspaceConfigServiceConfig{ - ConfigStore: s.workspaceConfigStore, + s.workspaceTemplateStore = workspacetemplate_internal.NewInMemoryWorkspaceTemplateStore() + s.workspaceTemplateService = workspacetemplates.NewWorkspaceTemplateService(workspacetemplates.WorkspaceTemplateServiceConfig{ + ConfigStore: s.workspaceTemplateStore, FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { return s.buildService.Find(&stores.BuildFilter{ PrebuildIds: &[]string{prebuildId}, @@ -129,12 +129,12 @@ func (s *WorkspaceConfigServiceTestSuite) SetupTest() { States: &[]models.BuildState{models.BuildStatePublished}, }) }, - CreateBuild: func(ctx context.Context, workspaceConfig *models.WorkspaceConfig, repo *gitprovider.GitRepository, prebuildId string) error { + CreateBuild: func(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error { createBuildDto := services.CreateBuildDTO{ - WorkspaceConfigName: workspaceConfig.Name, - Branch: repo.Branch, - PrebuildId: &prebuildId, - EnvVars: workspaceConfig.EnvVars, + WorkspaceTemplateName: workspaceTemplate.Name, + Branch: repo.Branch, + PrebuildId: &prebuildId, + EnvVars: workspaceTemplate.EnvVars, } _, err := s.buildService.Create(createBuildDto) @@ -182,74 +182,74 @@ func (s *WorkspaceConfigServiceTestSuite) SetupTest() { }, }) - for _, wc := range expectedWorkspaceConfigs { - _ = s.workspaceConfigStore.Save(wc) + for _, wt := range expectedWorkspaceTemplates { + _ = s.workspaceTemplateStore.Save(wt) } } -func TestWorkspaceConfigService(t *testing.T) { +func TestWorkspaceTemplateService(t *testing.T) { suite.Run(t, NewConfigServiceTestSuite()) } -func (s *WorkspaceConfigServiceTestSuite) TestList() { +func (s *WorkspaceTemplateServiceTestSuite) TestList() { require := s.Require() - workspaceConfigs, err := s.workspaceConfigService.List(nil) + workspaceTemplates, err := s.workspaceTemplateService.List(nil) require.Nil(err) - require.ElementsMatch(expectedWorkspaceConfigs, workspaceConfigs) + require.ElementsMatch(expectedWorkspaceTemplates, workspaceTemplates) } -func (s *WorkspaceConfigServiceTestSuite) TestFind() { +func (s *WorkspaceTemplateServiceTestSuite) TestFind() { require := s.Require() - workspaceConfig, err := s.workspaceConfigService.Find(&stores.WorkspaceConfigFilter{ - Name: &workspaceConfig1.Name, + workspaceTemplate, err := s.workspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplate1.Name, }) require.Nil(err) - require.Equal(workspaceConfig1, workspaceConfig) + require.Equal(workspaceTemplate1, workspaceTemplate) } -func (s *WorkspaceConfigServiceTestSuite) TestSetDefault() { +func (s *WorkspaceTemplateServiceTestSuite) TestSetDefault() { require := s.Require() - err := s.workspaceConfigService.SetDefault(workspaceConfig2.Name) + err := s.workspaceTemplateService.SetDefault(workspaceTemplate2.Name) require.Nil(err) - workspaceConfig, err := s.workspaceConfigService.Find(&stores.WorkspaceConfigFilter{ - Url: util.Pointer(workspaceConfig1.RepositoryUrl), + workspaceTemplate, err := s.workspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + Url: util.Pointer(workspaceTemplate1.RepositoryUrl), Default: util.Pointer(true), }) require.Nil(err) - require.Equal(workspaceConfig2, workspaceConfig) + require.Equal(workspaceTemplate2, workspaceTemplate) } -func (s *WorkspaceConfigServiceTestSuite) TestSave() { - expectedWorkspaceConfigs = append(expectedWorkspaceConfigs, workspaceConfig4) +func (s *WorkspaceTemplateServiceTestSuite) TestSave() { + expectedWorkspaceTemplates = append(expectedWorkspaceTemplates, workspaceTemplate4) require := s.Require() - err := s.workspaceConfigService.Save(workspaceConfig4) + err := s.workspaceTemplateService.Save(workspaceTemplate4) require.Nil(err) - workspaceConfigs, err := s.workspaceConfigService.List(nil) + workspaceTemplates, err := s.workspaceTemplateService.List(nil) require.Nil(err) - require.ElementsMatch(expectedWorkspaceConfigs, workspaceConfigs) + require.ElementsMatch(expectedWorkspaceTemplates, workspaceTemplates) } -func (s *WorkspaceConfigServiceTestSuite) TestDelete() { - expectedWorkspaceConfigs = expectedWorkspaceConfigs[:2] +func (s *WorkspaceTemplateServiceTestSuite) TestDelete() { + expectedWorkspaceTemplates = expectedWorkspaceTemplates[:2] require := s.Require() - err := s.workspaceConfigService.Delete(workspaceConfig3.Name, false) + err := s.workspaceTemplateService.Delete(workspaceTemplate3.Name, false) require.Nil(err) - workspaceConfigs, errs := s.workspaceConfigService.List(nil) + workspaceTemplates, errs := s.workspaceTemplateService.List(nil) require.Nil(errs) - require.ElementsMatch(expectedWorkspaceConfigs, workspaceConfigs) + require.ElementsMatch(expectedWorkspaceTemplates, workspaceTemplates) } -func (s *WorkspaceConfigServiceTestSuite) AfterTest(_, _ string) { +func (s *WorkspaceTemplateServiceTestSuite) AfterTest(_, _ string) { s.gitProviderService.AssertExpectations(s.T()) s.gitProviderService.ExpectedCalls = nil s.buildService.AssertExpectations(s.T()) diff --git a/pkg/services/build.go b/pkg/services/build.go index 1129d94cdd..08c3a792d7 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -22,8 +22,8 @@ type IBuildService interface { } type CreateBuildDTO struct { - WorkspaceConfigName string `json:"workspaceConfigName" validate:"required"` - Branch string `json:"branch" validate:"required"` - PrebuildId *string `json:"prebuildId" validate:"optional"` - EnvVars map[string]string `json:"envVars" validate:"required"` + WorkspaceTemplateName string `json:"workspaceTemplateName" validate:"required"` + Branch string `json:"branch" validate:"required"` + PrebuildId *string `json:"prebuildId" validate:"optional"` + EnvVars map[string]string `json:"envVars" validate:"required"` } // @name CreateBuildDTO diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 389b3e9791..bff0a5bd76 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -76,10 +76,10 @@ type CreateWorkspaceSourceDTO struct { } // @name CreateWorkspaceSourceDTO var ( - ErrWorkspaceAlreadyExists = errors.New("workspace already exists") - ErrWorkspaceDeleted = errors.New("workspace is deleted") - ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") - ErrInvalidWorkspaceConfig = errors.New("workspace config is invalid") + ErrWorkspaceAlreadyExists = errors.New("workspace already exists") + ErrWorkspaceDeleted = errors.New("workspace is deleted") + ErrInvalidWorkspaceName = errors.New("workspace name is not valid. Only [a-zA-Z0-9-_.] are allowed") + ErrInvalidWorkspaceTemplate = errors.New("workspace template is invalid") ) func IsWorkspaceDeleted(err error) bool { diff --git a/pkg/services/workspace_config.go b/pkg/services/workspace_config.go deleted file mode 100644 index 708b8ce17d..0000000000 --- a/pkg/services/workspace_config.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package services - -import ( - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspaceconfigs/dto" - "github.com/daytonaio/daytona/pkg/stores" -) - -type IWorkspaceConfigService interface { - Save(workspaceConfig *models.WorkspaceConfig) error - Find(filter *stores.WorkspaceConfigFilter) (*models.WorkspaceConfig, error) - List(filter *stores.WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) - SetDefault(workspaceConfigName string) error - Delete(workspaceConfigName string, force bool) []error - - SetPrebuild(workspaceConfigName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) - FindPrebuild(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) - ListPrebuilds(workspaceConfigFilter *stores.WorkspaceConfigFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) - DeletePrebuild(workspaceConfigName string, id string, force bool) []error - - StartRetentionPoller() error - EnforceRetentionPolicy() error - ProcessGitEvent(gitprovider.GitEventData) error -} diff --git a/pkg/services/workspace_template.go b/pkg/services/workspace_template.go new file mode 100644 index 0000000000..88ffdcffa2 --- /dev/null +++ b/pkg/services/workspace_template.go @@ -0,0 +1,28 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "github.com/daytonaio/daytona/pkg/gitprovider" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/stores" +) + +type IWorkspaceTemplateService interface { + Save(workspaceTemplate *models.WorkspaceTemplate) error + Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) + List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) + SetDefault(workspaceTemplateName string) error + Delete(workspaceTemplateName string, force bool) []error + + SetPrebuild(workspaceTemplateName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) + FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) + ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) + DeletePrebuild(workspaceTemplateName string, id string, force bool) []error + + StartRetentionPoller() error + EnforceRetentionPolicy() error + ProcessGitEvent(gitprovider.GitEventData) error +} diff --git a/pkg/stores/workspace_config.go b/pkg/stores/workspace_config.go deleted file mode 100644 index f6f5a33692..0000000000 --- a/pkg/stores/workspace_config.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package stores - -import ( - "errors" - - "github.com/daytonaio/daytona/pkg/models" -) - -type WorkspaceConfigFilter struct { - Name *string - Url *string - Default *bool - PrebuildId *string - GitProviderConfigId *string -} - -type PrebuildFilter struct { - WorkspaceConfigName *string - Id *string - Branch *string - CommitInterval *int - TriggerFiles *[]string -} - -type WorkspaceConfigStore interface { - List(filter *WorkspaceConfigFilter) ([]*models.WorkspaceConfig, error) - Find(filter *WorkspaceConfigFilter) (*models.WorkspaceConfig, error) - Save(workspaceConfig *models.WorkspaceConfig) error - Delete(workspaceConfig *models.WorkspaceConfig) error -} - -var ( - ErrWorkspaceConfigNotFound = errors.New("workspace config not found") - ErrPrebuildNotFound = errors.New("prebuild not found") -) - -func IsWorkspaceConfigNotFound(err error) bool { - return err.Error() == ErrWorkspaceConfigNotFound.Error() -} - -func IsPrebuildNotFound(err error) bool { - return err.Error() == ErrPrebuildNotFound.Error() -} diff --git a/pkg/stores/workspace_template.go b/pkg/stores/workspace_template.go new file mode 100644 index 0000000000..0052d031d9 --- /dev/null +++ b/pkg/stores/workspace_template.go @@ -0,0 +1,46 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type WorkspaceTemplateFilter struct { + Name *string + Url *string + Default *bool + PrebuildId *string + GitProviderConfigId *string +} + +type PrebuildFilter struct { + WorkspaceTemplateName *string + Id *string + Branch *string + CommitInterval *int + TriggerFiles *[]string +} + +type WorkspaceTemplateStore interface { + List(filter *WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) + Find(filter *WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) + Save(workspaceTemplate *models.WorkspaceTemplate) error + Delete(workspaceTemplate *models.WorkspaceTemplate) error +} + +var ( + ErrWorkspaceTemplateNotFound = errors.New("workspace template not found") + ErrPrebuildNotFound = errors.New("prebuild not found") +) + +func IsWorkspaceTemplateNotFound(err error) bool { + return err.Error() == ErrWorkspaceTemplateNotFound.Error() +} + +func IsPrebuildNotFound(err error) bool { + return err.Error() == ErrPrebuildNotFound.Error() +} diff --git a/pkg/views/build/info/view.go b/pkg/views/build/info/view.go index bad0d66fd0..7bfd515755 100644 --- a/pkg/views/build/info/view.go +++ b/pkg/views/build/info/view.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" - workspaceconfig_info "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" + workspacetemplate_info "github.com/daytonaio/daytona/pkg/views/workspacetemplate/info" "golang.org/x/term" ) @@ -45,8 +45,8 @@ func Render(b *apiclient.Build, apiServerConfig *apiclient.ServerConfig, forceUn output += getInfoLine("User", *b.User) + "\n" } - if workspaceconfig_info.GetLabelFromBuild(b.BuildConfig) != "" { - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + if workspacetemplate_info.GetLabelFromBuild(b.BuildConfig) != "" { + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, } diff --git a/pkg/views/prebuild/add/add.go b/pkg/views/prebuild/add/add.go index e4247e27e7..00c1d0d372 100644 --- a/pkg/views/prebuild/add/add.go +++ b/pkg/views/prebuild/add/add.go @@ -19,12 +19,12 @@ var DEFAULT_COMMIT_INTERVAL = "10" var DEFAULT_RETENTION = "3" type PrebuildAddView struct { - WorkspaceConfigName string - Branch string - CommitInterval string - TriggerFiles []string - Retention string - RunBuildOnAdd bool + WorkspaceTemplateName string + Branch string + CommitInterval string + TriggerFiles []string + Retention string + RunBuildOnAdd bool } func PrebuildCreationView(prebuildAddView *PrebuildAddView, editing bool) { diff --git a/pkg/views/prebuild/info/view.go b/pkg/views/prebuild/info/view.go index 74c2e448f4..9ff82f6dad 100644 --- a/pkg/views/prebuild/info/view.go +++ b/pkg/views/prebuild/info/view.go @@ -32,7 +32,7 @@ func Render(prebuild *apiclient.PrebuildDTO, forceUnstyled bool) { output += getInfoLine("ID", prebuild.Id) + "\n" - output += getInfoLine("Workspace config", prebuild.WorkspaceConfigName) + "\n" + output += getInfoLine("Workspace template", prebuild.WorkspaceTemplateName) + "\n" output += getInfoLine("Branch", views.GetBranchNameLabel(prebuild.Branch)) + "\n" diff --git a/pkg/views/prebuild/list/view.go b/pkg/views/prebuild/list/view.go index e0ba9f9a7c..dbeebacaa2 100644 --- a/pkg/views/prebuild/list/view.go +++ b/pkg/views/prebuild/list/view.go @@ -17,11 +17,11 @@ import ( var maxTriggerFilesStringLength = 24 type rowData struct { - WorkspaceConfigName string - Branch string - CommitInterval string - TriggerFiles string - Retention string + WorkspaceTemplateName string + Branch string + CommitInterval string + TriggerFiles string + Retention string } func ListPrebuilds(prebuildList []apiclient.PrebuildDTO) { @@ -37,7 +37,7 @@ func ListPrebuilds(prebuildList []apiclient.PrebuildDTO) { } table := util.GetTableView(data, []string{ - "Workspace Config", "Branch", "Commit Interval", "Trigger files", "Build Retention", + "Workspace Template", "Branch", "Commit Interval", "Trigger files", "Build Retention", }, nil, func() { renderUnstyledList(prebuildList) }) @@ -46,10 +46,10 @@ func ListPrebuilds(prebuildList []apiclient.PrebuildDTO) { } func renderUnstyledList(prebuildList []apiclient.PrebuildDTO) { - for _, wc := range prebuildList { - info.Render(&wc, true) + for _, p := range prebuildList { + info.Render(&p, true) - if wc.Id != prebuildList[len(prebuildList)-1].Id { + if p.Id != prebuildList[len(prebuildList)-1].Id { fmt.Printf("\n%s\n\n", views.SeparatorString) } } @@ -58,7 +58,7 @@ func renderUnstyledList(prebuildList []apiclient.PrebuildDTO) { func getRowFromData(prebuildConfig apiclient.PrebuildDTO) []string { var data rowData - data.WorkspaceConfigName = prebuildConfig.WorkspaceConfigName + views_util.AdditionalPropertyPadding + data.WorkspaceTemplateName = prebuildConfig.WorkspaceTemplateName + views_util.AdditionalPropertyPadding data.Branch = prebuildConfig.Branch if prebuildConfig.CommitInterval != nil { data.CommitInterval = strconv.Itoa(int(*prebuildConfig.CommitInterval)) @@ -69,7 +69,7 @@ func getRowFromData(prebuildConfig apiclient.PrebuildDTO) []string { data.Retention = strconv.Itoa(int(prebuildConfig.Retention)) return []string{ - views.NameStyle.Render(data.WorkspaceConfigName), + views.NameStyle.Render(data.WorkspaceTemplateName), views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(data.Branch)), views.ActiveStyle.Render(data.CommitInterval), views.DefaultRowDataStyle.Render(data.TriggerFiles), diff --git a/pkg/views/selection/prebuild.go b/pkg/views/selection/prebuild.go index 6d36b32f78..44b529e01c 100644 --- a/pkg/views/selection/prebuild.go +++ b/pkg/views/selection/prebuild.go @@ -25,7 +25,7 @@ func selectPrebuildPrompt(prebuilds []apiclient.PrebuildDTO, actionVerb string, items := []list.Item{} for _, pb := range prebuilds { - title := fmt.Sprintf("%s (%s)", pb.WorkspaceConfigName, views.GetBranchNameLabel(pb.Branch)) + title := fmt.Sprintf("%s (%s)", pb.WorkspaceTemplateName, views.GetBranchNameLabel(pb.Branch)) desc := pb.Id if pb.CommitInterval != nil { diff --git a/pkg/views/selection/workspaceconfig.go b/pkg/views/selection/workspacetemplate.go similarity index 51% rename from pkg/views/selection/workspaceconfig.go rename to pkg/views/selection/workspacetemplate.go index 75921666c3..d8548dbc27 100644 --- a/pkg/views/selection/workspaceconfig.go +++ b/pkg/views/selection/workspacetemplate.go @@ -16,37 +16,37 @@ import ( ) var BlankWorkspaceIdentifier = "" -var NewWorkspaceConfigIdentifier = "" +var NewWorkspaceTemplateIdentifier = "" -func GetWorkspaceConfigFromPrompt(workspaceConfigs []apiclient.WorkspaceConfig, workspaceOrder int, showBlankOption, withNewWorkspaceConfig bool, actionVerb string) *apiclient.WorkspaceConfig { - choiceChan := make(chan *apiclient.WorkspaceConfig) - go selectWorkspaceConfigPrompt(workspaceConfigs, workspaceOrder, showBlankOption, withNewWorkspaceConfig, actionVerb, choiceChan) +func GetWorkspaceTemplateFromPrompt(workspaceTemplates []apiclient.WorkspaceTemplate, workspaceOrder int, showBlankOption, withNewWorkspaceTemplate bool, actionVerb string) *apiclient.WorkspaceTemplate { + choiceChan := make(chan *apiclient.WorkspaceTemplate) + go selectWorkspaceTemplatePrompt(workspaceTemplates, workspaceOrder, showBlankOption, withNewWorkspaceTemplate, actionVerb, choiceChan) return <-choiceChan } -func selectWorkspaceConfigPrompt(workspaceConfigs []apiclient.WorkspaceConfig, workspaceOrder int, showBlankOption, withNewWorkspaceConfig bool, actionVerb string, choiceChan chan<- *apiclient.WorkspaceConfig) { +func selectWorkspaceTemplatePrompt(workspaceTemplates []apiclient.WorkspaceTemplate, workspaceOrder int, showBlankOption, withNewWorkspaceTemplate bool, actionVerb string, choiceChan chan<- *apiclient.WorkspaceTemplate) { items := []list.Item{} if showBlankOption { - newItem := item[apiclient.WorkspaceConfig]{title: "Make a blank workspace", desc: "(default workspace configuration)", choiceProperty: apiclient.WorkspaceConfig{ + newItem := item[apiclient.WorkspaceTemplate]{title: "Make a blank workspace", desc: "(default workspace configuration)", choiceProperty: apiclient.WorkspaceTemplate{ Name: BlankWorkspaceIdentifier, }} items = append(items, newItem) } - for _, wc := range workspaceConfigs { - workspaceConfigName := wc.Name - if wc.Name == "" { - workspaceConfigName = "Unnamed Workspace Config" + for _, wt := range workspaceTemplates { + workspaceTemplateName := wt.Name + if wt.Name == "" { + workspaceTemplateName = "Unnamed Workspace Template" } - newItem := item[apiclient.WorkspaceConfig]{title: workspaceConfigName, desc: wc.RepositoryUrl, choiceProperty: wc} + newItem := item[apiclient.WorkspaceTemplate]{title: workspaceTemplateName, desc: wt.RepositoryUrl, choiceProperty: wt} items = append(items, newItem) } - if withNewWorkspaceConfig { - newItem := item[apiclient.WorkspaceConfig]{title: "+ Create a new workspace configuration", desc: "", choiceProperty: apiclient.WorkspaceConfig{ - Name: NewWorkspaceConfigIdentifier, + if withNewWorkspaceTemplate { + newItem := item[apiclient.WorkspaceTemplate]{title: "+ Create a new workspace template", desc: "", choiceProperty: apiclient.WorkspaceTemplate{ + Name: NewWorkspaceTemplateIdentifier, }} items = append(items, newItem) } @@ -70,14 +70,14 @@ func selectWorkspaceConfigPrompt(workspaceConfigs []apiclient.WorkspaceConfig, w l.FilterInput.PromptStyle = lipgloss.NewStyle().Foreground(views.Green) l.FilterInput.TextStyle = lipgloss.NewStyle().Foreground(views.Green) - title := "Select a Workspace Config To " + actionVerb + title := "Select a Workspace Template To " + actionVerb if workspaceOrder > 1 { title += fmt.Sprintf(" (Workspace #%d)", workspaceOrder) } l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle - m := model[apiclient.WorkspaceConfig]{list: l} + m := model[apiclient.WorkspaceTemplate]{list: l} p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { @@ -85,7 +85,7 @@ func selectWorkspaceConfigPrompt(workspaceConfigs []apiclient.WorkspaceConfig, w os.Exit(1) } - if m, ok := p.(model[apiclient.WorkspaceConfig]); ok && m.choice != nil { + if m, ok := p.(model[apiclient.WorkspaceTemplate]); ok && m.choice != nil { choiceChan <- m.choice } else { choiceChan <- nil diff --git a/pkg/views/util/build_choice.go b/pkg/views/util/build_choice.go index ac18c7578b..cefa3e4fbb 100644 --- a/pkg/views/util/build_choice.go +++ b/pkg/views/util/build_choice.go @@ -18,14 +18,14 @@ const ( NONE BuildChoice = "none" ) -type WorkspaceConfigDefaults struct { +type WorkspaceTemplateDefaults struct { BuildChoice BuildChoice Image *string ImageUser *string DevcontainerFilePath string } -func GetWorkspaceBuildChoice(workspace apiclient.CreateWorkspaceDTO, defaults *WorkspaceConfigDefaults) (BuildChoice, string) { +func GetWorkspaceBuildChoice(workspace apiclient.CreateWorkspaceDTO, defaults *WorkspaceTemplateDefaults) (BuildChoice, string) { if workspace.BuildConfig == nil { if workspace.Image != nil && workspace.User != nil && defaults.Image != nil && defaults.ImageUser != nil && diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index e50eee081e..d9836c7829 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -26,10 +26,10 @@ func NotifyEmptyTargetConfigList(tip bool) { } } -func NotifyEmptyWorkspaceConfigList(tip bool) { - views.RenderInfoMessageBold("No workspace configs found") +func NotifyEmptyWorkspaceTemplateList(tip bool) { + views.RenderInfoMessageBold("No workspace templates found") if tip { - views.RenderTip("Use 'daytona workspace-config add' to add a workspace config") + views.RenderTip("Use 'daytona workspace-template add' to add a workspace template") } } diff --git a/pkg/views/workspace/create/configuration.go b/pkg/views/workspace/create/configuration.go index 8ad666c0fd..acd8fd087e 100644 --- a/pkg/views/workspace/create/configuration.go +++ b/pkg/views/workspace/create/configuration.go @@ -33,7 +33,7 @@ type WorkspaceConfigurationData struct { EnvVars map[string]string } -func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePath string, currentWorkspace *apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults) *WorkspaceConfigurationData { +func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePath string, currentWorkspace *apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceTemplateDefaults) *WorkspaceConfigurationData { workspaceConfigurationData := &WorkspaceConfigurationData{ Name: currentWorkspace.Name, BuildChoice: string(buildChoice), @@ -58,7 +58,7 @@ func NewConfigurationData(buildChoice views_util.BuildChoice, devContainerFilePa return workspaceConfigurationData } -func RunWorkspaceConfiguration(workspaceList *[]apiclient.CreateWorkspaceDTO, defaults views_util.WorkspaceConfigDefaults, isTemplateImport bool) (bool, error) { +func RunWorkspaceConfiguration(workspaceList *[]apiclient.CreateWorkspaceDTO, defaults views_util.WorkspaceTemplateDefaults, isTemplateImport bool) (bool, error) { var currentWorkspace *apiclient.CreateWorkspaceDTO if len(*workspaceList) > 1 { diff --git a/pkg/views/workspace/create/summary.go b/pkg/views/workspace/create/summary.go index d15abdeed2..d5c692682f 100644 --- a/pkg/views/workspace/create/summary.go +++ b/pkg/views/workspace/create/summary.go @@ -40,7 +40,7 @@ type SummaryModel struct { quitting bool name string workspaceList []apiclient.CreateWorkspaceDTO - defaults *views_util.WorkspaceConfigDefaults + defaults *views_util.WorkspaceTemplateDefaults nameLabel string } @@ -49,7 +49,7 @@ type SubmissionFormParams struct { SuggestedName string WorkspaceList *[]apiclient.CreateWorkspaceDTO NameLabel string - Defaults *views_util.WorkspaceConfigDefaults + Defaults *views_util.WorkspaceTemplateDefaults ExistingWorkspaceNames []string ImportConfirmation *bool } @@ -93,12 +93,12 @@ func RunSubmissionForm(params SubmissionFormParams) error { return RunSubmissionForm(params) } -func RenderSummary(name string, workspaceList []apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceConfigDefaults, nameLabel string) (string, error) { +func RenderSummary(name string, workspaceList []apiclient.CreateWorkspaceDTO, defaults *views_util.WorkspaceTemplateDefaults, nameLabel string) (string, error) { var output string if nameLabel == "" { output = views.GetStyledMainTitle("SUMMARY") } else { - output = views.GetStyledMainTitle(fmt.Sprintf("SUMMARY - Target %s", nameLabel)) + output = views.GetStyledMainTitle(fmt.Sprintf("SUMMARY - %s", nameLabel)) } output += "\n\n" diff --git a/pkg/views/workspaceconfig/info/view.go b/pkg/views/workspacetemplate/info/view.go similarity index 70% rename from pkg/views/workspaceconfig/info/view.go rename to pkg/views/workspacetemplate/info/view.go index 34e76d7416..4e0774fd76 100644 --- a/pkg/views/workspaceconfig/info/view.go +++ b/pkg/views/workspacetemplate/info/view.go @@ -27,61 +27,61 @@ var propertyValueStyle = lipgloss.NewStyle(). var prebuildDetailStyle = propertyNameStyle -func Render(workspaceConfig *apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig, forceUnstyled bool) { +func Render(workspaceTemplate *apiclient.WorkspaceTemplate, apiServerConfig *apiclient.ServerConfig, forceUnstyled bool) { var output string output += "\n\n" - output += views.GetStyledMainTitle("Workspace Config Info") + "\n\n" + output += views.GetStyledMainTitle("Workspace Template Info") + "\n\n" - output += getInfoLine("Name", workspaceConfig.Name) + "\n" + output += getInfoLine("Name", workspaceTemplate.Name) + "\n" - output += getInfoLine("Repository", workspaceConfig.RepositoryUrl) + "\n" + output += getInfoLine("Repository", workspaceTemplate.RepositoryUrl) + "\n" gitProviderConfig := "/" - if workspaceConfig.GitProviderConfigId != nil { - gitProviderConfig = *workspaceConfig.GitProviderConfigId + if workspaceTemplate.GitProviderConfigId != nil { + gitProviderConfig = *workspaceTemplate.GitProviderConfigId } output += getInfoLine("Git Provider ID", gitProviderConfig) + "\n" - if workspaceConfig.Default { + if workspaceTemplate.Default { output += getInfoLine("Default", "Yes") + "\n" } - if GetLabelFromBuild(workspaceConfig.BuildConfig) != "" { - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + if GetLabelFromBuild(workspaceTemplate.BuildConfig) != "" { + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, } createWorkspaceDto := apiclient.CreateWorkspaceDTO{ - BuildConfig: workspaceConfig.BuildConfig, + BuildConfig: workspaceTemplate.BuildConfig, } _, buildChoice := views_util.GetWorkspaceBuildChoice(createWorkspaceDto, workspaceDefaults) output += getInfoLine("Build", buildChoice) + "\n" } - if workspaceConfig.Image != "" { - output += getInfoLine("Image", workspaceConfig.Image) + "\n" + if workspaceTemplate.Image != "" { + output += getInfoLine("Image", workspaceTemplate.Image) + "\n" } - if workspaceConfig.User != "" { - output += getInfoLine("User", workspaceConfig.User) + "\n" + if workspaceTemplate.User != "" { + output += getInfoLine("User", workspaceTemplate.User) + "\n" } - if workspaceConfig.BuildConfig != nil && workspaceConfig.BuildConfig.Devcontainer != nil { - output += getInfoLine("Devcontainer path", workspaceConfig.BuildConfig.Devcontainer.FilePath) + "\n" + if workspaceTemplate.BuildConfig != nil && workspaceTemplate.BuildConfig.Devcontainer != nil { + output += getInfoLine("Devcontainer path", workspaceTemplate.BuildConfig.Devcontainer.FilePath) + "\n" } - prebuildCount := len(workspaceConfig.Prebuilds) + prebuildCount := len(workspaceTemplate.Prebuilds) if prebuildCount > 0 { if prebuildCount == 1 { - output += getInfoLine("Prebuild: ", getPrebuildLine(workspaceConfig.Prebuilds[0], nil)) + "\n" + output += getInfoLine("Prebuild: ", getPrebuildLine(workspaceTemplate.Prebuilds[0], nil)) + "\n" } else { output += getInfoLine("Prebuilds: ", "") + "\n" - for i, prebuild := range workspaceConfig.Prebuilds { - if len(workspaceConfig.Prebuilds) != 1 { + for i, prebuild := range workspaceTemplate.Prebuilds { + if len(workspaceTemplate.Prebuilds) != 1 { output += getPrebuildLine(prebuild, util.Pointer(i+1)) + "\n" } else { output += getPrebuildLine(prebuild, nil) + "\n" diff --git a/pkg/views/workspaceconfig/list/view.go b/pkg/views/workspacetemplate/list/view.go similarity index 50% rename from pkg/views/workspaceconfig/list/view.go rename to pkg/views/workspacetemplate/list/view.go index fd992b6fcc..80e135c6c9 100644 --- a/pkg/views/workspaceconfig/list/view.go +++ b/pkg/views/workspacetemplate/list/view.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/daytonaio/daytona/pkg/views/workspaceconfig/info" + "github.com/daytonaio/daytona/pkg/views/workspacetemplate/info" ) type rowData struct { @@ -21,64 +21,64 @@ type rowData struct { IsDefault string } -func ListWorkspaceConfigs(workspaceConfigList []apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) { - if len(workspaceConfigList) == 0 { - views_util.NotifyEmptyWorkspaceConfigList(true) +func ListWorkspaceTemplates(workspaceTemplateList []apiclient.WorkspaceTemplate, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) { + if len(workspaceTemplateList) == 0 { + views_util.NotifyEmptyWorkspaceTemplateList(true) return } data := [][]string{} - for _, wc := range workspaceConfigList { - data = append(data, getRowFromData(wc, apiServerConfig, specifyGitProviders)) + for _, wt := range workspaceTemplateList { + data = append(data, getRowFromData(wt, apiServerConfig, specifyGitProviders)) } table := views_util.GetTableView(data, []string{ "Name", "Repository", "Build", "Prebuild rules", "Default", }, nil, func() { - renderUnstyledList(workspaceConfigList, apiServerConfig) + renderUnstyledList(workspaceTemplateList, apiServerConfig) }) fmt.Println(table) } -func renderUnstyledList(workspaceConfigList []apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig) { - for _, wc := range workspaceConfigList { - info.Render(&wc, apiServerConfig, true) +func renderUnstyledList(workspaceTemplateList []apiclient.WorkspaceTemplate, apiServerConfig *apiclient.ServerConfig) { + for _, wt := range workspaceTemplateList { + info.Render(&wt, apiServerConfig, true) - if wc.Name != workspaceConfigList[len(workspaceConfigList)-1].Name { + if wt.Name != workspaceTemplateList[len(workspaceTemplateList)-1].Name { fmt.Printf("\n%s\n\n", views.SeparatorString) } } } -func getRowFromData(workspaceConfig apiclient.WorkspaceConfig, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) []string { +func getRowFromData(workspaceTemplate apiclient.WorkspaceTemplate, apiServerConfig *apiclient.ServerConfig, specifyGitProviders bool) []string { var isDefault string var data rowData - data.Name = workspaceConfig.Name + views_util.AdditionalPropertyPadding - data.Repository = util.GetRepositorySlugFromUrl(workspaceConfig.RepositoryUrl, specifyGitProviders) + data.Name = workspaceTemplate.Name + views_util.AdditionalPropertyPadding + data.Repository = util.GetRepositorySlugFromUrl(workspaceTemplate.RepositoryUrl, specifyGitProviders) data.Prebuilds = "None" - workspaceDefaults := &views_util.WorkspaceConfigDefaults{ + workspaceDefaults := &views_util.WorkspaceTemplateDefaults{ Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, } createWorkspaceDto := apiclient.CreateWorkspaceDTO{ - BuildConfig: workspaceConfig.BuildConfig, + BuildConfig: workspaceTemplate.BuildConfig, } _, data.Build = views_util.GetWorkspaceBuildChoice(createWorkspaceDto, workspaceDefaults) - if workspaceConfig.Default { + if workspaceTemplate.Default { isDefault = views.ActiveStyle.Render("Yes") } else { isDefault = views.InactiveStyle.Render("/") } - if len(workspaceConfig.Prebuilds) > 0 { - data.Prebuilds = fmt.Sprintf("%d", len(workspaceConfig.Prebuilds)) + if len(workspaceTemplate.Prebuilds) > 0 { + data.Prebuilds = fmt.Sprintf("%d", len(workspaceTemplate.Prebuilds)) } return []string{ From 9bef3814d30e5c864dffd1c57d376307a214fd02 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 2 Dec 2024 14:51:05 +0100 Subject: [PATCH 16/76] fix: disallow concurrent jobs (#1405) Signed-off-by: Toma Puljak --- internal/testing/job/store.go | 7 +++ pkg/cmd/server/bootstrap/get_job_runner.go | 2 +- .../server/bootstrap/get_server_instance.go | 4 +- pkg/db/job_store.go | 3 + pkg/server/jobs/service.go | 26 +++++++- pkg/server/jobs/service_test.go | 59 ++++++++++++------- pkg/services/job.go | 3 +- pkg/stores/job_store.go | 8 ++- 8 files changed, 85 insertions(+), 27 deletions(-) diff --git a/internal/testing/job/store.go b/internal/testing/job/store.go index 7f09149e71..5332679ede 100644 --- a/internal/testing/job/store.go +++ b/internal/testing/job/store.go @@ -97,6 +97,13 @@ func (s *InMemoryJobStore) processFilters(filter *stores.JobFilter) ([]*models.J } } } + if filter.ResourceId != nil { + for _, job := range filteredJobs { + if job.ResourceId != *filter.ResourceId { + delete(filteredJobs, job.Id) + } + } + } } for _, job := range filteredJobs { diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go index 08e01391d0..b2af45919e 100644 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -47,7 +47,7 @@ func GetJobRunner(c *server.Config, configDir string, version string, telemetryS if err != nil { job.Error = util.Pointer((*err).Error()) } - return jobService.Save(job) + return jobService.Update(job) }, WorkspaceJobFactory: workspaceJobFactory, TargetJobFactory: targetJobFactory, diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index d82ec5eb20..d87cad79d8 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -299,7 +299,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return apiKeyService.Revoke(name) }, CreateJob: func(ctx context.Context, targetId string, action models.JobAction) error { - return jobService.Save(&models.Job{ + return jobService.Create(&models.Job{ ResourceId: targetId, ResourceType: models.ResourceTypeTarget, Action: action, @@ -369,7 +369,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return gitProviderService.GetLastCommitSha(repo) }, CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { - return jobService.Save(&models.Job{ + return jobService.Create(&models.Job{ ResourceId: workspaceId, ResourceType: models.ResourceTypeWorkspace, Action: action, diff --git a/pkg/db/job_store.go b/pkg/db/job_store.go index a8eec4e5d7..f2d4e6a3fa 100644 --- a/pkg/db/job_store.go +++ b/pkg/db/job_store.go @@ -79,6 +79,9 @@ func processJobFilters(tx *gorm.DB, filter *stores.JobFilter) *gorm.DB { if filter.ResourceType != nil { tx = tx.Where("resource_type = ?", *filter.ResourceType) } + if filter.ResourceId != nil { + tx = tx.Where("resource_id = ?", *filter.ResourceId) + } if filter.States != nil && len(*filter.States) > 0 { placeholders := strings.Repeat("?,", len(*filter.States)) placeholders = placeholders[:len(placeholders)-1] diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index 3ea88a2d52..88e1e548d2 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -32,7 +32,20 @@ func (s *JobService) Find(filter *stores.JobFilter) (*models.Job, error) { return s.jobStore.Find(filter) } -func (s *JobService) Save(j *models.Job) error { +func (s *JobService) Create(j *models.Job) error { + pendingJobs, err := s.List(&stores.JobFilter{ + ResourceId: &j.ResourceId, + ResourceType: &j.ResourceType, + States: &[]models.JobState{models.JobStatePending, models.JobStateRunning}, + }) + if err != nil { + return err + } + + if len(pendingJobs) > 0 { + return stores.ErrJobInProgress + } + if j.Id == "" { id := stringid.GenerateRandomID() id = stringid.TruncateID(id) @@ -41,6 +54,17 @@ func (s *JobService) Save(j *models.Job) error { return s.jobStore.Save(j) } +func (s *JobService) Update(j *models.Job) error { + _, err := s.Find(&stores.JobFilter{ + Id: &j.Id, + }) + if err != nil { + return err + } + + return s.jobStore.Save(j) +} + func (s *JobService) Delete(j *models.Job) error { return s.jobStore.Delete(j) } diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go index 20f13f595f..237ac4dfc4 100644 --- a/pkg/server/jobs/service_test.go +++ b/pkg/server/jobs/service_test.go @@ -15,10 +15,6 @@ import ( ) var expectedJobs []*models.Job -var expectedFilteredJobs []*models.Job - -var expectedJobsMap map[string]*models.Job -var expectedFilteredJobsMap map[string]*models.Job var job1 = &models.Job{ Id: "1", @@ -63,21 +59,6 @@ func (s *JobServiceTestSuite) SetupTest() { job1, job2, job3, } - expectedJobsMap = map[string]*models.Job{ - job1.Id: job1, - job2.Id: job2, - job3.Id: job3, - } - - expectedFilteredJobs = []*models.Job{ - job1, job2, - } - - expectedFilteredJobsMap = map[string]*models.Job{ - job1.Id: job1, - job2.Id: job2, - } - s.jobStore = job_internal.NewInMemoryJobStore() s.jobService = jobs.NewJobService(jobs.JobServiceConfig{ JobStore: s.jobStore, @@ -110,12 +91,12 @@ func (s *JobServiceTestSuite) TestFind() { require.Equal(job1, job) } -func (s *JobServiceTestSuite) TestSave() { +func (s *JobServiceTestSuite) TestCreate() { expectedJobs = append(expectedJobs, job4) require := s.Require() - err := s.jobService.Save(job4) + err := s.jobService.Create(job4) require.Nil(err) jobs, err := s.jobService.List(nil) @@ -123,6 +104,42 @@ func (s *JobServiceTestSuite) TestSave() { require.ElementsMatch(expectedJobs, jobs) } +func (s *JobServiceTestSuite) TestUpdate() { + require := s.Require() + + err := s.jobService.Create(job4) + require.Nil(err) + + job4Update := *job4 + job4Update.State = models.JobStateSuccess + + err = s.jobService.Update(&job4Update) + require.Nil(err) + + updated, err := s.jobService.Find(&stores.JobFilter{ + Id: &job4.Id, + }) + require.Nil(err) + require.Equal(job4Update, *updated) +} + +func (s *JobServiceTestSuite) TestCreateWithAnotherJobInProgress() { + require := s.Require() + + err := s.jobService.Create(job4) + require.Nil(err) + + var job5 = &models.Job{ + Id: "5", + ResourceId: "4", + Action: models.JobActionStart, + State: models.JobStatePending, + } + + err = s.jobService.Create(job5) + require.EqualError(err, stores.ErrJobInProgress.Error()) +} + func (s *JobServiceTestSuite) TestDelete() { expectedJobs = expectedJobs[:2] diff --git a/pkg/services/job.go b/pkg/services/job.go index c1feae08dc..5a473dc2d0 100644 --- a/pkg/services/job.go +++ b/pkg/services/job.go @@ -9,7 +9,8 @@ import ( ) type IJobService interface { - Save(job *models.Job) error + Create(job *models.Job) error + Update(job *models.Job) error Find(filter *stores.JobFilter) (*models.Job, error) List(filter *stores.JobFilter) ([]*models.Job, error) Delete(job *models.Job) error diff --git a/pkg/stores/job_store.go b/pkg/stores/job_store.go index f00206ac65..761f4b402f 100644 --- a/pkg/stores/job_store.go +++ b/pkg/stores/job_store.go @@ -18,6 +18,7 @@ type JobStore interface { type JobFilter struct { Id *string + ResourceId *string ResourceType *models.ResourceType States *[]models.JobState Actions *[]models.JobAction @@ -40,9 +41,14 @@ func (f *JobFilter) ActionsToInterface() []interface{} { } var ( - ErrJobNotFound = errors.New("job not found") + ErrJobNotFound = errors.New("job not found") + ErrJobInProgress = errors.New("another job is in progress") ) func IsJobNotFound(err error) bool { return err.Error() == ErrJobNotFound.Error() } + +func IsJobInProgress(err error) bool { + return err.Error() == ErrJobInProgress.Error() +} From a111348f115a6daab8cc6d4d9eff0769ccdf043a Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Wed, 4 Dec 2024 09:19:15 +0000 Subject: [PATCH 17/76] telemetry: disable polling requests Signed-off-by: Toma Puljak --- pkg/api/middlewares/telemetry.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/api/middlewares/telemetry.go b/pkg/api/middlewares/telemetry.go index c5049ccfee..d2a8620659 100644 --- a/pkg/api/middlewares/telemetry.go +++ b/pkg/api/middlewares/telemetry.go @@ -17,10 +17,12 @@ import ( ) var ignorePaths = map[string]bool{ - "/health": true, - "/target/:targetId/:metadata": true, - "/workspace/:workspaceId/:metadata": true, - "/server/network-key": true, + "/health": true, + "/target/:targetId/metadata": true, + "/target/:targetId": true, + "/workspace/:workspaceId/metadata": true, + "/workspace/:workspaceId": true, + "/server/network-key": true, } func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.HandlerFunc { From 86ffaad7c9304edd4bd82082471d43d8fd666d89 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Wed, 4 Dec 2024 19:14:37 +0100 Subject: [PATCH 18/76] refactor: build runner with states (#1410) Signed-off-by: Ivan Dagelic --- internal/testing/build/store.go | 14 - .../server/targets/mocks/build_service.go | 16 +- .../testing/server/targets/mocks/builder.go | 1 - pkg/api/controllers/build/build.go | 26 +- pkg/api/docs/docs.go | 74 ++-- pkg/api/docs/swagger.json | 74 ++-- pkg/api/docs/swagger.yaml | 54 ++- pkg/apiclient/README.md | 3 +- pkg/apiclient/api/openapi.yaml | 80 +++-- pkg/apiclient/api_build.go | 16 +- pkg/apiclient/docs/BuildAPI.md | 12 +- pkg/apiclient/docs/{Build.md => BuildDTO.md} | 114 +++--- pkg/apiclient/docs/ModelsBuildState.md | 25 -- pkg/apiclient/docs/ModelsJobAction.md | 2 + pkg/apiclient/docs/ModelsResourceStateName.md | 6 + pkg/apiclient/docs/ResourceType.md | 2 + .../{model_build.go => model_build_dto.go} | 166 +++++---- pkg/apiclient/model_models_build_state.go | 122 ------- pkg/apiclient/model_models_job_action.go | 2 + .../model_models_resource_state_name.go | 6 + pkg/apiclient/model_resource_type.go | 2 + pkg/build/builder.go | 4 +- pkg/build/builder_test.go | 59 --- pkg/build/factory.go | 23 +- pkg/build/runner.go | 340 ------------------ pkg/build/runner_config.go | 113 ------ pkg/build/runner_test.go | 148 -------- pkg/cmd/build/info.go | 2 +- pkg/cmd/build/run.go | 6 + pkg/cmd/purge.go | 19 - pkg/cmd/server/bootstrap/get_build_runner.go | 111 ------ pkg/cmd/server/bootstrap/get_job_runner.go | 107 ++++++ .../server/bootstrap/get_server_instance.go | 60 ++-- pkg/cmd/server/serve.go | 16 - pkg/db/build_store.go | 14 +- pkg/jobs/build/build.go | 43 +++ pkg/jobs/build/delete.go | 23 ++ pkg/jobs/build/factory.go | 60 ++++ pkg/jobs/build/run.go | 141 ++++++++ pkg/models/build.go | 21 +- pkg/models/common.go | 45 +++ pkg/models/job.go | 6 + pkg/models/workspace.go | 36 -- pkg/runners/runner/runner.go | 6 + pkg/server/builds/service.go | 95 ++++- pkg/server/builds/service_test.go | 28 +- pkg/server/jobs/service.go | 35 ++ pkg/server/purge.go | 2 +- pkg/server/workspacetemplates/prebuild.go | 8 +- .../workspacetemplates/prebuild_test.go | 8 +- pkg/server/workspacetemplates/service.go | 10 +- pkg/server/workspacetemplates/service_test.go | 24 +- pkg/services/build.go | 28 +- pkg/services/job.go | 10 + pkg/stores/build.go | 9 - pkg/views/build/info/view.go | 4 +- pkg/views/build/list/view.go | 24 +- pkg/views/common.go | 9 + pkg/views/selection/build.go | 12 +- pkg/views/styles.go | 28 +- pkg/views/target/info/view.go | 5 +- pkg/views/target/list/view.go | 10 +- pkg/views/util/state_sort.go | 22 ++ pkg/views/workspace/list/view.go | 10 +- 64 files changed, 1113 insertions(+), 1488 deletions(-) rename pkg/apiclient/docs/{Build.md => BuildDTO.md} (63%) delete mode 100644 pkg/apiclient/docs/ModelsBuildState.md rename pkg/apiclient/{model_build.go => model_build_dto.go} (66%) delete mode 100644 pkg/apiclient/model_models_build_state.go delete mode 100644 pkg/build/builder_test.go delete mode 100644 pkg/build/runner.go delete mode 100644 pkg/build/runner_config.go delete mode 100644 pkg/build/runner_test.go delete mode 100644 pkg/cmd/server/bootstrap/get_build_runner.go create mode 100644 pkg/jobs/build/build.go create mode 100644 pkg/jobs/build/delete.go create mode 100644 pkg/jobs/build/factory.go create mode 100644 pkg/jobs/build/run.go create mode 100644 pkg/models/common.go create mode 100644 pkg/views/util/state_sort.go diff --git a/internal/testing/build/store.go b/internal/testing/build/store.go index ef6949b251..d52630a34b 100644 --- a/internal/testing/build/store.go +++ b/internal/testing/build/store.go @@ -69,20 +69,6 @@ func (s *InMemoryBuildStore) processFilters(filter *stores.BuildFilter) ([]*mode return []*models.Build{}, fmt.Errorf("build with id %s not found", *filter.Id) } } - if filter.States != nil { - for _, b := range filteredBuilds { - check := false - for _, state := range *filter.States { - if b.State == state { - check = true - break - } - } - if !check { - delete(filteredBuilds, b.Id) - } - } - } if filter.PrebuildIds != nil { for _, b := range filteredBuilds { check := false diff --git a/internal/testing/server/targets/mocks/build_service.go b/internal/testing/server/targets/mocks/build_service.go index 153c581198..4f24295acc 100644 --- a/internal/testing/server/targets/mocks/build_service.go +++ b/internal/testing/server/targets/mocks/build_service.go @@ -9,9 +9,7 @@ import ( "io" "time" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/mock" ) @@ -28,24 +26,24 @@ func (m *MockBuildService) Create(createBuildDto services.CreateBuildDTO) (strin return args.String(0), args.Error(1) } -func (m *MockBuildService) Find(filter *stores.BuildFilter) (*models.Build, error) { +func (m *MockBuildService) Find(filter *services.BuildFilter) (*services.BuildDTO, error) { args := m.Called(filter) - return args.Get(0).(*models.Build), args.Error(1) + return args.Get(0).(*services.BuildDTO), args.Error(1) } -func (m *MockBuildService) List(filter *stores.BuildFilter) ([]*models.Build, error) { +func (m *MockBuildService) List(filter *services.BuildFilter) ([]*services.BuildDTO, error) { args := m.Called(filter) - return args.Get(0).([]*models.Build), args.Error(1) + return args.Get(0).([]*services.BuildDTO), args.Error(1) } -func (m *MockBuildService) MarkForDeletion(filter *stores.BuildFilter, force bool) []error { +func (m *MockBuildService) Delete(filter *services.BuildFilter, force bool) []error { args := m.Called(filter, force) return args.Get(0).([]error) } -func (m *MockBuildService) Delete(id string) error { +func (m *MockBuildService) HandleSuccessfulRemoval(id string) error { args := m.Called(id) - return args.Error(0) + return args.Get(0).(error) } func (m *MockBuildService) AwaitEmptyList(waitTime time.Duration) error { diff --git a/internal/testing/server/targets/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go index 06be3f5157..4f566c174a 100644 --- a/internal/testing/server/targets/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -15,7 +15,6 @@ import ( var MockBuild = &models.Build{ Id: "1", - State: models.BuildStatePendingRun, Image: util.Pointer("image"), User: util.Pointer("user"), ContainerConfig: models.ContainerConfig{ diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index 1963852b10..9d9765bcd2 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -52,7 +52,7 @@ func CreateBuild(ctx *gin.Context) { // @Description Get build data // @Accept json // @Param buildId path string true "Build ID" -// @Success 200 {object} Build +// @Success 200 {object} BuildDTO // @Router /build/{buildId} [get] // // @id GetBuild @@ -61,12 +61,14 @@ func GetBuild(ctx *gin.Context) { server := server.GetInstance(nil) - b, err := server.BuildService.Find(&stores.BuildFilter{ - Id: &buildId, + b, err := server.BuildService.Find(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &buildId, + }, }) if err != nil { statusCode := http.StatusInternalServerError - if stores.IsBuildNotFound(err) { + if stores.IsBuildNotFound(err) || services.IsBuildDeleted(err) { statusCode = http.StatusNotFound } ctx.AbortWithError(statusCode, fmt.Errorf("failed to find build: %w", err)) @@ -82,7 +84,7 @@ func GetBuild(ctx *gin.Context) { // @Summary List builds // @Description List builds // @Produce json -// @Success 200 {array} Build +// @Success 200 {array} BuildDTO // @Router /build [get] // // @id ListBuilds @@ -123,7 +125,7 @@ func DeleteAllBuilds(ctx *gin.Context) { server := server.GetInstance(nil) - errs := server.BuildService.MarkForDeletion(nil, force) + errs := server.BuildService.Delete(nil, force) if len(errs) > 0 { for _, err := range errs { _ = ctx.Error(err) @@ -162,8 +164,10 @@ func DeleteBuild(ctx *gin.Context) { server := server.GetInstance(nil) - errs := server.BuildService.MarkForDeletion(&stores.BuildFilter{ - Id: &buildId, + errs := server.BuildService.Delete(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &buildId, + }, }, force) if len(errs) > 0 { for _, err := range errs { @@ -212,8 +216,10 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { return } - errs := server.BuildService.MarkForDeletion(&stores.BuildFilter{ - PrebuildIds: &[]string{prebuildId}, + errs := server.BuildService.Delete(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + PrebuildIds: &[]string{prebuildId}, + }, }, force) if len(errs) > 0 { for _, err := range errs { diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 4cced0b453..ba6fde7f1e 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -108,7 +108,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/Build" + "$ref": "#/definitions/BuildDTO" } } } @@ -220,7 +220,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/Build" + "$ref": "#/definitions/BuildDTO" } } } @@ -3433,7 +3433,18 @@ const docTemplate = `{ } } }, - "Build": { + "BuildConfig": { + "type": "object", + "properties": { + "cachedBuild": { + "$ref": "#/definitions/CachedBuild" + }, + "devcontainer": { + "$ref": "#/definitions/DevcontainerConfig" + } + } + }, + "BuildDTO": { "type": "object", "required": [ "containerConfig", @@ -3467,6 +3478,9 @@ const docTemplate = `{ "image": { "type": "string" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, "prebuildId": { "type": "string" }, @@ -3474,7 +3488,7 @@ const docTemplate = `{ "$ref": "#/definitions/GitRepository" }, "state": { - "$ref": "#/definitions/models.BuildState" + "$ref": "#/definitions/ResourceState" }, "updatedAt": { "type": "string" @@ -3484,17 +3498,6 @@ const docTemplate = `{ } } }, - "BuildConfig": { - "type": "object", - "properties": { - "cachedBuild": { - "$ref": "#/definitions/CachedBuild" - }, - "devcontainer": { - "$ref": "#/definitions/DevcontainerConfig" - } - } - }, "CachedBuild": { "type": "object", "required": [ @@ -4738,11 +4741,13 @@ const docTemplate = `{ "type": "string", "enum": [ "workspace", - "target" + "target", + "build" ], "x-enum-varnames": [ "ResourceTypeWorkspace", - "ResourceTypeTarget" + "ResourceTypeTarget", + "ResourceTypeBuild" ] }, "Sample": { @@ -5439,29 +5444,6 @@ const docTemplate = `{ "ApiKeyTypeTarget" ] }, - "models.BuildState": { - "type": "string", - "enum": [ - "pending-run", - "running", - "error", - "success", - "published", - "pending-delete", - "pending-forced-delete", - "deleting" - ], - "x-enum-varnames": [ - "BuildStatePendingRun", - "BuildStateRunning", - "BuildStateError", - "BuildStateSuccess", - "BuildStatePublished", - "BuildStatePendingDelete", - "BuildStatePendingForcedDelete", - "BuildStateDeleting" - ] - }, "models.JobAction": { "type": "string", "enum": [ @@ -5470,7 +5452,8 @@ const docTemplate = `{ "stop", "restart", "delete", - "force-delete" + "force-delete", + "run" ], "x-enum-varnames": [ "JobActionCreate", @@ -5478,13 +5461,17 @@ const docTemplate = `{ "JobActionStop", "JobActionRestart", "JobActionDelete", - "JobActionForceDelete" + "JobActionForceDelete", + "JobActionRun" ] }, "models.ResourceStateName": { "type": "string", "enum": [ "undefined", + "pending-run", + "running", + "run-successful", "pending-create", "creating", "pending-start", @@ -5503,6 +5490,9 @@ const docTemplate = `{ ], "x-enum-varnames": [ "ResourceStateNameUndefined", + "ResourceStateNamePendingRun", + "ResourceStateNameRunning", + "ResourceStateNameRunSuccessful", "ResourceStateNamePendingCreate", "ResourceStateNameCreating", "ResourceStateNamePendingStart", diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 4f6ba77bde..41cc0d8f7f 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -105,7 +105,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/Build" + "$ref": "#/definitions/BuildDTO" } } } @@ -217,7 +217,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/Build" + "$ref": "#/definitions/BuildDTO" } } } @@ -3430,7 +3430,18 @@ } } }, - "Build": { + "BuildConfig": { + "type": "object", + "properties": { + "cachedBuild": { + "$ref": "#/definitions/CachedBuild" + }, + "devcontainer": { + "$ref": "#/definitions/DevcontainerConfig" + } + } + }, + "BuildDTO": { "type": "object", "required": [ "containerConfig", @@ -3464,6 +3475,9 @@ "image": { "type": "string" }, + "lastJob": { + "$ref": "#/definitions/Job" + }, "prebuildId": { "type": "string" }, @@ -3471,7 +3485,7 @@ "$ref": "#/definitions/GitRepository" }, "state": { - "$ref": "#/definitions/models.BuildState" + "$ref": "#/definitions/ResourceState" }, "updatedAt": { "type": "string" @@ -3481,17 +3495,6 @@ } } }, - "BuildConfig": { - "type": "object", - "properties": { - "cachedBuild": { - "$ref": "#/definitions/CachedBuild" - }, - "devcontainer": { - "$ref": "#/definitions/DevcontainerConfig" - } - } - }, "CachedBuild": { "type": "object", "required": [ @@ -4735,11 +4738,13 @@ "type": "string", "enum": [ "workspace", - "target" + "target", + "build" ], "x-enum-varnames": [ "ResourceTypeWorkspace", - "ResourceTypeTarget" + "ResourceTypeTarget", + "ResourceTypeBuild" ] }, "Sample": { @@ -5436,29 +5441,6 @@ "ApiKeyTypeTarget" ] }, - "models.BuildState": { - "type": "string", - "enum": [ - "pending-run", - "running", - "error", - "success", - "published", - "pending-delete", - "pending-forced-delete", - "deleting" - ], - "x-enum-varnames": [ - "BuildStatePendingRun", - "BuildStateRunning", - "BuildStateError", - "BuildStateSuccess", - "BuildStatePublished", - "BuildStatePendingDelete", - "BuildStatePendingForcedDelete", - "BuildStateDeleting" - ] - }, "models.JobAction": { "type": "string", "enum": [ @@ -5467,7 +5449,8 @@ "stop", "restart", "delete", - "force-delete" + "force-delete", + "run" ], "x-enum-varnames": [ "JobActionCreate", @@ -5475,13 +5458,17 @@ "JobActionStop", "JobActionRestart", "JobActionDelete", - "JobActionForceDelete" + "JobActionForceDelete", + "JobActionRun" ] }, "models.ResourceStateName": { "type": "string", "enum": [ "undefined", + "pending-run", + "running", + "run-successful", "pending-create", "creating", "pending-start", @@ -5500,6 +5487,9 @@ ], "x-enum-varnames": [ "ResourceStateNameUndefined", + "ResourceStateNamePendingRun", + "ResourceStateNameRunning", + "ResourceStateNameRunSuccessful", "ResourceStateNamePendingCreate", "ResourceStateNameCreating", "ResourceStateNamePendingStart", diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index a6e2d213bd..2631d74006 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -27,7 +27,14 @@ definitions: - name - type type: object - Build: + BuildConfig: + properties: + cachedBuild: + $ref: '#/definitions/CachedBuild' + devcontainer: + $ref: '#/definitions/DevcontainerConfig' + type: object + BuildDTO: properties: buildConfig: $ref: '#/definitions/BuildConfig' @@ -43,12 +50,14 @@ definitions: type: string image: type: string + lastJob: + $ref: '#/definitions/Job' prebuildId: type: string repository: $ref: '#/definitions/GitRepository' state: - $ref: '#/definitions/models.BuildState' + $ref: '#/definitions/ResourceState' updatedAt: type: string user: @@ -63,13 +72,6 @@ definitions: - state - updatedAt type: object - BuildConfig: - properties: - cachedBuild: - $ref: '#/definitions/CachedBuild' - devcontainer: - $ref: '#/definitions/DevcontainerConfig' - type: object CachedBuild: properties: image: @@ -917,10 +919,12 @@ definitions: enum: - workspace - target + - build type: string x-enum-varnames: - ResourceTypeWorkspace - ResourceTypeTarget + - ResourceTypeBuild Sample: properties: description: @@ -1411,26 +1415,6 @@ definitions: - ApiKeyTypeClient - ApiKeyTypeWorkspace - ApiKeyTypeTarget - models.BuildState: - enum: - - pending-run - - running - - error - - success - - published - - pending-delete - - pending-forced-delete - - deleting - type: string - x-enum-varnames: - - BuildStatePendingRun - - BuildStateRunning - - BuildStateError - - BuildStateSuccess - - BuildStatePublished - - BuildStatePendingDelete - - BuildStatePendingForcedDelete - - BuildStateDeleting models.JobAction: enum: - create @@ -1439,6 +1423,7 @@ definitions: - restart - delete - force-delete + - run type: string x-enum-varnames: - JobActionCreate @@ -1447,9 +1432,13 @@ definitions: - JobActionRestart - JobActionDelete - JobActionForceDelete + - JobActionRun models.ResourceStateName: enum: - undefined + - pending-run + - running + - run-successful - pending-create - creating - pending-start @@ -1468,6 +1457,9 @@ definitions: type: string x-enum-varnames: - ResourceStateNameUndefined + - ResourceStateNamePendingRun + - ResourceStateNameRunning + - ResourceStateNameRunSuccessful - ResourceStateNamePendingCreate - ResourceStateNameCreating - ResourceStateNamePendingStart @@ -1582,7 +1574,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/Build' + $ref: '#/definitions/BuildDTO' type: array summary: List builds tags: @@ -1642,7 +1634,7 @@ paths: "200": description: OK schema: - $ref: '#/definitions/Build' + $ref: '#/definitions/BuildDTO' summary: Get build data tags: - build diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index bd086ce3bc..9f524b2319 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -187,8 +187,8 @@ Class | Method | HTTP request | Description - [AddTargetConfigDTO](docs/AddTargetConfigDTO.md) - [ApiKey](docs/ApiKey.md) - - [Build](docs/Build.md) - [BuildConfig](docs/BuildConfig.md) + - [BuildDTO](docs/BuildDTO.md) - [CachedBuild](docs/CachedBuild.md) - [CloneTarget](docs/CloneTarget.md) - [Command](docs/Command.md) @@ -240,7 +240,6 @@ Class | Method | HTTP request | Description - [LspSymbol](docs/LspSymbol.md) - [Match](docs/Match.md) - [ModelsApiKeyType](docs/ModelsApiKeyType.md) - - [ModelsBuildState](docs/ModelsBuildState.md) - [ModelsJobAction](docs/ModelsJobAction.md) - [ModelsResourceStateName](docs/ModelsResourceStateName.md) - [NetworkKey](docs/NetworkKey.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 65f047ac08..ee84a84272 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -89,7 +89,7 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/Build' + $ref: '#/components/schemas/BuildDTO' type: array description: OK summary: List builds @@ -177,7 +177,7 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/Build' + $ref: '#/components/schemas/BuildDTO' description: OK summary: Get build data tags: @@ -2503,7 +2503,20 @@ components: - name - type type: object - Build: + BuildConfig: + example: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + properties: + cachedBuild: + $ref: '#/components/schemas/CachedBuild' + devcontainer: + $ref: '#/components/schemas/DevcontainerConfig' + type: object + BuildDTO: example: buildConfig: cachedBuild: @@ -2517,10 +2530,22 @@ components: image: image user: user prebuildId: prebuildId + lastJob: + createdAt: createdAt + resourceId: resourceId + action: null + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt envVars: key: envVars id: id - state: null + state: + name: null + error: error + updatedAt: updatedAt repository: owner: owner path: path @@ -2549,12 +2574,14 @@ components: type: string image: type: string + lastJob: + $ref: '#/components/schemas/Job' prebuildId: type: string repository: $ref: '#/components/schemas/GitRepository' state: - $ref: '#/components/schemas/models.BuildState' + $ref: '#/components/schemas/ResourceState' updatedAt: type: string user: @@ -2569,19 +2596,6 @@ components: - state - updatedAt type: object - BuildConfig: - example: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - properties: - cachedBuild: - $ref: '#/components/schemas/CachedBuild' - devcontainer: - $ref: '#/components/schemas/DevcontainerConfig' - type: object CachedBuild: example: image: image @@ -3787,10 +3801,12 @@ components: enum: - workspace - target + - build type: string x-enum-varnames: - ResourceTypeWorkspace - ResourceTypeTarget + - ResourceTypeBuild Sample: example: name: name @@ -4852,26 +4868,6 @@ components: - ApiKeyTypeClient - ApiKeyTypeWorkspace - ApiKeyTypeTarget - models.BuildState: - enum: - - pending-run - - running - - error - - success - - published - - pending-delete - - pending-forced-delete - - deleting - type: string - x-enum-varnames: - - BuildStatePendingRun - - BuildStateRunning - - BuildStateError - - BuildStateSuccess - - BuildStatePublished - - BuildStatePendingDelete - - BuildStatePendingForcedDelete - - BuildStateDeleting models.JobAction: enum: - create @@ -4880,6 +4876,7 @@ components: - restart - delete - force-delete + - run type: string x-enum-varnames: - JobActionCreate @@ -4888,9 +4885,13 @@ components: - JobActionRestart - JobActionDelete - JobActionForceDelete + - JobActionRun models.ResourceStateName: enum: - undefined + - pending-run + - running + - run-successful - pending-create - creating - pending-start @@ -4909,6 +4910,9 @@ components: type: string x-enum-varnames: - ResourceStateNameUndefined + - ResourceStateNamePendingRun + - ResourceStateNameRunning + - ResourceStateNameRunSuccessful - ResourceStateNamePendingCreate - ResourceStateNameCreating - ResourceStateNamePendingStart diff --git a/pkg/apiclient/api_build.go b/pkg/apiclient/api_build.go index f3ed813ff3..bdb342bec5 100644 --- a/pkg/apiclient/api_build.go +++ b/pkg/apiclient/api_build.go @@ -498,7 +498,7 @@ type ApiGetBuildRequest struct { buildId string } -func (r ApiGetBuildRequest) Execute() (*Build, *http.Response, error) { +func (r ApiGetBuildRequest) Execute() (*BuildDTO, *http.Response, error) { return r.ApiService.GetBuildExecute(r) } @@ -521,13 +521,13 @@ func (a *BuildAPIService) GetBuild(ctx context.Context, buildId string) ApiGetBu // Execute executes the request // -// @return Build -func (a *BuildAPIService) GetBuildExecute(r ApiGetBuildRequest) (*Build, *http.Response, error) { +// @return BuildDTO +func (a *BuildAPIService) GetBuildExecute(r ApiGetBuildRequest) (*BuildDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *Build + localVarReturnValue *BuildDTO ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BuildAPIService.GetBuild") @@ -615,7 +615,7 @@ type ApiListBuildsRequest struct { ApiService *BuildAPIService } -func (r ApiListBuildsRequest) Execute() ([]Build, *http.Response, error) { +func (r ApiListBuildsRequest) Execute() ([]BuildDTO, *http.Response, error) { return r.ApiService.ListBuildsExecute(r) } @@ -636,13 +636,13 @@ func (a *BuildAPIService) ListBuilds(ctx context.Context) ApiListBuildsRequest { // Execute executes the request // -// @return []Build -func (a *BuildAPIService) ListBuildsExecute(r ApiListBuildsRequest) ([]Build, *http.Response, error) { +// @return []BuildDTO +func (a *BuildAPIService) ListBuildsExecute(r ApiListBuildsRequest) ([]BuildDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []Build + localVarReturnValue []BuildDTO ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BuildAPIService.ListBuilds") diff --git a/pkg/apiclient/docs/BuildAPI.md b/pkg/apiclient/docs/BuildAPI.md index e1a5cd3bdc..a98f28c917 100644 --- a/pkg/apiclient/docs/BuildAPI.md +++ b/pkg/apiclient/docs/BuildAPI.md @@ -285,7 +285,7 @@ Name | Type | Description | Notes ## GetBuild -> Build GetBuild(ctx, buildId).Execute() +> BuildDTO GetBuild(ctx, buildId).Execute() Get build data @@ -313,7 +313,7 @@ func main() { fmt.Fprintf(os.Stderr, "Error when calling `BuildAPI.GetBuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetBuild`: Build + // response from `GetBuild`: BuildDTO fmt.Fprintf(os.Stdout, "Response from `BuildAPI.GetBuild`: %v\n", resp) } ``` @@ -337,7 +337,7 @@ Name | Type | Description | Notes ### Return type -[**Build**](Build.md) +[**BuildDTO**](BuildDTO.md) ### Authorization @@ -355,7 +355,7 @@ Name | Type | Description | Notes ## ListBuilds -> []Build ListBuilds(ctx).Execute() +> []BuildDTO ListBuilds(ctx).Execute() List builds @@ -382,7 +382,7 @@ func main() { fmt.Fprintf(os.Stderr, "Error when calling `BuildAPI.ListBuilds``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListBuilds`: []Build + // response from `ListBuilds`: []BuildDTO fmt.Fprintf(os.Stdout, "Response from `BuildAPI.ListBuilds`: %v\n", resp) } ``` @@ -398,7 +398,7 @@ Other parameters are passed through a pointer to a apiListBuildsRequest struct v ### Return type -[**[]Build**](Build.md) +[**[]BuildDTO**](BuildDTO.md) ### Authorization diff --git a/pkg/apiclient/docs/Build.md b/pkg/apiclient/docs/BuildDTO.md similarity index 63% rename from pkg/apiclient/docs/Build.md rename to pkg/apiclient/docs/BuildDTO.md index 690ad8d492..7f2aa45f84 100644 --- a/pkg/apiclient/docs/Build.md +++ b/pkg/apiclient/docs/BuildDTO.md @@ -1,4 +1,4 @@ -# Build +# BuildDTO ## Properties @@ -10,263 +10,289 @@ Name | Type | Description | Notes **EnvVars** | **map[string]string** | | **Id** | **string** | | **Image** | Pointer to **string** | | [optional] +**LastJob** | Pointer to [**Job**](Job.md) | | [optional] **PrebuildId** | **string** | | **Repository** | [**GitRepository**](GitRepository.md) | | -**State** | [**ModelsBuildState**](ModelsBuildState.md) | | +**State** | [**ResourceState**](ResourceState.md) | | **UpdatedAt** | **string** | | **User** | Pointer to **string** | | [optional] ## Methods -### NewBuild +### NewBuildDTO -`func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ModelsBuildState, updatedAt string, ) *Build` +`func NewBuildDTO(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ResourceState, updatedAt string, ) *BuildDTO` -NewBuild instantiates a new Build object +NewBuildDTO instantiates a new BuildDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewBuildWithDefaults +### NewBuildDTOWithDefaults -`func NewBuildWithDefaults() *Build` +`func NewBuildDTOWithDefaults() *BuildDTO` -NewBuildWithDefaults instantiates a new Build object +NewBuildDTOWithDefaults instantiates a new BuildDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetBuildConfig -`func (o *Build) GetBuildConfig() BuildConfig` +`func (o *BuildDTO) GetBuildConfig() BuildConfig` GetBuildConfig returns the BuildConfig field if non-nil, zero value otherwise. ### GetBuildConfigOk -`func (o *Build) GetBuildConfigOk() (*BuildConfig, bool)` +`func (o *BuildDTO) GetBuildConfigOk() (*BuildConfig, bool)` GetBuildConfigOk returns a tuple with the BuildConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetBuildConfig -`func (o *Build) SetBuildConfig(v BuildConfig)` +`func (o *BuildDTO) SetBuildConfig(v BuildConfig)` SetBuildConfig sets BuildConfig field to given value. ### HasBuildConfig -`func (o *Build) HasBuildConfig() bool` +`func (o *BuildDTO) HasBuildConfig() bool` HasBuildConfig returns a boolean if a field has been set. ### GetContainerConfig -`func (o *Build) GetContainerConfig() ContainerConfig` +`func (o *BuildDTO) GetContainerConfig() ContainerConfig` GetContainerConfig returns the ContainerConfig field if non-nil, zero value otherwise. ### GetContainerConfigOk -`func (o *Build) GetContainerConfigOk() (*ContainerConfig, bool)` +`func (o *BuildDTO) GetContainerConfigOk() (*ContainerConfig, bool)` GetContainerConfigOk returns a tuple with the ContainerConfig field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetContainerConfig -`func (o *Build) SetContainerConfig(v ContainerConfig)` +`func (o *BuildDTO) SetContainerConfig(v ContainerConfig)` SetContainerConfig sets ContainerConfig field to given value. ### GetCreatedAt -`func (o *Build) GetCreatedAt() string` +`func (o *BuildDTO) GetCreatedAt() string` GetCreatedAt returns the CreatedAt field if non-nil, zero value otherwise. ### GetCreatedAtOk -`func (o *Build) GetCreatedAtOk() (*string, bool)` +`func (o *BuildDTO) GetCreatedAtOk() (*string, bool)` GetCreatedAtOk returns a tuple with the CreatedAt field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetCreatedAt -`func (o *Build) SetCreatedAt(v string)` +`func (o *BuildDTO) SetCreatedAt(v string)` SetCreatedAt sets CreatedAt field to given value. ### GetEnvVars -`func (o *Build) GetEnvVars() map[string]string` +`func (o *BuildDTO) GetEnvVars() map[string]string` GetEnvVars returns the EnvVars field if non-nil, zero value otherwise. ### GetEnvVarsOk -`func (o *Build) GetEnvVarsOk() (*map[string]string, bool)` +`func (o *BuildDTO) GetEnvVarsOk() (*map[string]string, bool)` GetEnvVarsOk returns a tuple with the EnvVars field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetEnvVars -`func (o *Build) SetEnvVars(v map[string]string)` +`func (o *BuildDTO) SetEnvVars(v map[string]string)` SetEnvVars sets EnvVars field to given value. ### GetId -`func (o *Build) GetId() string` +`func (o *BuildDTO) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *Build) GetIdOk() (*string, bool)` +`func (o *BuildDTO) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *Build) SetId(v string)` +`func (o *BuildDTO) SetId(v string)` SetId sets Id field to given value. ### GetImage -`func (o *Build) GetImage() string` +`func (o *BuildDTO) GetImage() string` GetImage returns the Image field if non-nil, zero value otherwise. ### GetImageOk -`func (o *Build) GetImageOk() (*string, bool)` +`func (o *BuildDTO) GetImageOk() (*string, bool)` GetImageOk returns a tuple with the Image field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetImage -`func (o *Build) SetImage(v string)` +`func (o *BuildDTO) SetImage(v string)` SetImage sets Image field to given value. ### HasImage -`func (o *Build) HasImage() bool` +`func (o *BuildDTO) HasImage() bool` HasImage returns a boolean if a field has been set. +### GetLastJob + +`func (o *BuildDTO) GetLastJob() Job` + +GetLastJob returns the LastJob field if non-nil, zero value otherwise. + +### GetLastJobOk + +`func (o *BuildDTO) GetLastJobOk() (*Job, bool)` + +GetLastJobOk returns a tuple with the LastJob field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJob + +`func (o *BuildDTO) SetLastJob(v Job)` + +SetLastJob sets LastJob field to given value. + +### HasLastJob + +`func (o *BuildDTO) HasLastJob() bool` + +HasLastJob returns a boolean if a field has been set. + ### GetPrebuildId -`func (o *Build) GetPrebuildId() string` +`func (o *BuildDTO) GetPrebuildId() string` GetPrebuildId returns the PrebuildId field if non-nil, zero value otherwise. ### GetPrebuildIdOk -`func (o *Build) GetPrebuildIdOk() (*string, bool)` +`func (o *BuildDTO) GetPrebuildIdOk() (*string, bool)` GetPrebuildIdOk returns a tuple with the PrebuildId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetPrebuildId -`func (o *Build) SetPrebuildId(v string)` +`func (o *BuildDTO) SetPrebuildId(v string)` SetPrebuildId sets PrebuildId field to given value. ### GetRepository -`func (o *Build) GetRepository() GitRepository` +`func (o *BuildDTO) GetRepository() GitRepository` GetRepository returns the Repository field if non-nil, zero value otherwise. ### GetRepositoryOk -`func (o *Build) GetRepositoryOk() (*GitRepository, bool)` +`func (o *BuildDTO) GetRepositoryOk() (*GitRepository, bool)` GetRepositoryOk returns a tuple with the Repository field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetRepository -`func (o *Build) SetRepository(v GitRepository)` +`func (o *BuildDTO) SetRepository(v GitRepository)` SetRepository sets Repository field to given value. ### GetState -`func (o *Build) GetState() ModelsBuildState` +`func (o *BuildDTO) GetState() ResourceState` GetState returns the State field if non-nil, zero value otherwise. ### GetStateOk -`func (o *Build) GetStateOk() (*ModelsBuildState, bool)` +`func (o *BuildDTO) GetStateOk() (*ResourceState, bool)` GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetState -`func (o *Build) SetState(v ModelsBuildState)` +`func (o *BuildDTO) SetState(v ResourceState)` SetState sets State field to given value. ### GetUpdatedAt -`func (o *Build) GetUpdatedAt() string` +`func (o *BuildDTO) GetUpdatedAt() string` GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. ### GetUpdatedAtOk -`func (o *Build) GetUpdatedAtOk() (*string, bool)` +`func (o *BuildDTO) GetUpdatedAtOk() (*string, bool)` GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUpdatedAt -`func (o *Build) SetUpdatedAt(v string)` +`func (o *BuildDTO) SetUpdatedAt(v string)` SetUpdatedAt sets UpdatedAt field to given value. ### GetUser -`func (o *Build) GetUser() string` +`func (o *BuildDTO) GetUser() string` GetUser returns the User field if non-nil, zero value otherwise. ### GetUserOk -`func (o *Build) GetUserOk() (*string, bool)` +`func (o *BuildDTO) GetUserOk() (*string, bool)` GetUserOk returns a tuple with the User field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUser -`func (o *Build) SetUser(v string)` +`func (o *BuildDTO) SetUser(v string)` SetUser sets User field to given value. ### HasUser -`func (o *Build) HasUser() bool` +`func (o *BuildDTO) HasUser() bool` HasUser returns a boolean if a field has been set. diff --git a/pkg/apiclient/docs/ModelsBuildState.md b/pkg/apiclient/docs/ModelsBuildState.md deleted file mode 100644 index fe1a303454..0000000000 --- a/pkg/apiclient/docs/ModelsBuildState.md +++ /dev/null @@ -1,25 +0,0 @@ -# ModelsBuildState - -## Enum - - -* `BuildStatePendingRun` (value: `"pending-run"`) - -* `BuildStateRunning` (value: `"running"`) - -* `BuildStateError` (value: `"error"`) - -* `BuildStateSuccess` (value: `"success"`) - -* `BuildStatePublished` (value: `"published"`) - -* `BuildStatePendingDelete` (value: `"pending-delete"`) - -* `BuildStatePendingForcedDelete` (value: `"pending-forced-delete"`) - -* `BuildStateDeleting` (value: `"deleting"`) - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/docs/ModelsJobAction.md b/pkg/apiclient/docs/ModelsJobAction.md index 57efef5a40..5e131d5365 100644 --- a/pkg/apiclient/docs/ModelsJobAction.md +++ b/pkg/apiclient/docs/ModelsJobAction.md @@ -15,6 +15,8 @@ * `JobActionForceDelete` (value: `"force-delete"`) +* `JobActionRun` (value: `"run"`) + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/ModelsResourceStateName.md b/pkg/apiclient/docs/ModelsResourceStateName.md index e8b2354a95..1b06ed61cb 100644 --- a/pkg/apiclient/docs/ModelsResourceStateName.md +++ b/pkg/apiclient/docs/ModelsResourceStateName.md @@ -5,6 +5,12 @@ * `ResourceStateNameUndefined` (value: `"undefined"`) +* `ResourceStateNamePendingRun` (value: `"pending-run"`) + +* `ResourceStateNameRunning` (value: `"running"`) + +* `ResourceStateNameRunSuccessful` (value: `"run-successful"`) + * `ResourceStateNamePendingCreate` (value: `"pending-create"`) * `ResourceStateNameCreating` (value: `"creating"`) diff --git a/pkg/apiclient/docs/ResourceType.md b/pkg/apiclient/docs/ResourceType.md index 3acb2bb6b1..cebd8a5e58 100644 --- a/pkg/apiclient/docs/ResourceType.md +++ b/pkg/apiclient/docs/ResourceType.md @@ -7,6 +7,8 @@ * `ResourceTypeTarget` (value: `"target"`) +* `ResourceTypeBuild` (value: `"build"`) + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/model_build.go b/pkg/apiclient/model_build_dto.go similarity index 66% rename from pkg/apiclient/model_build.go rename to pkg/apiclient/model_build_dto.go index a1b59a5369..7d4760f9af 100644 --- a/pkg/apiclient/model_build.go +++ b/pkg/apiclient/model_build_dto.go @@ -16,32 +16,33 @@ import ( "fmt" ) -// checks if the Build type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &Build{} +// checks if the BuildDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BuildDTO{} -// Build struct for Build -type Build struct { +// BuildDTO struct for BuildDTO +type BuildDTO struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty"` ContainerConfig ContainerConfig `json:"containerConfig"` CreatedAt string `json:"createdAt"` EnvVars map[string]string `json:"envVars"` Id string `json:"id"` Image *string `json:"image,omitempty"` + LastJob *Job `json:"lastJob,omitempty"` PrebuildId string `json:"prebuildId"` Repository GitRepository `json:"repository"` - State ModelsBuildState `json:"state"` + State ResourceState `json:"state"` UpdatedAt string `json:"updatedAt"` User *string `json:"user,omitempty"` } -type _Build Build +type _BuildDTO BuildDTO -// NewBuild instantiates a new Build object +// NewBuildDTO instantiates a new BuildDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ModelsBuildState, updatedAt string) *Build { - this := Build{} +func NewBuildDTO(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ResourceState, updatedAt string) *BuildDTO { + this := BuildDTO{} this.ContainerConfig = containerConfig this.CreatedAt = createdAt this.EnvVars = envVars @@ -53,16 +54,16 @@ func NewBuild(containerConfig ContainerConfig, createdAt string, envVars map[str return &this } -// NewBuildWithDefaults instantiates a new Build object +// NewBuildDTOWithDefaults instantiates a new BuildDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewBuildWithDefaults() *Build { - this := Build{} +func NewBuildDTOWithDefaults() *BuildDTO { + this := BuildDTO{} return &this } // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. -func (o *Build) GetBuildConfig() BuildConfig { +func (o *BuildDTO) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { var ret BuildConfig return ret @@ -72,7 +73,7 @@ func (o *Build) GetBuildConfig() BuildConfig { // GetBuildConfigOk returns a tuple with the BuildConfig field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Build) GetBuildConfigOk() (*BuildConfig, bool) { +func (o *BuildDTO) GetBuildConfigOk() (*BuildConfig, bool) { if o == nil || IsNil(o.BuildConfig) { return nil, false } @@ -80,7 +81,7 @@ func (o *Build) GetBuildConfigOk() (*BuildConfig, bool) { } // HasBuildConfig returns a boolean if a field has been set. -func (o *Build) HasBuildConfig() bool { +func (o *BuildDTO) HasBuildConfig() bool { if o != nil && !IsNil(o.BuildConfig) { return true } @@ -89,12 +90,12 @@ func (o *Build) HasBuildConfig() bool { } // SetBuildConfig gets a reference to the given BuildConfig and assigns it to the BuildConfig field. -func (o *Build) SetBuildConfig(v BuildConfig) { +func (o *BuildDTO) SetBuildConfig(v BuildConfig) { o.BuildConfig = &v } // GetContainerConfig returns the ContainerConfig field value -func (o *Build) GetContainerConfig() ContainerConfig { +func (o *BuildDTO) GetContainerConfig() ContainerConfig { if o == nil { var ret ContainerConfig return ret @@ -105,7 +106,7 @@ func (o *Build) GetContainerConfig() ContainerConfig { // GetContainerConfigOk returns a tuple with the ContainerConfig field value // and a boolean to check if the value has been set. -func (o *Build) GetContainerConfigOk() (*ContainerConfig, bool) { +func (o *BuildDTO) GetContainerConfigOk() (*ContainerConfig, bool) { if o == nil { return nil, false } @@ -113,12 +114,12 @@ func (o *Build) GetContainerConfigOk() (*ContainerConfig, bool) { } // SetContainerConfig sets field value -func (o *Build) SetContainerConfig(v ContainerConfig) { +func (o *BuildDTO) SetContainerConfig(v ContainerConfig) { o.ContainerConfig = v } // GetCreatedAt returns the CreatedAt field value -func (o *Build) GetCreatedAt() string { +func (o *BuildDTO) GetCreatedAt() string { if o == nil { var ret string return ret @@ -129,7 +130,7 @@ func (o *Build) GetCreatedAt() string { // GetCreatedAtOk returns a tuple with the CreatedAt field value // and a boolean to check if the value has been set. -func (o *Build) GetCreatedAtOk() (*string, bool) { +func (o *BuildDTO) GetCreatedAtOk() (*string, bool) { if o == nil { return nil, false } @@ -137,12 +138,12 @@ func (o *Build) GetCreatedAtOk() (*string, bool) { } // SetCreatedAt sets field value -func (o *Build) SetCreatedAt(v string) { +func (o *BuildDTO) SetCreatedAt(v string) { o.CreatedAt = v } // GetEnvVars returns the EnvVars field value -func (o *Build) GetEnvVars() map[string]string { +func (o *BuildDTO) GetEnvVars() map[string]string { if o == nil { var ret map[string]string return ret @@ -153,7 +154,7 @@ func (o *Build) GetEnvVars() map[string]string { // GetEnvVarsOk returns a tuple with the EnvVars field value // and a boolean to check if the value has been set. -func (o *Build) GetEnvVarsOk() (*map[string]string, bool) { +func (o *BuildDTO) GetEnvVarsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -161,12 +162,12 @@ func (o *Build) GetEnvVarsOk() (*map[string]string, bool) { } // SetEnvVars sets field value -func (o *Build) SetEnvVars(v map[string]string) { +func (o *BuildDTO) SetEnvVars(v map[string]string) { o.EnvVars = v } // GetId returns the Id field value -func (o *Build) GetId() string { +func (o *BuildDTO) GetId() string { if o == nil { var ret string return ret @@ -177,7 +178,7 @@ func (o *Build) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *Build) GetIdOk() (*string, bool) { +func (o *BuildDTO) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -185,12 +186,12 @@ func (o *Build) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *Build) SetId(v string) { +func (o *BuildDTO) SetId(v string) { o.Id = v } // GetImage returns the Image field value if set, zero value otherwise. -func (o *Build) GetImage() string { +func (o *BuildDTO) GetImage() string { if o == nil || IsNil(o.Image) { var ret string return ret @@ -200,7 +201,7 @@ func (o *Build) GetImage() string { // GetImageOk returns a tuple with the Image field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Build) GetImageOk() (*string, bool) { +func (o *BuildDTO) GetImageOk() (*string, bool) { if o == nil || IsNil(o.Image) { return nil, false } @@ -208,7 +209,7 @@ func (o *Build) GetImageOk() (*string, bool) { } // HasImage returns a boolean if a field has been set. -func (o *Build) HasImage() bool { +func (o *BuildDTO) HasImage() bool { if o != nil && !IsNil(o.Image) { return true } @@ -217,12 +218,44 @@ func (o *Build) HasImage() bool { } // SetImage gets a reference to the given string and assigns it to the Image field. -func (o *Build) SetImage(v string) { +func (o *BuildDTO) SetImage(v string) { o.Image = &v } +// GetLastJob returns the LastJob field value if set, zero value otherwise. +func (o *BuildDTO) GetLastJob() Job { + if o == nil || IsNil(o.LastJob) { + var ret Job + return ret + } + return *o.LastJob +} + +// GetLastJobOk returns a tuple with the LastJob field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BuildDTO) GetLastJobOk() (*Job, bool) { + if o == nil || IsNil(o.LastJob) { + return nil, false + } + return o.LastJob, true +} + +// HasLastJob returns a boolean if a field has been set. +func (o *BuildDTO) HasLastJob() bool { + if o != nil && !IsNil(o.LastJob) { + return true + } + + return false +} + +// SetLastJob gets a reference to the given Job and assigns it to the LastJob field. +func (o *BuildDTO) SetLastJob(v Job) { + o.LastJob = &v +} + // GetPrebuildId returns the PrebuildId field value -func (o *Build) GetPrebuildId() string { +func (o *BuildDTO) GetPrebuildId() string { if o == nil { var ret string return ret @@ -233,7 +266,7 @@ func (o *Build) GetPrebuildId() string { // GetPrebuildIdOk returns a tuple with the PrebuildId field value // and a boolean to check if the value has been set. -func (o *Build) GetPrebuildIdOk() (*string, bool) { +func (o *BuildDTO) GetPrebuildIdOk() (*string, bool) { if o == nil { return nil, false } @@ -241,12 +274,12 @@ func (o *Build) GetPrebuildIdOk() (*string, bool) { } // SetPrebuildId sets field value -func (o *Build) SetPrebuildId(v string) { +func (o *BuildDTO) SetPrebuildId(v string) { o.PrebuildId = v } // GetRepository returns the Repository field value -func (o *Build) GetRepository() GitRepository { +func (o *BuildDTO) GetRepository() GitRepository { if o == nil { var ret GitRepository return ret @@ -257,7 +290,7 @@ func (o *Build) GetRepository() GitRepository { // GetRepositoryOk returns a tuple with the Repository field value // and a boolean to check if the value has been set. -func (o *Build) GetRepositoryOk() (*GitRepository, bool) { +func (o *BuildDTO) GetRepositoryOk() (*GitRepository, bool) { if o == nil { return nil, false } @@ -265,14 +298,14 @@ func (o *Build) GetRepositoryOk() (*GitRepository, bool) { } // SetRepository sets field value -func (o *Build) SetRepository(v GitRepository) { +func (o *BuildDTO) SetRepository(v GitRepository) { o.Repository = v } // GetState returns the State field value -func (o *Build) GetState() ModelsBuildState { +func (o *BuildDTO) GetState() ResourceState { if o == nil { - var ret ModelsBuildState + var ret ResourceState return ret } @@ -281,7 +314,7 @@ func (o *Build) GetState() ModelsBuildState { // GetStateOk returns a tuple with the State field value // and a boolean to check if the value has been set. -func (o *Build) GetStateOk() (*ModelsBuildState, bool) { +func (o *BuildDTO) GetStateOk() (*ResourceState, bool) { if o == nil { return nil, false } @@ -289,12 +322,12 @@ func (o *Build) GetStateOk() (*ModelsBuildState, bool) { } // SetState sets field value -func (o *Build) SetState(v ModelsBuildState) { +func (o *BuildDTO) SetState(v ResourceState) { o.State = v } // GetUpdatedAt returns the UpdatedAt field value -func (o *Build) GetUpdatedAt() string { +func (o *BuildDTO) GetUpdatedAt() string { if o == nil { var ret string return ret @@ -305,7 +338,7 @@ func (o *Build) GetUpdatedAt() string { // GetUpdatedAtOk returns a tuple with the UpdatedAt field value // and a boolean to check if the value has been set. -func (o *Build) GetUpdatedAtOk() (*string, bool) { +func (o *BuildDTO) GetUpdatedAtOk() (*string, bool) { if o == nil { return nil, false } @@ -313,12 +346,12 @@ func (o *Build) GetUpdatedAtOk() (*string, bool) { } // SetUpdatedAt sets field value -func (o *Build) SetUpdatedAt(v string) { +func (o *BuildDTO) SetUpdatedAt(v string) { o.UpdatedAt = v } // GetUser returns the User field value if set, zero value otherwise. -func (o *Build) GetUser() string { +func (o *BuildDTO) GetUser() string { if o == nil || IsNil(o.User) { var ret string return ret @@ -328,7 +361,7 @@ func (o *Build) GetUser() string { // GetUserOk returns a tuple with the User field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *Build) GetUserOk() (*string, bool) { +func (o *BuildDTO) GetUserOk() (*string, bool) { if o == nil || IsNil(o.User) { return nil, false } @@ -336,7 +369,7 @@ func (o *Build) GetUserOk() (*string, bool) { } // HasUser returns a boolean if a field has been set. -func (o *Build) HasUser() bool { +func (o *BuildDTO) HasUser() bool { if o != nil && !IsNil(o.User) { return true } @@ -345,11 +378,11 @@ func (o *Build) HasUser() bool { } // SetUser gets a reference to the given string and assigns it to the User field. -func (o *Build) SetUser(v string) { +func (o *BuildDTO) SetUser(v string) { o.User = &v } -func (o Build) MarshalJSON() ([]byte, error) { +func (o BuildDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -357,7 +390,7 @@ func (o Build) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o Build) ToMap() (map[string]interface{}, error) { +func (o BuildDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig @@ -369,6 +402,9 @@ func (o Build) ToMap() (map[string]interface{}, error) { if !IsNil(o.Image) { toSerialize["image"] = o.Image } + if !IsNil(o.LastJob) { + toSerialize["lastJob"] = o.LastJob + } toSerialize["prebuildId"] = o.PrebuildId toSerialize["repository"] = o.Repository toSerialize["state"] = o.State @@ -379,7 +415,7 @@ func (o Build) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *Build) UnmarshalJSON(data []byte) (err error) { +func (o *BuildDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -408,53 +444,53 @@ func (o *Build) UnmarshalJSON(data []byte) (err error) { } } - varBuild := _Build{} + varBuildDTO := _BuildDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varBuild) + err = decoder.Decode(&varBuildDTO) if err != nil { return err } - *o = Build(varBuild) + *o = BuildDTO(varBuildDTO) return err } -type NullableBuild struct { - value *Build +type NullableBuildDTO struct { + value *BuildDTO isSet bool } -func (v NullableBuild) Get() *Build { +func (v NullableBuildDTO) Get() *BuildDTO { return v.value } -func (v *NullableBuild) Set(val *Build) { +func (v *NullableBuildDTO) Set(val *BuildDTO) { v.value = val v.isSet = true } -func (v NullableBuild) IsSet() bool { +func (v NullableBuildDTO) IsSet() bool { return v.isSet } -func (v *NullableBuild) Unset() { +func (v *NullableBuildDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableBuild(val *Build) *NullableBuild { - return &NullableBuild{value: val, isSet: true} +func NewNullableBuildDTO(val *BuildDTO) *NullableBuildDTO { + return &NullableBuildDTO{value: val, isSet: true} } -func (v NullableBuild) MarshalJSON() ([]byte, error) { +func (v NullableBuildDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableBuild) UnmarshalJSON(src []byte) error { +func (v *NullableBuildDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_models_build_state.go b/pkg/apiclient/model_models_build_state.go deleted file mode 100644 index 4ef142560c..0000000000 --- a/pkg/apiclient/model_models_build_state.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "encoding/json" - "fmt" -) - -// ModelsBuildState the model 'ModelsBuildState' -type ModelsBuildState string - -// List of models.BuildState -const ( - BuildStatePendingRun ModelsBuildState = "pending-run" - BuildStateRunning ModelsBuildState = "running" - BuildStateError ModelsBuildState = "error" - BuildStateSuccess ModelsBuildState = "success" - BuildStatePublished ModelsBuildState = "published" - BuildStatePendingDelete ModelsBuildState = "pending-delete" - BuildStatePendingForcedDelete ModelsBuildState = "pending-forced-delete" - BuildStateDeleting ModelsBuildState = "deleting" -) - -// All allowed values of ModelsBuildState enum -var AllowedModelsBuildStateEnumValues = []ModelsBuildState{ - "pending-run", - "running", - "error", - "success", - "published", - "pending-delete", - "pending-forced-delete", - "deleting", -} - -func (v *ModelsBuildState) UnmarshalJSON(src []byte) error { - var value string - err := json.Unmarshal(src, &value) - if err != nil { - return err - } - enumTypeValue := ModelsBuildState(value) - for _, existing := range AllowedModelsBuildStateEnumValues { - if existing == enumTypeValue { - *v = enumTypeValue - return nil - } - } - - return fmt.Errorf("%+v is not a valid ModelsBuildState", value) -} - -// NewModelsBuildStateFromValue returns a pointer to a valid ModelsBuildState -// for the value passed as argument, or an error if the value passed is not allowed by the enum -func NewModelsBuildStateFromValue(v string) (*ModelsBuildState, error) { - ev := ModelsBuildState(v) - if ev.IsValid() { - return &ev, nil - } else { - return nil, fmt.Errorf("invalid value '%v' for ModelsBuildState: valid values are %v", v, AllowedModelsBuildStateEnumValues) - } -} - -// IsValid return true if the value is valid for the enum, false otherwise -func (v ModelsBuildState) IsValid() bool { - for _, existing := range AllowedModelsBuildStateEnumValues { - if existing == v { - return true - } - } - return false -} - -// Ptr returns reference to models.BuildState value -func (v ModelsBuildState) Ptr() *ModelsBuildState { - return &v -} - -type NullableModelsBuildState struct { - value *ModelsBuildState - isSet bool -} - -func (v NullableModelsBuildState) Get() *ModelsBuildState { - return v.value -} - -func (v *NullableModelsBuildState) Set(val *ModelsBuildState) { - v.value = val - v.isSet = true -} - -func (v NullableModelsBuildState) IsSet() bool { - return v.isSet -} - -func (v *NullableModelsBuildState) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableModelsBuildState(val *ModelsBuildState) *NullableModelsBuildState { - return &NullableModelsBuildState{value: val, isSet: true} -} - -func (v NullableModelsBuildState) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableModelsBuildState) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_models_job_action.go b/pkg/apiclient/model_models_job_action.go index ec53817261..cbc619f622 100644 --- a/pkg/apiclient/model_models_job_action.go +++ b/pkg/apiclient/model_models_job_action.go @@ -26,6 +26,7 @@ const ( JobActionRestart ModelsJobAction = "restart" JobActionDelete ModelsJobAction = "delete" JobActionForceDelete ModelsJobAction = "force-delete" + JobActionRun ModelsJobAction = "run" ) // All allowed values of ModelsJobAction enum @@ -36,6 +37,7 @@ var AllowedModelsJobActionEnumValues = []ModelsJobAction{ "restart", "delete", "force-delete", + "run", } func (v *ModelsJobAction) UnmarshalJSON(src []byte) error { diff --git a/pkg/apiclient/model_models_resource_state_name.go b/pkg/apiclient/model_models_resource_state_name.go index 1bfecd1405..ffaba87386 100644 --- a/pkg/apiclient/model_models_resource_state_name.go +++ b/pkg/apiclient/model_models_resource_state_name.go @@ -21,6 +21,9 @@ type ModelsResourceStateName string // List of models.ResourceStateName const ( ResourceStateNameUndefined ModelsResourceStateName = "undefined" + ResourceStateNamePendingRun ModelsResourceStateName = "pending-run" + ResourceStateNameRunning ModelsResourceStateName = "running" + ResourceStateNameRunSuccessful ModelsResourceStateName = "run-successful" ResourceStateNamePendingCreate ModelsResourceStateName = "pending-create" ResourceStateNameCreating ModelsResourceStateName = "creating" ResourceStateNamePendingStart ModelsResourceStateName = "pending-start" @@ -41,6 +44,9 @@ const ( // All allowed values of ModelsResourceStateName enum var AllowedModelsResourceStateNameEnumValues = []ModelsResourceStateName{ "undefined", + "pending-run", + "running", + "run-successful", "pending-create", "creating", "pending-start", diff --git a/pkg/apiclient/model_resource_type.go b/pkg/apiclient/model_resource_type.go index 47b9ccb927..ac7954ac59 100644 --- a/pkg/apiclient/model_resource_type.go +++ b/pkg/apiclient/model_resource_type.go @@ -22,12 +22,14 @@ type ResourceType string const ( ResourceTypeWorkspace ResourceType = "workspace" ResourceTypeTarget ResourceType = "target" + ResourceTypeBuild ResourceType = "build" ) // All allowed values of ResourceType enum var AllowedResourceTypeEnumValues = []ResourceType{ "workspace", "target", + "build", } func (v *ResourceType) UnmarshalJSON(src []byte) error { diff --git a/pkg/build/builder.go b/pkg/build/builder.go index f529a8b9e8..abe9022783 100644 --- a/pkg/build/builder.go +++ b/pkg/build/builder.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/services" ) type IBuilder interface { @@ -26,7 +26,7 @@ type Builder struct { image string containerRegistry *models.ContainerRegistry buildImageContainerRegistry *models.ContainerRegistry - buildStore stores.BuildStore + buildService services.IBuildService buildImageNamespace string loggerFactory logs.LoggerFactory defaultWorkspaceImage string diff --git a/pkg/build/builder_test.go b/pkg/build/builder_test.go deleted file mode 100644 index c86b0a9059..0000000000 --- a/pkg/build/builder_test.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package build_test - -import ( - "testing" - - t_build "github.com/daytonaio/daytona/internal/testing/build" - git_mocks "github.com/daytonaio/daytona/internal/testing/git/mocks" - builder_mocks "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" - "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/stretchr/testify/suite" -) - -var expectedBuilds []*models.Build - -type BuilderTestSuite struct { - suite.Suite - mockGitService *git_mocks.MockGitService - mockBuildStore stores.BuildStore - builder build.IBuilder -} - -func NewBuilderTestSuite() *BuilderTestSuite { - return &BuilderTestSuite{} -} - -func (s *BuilderTestSuite) SetupTest() { - s.mockBuildStore = t_build.NewInMemoryBuildStore() - s.mockGitService = git_mocks.NewMockGitService() - factory := build.NewBuilderFactory(build.BuilderFactoryConfig{ - BuildStore: s.mockBuildStore, - }) - s.builder, _ = factory.Create(*builder_mocks.MockBuild, "") - err := s.mockBuildStore.Save(builder_mocks.MockBuild) - if err != nil { - panic(err) - } -} - -func TestBuilder(t *testing.T) { - suite.Run(t, NewBuilderTestSuite()) -} - -func (s *BuilderTestSuite) TestSaveBuild() { - expectedBuilds = append(expectedBuilds, builder_mocks.MockBuild) - - require := s.Require() - - err := s.mockBuildStore.Save(builder_mocks.MockBuild) - require.NoError(err) - - savedBuilds, err := s.mockBuildStore.List(nil) - require.NoError(err) - require.ElementsMatch(expectedBuilds, savedBuilds) -} diff --git a/pkg/build/factory.go b/pkg/build/factory.go index 10e7283e59..fb0d65826d 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -10,6 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/docker/docker/pkg/stringid" ) @@ -23,7 +24,7 @@ type BuilderFactory struct { containerRegistry *models.ContainerRegistry buildImageContainerRegistry *models.ContainerRegistry buildImageNamespace string - buildStore stores.BuildStore + buildService services.IBuildService loggerFactory logs.LoggerFactory image string defaultWorkspaceImage string @@ -34,7 +35,7 @@ type BuilderFactoryConfig struct { Image string ContainerRegistry *models.ContainerRegistry BuildImageContainerRegistry *models.ContainerRegistry - BuildStore stores.BuildStore + BuildService services.IBuildService BuildImageNamespace string // Namespace to be used when tagging and pushing the build image LoggerFactory logs.LoggerFactory DefaultWorkspaceImage string @@ -47,7 +48,7 @@ func NewBuilderFactory(config BuilderFactoryConfig) IBuilderFactory { containerRegistry: config.ContainerRegistry, buildImageNamespace: config.BuildImageNamespace, buildImageContainerRegistry: config.BuildImageContainerRegistry, - buildStore: config.BuildStore, + buildService: config.BuildService, loggerFactory: config.LoggerFactory, defaultWorkspaceImage: config.DefaultWorkspaceImage, defaultWorkspaceUser: config.DefaultWorkspaceUser, @@ -64,17 +65,19 @@ func (f *BuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, erro return nil, errors.New("repository must be set") } - build, err := f.buildStore.Find(&stores.BuildFilter{ - Branch: &b.Repository.Branch, - RepositoryUrl: &b.Repository.Url, - BuildConfig: b.BuildConfig, - EnvVars: &b.EnvVars, + build, err := f.buildService.Find(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Branch: &b.Repository.Branch, + RepositoryUrl: &b.Repository.Url, + BuildConfig: b.BuildConfig, + EnvVars: &b.EnvVars, + }, }) if err != nil { return nil, err } - return build, nil + return &build.Build, nil } func (f *BuilderFactory) newDevcontainerBuilder(workspaceDir string) (*DevcontainerBuilder, error) { @@ -95,7 +98,7 @@ func (f *BuilderFactory) newDevcontainerBuilder(workspaceDir string) (*Devcontai containerRegistry: f.containerRegistry, buildImageContainerRegistry: f.buildImageContainerRegistry, buildImageNamespace: f.buildImageNamespace, - buildStore: f.buildStore, + buildService: f.buildService, loggerFactory: f.loggerFactory, defaultWorkspaceImage: f.defaultWorkspaceImage, defaultWorkspaceUser: f.defaultWorkspaceUser, diff --git a/pkg/build/runner.go b/pkg/build/runner.go deleted file mode 100644 index cb020102ad..0000000000 --- a/pkg/build/runner.go +++ /dev/null @@ -1,340 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package build - -import ( - "context" - "fmt" - "path/filepath" - "sync" - - "github.com/charmbracelet/lipgloss" - "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/git" - "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/scheduler" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/docker/docker/client" - "github.com/go-git/go-git/v5/plumbing/transport/http" - log "github.com/sirupsen/logrus" -) - -type BuildRunnerInstanceConfig struct { - Interval string - Scheduler scheduler.IScheduler - BuildRunnerId string - ContainerRegistry *models.ContainerRegistry - GitProviderStore GitProviderStore - BuildStore stores.BuildStore - BuilderFactory IBuilderFactory - LoggerFactory logs.LoggerFactory - BasePath string - TelemetryEnabled bool - TelemetryService telemetry.TelemetryService -} - -type BuildRunner struct { - Id string - scheduler scheduler.IScheduler - runInterval string - containerRegistry *models.ContainerRegistry - gitProviderStore GitProviderStore - buildStore stores.BuildStore - builderFactory IBuilderFactory - loggerFactory logs.LoggerFactory - basePath string - telemetryEnabled bool - telemetryService telemetry.TelemetryService -} - -type BuildProcessConfig struct { - Builder IBuilder - BuildLogger logs.Logger - Build *models.Build - WorkspaceDir string - GitService git.IGitService - Wg *sync.WaitGroup -} - -type GitProviderStore interface { - ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) -} - -func NewBuildRunner(config BuildRunnerInstanceConfig) *BuildRunner { - runner := &BuildRunner{ - Id: config.BuildRunnerId, - scheduler: config.Scheduler, - runInterval: config.Interval, - containerRegistry: config.ContainerRegistry, - gitProviderStore: config.GitProviderStore, - buildStore: config.BuildStore, - builderFactory: config.BuilderFactory, - loggerFactory: config.LoggerFactory, - basePath: config.BasePath, - telemetryEnabled: config.TelemetryEnabled, - telemetryService: config.TelemetryService, - } - - return runner -} - -func (r *BuildRunner) Start() error { - err := r.scheduler.AddFunc(r.runInterval, func() { r.RunBuilds() }) - if err != nil { - return err - } - err = r.scheduler.AddFunc(r.runInterval, func() { r.DeleteBuilds() }) - if err != nil { - return err - } - - r.scheduler.Start() - return nil -} - -func (r *BuildRunner) Stop() { - r.scheduler.Stop() -} - -func (r *BuildRunner) RunBuilds() { - builds, err := r.buildStore.List(&stores.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePendingRun, models.BuildStatePublished}, - }) - if err != nil { - log.Error(err) - return - } - - var wg sync.WaitGroup - for _, b := range builds { - if b.State == models.BuildStatePendingRun { - wg.Add(1) - - if b.BuildConfig == nil { - return - } - - buildLogger := r.loggerFactory.CreateBuildLogger(b.Id, logs.LogSourceBuilder) - defer buildLogger.Close() - - workspaceDir := filepath.Join(r.basePath, b.Id, "workspace") - - builder, err := r.builderFactory.Create(*b, workspaceDir) - if err != nil { - r.handleBuildError(*b, builder, err, buildLogger) - return - } - - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Error(err) - return - } - - imageName, err := builder.GetImageName(*b) - if err != nil { - r.handleBuildError(*b, builder, err, buildLogger) - return - } - - _, _, err = cli.ImageInspectWithRaw(context.Background(), imageName) - if err == nil { - b.State = models.BuildStatePublished - err = r.buildStore.Save(b) - if err != nil { - r.handleBuildError(*b, builder, err, buildLogger) - return - } - return - } - - b.BuildConfig.CachedBuild = models.GetCachedBuild(b, builds) - - go r.RunBuildProcess(BuildProcessConfig{ - Builder: builder, - BuildLogger: buildLogger, - Build: b, - WorkspaceDir: workspaceDir, - GitService: &git.Service{ - WorkspaceDir: workspaceDir, - LogWriter: buildLogger, - }, - Wg: &wg, - }) - } - } - - wg.Wait() -} - -func (r *BuildRunner) DeleteBuilds() { - markedForDeletionBuilds, err := r.buildStore.List(&stores.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePendingDelete, models.BuildStatePendingForcedDelete}, - }) - if err != nil { - log.Error(err) - return - } - - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Error(err) - return - } - - dockerClient := docker.NewDockerClient(docker.DockerClientConfig{ - ApiClient: cli, - }) - - var wg sync.WaitGroup - for _, b := range markedForDeletionBuilds { - wg.Add(1) - - go func(b *models.Build) { - buildLogger := r.loggerFactory.CreateBuildLogger(b.Id, logs.LogSourceBuilder) - defer buildLogger.Close() - - force := b.State == models.BuildStatePendingForcedDelete - - b.State = models.BuildStateDeleting - err = r.buildStore.Save(b) - if err != nil { - r.handleBuildError(*b, nil, err, buildLogger) - return - } - - // If the build has an image, delete it first - if b.Image != nil { - err := dockerClient.DeleteImage(*b.Image, true, nil) - if err != nil { - r.handleBuildError(*b, nil, err, buildLogger) - if !force { - return - } - } - } - - err = r.buildStore.Delete(b.Id) - if err != nil { - r.handleBuildError(*b, nil, err, buildLogger) - return - } - }(b) - } - - wg.Wait() -} - -func (r *BuildRunner) RunBuildProcess(config BuildProcessConfig) { - if config.Wg != nil { - defer config.Wg.Done() - } - - config.Build.State = models.BuildStateRunning - err := r.buildStore.Save(config.Build) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - gitProviders, err := r.gitProviderStore.ListConfigsForUrl(config.Build.Repository.Url) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - var auth *http.BasicAuth - if len(gitProviders) > 0 { - auth = &http.BasicAuth{} - auth.Username = gitProviders[0].Username - auth.Password = gitProviders[0].Token - } - - err = config.GitService.CloneRepository(config.Build.Repository, auth) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - image, user, err := config.Builder.Build(*config.Build) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - config.Build.Image = &image - config.Build.User = &user - config.Build.State = models.BuildStateSuccess - err = r.buildStore.Save(config.Build) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - err = config.Builder.Publish(*config.Build) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - config.Build.State = models.BuildStatePublished - err = r.buildStore.Save(config.Build) - if err != nil { - r.handleBuildError(*config.Build, config.Builder, err, config.BuildLogger) - return - } - - err = config.Builder.CleanUp() - if err != nil { - errMsg := fmt.Sprintf("Error cleaning up build: %s\n", err.Error()) - config.BuildLogger.Write([]byte(errMsg + "\n")) - } - - config.BuildLogger.Write([]byte("\n \n" + lipgloss.NewStyle().Bold(true).Render("Build completed successfully"))) - - if r.telemetryEnabled { - r.logTelemetry(context.Background(), *config.Build, err) - } -} - -func (r *BuildRunner) handleBuildError(b models.Build, builder IBuilder, err error, buildLogger logs.Logger) { - var errMsg string - errMsg += "################################################\n" - errMsg += fmt.Sprintf("#### BUILD FAILED FOR %s: %s\n", b.Id, err.Error()) - errMsg += "################################################\n" - - b.State = models.BuildStateError - err = r.buildStore.Save(&b) - if err != nil { - errMsg += fmt.Sprintf("Error saving build: %s\n", err.Error()) - } - - if builder != nil { - cleanupErr := builder.CleanUp() - if cleanupErr != nil { - errMsg += fmt.Sprintf("Error cleaning up build: %s\n", cleanupErr.Error()) - } - } - - buildLogger.Write([]byte(errMsg + "\n")) - - if r.telemetryEnabled { - r.logTelemetry(context.Background(), b, err) - } -} - -func (r *BuildRunner) logTelemetry(ctx context.Context, b models.Build, err error) { - telemetryProps := telemetry.NewBuildRunnerEventProps(ctx, b.Id, string(b.State)) - event := telemetry.BuildRunnerEventRunBuild - if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.BuildRunnerEventRunBuildError - } - telemetryError := r.telemetryService.TrackBuildRunnerEvent(event, r.Id, telemetryProps) - if telemetryError != nil { - log.Trace(telemetryError) - } -} diff --git a/pkg/build/runner_config.go b/pkg/build/runner_config.go deleted file mode 100644 index 7e81640634..0000000000 --- a/pkg/build/runner_config.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package build - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/google/uuid" -) - -// TODO: add lock when running interval func -// 10 second interval -const DEFAULT_BUILD_POLL_INTERVAL = "*/10 * * * * *" - -type Config struct { - Id string `json:"id" validate:"required"` - Interval string `json:"interval" validate:"required"` - TelemetryEnabled bool `json:"telemetryEnabled" validate:"required"` -} // @name BuildRunnerConfig - -func GetConfig() (*Config, error) { - configFilePath, err := getConfigFilePath() - if err != nil { - return nil, err - } - - _, err = os.Stat(configFilePath) - if os.IsNotExist(err) { - c := getDefaultConfig() - - err = Save(*c) - if err != nil { - return nil, fmt.Errorf("failed to save default config file: %w", err) - } - - return c, nil - } - - if err != nil { - return nil, err - } - - var c Config - configContent, err := os.ReadFile(configFilePath) - if err != nil { - return nil, err - } - - err = json.Unmarshal(configContent, &c) - if err != nil { - return nil, err - } - - if c.Id == "" { - c.Id = uuid.NewString() - } - err = Save(c) - if err != nil { - return nil, err - } - - return &c, nil -} - -func getConfigFilePath() (string, error) { - configDir, err := GetRunnerConfigDir() - if err != nil { - return "", err - } - - return filepath.Join(configDir, "config.json"), nil -} - -func Save(c Config) error { - configFilePath, err := getConfigFilePath() - if err != nil { - return err - } - - configContent, err := json.MarshalIndent(c, "", " ") - if err != nil { - return err - } - - err = os.MkdirAll(filepath.Dir(configFilePath), 0700) - if err != nil { - return err - } - - return os.WriteFile(configFilePath, configContent, 0600) -} - -func GetRunnerConfigDir() (string, error) { - configDir, err := config.GetConfigDir() - if err != nil { - return "", err - } - - return filepath.Join(configDir, "build-runner"), nil -} - -func getDefaultConfig() *Config { - return &Config{ - Id: uuid.NewString(), - Interval: DEFAULT_BUILD_POLL_INTERVAL, - TelemetryEnabled: false, - } -} diff --git a/pkg/build/runner_test.go b/pkg/build/runner_test.go deleted file mode 100644 index 531e05a79f..0000000000 --- a/pkg/build/runner_test.go +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package build_test - -import ( - "testing" - - t_build "github.com/daytonaio/daytona/internal/testing/build" - git_mocks "github.com/daytonaio/daytona/internal/testing/git/mocks" - logger_mocks "github.com/daytonaio/daytona/internal/testing/logger/mocks" - "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/build" - t_gitprovider "github.com/daytonaio/daytona/pkg/build/mocks" - "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/go-git/go-git/v5/plumbing/transport/http" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/suite" -) - -var gitProviderConfig = models.GitProviderConfig{ - Id: "github", - Username: "daytonaio", - Token: "", - BaseApiUrl: nil, -} - -type BuildRunnerTestSuite struct { - suite.Suite - mockBuilderFactory mocks.MockBuilderFactory - mockBuilder mocks.MockBuilder - mockScheduler mocks.MockScheduler - mockGitService git_mocks.MockGitService - loggerFactory logs.LoggerFactory - mockBuildStore stores.BuildStore - mockGitProviderConfigStore t_gitprovider.MockGitProviderConfigStore - Runner build.BuildRunner -} - -func NewBuildRunnerTestSuite() *BuildRunnerTestSuite { - return &BuildRunnerTestSuite{} -} - -func TestBuildRunner(t *testing.T) { - s := NewBuildRunnerTestSuite() - - s.mockBuilderFactory = mocks.MockBuilderFactory{} - s.mockBuilder = mocks.MockBuilder{} - s.mockScheduler = mocks.MockScheduler{} - s.mockGitProviderConfigStore = t_gitprovider.MockGitProviderConfigStore{} - - s.mockBuildStore = t_build.NewInMemoryBuildStore() - logTempDir := t.TempDir() - s.loggerFactory = logs.NewLoggerFactory(nil, &logTempDir) - - s.Runner = *build.NewBuildRunner(build.BuildRunnerInstanceConfig{ - Interval: "0 */5 * * * *", - Scheduler: &s.mockScheduler, - BuildRunnerId: "1", - BuildStore: s.mockBuildStore, - GitProviderStore: &s.mockGitProviderConfigStore, - BuilderFactory: &s.mockBuilderFactory, - LoggerFactory: s.loggerFactory, - TelemetryEnabled: false, - }) - - suite.Run(t, s) -} - -func (s *BuildRunnerTestSuite) SetupTest() { - err := s.mockBuildStore.Save(mocks.MockBuild) - if err != nil { - s.T().Fatal(err) - } -} - -func (s *BuildRunnerTestSuite) TestStart() { - s.mockScheduler.On("AddFunc", mock.Anything, mock.Anything).Return(nil) - s.mockScheduler.On("Start").Return() - - require := s.Require() - - err := s.Runner.Start() - require.NoError(err) - - s.mockScheduler.AssertExpectations(s.T()) -} - -func (s *BuildRunnerTestSuite) TestStop() { - s.mockScheduler.On("Stop").Return() - - s.Runner.Stop() - - s.mockScheduler.AssertExpectations(s.T()) -} - -// TODO FIXME: Need to figure out how to test the RunBuildProcess goroutine -func (s *BuildRunnerTestSuite) TestRun() { - s.T().Skip("Need to figure out how to test the runBuildProcess goroutine") -} - -func (s *BuildRunnerTestSuite) TestRunBuildProcess() { - pendingBuild := *mocks.MockBuild - s.mockGitProviderConfigStore.On("ListConfigsForUrl", pendingBuild.Repository.Url).Return([]*models.GitProviderConfig{&gitProviderConfig}, nil) - s.mockGitService.On("CloneRepository", pendingBuild.Repository, &http.BasicAuth{ - Username: gitProviderConfig.Username, - }).Return(nil) - - mockGitService := git_mocks.NewMockGitService() - mockGitService.On("CloneRepository", pendingBuild.Repository, &http.BasicAuth{ - Username: gitProviderConfig.Username, - }).Return(nil) - - runningBuild := *mocks.MockBuild - runningBuild.State = models.BuildStateRunning - s.mockBuilder.On("Build", runningBuild).Return("image", "user", nil) - - successBuild := *mocks.MockBuild - successBuild.State = models.BuildStateSuccess - successBuild.Image = util.Pointer("image") - successBuild.User = util.Pointer("user") - s.mockBuilder.On("Publish", successBuild).Return(nil) - - s.mockBuilder.On("CleanUp").Return(nil) - - mockLogger := logger_mocks.NewMockLogger() - mockLogger.On("Write", mock.Anything).Return(0, nil) - - s.Runner.RunBuildProcess(build.BuildProcessConfig{ - Builder: &s.mockBuilder, - BuildLogger: mockLogger, - Build: mocks.MockBuild, - WorkspaceDir: "", - GitService: mockGitService, - Wg: nil, - }) - - mockLogger.AssertExpectations(s.T()) - s.mockBuilder.AssertExpectations(s.T()) - s.mockGitProviderConfigStore.AssertExpectations(s.T()) - - s.Require().Equal(mocks.MockBuild.Image, util.Pointer("image")) - s.Require().Equal(mocks.MockBuild.User, util.Pointer("user")) - s.Require().Equal(mocks.MockBuild.State, models.BuildStatePublished) -} diff --git a/pkg/cmd/build/info.go b/pkg/cmd/build/info.go index b471f46674..f38fb46b4f 100644 --- a/pkg/cmd/build/info.go +++ b/pkg/cmd/build/info.go @@ -23,7 +23,7 @@ var buildInfoCmd = &cobra.Command{ Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - var build *apiclient.Build + var build *apiclient.BuildDTO apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index 8489c12631..07d2315feb 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -15,6 +15,7 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" ) @@ -37,6 +38,11 @@ var buildRunCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } + if len(workspaceTemplateList) == 0 { + views_util.NotifyEmptyWorkspaceTemplateList(true) + return nil + } + workspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceTemplateList, 0, false, false, "Build") if workspaceTemplate == nil { return nil diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 9a148fb300..1cd053d401 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -12,7 +12,6 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/cmd/server/bootstrap" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/posthogservice" @@ -51,11 +50,6 @@ var purgeCmd = &cobra.Command{ return err } - buildRunnerConfig, err := build.GetConfig() - if err != nil { - return err - } - if c.ActiveProfileId != "default" { if !create.YesFlag { view.DefaultProfileNoticePrompt(&defaultProfileNoticeConfirm) @@ -116,10 +110,6 @@ var purgeCmd = &cobra.Command{ if err != nil { return err } - buildRunner, err := bootstrap.GetBuildRunner(serverConfig, buildRunnerConfig, telemetryService) - if err != nil { - return err - } ctx := context.Background() ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, config.GetClientId()) @@ -127,19 +117,10 @@ var purgeCmd = &cobra.Command{ errCh := make(chan error) - // Starting the build runner so it can be used to delete builds - err = buildRunner.Start() - if err != nil { - if !forceFlag { - return err - } - } - go func() { err := <-errCh if err != nil { if !forceFlag { - buildRunner.Stop() log.Fatal(err) } } diff --git a/pkg/cmd/server/bootstrap/get_build_runner.go b/pkg/cmd/server/bootstrap/get_build_runner.go deleted file mode 100644 index 52453fda10..0000000000 --- a/pkg/cmd/server/bootstrap/get_build_runner.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package bootstrap - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/db" - "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/scheduler" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/daytonaio/daytona/pkg/server/gitproviders" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/daytonaio/daytona/pkg/telemetry" -) - -func GetBuildRunner(c *server.Config, buildRunnerConfig *build.Config, telemetryService telemetry.TelemetryService) (*build.BuildRunner, error) { - logsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(nil, &logsDir) - - dbPath, err := getDbPath() - if err != nil { - return nil, err - } - - dbConnection := db.GetSQLiteConnection(dbPath) - - gitProviderConfigStore, err := db.NewGitProviderConfigStore(dbConnection) - if err != nil { - return nil, err - } - - gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ - ConfigStore: gitProviderConfigStore, - }) - - buildStore, err := db.NewBuildStore(dbConnection) - if err != nil { - return nil, err - } - - buildImageNamespace := c.BuildImageNamespace - if buildImageNamespace != "" { - buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) - } - buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") - - containerRegistryStore, err := db.NewContainerRegistryStore(dbConnection) - if err != nil { - return nil, err - } - - containerRegistryService := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ - Store: containerRegistryStore, - }) - - var builderRegistry *models.ContainerRegistry - - if c.BuilderRegistryServer != "local" { - builderRegistry, err = containerRegistryService.Find(c.BuilderRegistryServer) - if err != nil { - builderRegistry = &models.ContainerRegistry{ - Server: c.BuilderRegistryServer, - } - } - } - - cr, err := containerRegistryService.FindByImageName(c.BuilderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return nil, err - } - - configDir, err := config.GetConfigDir() - if err != nil { - return nil, err - } - - builderFactory := build.NewBuilderFactory(build.BuilderFactoryConfig{ - Image: c.BuilderImage, - ContainerRegistry: cr, - BuildImageContainerRegistry: builderRegistry, - BuildStore: buildStore, - BuildImageNamespace: buildImageNamespace, - LoggerFactory: loggerFactory, - DefaultWorkspaceImage: c.DefaultWorkspaceImage, - DefaultWorkspaceUser: c.DefaultWorkspaceUser, - }) - - return build.NewBuildRunner(build.BuildRunnerInstanceConfig{ - Interval: buildRunnerConfig.Interval, - Scheduler: scheduler.NewCronScheduler(), - BuildRunnerId: buildRunnerConfig.Id, - ContainerRegistry: builderRegistry, - GitProviderStore: gitProviderService, - BuildStore: buildStore, - BuilderFactory: builderFactory, - LoggerFactory: loggerFactory, - BasePath: filepath.Join(configDir, "builds"), - TelemetryService: telemetryService, - }), nil -} diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go index b2af45919e..5e024f2b56 100644 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -5,9 +5,14 @@ package bootstrap import ( "context" + "fmt" + "path/filepath" + "strings" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/docker" + jobs_build "github.com/daytonaio/daytona/pkg/jobs/build" "github.com/daytonaio/daytona/pkg/jobs/target" "github.com/daytonaio/daytona/pkg/jobs/workspace" "github.com/daytonaio/daytona/pkg/logs" @@ -19,6 +24,7 @@ import ( "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/docker/docker/client" "github.com/daytonaio/daytona/pkg/runners/runner" ) @@ -36,6 +42,11 @@ func GetJobRunner(c *server.Config, configDir string, version string, telemetryS return nil, err } + buildJobFactory, err := GetBuildJobFactory(c, configDir, version, telemetryService) + if err != nil { + return nil, err + } + return runner.NewJobRunner(runner.JobRunnerConfig{ ListPendingJobs: func(ctx context.Context) ([]*models.Job, error) { return jobService.List(&stores.JobFilter{ @@ -51,6 +62,7 @@ func GetJobRunner(c *server.Config, configDir string, version string, telemetryS }, WorkspaceJobFactory: workspaceJobFactory, TargetJobFactory: targetJobFactory, + BuildJobFactory: buildJobFactory, }), nil } @@ -146,3 +158,98 @@ func GetTargetJobFactory(c *server.Config, configDir string, version string, tel Provisioner: provisioner, }), nil } + +func GetBuildJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (jobs_build.IBuildJobFactory, error) { + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return nil, err + } + + dockerClient := docker.NewDockerClient(docker.DockerClientConfig{ + ApiClient: cli, + }) + + logsDir, err := build.GetBuildLogsDir() + if err != nil { + return nil, err + } + loggerFactory := logs.NewLoggerFactory(nil, &logsDir) + + buildService := server.GetInstance(nil).BuildService + + containerRegistryService := server.GetInstance(nil).ContainerRegistryService + + cr, err := containerRegistryService.FindByImageName(c.BuilderImage) + if err != nil && !stores.IsContainerRegistryNotFound(err) { + return nil, err + } + + buildImageNamespace := c.BuildImageNamespace + if buildImageNamespace != "" { + buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) + } + buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") + + var builderRegistry *models.ContainerRegistry + + if c.BuilderRegistryServer != "local" { + builderRegistry, err = containerRegistryService.Find(c.BuilderRegistryServer) + if err != nil { + builderRegistry = &models.ContainerRegistry{ + Server: c.BuilderRegistryServer, + } + } + } + + return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ + FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { + return buildService.Find(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &buildId, + }, + }) + }, + ListSuccessfulBuilds: func(ctx context.Context, repoUrl string) ([]*models.Build, error) { + buildDtos, err := buildService.List(&services.BuildFilter{ + StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, + StoreFilter: stores.BuildFilter{ + RepositoryUrl: &repoUrl, + }, + }) + if err != nil { + return nil, err + } + + var builds []*models.Build + for _, buildDto := range buildDtos { + builds = append(builds, &buildDto.Build) + } + return builds, nil + }, + ListConfigsForUrl: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { + return server.GetInstance(nil).GitProviderService.ListConfigsForUrl(repoUrl) + }, + CheckImageExists: func(ctx context.Context, image string) bool { + _, _, err = cli.ImageInspectWithRaw(context.Background(), image) + return err == nil + }, + DeleteImage: func(ctx context.Context, image string, force bool) error { + return dockerClient.DeleteImage(image, force, nil) + }, + TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { + return telemetryService.TrackBuildRunnerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ + Image: c.BuilderImage, + ContainerRegistry: cr, + BuildImageContainerRegistry: builderRegistry, + BuildService: buildService, + BuildImageNamespace: buildImageNamespace, + LoggerFactory: loggerFactory, + DefaultWorkspaceImage: c.DefaultWorkspaceImage, + DefaultWorkspaceUser: c.DefaultWorkspaceUser, + }), + BasePath: filepath.Join(configDir, "builds"), + }), nil +} diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index d87cad79d8..7d89a5c428 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -149,6 +149,10 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }, }) + jobService := jobs.NewJobService(jobs.JobServiceConfig{ + JobStore: jobStore, + }) + buildService := builds.NewBuildService(builds.BuildServiceConfig{ BuildStore: buildStore, FindWorkspaceTemplate: func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) { @@ -168,6 +172,14 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return repo, err }, + CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { + return jobService.Create(&models.Job{ + ResourceId: workspaceId, + ResourceType: models.ResourceTypeBuild, + Action: action, + State: models.JobStatePending, + }) + }, LoggerFactory: loggerFactory, }) @@ -176,15 +188,17 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe workspaceTemplateService := workspacetemplates.NewWorkspaceTemplateService(workspacetemplates.WorkspaceTemplateServiceConfig{ PrebuildWebhookEndpoint: prebuildWebhookEndpoint, ConfigStore: workspaceTemplateStore, - FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { - return buildService.Find(&stores.BuildFilter{ - PrebuildIds: &[]string{prebuildId}, - GetNewest: util.Pointer(true), + FindNewestBuild: func(ctx context.Context, prebuildId string) (*services.BuildDTO, error) { + return buildService.Find(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + PrebuildIds: &[]string{prebuildId}, + GetNewest: util.Pointer(true), + }, }) }, - ListPublishedBuilds: func(ctx context.Context) ([]*models.Build, error) { - return buildService.List(&stores.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePublished}, + ListSuccessfulBuilds: func(ctx context.Context) ([]*services.BuildDTO, error) { + return buildService.List(&services.BuildFilter{ + StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, }) }, CreateBuild: func(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error { @@ -204,9 +218,11 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe prebuildIds = &[]string{*prebuildId} } - return buildService.MarkForDeletion(&stores.BuildFilter{ - Id: id, - PrebuildIds: prebuildIds, + return buildService.Delete(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: id, + PrebuildIds: prebuildIds, + }, }, force) }, GetRepositoryContext: func(ctx context.Context, url string) (*gitprovider.GitRepository, string, error) { @@ -278,10 +294,6 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) - jobService := jobs.NewJobService(jobs.JobServiceConfig{ - JobStore: jobStore, - }) - provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ ProviderManager: providerManager, }) @@ -328,17 +340,19 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return containerRegistryService.FindByImageName(image) }, FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { - validStates := &[]models.BuildState{ - models.BuildStatePublished, + validStates := []models.ResourceStateName{ + models.ResourceStateNameRunSuccessful, } - build, err := buildService.Find(&stores.BuildFilter{ - States: validStates, - RepositoryUrl: &w.Repository.Url, - Branch: &w.Repository.Branch, - EnvVars: &w.EnvVars, - BuildConfig: w.BuildConfig, - GetNewest: util.Pointer(true), + build, err := buildService.Find(&services.BuildFilter{ + StateNames: &validStates, + StoreFilter: stores.BuildFilter{ + RepositoryUrl: &w.Repository.Url, + Branch: &w.Repository.Branch, + EnvVars: &w.EnvVars, + BuildConfig: w.BuildConfig, + GetNewest: util.Pointer(true), + }, }) if err != nil { return nil, err diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index e7d8d0e97b..01c352df92 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -15,7 +15,6 @@ import ( "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/api" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/cmd/server/bootstrap" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" @@ -85,21 +84,6 @@ var ServeCmd = &cobra.Command{ return err } - buildRunnerConfig, err := build.GetConfig() - if err != nil { - return err - } - - buildRunner, err := bootstrap.GetBuildRunner(c, buildRunnerConfig, telemetryService) - if err != nil { - return err - } - - err = buildRunner.Start() - if err != nil { - return err - } - jobRunner, err := bootstrap.GetJobRunner(c, configDir, internal.Version, telemetryService) if err != nil { return err diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index 15705778da..b11c5799a8 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -33,7 +33,7 @@ func (b *BuildStore) Find(filter *stores.BuildFilter) (*models.Build, error) { defer b.Lock.Unlock() build := &models.Build{} - tx := processBuildFilters(b.db, filter).First(build) + tx := preloadBuildEntities(processBuildFilters(b.db, filter)).First(build) if tx.Error != nil { if tx.Error == gorm.ErrRecordNotFound { @@ -50,7 +50,7 @@ func (b *BuildStore) List(filter *stores.BuildFilter) ([]*models.Build, error) { defer b.Lock.Unlock() builds := []*models.Build{} - tx := processBuildFilters(b.db, filter).Find(&builds) + tx := preloadBuildEntities(processBuildFilters(b.db, filter)).Find(&builds) if tx.Error != nil { return nil, tx.Error @@ -86,17 +86,15 @@ func (b *BuildStore) Delete(id string) error { return nil } +func preloadBuildEntities(tx *gorm.DB) *gorm.DB { + return tx.Preload("LastJob", preloadLastJob) +} + func processBuildFilters(tx *gorm.DB, filter *stores.BuildFilter) *gorm.DB { if filter != nil { if filter.Id != nil { tx = tx.Where("id = ?", *filter.Id) } - if filter.States != nil && len(*filter.States) > 0 { - placeholders := strings.Repeat("?,", len(*filter.States)) - placeholders = placeholders[:len(placeholders)-1] - - tx = tx.Where(fmt.Sprintf("state IN (%s)", placeholders), filter.StatesToInterface()...) - } if filter.PrebuildIds != nil && len(*filter.PrebuildIds) > 0 { placeholders := strings.Repeat("?,", len(*filter.PrebuildIds)) placeholders = placeholders[:len(placeholders)-1] diff --git a/pkg/jobs/build/build.go b/pkg/jobs/build/build.go new file mode 100644 index 0000000000..1abff13387 --- /dev/null +++ b/pkg/jobs/build/build.go @@ -0,0 +1,43 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type BuildJob struct { + models.Job + + findBuild func(ctx context.Context, buildId string) (*services.BuildDTO, error) + listSuccessfulBuilds func(ctx context.Context, repoUrl string) ([]*models.Build, error) + listConfigsForUrl func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) + checkImageExists func(ctx context.Context, image string) bool + deleteImage func(ctx context.Context, image string, force bool) error + + trackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + loggerFactory logs.LoggerFactory + builderFactory build.IBuilderFactory + + basePath string +} + +func (tj *BuildJob) Execute(ctx context.Context) error { + switch tj.Action { + case models.JobActionRun: + return tj.run(ctx, &tj.Job) + case models.JobActionDelete: + return tj.delete(ctx, &tj.Job, false) + case models.JobActionForceDelete: + return tj.delete(ctx, &tj.Job, true) + } + return errors.New("invalid job action") +} diff --git a/pkg/jobs/build/delete.go b/pkg/jobs/build/delete.go new file mode 100644 index 0000000000..9e2f2a7486 --- /dev/null +++ b/pkg/jobs/build/delete.go @@ -0,0 +1,23 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" +) + +func (bj *BuildJob) delete(ctx context.Context, j *models.Job, force bool) error { + b, err := bj.findBuild(ctx, j.ResourceId) + if err != nil { + return err + } + + if b.Image != nil { + return bj.deleteImage(ctx, *b.Image, force) + } + + return nil +} diff --git a/pkg/jobs/build/factory.go b/pkg/jobs/build/factory.go new file mode 100644 index 0000000000..d32b33f330 --- /dev/null +++ b/pkg/jobs/build/factory.go @@ -0,0 +1,60 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type IBuildJobFactory interface { + Create(job models.Job) jobs.IJob +} + +type BuildJobFactory struct { + config BuildJobFactoryConfig +} + +type BuildJobFactoryConfig struct { + FindBuild func(ctx context.Context, buildId string) (*services.BuildDTO, error) + ListSuccessfulBuilds func(ctx context.Context, repoUrl string) ([]*models.Build, error) + ListConfigsForUrl func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) + CheckImageExists func(ctx context.Context, image string) bool + DeleteImage func(ctx context.Context, image string, force bool) error + + TrackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + LoggerFactory logs.LoggerFactory + BuilderFactory build.IBuilderFactory + + BasePath string +} + +func NewBuildJobFactory(config BuildJobFactoryConfig) IBuildJobFactory { + return &BuildJobFactory{ + config: config, + } +} + +func (f *BuildJobFactory) Create(job models.Job) jobs.IJob { + return &BuildJob{ + Job: job, + + findBuild: f.config.FindBuild, + listSuccessfulBuilds: f.config.ListSuccessfulBuilds, + listConfigsForUrl: f.config.ListConfigsForUrl, + checkImageExists: f.config.CheckImageExists, + deleteImage: f.config.DeleteImage, + + trackTelemetryEvent: f.config.TrackTelemetryEvent, + loggerFactory: f.config.LoggerFactory, + builderFactory: f.config.BuilderFactory, + basePath: f.config.BasePath, + } +} diff --git a/pkg/jobs/build/run.go b/pkg/jobs/build/run.go new file mode 100644 index 0000000000..6e77244c7f --- /dev/null +++ b/pkg/jobs/build/run.go @@ -0,0 +1,141 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + "fmt" + "path/filepath" + + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/git" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/go-git/go-git/v5/plumbing/transport/http" +) + +func (bj *BuildJob) run(ctx context.Context, j *models.Job) error { + b, err := bj.findBuild(ctx, j.ResourceId) + if err != nil { + return err + } + + successfulBuilds, err := bj.listSuccessfulBuilds(ctx, b.Repository.Url) + if err != nil { + return err + } + + if b.BuildConfig == nil { + return fmt.Errorf("build config is not set") + } + + buildLogger := bj.loggerFactory.CreateBuildLogger(b.Id, logs.LogSourceBuilder) + defer buildLogger.Close() + + workspaceDir := filepath.Join(bj.basePath, b.Id, "workspace") + + builder, err := bj.builderFactory.Create(b.Build, workspaceDir) + if err != nil { + return bj.handleBuildResult(b.Build, builder, buildLogger, err) + } + + imageName, err := builder.GetImageName(b.Build) + if err != nil { + return bj.handleBuildResult(b.Build, builder, buildLogger, err) + } + + exists := bj.checkImageExists(ctx, imageName) + if err != nil { + return bj.handleBuildResult(b.Build, builder, buildLogger, err) + } + + if exists { + return bj.handleBuildResult(b.Build, builder, buildLogger, nil) + } + + b.BuildConfig.CachedBuild = models.GetCachedBuild(&b.Build, successfulBuilds) + + err = bj.runBuildProcess(ctx, BuildProcessConfig{ + Builder: builder, + Build: &b.Build, + GitService: &git.Service{ + WorkspaceDir: workspaceDir, + LogWriter: buildLogger, + }, + }) + if err != nil { + return bj.handleBuildResult(b.Build, builder, buildLogger, err) + } + + buildLogger.Write([]byte("\n \n" + lipgloss.NewStyle().Bold(true).Render("Build run successful. Publishing..."))) + + err = builder.Publish(b.Build) + if err != nil { + return bj.handleBuildResult(b.Build, builder, buildLogger, err) + } + + err = builder.CleanUp() + if err != nil { + errMsg := fmt.Sprintf("Error cleaning up build: %s\n", err.Error()) + buildLogger.Write([]byte(errMsg + "\n")) + } + + return bj.handleBuildResult(b.Build, builder, buildLogger, err) +} + +type BuildProcessConfig struct { + Builder build.IBuilder + Build *models.Build + GitService git.IGitService +} + +func (bj *BuildJob) runBuildProcess(ctx context.Context, config BuildProcessConfig) error { + gitProviders, err := bj.listConfigsForUrl(ctx, config.Build.Repository.Url) + if err != nil { + return err + } + + var auth *http.BasicAuth + if len(gitProviders) > 0 { + auth = &http.BasicAuth{} + auth.Username = gitProviders[0].Username + auth.Password = gitProviders[0].Token + } + + err = config.GitService.CloneRepository(config.Build.Repository, auth) + if err != nil { + return err + } + + image, user, err := config.Builder.Build(*config.Build) + if err != nil { + return err + } + + config.Build.Image = &image + config.Build.User = &user + + return nil +} + +func (bj *BuildJob) handleBuildResult(b models.Build, builder build.IBuilder, buildLogger logs.Logger, err error) error { + var errMsg string + + if err != nil { + errMsg += "################################################\n" + errMsg += fmt.Sprintf("#### BUILD FAILED FOR %s: %s\n", b.Id, err.Error()) + errMsg += "################################################\n" + } + + if builder != nil { + cleanupErr := builder.CleanUp() + if cleanupErr != nil { + errMsg += fmt.Sprintf("Error cleaning up build: %s\n", cleanupErr.Error()) + } + } + + buildLogger.Write([]byte(errMsg + "\n")) + return err +} diff --git a/pkg/models/build.go b/pkg/models/build.go index b07aa34d0e..2b6e4f6a44 100644 --- a/pkg/models/build.go +++ b/pkg/models/build.go @@ -11,33 +11,24 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" ) -type BuildState string - -const ( - BuildStatePendingRun BuildState = "pending-run" - BuildStateRunning BuildState = "running" - BuildStateError BuildState = "error" - BuildStateSuccess BuildState = "success" - BuildStatePublished BuildState = "published" - BuildStatePendingDelete BuildState = "pending-delete" - BuildStatePendingForcedDelete BuildState = "pending-forced-delete" - BuildStateDeleting BuildState = "deleting" -) - type Build struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - State BuildState `json:"state" validate:"required"` Image *string `json:"image" validate:"optional"` User *string `json:"user" validate:"optional"` ContainerConfig ContainerConfig `json:"containerConfig" validate:"required" gorm:"serializer:json"` BuildConfig *BuildConfig `json:"buildConfig" validate:"optional" gorm:"serializer:json"` Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` + LastJob *Job `gorm:"foreignKey:ResourceId;references:Id" validate:"optional"` PrebuildId string `json:"prebuildId" validate:"required"` CreatedAt time.Time `json:"createdAt" validate:"required"` UpdatedAt time.Time `json:"updatedAt" validate:"required"` } // @name Build +func (w *Build) GetState() ResourceState { + return getResourceStateFromJob(w.LastJob) +} + type ContainerConfig struct { Image string `json:"image" validate:"required"` User string `json:"user" validate:"required"` @@ -114,7 +105,7 @@ func GetCachedBuild(build *Build, builds []*Build) *CachedBuild { if err != nil { continue } - if !equal || existingBuild.State != BuildStatePublished { + if !equal || existingBuild.GetState().Name != ResourceStateNameRunSuccessful { continue } if cachedBuild == nil { diff --git a/pkg/models/common.go b/pkg/models/common.go new file mode 100644 index 0000000000..4a6ee240aa --- /dev/null +++ b/pkg/models/common.go @@ -0,0 +1,45 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +import "time" + +type ResourceState struct { + Name ResourceStateName `json:"name" validate:"required"` + Error *string `json:"error" validate:"optional"` + UpdatedAt time.Time `json:"updatedAt" validate:"required"` +} // @name ResourceState + +type ResourceStateName string + +const ( + ResourceStateNameUndefined ResourceStateName = "undefined" + ResourceStateNamePendingRun ResourceStateName = "pending-run" + ResourceStateNameRunning ResourceStateName = "running" + ResourceStateNameRunSuccessful ResourceStateName = "run-successful" + ResourceStateNamePendingCreate ResourceStateName = "pending-create" + ResourceStateNameCreating ResourceStateName = "creating" + ResourceStateNamePendingStart ResourceStateName = "pending-start" + ResourceStateNameStarting ResourceStateName = "starting" + ResourceStateNameStarted ResourceStateName = "started" + ResourceStateNamePendingStop ResourceStateName = "pending-stop" + ResourceStateNameStopping ResourceStateName = "stopping" + ResourceStateNameStopped ResourceStateName = "stopped" + ResourceStateNamePendingRestart ResourceStateName = "pending-restart" + ResourceStateNameError ResourceStateName = "error" + ResourceStateNameUnresponsive ResourceStateName = "unresponsive" + ResourceStateNamePendingDelete ResourceStateName = "pending-delete" + ResourceStateNamePendingForcedDelete ResourceStateName = "pending-forced-delete" + ResourceStateNameDeleting ResourceStateName = "deleting" + ResourceStateNameDeleted ResourceStateName = "deleted" +) + +type BuildConfig struct { + Devcontainer *DevcontainerConfig `json:"devcontainer,omitempty" validate:"optional"` + CachedBuild *CachedBuild `json:"cachedBuild,omitempty" validate:"optional"` +} // @name BuildConfig + +type DevcontainerConfig struct { + FilePath string `json:"filePath" validate:"required"` +} // @name DevcontainerConfig diff --git a/pkg/models/job.go b/pkg/models/job.go index b51c4a3a4b..005c1e5447 100644 --- a/pkg/models/job.go +++ b/pkg/models/job.go @@ -23,6 +23,7 @@ type ResourceType string // @name ResourceType const ( ResourceTypeWorkspace ResourceType = "workspace" ResourceTypeTarget ResourceType = "target" + ResourceTypeBuild ResourceType = "build" ) type JobState string // @name JobState @@ -43,6 +44,7 @@ const ( JobActionRestart JobAction = "restart" JobActionDelete JobAction = "delete" JobActionForceDelete JobAction = "force-delete" + JobActionRun JobAction = "run" ) func getResourceStateFromJob(job *Job) ResourceState { @@ -57,6 +59,8 @@ func getResourceStateFromJob(job *Job) ResourceState { if job.State == JobStateSuccess { switch job.Action { + case JobActionRun: + state.Name = ResourceStateNameRunSuccessful case JobActionCreate: state.Name = ResourceStateNameStarted case JobActionStart: @@ -75,6 +79,8 @@ func getResourceStateFromJob(job *Job) ResourceState { state.Error = job.Error } else if job.State == JobStateRunning { switch job.Action { + case JobActionRun: + state.Name = ResourceStateNameRunning case JobActionCreate: state.Name = ResourceStateNameCreating case JobActionStart: diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index 912034e353..e29187cbb9 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -33,33 +33,6 @@ type WorkspaceMetadata struct { GitStatus *GitStatus `json:"gitStatus" validate:"optional" gorm:"serializer:json"` } // @name WorkspaceMetadata -type ResourceState struct { - Name ResourceStateName `json:"name" validate:"required"` - Error *string `json:"error" validate:"optional"` - UpdatedAt time.Time `json:"updatedAt" validate:"required"` -} // @name ResourceState - -type ResourceStateName string - -const ( - ResourceStateNameUndefined ResourceStateName = "undefined" - ResourceStateNamePendingCreate ResourceStateName = "pending-create" - ResourceStateNameCreating ResourceStateName = "creating" - ResourceStateNamePendingStart ResourceStateName = "pending-start" - ResourceStateNameStarting ResourceStateName = "starting" - ResourceStateNameStarted ResourceStateName = "started" - ResourceStateNamePendingStop ResourceStateName = "pending-stop" - ResourceStateNameStopping ResourceStateName = "stopping" - ResourceStateNameStopped ResourceStateName = "stopped" - ResourceStateNamePendingRestart ResourceStateName = "pending-restart" - ResourceStateNameError ResourceStateName = "error" - ResourceStateNameUnresponsive ResourceStateName = "unresponsive" - ResourceStateNamePendingDelete ResourceStateName = "pending-delete" - ResourceStateNamePendingForcedDelete ResourceStateName = "pending-forced-delete" - ResourceStateNameDeleting ResourceStateName = "deleting" - ResourceStateNameDeleted ResourceStateName = "deleted" -) - func (w *Workspace) WorkspaceFolderName() string { if w.Repository != nil { return w.Repository.Name @@ -82,15 +55,6 @@ func (w *Workspace) GetState() ResourceState { return state } -type BuildConfig struct { - Devcontainer *DevcontainerConfig `json:"devcontainer,omitempty" validate:"optional"` - CachedBuild *CachedBuild `json:"cachedBuild,omitempty" validate:"optional"` -} // @name BuildConfig - -type DevcontainerConfig struct { - FilePath string `json:"filePath" validate:"required"` -} // @name DevcontainerConfig - type CachedBuild struct { User string `json:"user" validate:"required"` Image string `json:"image" validate:"required"` diff --git a/pkg/runners/runner/runner.go b/pkg/runners/runner/runner.go index fbac634b6c..d956955831 100644 --- a/pkg/runners/runner/runner.go +++ b/pkg/runners/runner/runner.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/jobs/build" "github.com/daytonaio/daytona/pkg/jobs/target" "github.com/daytonaio/daytona/pkg/jobs/workspace" "github.com/daytonaio/daytona/pkg/models" @@ -23,6 +24,7 @@ type JobRunnerConfig struct { WorkspaceJobFactory workspace.IWorkspaceJobFactory TargetJobFactory target.ITargetJobFactory + BuildJobFactory build.IBuildJobFactory } func NewJobRunner(config JobRunnerConfig) runners.IJobRunner { @@ -32,6 +34,7 @@ func NewJobRunner(config JobRunnerConfig) runners.IJobRunner { workspaceJobFactory: config.WorkspaceJobFactory, targetJobFactory: config.TargetJobFactory, + buildJobFactory: config.BuildJobFactory, } } @@ -41,6 +44,7 @@ type JobRunner struct { workspaceJobFactory workspace.IWorkspaceJobFactory targetJobFactory target.ITargetJobFactory + buildJobFactory build.IBuildJobFactory } func (s *JobRunner) StartRunner(ctx context.Context) error { @@ -99,6 +103,8 @@ func (s *JobRunner) runJob(ctx context.Context, j *models.Job) error { job = s.workspaceJobFactory.Create(*j) case models.ResourceTypeTarget: job = s.targetJobFactory.Create(*j) + case models.ResourceTypeBuild: + job = s.buildJobFactory.Create(*j) } err = job.Execute(ctx) diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index 66f30f56b7..98cc219ca3 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -21,6 +21,7 @@ type BuildServiceConfig struct { BuildStore stores.BuildStore FindWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) + CreateJob func(ctx context.Context, workspaceId string, action models.JobAction) error LoggerFactory logs.LoggerFactory } @@ -28,6 +29,7 @@ type BuildService struct { buildStore stores.BuildStore findWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) + createJob func(ctx context.Context, workspaceId string, action models.JobAction) error loggerFactory logs.LoggerFactory } @@ -37,6 +39,7 @@ func NewBuildService(config BuildServiceConfig) services.IBuildService { findWorkspaceTemplate: config.FindWorkspaceTemplate, getRepositoryContext: config.GetRepositoryContext, loggerFactory: config.LoggerFactory, + createJob: config.CreateJob, } } @@ -56,8 +59,7 @@ func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { } newBuild := models.Build{ - Id: id, - State: models.BuildStatePendingRun, + Id: id, ContainerConfig: models.ContainerConfig{ Image: workspaceTemplate.Image, User: workspaceTemplate.User, @@ -76,18 +78,74 @@ func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { return "", err } + err = s.createJob(ctx, id, models.JobActionRun) + if err != nil { + return "", err + } + return id, nil } -func (s *BuildService) Find(filter *stores.BuildFilter) (*models.Build, error) { - return s.buildStore.Find(filter) +func (s *BuildService) Find(filter *services.BuildFilter) (*services.BuildDTO, error) { + var storeFilter *stores.BuildFilter + + if filter != nil { + storeFilter = &filter.StoreFilter + } + + build, err := s.buildStore.Find(storeFilter) + if err != nil { + return nil, err + } + + state := build.GetState() + + if state.Name == models.ResourceStateNameDeleted && (filter == nil || !filter.ShowDeleted) { + return nil, services.ErrBuildDeleted + } + + return &services.BuildDTO{ + Build: *build, + State: state, + }, nil } -func (s *BuildService) List(filter *stores.BuildFilter) ([]*models.Build, error) { - return s.buildStore.List(filter) +func (s *BuildService) List(filter *services.BuildFilter) ([]*services.BuildDTO, error) { + var storeFilter *stores.BuildFilter + + if filter != nil { + storeFilter = &filter.StoreFilter + } + + builds, err := s.buildStore.List(storeFilter) + if err != nil { + return nil, err + } + + var result []*services.BuildDTO + + for _, b := range builds { + state := b.GetState() + + if state.Name == models.ResourceStateNameDeleted && (filter == nil || !filter.ShowDeleted) { + continue + } + + result = append(result, &services.BuildDTO{ + Build: *b, + State: state, + }) + } + + return result, nil } -func (s *BuildService) MarkForDeletion(filter *stores.BuildFilter, force bool) []error { +func (s *BuildService) HandleSuccessfulRemoval(id string) error { + return s.buildStore.Delete(id) +} + +func (s *BuildService) Delete(filter *services.BuildFilter, force bool) []error { + ctx := context.Background() var errors []error builds, err := s.List(filter) @@ -97,24 +155,21 @@ func (s *BuildService) MarkForDeletion(filter *stores.BuildFilter, force bool) [ for _, b := range builds { if force { - b.State = models.BuildStatePendingForcedDelete + err = s.createJob(ctx, b.Id, models.JobActionForceDelete) + if err != nil { + errors = append(errors, err) + } } else { - b.State = models.BuildStatePendingDelete - } - - err = s.buildStore.Save(b) - if err != nil { - errors = append(errors, err) + err = s.createJob(ctx, b.Id, models.JobActionDelete) + if err != nil { + errors = append(errors, err) + } } } return errors } -func (s *BuildService) Delete(id string) error { - return s.buildStore.Delete(id) -} - func (s *BuildService) AwaitEmptyList(waitTime time.Duration) error { timeout := time.NewTimer(waitTime) defer timeout.Stop() @@ -124,7 +179,9 @@ func (s *BuildService) AwaitEmptyList(waitTime time.Duration) error { case <-timeout.C: return errors.New("awaiting empty build list timed out") default: - builds, err := s.List(nil) + builds, err := s.List(&services.BuildFilter{ + ShowDeleted: true, + }) if err != nil { return err } diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 80e9da6a8d..0a7408578c 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -28,7 +28,6 @@ var build1 *models.Build = &models.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha1", }, - State: models.BuildStatePublished, } var build2 *models.Build = &models.Build{ @@ -41,7 +40,6 @@ var build2 *models.Build = &models.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha2", }, - State: models.BuildStatePublished, } var build3 *models.Build = &models.Build{ @@ -54,7 +52,6 @@ var build3 *models.Build = &models.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha3", }, - State: models.BuildStatePendingRun, } var build4 *models.Build = &models.Build{ @@ -67,7 +64,6 @@ var build4 *models.Build = &models.Build{ Repository: &gitprovider.GitRepository{ Sha: "sha4", }, - State: models.BuildStatePendingRun, } var expectedBuilds []*models.Build @@ -131,8 +127,10 @@ func (s *BuildServiceTestSuite) TestList() { func (s *BuildServiceTestSuite) TestFind() { require := s.Require() - build, err := s.buildService.Find(&stores.BuildFilter{ - Id: &build1.Id, + build, err := s.buildService.Find(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &build1.Id, + }, }) require.Nil(err) require.Equal(build1, build) @@ -159,29 +157,25 @@ func (s *BuildServiceTestSuite) TestSave() { require.Contains(expectedBuilds, build4) } -func (s *BuildServiceTestSuite) TestMarkForDeletion() { +func (s *BuildServiceTestSuite) TestDelete() { expectedBuilds = append(expectedBuilds, build3) require := s.Require() - err := s.buildService.MarkForDeletion(&stores.BuildFilter{ - Id: &build3.Id, + err := s.buildService.Delete(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &build3.Id, + }, }, false) require.Nil(err) - - b, errs := s.buildService.Find(&stores.BuildFilter{ - Id: &build3.Id, - }) - require.Nil(errs) - require.Equal(b.State, models.BuildStatePendingDelete) } -func (s *BuildServiceTestSuite) TestDelete() { +func (s *BuildServiceTestSuite) TestHandleSuccessfulRemoval() { expectedBuilds = expectedBuilds[:2] require := s.Require() - err := s.buildService.Delete(build3.Id) + err := s.buildService.HandleSuccessfulRemoval(build3.Id) require.Nil(err) builds, err := s.buildService.List(nil) diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index 88e1e548d2..3fea5e94f4 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -4,6 +4,8 @@ package jobs import ( + "slices" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -33,6 +35,15 @@ func (s *JobService) Find(filter *stores.JobFilter) (*models.Job, error) { } func (s *JobService) Create(j *models.Job) error { + validAction, ok := validResourceActions[j.ResourceType] + if !ok { + return services.ErrInvalidResourceJobAction + } + + if !slices.Contains(validAction, j.Action) { + return services.ErrInvalidResourceJobAction + } + pendingJobs, err := s.List(&stores.JobFilter{ ResourceId: &j.ResourceId, ResourceType: &j.ResourceType, @@ -68,3 +79,27 @@ func (s *JobService) Update(j *models.Job) error { func (s *JobService) Delete(j *models.Job) error { return s.jobStore.Delete(j) } + +var validResourceActions = map[models.ResourceType][]models.JobAction{ + models.ResourceTypeWorkspace: { + models.JobActionCreate, + models.JobActionStart, + models.JobActionStop, + models.JobActionRestart, + models.JobActionDelete, + models.JobActionForceDelete, + }, + models.ResourceTypeTarget: { + models.JobActionCreate, + models.JobActionStart, + models.JobActionStop, + models.JobActionRestart, + models.JobActionDelete, + models.JobActionForceDelete, + }, + models.ResourceTypeBuild: { + models.JobActionRun, + models.JobActionDelete, + models.JobActionForceDelete, + }, +} diff --git a/pkg/server/purge.go b/pkg/server/purge.go index 556663fc62..1780714d6a 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -75,7 +75,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { } fmt.Println("Purging builds...") - errs := s.BuildService.MarkForDeletion(nil, force) + errs := s.BuildService.Delete(nil, force) if len(errs) > 0 { s.trackPurgeError(ctx, force, errs[0]) if !force { diff --git a/pkg/server/workspacetemplates/prebuild.go b/pkg/server/workspacetemplates/prebuild.go index 6f802ddcbe..2fd78a2f40 100644 --- a/pkg/server/workspacetemplates/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -9,9 +9,9 @@ import ( "fmt" "sort" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runners" "github.com/daytonaio/daytona/pkg/scheduler" "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" "github.com/daytonaio/daytona/pkg/stores" @@ -294,7 +294,7 @@ func (s *WorkspaceTemplateService) EnforceRetentionPolicy() error { return err } - existingBuilds, err := s.listPublishedBuilds(ctx) + existingBuilds, err := s.listSuccessfulBuilds(ctx) if err != nil { return err } @@ -303,7 +303,7 @@ func (s *WorkspaceTemplateService) EnforceRetentionPolicy() error { // Group builds by their prebuildId for _, b := range existingBuilds { - buildMap[b.PrebuildId] = append(buildMap[b.PrebuildId], *b) + buildMap[b.PrebuildId] = append(buildMap[b.PrebuildId], b.Build) } for _, prebuild := range prebuilds { @@ -337,7 +337,7 @@ func (s *WorkspaceTemplateService) EnforceRetentionPolicy() error { func (s *WorkspaceTemplateService) StartRetentionPoller() error { scheduler := scheduler.NewCronScheduler() - err := scheduler.AddFunc(build.DEFAULT_BUILD_POLL_INTERVAL, func() { + err := scheduler.AddFunc(runners.DEFAULT_JOB_POLL_INTERVAL, func() { err := s.EnforceRetentionPolicy() if err != nil { log.Error(err) diff --git a/pkg/server/workspacetemplates/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go index d83df0f3b1..690f78b758 100644 --- a/pkg/server/workspacetemplates/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -197,31 +197,27 @@ func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventTriggerFiles() { func (s *WorkspaceTemplateServiceTestSuite) TestEnforceRetentionPolicy() { require := s.Require() - s.buildService.On("List", &stores.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePublished}, + s.buildService.On("List", &services.BuildFilter{ + StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, }).Return([]*models.Build{ { Id: "1", PrebuildId: "1", - State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -4), }, { Id: "2", PrebuildId: "1", - State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -3), }, { Id: "3", PrebuildId: "1", - State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -2), }, { Id: "4", PrebuildId: "1", - State: models.BuildStatePublished, CreatedAt: time.Now().Add(time.Hour * -1), }, }, nil) diff --git a/pkg/server/workspacetemplates/service.go b/pkg/server/workspacetemplates/service.go index 2cdbe5f9de..2487237a96 100644 --- a/pkg/server/workspacetemplates/service.go +++ b/pkg/server/workspacetemplates/service.go @@ -18,8 +18,8 @@ type WorkspaceTemplateServiceConfig struct { PrebuildWebhookEndpoint string ConfigStore stores.WorkspaceTemplateStore - FindNewestBuild func(ctx context.Context, prebuildId string) (*models.Build, error) - ListPublishedBuilds func(ctx context.Context) ([]*models.Build, error) + FindNewestBuild func(ctx context.Context, prebuildId string) (*services.BuildDTO, error) + ListSuccessfulBuilds func(ctx context.Context) ([]*services.BuildDTO, error) CreateBuild func(ctx context.Context, wt *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error DeleteBuilds func(ctx context.Context, id, prebuildId *string, force bool) []error GetRepositoryContext func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) @@ -33,8 +33,8 @@ type WorkspaceTemplateService struct { prebuildWebhookEndpoint string templateStore stores.WorkspaceTemplateStore - findNewestBuild func(ctx context.Context, prebuildId string) (*models.Build, error) - listPublishedBuilds func(ctx context.Context) ([]*models.Build, error) + findNewestBuild func(ctx context.Context, prebuildId string) (*services.BuildDTO, error) + listSuccessfulBuilds func(ctx context.Context) ([]*services.BuildDTO, error) createBuild func(ctx context.Context, wt *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error deleteBuilds func(ctx context.Context, id, prebuildId *string, force bool) []error getRepositoryContext func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) @@ -49,7 +49,7 @@ func NewWorkspaceTemplateService(config WorkspaceTemplateServiceConfig) services prebuildWebhookEndpoint: config.PrebuildWebhookEndpoint, templateStore: config.ConfigStore, findNewestBuild: config.FindNewestBuild, - listPublishedBuilds: config.ListPublishedBuilds, + listSuccessfulBuilds: config.ListSuccessfulBuilds, createBuild: config.CreateBuild, deleteBuilds: config.DeleteBuilds, getRepositoryContext: config.GetRepositoryContext, diff --git a/pkg/server/workspacetemplates/service_test.go b/pkg/server/workspacetemplates/service_test.go index 5e59291e85..35835e69a5 100644 --- a/pkg/server/workspacetemplates/service_test.go +++ b/pkg/server/workspacetemplates/service_test.go @@ -118,15 +118,17 @@ func (s *WorkspaceTemplateServiceTestSuite) SetupTest() { s.workspaceTemplateStore = workspacetemplate_internal.NewInMemoryWorkspaceTemplateStore() s.workspaceTemplateService = workspacetemplates.NewWorkspaceTemplateService(workspacetemplates.WorkspaceTemplateServiceConfig{ ConfigStore: s.workspaceTemplateStore, - FindNewestBuild: func(ctx context.Context, prebuildId string) (*models.Build, error) { - return s.buildService.Find(&stores.BuildFilter{ - PrebuildIds: &[]string{prebuildId}, - GetNewest: util.Pointer(true), + FindNewestBuild: func(ctx context.Context, prebuildId string) (*services.BuildDTO, error) { + return s.buildService.Find(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + PrebuildIds: &[]string{prebuildId}, + GetNewest: util.Pointer(true), + }, }) }, - ListPublishedBuilds: func(ctx context.Context) ([]*models.Build, error) { - return s.buildService.List(&stores.BuildFilter{ - States: &[]models.BuildState{models.BuildStatePublished}, + ListSuccessfulBuilds: func(ctx context.Context) ([]*services.BuildDTO, error) { + return s.buildService.List(&services.BuildFilter{ + StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, }) }, CreateBuild: func(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate, repo *gitprovider.GitRepository, prebuildId string) error { @@ -146,9 +148,11 @@ func (s *WorkspaceTemplateServiceTestSuite) SetupTest() { prebuildIds = &[]string{*prebuildId} } - return s.buildService.MarkForDeletion(&stores.BuildFilter{ - Id: id, - PrebuildIds: prebuildIds, + return s.buildService.Delete(&services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: id, + PrebuildIds: prebuildIds, + }, }, force) }, GetRepositoryContext: func(ctx context.Context, url string) (repo *gitprovider.GitRepository, gitProviderId string, err error) { diff --git a/pkg/services/build.go b/pkg/services/build.go index 08c3a792d7..c5cb3084e2 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -4,6 +4,7 @@ package services import ( + "errors" "io" "time" @@ -13,17 +14,36 @@ import ( type IBuildService interface { Create(CreateBuildDTO) (string, error) - Find(filter *stores.BuildFilter) (*models.Build, error) - List(filter *stores.BuildFilter) ([]*models.Build, error) - MarkForDeletion(filter *stores.BuildFilter, force bool) []error - Delete(id string) error + Find(filter *BuildFilter) (*BuildDTO, error) + List(filter *BuildFilter) ([]*BuildDTO, error) + Delete(filter *BuildFilter, force bool) []error + HandleSuccessfulRemoval(id string) error AwaitEmptyList(time.Duration) error GetBuildLogReader(buildId string) (io.Reader, error) } +type BuildDTO struct { + models.Build + State models.ResourceState `json:"state" validate:"required"` +} // @name BuildDTO + type CreateBuildDTO struct { WorkspaceTemplateName string `json:"workspaceTemplateName" validate:"required"` Branch string `json:"branch" validate:"required"` PrebuildId *string `json:"prebuildId" validate:"optional"` EnvVars map[string]string `json:"envVars" validate:"required"` } // @name CreateBuildDTO + +type BuildFilter struct { + StateNames *[]models.ResourceStateName + ShowDeleted bool + StoreFilter stores.BuildFilter +} + +var ( + ErrBuildDeleted = errors.New("build is deleted") +) + +func IsBuildDeleted(err error) bool { + return err.Error() == ErrBuildDeleted.Error() +} diff --git a/pkg/services/job.go b/pkg/services/job.go index 5a473dc2d0..2cbdaebb5c 100644 --- a/pkg/services/job.go +++ b/pkg/services/job.go @@ -4,6 +4,8 @@ package services import ( + "errors" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) @@ -15,3 +17,11 @@ type IJobService interface { List(filter *stores.JobFilter) ([]*models.Job, error) Delete(job *models.Job) error } + +var ( + ErrInvalidResourceJobAction = errors.New("invalid job action for resource") +) + +func IsInvalidResourceJobAction(err error) bool { + return err.Error() == ErrInvalidResourceJobAction.Error() +} diff --git a/pkg/stores/build.go b/pkg/stores/build.go index 6377cb95db..b6da33c9b1 100644 --- a/pkg/stores/build.go +++ b/pkg/stores/build.go @@ -26,7 +26,6 @@ func IsBuildNotFound(err error) bool { type BuildFilter struct { Id *string - States *[]models.BuildState PrebuildIds *[]string GetNewest *bool BuildConfig *models.BuildConfig @@ -35,14 +34,6 @@ type BuildFilter struct { EnvVars *map[string]string } -func (f *BuildFilter) StatesToInterface() []interface{} { - args := make([]interface{}, len(*f.States)) - for i, v := range *f.States { - args[i] = v - } - return args -} - func (f *BuildFilter) PrebuildIdsToInterface() []interface{} { args := make([]interface{}, len(*f.PrebuildIds)) for i, v := range *f.PrebuildIds { diff --git a/pkg/views/build/info/view.go b/pkg/views/build/info/view.go index 7bfd515755..6f080cda3c 100644 --- a/pkg/views/build/info/view.go +++ b/pkg/views/build/info/view.go @@ -25,7 +25,7 @@ var propertyValueStyle = lipgloss.NewStyle(). Foreground(views.Light). Bold(true) -func Render(b *apiclient.Build, apiServerConfig *apiclient.ServerConfig, forceUnstyled bool) { +func Render(b *apiclient.BuildDTO, apiServerConfig *apiclient.ServerConfig, forceUnstyled bool) { var output string output += "\n\n" @@ -33,7 +33,7 @@ func Render(b *apiclient.Build, apiServerConfig *apiclient.ServerConfig, forceUn output += getInfoLine("ID", b.Id) + "\n" - output += getInfoLine("State", string(b.State)) + "\n" + output += getInfoLine("State", views.GetStateLabel(b.State.Name)) + "\n" output += getInfoLine("Repository", b.Repository.Url) + "\n" diff --git a/pkg/views/build/list/view.go b/pkg/views/build/list/view.go index 807774ecce..75e1c7fc1d 100644 --- a/pkg/views/build/list/view.go +++ b/pkg/views/build/list/view.go @@ -16,13 +16,13 @@ import ( type rowData struct { Id string - State string + Status string PrebuildId string CreatedAt string UpdatedAt string } -func ListBuilds(buildList []apiclient.Build, apiServerConfig *apiclient.ServerConfig) { +func ListBuilds(buildList []apiclient.BuildDTO, apiServerConfig *apiclient.ServerConfig) { if len(buildList) == 0 { views_util.NotifyEmptyBuildList(true) return @@ -45,15 +45,19 @@ func ListBuilds(buildList []apiclient.Build, apiServerConfig *apiclient.ServerCo fmt.Println(table) } -func SortBuilds(buildList *[]apiclient.Build) { +func SortBuilds(buildList *[]apiclient.BuildDTO) { sort.Slice(*buildList, func(i, j int) bool { - b1 := (*buildList)[i] - b2 := (*buildList)[j] - return b1.UpdatedAt > b2.UpdatedAt + pi, pj := views_util.GetStateSortPriorities((*buildList)[i].State.Name, (*buildList)[j].State.Name) + if pi != pj { + return pi < pj + } + + // If two builds have the same state priority, compare the UpdatedAt property + return (*buildList)[i].State.UpdatedAt > (*buildList)[j].State.UpdatedAt }) } -func renderUnstyledList(buildList []apiclient.Build, apiServerConfig *apiclient.ServerConfig) { +func renderUnstyledList(buildList []apiclient.BuildDTO, apiServerConfig *apiclient.ServerConfig) { for _, b := range buildList { info.Render(&b, apiServerConfig, true) @@ -63,11 +67,11 @@ func renderUnstyledList(buildList []apiclient.Build, apiServerConfig *apiclient. } } -func getRowFromRowData(build apiclient.Build) []string { +func getRowFromRowData(build apiclient.BuildDTO) []string { var data rowData data.Id = build.Id + views_util.AdditionalPropertyPadding - data.State = string(build.State) + data.Status = views.GetStateLabel(build.State.Name) data.PrebuildId = build.PrebuildId if data.PrebuildId == "" { data.PrebuildId = "/" @@ -77,7 +81,7 @@ func getRowFromRowData(build apiclient.Build) []string { return []string{ views.NameStyle.Render(data.Id), - views.DefaultRowDataStyle.Render(data.State), + views.DefaultRowDataStyle.Render(data.Status), views.DefaultRowDataStyle.Render(data.PrebuildId), views.DefaultRowDataStyle.Render(data.CreatedAt), views.DefaultRowDataStyle.Render(data.UpdatedAt), diff --git a/pkg/views/common.go b/pkg/views/common.go index 5a37fc12da..da0b7788be 100644 --- a/pkg/views/common.go +++ b/pkg/views/common.go @@ -49,17 +49,20 @@ var ( // Resources that have actions being performed on them have a higher priority when listing var ResourceListStatePriorities = map[apiclient.ModelsResourceStateName]int{ + apiclient.ResourceStateNamePendingRun: 1, apiclient.ResourceStateNamePendingCreate: 1, apiclient.ResourceStateNamePendingStart: 1, apiclient.ResourceStateNamePendingStop: 1, apiclient.ResourceStateNamePendingRestart: 1, apiclient.ResourceStateNamePendingDelete: 1, apiclient.ResourceStateNamePendingForcedDelete: 1, + apiclient.ResourceStateNameRunning: 1, apiclient.ResourceStateNameCreating: 1, apiclient.ResourceStateNameStarting: 1, apiclient.ResourceStateNameStopping: 1, apiclient.ResourceStateNameDeleting: 1, apiclient.ResourceStateNameStarted: 2, + apiclient.ResourceStateNameRunSuccessful: 2, apiclient.ResourceStateNameUndefined: 2, apiclient.ResourceStateNameError: 3, apiclient.ResourceStateNameUnresponsive: 4, @@ -210,6 +213,12 @@ func GetStateLabel(state apiclient.ModelsResourceStateName) string { switch state { case apiclient.ResourceStateNameUndefined: return UndefinedStyle.Render("/") + case apiclient.ResourceStateNamePendingRun: + return PendingStyle.Render("PENDING") + case apiclient.ResourceStateNameRunning: + return RunningStyle.Render("RUNNING") + case apiclient.ResourceStateNameRunSuccessful: + return RunSuccessfulStyle.Render("SUCCESS") case apiclient.ResourceStateNamePendingCreate: return PendingStyle.Render("PENDING") case apiclient.ResourceStateNameCreating: diff --git a/pkg/views/selection/build.go b/pkg/views/selection/build.go index 7cb7b382a8..af09f4bb57 100644 --- a/pkg/views/selection/build.go +++ b/pkg/views/selection/build.go @@ -17,19 +17,19 @@ import ( list_view "github.com/daytonaio/daytona/pkg/views/build/list" ) -func GetBuildFromPrompt(builds []apiclient.Build, actionVerb string) *apiclient.Build { - choiceChan := make(chan *apiclient.Build) +func GetBuildFromPrompt(builds []apiclient.BuildDTO, actionVerb string) *apiclient.BuildDTO { + choiceChan := make(chan *apiclient.BuildDTO) go selectBuildPrompt(builds, actionVerb, choiceChan) return <-choiceChan } -func selectBuildPrompt(builds []apiclient.Build, actionVerb string, choiceChan chan<- *apiclient.Build) { +func selectBuildPrompt(builds []apiclient.BuildDTO, actionVerb string, choiceChan chan<- *apiclient.BuildDTO) { list_view.SortBuilds(&builds) items := []list.Item{} for _, b := range builds { - newItem := item[apiclient.Build]{title: fmt.Sprintf("ID: %s (%s)", b.Id, b.State), desc: fmt.Sprintf("created %s", util.FormatTimestamp(b.CreatedAt)), choiceProperty: b} + newItem := item[apiclient.BuildDTO]{title: fmt.Sprintf("ID: %s - %s", b.Id, b.Repository.Url), desc: fmt.Sprintf("State: %s (created %s)", b.State.Name, util.FormatTimestamp(b.CreatedAt)), choiceProperty: b} items = append(items, newItem) } @@ -56,7 +56,7 @@ func selectBuildPrompt(builds []apiclient.Build, actionVerb string, choiceChan c l.Title = views.GetStyledMainTitle(title) l.Styles.Title = titleStyle - m := model[apiclient.Build]{list: l} + m := model[apiclient.BuildDTO]{list: l} p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() if err != nil { @@ -64,7 +64,7 @@ func selectBuildPrompt(builds []apiclient.Build, actionVerb string, choiceChan c os.Exit(1) } - if m, ok := p.(model[apiclient.Build]); ok && m.choice != nil { + if m, ok := p.(model[apiclient.BuildDTO]); ok && m.choice != nil { choiceChan <- m.choice } else { choiceChan <- nil diff --git a/pkg/views/styles.go b/pkg/views/styles.go index 00a5f9c71d..a38ffafacb 100644 --- a/pkg/views/styles.go +++ b/pkg/views/styles.go @@ -33,8 +33,8 @@ var ( var ( ColorPending = lipgloss.AdaptiveColor{Light: "#cce046", Dark: "#cce046"} - ColorStarted = lipgloss.AdaptiveColor{Light: "#2ecc71", Dark: "#2ecc71"} - ColorStarting = ColorStarted + ColorSuccess = lipgloss.AdaptiveColor{Light: "#2ecc71", Dark: "#2ecc71"} + ColorStarting = ColorSuccess ColorStopped = lipgloss.AdaptiveColor{Light: "#a2a2a2", Dark: "#a2a2a2"} ColorStopping = ColorStopped ColorError = lipgloss.AdaptiveColor{Light: "#e74c3c", Dark: "#e74c3c"} @@ -60,17 +60,19 @@ var ( ) var ( - UndefinedStyle = lipgloss.NewStyle().Foreground(ColorPending) - PendingStyle = lipgloss.NewStyle().Foreground(ColorPending) - CreatingStyle = lipgloss.NewStyle().Foreground(ColorPending) - StartedStyle = lipgloss.NewStyle().Foreground(ColorStarted) - StartingStyle = lipgloss.NewStyle().Foreground(ColorStarting) - StoppedStyle = lipgloss.NewStyle().Foreground(ColorStopped) - StoppingStyle = lipgloss.NewStyle().Foreground(ColorStopping) - ErrorStyle = lipgloss.NewStyle().Foreground(ColorError) - DeletingStyle = lipgloss.NewStyle().Foreground(ColorDeleting) - DeletedStyle = lipgloss.NewStyle().Foreground(ColorDeleted) - UnresponsiveStyle = lipgloss.NewStyle().Foreground(ColorUnresponsive) + UndefinedStyle = lipgloss.NewStyle().Foreground(ColorPending) + PendingStyle = lipgloss.NewStyle().Foreground(ColorPending) + RunningStyle = lipgloss.NewStyle().Foreground(ColorPending) + RunSuccessfulStyle = lipgloss.NewStyle().Foreground(ColorSuccess) + CreatingStyle = lipgloss.NewStyle().Foreground(ColorPending) + StartedStyle = lipgloss.NewStyle().Foreground(ColorSuccess) + StartingStyle = lipgloss.NewStyle().Foreground(ColorStarting) + StoppedStyle = lipgloss.NewStyle().Foreground(ColorStopped) + StoppingStyle = lipgloss.NewStyle().Foreground(ColorStopping) + ErrorStyle = lipgloss.NewStyle().Foreground(ColorError) + DeletingStyle = lipgloss.NewStyle().Foreground(ColorDeleting) + DeletedStyle = lipgloss.NewStyle().Foreground(ColorDeleted) + UnresponsiveStyle = lipgloss.NewStyle().Foreground(ColorUnresponsive) ) var LogPrefixColors = []lipgloss.AdaptiveColor{ diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index eca5b5f33f..71bda0a328 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -48,10 +48,7 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("Error", *target.State.Error) + "\n" } - output += getInfoLineState("State", target.State, target.Metadata) + "\n" - if target.State.Error != nil { - output += getInfoLine("Error", *target.State.Error) + "\n" - } + output += getInfoLine("# Workspaces", fmt.Sprint(len(target.Workspaces))) + "\n" output += getInfoLine("Options", target.TargetConfig.Options) + "\n" diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index 5f3ee36a32..d91efc3390 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -76,15 +76,7 @@ func SortTargets(targetList *[]apiclient.TargetDTO) { return false } - pi, ok := views.ResourceListStatePriorities[(*targetList)[i].State.Name] - if !ok { - pi = 99 - } - pj, ok2 := views.ResourceListStatePriorities[(*targetList)[j].State.Name] - if !ok2 { - pj = 99 - } - + pi, pj := views_util.GetStateSortPriorities((*targetList)[i].State.Name, (*targetList)[j].State.Name) if pi != pj { return pi < pj } diff --git a/pkg/views/util/state_sort.go b/pkg/views/util/state_sort.go new file mode 100644 index 0000000000..9bfbd43203 --- /dev/null +++ b/pkg/views/util/state_sort.go @@ -0,0 +1,22 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" +) + +func GetStateSortPriorities(state1, state2 apiclient.ModelsResourceStateName) (int, int) { + pi, ok := views.ResourceListStatePriorities[state1] + if !ok { + pi = 99 + } + pj, ok2 := views.ResourceListStatePriorities[state2] + if !ok2 { + pj = 99 + } + + return pi, pj +} diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index f567ed4709..93a3bcf7d1 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -64,15 +64,7 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { sort.Slice(*workspaceList, func(i, j int) bool { - pi, ok := views.ResourceListStatePriorities[(*workspaceList)[i].State.Name] - if !ok { - pi = 99 - } - pj, ok2 := views.ResourceListStatePriorities[(*workspaceList)[j].State.Name] - if !ok2 { - pj = 99 - } - + pi, pj := views_util.GetStateSortPriorities((*workspaceList)[i].State.Name, (*workspaceList)[j].State.Name) if pi != pj { return pi < pj } From 62bee0ea7cf185de6462efcfa7e61bff71bf54ff Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Wed, 4 Dec 2024 19:15:21 +0100 Subject: [PATCH 19/76] fix: api hide env vars for nested targets or workspaces (#1415) Signed-off-by: Ivan Dagelic --- pkg/api/controllers/target/target.go | 9 +++++++++ pkg/api/controllers/workspace/workspace.go | 2 ++ 2 files changed, 11 insertions(+) diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index 2cb77ee20c..56151189f2 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -61,6 +61,10 @@ func GetTarget(ctx *gin.Context) { t.TargetConfig.Options = maskedOptions } + for i := range t.Workspaces { + util.HideDaytonaEnvVars(&t.Workspaces[i].EnvVars) + } + util.HideDaytonaEnvVars(&t.EnvVars) ctx.JSON(200, t) @@ -106,6 +110,11 @@ func ListTargets(ctx *gin.Context) { } targetList[i].TargetConfig.Options = maskedOptions + + for j := range targetList[i].Workspaces { + util.HideDaytonaEnvVars(&targetList[i].Workspaces[j].EnvVars) + } + util.HideDaytonaEnvVars(&targetList[i].EnvVars) } diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go index 6d17677aea..84bf144863 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/workspace/workspace.go @@ -55,6 +55,7 @@ func GetWorkspace(ctx *gin.Context) { } util.HideDaytonaEnvVars(&w.EnvVars) + util.HideDaytonaEnvVars(&w.Target.EnvVars) ctx.JSON(200, w) } @@ -93,6 +94,7 @@ func ListWorkspaces(ctx *gin.Context) { for i, _ := range workspaceList { util.HideDaytonaEnvVars(&workspaceList[i].EnvVars) + util.HideDaytonaEnvVars(&workspaceList[i].Target.EnvVars) } ctx.JSON(200, workspaceList) From cb5d3a7a7f62f20f84786c16e2a0ed0a844083e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 5 Dec 2024 00:15:49 +0100 Subject: [PATCH 20/76] feat: disable items for selection when in invalid state (#1412) Signed-off-by: Luka Brecic --- pkg/cmd/workspace/delete.go | 2 +- pkg/cmd/workspace/restart.go | 2 +- pkg/cmd/workspace/start.go | 2 +- pkg/cmd/workspace/stop.go | 2 +- pkg/views/workspace/selection/view.go | 91 +++++++++++++++++++--- pkg/views/workspace/selection/workspace.go | 47 ++++++++--- 6 files changed, 121 insertions(+), 25 deletions(-) diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index 3a1f589641..0649176a27 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -82,7 +82,7 @@ var DeleteCmd = &cobra.Command{ return nil } - workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, "Delete") + workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, selection.DeleteActionVerb) } else { for _, arg := range args { workspace, _, err := apiclient_util.GetWorkspace(arg, false) diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/workspace/restart.go index 434a49ff78..1b5d9f5461 100644 --- a/pkg/cmd/workspace/restart.go +++ b/pkg/cmd/workspace/restart.go @@ -44,7 +44,7 @@ var RestartCmd = &cobra.Command{ } if len(args) == 0 { - selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Restart") + selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, selection.RestartActionVerb) if selectedWorkspaces == nil { return nil } diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index adc99e9488..8f87d4c6d2 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -60,7 +60,7 @@ var StartCmd = &cobra.Command{ return nil } - selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Start") + selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, selection.StartActionVerb) } else { for _, arg := range args { workspace, _, err := apiclient_util.GetWorkspace(arg, false) diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go index 2f833f1436..97a41a456d 100644 --- a/pkg/cmd/workspace/stop.go +++ b/pkg/cmd/workspace/stop.go @@ -50,7 +50,7 @@ var StopCmd = &cobra.Command{ return nil } - selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, "Stop") + selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, selection.StopActionVerb) } else { for _, arg := range args { workspace, _, err := apiclient_util.GetWorkspace(arg, false) diff --git a/pkg/views/workspace/selection/view.go b/pkg/views/workspace/selection/view.go index b536cbdfd3..21bc7d517c 100644 --- a/pkg/views/workspace/selection/view.go +++ b/pkg/views/workspace/selection/view.go @@ -40,6 +40,7 @@ type item[T any] struct { choiceProperty T isMarked bool isMultipleSelect bool + isDisabled bool action string } @@ -75,23 +76,70 @@ func (m model[T]) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch keypress := msg.String(); keypress { + case "down", "j": + for { + isSubsequentItemsDisabled := true + curIndex := m.list.Index() + lastIndex := len(m.list.Items()) - 1 + for i := curIndex + 1; i <= lastIndex; i++ { + if !m.list.Items()[i].(item[T]).isDisabled { + isSubsequentItemsDisabled = false + break + } + } + // no need of moving cursor down if all subsequent items after current index have + // disabled property true. + if isSubsequentItemsDisabled { + break + } + m.list.CursorDown() + item := m.list.SelectedItem().(item[T]) + if !item.isDisabled { + break + } + } + return m, nil + + case "up", "k": + for { + isPrecedingItemsDisabled := true + curIndex := m.list.Index() + for i := curIndex - 1; i >= 0; i-- { + if !m.list.Items()[i].(item[T]).isDisabled { + isPrecedingItemsDisabled = false + break + } + } + // no need of moving cursor up if all preceding items before current index have + // disabled property true. + if isPrecedingItemsDisabled { + break + } + m.list.CursorUp() + item := m.list.SelectedItem().(item[T]) + if !item.isDisabled { + break + } + } + return m, nil + case "ctrl+c": return m, tea.Quit case "enter": i, ok := m.list.SelectedItem().(item[T]) - if ok { + if ok && !i.isDisabled { m.choice = &i.choiceProperty } - targetList := m.list.Items() + workspaceList := m.list.Items() var choices []*T - for _, target := range targetList { - if target.(item[T]).isMarked { - targetItem, ok := target.(item[T]) - if !ok { + for _, workspace := range workspaceList { + if workspace.(item[T]).isMarked { + workspaceItem, ok := workspace.(item[T]) + if !ok || workspaceItem.isDisabled { continue } - choices = append(choices, &targetItem.choiceProperty) + choices = append(choices, &workspaceItem.choiceProperty) } } @@ -166,13 +214,29 @@ func (d ItemDelegate[T]) Render(w io.Writer, m list.Model, index int, listItem l stateLabel = timeStyles.Render(i.State()) } + if i.isDisabled { + title = baseStyles.Foreground(views.Gray).Render(i.Title()) + idWithTarget = baseStyles.Foreground(views.Gray).Render(idWithTargetString) + repository = baseStyles.Foreground(views.Gray).Render(i.Repository()) + description = baseStyles.Foreground(views.Gray).Render(i.Description()) + stateLabel = timeStyles.Foreground(views.Gray).Render(stateLabel) + } + // Adjust styles as the user moves through the menu if isSelected { - title = selectedStyles.Foreground(views.Green).Render(i.Title()) - idWithTarget = selectedStyles.Foreground(views.Gray).Render(idWithTargetString) - repository = selectedStyles.Foreground(views.DimmedGreen).Render(i.Repository()) - description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) - stateLabel = timeStyles.Foreground(views.DimmedGreen).Render(stateLabel) + if !i.isDisabled { + title = selectedStyles.Foreground(views.Green).Render(i.Title()) + idWithTarget = selectedStyles.Foreground(views.Gray).Render(idWithTargetString) + repository = selectedStyles.Foreground(views.DimmedGreen).Render(i.Repository()) + description = selectedStyles.Foreground(views.DimmedGreen).Render(i.Description()) + stateLabel = timeStyles.Foreground(views.DimmedGreen).Render(stateLabel) + } else { + title = selectedStyles.Render(i.Title()) + idWithTarget = selectedStyles.Foreground(views.Gray).Render(idWithTargetString) + repository = selectedStyles.Foreground(views.LightGray).Render(i.Repository()) + description = selectedStyles.Foreground(views.LightGray).Render(i.Description()) + stateLabel = timeStyles.Foreground(views.LightGray).Render(stateLabel) + } } // Render to the terminal @@ -215,6 +279,9 @@ func (d ItemDelegate[T]) Update(msg tea.Msg, m *list.Model) tea.Cmd { if !i.isMultipleSelect { return nil } + if i.isDisabled { + return m.NewStatusMessage(statusMessageGreenStyle("Workspace ") + i.title + statusMessageGreenStyle(" selection is disabled for this action")) + } if i.isMarked { i.title = strings.TrimPrefix(i.title, statusMessageDangerStyle(fmt.Sprintf("%s: ", i.action))) i.isMarked = false diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go index bf09b87293..4236e1c885 100644 --- a/pkg/views/workspace/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -19,9 +19,18 @@ import ( var NewWorkspaceIdentifier = "" -func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect bool, action string) []list.Item { +type ActionVerb string + +var StartActionVerb ActionVerb = "Start" +var StopActionVerb ActionVerb = "Stop" +var RestartActionVerb ActionVerb = "Restart" +var DeleteActionVerb ActionVerb = "Delete" + +func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect bool, action ActionVerb) []list.Item { // Initialize an empty list of items. items := []list.Item{} + enabledItems := []list.Item{} + disabledItems := []list.Item{} // Populate items with titles and descriptions from workspaces. for _, workspace := range workspaces { @@ -39,6 +48,18 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect stateLabel := views.GetStateLabel(workspace.State.Name) + isDisabled := false + switch action { + case StartActionVerb: + if workspace.State.Name == apiclient.ResourceStateNameStarted { + isDisabled = true + } + case StopActionVerb, RestartActionVerb: + if workspace.State.Name == apiclient.ResourceStateNameStopped { + isDisabled = true + } + } + if workspace.Metadata != nil { views_util.CheckAndAppendTimeLabel(&stateLabel, workspace.State, workspace.Metadata.Uptime) } @@ -53,20 +74,28 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect state: stateLabel, workspace: &workspace, choiceProperty: workspace, + isDisabled: isDisabled, } if isMultipleSelect { newItem.isMultipleSelect = true - newItem.action = action + newItem.action = string(action) } - items = append(items, newItem) + if isDisabled { + disabledItems = append(disabledItems, newItem) + } else { + enabledItems = append(enabledItems, newItem) + } } + items = append(items, enabledItems...) + items = append(items, disabledItems...) + return items } -func getWorkspaceProgramEssentials(modelTitle string, actionVerb string, workspaces []apiclient.WorkspaceDTO, footerText string, isMultipleSelect bool) tea.Model { +func getWorkspaceProgramEssentials(modelTitle string, actionVerb ActionVerb, workspaces []apiclient.WorkspaceDTO, footerText string, isMultipleSelect bool) tea.Model { items := generateWorkspaceList(workspaces, isMultipleSelect, actionVerb) @@ -82,7 +111,7 @@ func getWorkspaceProgramEssentials(modelTitle string, actionVerb string, workspa m := model[apiclient.WorkspaceDTO]{list: l} - m.list.Title = views.GetStyledMainTitle(modelTitle + actionVerb) + m.list.Title = views.GetStyledMainTitle(modelTitle + string(actionVerb)) m.list.Styles.Title = lipgloss.NewStyle().Foreground(views.Green).Bold(true) m.footer = footerText @@ -96,7 +125,7 @@ func getWorkspaceProgramEssentials(modelTitle string, actionVerb string, workspa return p } -func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- *apiclient.WorkspaceDTO) { +func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb ActionVerb, choiceChan chan<- *apiclient.WorkspaceDTO) { list_view.SortWorkspaces(&workspaces, true) p := getWorkspaceProgramEssentials("Select a Workspace To ", actionVerb, workspaces, "", false) @@ -107,7 +136,7 @@ func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb strin } } -func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) *apiclient.WorkspaceDTO { +func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb ActionVerb) *apiclient.WorkspaceDTO { choiceChan := make(chan *apiclient.WorkspaceDTO) go selectWorkspacePrompt(workspaces, actionVerb, choiceChan) @@ -115,7 +144,7 @@ func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb stri return <-choiceChan } -func selectWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string, choiceChan chan<- []*apiclient.WorkspaceDTO) { +func selectWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb ActionVerb, choiceChan chan<- []*apiclient.WorkspaceDTO) { list_view.SortWorkspaces(&workspaces, true) footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark a workspace.\nPress 'enter' to %s the current/marked workspaces.", actionVerb)) @@ -131,7 +160,7 @@ func selectWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb } } -func GetWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb string) []*apiclient.WorkspaceDTO { +func GetWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb ActionVerb) []*apiclient.WorkspaceDTO { choiceChan := make(chan []*apiclient.WorkspaceDTO) go selectWorkspacesFromPrompt(workspaces, actionVerb, choiceChan) From 48e97e1181d2d959e0aa620c770dd7984a9b87a7 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Thu, 5 Dec 2024 09:10:53 +0100 Subject: [PATCH 21/76] feat: target ssh command (#1404) Signed-off-by: Toma Puljak --- cmd/daytona/config/ssh_file.go | 68 ++++++------ internal/cmd/tailscale/forward.go | 2 +- internal/util/path.go | 8 +- pkg/cmd/agent/agent.go | 4 +- pkg/cmd/common/delete_workspace.go | 2 +- pkg/cmd/common/get_gpg_key.go | 10 +- pkg/cmd/common/open_ide.go | 2 +- pkg/cmd/target/delete.go | 31 ++++-- pkg/cmd/target/ssh.go | 112 ++++++++++++++++++++ pkg/cmd/target/target.go | 1 + pkg/cmd/workspace/code.go | 2 +- pkg/cmd/workspace/create/cmd.go | 6 +- pkg/cmd/workspace/ssh-proxy.go | 34 ++++-- pkg/cmd/workspace/ssh.go | 2 +- pkg/common/tailscale_hostname.go | 22 ++++ pkg/common/workspace_hostname.go | 25 ----- pkg/ide/browser.go | 4 +- pkg/ide/cursor.go | 6 +- pkg/ide/fleet.go | 4 +- pkg/ide/jetbrains.go | 4 +- pkg/ide/jupyter.go | 6 +- pkg/ide/terminal.go | 12 +-- pkg/ide/vscode.go | 4 +- pkg/ide/zed.go | 4 +- pkg/views/ide/{start_target.go => start.go} | 10 +- 25 files changed, 267 insertions(+), 118 deletions(-) create mode 100644 pkg/cmd/target/ssh.go create mode 100644 pkg/common/tailscale_hostname.go delete mode 100644 pkg/common/workspace_hostname.go rename pkg/views/ide/{start_target.go => start.go} (65%) diff --git a/cmd/daytona/config/ssh_file.go b/cmd/daytona/config/ssh_file.go index d10de0d2ac..00daa44ada 100644 --- a/cmd/daytona/config/ssh_file.go +++ b/cmd/daytona/config/ssh_file.go @@ -114,21 +114,21 @@ func UnlinkSshFiles() error { // Add ssh entry -func generateSshConfigEntry(profileId, workspaceName, knownHostsPath string, gpgForward bool) (string, error) { +func generateSshConfigEntry(profileId, resourceId, knownHostsPath string, gpgForward bool) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } tab := "\t" - workspaceHostname := GetWorkspaceHostname(profileId, workspaceName) + resourceHostname := GetHostname(profileId, resourceId) config := fmt.Sprintf("Host %s\n"+ tab+"User daytona\n"+ tab+"StrictHostKeyChecking no\n"+ tab+"UserKnownHostsFile %s\n"+ tab+"ProxyCommand \"%s\" ssh-proxy %s %s\n"+ - tab+"ForwardAgent yes\n", workspaceHostname, knownHostsPath, daytonaPath, profileId, workspaceName) + tab+"ForwardAgent yes\n", resourceHostname, knownHostsPath, daytonaPath, profileId, resourceId) if gpgForward { localSocket, err := getLocalGPGSocket() @@ -137,7 +137,7 @@ func generateSshConfigEntry(profileId, workspaceName, knownHostsPath string, gpg return config, nil } - remoteSocket, err := getRemoteGPGSocket(workspaceHostname) + remoteSocket, err := getRemoteGPGSocket(resourceHostname) if err != nil { log.Trace(err) return config, nil @@ -153,7 +153,7 @@ func generateSshConfigEntry(profileId, workspaceName, knownHostsPath string, gpg return config, nil } -func EnsureSshConfigEntryAdded(profileId, workspaceId string, gpgKey string) error { +func EnsureSshConfigEntryAdded(profileId, resourceId string, gpgKey *string) error { err := ensureSshFilesLinked() if err != nil { return err @@ -171,10 +171,10 @@ func EnsureSshConfigEntryAdded(profileId, workspaceId string, gpgKey string) err } var configGenerated bool - regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, workspaceId)) - regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, workspaceId)) + regexWithoutGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s\s*\n(?:\s+[^\n]*\n?)*`, profileId, resourceId)) + regexWithGPG := regexp.MustCompile(fmt.Sprintf(`(?m)^Host %s-%s\s*\n(?:\s+[^\n]*\n?)*StreamLocalBindUnlink\s+yes\s*\n(?:\s+[^\n]*\n?)*RemoteForward\s+[^\s]+\s+[^\s]+\s*\n`, profileId, resourceId)) if !regexWithoutGPG.MatchString(existingContent) { - newContent, err := appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile, false, existingContent) + newContent, err := appendSshConfigEntry(configPath, profileId, resourceId, knownHostsFile, false, existingContent) if err != nil { return err } @@ -182,14 +182,14 @@ func EnsureSshConfigEntryAdded(profileId, workspaceId string, gpgKey string) err configGenerated = true } - if gpgKey != "" && !regexWithGPG.MatchString(existingContent) { - _, err := appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile, true, existingContent) + if gpgKey != nil && *gpgKey != "" && !regexWithGPG.MatchString(existingContent) { + _, err := appendSshConfigEntry(configPath, profileId, resourceId, knownHostsFile, true, existingContent) if err != nil { return err } - workspaceHostname := GetWorkspaceHostname(profileId, workspaceId) - err = ExportGPGKey(gpgKey, workspaceHostname) + hostname := GetHostname(profileId, resourceId) + err = ExportGPGKey(*gpgKey, hostname) if err != nil { return err } @@ -198,11 +198,11 @@ func EnsureSshConfigEntryAdded(profileId, workspaceId string, gpgKey string) err } if !configGenerated { - updatedContent, err := regenerateProxyCommand(existingContent, profileId, workspaceId) + updatedContent, err := regenerateProxyCommand(existingContent, profileId, resourceId) if err != nil { return err } - err = UpdateWorkspaceSshEntry(profileId, workspaceId, updatedContent) + err = UpdateSshEntry(profileId, resourceId, updatedContent) if err != nil { return err } @@ -211,21 +211,21 @@ func EnsureSshConfigEntryAdded(profileId, workspaceId string, gpgKey string) err return nil } -func regenerateProxyCommand(existingContent, profileId, workspaceId string) (string, error) { +func regenerateProxyCommand(existingContent, profileId, resourceId string) (string, error) { daytonaPath, err := os.Executable() if err != nil { return "", err } - hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, workspaceId)) + hostLine := fmt.Sprintf("Host %s", GetHostname(profileId, resourceId)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(existingContent) if matchedEntry == "" { - return "", fmt.Errorf("no SSH entry found for workspace %s", workspaceId) + return "", fmt.Errorf("no SSH entry found for resource %s", resourceId) } re := regexp.MustCompile(`(?m)^\s*ProxyCommand\s+.*$`) - updatedContent := re.ReplaceAllString(matchedEntry, fmt.Sprintf("\tProxyCommand \"%s\" ssh-proxy %s %s", daytonaPath, profileId, workspaceId)) + updatedContent := re.ReplaceAllString(matchedEntry, fmt.Sprintf("\tProxyCommand \"%s\" ssh-proxy %s %s", daytonaPath, profileId, resourceId)) return updatedContent, nil } @@ -237,8 +237,8 @@ func getKnownHostsFile() string { return "/dev/null" } -func appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { - data, err := generateSshConfigEntry(profileId, workspaceId, knownHostsFile, gpgForward) +func appendSshConfigEntry(configPath, profileId, resourceId, knownHostsFile string, gpgForward bool, existingContent string) (string, error) { + data, err := generateSshConfigEntry(profileId, resourceId, knownHostsFile, gpgForward) if err != nil { return "", err } @@ -249,7 +249,7 @@ func appendSshConfigEntry(configPath, profileId, workspaceId, knownHostsFile str } // We want to remove the config entry gpg counterpart - configCounterpart, err := generateSshConfigEntry(profileId, workspaceId, knownHostsFile, !gpgForward) + configCounterpart, err := generateSshConfigEntry(profileId, resourceId, knownHostsFile, !gpgForward) if err != nil { return "", err } @@ -282,8 +282,8 @@ func getLocalGPGSocket() (string, error) { return strings.TrimSpace(string(output)), nil } -func getRemoteGPGSocket(workspaceHostname string) (string, error) { - cmd := exec.Command("ssh", workspaceHostname, "gpgconf --list-dir agent-socket") +func getRemoteGPGSocket(resourceHostname string) (string, error) { + cmd := exec.Command("ssh", resourceHostname, "gpgconf --list-dir agent-socket") output, err := cmd.Output() if err != nil { return "", fmt.Errorf("failed to get remote GPG socket: %v", err) @@ -291,7 +291,7 @@ func getRemoteGPGSocket(workspaceHostname string) (string, error) { return strings.TrimSpace(string(output)), nil } -func ExportGPGKey(keyID, workspaceHostname string) error { +func ExportGPGKey(keyID, resourceHostname string) error { exportCmd := exec.Command("gpg", "--export", keyID) var output bytes.Buffer exportCmd.Stdout = &output @@ -300,7 +300,7 @@ func ExportGPGKey(keyID, workspaceHostname string) error { return err } - importCmd := exec.Command("ssh", workspaceHostname, "gpg --import") + importCmd := exec.Command("ssh", resourceHostname, "gpg --import") importCmd.Stdin = &output return importCmd.Run() @@ -328,8 +328,8 @@ func writeSshConfig(configPath, newContent string) error { return nil } -// RemoveTargetSshEntries removes all SSH entries for a given profileId and workspaceId -func RemoveWorkspaceSshEntries(profileId, workspaceId string) error { +// RemoveSshEntries removes all SSH entries for a given profileId and resourceId +func RemoveSshEntries(profileId, resourceId string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -339,8 +339,8 @@ func RemoveWorkspaceSshEntries(profileId, workspaceId string) error { return err } - // Define the regex pattern to match Host entries for the given profileId and workspaceId - regex := regexp.MustCompile(fmt.Sprintf(`Host %s-%s\n(?:\t.*\n?)*`, profileId, workspaceId)) + // Define the regex pattern to match Host entries for the given profileId and resourceId + regex := regexp.MustCompile(fmt.Sprintf(`Host %s-%s\n(?:\t.*\n?)*`, profileId, resourceId)) contentToDelete := regex.FindString(existingContent) if contentToDelete == "" { @@ -354,7 +354,7 @@ func RemoveWorkspaceSshEntries(profileId, workspaceId string) error { return writeSshConfig(configPath, newContent) } -func UpdateWorkspaceSshEntry(profileId, workspaceId, updatedContent string) error { +func UpdateSshEntry(profileId, resourceId, updatedContent string) error { sshDir := filepath.Join(SshHomeDir, ".ssh") configPath := filepath.Join(sshDir, "daytona_config") @@ -363,11 +363,11 @@ func UpdateWorkspaceSshEntry(profileId, workspaceId, updatedContent string) erro return err } - hostLine := fmt.Sprintf("Host %s", GetWorkspaceHostname(profileId, workspaceId)) + hostLine := fmt.Sprintf("Host %s", GetHostname(profileId, resourceId)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) oldContent := regex.FindString(existingContent) if oldContent == "" { - return fmt.Errorf("no SSH entry found for workspace %s", workspaceId) + return fmt.Errorf("no SSH entry found for resource %s", resourceId) } existingContent = strings.ReplaceAll(existingContent, oldContent, updatedContent) @@ -379,8 +379,8 @@ func UpdateWorkspaceSshEntry(profileId, workspaceId, updatedContent string) erro return nil } -func GetWorkspaceHostname(profileId, workspaceName string) string { - return fmt.Sprintf("%s-%s", profileId, workspaceName) +func GetHostname(profileId, resourceId string) string { + return fmt.Sprintf("%s-%s", profileId, resourceId) } func init() { diff --git a/internal/cmd/tailscale/forward.go b/internal/cmd/tailscale/forward.go index 6ebf8cf700..1958215321 100644 --- a/internal/cmd/tailscale/forward.go +++ b/internal/cmd/tailscale/forward.go @@ -47,7 +47,7 @@ func ForwardPort(workspaceId string, targetPort uint16, profile config.Profile) return } - targetUrl := fmt.Sprintf("%s:%d", common.GetWorkspaceHostname(workspaceId), targetPort) + targetUrl := fmt.Sprintf("%s:%d", common.GetTailscaleHostname(workspaceId), targetPort) go handlePortConnection(conn, tsConn, targetUrl, errChan) } diff --git a/internal/util/path.go b/internal/util/path.go index b367946653..7213b40b6a 100644 --- a/internal/util/path.go +++ b/internal/util/path.go @@ -11,13 +11,13 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func GetHomeDir(activeProfile config.Profile, workspaceId string, gpgKey string) (string, error) { +func GetHomeDir(activeProfile config.Profile, workspaceId string, gpgKey *string) (string, error) { err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return "", err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) homeDir, err := exec.Command("ssh", workspaceHostname, "echo", "$HOME").Output() if err != nil { @@ -27,13 +27,13 @@ func GetHomeDir(activeProfile config.Profile, workspaceId string, gpgKey string) return strings.TrimRight(string(homeDir), "\n"), nil } -func GetWorkspaceDir(activeProfile config.Profile, workspaceId string, gpgKey string) (string, error) { +func GetWorkspaceDir(activeProfile config.Profile, workspaceId string, gpgKey *string) (string, error) { err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return "", err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) daytonaWorkspaceDir, err := exec.Command("ssh", workspaceHostname, "echo", "$DAYTONA_WORKSPACE_DIR").Output() if err != nil { diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index 1a60ac6c43..c3414ff4e0 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -99,9 +99,9 @@ var AgentCmd = &cobra.Command{ DefaultWorkspaceDir: os.Getenv("HOME"), } - tailscaleHostname := c.TargetId + tailscaleHostname := common.GetTailscaleHostname(c.TargetId) if agentMode == agent_config.ModeWorkspace { - tailscaleHostname = common.GetWorkspaceHostname(ws.Id) + tailscaleHostname = common.GetTailscaleHostname(ws.Id) } toolBoxServer := &toolbox.Server{ diff --git a/pkg/cmd/common/delete_workspace.go b/pkg/cmd/common/delete_workspace.go index 5d03a2dc36..0b30b65778 100644 --- a/pkg/cmd/common/delete_workspace.go +++ b/pkg/cmd/common/delete_workspace.go @@ -30,7 +30,7 @@ func DeleteWorkspace(ctx context.Context, apiClient *apiclient.APIClient, worksp return err } - err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspaceId) + err = config.RemoveSshEntries(activeProfile.Id, workspaceId) if err != nil { return err } diff --git a/pkg/cmd/common/get_gpg_key.go b/pkg/cmd/common/get_gpg_key.go index d4551c9274..1208348bad 100644 --- a/pkg/cmd/common/get_gpg_key.go +++ b/pkg/cmd/common/get_gpg_key.go @@ -10,23 +10,23 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" ) -func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (string, error) { +func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (*string, error) { if providerConfigId == nil || *providerConfigId == "" { - return "", nil + return nil, nil } - var gpgKey string + var gpgKey *string gitProvider, res, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *providerConfigId).Execute() if err != nil { - return "", apiclient_util.HandleErrorResponse(res, err) + return nil, apiclient_util.HandleErrorResponse(res, err) } // Extract GPG key if present if gitProvider != nil { if gitProvider.SigningMethod != nil && gitProvider.SigningKey != nil { if *gitProvider.SigningMethod == apiclient.SigningMethodGPG { - gpgKey = *gitProvider.SigningKey + gpgKey = gitProvider.SigningKey } } } diff --git a/pkg/cmd/common/open_ide.go b/pkg/cmd/common/open_ide.go index bebe9bbcf7..cb600b9ba3 100644 --- a/pkg/cmd/common/open_ide.go +++ b/pkg/cmd/common/open_ide.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/telemetry" ) -func OpenIDE(ideId string, activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { +func OpenIDE(ideId string, activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, yesFlag bool, gpgKey *string) error { telemetry.AdditionalData["ide"] = ideId switch ideId { diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index c5a34a90a5..99a5f798ea 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" @@ -35,9 +36,18 @@ var deleteCmd = &cobra.Command{ if err != nil { return err } + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } if allFlag { - return deleteAllTargetsView(ctx, apiClient) + return deleteAllTargetsView(ctx, activeProfile.Id, apiClient) } if len(args) == 0 { @@ -93,7 +103,7 @@ var deleteCmd = &cobra.Command{ fmt.Println("Operation canceled.") } else { for _, target := range targetDeleteList { - err := deleteTarget(ctx, apiClient, target) + err := deleteTarget(ctx, activeProfile.Id, apiClient, target) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", target.Name, err)) } else { @@ -114,12 +124,12 @@ func init() { deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete a target by force") } -func deleteAllTargetsView(ctx context.Context, apiClient *apiclient.APIClient) error { +func deleteAllTargetsView(ctx context.Context, activeProfileId string, apiClient *apiclient.APIClient) error { var deleteAllTargetsFlag bool if yesFlag { fmt.Println("Deleting all targets.") - err := deleteAllTargets(ctx, apiClient) + err := deleteAllTargets(ctx, activeProfileId, apiClient) if err != nil { return err } @@ -139,7 +149,7 @@ func deleteAllTargetsView(ctx context.Context, apiClient *apiclient.APIClient) e } if deleteAllTargetsFlag { - err := deleteAllTargets(ctx, apiClient) + err := deleteAllTargets(ctx, activeProfileId, apiClient) if err != nil { return err } @@ -151,14 +161,14 @@ func deleteAllTargetsView(ctx context.Context, apiClient *apiclient.APIClient) e return nil } -func deleteAllTargets(ctx context.Context, apiClient *apiclient.APIClient) error { +func deleteAllTargets(ctx context.Context, activeProfileId string, apiClient *apiclient.APIClient) error { targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } for _, target := range targetList { - err := deleteTarget(ctx, apiClient, &target) + err := deleteTarget(ctx, activeProfileId, apiClient, &target) if err != nil { log.Errorf("Failed to delete target %s: %v", target.Name, err) continue @@ -168,7 +178,7 @@ func deleteAllTargets(ctx context.Context, apiClient *apiclient.APIClient) error return nil } -func deleteTarget(ctx context.Context, apiClient *apiclient.APIClient, target *apiclient.TargetDTO) error { +func deleteTarget(ctx context.Context, activeProfileId string, apiClient *apiclient.APIClient, target *apiclient.TargetDTO) error { if len(target.Workspaces) > 0 { err := deleteWorkspacesForTarget(ctx, apiClient, target) if err != nil { @@ -183,6 +193,11 @@ func deleteTarget(ctx context.Context, apiClient *apiclient.APIClient, target *a return apiclient_util.HandleErrorResponse(res, err) } + err = config.RemoveSshEntries(activeProfileId, target.Id) + if err != nil { + return err + } + err = common.AwaitTargetDeleted(target.Id) if err != nil { return err diff --git a/pkg/cmd/target/ssh.go b/pkg/cmd/target/ssh.go new file mode 100644 index 0000000000..88ee54f1ad --- /dev/null +++ b/pkg/cmd/target/ssh.go @@ -0,0 +1,112 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "context" + + "github.com/daytonaio/daytona/cmd/daytona/config" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" + "github.com/daytonaio/daytona/pkg/ide" + ide_views "github.com/daytonaio/daytona/pkg/views/ide" + "github.com/daytonaio/daytona/pkg/views/target/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + "github.com/spf13/cobra" +) + +var sshOptions []string + +var sshCmd = &cobra.Command{ + Use: "ssh [TARGET] [CMD...]", + Short: "SSH into a target using the terminal", + Args: cobra.ArbitraryArgs, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + ctx := context.Background() + var tg *apiclient.TargetDTO + + apiClient, err := apiclient_util.GetApiClient(&activeProfile) + if err != nil { + return err + } + + if len(args) == 0 { + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(targetList) == 0 { + views_util.NotifyEmptyWorkspaceList(true) + return nil + } + + tg = selection.GetTargetFromPrompt(targetList, false, "SSH Into") + if tg == nil { + return nil + } + } else { + tg, _, err = apiclient_util.GetTarget(args[0], true) + if err != nil { + return err + } + } + + if tg.State.Name == apiclient.ResourceStateNameStopped { + tgRunningStatus, err := autoStartTarget(*tg) + if err != nil { + return err + } + if !tgRunningStatus { + return nil + } + } + + sshArgs := []string{} + if len(args) > 1 { + sshArgs = append(sshArgs, args[1:]...) + } + + return ide.OpenTerminalSsh(activeProfile, tg.Id, nil, sshOptions, sshArgs...) + }, + ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return common.GetWorkspaceNameCompletions() + }, +} + +func init() { + sshCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") + sshCmd.Flags().StringArrayVarP(&sshOptions, "option", "o", []string{}, "Specify SSH options in KEY=VALUE format.") +} + +func autoStartTarget(target apiclient.TargetDTO) (bool, error) { + if !yesFlag { + if !ide_views.RunStartTargetForm(target.Name) { + return false, nil + } + } + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return false, err + } + + err = StartTarget(apiClient, target.Id) + if err != nil { + return false, err + } + + return true, nil +} diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go index de6cf5c8b3..186e6f6928 100644 --- a/pkg/cmd/target/target.go +++ b/pkg/cmd/target/target.go @@ -25,4 +25,5 @@ func init() { TargetCmd.AddCommand(logsCmd) TargetCmd.AddCommand(listCmd) TargetCmd.AddCommand(setDefaultCmd) + TargetCmd.AddCommand(sshCmd) } diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go index 406f499299..ff8a46ad4a 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/workspace/code.go @@ -124,7 +124,7 @@ func init() { func AutoStartWorkspace(workspace apiclient.WorkspaceDTO) (bool, error) { if !yesFlag { - if !ide_views.RunStartWorkspaceForm(workspace.Id) { + if !ide_views.RunStartWorkspaceForm(workspace.Name) { return false, nil } } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index e12007035a..96c9ef40bf 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -328,14 +328,14 @@ func init() { cmd_common.AddWorkspaceConfigurationFlags(CreateCmd, workspaceConfigurationFlags, true) } -func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey string) error { +func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey *string) error { if IsLocalDockerTarget(target) && (activeProfile != nil && activeProfile.Id == "default") { err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) for { sshCommand := exec.Command("ssh", workspaceHostname, "daytona", "version") @@ -358,7 +358,7 @@ func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile go func() { for { - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", common.GetWorkspaceHostname(workspaceId), ssh_config.SSH_PORT)) + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", common.GetTailscaleHostname(workspaceId), ssh_config.SSH_PORT)) if err == nil { connectChan <- dialConn.Close() return diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index a81a8a693c..a3776236ad 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "io" + "net/http" "os" "time" @@ -15,6 +16,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/docker" @@ -27,7 +29,7 @@ import ( ) var SshProxyCmd = &cobra.Command{ - Use: "ssh-proxy [PROFILE_ID] [WORKSPACE]", + Use: "ssh-proxy [PROFILE_ID] [TARGET_ID | WORKSPACE_ID]", Args: cobra.ExactArgs(2), Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { @@ -37,24 +39,33 @@ var SshProxyCmd = &cobra.Command{ } profileId := args[0] - workspaceId := args[1] + resourceId := args[1] profile, err := c.GetProfile(profileId) if err != nil { return err } - ws, _, err := apiclient_util.GetWorkspace(workspaceId, true) - if err != nil { + var target *apiclient.TargetDTO + + ws, statusCode, err := apiclient_util.GetWorkspace(resourceId, true) + if err != nil && statusCode != http.StatusNotFound { return err } - target, _, err := apiclient_util.GetTarget(ws.TargetId, true) - if err != nil { - return err + if ws == nil { + target, _, err = apiclient_util.GetTarget(resourceId, true) + if err != nil { + return err + } + } else { + target, _, err = apiclient_util.GetTarget(ws.TargetId, true) + if err != nil { + return err + } } - if create.IsLocalDockerTarget(target) && profile.Id == "default" { + if ws != nil && create.IsLocalDockerTarget(target) && profile.Id == "default" { // If the target is local, we directly access the ssh port through the container cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) @@ -125,7 +136,12 @@ var SshProxyCmd = &cobra.Command{ errChan := make(chan error) - dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", common.GetWorkspaceHostname(ws.Id), ssh_config.SSH_PORT)) + hostname := common.GetTailscaleHostname(target.Id) + if ws != nil { + hostname = common.GetTailscaleHostname(ws.Id) + } + + dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", hostname, ssh_config.SSH_PORT)) if err != nil { return err } diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index dcfdd66f62..659e42b53a 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -205,7 +205,7 @@ func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceD modifiedContent += "\n" } - err = config.UpdateWorkspaceSshEntry(activeProfile.Id, workspace.Id, modifiedContent) + err = config.UpdateSshEntry(activeProfile.Id, workspace.Id, modifiedContent) if err != nil { return err } diff --git a/pkg/common/tailscale_hostname.go b/pkg/common/tailscale_hostname.go new file mode 100644 index 0000000000..fd5e55e25f --- /dev/null +++ b/pkg/common/tailscale_hostname.go @@ -0,0 +1,22 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "strings" +) + +func GetTailscaleHostname(resourceId string) string { + // Replace special chars with hyphen to form valid hostname + // String resulting in consecutive hyphens is also valid + resourceId = strings.ReplaceAll(resourceId, "_", "-") + resourceId = strings.ReplaceAll(resourceId, "*", "-") + resourceId = strings.ReplaceAll(resourceId, ".", "-") + + if len(resourceId) > 63 { + return resourceId[:63] + } + + return resourceId +} diff --git a/pkg/common/workspace_hostname.go b/pkg/common/workspace_hostname.go deleted file mode 100644 index a49c25e3e5..0000000000 --- a/pkg/common/workspace_hostname.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package common - -import ( - "fmt" - "strings" -) - -func GetWorkspaceHostname(workspaceId string) string { - // Replace special chars with hyphen to form valid hostname - // String resulting in consecutive hyphens is also valid - workspaceId = strings.ReplaceAll(workspaceId, "_", "-") - workspaceId = strings.ReplaceAll(workspaceId, "*", "-") - workspaceId = strings.ReplaceAll(workspaceId, ".", "-") - - hostname := fmt.Sprintf("ws-%s", workspaceId) - - if len(hostname) > 63 { - return hostname[:63] - } - - return hostname -} diff --git a/pkg/ide/browser.go b/pkg/ide/browser.go index 5ebb20a8cd..89af2fd864 100644 --- a/pkg/ide/browser.go +++ b/pkg/ide/browser.go @@ -23,7 +23,7 @@ import ( const startVSCodeServerCommand = "$HOME/vscode-server/bin/openvscode-server --start-server --port=63000 --host=0.0.0.0 --without-connection-token --disable-workspace-trust --default-folder=" -func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { +func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey *string) error { // Download and start IDE err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { @@ -31,7 +31,7 @@ func OpenBrowserIDE(activeProfile config.Profile, workspaceId string, workspaceP } views.RenderInfoMessageBold("Downloading OpenVSCode Server...") - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) installServerCommand := exec.Command("ssh", workspaceHostname, "curl -fsSL https://download.daytona.io/daytona/get-openvscode-server.sh | sh") installServerCommand.Stdout = io.Writer(&util.DebugLogWriter{}) diff --git a/pkg/ide/cursor.go b/pkg/ide/cursor.go index 368cfb2e34..c1bd38c563 100644 --- a/pkg/ide/cursor.go +++ b/pkg/ide/cursor.go @@ -14,15 +14,15 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenCursor(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenCursor(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey *string) error { path, err := GetCursorBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) - workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) + workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err } diff --git a/pkg/ide/fleet.go b/pkg/ide/fleet.go index 28d7c179a0..4f784792b4 100644 --- a/pkg/ide/fleet.go +++ b/pkg/ide/fleet.go @@ -13,12 +13,12 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenFleet(activeProfile config.Profile, workspaceId string, gpgKey string) error { +func OpenFleet(activeProfile config.Profile, workspaceId string, gpgKey *string) error { if err := CheckFleetInstallation(); err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err diff --git a/pkg/ide/jetbrains.go b/pkg/ide/jetbrains.go index 6197f42054..9d8ee26693 100644 --- a/pkg/ide/jetbrains.go +++ b/pkg/ide/jetbrains.go @@ -23,7 +23,7 @@ import ( "github.com/pkg/browser" ) -func OpenJetbrainsIDE(activeProfile config.Profile, ide, workspaceId string, gpgKey string) error { +func OpenJetbrainsIDE(activeProfile config.Profile, ide, workspaceId string, gpgKey *string) error { err := IsJetBrainsGatewayInstalled() if err != nil { return err @@ -34,7 +34,7 @@ func OpenJetbrainsIDE(activeProfile config.Profile, ide, workspaceId string, gpg return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) jbIde, ok := jetbrains.GetIdes()[jetbrains.Id(ide)] if !ok { diff --git a/pkg/ide/jupyter.go b/pkg/ide/jupyter.go index 88394d50da..34315be676 100644 --- a/pkg/ide/jupyter.go +++ b/pkg/ide/jupyter.go @@ -26,14 +26,14 @@ import ( const startJupyterCommand = "notebook --no-browser --port=8888 --ip=0.0.0.0 --NotebookApp.token='' --NotebookApp.password=''" // OpenJupyterIDE manages the installation and startup of a Jupyter IDE on a remote target. -func OpenJupyterIDE(activeProfile config.Profile, workspaceId, workspaceProviderMetadata string, yesFlag bool, gpgKey string) error { +func OpenJupyterIDE(activeProfile config.Profile, workspaceId, workspaceProviderMetadata string, yesFlag bool, gpgKey *string) error { // Ensure SSH config entry is added err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) // Check and install Python if necessary if err := ensurePythonInstalled(workspaceHostname, yesFlag); err != nil { @@ -216,7 +216,7 @@ func ensureJupyterInstalled(hostname string) error { } // startJupyterServer starts the Jupyter Notebook server on the remote target. -func startJupyterServer(hostname string, activeProfile config.Profile, workspaceId string, gpgKey string) error { +func startJupyterServer(hostname string, activeProfile config.Profile, workspaceId string, gpgKey *string) error { workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err diff --git a/pkg/ide/terminal.go b/pkg/ide/terminal.go index 63c43f4972..5b61d4c4d4 100644 --- a/pkg/ide/terminal.go +++ b/pkg/ide/terminal.go @@ -12,8 +12,8 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" ) -func OpenTerminalSsh(activeProfile config.Profile, workspaceId string, gpgKey string, sshOptions []string, args ...string) error { - if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey); err != nil { +func OpenTerminalSsh(activeProfile config.Profile, resourceId string, gpgKey *string, sshOptions []string, args ...string) error { + if err := config.EnsureSshConfigEntryAdded(activeProfile.Id, resourceId, gpgKey); err != nil { return err } @@ -23,8 +23,8 @@ func OpenTerminalSsh(activeProfile config.Profile, workspaceId string, gpgKey st return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) - cmdArgs := buildCommandArgs(workspaceHostname, parsedOptions, args...) + resourceHostname := config.GetHostname(activeProfile.Id, resourceId) + cmdArgs := buildCommandArgs(resourceHostname, parsedOptions, args...) sshCommand := exec.Command("ssh", cmdArgs...) sshCommand.Stdin = os.Stdin @@ -50,8 +50,8 @@ func parseSshOptions(sshOptions []string) (map[string]string, error) { return parsedOptions, nil } -func buildCommandArgs(workspaceHostname string, parsedOptions map[string]string, args ...string) []string { - cmdArgs := []string{workspaceHostname} +func buildCommandArgs(resourceHostname string, parsedOptions map[string]string, args ...string) []string { + cmdArgs := []string{resourceHostname} for key, value := range parsedOptions { cmdArgs = append(cmdArgs, "-o", fmt.Sprintf("%s=%s", key, value)) } diff --git a/pkg/ide/vscode.go b/pkg/ide/vscode.go index 61fc4f69d4..7b24441893 100644 --- a/pkg/ide/vscode.go +++ b/pkg/ide/vscode.go @@ -19,14 +19,14 @@ import ( log "github.com/sirupsen/logrus" ) -func OpenVSCode(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { +func OpenVSCode(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey *string) error { CheckAndAlertVSCodeInstalled() err := installRemoteSSHExtension("code") if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { diff --git a/pkg/ide/zed.go b/pkg/ide/zed.go index 2b806e35d4..e96d7a8385 100644 --- a/pkg/ide/zed.go +++ b/pkg/ide/zed.go @@ -14,13 +14,13 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenZed(activeProfile config.Profile, workspaceId, gpgKey string) error { +func OpenZed(activeProfile config.Profile, workspaceId string, gpgKey *string) error { path, err := GetZedBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { return err diff --git a/pkg/views/ide/start_target.go b/pkg/views/ide/start.go similarity index 65% rename from pkg/views/ide/start_target.go rename to pkg/views/ide/start.go index 92d56004f7..e8722fef0b 100644 --- a/pkg/views/ide/start_target.go +++ b/pkg/views/ide/start.go @@ -12,12 +12,20 @@ import ( ) func RunStartWorkspaceForm(workspaceName string) bool { + return runStartForm("workspace", workspaceName) +} + +func RunStartTargetForm(targetName string) bool { + return runStartForm("target", targetName) +} + +func runStartForm(resource, name string) bool { confirmCheck := true form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title(fmt.Sprintf("The workspace %s is stopped, would you like to start it?", workspaceName)). + Title(fmt.Sprintf("The %s %s is stopped, would you like to start it?", resource, name)). Value(&confirmCheck), ), ).WithTheme(views.GetCustomTheme()) From 71df1e1a616b639f21d726eeb70d4440fc91206f Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Thu, 5 Dec 2024 10:09:07 +0000 Subject: [PATCH 22/76] fix: start job runner after server Signed-off-by: Toma Puljak --- pkg/cmd/server/serve.go | 24 +++++++++++++----------- pkg/runners/runner/runner.go | 11 ----------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 01c352df92..1e7b374314 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -84,17 +84,6 @@ var ServeCmd = &cobra.Command{ return err } - jobRunner, err := bootstrap.GetJobRunner(c, configDir, internal.Version, telemetryService) - if err != nil { - return err - } - - // TODO: context? - err = jobRunner.StartRunner(context.Background()) - if err != nil { - return err - } - apiServerErrChan := make(chan error) go func() { @@ -141,6 +130,19 @@ var ServeCmd = &cobra.Command{ return err } + log.Info("Starting job runner...") + jobRunner, err := bootstrap.GetJobRunner(c, configDir, internal.Version, telemetryService) + if err != nil { + return err + } + + // TODO: context? + err = jobRunner.StartRunner(context.Background()) + if err != nil { + return err + } + log.Info("Job runner started") + err = waitForApiServerToStart(apiServer) if err != nil { return err diff --git a/pkg/runners/runner/runner.go b/pkg/runners/runner/runner.go index d956955831..b647181ca1 100644 --- a/pkg/runners/runner/runner.go +++ b/pkg/runners/runner/runner.go @@ -5,9 +5,7 @@ package runner import ( "context" - "time" - "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/jobs" "github.com/daytonaio/daytona/pkg/jobs/build" "github.com/daytonaio/daytona/pkg/jobs/target" @@ -50,15 +48,6 @@ type JobRunner struct { func (s *JobRunner) StartRunner(ctx context.Context) error { scheduler := scheduler.NewCronScheduler() - // Make sure the API is up - for { - _, err := apiclient.GetApiClient(nil) - if err != nil { - break - } - time.Sleep(500 * time.Millisecond) - } - err := scheduler.AddFunc(runners.DEFAULT_JOB_POLL_INTERVAL, func() { err := s.CheckAndRunJobs(ctx) if err != nil { From a55e01e6717db7efd01ce8d10eceae5ad0022b73 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Thu, 5 Dec 2024 10:18:39 +0000 Subject: [PATCH 23/76] refactor: move target and workspacetemplate dtos into service files Signed-off-by: Toma Puljak --- .../mocks/workspace_template_service.go | 14 ++++---- .../util/apiclient/conversion/workspace.go | 4 +-- pkg/api/controllers/target/create.go | 4 +-- .../workspacetemplate/prebuild/prebuild.go | 4 +-- .../workspacetemplate/workspace_template.go | 4 +-- pkg/server/targets/create.go | 3 +- pkg/server/targets/dto/target.go | 20 ----------- pkg/server/targets/get.go | 5 ++- pkg/server/targets/list.go | 7 ++-- pkg/server/targets/service_test.go | 5 ++- pkg/server/targets/set-default.go | 3 +- .../dto/workspacetemplate.go | 33 ------------------ pkg/server/workspacetemplates/prebuild.go | 16 ++++----- .../workspacetemplates/prebuild_test.go | 7 ++-- pkg/services/target.go | 19 ++++++++--- pkg/services/workspace_template.go | 34 ++++++++++++++++--- 16 files changed, 80 insertions(+), 102 deletions(-) delete mode 100644 pkg/server/targets/dto/target.go delete mode 100644 pkg/server/workspacetemplates/dto/workspacetemplate.go diff --git a/internal/testing/server/targets/mocks/workspace_template_service.go b/internal/testing/server/targets/mocks/workspace_template_service.go index ff0cc4780c..6a4024c028 100644 --- a/internal/testing/server/targets/mocks/workspace_template_service.go +++ b/internal/testing/server/targets/mocks/workspace_template_service.go @@ -8,7 +8,7 @@ package mocks import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/stretchr/testify/mock" ) @@ -46,19 +46,19 @@ func (m *mockWorkspaceTemplateService) Save(wt *models.WorkspaceTemplate) error return args.Error(0) } -func (m *mockWorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { +func (m *mockWorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto services.CreatePrebuildDTO) (*services.PrebuildDTO, error) { args := m.Called(workspaceTemplateName, createPrebuildDto) - return args.Get(0).(*dto.PrebuildDTO), args.Error(1) + return args.Get(0).(*services.PrebuildDTO), args.Error(1) } -func (m *mockWorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { +func (m *mockWorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*services.PrebuildDTO, error) { args := m.Called(workspaceTemplateFilter, prebuildFilter) - return args.Get(0).(*dto.PrebuildDTO), args.Error(1) + return args.Get(0).(*services.PrebuildDTO), args.Error(1) } -func (m *mockWorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { +func (m *mockWorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*services.PrebuildDTO, error) { args := m.Called(workspaceTemplateFilter, prebuildFilter) - return args.Get(0).([]*dto.PrebuildDTO), args.Error(1) + return args.Get(0).([]*services.PrebuildDTO), args.Error(1) } func (m *mockWorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, id string, force bool) []error { diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go index dc1ef66198..d5b6362f58 100644 --- a/internal/util/apiclient/conversion/workspace.go +++ b/internal/util/apiclient/conversion/workspace.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - wt_dto "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/services" ) func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { @@ -154,7 +154,7 @@ func ToGitStatusDTO(gitStatus *models.GitStatus) *apiclient.GitStatus { } } -func ToWorkspaceTemplate(createWorkspaceTemplateDto wt_dto.CreateWorkspaceTemplateDTO) *models.WorkspaceTemplate { +func ToWorkspaceTemplate(createWorkspaceTemplateDto services.CreateWorkspaceTemplateDTO) *models.WorkspaceTemplate { result := &models.WorkspaceTemplate{ Name: createWorkspaceTemplateDto.Name, BuildConfig: createWorkspaceTemplateDto.BuildConfig, diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go index 0fde92ed95..981752561a 100644 --- a/pkg/api/controllers/target/create.go +++ b/pkg/api/controllers/target/create.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/targets/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" ) @@ -25,7 +25,7 @@ import ( // // @id CreateTarget func CreateTarget(ctx *gin.Context) { - var createTargetReq dto.CreateTargetDTO + var createTargetReq services.CreateTargetDTO err := ctx.BindJSON(&createTargetReq) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) diff --git a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go index c55c62ed17..6a06b7befe 100644 --- a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go @@ -10,7 +10,7 @@ import ( "strconv" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -64,7 +64,7 @@ func GetPrebuild(ctx *gin.Context) { func SetPrebuild(ctx *gin.Context) { templateName := ctx.Param("templateName") - var dto dto.CreatePrebuildDTO + var dto services.CreatePrebuildDTO err := ctx.BindJSON(&dto) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) diff --git a/pkg/api/controllers/workspacetemplate/workspace_template.go b/pkg/api/controllers/workspacetemplate/workspace_template.go index d5a7577eb1..c95a5f0151 100644 --- a/pkg/api/controllers/workspacetemplate/workspace_template.go +++ b/pkg/api/controllers/workspacetemplate/workspace_template.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" @@ -121,7 +121,7 @@ func ListWorkspaceTemplates(ctx *gin.Context) { // // @id SetWorkspaceTemplate func SetWorkspaceTemplate(ctx *gin.Context) { - var req dto.CreateWorkspaceTemplateDTO + var req services.CreateWorkspaceTemplateDTO err := ctx.BindJSON(&req) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index b569740554..7e16047bca 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -8,7 +8,6 @@ import ( "regexp" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" @@ -16,7 +15,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *TargetService) CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) { +func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTargetDTO) (*models.Target, error) { _, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &req.Id}) if err == nil { return nil, services.ErrTargetAlreadyExists diff --git a/pkg/server/targets/dto/target.go b/pkg/server/targets/dto/target.go deleted file mode 100644 index 135201e2f8..0000000000 --- a/pkg/server/targets/dto/target.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import ( - "github.com/daytonaio/daytona/pkg/models" -) - -type TargetDTO struct { - models.Target - State models.ResourceState `json:"state" validate:"required"` - Info *models.TargetInfo `json:"info" validate:"optional"` -} // @name TargetDTO - -type CreateTargetDTO struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - TargetConfigName string `json:"targetConfigName" validate:"required"` -} // @name CreateTargetDTO diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 9f1420379c..931f1f74dc 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -11,13 +11,12 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*dto.TargetDTO, error) { +func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { tg, err := s.targetStore.Find(filter) if err != nil { return nil, stores.ErrTargetNotFound @@ -38,7 +37,7 @@ func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilt } tg.Workspaces = updatedWorkspaces - response := dto.TargetDTO{ + response := services.TargetDTO{ Target: *tg, State: state, } diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index d6967f734d..85d12487d0 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -12,20 +12,19 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]dto.TargetDTO, error) { +func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]services.TargetDTO, error) { targets, err := s.targetStore.List(filter) if err != nil { return nil, err } var wg sync.WaitGroup - response := []dto.TargetDTO{} + response := []services.TargetDTO{} for i, t := range targets { state := t.GetState() @@ -43,7 +42,7 @@ func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFi } t.Workspaces = updatedWorkspaces - response = append(response, dto.TargetDTO{ + response = append(response, services.TargetDTO{ Target: *t, State: state, }) diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 4da77e12bc..67d0240cae 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -14,7 +14,6 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/targets" - "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" @@ -43,7 +42,7 @@ var tg = &models.Target{ TargetConfig: tc, } -var createTargetDTO = dto.CreateTargetDTO{ +var createTargetDTO = services.CreateTargetDTO{ Name: "test", Id: "test", TargetConfigName: "test", @@ -247,7 +246,7 @@ func targetEquals(t *testing.T, t1, t2 *models.Target) { require.Equal(t, t1.IsDefault, t2.IsDefault) } -func targetDtoEquals(t *testing.T, req dto.CreateTargetDTO, target dto.TargetDTO, targetInfo models.TargetInfo, verbose bool) { +func targetDtoEquals(t *testing.T, req services.CreateTargetDTO, target services.TargetDTO, targetInfo models.TargetInfo, verbose bool) { t.Helper() require.Equal(t, req.Id, target.Id) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index 65c725d7e1..33f07674f4 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -8,7 +8,6 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" ) @@ -40,7 +39,7 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { return s.targetStore.Save(TargetDtoToTarget(*currentTarget)) } -func TargetDtoToTarget(targetDto dto.TargetDTO) *models.Target { +func TargetDtoToTarget(targetDto services.TargetDTO) *models.Target { return &models.Target{ Id: targetDto.Id, Name: targetDto.Name, diff --git a/pkg/server/workspacetemplates/dto/workspacetemplate.go b/pkg/server/workspacetemplates/dto/workspacetemplate.go deleted file mode 100644 index 572447dd90..0000000000 --- a/pkg/server/workspacetemplates/dto/workspacetemplate.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package dto - -import "github.com/daytonaio/daytona/pkg/models" - -type CreateWorkspaceTemplateDTO struct { - Name string `json:"name" validate:"required"` - Image *string `json:"image,omitempty" validate:"optional"` - User *string `json:"user,omitempty" validate:"optional"` - BuildConfig *models.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` - RepositoryUrl string `json:"repositoryUrl" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` -} // @name CreateWorkspaceTemplateDTO - -type PrebuildDTO struct { - Id string `json:"id" validate:"required"` - WorkspaceTemplateName string `json:"workspaceTemplateName" validate:"required"` - Branch string `json:"branch" validate:"required"` - CommitInterval *int `json:"commitInterval" validate:"optional"` - TriggerFiles []string `json:"triggerFiles" validate:"optional"` - Retention int `json:"retention" validate:"required"` -} // @name PrebuildDTO - -type CreatePrebuildDTO struct { - Id *string `json:"id" validate:"optional"` - Branch string `json:"branch" validate:"optional"` - CommitInterval *int `json:"commitInterval" validate:"optional"` - TriggerFiles []string `json:"triggerFiles" validate:"optional"` - Retention int `json:"retention" validate:"required"` -} // @name CreatePrebuildDTO diff --git a/pkg/server/workspacetemplates/prebuild.go b/pkg/server/workspacetemplates/prebuild.go index 2fd78a2f40..4ce4749805 100644 --- a/pkg/server/workspacetemplates/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -13,12 +13,12 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/runners" "github.com/daytonaio/daytona/pkg/scheduler" - "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" log "github.com/sirupsen/logrus" ) -func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) { +func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto services.CreatePrebuildDTO) (*services.PrebuildDTO, error) { ctx := context.Background() workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ @@ -93,7 +93,7 @@ func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, cre return nil, err } - return &dto.PrebuildDTO{ + return &services.PrebuildDTO{ Id: prebuild.Id, WorkspaceTemplateName: workspaceTemplate.Name, Branch: prebuild.Branch, @@ -103,7 +103,7 @@ func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, cre }, nil } -func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) { +func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*services.PrebuildDTO, error) { wt, err := s.templateStore.Find(workspaceTemplateFilter) if err != nil { return nil, stores.ErrWorkspaceTemplateNotFound @@ -120,7 +120,7 @@ func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores. return nil, err } - return &dto.PrebuildDTO{ + return &services.PrebuildDTO{ Id: prebuild.Id, WorkspaceTemplateName: wt.Name, Branch: prebuild.Branch, @@ -130,8 +130,8 @@ func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores. }, nil } -func (s *WorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) { - var result []*dto.PrebuildDTO +func (s *WorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*services.PrebuildDTO, error) { + var result []*services.PrebuildDTO wts, err := s.templateStore.List(workspaceTemplateFilter) if err != nil { return nil, stores.ErrWorkspaceTemplateNotFound @@ -139,7 +139,7 @@ func (s *WorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores for _, wt := range wts { for _, prebuild := range wt.Prebuilds { - result = append(result, &dto.PrebuildDTO{ + result = append(result, &services.PrebuildDTO{ Id: prebuild.Id, WorkspaceTemplateName: wt.Name, Branch: prebuild.Branch, diff --git a/pkg/server/workspacetemplates/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go index 690f78b758..4e5bd1368a 100644 --- a/pkg/server/workspacetemplates/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -9,7 +9,6 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" ) @@ -38,7 +37,7 @@ var prebuild3 = &models.PrebuildConfig{ TriggerFiles: []string{"file1", "file2"}, } -var prebuild1Dto = &dto.PrebuildDTO{ +var prebuild1Dto = &services.PrebuildDTO{ WorkspaceTemplateName: workspaceTemplate1.Name, Id: prebuild1.Id, Branch: prebuild1.Branch, @@ -68,7 +67,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestSetPrebuild() { }).Return(repository1, nil) s.gitProviderService.On("GetPrebuildWebhook", "github", repository1, "").Return(util.Pointer("webhook-id"), nil) - newPrebuildDto, err := s.workspaceTemplateService.SetPrebuild(workspaceTemplate1.Name, dto.CreatePrebuildDTO{ + newPrebuildDto, err := s.workspaceTemplateService.SetPrebuild(workspaceTemplate1.Name, services.CreatePrebuildDTO{ Id: &prebuild3.Id, Branch: prebuild3.Branch, CommitInterval: prebuild3.CommitInterval, @@ -122,7 +121,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestDeletePrebuild() { Name: &workspaceTemplate1.Name, }, nil) require.Nil(errs) - require.ElementsMatch([]*dto.PrebuildDTO{ + require.ElementsMatch([]*services.PrebuildDTO{ prebuild1Dto, }, prebuildDtos) } diff --git a/pkg/services/target.go b/pkg/services/target.go index 0ca9f9545d..7247b62dd0 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -9,15 +9,14 @@ import ( "io" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/targets/dto" "github.com/daytonaio/daytona/pkg/stores" ) type ITargetService interface { - CreateTarget(ctx context.Context, req dto.CreateTargetDTO) (*models.Target, error) - GetTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*dto.TargetDTO, error) + CreateTarget(ctx context.Context, req CreateTargetDTO) (*models.Target, error) + GetTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*TargetDTO, error) GetTargetLogReader(targetId string) (io.Reader, error) - ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]dto.TargetDTO, error) + ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]TargetDTO, error) StartTarget(ctx context.Context, targetId string) error StopTarget(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error @@ -29,6 +28,18 @@ type ITargetService interface { SetTargetMetadata(targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) } +type TargetDTO struct { + models.Target + State models.ResourceState `json:"state" validate:"required"` + Info *models.TargetInfo `json:"info" validate:"optional"` +} // @name TargetDTO + +type CreateTargetDTO struct { + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfigName string `json:"targetConfigName" validate:"required"` +} // @name CreateTargetDTO + type TargetRetrievalParams struct { Verbose bool ShowDeleted bool diff --git a/pkg/services/workspace_template.go b/pkg/services/workspace_template.go index 88ffdcffa2..e1da7d5667 100644 --- a/pkg/services/workspace_template.go +++ b/pkg/services/workspace_template.go @@ -6,7 +6,6 @@ package services import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/workspacetemplates/dto" "github.com/daytonaio/daytona/pkg/stores" ) @@ -17,12 +16,39 @@ type IWorkspaceTemplateService interface { SetDefault(workspaceTemplateName string) error Delete(workspaceTemplateName string, force bool) []error - SetPrebuild(workspaceTemplateName string, createPrebuildDto dto.CreatePrebuildDTO) (*dto.PrebuildDTO, error) - FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*dto.PrebuildDTO, error) - ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*dto.PrebuildDTO, error) + SetPrebuild(workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) + FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*PrebuildDTO, error) + ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*PrebuildDTO, error) DeletePrebuild(workspaceTemplateName string, id string, force bool) []error StartRetentionPoller() error EnforceRetentionPolicy() error ProcessGitEvent(gitprovider.GitEventData) error } + +type CreateWorkspaceTemplateDTO struct { + Name string `json:"name" validate:"required"` + Image *string `json:"image,omitempty" validate:"optional"` + User *string `json:"user,omitempty" validate:"optional"` + BuildConfig *models.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` + RepositoryUrl string `json:"repositoryUrl" validate:"required"` + EnvVars map[string]string `json:"envVars" validate:"required"` + GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` +} // @name CreateWorkspaceTemplateDTO + +type PrebuildDTO struct { + Id string `json:"id" validate:"required"` + WorkspaceTemplateName string `json:"workspaceTemplateName" validate:"required"` + Branch string `json:"branch" validate:"required"` + CommitInterval *int `json:"commitInterval" validate:"optional"` + TriggerFiles []string `json:"triggerFiles" validate:"optional"` + Retention int `json:"retention" validate:"required"` +} // @name PrebuildDTO + +type CreatePrebuildDTO struct { + Id *string `json:"id" validate:"optional"` + Branch string `json:"branch" validate:"optional"` + CommitInterval *int `json:"commitInterval" validate:"optional"` + TriggerFiles []string `json:"triggerFiles" validate:"optional"` + Retention int `json:"retention" validate:"required"` +} // @name CreatePrebuildDTO From c004e92ea971e0b468c59359a48272f79626f9e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 5 Dec 2024 16:00:16 +0100 Subject: [PATCH 24/76] refactor: enable container registry setting through env-vars (#1406) Signed-off-by: Luka Brecic --- docs/daytona.md | 1 - docs/daytona_container-registry.md | 17 - docs/daytona_container-registry_delete.md | 18 - docs/daytona_container-registry_list.md | 24 - docs/daytona_container-registry_set.md | 26 - docs/daytona_env_list.md | 1 + docs/daytona_target.md | 1 + docs/daytona_target_ssh.md | 25 + hack/docs/daytona.yaml | 1 - hack/docs/daytona_container-registry.yaml | 11 - .../daytona_container-registry_delete.yaml | 9 - .../docs/daytona_container-registry_list.yaml | 13 - hack/docs/daytona_container-registry_set.yaml | 19 - hack/docs/daytona_env_list.yaml | 4 + hack/docs/daytona_target.yaml | 1 + hack/docs/daytona_target_ssh.yaml | 18 + .../server/containerregistries/store.go | 53 -- .../mocks/container_registry_service.go | 49 -- internal/util/apiclient/conversion/env.go | 16 - pkg/api/controllers/containerregistry/list.go | 72 --- .../controllers/containerregistry/remove.go | 43 -- pkg/api/controllers/containerregistry/set.go | 67 --- pkg/api/docs/docs.go | 126 ----- pkg/api/docs/swagger.json | 126 ----- pkg/api/docs/swagger.yaml | 85 ---- pkg/api/server.go | 11 +- pkg/apiclient/README.md | 5 - pkg/apiclient/api/openapi.yaml | 96 ---- pkg/apiclient/api_container_registry.go | 479 ------------------ pkg/apiclient/client.go | 3 - pkg/apiclient/docs/ContainerRegistry.md | 93 ---- pkg/apiclient/docs/ContainerRegistryAPI.md | 281 ---------- pkg/apiclient/model_container_registry.go | 212 -------- pkg/cmd/build/run.go | 13 - pkg/cmd/cmd.go | 2 - .../containerregistry/containerregistry.go | 22 - pkg/cmd/containerregistry/delete.go | 77 --- pkg/cmd/containerregistry/list.go | 45 -- pkg/cmd/containerregistry/set.go | 108 ---- pkg/cmd/env/list.go | 11 + pkg/cmd/env/set.go | 2 +- pkg/cmd/server/bootstrap/get_job_runner.go | 37 +- .../server/bootstrap/get_server_instance.go | 21 +- pkg/cmd/server/configure.go | 7 +- pkg/cmd/target/target.go | 2 +- pkg/cmd/workspace/create/cmd.go | 11 - pkg/db/container_registry_store.go | 68 --- pkg/jobs/util/env.go | 18 + pkg/jobs/workspace/create.go | 15 +- pkg/jobs/workspace/factory.go | 28 +- pkg/jobs/workspace/start.go | 15 +- pkg/jobs/workspace/workspace.go | 11 +- pkg/server/containerregistries/service.go | 76 --- .../containerregistries/service_test.go | 55 -- pkg/server/env/service.go | 14 + pkg/server/server.go | 3 - pkg/server/targets/create.go | 4 +- pkg/server/targets/set-default.go | 15 +- pkg/server/workspaces/create.go | 10 +- pkg/server/workspaces/service.go | 4 +- pkg/server/workspaces/service_test.go | 8 +- pkg/services/container_registry.go | 15 - pkg/services/env.go | 36 +- pkg/stores/container_registry.go | 25 - pkg/views/containerregistry/list/view.go | 73 --- pkg/views/containerregistry/select.go | 51 -- pkg/views/containerregistry/set.go | 63 --- pkg/views/containerregistry/view.go | 62 --- pkg/views/env/add.go | 53 -- pkg/views/env/form/model.go | 126 +++++ pkg/views/env/set.go | 54 ++ pkg/views/server/configure.go | 27 +- 72 files changed, 397 insertions(+), 2896 deletions(-) delete mode 100644 docs/daytona_container-registry.md delete mode 100644 docs/daytona_container-registry_delete.md delete mode 100644 docs/daytona_container-registry_list.md delete mode 100644 docs/daytona_container-registry_set.md create mode 100644 docs/daytona_target_ssh.md delete mode 100644 hack/docs/daytona_container-registry.yaml delete mode 100644 hack/docs/daytona_container-registry_delete.yaml delete mode 100644 hack/docs/daytona_container-registry_list.yaml delete mode 100644 hack/docs/daytona_container-registry_set.yaml create mode 100644 hack/docs/daytona_target_ssh.yaml delete mode 100644 internal/testing/server/containerregistries/store.go delete mode 100644 internal/testing/server/targets/mocks/container_registry_service.go delete mode 100644 internal/util/apiclient/conversion/env.go delete mode 100644 pkg/api/controllers/containerregistry/list.go delete mode 100644 pkg/api/controllers/containerregistry/remove.go delete mode 100644 pkg/api/controllers/containerregistry/set.go delete mode 100644 pkg/apiclient/api_container_registry.go delete mode 100644 pkg/apiclient/docs/ContainerRegistry.md delete mode 100644 pkg/apiclient/docs/ContainerRegistryAPI.md delete mode 100644 pkg/apiclient/model_container_registry.go delete mode 100644 pkg/cmd/containerregistry/containerregistry.go delete mode 100644 pkg/cmd/containerregistry/delete.go delete mode 100644 pkg/cmd/containerregistry/list.go delete mode 100644 pkg/cmd/containerregistry/set.go delete mode 100644 pkg/db/container_registry_store.go create mode 100644 pkg/jobs/util/env.go delete mode 100644 pkg/server/containerregistries/service.go delete mode 100644 pkg/server/containerregistries/service_test.go delete mode 100644 pkg/services/container_registry.go delete mode 100644 pkg/stores/container_registry.go delete mode 100644 pkg/views/containerregistry/list/view.go delete mode 100644 pkg/views/containerregistry/select.go delete mode 100644 pkg/views/containerregistry/set.go delete mode 100644 pkg/views/containerregistry/view.go delete mode 100644 pkg/views/env/add.go create mode 100644 pkg/views/env/form/model.go create mode 100644 pkg/views/env/set.go diff --git a/docs/daytona.md b/docs/daytona.md index 770c63c336..60fa9ba34b 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -24,7 +24,6 @@ daytona [flags] * [daytona build](daytona_build.md) - Manage builds * [daytona code](daytona_code.md) - Open a workspace in your preferred IDE * [daytona config](daytona_config.md) - Output Daytona configuration -* [daytona container-registry](daytona_container-registry.md) - Manage container registries * [daytona create](daytona_create.md) - Create a workspace * [daytona delete](daytona_delete.md) - Delete a workspace * [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. diff --git a/docs/daytona_container-registry.md b/docs/daytona_container-registry.md deleted file mode 100644 index f101ccfbd7..0000000000 --- a/docs/daytona_container-registry.md +++ /dev/null @@ -1,17 +0,0 @@ -## daytona container-registry - -Manage container registries - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona container-registry delete](daytona_container-registry_delete.md) - Delete a container registry -* [daytona container-registry list](daytona_container-registry_list.md) - Lists container registries -* [daytona container-registry set](daytona_container-registry_set.md) - Set container registry - diff --git a/docs/daytona_container-registry_delete.md b/docs/daytona_container-registry_delete.md deleted file mode 100644 index bbf017d9f9..0000000000 --- a/docs/daytona_container-registry_delete.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona container-registry delete - -Delete a container registry - -``` -daytona container-registry delete [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona container-registry](daytona_container-registry.md) - Manage container registries - diff --git a/docs/daytona_container-registry_list.md b/docs/daytona_container-registry_list.md deleted file mode 100644 index ca07652b86..0000000000 --- a/docs/daytona_container-registry_list.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona container-registry list - -Lists container registries - -``` -daytona container-registry list [flags] -``` - -### Options - -``` - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona container-registry](daytona_container-registry.md) - Manage container registries - diff --git a/docs/daytona_container-registry_set.md b/docs/daytona_container-registry_set.md deleted file mode 100644 index dd3ed61d0c..0000000000 --- a/docs/daytona_container-registry_set.md +++ /dev/null @@ -1,26 +0,0 @@ -## daytona container-registry set - -Set container registry - -``` -daytona container-registry set [flags] -``` - -### Options - -``` - -p, --password string Password - -s, --server string Server - -u, --username string Username -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona container-registry](daytona_container-registry.md) - Manage container registries - diff --git a/docs/daytona_env_list.md b/docs/daytona_env_list.md index 8b19de8360..600fc50a36 100644 --- a/docs/daytona_env_list.md +++ b/docs/daytona_env_list.md @@ -10,6 +10,7 @@ daytona env list [flags] ``` -f, --format string Output format. Must be one of (yaml, json) + -v, --show-values Show environment variable values ``` ### Options inherited from parent commands diff --git a/docs/daytona_target.md b/docs/daytona_target.md index 6a3790a81d..2470776308 100644 --- a/docs/daytona_target.md +++ b/docs/daytona_target.md @@ -18,6 +18,7 @@ Manage targets * [daytona target logs](daytona_target_logs.md) - View the logs of a target * [daytona target restart](daytona_target_restart.md) - Restart a target * [daytona target set-default](daytona_target_set-default.md) - Set default target +* [daytona target ssh](daytona_target_ssh.md) - SSH into a target using the terminal * [daytona target start](daytona_target_start.md) - Start a target * [daytona target stop](daytona_target_stop.md) - Stop a target diff --git a/docs/daytona_target_ssh.md b/docs/daytona_target_ssh.md new file mode 100644 index 0000000000..b1640a613e --- /dev/null +++ b/docs/daytona_target_ssh.md @@ -0,0 +1,25 @@ +## daytona target ssh + +SSH into a target using the terminal + +``` +daytona target ssh [TARGET] [CMD...] [flags] +``` + +### Options + +``` + -o, --option stringArray Specify SSH options in KEY=VALUE format. + -y, --yes Automatically confirm any prompts +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona target](daytona_target.md) - Manage targets + diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 7f008b6c22..7e56e486ad 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -16,7 +16,6 @@ see_also: - daytona build - Manage builds - daytona code - Open a workspace in your preferred IDE - daytona config - Output Daytona configuration - - daytona container-registry - Manage container registries - daytona create - Create a workspace - daytona delete - Delete a workspace - daytona docs - Opens the Daytona documentation in your default browser. diff --git a/hack/docs/daytona_container-registry.yaml b/hack/docs/daytona_container-registry.yaml deleted file mode 100644 index 8157d18d0d..0000000000 --- a/hack/docs/daytona_container-registry.yaml +++ /dev/null @@ -1,11 +0,0 @@ -name: daytona container-registry -synopsis: Manage container registries -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona container-registry delete - Delete a container registry - - daytona container-registry list - Lists container registries - - daytona container-registry set - Set container registry diff --git a/hack/docs/daytona_container-registry_delete.yaml b/hack/docs/daytona_container-registry_delete.yaml deleted file mode 100644 index 8200c586fd..0000000000 --- a/hack/docs/daytona_container-registry_delete.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona container-registry delete -synopsis: Delete a container registry -usage: daytona container-registry delete [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_container-registry_list.yaml b/hack/docs/daytona_container-registry_list.yaml deleted file mode 100644 index be84cb144c..0000000000 --- a/hack/docs/daytona_container-registry_list.yaml +++ /dev/null @@ -1,13 +0,0 @@ -name: daytona container-registry list -synopsis: Lists container registries -usage: daytona container-registry list [flags] -options: - - name: format - shorthand: f - usage: Output format. Must be one of (yaml, json) -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_container-registry_set.yaml b/hack/docs/daytona_container-registry_set.yaml deleted file mode 100644 index b4ca3426b9..0000000000 --- a/hack/docs/daytona_container-registry_set.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: daytona container-registry set -synopsis: Set container registry -usage: daytona container-registry set [flags] -options: - - name: password - shorthand: p - usage: Password - - name: server - shorthand: s - usage: Server - - name: username - shorthand: u - usage: Username -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona container-registry - Manage container registries diff --git a/hack/docs/daytona_env_list.yaml b/hack/docs/daytona_env_list.yaml index 7b84540475..da0588f306 100644 --- a/hack/docs/daytona_env_list.yaml +++ b/hack/docs/daytona_env_list.yaml @@ -5,6 +5,10 @@ options: - name: format shorthand: f usage: Output format. Must be one of (yaml, json) + - name: show-values + shorthand: v + default_value: "false" + usage: Show environment variable values inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_target.yaml b/hack/docs/daytona_target.yaml index 0ffef0f381..42b77d3d3f 100644 --- a/hack/docs/daytona_target.yaml +++ b/hack/docs/daytona_target.yaml @@ -13,5 +13,6 @@ see_also: - daytona target logs - View the logs of a target - daytona target restart - Restart a target - daytona target set-default - Set default target + - daytona target ssh - SSH into a target using the terminal - daytona target start - Start a target - daytona target stop - Stop a target diff --git a/hack/docs/daytona_target_ssh.yaml b/hack/docs/daytona_target_ssh.yaml new file mode 100644 index 0000000000..4549241c9f --- /dev/null +++ b/hack/docs/daytona_target_ssh.yaml @@ -0,0 +1,18 @@ +name: daytona target ssh +synopsis: SSH into a target using the terminal +usage: daytona target ssh [TARGET] [CMD...] [flags] +options: + - name: option + shorthand: o + default_value: '[]' + usage: Specify SSH options in KEY=VALUE format. + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Automatically confirm any prompts +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona target - Manage targets diff --git a/internal/testing/server/containerregistries/store.go b/internal/testing/server/containerregistries/store.go deleted file mode 100644 index 17a6c26f65..0000000000 --- a/internal/testing/server/containerregistries/store.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistries - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" -) - -type InMemoryContainerRegistryStore struct { - crs map[string]*models.ContainerRegistry -} - -func NewInMemoryContainerRegistryStore() stores.ContainerRegistryStore { - return &InMemoryContainerRegistryStore{ - crs: make(map[string]*models.ContainerRegistry), - } -} - -func (s *InMemoryContainerRegistryStore) List() ([]*models.ContainerRegistry, error) { - crs := []*models.ContainerRegistry{} - for _, cr := range s.crs { - crs = append(crs, cr) - } - - return crs, nil -} - -func (s *InMemoryContainerRegistryStore) Find(server string) (*models.ContainerRegistry, error) { - cr, ok := s.crs[server] - if !ok { - return nil, stores.ErrContainerRegistryNotFound - } - - return cr, nil -} - -func (s *InMemoryContainerRegistryStore) Save(cr *models.ContainerRegistry) error { - s.crs[cr.Server] = cr - return nil -} - -func (s *InMemoryContainerRegistryStore) Delete(cr *models.ContainerRegistry) error { - _, ok := s.crs[cr.Server] - if !ok { - return stores.ErrContainerRegistryNotFound - } - delete(s.crs, cr.Server) - return nil -} diff --git a/internal/testing/server/targets/mocks/container_registry_service.go b/internal/testing/server/targets/mocks/container_registry_service.go deleted file mode 100644 index 86768e5c99..0000000000 --- a/internal/testing/server/targets/mocks/container_registry_service.go +++ /dev/null @@ -1,49 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package mocks - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/stretchr/testify/mock" -) - -type mockContainerRegistryService struct { - mock.Mock -} - -func NewMockContainerRegistryService() *mockContainerRegistryService { - return &mockContainerRegistryService{} -} - -func (m *mockContainerRegistryService) Delete(server string) error { - args := m.Called(server) - return args.Error(0) -} - -func (m *mockContainerRegistryService) Find(server string) (*models.ContainerRegistry, error) { - args := m.Called(server) - return args.Get(0).(*models.ContainerRegistry), args.Error(1) -} - -func (m *mockContainerRegistryService) FindByImageName(imageName string) (*models.ContainerRegistry, error) { - args := m.Called(imageName) - return args.Get(0).(*models.ContainerRegistry), args.Error(1) -} - -func (m *mockContainerRegistryService) List() ([]*models.ContainerRegistry, error) { - args := m.Called() - return args.Get(0).([]*models.ContainerRegistry), args.Error(1) -} - -func (m *mockContainerRegistryService) Map() (map[string]*models.ContainerRegistry, error) { - args := m.Called() - return args.Get(0).(map[string]*models.ContainerRegistry), args.Error(1) -} - -func (m *mockContainerRegistryService) Save(cr *models.ContainerRegistry) error { - args := m.Called(cr) - return args.Error(0) -} diff --git a/internal/util/apiclient/conversion/env.go b/internal/util/apiclient/conversion/env.go deleted file mode 100644 index fa63e63bcd..0000000000 --- a/internal/util/apiclient/conversion/env.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package conversion - -import "github.com/daytonaio/daytona/pkg/apiclient" - -func ToEnvVarsMap(envVars []apiclient.EnvironmentVariable) map[string]string { - envVarsMap := map[string]string{} - - for _, envVar := range envVars { - envVarsMap[envVar.Key] = envVar.Value - } - - return envVarsMap -} diff --git a/pkg/api/controllers/containerregistry/list.go b/pkg/api/controllers/containerregistry/list.go deleted file mode 100644 index 29ba7219fd..0000000000 --- a/pkg/api/controllers/containerregistry/list.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "fmt" - "net/http" - "net/url" - - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// GetContainerRegistry godoc -// -// @Tags container-registry -// @Summary Get container registry credentials -// @Description Get container registry credentials -// @Produce json -// @Param server path string true "Container Registry server name" -// @Success 200 {object} ContainerRegistry -// @Router /container-registry/{server} [get] -// -// @id GetContainerRegistry -func GetContainerRegistry(ctx *gin.Context) { - crServer := ctx.Param("server") - - decodedServerURL, err := url.QueryUnescape(crServer) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode server URL: %w", err)) - return - } - - server := server.GetInstance(nil) - - cr, err := server.ContainerRegistryService.Find(decodedServerURL) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get container registry: %w", err)) - return - } - - cr.Password = "" - - ctx.JSON(200, cr) -} - -// ListContainerRegistries godoc -// -// @Tags container-registry -// @Summary List container registries -// @Description List container registries -// @Produce json -// @Success 200 {array} ContainerRegistry -// @Router /container-registry [get] -// -// @id ListContainerRegistries -func ListContainerRegistries(ctx *gin.Context) { - server := server.GetInstance(nil) - - crs, err := server.ContainerRegistryService.List() - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list container registries: %w", err)) - return - } - - for _, cr := range crs { - cr.Password = "" - } - - ctx.JSON(200, crs) -} diff --git a/pkg/api/controllers/containerregistry/remove.go b/pkg/api/controllers/containerregistry/remove.go deleted file mode 100644 index a1a9d2b57a..0000000000 --- a/pkg/api/controllers/containerregistry/remove.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "fmt" - "net/http" - "net/url" - - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// RemoveContainerRegistry godoc -// -// @Tags container-registry -// @Summary Remove a container registry credentials -// @Description Remove a container registry credentials -// @Param server path string true "Container Registry server name" -// @Success 204 -// @Router /container-registry/{server} [delete] -// -// @id RemoveContainerRegistry -func RemoveContainerRegistry(ctx *gin.Context) { - crServer := ctx.Param("server") - - decodedServerURL, err := url.QueryUnescape(crServer) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode server URL: %w", err)) - return - } - - server := server.GetInstance(nil) - - err = server.ContainerRegistryService.Delete(decodedServerURL) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove container registry: %w", err)) - return - } - - ctx.Status(204) -} diff --git a/pkg/api/controllers/containerregistry/set.go b/pkg/api/controllers/containerregistry/set.go deleted file mode 100644 index 21c6197d97..0000000000 --- a/pkg/api/controllers/containerregistry/set.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "fmt" - "net/http" - "net/url" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// SetContainerRegistry godoc -// -// @Tags container-registry -// @Summary Set container registry credentials -// @Description Set container registry credentials -// @Param server path string true "Container Registry server name" -// @Param containerRegistry body ContainerRegistry true "Container Registry credentials to set" -// @Success 201 -// @Router /container-registry/{server} [put] -// -// @id SetContainerRegistry -func SetContainerRegistry(ctx *gin.Context) { - crServer := ctx.Param("server") - - decodedServerURL, err := url.QueryUnescape(crServer) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode server URL: %w", err)) - return - } - - var req models.ContainerRegistry - err = ctx.BindJSON(&req) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - - cr, err := server.ContainerRegistryService.Find(decodedServerURL) - if err == nil { - err = server.ContainerRegistryService.Delete(decodedServerURL) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove container registry: %w", err)) - return - } - - cr.Server = req.Server - cr.Username = req.Username - cr.Password = req.Password - } else { - cr = &req - } - - err = server.ContainerRegistryService.Save(cr) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set container registry: %w", err)) - return - } - - ctx.Status(201) -} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index ba6fde7f1e..453abfca58 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -254,113 +254,6 @@ const docTemplate = `{ } } }, - "/container-registry": { - "get": { - "description": "List container registries", - "produces": [ - "application/json" - ], - "tags": [ - "container-registry" - ], - "summary": "List container registries", - "operationId": "ListContainerRegistries", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/ContainerRegistry" - } - } - } - } - } - }, - "/container-registry/{server}": { - "get": { - "description": "Get container registry credentials", - "produces": [ - "application/json" - ], - "tags": [ - "container-registry" - ], - "summary": "Get container registry credentials", - "operationId": "GetContainerRegistry", - "parameters": [ - { - "type": "string", - "description": "Container Registry server name", - "name": "server", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ContainerRegistry" - } - } - } - }, - "put": { - "description": "Set container registry credentials", - "tags": [ - "container-registry" - ], - "summary": "Set container registry credentials", - "operationId": "SetContainerRegistry", - "parameters": [ - { - "type": "string", - "description": "Container Registry server name", - "name": "server", - "in": "path", - "required": true - }, - { - "description": "Container Registry credentials to set", - "name": "containerRegistry", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/ContainerRegistry" - } - } - ], - "responses": { - "201": { - "description": "Created" - } - } - }, - "delete": { - "description": "Remove a container registry credentials", - "tags": [ - "container-registry" - ], - "summary": "Remove a container registry credentials", - "operationId": "RemoveContainerRegistry", - "parameters": [ - { - "type": "string", - "description": "Container Registry server name", - "name": "server", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/env": { "get": { "description": "List environment variables", @@ -3616,25 +3509,6 @@ const docTemplate = `{ } } }, - "ContainerRegistry": { - "type": "object", - "required": [ - "password", - "server", - "username" - ], - "properties": { - "password": { - "type": "string" - }, - "server": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, "CreateBuildDTO": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 41cc0d8f7f..bd737636e4 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -251,113 +251,6 @@ } } }, - "/container-registry": { - "get": { - "description": "List container registries", - "produces": [ - "application/json" - ], - "tags": [ - "container-registry" - ], - "summary": "List container registries", - "operationId": "ListContainerRegistries", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/ContainerRegistry" - } - } - } - } - } - }, - "/container-registry/{server}": { - "get": { - "description": "Get container registry credentials", - "produces": [ - "application/json" - ], - "tags": [ - "container-registry" - ], - "summary": "Get container registry credentials", - "operationId": "GetContainerRegistry", - "parameters": [ - { - "type": "string", - "description": "Container Registry server name", - "name": "server", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/ContainerRegistry" - } - } - } - }, - "put": { - "description": "Set container registry credentials", - "tags": [ - "container-registry" - ], - "summary": "Set container registry credentials", - "operationId": "SetContainerRegistry", - "parameters": [ - { - "type": "string", - "description": "Container Registry server name", - "name": "server", - "in": "path", - "required": true - }, - { - "description": "Container Registry credentials to set", - "name": "containerRegistry", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/ContainerRegistry" - } - } - ], - "responses": { - "201": { - "description": "Created" - } - } - }, - "delete": { - "description": "Remove a container registry credentials", - "tags": [ - "container-registry" - ], - "summary": "Remove a container registry credentials", - "operationId": "RemoveContainerRegistry", - "parameters": [ - { - "type": "string", - "description": "Container Registry server name", - "name": "server", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/env": { "get": { "description": "List environment variables", @@ -3613,25 +3506,6 @@ } } }, - "ContainerRegistry": { - "type": "object", - "required": [ - "password", - "server", - "username" - ], - "properties": { - "password": { - "type": "string" - }, - "server": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, "CreateBuildDTO": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 2631d74006..1f26b06c85 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -151,19 +151,6 @@ definitions: - image - user type: object - ContainerRegistry: - properties: - password: - type: string - server: - type: string - username: - type: string - required: - - password - - server - - username - type: object CreateBuildDTO: properties: branch: @@ -1658,78 +1645,6 @@ paths: summary: Delete builds tags: - build - /container-registry: - get: - description: List container registries - operationId: ListContainerRegistries - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/ContainerRegistry' - type: array - summary: List container registries - tags: - - container-registry - /container-registry/{server}: - delete: - description: Remove a container registry credentials - operationId: RemoveContainerRegistry - parameters: - - description: Container Registry server name - in: path - name: server - required: true - type: string - responses: - "204": - description: No Content - summary: Remove a container registry credentials - tags: - - container-registry - get: - description: Get container registry credentials - operationId: GetContainerRegistry - parameters: - - description: Container Registry server name - in: path - name: server - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/ContainerRegistry' - summary: Get container registry credentials - tags: - - container-registry - put: - description: Set container registry credentials - operationId: SetContainerRegistry - parameters: - - description: Container Registry server name - in: path - name: server - required: true - type: string - - description: Container Registry credentials to set - in: body - name: containerRegistry - required: true - schema: - $ref: '#/definitions/ContainerRegistry' - responses: - "201": - description: Created - summary: Set container registry credentials - tags: - - container-registry /env: get: description: List environment variables diff --git a/pkg/api/server.go b/pkg/api/server.go index 73159e4f60..97f1b6e4dc 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -35,7 +35,6 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/apikey" "github.com/daytonaio/daytona/pkg/api/controllers/binary" "github.com/daytonaio/daytona/pkg/api/controllers/build" - "github.com/daytonaio/daytona/pkg/api/controllers/containerregistry" "github.com/daytonaio/daytona/pkg/api/controllers/env" "github.com/daytonaio/daytona/pkg/api/controllers/gitprovider" "github.com/daytonaio/daytona/pkg/api/controllers/health" @@ -227,7 +226,7 @@ func (a *ApiServer) Start() error { jobController := protected.Group("/job") { - jobController.GET("/", job.ListJobs) + jobController.GET("", job.ListJobs) } workspaceTemplateController := protected.Group("/workspace-template") @@ -266,14 +265,6 @@ func (a *ApiServer) Start() error { providerController.GET("/:provider/target-config-manifest", provider.GetTargetConfigManifest) } - containerRegistryController := protected.Group("/container-registry") - { - containerRegistryController.GET("", containerregistry.ListContainerRegistries) - containerRegistryController.GET("/:server", containerregistry.GetContainerRegistry) - containerRegistryController.PUT("/:server", containerregistry.SetContainerRegistry) - containerRegistryController.DELETE("/:server", containerregistry.RemoveContainerRegistry) - } - buildController := protected.Group("/build") { buildController.POST("", build.CreateBuild) diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 9f524b2319..77604d1296 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -86,10 +86,6 @@ Class | Method | HTTP request | Description *BuildAPI* | [**DeleteBuildsFromPrebuild**](docs/BuildAPI.md#deletebuildsfromprebuild) | **Delete** /build/prebuild/{prebuildId} | Delete builds *BuildAPI* | [**GetBuild**](docs/BuildAPI.md#getbuild) | **Get** /build/{buildId} | Get build data *BuildAPI* | [**ListBuilds**](docs/BuildAPI.md#listbuilds) | **Get** /build | List builds -*ContainerRegistryAPI* | [**GetContainerRegistry**](docs/ContainerRegistryAPI.md#getcontainerregistry) | **Get** /container-registry/{server} | Get container registry credentials -*ContainerRegistryAPI* | [**ListContainerRegistries**](docs/ContainerRegistryAPI.md#listcontainerregistries) | **Get** /container-registry | List container registries -*ContainerRegistryAPI* | [**RemoveContainerRegistry**](docs/ContainerRegistryAPI.md#removecontainerregistry) | **Delete** /container-registry/{server} | Remove a container registry credentials -*ContainerRegistryAPI* | [**SetContainerRegistry**](docs/ContainerRegistryAPI.md#setcontainerregistry) | **Put** /container-registry/{server} | Set container registry credentials *DefaultAPI* | [**HealthCheck**](docs/DefaultAPI.md#healthcheck) | **Get** /health | Health check *EnvVarAPI* | [**DeleteEnvironmentVariable**](docs/EnvVarAPI.md#deleteenvironmentvariable) | **Delete** /env/{key} | Delete environment variable *EnvVarAPI* | [**ListEnvironmentVariables**](docs/EnvVarAPI.md#listenvironmentvariables) | **Get** /env | List environment variables @@ -196,7 +192,6 @@ Class | Method | HTTP request | Description - [CompletionItem](docs/CompletionItem.md) - [CompletionList](docs/CompletionList.md) - [ContainerConfig](docs/ContainerConfig.md) - - [ContainerRegistry](docs/ContainerRegistry.md) - [CreateBuildDTO](docs/CreateBuildDTO.md) - [CreatePrebuildDTO](docs/CreatePrebuildDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index ee84a84272..0bed61edc1 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -182,85 +182,6 @@ paths: summary: Get build data tags: - build - /container-registry: - get: - description: List container registries - operationId: ListContainerRegistries - responses: - "200": - content: - application/json: - schema: - items: - $ref: '#/components/schemas/ContainerRegistry' - type: array - description: OK - summary: List container registries - tags: - - container-registry - /container-registry/{server}: - delete: - description: Remove a container registry credentials - operationId: RemoveContainerRegistry - parameters: - - description: Container Registry server name - in: path - name: server - required: true - schema: - type: string - responses: - "204": - content: {} - description: No Content - summary: Remove a container registry credentials - tags: - - container-registry - get: - description: Get container registry credentials - operationId: GetContainerRegistry - parameters: - - description: Container Registry server name - in: path - name: server - required: true - schema: - type: string - responses: - "200": - content: - application/json: - schema: - $ref: '#/components/schemas/ContainerRegistry' - description: OK - summary: Get container registry credentials - tags: - - container-registry - put: - description: Set container registry credentials - operationId: SetContainerRegistry - parameters: - - description: Container Registry server name - in: path - name: server - required: true - schema: - type: string - requestBody: - content: - '*/*': - schema: - $ref: '#/components/schemas/ContainerRegistry' - description: Container Registry credentials to set - required: true - responses: - "201": - content: {} - description: Created - summary: Set container registry credentials - tags: - - container-registry - x-codegen-request-body-name: containerRegistry /env: get: description: List environment variables @@ -2714,23 +2635,6 @@ components: - image - user type: object - ContainerRegistry: - example: - server: server - password: password - username: username - properties: - password: - type: string - server: - type: string - username: - type: string - required: - - password - - server - - username - type: object CreateBuildDTO: example: prebuildId: prebuildId diff --git a/pkg/apiclient/api_container_registry.go b/pkg/apiclient/api_container_registry.go deleted file mode 100644 index fd1a8876ba..0000000000 --- a/pkg/apiclient/api_container_registry.go +++ /dev/null @@ -1,479 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "context" - "io" - "net/http" - "net/url" - "strings" -) - -// ContainerRegistryAPIService ContainerRegistryAPI service -type ContainerRegistryAPIService service - -type ApiGetContainerRegistryRequest struct { - ctx context.Context - ApiService *ContainerRegistryAPIService - server string -} - -func (r ApiGetContainerRegistryRequest) Execute() (*ContainerRegistry, *http.Response, error) { - return r.ApiService.GetContainerRegistryExecute(r) -} - -/* -GetContainerRegistry Get container registry credentials - -Get container registry credentials - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param server Container Registry server name - @return ApiGetContainerRegistryRequest -*/ -func (a *ContainerRegistryAPIService) GetContainerRegistry(ctx context.Context, server string) ApiGetContainerRegistryRequest { - return ApiGetContainerRegistryRequest{ - ApiService: a, - ctx: ctx, - server: server, - } -} - -// Execute executes the request -// -// @return ContainerRegistry -func (a *ContainerRegistryAPIService) GetContainerRegistryExecute(r ApiGetContainerRegistryRequest) (*ContainerRegistry, *http.Response, error) { - var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *ContainerRegistry - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.GetContainerRegistry") - if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/container-registry/{server}" - localVarPath = strings.Replace(localVarPath, "{"+"server"+"}", url.PathEscape(parameterValueToString(r.server, "server")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarReturnValue, localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - return localVarReturnValue, localVarHTTPResponse, nil -} - -type ApiListContainerRegistriesRequest struct { - ctx context.Context - ApiService *ContainerRegistryAPIService -} - -func (r ApiListContainerRegistriesRequest) Execute() ([]ContainerRegistry, *http.Response, error) { - return r.ApiService.ListContainerRegistriesExecute(r) -} - -/* -ListContainerRegistries List container registries - -List container registries - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListContainerRegistriesRequest -*/ -func (a *ContainerRegistryAPIService) ListContainerRegistries(ctx context.Context) ApiListContainerRegistriesRequest { - return ApiListContainerRegistriesRequest{ - ApiService: a, - ctx: ctx, - } -} - -// Execute executes the request -// -// @return []ContainerRegistry -func (a *ContainerRegistryAPIService) ListContainerRegistriesExecute(r ApiListContainerRegistriesRequest) ([]ContainerRegistry, *http.Response, error) { - var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue []ContainerRegistry - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.ListContainerRegistries") - if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/container-registry" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarReturnValue, localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - return localVarReturnValue, localVarHTTPResponse, nil -} - -type ApiRemoveContainerRegistryRequest struct { - ctx context.Context - ApiService *ContainerRegistryAPIService - server string -} - -func (r ApiRemoveContainerRegistryRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveContainerRegistryExecute(r) -} - -/* -RemoveContainerRegistry Remove a container registry credentials - -Remove a container registry credentials - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param server Container Registry server name - @return ApiRemoveContainerRegistryRequest -*/ -func (a *ContainerRegistryAPIService) RemoveContainerRegistry(ctx context.Context, server string) ApiRemoveContainerRegistryRequest { - return ApiRemoveContainerRegistryRequest{ - ApiService: a, - ctx: ctx, - server: server, - } -} - -// Execute executes the request -func (a *ContainerRegistryAPIService) RemoveContainerRegistryExecute(r ApiRemoveContainerRegistryRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.RemoveContainerRegistry") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/container-registry/{server}" - localVarPath = strings.Replace(localVarPath, "{"+"server"+"}", url.PathEscape(parameterValueToString(r.server, "server")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} - -type ApiSetContainerRegistryRequest struct { - ctx context.Context - ApiService *ContainerRegistryAPIService - server string - containerRegistry *ContainerRegistry -} - -// Container Registry credentials to set -func (r ApiSetContainerRegistryRequest) ContainerRegistry(containerRegistry ContainerRegistry) ApiSetContainerRegistryRequest { - r.containerRegistry = &containerRegistry - return r -} - -func (r ApiSetContainerRegistryRequest) Execute() (*http.Response, error) { - return r.ApiService.SetContainerRegistryExecute(r) -} - -/* -SetContainerRegistry Set container registry credentials - -Set container registry credentials - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param server Container Registry server name - @return ApiSetContainerRegistryRequest -*/ -func (a *ContainerRegistryAPIService) SetContainerRegistry(ctx context.Context, server string) ApiSetContainerRegistryRequest { - return ApiSetContainerRegistryRequest{ - ApiService: a, - ctx: ctx, - server: server, - } -} - -// Execute executes the request -func (a *ContainerRegistryAPIService) SetContainerRegistryExecute(r ApiSetContainerRegistryRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodPut - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.SetContainerRegistry") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/container-registry/{server}" - localVarPath = strings.Replace(localVarPath, "{"+"server"+"}", url.PathEscape(parameterValueToString(r.server, "server")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - if r.containerRegistry == nil { - return nil, reportError("containerRegistry is required and must be specified") - } - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - // body params - localVarPostBody = r.containerRegistry - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index fccca57914..58d913f356 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -52,8 +52,6 @@ type APIClient struct { BuildAPI *BuildAPIService - ContainerRegistryAPI *ContainerRegistryAPIService - DefaultAPI *DefaultAPIService EnvVarAPI *EnvVarAPIService @@ -99,7 +97,6 @@ func NewAPIClient(cfg *Configuration) *APIClient { // API Services c.ApiKeyAPI = (*ApiKeyAPIService)(&c.common) c.BuildAPI = (*BuildAPIService)(&c.common) - c.ContainerRegistryAPI = (*ContainerRegistryAPIService)(&c.common) c.DefaultAPI = (*DefaultAPIService)(&c.common) c.EnvVarAPI = (*EnvVarAPIService)(&c.common) c.GitProviderAPI = (*GitProviderAPIService)(&c.common) diff --git a/pkg/apiclient/docs/ContainerRegistry.md b/pkg/apiclient/docs/ContainerRegistry.md deleted file mode 100644 index 01a8520448..0000000000 --- a/pkg/apiclient/docs/ContainerRegistry.md +++ /dev/null @@ -1,93 +0,0 @@ -# ContainerRegistry - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**Password** | **string** | | -**Server** | **string** | | -**Username** | **string** | | - -## Methods - -### NewContainerRegistry - -`func NewContainerRegistry(password string, server string, username string, ) *ContainerRegistry` - -NewContainerRegistry instantiates a new ContainerRegistry object -This constructor will assign default values to properties that have it defined, -and makes sure properties required by API are set, but the set of arguments -will change when the set of required properties is changed - -### NewContainerRegistryWithDefaults - -`func NewContainerRegistryWithDefaults() *ContainerRegistry` - -NewContainerRegistryWithDefaults instantiates a new ContainerRegistry object -This constructor will only assign default values to properties that have it defined, -but it doesn't guarantee that properties required by API are set - -### GetPassword - -`func (o *ContainerRegistry) GetPassword() string` - -GetPassword returns the Password field if non-nil, zero value otherwise. - -### GetPasswordOk - -`func (o *ContainerRegistry) GetPasswordOk() (*string, bool)` - -GetPasswordOk returns a tuple with the Password field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetPassword - -`func (o *ContainerRegistry) SetPassword(v string)` - -SetPassword sets Password field to given value. - - -### GetServer - -`func (o *ContainerRegistry) GetServer() string` - -GetServer returns the Server field if non-nil, zero value otherwise. - -### GetServerOk - -`func (o *ContainerRegistry) GetServerOk() (*string, bool)` - -GetServerOk returns a tuple with the Server field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetServer - -`func (o *ContainerRegistry) SetServer(v string)` - -SetServer sets Server field to given value. - - -### GetUsername - -`func (o *ContainerRegistry) GetUsername() string` - -GetUsername returns the Username field if non-nil, zero value otherwise. - -### GetUsernameOk - -`func (o *ContainerRegistry) GetUsernameOk() (*string, bool)` - -GetUsernameOk returns a tuple with the Username field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetUsername - -`func (o *ContainerRegistry) SetUsername(v string)` - -SetUsername sets Username field to given value. - - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/docs/ContainerRegistryAPI.md b/pkg/apiclient/docs/ContainerRegistryAPI.md deleted file mode 100644 index fe3c0dcbd1..0000000000 --- a/pkg/apiclient/docs/ContainerRegistryAPI.md +++ /dev/null @@ -1,281 +0,0 @@ -# \ContainerRegistryAPI - -All URIs are relative to *http://localhost:3986* - -Method | HTTP request | Description -------------- | ------------- | ------------- -[**GetContainerRegistry**](ContainerRegistryAPI.md#GetContainerRegistry) | **Get** /container-registry/{server} | Get container registry credentials -[**ListContainerRegistries**](ContainerRegistryAPI.md#ListContainerRegistries) | **Get** /container-registry | List container registries -[**RemoveContainerRegistry**](ContainerRegistryAPI.md#RemoveContainerRegistry) | **Delete** /container-registry/{server} | Remove a container registry credentials -[**SetContainerRegistry**](ContainerRegistryAPI.md#SetContainerRegistry) | **Put** /container-registry/{server} | Set container registry credentials - - - -## GetContainerRegistry - -> ContainerRegistry GetContainerRegistry(ctx, server).Execute() - -Get container registry credentials - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - server := "server_example" // string | Container Registry server name - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ContainerRegistryAPI.GetContainerRegistry(context.Background(), server).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.GetContainerRegistry``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } - // response from `GetContainerRegistry`: ContainerRegistry - fmt.Fprintf(os.Stdout, "Response from `ContainerRegistryAPI.GetContainerRegistry`: %v\n", resp) -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**server** | **string** | Container Registry server name | - -### Other Parameters - -Other parameters are passed through a pointer to a apiGetContainerRegistryRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - -### Return type - -[**ContainerRegistry**](ContainerRegistry.md) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: application/json - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## ListContainerRegistries - -> []ContainerRegistry ListContainerRegistries(ctx).Execute() - -List container registries - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ContainerRegistryAPI.ListContainerRegistries(context.Background()).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.ListContainerRegistries``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } - // response from `ListContainerRegistries`: []ContainerRegistry - fmt.Fprintf(os.Stdout, "Response from `ContainerRegistryAPI.ListContainerRegistries`: %v\n", resp) -} -``` - -### Path Parameters - -This endpoint does not need any parameter. - -### Other Parameters - -Other parameters are passed through a pointer to a apiListContainerRegistriesRequest struct via the builder pattern - - -### Return type - -[**[]ContainerRegistry**](ContainerRegistry.md) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: application/json - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## RemoveContainerRegistry - -> RemoveContainerRegistry(ctx, server).Execute() - -Remove a container registry credentials - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - server := "server_example" // string | Container Registry server name - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ContainerRegistryAPI.RemoveContainerRegistry(context.Background(), server).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.RemoveContainerRegistry``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**server** | **string** | Container Registry server name | - -### Other Parameters - -Other parameters are passed through a pointer to a apiRemoveContainerRegistryRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## SetContainerRegistry - -> SetContainerRegistry(ctx, server).ContainerRegistry(containerRegistry).Execute() - -Set container registry credentials - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - server := "server_example" // string | Container Registry server name - containerRegistry := *openapiclient.NewContainerRegistry("Password_example", "Server_example", "Username_example") // ContainerRegistry | Container Registry credentials to set - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ContainerRegistryAPI.SetContainerRegistry(context.Background(), server).ContainerRegistry(containerRegistry).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.SetContainerRegistry``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**server** | **string** | Container Registry server name | - -### Other Parameters - -Other parameters are passed through a pointer to a apiSetContainerRegistryRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - **containerRegistry** | [**ContainerRegistry**](ContainerRegistry.md) | Container Registry credentials to set | - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - diff --git a/pkg/apiclient/model_container_registry.go b/pkg/apiclient/model_container_registry.go deleted file mode 100644 index dbe38007b7..0000000000 --- a/pkg/apiclient/model_container_registry.go +++ /dev/null @@ -1,212 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "encoding/json" - "fmt" -) - -// checks if the ContainerRegistry type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ContainerRegistry{} - -// ContainerRegistry struct for ContainerRegistry -type ContainerRegistry struct { - Password string `json:"password"` - Server string `json:"server"` - Username string `json:"username"` -} - -type _ContainerRegistry ContainerRegistry - -// NewContainerRegistry instantiates a new ContainerRegistry object -// This constructor will assign default values to properties that have it defined, -// and makes sure properties required by API are set, but the set of arguments -// will change when the set of required properties is changed -func NewContainerRegistry(password string, server string, username string) *ContainerRegistry { - this := ContainerRegistry{} - this.Password = password - this.Server = server - this.Username = username - return &this -} - -// NewContainerRegistryWithDefaults instantiates a new ContainerRegistry object -// This constructor will only assign default values to properties that have it defined, -// but it doesn't guarantee that properties required by API are set -func NewContainerRegistryWithDefaults() *ContainerRegistry { - this := ContainerRegistry{} - return &this -} - -// GetPassword returns the Password field value -func (o *ContainerRegistry) GetPassword() string { - if o == nil { - var ret string - return ret - } - - return o.Password -} - -// GetPasswordOk returns a tuple with the Password field value -// and a boolean to check if the value has been set. -func (o *ContainerRegistry) GetPasswordOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Password, true -} - -// SetPassword sets field value -func (o *ContainerRegistry) SetPassword(v string) { - o.Password = v -} - -// GetServer returns the Server field value -func (o *ContainerRegistry) GetServer() string { - if o == nil { - var ret string - return ret - } - - return o.Server -} - -// GetServerOk returns a tuple with the Server field value -// and a boolean to check if the value has been set. -func (o *ContainerRegistry) GetServerOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Server, true -} - -// SetServer sets field value -func (o *ContainerRegistry) SetServer(v string) { - o.Server = v -} - -// GetUsername returns the Username field value -func (o *ContainerRegistry) GetUsername() string { - if o == nil { - var ret string - return ret - } - - return o.Username -} - -// GetUsernameOk returns a tuple with the Username field value -// and a boolean to check if the value has been set. -func (o *ContainerRegistry) GetUsernameOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Username, true -} - -// SetUsername sets field value -func (o *ContainerRegistry) SetUsername(v string) { - o.Username = v -} - -func (o ContainerRegistry) MarshalJSON() ([]byte, error) { - toSerialize, err := o.ToMap() - if err != nil { - return []byte{}, err - } - return json.Marshal(toSerialize) -} - -func (o ContainerRegistry) ToMap() (map[string]interface{}, error) { - toSerialize := map[string]interface{}{} - toSerialize["password"] = o.Password - toSerialize["server"] = o.Server - toSerialize["username"] = o.Username - return toSerialize, nil -} - -func (o *ContainerRegistry) UnmarshalJSON(data []byte) (err error) { - // This validates that all required properties are included in the JSON object - // by unmarshalling the object into a generic map with string keys and checking - // that every required field exists as a key in the generic map. - requiredProperties := []string{ - "password", - "server", - "username", - } - - allProperties := make(map[string]interface{}) - - err = json.Unmarshal(data, &allProperties) - - if err != nil { - return err - } - - for _, requiredProperty := range requiredProperties { - if _, exists := allProperties[requiredProperty]; !exists { - return fmt.Errorf("no value given for required property %v", requiredProperty) - } - } - - varContainerRegistry := _ContainerRegistry{} - - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(&varContainerRegistry) - - if err != nil { - return err - } - - *o = ContainerRegistry(varContainerRegistry) - - return err -} - -type NullableContainerRegistry struct { - value *ContainerRegistry - isSet bool -} - -func (v NullableContainerRegistry) Get() *ContainerRegistry { - return v.value -} - -func (v *NullableContainerRegistry) Set(val *ContainerRegistry) { - v.value = val - v.isSet = true -} - -func (v NullableContainerRegistry) IsSet() bool { - return v.isSet -} - -func (v *NullableContainerRegistry) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableContainerRegistry(val *ContainerRegistry) *NullableContainerRegistry { - return &NullableContainerRegistry{value: val, isSet: true} -} - -func (v NullableContainerRegistry) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableContainerRegistry) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index 07d2315feb..7eedfcb040 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -8,9 +8,7 @@ import ( "errors" "fmt" - "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/views" @@ -75,11 +73,6 @@ var buildRunCmd = &cobra.Command{ func CreateBuild(apiClient *apiclient.APIClient, workspaceTemplate *apiclient.WorkspaceTemplate, branch string, prebuildId *string) (string, error) { ctx := context.Background() - envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() - if err != nil { - return "", apiclient_util.HandleErrorResponse(res, err) - } - if workspaceTemplate.BuildConfig == nil { return "", errors.New("the chosen workspace template does not have a build configuration") } @@ -90,12 +83,6 @@ func CreateBuild(apiClient *apiclient.APIClient, workspaceTemplate *apiclient.Wo PrebuildId: prebuildId, } - if envVars != nil { - createBuildDto.EnvVars = util.MergeEnvVars(conversion.ToEnvVarsMap(envVars), workspaceTemplate.EnvVars) - } else { - createBuildDto.EnvVars = util.MergeEnvVars(workspaceTemplate.EnvVars) - } - buildId, res, err := apiClient.BuildAPI.CreateBuild(ctx).CreateBuildDto(createBuildDto).Execute() if err != nil { return "", apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index bcbb5fd13a..ccd3d38314 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -17,7 +17,6 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/apikey" . "github.com/daytonaio/daytona/pkg/cmd/autocomplete" . "github.com/daytonaio/daytona/pkg/cmd/build" - . "github.com/daytonaio/daytona/pkg/cmd/containerregistry" . "github.com/daytonaio/daytona/pkg/cmd/env" . "github.com/daytonaio/daytona/pkg/cmd/gitprovider" . "github.com/daytonaio/daytona/pkg/cmd/ports" @@ -65,7 +64,6 @@ func Execute() error { rootCmd.AddCommand(DaemonServeCmd) rootCmd.AddCommand(ServerCmd) rootCmd.AddCommand(ApiKeyCmd) - rootCmd.AddCommand(ContainerRegistryCmd) rootCmd.AddCommand(ProviderCmd) rootCmd.AddCommand(TargetConfigCmd) rootCmd.AddCommand(configCmd) diff --git a/pkg/cmd/containerregistry/containerregistry.go b/pkg/cmd/containerregistry/containerregistry.go deleted file mode 100644 index 32241ee0c7..0000000000 --- a/pkg/cmd/containerregistry/containerregistry.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var ContainerRegistryCmd = &cobra.Command{ - Use: "container-registry", - Aliases: []string{"container-registries", "cr"}, - Short: "Manage container registries", - GroupID: util.SERVER_GROUP, -} - -func init() { - ContainerRegistryCmd.AddCommand(containerRegistryListCmd) - ContainerRegistryCmd.AddCommand(containerRegistrySetCmd) - ContainerRegistryCmd.AddCommand(containerRegistryDeleteCmd) -} diff --git a/pkg/cmd/containerregistry/delete.go b/pkg/cmd/containerregistry/delete.go deleted file mode 100644 index 3dd952cd8d..0000000000 --- a/pkg/cmd/containerregistry/delete.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "context" - "net/url" - - "github.com/daytonaio/daytona/cmd/daytona/config" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/views" - containerregistry_view "github.com/daytonaio/daytona/pkg/views/containerregistry" - views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/spf13/cobra" -) - -var containerRegistryDeleteCmd = &cobra.Command{ - Use: "delete", - Aliases: []string{"remove", "rm"}, - Short: "Delete a container registry", - Args: cobra.RangeArgs(0, 2), - RunE: func(cmd *cobra.Command, args []string) error { - var registryDto *apiclient.ContainerRegistry - var selectedServer string - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - if len(args) == 0 { - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - containerRegistries, res, err := apiClient.ContainerRegistryAPI.ListContainerRegistries(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if len(containerRegistries) == 0 { - views_util.NotifyEmptyContainerRegistryList(false) - return nil - } - - registryDto, err = containerregistry_view.GetRegistryFromPrompt(containerRegistries, activeProfile.Name, false) - if err != nil { - if common.IsCtrlCAbort(err) { - return nil - } else { - return err - } - } - - selectedServer = registryDto.Server - } else { - selectedServer = args[0] - } - - res, err := apiClient.ContainerRegistryAPI.RemoveContainerRegistry(context.Background(), url.QueryEscape(selectedServer)).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - views.RenderInfoMessage("Container registry deleted successfully") - return nil - }, -} diff --git a/pkg/cmd/containerregistry/list.go b/pkg/cmd/containerregistry/list.go deleted file mode 100644 index c54710f460..0000000000 --- a/pkg/cmd/containerregistry/list.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "context" - - "github.com/daytonaio/daytona/internal/util/apiclient" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/format" - containerregistry_view "github.com/daytonaio/daytona/pkg/views/containerregistry/list" - "github.com/spf13/cobra" -) - -var containerRegistryListCmd = &cobra.Command{ - Use: "list", - Short: "Lists container registries", - Aliases: []string{"ls"}, - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - containerRegistries, res, err := apiClient.ContainerRegistryAPI.ListContainerRegistries(context.Background()).Execute() - if err != nil { - return apiclient.HandleErrorResponse(res, err) - } - - if format.FormatFlag != "" { - formattedData := format.NewFormatter(containerRegistries) - formattedData.Print() - return nil - } - - containerregistry_view.ListRegistries(containerRegistries) - return nil - }, -} - -func init() { - format.RegisterFormatFlag(containerRegistryListCmd) -} diff --git a/pkg/cmd/containerregistry/set.go b/pkg/cmd/containerregistry/set.go deleted file mode 100644 index aa81686be6..0000000000 --- a/pkg/cmd/containerregistry/set.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "context" - "net/url" - - "github.com/daytonaio/daytona/cmd/daytona/config" - apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/views" - containerregistry_view "github.com/daytonaio/daytona/pkg/views/containerregistry" - "github.com/spf13/cobra" -) - -var containerRegistrySetCmd = &cobra.Command{ - Use: "set", - Short: "Set container registry", - Args: cobra.NoArgs, - Aliases: []string{"add", "update", "register"}, - RunE: func(cmd *cobra.Command, args []string) error { - var registryDto *apiclient.ContainerRegistry - selectedServer := serverFlag - - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - registryView := containerregistry_view.RegistryView{ - Server: serverFlag, - Username: usernameFlag, - Password: passwordFlag, - } - - apiClient, err := apiclient_util.GetApiClient(nil) - if err != nil { - return err - } - - containerRegistries, res, err := apiClient.ContainerRegistryAPI.ListContainerRegistries(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if serverFlag == "" || usernameFlag == "" || passwordFlag == "" { - if len(containerRegistries) == 0 { - containerregistry_view.RegistryCreationView(®istryView, containerRegistries, false) - selectedServer = registryView.Server - } else { - registryDto, err := containerregistry_view.GetRegistryFromPrompt(containerRegistries, activeProfile.Name, true) - if err != nil { - if common.IsCtrlCAbort(err) { - return nil - } else { - return err - } - } - - editing := true - selectedServer = registryDto.Server - - if registryDto.Server == containerregistry_view.NewRegistryServerIdentifier { - editing = false - registryView.Server, registryView.Username, registryView.Password = "", "", "" - } else { - registryView.Server = registryDto.Server - registryView.Username = registryDto.Username - registryView.Password = registryDto.Password - } - - containerregistry_view.RegistryCreationView(®istryView, containerRegistries, editing) - } - } - - registryDto = &apiclient.ContainerRegistry{ - Server: registryView.Server, - Username: registryView.Username, - Password: registryView.Password, - } - - res, err = apiClient.ContainerRegistryAPI.SetContainerRegistry(context.Background(), url.QueryEscape(selectedServer)).ContainerRegistry(*registryDto).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - views.RenderInfoMessage("Registry set successfully") - return nil - }, -} - -var serverFlag string -var usernameFlag string -var passwordFlag string - -func init() { - containerRegistrySetCmd.Flags().StringVarP(&serverFlag, "server", "s", "", "Server") - containerRegistrySetCmd.Flags().StringVarP(&usernameFlag, "username", "u", "", "Username") - containerRegistrySetCmd.Flags().StringVarP(&passwordFlag, "password", "p", "", "Password") -} diff --git a/pkg/cmd/env/list.go b/pkg/cmd/env/list.go index 2743c31557..1ff06b849c 100644 --- a/pkg/cmd/env/list.go +++ b/pkg/cmd/env/list.go @@ -13,6 +13,8 @@ import ( "github.com/spf13/cobra" ) +var showValuesFlag bool + var listCmd = &cobra.Command{ Use: "list", Short: "List server environment variables", @@ -29,10 +31,17 @@ var listCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } + if !showValuesFlag { + for i := range envVars { + envVars[i].Value = "****************" + } + } + if format.FormatFlag != "" { if envVars == nil { envVars = []apiclient.EnvironmentVariable{} } + formattedData := format.NewFormatter(envVars) formattedData.Print() return nil @@ -45,4 +54,6 @@ var listCmd = &cobra.Command{ func init() { format.RegisterFormatFlag(listCmd) + + listCmd.Flags().BoolVarP(&showValuesFlag, "show-values", "v", false, "Show environment variable values") } diff --git a/pkg/cmd/env/set.go b/pkg/cmd/env/set.go index 50a5332570..a890ec625c 100644 --- a/pkg/cmd/env/set.go +++ b/pkg/cmd/env/set.go @@ -32,7 +32,7 @@ var setCmd = &cobra.Command{ envVarsMap[kv[0]] = kv[1] } } else { - err := env.AddEnvVarsView(&envVarsMap) + err := env.SetEnvVarsView(&envVarsMap) if err != nil { return err } diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go index 5e024f2b56..69d1a94bee 100644 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -67,7 +67,7 @@ func GetJobRunner(c *server.Config, configDir string, version string, telemetryS } func GetWorkspaceJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (workspace.IWorkspaceJobFactory, error) { - containerRegistryService := server.GetInstance(nil).ContainerRegistryService + envVarService := server.GetInstance(nil).EnvironmentVariableService gitProviderService := server.GetInstance(nil).GitProviderService @@ -106,12 +106,20 @@ func GetWorkspaceJobFactory(c *server.Config, configDir string, version string, } return &targetDto.Target, nil }, - FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { - return containerRegistryService.Find(image) + FindContainerRegistry: func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry { + return services.EnvironmentVariables(envVars).FindContainerRegistryByImageName(image) }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { return gitProviderService.GetConfig(id) }, + GetWorkspaceEnvironmentVariables: func(ctx context.Context, w *models.Workspace) (map[string]string, error) { + serverEnvVars, err := envVarService.Map() + if err != nil { + return nil, err + } + + return util.MergeEnvVars(serverEnvVars, w.EnvVars), nil + }, TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { return telemetryService.TrackServerEvent(event, clientId, props) }, @@ -177,13 +185,6 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele buildService := server.GetInstance(nil).BuildService - containerRegistryService := server.GetInstance(nil).ContainerRegistryService - - cr, err := containerRegistryService.FindByImageName(c.BuilderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return nil, err - } - buildImageNamespace := c.BuildImageNamespace if buildImageNamespace != "" { buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) @@ -192,15 +193,19 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele var builderRegistry *models.ContainerRegistry - if c.BuilderRegistryServer != "local" { - builderRegistry, err = containerRegistryService.Find(c.BuilderRegistryServer) - if err != nil { - builderRegistry = &models.ContainerRegistry{ - Server: c.BuilderRegistryServer, - } + envVarService := server.GetInstance(nil).EnvironmentVariableService + + envVars, err := envVarService.Map() + if err != nil { + builderRegistry = &models.ContainerRegistry{ + Server: c.BuilderRegistryServer, } + } else { + builderRegistry = envVars.FindContainerRegistry(c.BuilderRegistryServer) } + cr := envVars.FindContainerRegistryByImageName(c.BuilderImage) + return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { return buildService.Find(&services.BuildFilter{ diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index 7d89a5c428..df82e39457 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -23,7 +23,6 @@ import ( "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/server/builds" - "github.com/daytonaio/daytona/pkg/server/containerregistries" "github.com/daytonaio/daytona/pkg/server/env" "github.com/daytonaio/daytona/pkg/server/gitproviders" "github.com/daytonaio/daytona/pkg/server/headscale" @@ -62,10 +61,6 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - containerRegistryStore, err := db.NewContainerRegistryStore(dbConnection) - if err != nil { - return nil, err - } buildStore, err := db.NewBuildStore(dbConnection) if err != nil { return nil, err @@ -122,10 +117,6 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return nil, err } - containerRegistryService := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ - Store: containerRegistryStore, - }) - gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ ConfigStore: gitProviderConfigStore, DetachWorkspaceTemplates: func(ctx context.Context, gitProviderConfigId string) error { @@ -264,10 +255,11 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe var localContainerRegistry server.ILocalContainerRegistry if c.BuilderRegistryServer != "local" { - _, err := containerRegistryService.Find(c.BuilderRegistryServer) - if err != nil { + envVarService := server.GetInstance(nil).EnvironmentVariableService + envVars, err := envVarService.Map() + if err != nil || envVars.FindContainerRegistry(c.BuilderRegistryServer) == nil { log.Errorf("Failed to find container registry credentials for builder registry server %s\n", c.BuilderRegistryServer) - log.Errorf("Defaulting to local container registry. To use %s as the builder registry, add credentials for the registry server with 'daytona container-registry set' and restart the server\n", c.BuilderRegistryServer) + log.Errorf("Defaulting to local container registry. To use %s as the builder registry, add credentials for the registry server by adding them as environment variables using `daytona env set` and restart the server\n", c.BuilderRegistryServer) c.BuilderRegistryServer = "local" } } @@ -336,8 +328,8 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe } return &t.Target, nil }, - FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { - return containerRegistryService.FindByImageName(image) + FindContainerRegistry: func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry { + return services.EnvironmentVariables(envVars).FindContainerRegistryByImageName(image) }, FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { validStates := []models.ResourceStateName{ @@ -409,7 +401,6 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe Version: version, TailscaleServer: headscaleServer, TargetConfigService: targetConfigService, - ContainerRegistryService: containerRegistryService, BuildService: buildService, WorkspaceTemplateService: workspaceTemplateService, WorkspaceService: workspaceService, diff --git a/pkg/cmd/server/configure.go b/pkg/cmd/server/configure.go index 17be48ed01..f568aee630 100644 --- a/pkg/cmd/server/configure.go +++ b/pkg/cmd/server/configure.go @@ -26,12 +26,7 @@ var configureCmd = &cobra.Command{ return apiclient.HandleErrorResponse(res, err) } - containerRegistries, res, err := apiClient.ContainerRegistryAPI.ListContainerRegistries(context.Background()).Execute() - if err != nil { - return apiclient.HandleErrorResponse(res, err) - } - - apiServerConfig, err = server_view.ConfigurationForm(apiServerConfig, containerRegistries) + apiServerConfig, err = server_view.ConfigurationForm(apiServerConfig) if err != nil { return err } diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go index 186e6f6928..131c11c9e5 100644 --- a/pkg/cmd/target/target.go +++ b/pkg/cmd/target/target.go @@ -10,7 +10,7 @@ import ( var TargetCmd = &cobra.Command{ Use: "target", - Aliases: []string{"targets"}, + Aliases: []string{"targets", "tg"}, Short: "Manage targets", GroupID: util.TARGET_GROUP, } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 96c9ef40bf..a09285a54e 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -14,7 +14,6 @@ import ( "github.com/daytonaio/daytona/internal/cmd/tailscale" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" @@ -58,11 +57,6 @@ var CreateCmd = &cobra.Command{ return err } - envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - target, createTargetDto, err := GetTarget(ctx, GetTargetConfigParams{ ApiClient: apiClient, ActiveProfileName: activeProfile.Name, @@ -121,11 +115,6 @@ var CreateCmd = &cobra.Command{ workspaceNames := []string{} for i := range createWorkspaceDtos { - if envVars != nil { - createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(conversion.ToEnvVarsMap(envVars), createWorkspaceDtos[i].EnvVars) - } else { - createWorkspaceDtos[i].EnvVars = util.MergeEnvVars(createWorkspaceDtos[i].EnvVars) - } workspaceNames = append(workspaceNames, createWorkspaceDtos[i].Name) } diff --git a/pkg/db/container_registry_store.go b/pkg/db/container_registry_store.go deleted file mode 100644 index ecca43d387..0000000000 --- a/pkg/db/container_registry_store.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "gorm.io/gorm" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" -) - -type ContainerRegistryStore struct { - db *gorm.DB -} - -func NewContainerRegistryStore(db *gorm.DB) (stores.ContainerRegistryStore, error) { - err := db.AutoMigrate(&models.ContainerRegistry{}) - if err != nil { - return nil, err - } - - return &ContainerRegistryStore{db: db}, nil -} - -func (s *ContainerRegistryStore) List() ([]*models.ContainerRegistry, error) { - containerRegistries := []*models.ContainerRegistry{} - tx := s.db.Find(&containerRegistries) - if tx.Error != nil { - return nil, tx.Error - } - - return containerRegistries, nil -} - -func (s *ContainerRegistryStore) Find(server string) (*models.ContainerRegistry, error) { - containerRegistry := &models.ContainerRegistry{} - tx := s.db.Where("server = ?", server).First(containerRegistry) - if tx.Error != nil { - if IsRecordNotFound(tx.Error) { - return nil, stores.ErrContainerRegistryNotFound - } - return nil, tx.Error - } - - return containerRegistry, nil -} - -func (s *ContainerRegistryStore) Save(cr *models.ContainerRegistry) error { - tx := s.db.Save(cr) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (s *ContainerRegistryStore) Delete(cr *models.ContainerRegistry) error { - tx := s.db.Delete(cr) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return stores.ErrContainerRegistryNotFound - } - - return nil -} diff --git a/pkg/jobs/util/env.go b/pkg/jobs/util/env.go new file mode 100644 index 0000000000..189f843a3b --- /dev/null +++ b/pkg/jobs/util/env.go @@ -0,0 +1,18 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import "strings" + +func ExtractContainerRegistryFromEnvVars(envVars map[string]string) map[string]string { + result := make(map[string]string) + + for k, v := range envVars { + if !strings.HasSuffix(k, "CONTAINER_REGISTRY_SERVER") && !strings.HasSuffix(k, "CONTAINER_REGISTRY_USERNAME") && !strings.HasSuffix(k, "CONTAINER_REGISTRY_PASSWORD") { + result[k] = v + } + } + + return result +} diff --git a/pkg/jobs/workspace/create.go b/pkg/jobs/workspace/create.go index be76ba3f7f..f607e5141a 100644 --- a/pkg/jobs/workspace/create.go +++ b/pkg/jobs/workspace/create.go @@ -7,6 +7,7 @@ import ( "context" "fmt" + "github.com/daytonaio/daytona/pkg/jobs/util" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" @@ -25,15 +26,15 @@ func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) - cr, err := wj.findContainerRegistry(ctx, w.Image) - if err != nil && !stores.IsContainerRegistryNotFound(err) { + workspaceEnvVars, err := wj.getWorkspaceEnvironmentVariables(ctx, w) + if err != nil { return err } + w.EnvVars = workspaceEnvVars - builderCr, err := wj.findContainerRegistry(ctx, wj.builderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return err - } + cr := wj.findContainerRegistry(ctx, w.Image, workspaceEnvVars) + + builderCr := wj.findContainerRegistry(ctx, wj.builderImage, workspaceEnvVars) var gc *models.GitProviderConfig @@ -44,6 +45,8 @@ func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { } } + w.EnvVars = util.ExtractContainerRegistryFromEnvVars(workspaceEnvVars) + err = wj.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ Workspace: w, ContainerRegistry: cr, diff --git a/pkg/jobs/workspace/factory.go b/pkg/jobs/workspace/factory.go index 1453d10f87..b94f0d49e8 100644 --- a/pkg/jobs/workspace/factory.go +++ b/pkg/jobs/workspace/factory.go @@ -22,11 +22,12 @@ type WorkspaceJobFactory struct { } type WorkspaceJobFactoryConfig struct { - FindWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) - FindTarget func(ctx context.Context, targetId string) (*models.Target, error) - FindContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) - FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) - TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + FindWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) + FindTarget func(ctx context.Context, targetId string) (*models.Target, error) + FindContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry + FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + GetWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) + TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error LoggerFactory logs.LoggerFactory Provisioner provisioner.IProvisioner @@ -43,13 +44,14 @@ func (f *WorkspaceJobFactory) Create(job models.Job) jobs.IJob { return &WorkspaceJob{ Job: job, - findWorkspace: f.config.FindWorkspace, - findTarget: f.config.FindTarget, - findContainerRegistry: f.config.FindContainerRegistry, - findGitProviderConfig: f.config.FindGitProviderConfig, - trackTelemetryEvent: f.config.TrackTelemetryEvent, - loggerFactory: f.config.LoggerFactory, - provisioner: f.config.Provisioner, - builderImage: f.config.BuilderImage, + findWorkspace: f.config.FindWorkspace, + findTarget: f.config.FindTarget, + findContainerRegistry: f.config.FindContainerRegistry, + findGitProviderConfig: f.config.FindGitProviderConfig, + getWorkspaceEnvironmentVariables: f.config.GetWorkspaceEnvironmentVariables, + trackTelemetryEvent: f.config.TrackTelemetryEvent, + loggerFactory: f.config.LoggerFactory, + provisioner: f.config.Provisioner, + builderImage: f.config.BuilderImage, } } diff --git a/pkg/jobs/workspace/start.go b/pkg/jobs/workspace/start.go index 90040c1730..438332812c 100644 --- a/pkg/jobs/workspace/start.go +++ b/pkg/jobs/workspace/start.go @@ -7,6 +7,7 @@ import ( "context" "fmt" + "github.com/daytonaio/daytona/pkg/jobs/util" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" @@ -25,15 +26,15 @@ func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { workspaceLogger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) - cr, err := wj.findContainerRegistry(ctx, w.Image) - if err != nil && !stores.IsContainerRegistryNotFound(err) { + workspaceEnvVars, err := wj.getWorkspaceEnvironmentVariables(ctx, w) + if err != nil { return err } + w.EnvVars = workspaceEnvVars - builderCr, err := wj.findContainerRegistry(ctx, wj.builderImage) - if err != nil && !stores.IsContainerRegistryNotFound(err) { - return err - } + cr := wj.findContainerRegistry(ctx, w.Image, workspaceEnvVars) + + builderCr := wj.findContainerRegistry(ctx, wj.builderImage, workspaceEnvVars) var gc *models.GitProviderConfig @@ -44,6 +45,8 @@ func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { } } + w.EnvVars = util.ExtractContainerRegistryFromEnvVars(workspaceEnvVars) + err = wj.provisioner.StartWorkspace(provisioner.WorkspaceParams{ Workspace: w, ContainerRegistry: cr, diff --git a/pkg/jobs/workspace/workspace.go b/pkg/jobs/workspace/workspace.go index 126e746278..70d85618a9 100644 --- a/pkg/jobs/workspace/workspace.go +++ b/pkg/jobs/workspace/workspace.go @@ -16,11 +16,12 @@ import ( type WorkspaceJob struct { models.Job - findWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) - findTarget func(ctx context.Context, targetId string) (*models.Target, error) - findContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) - findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) - trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + findWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) + findTarget func(ctx context.Context, targetId string) (*models.Target, error) + findContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry + findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + getWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) + trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error loggerFactory logs.LoggerFactory provisioner provisioner.IProvisioner diff --git a/pkg/server/containerregistries/service.go b/pkg/server/containerregistries/service.go deleted file mode 100644 index 95f2e7b149..0000000000 --- a/pkg/server/containerregistries/service.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistries - -import ( - "strings" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" -) - -type ContainerRegistryServiceConfig struct { - Store stores.ContainerRegistryStore -} - -type ContainerRegistryService struct { - store stores.ContainerRegistryStore -} - -func NewContainerRegistryService(config ContainerRegistryServiceConfig) services.IContainerRegistryService { - return &ContainerRegistryService{ - store: config.Store, - } -} - -func (s *ContainerRegistryService) List() ([]*models.ContainerRegistry, error) { - return s.store.List() -} - -func (s *ContainerRegistryService) Map() (map[string]*models.ContainerRegistry, error) { - list, err := s.store.List() - if err != nil { - return nil, err - } - - crs := make(map[string]*models.ContainerRegistry) - for _, cr := range list { - crs[cr.Server] = cr - } - - return crs, nil -} - -func (s *ContainerRegistryService) Find(server string) (*models.ContainerRegistry, error) { - return s.store.Find(server) -} - -func (s *ContainerRegistryService) FindByImageName(imageName string) (*models.ContainerRegistry, error) { - server := getImageServer(imageName) - - return s.Find(server) -} - -func (s *ContainerRegistryService) Save(cr *models.ContainerRegistry) error { - return s.store.Save(cr) -} - -func (s *ContainerRegistryService) Delete(server string) error { - cr, err := s.Find(server) - if err != nil { - return err - } - return s.store.Delete(cr) -} - -func getImageServer(imageName string) string { - parts := strings.Split(imageName, "/") - - if len(parts) < 3 { - return "docker.io" - } - - return parts[0] -} diff --git a/pkg/server/containerregistries/service_test.go b/pkg/server/containerregistries/service_test.go deleted file mode 100644 index bbd2793587..0000000000 --- a/pkg/server/containerregistries/service_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistries_test - -import ( - "testing" - - t_containerregistries "github.com/daytonaio/daytona/internal/testing/server/containerregistries" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server/containerregistries" - "github.com/stretchr/testify/require" -) - -func TestContainerRegistryService(t *testing.T) { - crStore := t_containerregistries.NewInMemoryContainerRegistryStore() - - service := containerregistries.NewContainerRegistryService(containerregistries.ContainerRegistryServiceConfig{ - Store: crStore, - }) - - t.Run("CreateContainerRegistry", func(t *testing.T) { - var crOrg = &models.ContainerRegistry{ - Server: "example.com", - Username: "user", - Password: "password", - } - - err := service.Save(crOrg) - - require.Nil(t, err) - - cr, err := service.Find("example.com") - - require.Nil(t, err) - require.EqualValues(t, crOrg, cr) - }) - - t.Run("FindByImageName", func(t *testing.T) { - var crOrg = &models.ContainerRegistry{ - Server: "example.com", - Username: "user", - Password: "password", - } - - err := service.Save(crOrg) - - require.Nil(t, err) - - cr, err := service.FindByImageName("example.com/image/image") - - require.Nil(t, err) - require.EqualValues(t, crOrg, cr) - }) -} diff --git a/pkg/server/env/service.go b/pkg/server/env/service.go index 84a1b7e62a..bcd8c785d6 100644 --- a/pkg/server/env/service.go +++ b/pkg/server/env/service.go @@ -27,6 +27,20 @@ func (s *EnvironmentVariableService) List() ([]*models.EnvironmentVariable, erro return s.environmentVariableStore.List() } +func (s *EnvironmentVariableService) Map() (services.EnvironmentVariables, error) { + envVars, err := s.List() + if err != nil { + return nil, err + } + + envVarsMap := services.EnvironmentVariables{} + for _, envVar := range envVars { + envVarsMap[envVar.Key] = envVar.Value + } + + return envVarsMap, nil +} + func (s *EnvironmentVariableService) Save(environmentVariable *models.EnvironmentVariable) error { return s.environmentVariableStore.Save(environmentVariable) } diff --git a/pkg/server/server.go b/pkg/server/server.go index 014443bdd0..f00352e55a 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -20,7 +20,6 @@ type ServerInstanceConfig struct { Version string TailscaleServer TailscaleServer TargetConfigService services.ITargetConfigService - ContainerRegistryService services.IContainerRegistryService BuildService services.IBuildService WorkspaceTemplateService services.IWorkspaceTemplateService WorkspaceService services.IWorkspaceService @@ -51,7 +50,6 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { Version: serverConfig.Version, TailscaleServer: serverConfig.TailscaleServer, TargetConfigService: serverConfig.TargetConfigService, - ContainerRegistryService: serverConfig.ContainerRegistryService, BuildService: serverConfig.BuildService, WorkspaceTemplateService: serverConfig.WorkspaceTemplateService, WorkspaceService: serverConfig.WorkspaceService, @@ -75,7 +73,6 @@ type Server struct { Version string TailscaleServer TailscaleServer TargetConfigService services.ITargetConfigService - ContainerRegistryService services.IContainerRegistryService BuildService services.IBuildService WorkspaceTemplateService services.IWorkspaceTemplateService WorkspaceService services.IWorkspaceService diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index 7e16047bca..3d662e6896 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -7,6 +7,7 @@ import ( "context" "regexp" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -44,13 +45,14 @@ func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTar } tg.ApiKey = apiKey - tg.EnvVars = GetTargetEnvVars(tg, TargetEnvVarParams{ + daytonaTargetEnvVars := GetTargetEnvVars(tg, TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), TelemetryEnabled: telemetry.TelemetryEnabled(ctx), }) + tg.EnvVars = util.MergeEnvVars(daytonaTargetEnvVars, tg.EnvVars) err = s.targetStore.Save(tg) if err != nil { diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index 33f07674f4..52ab8eabf3 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -7,7 +7,6 @@ import ( "context" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" ) @@ -29,22 +28,12 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { if defaultTarget != nil { defaultTarget.IsDefault = false - err := s.targetStore.Save(TargetDtoToTarget(*defaultTarget)) + err := s.targetStore.Save(&defaultTarget.Target) if err != nil { return err } } currentTarget.IsDefault = true - return s.targetStore.Save(TargetDtoToTarget(*currentTarget)) -} - -func TargetDtoToTarget(targetDto services.TargetDTO) *models.Target { - return &models.Target{ - Id: targetDto.Id, - Name: targetDto.Name, - TargetConfigId: targetDto.TargetConfigId, - TargetConfig: targetDto.TargetConfig, - IsDefault: targetDto.IsDefault, - } + return s.targetStore.Save(¤tTarget.Target) } diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 7d4a294a9a..307f9e225e 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -81,20 +81,14 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre w.ApiKey = apiKey - workspaceWithEnv := *w - workspaceWithEnv.EnvVars = GetWorkspaceEnvVars(w, WorkspaceEnvVarParams{ + daytonaWorkspaceEnvVars := GetWorkspaceEnvVars(w, WorkspaceEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, ServerVersion: s.serverVersion, ClientId: telemetry.ClientId(ctx), TelemetryEnabled: telemetry.TelemetryEnabled(ctx), }) - - for k, v := range w.EnvVars { - workspaceWithEnv.EnvVars[k] = v - } - - w = &workspaceWithEnv + w.EnvVars = util.MergeEnvVars(daytonaWorkspaceEnvVars, w.EnvVars) err = s.workspaceStore.Save(w) if err != nil { diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index f5b4b03382..ee07cc2638 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -21,7 +21,7 @@ type WorkspaceServiceConfig struct { WorkspaceMetadataStore stores.WorkspaceMetadataStore FindTarget func(ctx context.Context, targetId string) (*models.Target, error) - FindContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) + FindContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry FindCachedBuild func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) GenerateApiKey func(ctx context.Context, name string) (string, error) RevokeApiKey func(ctx context.Context, name string) error @@ -71,7 +71,7 @@ type WorkspaceService struct { workspaceMetadataStore stores.WorkspaceMetadataStore findTarget func(ctx context.Context, targetId string) (*models.Target, error) - findContainerRegistry func(ctx context.Context, image string) (*models.ContainerRegistry, error) + findContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry findCachedBuild func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) generateApiKey func(ctx context.Context, name string) (string, error) revokeApiKey func(ctx context.Context, name string) error diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index aaed9c0fbe..f2685dd682 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -119,8 +119,6 @@ func TestTargetService(t *testing.T) { workspaceStore := t_workspaces.NewInMemoryWorkspaceStore() - containerRegistryService := mocks.NewMockContainerRegistryService() - apiKeyService := mocks.NewMockApiKeyService() gitProviderService := mocks.NewMockGitProviderService() mockProvisioner := mocks.NewMockProvisioner() @@ -136,8 +134,8 @@ func TestTargetService(t *testing.T) { } return t, nil }, - FindContainerRegistry: func(ctx context.Context, image string) (*models.ContainerRegistry, error) { - return containerRegistryService.FindByImageName(image) + FindContainerRegistry: func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry { + return services.EnvironmentVariables(envVars).FindContainerRegistryByImageName(image) }, FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { return nil, nil @@ -172,8 +170,6 @@ func TestTargetService(t *testing.T) { t.Run("CreateWorkspace", func(t *testing.T) { var containerRegistry *models.ContainerRegistry - containerRegistryService.On("FindByImageName", defaultWorkspaceImage).Return(containerRegistry, stores.ErrContainerRegistryNotFound) - gitProviderService.On("GetLastCommitSha", createWorkspaceDTO.Source.Repository).Return("123", nil) apiKeyService.On("Generate", models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) diff --git a/pkg/services/container_registry.go b/pkg/services/container_registry.go deleted file mode 100644 index a6729ea0ad..0000000000 --- a/pkg/services/container_registry.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package services - -import "github.com/daytonaio/daytona/pkg/models" - -type IContainerRegistryService interface { - Delete(server string) error - Find(server string) (*models.ContainerRegistry, error) - FindByImageName(imageName string) (*models.ContainerRegistry, error) - List() ([]*models.ContainerRegistry, error) - Map() (map[string]*models.ContainerRegistry, error) - Save(cr *models.ContainerRegistry) error -} diff --git a/pkg/services/env.go b/pkg/services/env.go index 96aa56ba4b..08becbb7ba 100644 --- a/pkg/services/env.go +++ b/pkg/services/env.go @@ -3,10 +3,44 @@ package services -import "github.com/daytonaio/daytona/pkg/models" +import ( + "strings" + + "github.com/daytonaio/daytona/pkg/models" +) type IEnvironmentVariableService interface { List() ([]*models.EnvironmentVariable, error) + Map() (EnvironmentVariables, error) Save(environmentVariable *models.EnvironmentVariable) error Delete(key string) error } + +type EnvironmentVariables map[string]string + +func (e EnvironmentVariables) FindContainerRegistry(server string) *models.ContainerRegistry { + for key, value := range e { + if strings.HasSuffix(key, "CONTAINER_REGISTRY_SERVER") && value == server { + usernameKey := strings.ReplaceAll(key, "SERVER", "USERNAME") + passwordKey := strings.ReplaceAll(key, "SERVER", "PASSWORD") + + return &models.ContainerRegistry{ + Server: server, + Username: e[usernameKey], + Password: e[passwordKey], + } + } + } + + return nil +} + +func (e EnvironmentVariables) FindContainerRegistryByImageName(image string) *models.ContainerRegistry { + parts := strings.Split(image, "/") + + if len(parts) < 3 { + return e.FindContainerRegistry("docker.io") + } + + return e.FindContainerRegistry(parts[0]) +} diff --git a/pkg/stores/container_registry.go b/pkg/stores/container_registry.go deleted file mode 100644 index 1ed49c158c..0000000000 --- a/pkg/stores/container_registry.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package stores - -import ( - "errors" - - "github.com/daytonaio/daytona/pkg/models" -) - -type ContainerRegistryStore interface { - List() ([]*models.ContainerRegistry, error) - Find(server string) (*models.ContainerRegistry, error) - Save(cr *models.ContainerRegistry) error - Delete(cr *models.ContainerRegistry) error -} - -var ( - ErrContainerRegistryNotFound = errors.New("container registry not found") -) - -func IsContainerRegistryNotFound(err error) bool { - return err.Error() == ErrContainerRegistryNotFound.Error() -} diff --git a/pkg/views/containerregistry/list/view.go b/pkg/views/containerregistry/list/view.go deleted file mode 100644 index 94a39abcc1..0000000000 --- a/pkg/views/containerregistry/list/view.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package list - -import ( - "fmt" - "strings" - - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" - views_util "github.com/daytonaio/daytona/pkg/views/util" -) - -type rowData struct { - Server string - Username string - Password string -} - -func ListRegistries(registryList []apiclient.ContainerRegistry) { - if len(registryList) == 0 { - views_util.NotifyEmptyContainerRegistryList(true) - return - } - - data := [][]string{} - - for _, registry := range registryList { - data = append(data, getRowFromData(registry)) - } - - table := views_util.GetTableView(data, []string{ - "Server", "Username", "Password", - }, nil, func() { - renderUnstyledList(registryList) - }) - - fmt.Println(table) -} - -func getRowFromData(registry apiclient.ContainerRegistry) []string { - var data rowData - - data.Server = registry.Server - data.Username = registry.Username - - row := []string{ - views.NameStyle.Render(data.Server), - views.DefaultRowDataStyle.Render(data.Username), - views.DefaultRowDataStyle.Render(strings.Repeat("*", 10)), - } - - return row -} - -func renderUnstyledList(registryList []apiclient.ContainerRegistry) { - output := "\n" - - for _, registry := range registryList { - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Server: "), registry.Server) + "\n\n" - - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Username: "), registry.Username) + "\n\n" - - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Password: "), registry.Password) + "\n\n" - - if registry.Server != registryList[len(registryList)-1].Server { - output += views.SeparatorString + "\n\n" - } - } - - fmt.Println(output) -} diff --git a/pkg/views/containerregistry/select.go b/pkg/views/containerregistry/select.go deleted file mode 100644 index 914c27087c..0000000000 --- a/pkg/views/containerregistry/select.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/views" -) - -const NewRegistryServerIdentifier = "+ New Container Registry" - -func GetRegistryFromPrompt(registries []apiclient.ContainerRegistry, activeProfileName string, withNewRegistry bool) (*apiclient.ContainerRegistry, error) { - items := util.ArrayMap(registries, func(r apiclient.ContainerRegistry) list.Item { - return item{ - registry: r, - } - }) - - if withNewRegistry { - name := NewRegistryServerIdentifier - emptyString := "" - items = append(items, item{ - registry: apiclient.ContainerRegistry{ - Password: emptyString, - Username: emptyString, - Server: name, - }, - }) - } - - l := views.GetStyledSelectList(items) - m := model{list: l} - m.list.Title = "Choose a container registry" - m.footer = views.GetListFooter(activeProfileName, views.DefaultListFooterPadding) - - p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() - if err != nil { - return nil, err - } - - if m, ok := p.(model); ok && m.choice != nil { - return m.choice, nil - } - - return nil, common.ErrCtrlCAbort -} diff --git a/pkg/views/containerregistry/set.go b/pkg/views/containerregistry/set.go deleted file mode 100644 index 2183a3b2f4..0000000000 --- a/pkg/views/containerregistry/set.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "errors" - "log" - - "github.com/charmbracelet/huh" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" -) - -type RegistryView struct { - Server string - Username string - Password string -} - -func RegistryCreationView(registryView *RegistryView, registries []apiclient.ContainerRegistry, editing bool) { - form := huh.NewForm( - huh.NewGroup( - huh.NewInput(). - Title("Server URL"). - Value(®istryView.Server). - Validate(func(str string) error { - if str == "" { - return errors.New("server URL can not be blank") - } - return nil - }), - huh.NewInput(). - Title("Username"). - Value(®istryView.Username). - Validate(func(str string) error { - if str == "" { - return errors.New("username can not be blank") - } - return nil - }), - huh.NewInput(). - Title("Password"). - EchoMode(huh.EchoModePassword). - Value(®istryView.Password). - Validate(func(str string) error { - if str == "" { - return errors.New("password can not be blank") - } - return nil - }), - ), - ).WithTheme(views.GetCustomTheme()) - - err := form.Run() - if err != nil { - log.Fatal(err) - } - - if err != nil { - log.Fatal(err) - } -} diff --git a/pkg/views/containerregistry/view.go b/pkg/views/containerregistry/view.go deleted file mode 100644 index 24392c00f7..0000000000 --- a/pkg/views/containerregistry/view.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package containerregistry - -import ( - "github.com/charmbracelet/bubbles/list" - tea "github.com/charmbracelet/bubbletea" - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views" -) - -type item struct { - registry apiclient.ContainerRegistry -} - -func (i item) Title() string { return i.registry.Server } -func (i item) Description() string { - if i.registry.Server == NewRegistryServerIdentifier { - return "Add a new container registry" - } - return i.registry.Username -} -func (i item) FilterValue() string { return i.registry.Server } - -type model struct { - list list.Model - choice *apiclient.ContainerRegistry - footer string -} - -func (m model) Init() tea.Cmd { - return nil -} - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyMsg: - switch keypress := msg.String(); keypress { - case "ctrl+c": - return m, tea.Quit - - case "enter": - i, ok := m.list.SelectedItem().(item) - if ok { - m.choice = &i.registry - } - return m, tea.Quit - } - case tea.WindowSizeMsg: - h, v := views.DocStyle.GetFrameSize() - m.list.SetSize(msg.Width-h, msg.Height-v) - } - - var cmd tea.Cmd - m.list, cmd = m.list.Update(msg) - return m, cmd -} - -func (m model) View() string { - return views.DocStyle.Render(m.list.View() + m.footer) -} diff --git a/pkg/views/env/add.go b/pkg/views/env/add.go deleted file mode 100644 index c5064400ef..0000000000 --- a/pkg/views/env/add.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package env - -import ( - "github.com/charmbracelet/huh" - "github.com/daytonaio/daytona/pkg/views" -) - -func AddEnvVarsView(envVarsMap *map[string]string) error { - var addAntoher bool - - var key string - var value string - - form := huh.NewForm( - huh.NewGroup( - huh.NewInput(). - Title("Key"). - Value(&key), - huh.NewInput(). - Title("Value"). - Value(&value), - ), - ).WithTheme(views.GetCustomTheme()).WithHeight(12) - - err := form.Run() - if err != nil { - return err - } - - (*envVarsMap)[key] = value - - form = huh.NewForm( - huh.NewGroup( - huh.NewConfirm(). - Title("Add another environment variable?"). - Value(&addAntoher), - ), - ).WithTheme(views.GetCustomTheme()).WithHeight(12) - - err = form.Run() - if err != nil { - return err - } - - if addAntoher { - return AddEnvVarsView(envVarsMap) - } - - return nil -} diff --git a/pkg/views/env/form/model.go b/pkg/views/env/form/model.go new file mode 100644 index 0000000000..611eadc6dd --- /dev/null +++ b/pkg/views/env/form/model.go @@ -0,0 +1,126 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package form + +import ( + "fmt" + + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/huh" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/views" +) + +const maxWidth = 160 + +var userCancelled bool + +type styles struct { + HeaderText, FooterText lipgloss.Style +} + +func newStyles(lg *lipgloss.Renderer) *styles { + s := styles{} + s.HeaderText = lg.NewStyle(). + Foreground(views.Green). + Bold(true). + Padding(1, 1, 0, 0) + s.FooterText = lg.NewStyle(). + Foreground(views.Gray). + Bold(true). + Padding(1, 1, 0, 0) + return &s +} + +type formModel struct { + lg *lipgloss.Renderer + styles *styles + form *huh.Form + width int + quitting bool + tip string +} + +func NewFormModel(key, value *string) formModel { + m := formModel{width: maxWidth} + m.lg = lipgloss.DefaultRenderer() + m.styles = newStyles(m.lg) + + m.form = huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("Key"). + Value(key). + Validate(func(s string) error { + if s == "" { + return fmt.Errorf("key cannot be empty") + } + return nil + }), + huh.NewInput(). + Title("Value"). + Value(value). + Validate(func(s string) error { + if s == "" { + return fmt.Errorf("key cannot be empty") + } + return nil + }), + ), + ).WithTheme(views.GetCustomTheme()).WithHeight(12) + + m.tip = "\nTip: To set container registry credentials, add the following environment variables:\n <*>_CONTAINER_REGISTRY_SERVER\n <*>_CONTAINER_REGISTRY_USERNAME\n <*>_CONTAINER_REGISTRY_PASSWORD" + + return m +} + +func (m formModel) Init() tea.Cmd { + return m.form.Init() +} + +func (m formModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "ctrl+c": + m.quitting = true + userCancelled = true + return m, tea.Quit + case "f10": + m.quitting = true + m.form.State = huh.StateCompleted + return m, tea.Quit + } + } + + var cmds []tea.Cmd + + // Process the form + form, cmd := m.form.Update(msg) + if f, ok := form.(*huh.Form); ok { + m.form = f + cmds = append(cmds, cmd) + } + + if m.form.State == huh.StateCompleted { + // Quit when the form is done. + m.quitting = true + cmds = append(cmds, tea.Quit) + } + + return m, tea.Batch(cmds...) +} + +func (m formModel) View() string { + if m.quitting { + return "" + } + + view := m.styles.HeaderText.Render("Set server environment variable\n") + m.form.WithHeight(5).View() + m.styles.FooterText.Render(m.tip) + + return view +} +func IsUserCancelled() bool { + return userCancelled +} diff --git a/pkg/views/env/set.go b/pkg/views/env/set.go new file mode 100644 index 0000000000..638770244b --- /dev/null +++ b/pkg/views/env/set.go @@ -0,0 +1,54 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package env + +import ( + "fmt" + + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/env/form" +) + +func SetEnvVarsView(envVarsMap *map[string]string) error { + return runSetEnvVarsForm(envVarsMap) +} + +func runSetEnvVarsForm(envVarsMap *map[string]string) error { + var key, value string + + m := form.NewFormModel(&key, &value) + + if _, err := tea.NewProgram(m, tea.WithAltScreen()).Run(); err != nil { + return err + } + + if form.IsUserCancelled() { + return fmt.Errorf("user cancelled") + } + + (*envVarsMap)[key] = value + + var addAntoher bool + + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Add another environment variable?"). + Value(&addAntoher), + ), + ).WithTheme(views.GetCustomTheme()).WithHeight(6) + + err := form.Run() + if err != nil { + return err + } + + if addAntoher { + return runSetEnvVarsForm(envVarsMap) + } + + return nil +} diff --git a/pkg/views/server/configure.go b/pkg/views/server/configure.go index d382d8309e..d522f52803 100644 --- a/pkg/views/server/configure.go +++ b/pkg/views/server/configure.go @@ -28,7 +28,7 @@ type keymap struct { submit key.Binding } -func NewModel(config *apiclient.ServerConfig, containerRegistries []apiclient.ContainerRegistry) Model { +func NewModel(config *apiclient.ServerConfig) Model { m := Model{ config: config, help: help.New(), @@ -37,23 +37,15 @@ func NewModel(config *apiclient.ServerConfig, containerRegistries []apiclient.Co }, } - m.form = m.createForm(containerRegistries) + m.form = m.createForm() return m } -func (m *Model) createForm(containerRegistries []apiclient.ContainerRegistry) *huh.Form { +func (m *Model) createForm() *huh.Form { apiPortView := strconv.Itoa(int(m.config.GetApiPort())) headscalePortView := strconv.Itoa(int(m.config.GetHeadscalePort())) frpsPortView := strconv.Itoa(int(m.config.Frps.GetPort())) localBuilderRegistryPort := strconv.Itoa(int(m.config.GetLocalBuilderRegistryPort())) - builderContainerRegistryOptions := []huh.Option[string]{{ - Key: "Local registry managed by Daytona", - Value: "local", - }} - for _, cr := range containerRegistries { - builderContainerRegistryOptions = append(builderContainerRegistryOptions, huh.Option[string]{Key: cr.Server, Value: cr.Server}) - } - logFileMaxSize := strconv.Itoa(int(m.config.LogFile.MaxSize)) logFileMaxBackups := strconv.Itoa(int(m.config.LogFile.MaxBackups)) logFileMaxAge := strconv.Itoa(int(m.config.LogFile.MaxAge)) @@ -88,12 +80,9 @@ func (m *Model) createForm(containerRegistries []apiclient.ContainerRegistry) *h Title("Builder Image"). Description("Image dependencies: docker, socat, git, @devcontainers/cli (node package)"). Value(&m.config.BuilderImage), - huh.NewSelect[string](). - Title("Builder Registry"). - Description("To add options, add a container registry with 'daytona cr set'"). - Options( - builderContainerRegistryOptions..., - ). + huh.NewInput(). + Title("Builder Registry Server"). + Description("Add container registry credentials to the server by adding them as environment variables using `daytona env set`"). Value(&m.config.BuilderRegistryServer), huh.NewInput(). Title("Build Image Namespace"). @@ -232,8 +221,8 @@ func (m Model) View() string { return m.form.View() + helpView } -func ConfigurationForm(config *apiclient.ServerConfig, containerRegistries []apiclient.ContainerRegistry) (*apiclient.ServerConfig, error) { - m := NewModel(config, containerRegistries) +func ConfigurationForm(config *apiclient.ServerConfig) (*apiclient.ServerConfig, error) { + m := NewModel(config) p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() From adeac5d8ae187982f97a84a0285b24c05eb09697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 5 Dec 2024 16:45:50 +0100 Subject: [PATCH 25/76] refactor: update gorm decorators (#1420) Signed-off-by: Luka Brecic --- .../controllers/workspace/toolbox/toolbox.go | 2 +- pkg/api/docs/docs.go | 7 ++-- pkg/api/docs/swagger.json | 7 ++-- pkg/api/docs/swagger.yaml | 3 +- pkg/apiclient/api/openapi.yaml | 3 +- pkg/apiclient/docs/PrebuildConfig.md | 9 +++-- pkg/apiclient/docs/Target.md | 9 ++--- pkg/apiclient/docs/TargetDTO.md | 9 ++--- pkg/apiclient/model_prebuild_config.go | 36 +++++++++++-------- pkg/apiclient/model_target.go | 30 ++++++---------- pkg/apiclient/model_target_dto.go | 30 ++++++---------- pkg/cmd/workspace/ssh.go | 4 +-- pkg/ide/positron.go | 4 +-- pkg/ide/vscode-insiders.go | 4 +-- pkg/ide/vscodium-insiders.go | 4 +-- pkg/ide/vscodium.go | 4 +-- pkg/ide/windsurf.go | 4 +-- pkg/models/api_key.go | 4 +-- pkg/models/build.go | 18 +++++----- pkg/models/env.go | 2 +- pkg/models/git_provider_config.go | 8 ++--- pkg/models/job.go | 12 +++---- pkg/models/target.go | 22 ++++++------ pkg/models/target_config.go | 8 ++--- pkg/models/workspace.go | 24 ++++++------- pkg/models/workspace_template.go | 20 +++++------ 26 files changed, 139 insertions(+), 148 deletions(-) diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index 1030de1db6..5f35f4010f 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -61,7 +61,7 @@ func forwardRequestToToolbox(ctx *gin.Context) { var client *http.Client var websocketDialer *websocket.Dialer - workspaceHostname := common.GetWorkspaceHostname(w.Id) + workspaceHostname := common.GetTailscaleHostname(w.Id) route := strings.Replace(ctx.Request.URL.Path, fmt.Sprintf("/workspace/%s/toolbox/", workspaceId), "", 1) query := ctx.Request.URL.Query().Encode() diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 453abfca58..e480188405 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -4470,7 +4470,6 @@ const docTemplate = `{ "type": "object", "required": [ "branch", - "commitInterval", "id", "retention", "triggerFiles" @@ -4875,7 +4874,8 @@ const docTemplate = `{ "id", "name", "targetConfig", - "targetConfigId" + "targetConfigId", + "workspaces" ], "properties": { "default": { @@ -4993,7 +4993,8 @@ const docTemplate = `{ "name", "state", "targetConfig", - "targetConfigId" + "targetConfigId", + "workspaces" ], "properties": { "default": { diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index bd737636e4..421b773f58 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -4467,7 +4467,6 @@ "type": "object", "required": [ "branch", - "commitInterval", "id", "retention", "triggerFiles" @@ -4872,7 +4871,8 @@ "id", "name", "targetConfig", - "targetConfigId" + "targetConfigId", + "workspaces" ], "properties": { "default": { @@ -4990,7 +4990,8 @@ "name", "state", "targetConfig", - "targetConfigId" + "targetConfigId", + "workspaces" ], "properties": { "default": { diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 1f26b06c85..047df1b0c6 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -820,7 +820,6 @@ definitions: type: array required: - branch - - commitInterval - id - retention - triggerFiles @@ -1113,6 +1112,7 @@ definitions: - name - targetConfig - targetConfigId + - workspaces type: object TargetConfig: properties: @@ -1206,6 +1206,7 @@ definitions: - state - targetConfig - targetConfigId + - workspaces type: object TargetInfo: properties: diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 0bed61edc1..b53fd5a159 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -3590,7 +3590,6 @@ components: type: array required: - branch - - commitInterval - id - retention - triggerFiles @@ -4022,6 +4021,7 @@ components: - name - targetConfig - targetConfigId + - workspaces type: object TargetConfig: example: @@ -4329,6 +4329,7 @@ components: - state - targetConfig - targetConfigId + - workspaces type: object TargetInfo: example: diff --git a/pkg/apiclient/docs/PrebuildConfig.md b/pkg/apiclient/docs/PrebuildConfig.md index 9a03b4b8c6..ab084ebe17 100644 --- a/pkg/apiclient/docs/PrebuildConfig.md +++ b/pkg/apiclient/docs/PrebuildConfig.md @@ -5,7 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Branch** | **string** | | -**CommitInterval** | **int32** | | +**CommitInterval** | Pointer to **int32** | | [optional] **Id** | **string** | | **Retention** | **int32** | | **TriggerFiles** | **[]string** | | @@ -14,7 +14,7 @@ Name | Type | Description | Notes ### NewPrebuildConfig -`func NewPrebuildConfig(branch string, commitInterval int32, id string, retention int32, triggerFiles []string, ) *PrebuildConfig` +`func NewPrebuildConfig(branch string, id string, retention int32, triggerFiles []string, ) *PrebuildConfig` NewPrebuildConfig instantiates a new PrebuildConfig object This constructor will assign default values to properties that have it defined, @@ -68,6 +68,11 @@ and a boolean to check if the value has been set. SetCommitInterval sets CommitInterval field to given value. +### HasCommitInterval + +`func (o *PrebuildConfig) HasCommitInterval() bool` + +HasCommitInterval returns a boolean if a field has been set. ### GetId diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index 95d709455d..bd0e3681ff 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -12,13 +12,13 @@ Name | Type | Description | Notes **Name** | **string** | | **TargetConfig** | [**TargetConfig**](TargetConfig.md) | | **TargetConfigId** | **string** | | -**Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] +**Workspaces** | [**[]Workspace**](Workspace.md) | | ## Methods ### NewTarget -`func NewTarget(default_ bool, envVars map[string]string, id string, name string, targetConfig TargetConfig, targetConfigId string, ) *Target` +`func NewTarget(default_ bool, envVars map[string]string, id string, name string, targetConfig TargetConfig, targetConfigId string, workspaces []Workspace, ) *Target` NewTarget instantiates a new Target object This constructor will assign default values to properties that have it defined, @@ -222,11 +222,6 @@ and a boolean to check if the value has been set. SetWorkspaces sets Workspaces field to given value. -### HasWorkspaces - -`func (o *Target) HasWorkspaces() bool` - -HasWorkspaces returns a boolean if a field has been set. [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index 1a094c4b4f..67a9a19eb5 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -14,13 +14,13 @@ Name | Type | Description | Notes **State** | [**ResourceState**](ResourceState.md) | | **TargetConfig** | [**TargetConfig**](TargetConfig.md) | | **TargetConfigId** | **string** | | -**Workspaces** | Pointer to [**[]Workspace**](Workspace.md) | | [optional] +**Workspaces** | [**[]Workspace**](Workspace.md) | | ## Methods ### NewTargetDTO -`func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, state ResourceState, targetConfig TargetConfig, targetConfigId string, ) *TargetDTO` +`func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, state ResourceState, targetConfig TargetConfig, targetConfigId string, workspaces []Workspace, ) *TargetDTO` NewTargetDTO instantiates a new TargetDTO object This constructor will assign default values to properties that have it defined, @@ -269,11 +269,6 @@ and a boolean to check if the value has been set. SetWorkspaces sets Workspaces field to given value. -### HasWorkspaces - -`func (o *TargetDTO) HasWorkspaces() bool` - -HasWorkspaces returns a boolean if a field has been set. [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/model_prebuild_config.go b/pkg/apiclient/model_prebuild_config.go index b018c656bc..b4e3086eed 100644 --- a/pkg/apiclient/model_prebuild_config.go +++ b/pkg/apiclient/model_prebuild_config.go @@ -22,7 +22,7 @@ var _ MappedNullable = &PrebuildConfig{} // PrebuildConfig struct for PrebuildConfig type PrebuildConfig struct { Branch string `json:"branch"` - CommitInterval int32 `json:"commitInterval"` + CommitInterval *int32 `json:"commitInterval,omitempty"` Id string `json:"id"` Retention int32 `json:"retention"` TriggerFiles []string `json:"triggerFiles"` @@ -34,10 +34,9 @@ type _PrebuildConfig PrebuildConfig // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewPrebuildConfig(branch string, commitInterval int32, id string, retention int32, triggerFiles []string) *PrebuildConfig { +func NewPrebuildConfig(branch string, id string, retention int32, triggerFiles []string) *PrebuildConfig { this := PrebuildConfig{} this.Branch = branch - this.CommitInterval = commitInterval this.Id = id this.Retention = retention this.TriggerFiles = triggerFiles @@ -76,28 +75,36 @@ func (o *PrebuildConfig) SetBranch(v string) { o.Branch = v } -// GetCommitInterval returns the CommitInterval field value +// GetCommitInterval returns the CommitInterval field value if set, zero value otherwise. func (o *PrebuildConfig) GetCommitInterval() int32 { - if o == nil { + if o == nil || IsNil(o.CommitInterval) { var ret int32 return ret } - - return o.CommitInterval + return *o.CommitInterval } -// GetCommitIntervalOk returns a tuple with the CommitInterval field value +// GetCommitIntervalOk returns a tuple with the CommitInterval field value if set, nil otherwise // and a boolean to check if the value has been set. func (o *PrebuildConfig) GetCommitIntervalOk() (*int32, bool) { - if o == nil { + if o == nil || IsNil(o.CommitInterval) { return nil, false } - return &o.CommitInterval, true + return o.CommitInterval, true +} + +// HasCommitInterval returns a boolean if a field has been set. +func (o *PrebuildConfig) HasCommitInterval() bool { + if o != nil && !IsNil(o.CommitInterval) { + return true + } + + return false } -// SetCommitInterval sets field value +// SetCommitInterval gets a reference to the given int32 and assigns it to the CommitInterval field. func (o *PrebuildConfig) SetCommitInterval(v int32) { - o.CommitInterval = v + o.CommitInterval = &v } // GetId returns the Id field value @@ -183,7 +190,9 @@ func (o PrebuildConfig) MarshalJSON() ([]byte, error) { func (o PrebuildConfig) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["branch"] = o.Branch - toSerialize["commitInterval"] = o.CommitInterval + if !IsNil(o.CommitInterval) { + toSerialize["commitInterval"] = o.CommitInterval + } toSerialize["id"] = o.Id toSerialize["retention"] = o.Retention toSerialize["triggerFiles"] = o.TriggerFiles @@ -196,7 +205,6 @@ func (o *PrebuildConfig) UnmarshalJSON(data []byte) (err error) { // that every required field exists as a key in the generic map. requiredProperties := []string{ "branch", - "commitInterval", "id", "retention", "triggerFiles", diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index 0b30d56898..f4b43698e7 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -29,7 +29,7 @@ type Target struct { Name string `json:"name"` TargetConfig TargetConfig `json:"targetConfig"` TargetConfigId string `json:"targetConfigId"` - Workspaces []Workspace `json:"workspaces,omitempty"` + Workspaces []Workspace `json:"workspaces"` } type _Target Target @@ -38,7 +38,7 @@ type _Target Target // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTarget(default_ bool, envVars map[string]string, id string, name string, targetConfig TargetConfig, targetConfigId string) *Target { +func NewTarget(default_ bool, envVars map[string]string, id string, name string, targetConfig TargetConfig, targetConfigId string, workspaces []Workspace) *Target { this := Target{} this.Default = default_ this.EnvVars = envVars @@ -46,6 +46,7 @@ func NewTarget(default_ bool, envVars map[string]string, id string, name string, this.Name = name this.TargetConfig = targetConfig this.TargetConfigId = targetConfigId + this.Workspaces = workspaces return &this } @@ -265,34 +266,26 @@ func (o *Target) SetTargetConfigId(v string) { o.TargetConfigId = v } -// GetWorkspaces returns the Workspaces field value if set, zero value otherwise. +// GetWorkspaces returns the Workspaces field value func (o *Target) GetWorkspaces() []Workspace { - if o == nil || IsNil(o.Workspaces) { + if o == nil { var ret []Workspace return ret } + return o.Workspaces } -// GetWorkspacesOk returns a tuple with the Workspaces field value if set, nil otherwise +// GetWorkspacesOk returns a tuple with the Workspaces field value // and a boolean to check if the value has been set. func (o *Target) GetWorkspacesOk() ([]Workspace, bool) { - if o == nil || IsNil(o.Workspaces) { + if o == nil { return nil, false } return o.Workspaces, true } -// HasWorkspaces returns a boolean if a field has been set. -func (o *Target) HasWorkspaces() bool { - if o != nil && !IsNil(o.Workspaces) { - return true - } - - return false -} - -// SetWorkspaces gets a reference to the given []Workspace and assigns it to the Workspaces field. +// SetWorkspaces sets field value func (o *Target) SetWorkspaces(v []Workspace) { o.Workspaces = v } @@ -319,9 +312,7 @@ func (o Target) ToMap() (map[string]interface{}, error) { toSerialize["name"] = o.Name toSerialize["targetConfig"] = o.TargetConfig toSerialize["targetConfigId"] = o.TargetConfigId - if !IsNil(o.Workspaces) { - toSerialize["workspaces"] = o.Workspaces - } + toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -336,6 +327,7 @@ func (o *Target) UnmarshalJSON(data []byte) (err error) { "name", "targetConfig", "targetConfigId", + "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 40c984584e..1594473a28 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -31,7 +31,7 @@ type TargetDTO struct { State ResourceState `json:"state"` TargetConfig TargetConfig `json:"targetConfig"` TargetConfigId string `json:"targetConfigId"` - Workspaces []Workspace `json:"workspaces,omitempty"` + Workspaces []Workspace `json:"workspaces"` } type _TargetDTO TargetDTO @@ -40,7 +40,7 @@ type _TargetDTO TargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, state ResourceState, targetConfig TargetConfig, targetConfigId string) *TargetDTO { +func NewTargetDTO(default_ bool, envVars map[string]string, id string, name string, state ResourceState, targetConfig TargetConfig, targetConfigId string, workspaces []Workspace) *TargetDTO { this := TargetDTO{} this.Default = default_ this.EnvVars = envVars @@ -49,6 +49,7 @@ func NewTargetDTO(default_ bool, envVars map[string]string, id string, name stri this.State = state this.TargetConfig = targetConfig this.TargetConfigId = targetConfigId + this.Workspaces = workspaces return &this } @@ -324,34 +325,26 @@ func (o *TargetDTO) SetTargetConfigId(v string) { o.TargetConfigId = v } -// GetWorkspaces returns the Workspaces field value if set, zero value otherwise. +// GetWorkspaces returns the Workspaces field value func (o *TargetDTO) GetWorkspaces() []Workspace { - if o == nil || IsNil(o.Workspaces) { + if o == nil { var ret []Workspace return ret } + return o.Workspaces } -// GetWorkspacesOk returns a tuple with the Workspaces field value if set, nil otherwise +// GetWorkspacesOk returns a tuple with the Workspaces field value // and a boolean to check if the value has been set. func (o *TargetDTO) GetWorkspacesOk() ([]Workspace, bool) { - if o == nil || IsNil(o.Workspaces) { + if o == nil { return nil, false } return o.Workspaces, true } -// HasWorkspaces returns a boolean if a field has been set. -func (o *TargetDTO) HasWorkspaces() bool { - if o != nil && !IsNil(o.Workspaces) { - return true - } - - return false -} - -// SetWorkspaces gets a reference to the given []Workspace and assigns it to the Workspaces field. +// SetWorkspaces sets field value func (o *TargetDTO) SetWorkspaces(v []Workspace) { o.Workspaces = v } @@ -382,9 +375,7 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["state"] = o.State toSerialize["targetConfig"] = o.TargetConfig toSerialize["targetConfigId"] = o.TargetConfigId - if !IsNil(o.Workspaces) { - toSerialize["workspaces"] = o.Workspaces - } + toSerialize["workspaces"] = o.Workspaces return toSerialize, nil } @@ -400,6 +391,7 @@ func (o *TargetDTO) UnmarshalJSON(data []byte) (err error) { "state", "targetConfig", "targetConfigId", + "workspaces", } allProperties := make(map[string]interface{}) diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index 659e42b53a..b884fc9ccf 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -124,7 +124,7 @@ func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceD return err } - hostLine := fmt.Sprintf("Host %s", config.GetWorkspaceHostname(activeProfile.Id, workspace.Id)) + hostLine := fmt.Sprintf("Host %s", config.GetHostname(activeProfile.Id, workspace.Id)) regex := regexp.MustCompile(fmt.Sprintf(`%s\s*\n(?:\t.*\n?)*`, hostLine)) matchedEntry := regex.FindString(sshConfig) if matchedEntry == "" { @@ -181,7 +181,7 @@ func editSSHConfig(activeProfile config.Profile, workspace *apiclient.WorkspaceD } if modifiedContent == "" { - err = config.RemoveWorkspaceSshEntries(activeProfile.Id, workspace.Id) + err = config.RemoveSshEntries(activeProfile.Id, workspace.Id) if err != nil { return err } diff --git a/pkg/ide/positron.go b/pkg/ide/positron.go index 1f1c12df43..7e7538d12c 100644 --- a/pkg/ide/positron.go +++ b/pkg/ide/positron.go @@ -15,13 +15,13 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func OpenPositron(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenPositron(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey *string) error { path, err := GetPositronBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { diff --git a/pkg/ide/vscode-insiders.go b/pkg/ide/vscode-insiders.go index 147c1d5615..019c12aace 100644 --- a/pkg/ide/vscode-insiders.go +++ b/pkg/ide/vscode-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVSCodeInsiders(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey string) error { +func OpenVSCodeInsiders(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgKey *string) error { path, err := GetVSCodeInsidersBinaryPath() if err != nil { return err @@ -23,7 +23,7 @@ func OpenVSCodeInsiders(activeProfile config.Profile, workspaceId string, worksp return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgKey) if err != nil { diff --git a/pkg/ide/vscodium-insiders.go b/pkg/ide/vscodium-insiders.go index 22e008e4b5..1c6570398d 100644 --- a/pkg/ide/vscodium-insiders.go +++ b/pkg/ide/vscodium-insiders.go @@ -13,7 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenVScodiumInsiders(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenVScodiumInsiders(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey *string) error { path, err := GetCodiumInsidersBinaryPath() if err != nil { return err @@ -24,7 +24,7 @@ func OpenVScodiumInsiders(activeProfile config.Profile, workspaceId string, work return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { diff --git a/pkg/ide/vscodium.go b/pkg/ide/vscodium.go index de1354f232..0d17103dac 100644 --- a/pkg/ide/vscodium.go +++ b/pkg/ide/vscodium.go @@ -16,7 +16,7 @@ import ( const requiredExtension = "jeanp413.open-remote-ssh" -func OpenVScodium(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenVScodium(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey *string) error { path, err := GetCodiumBinaryPath() if err != nil { return err @@ -27,7 +27,7 @@ func OpenVScodium(activeProfile config.Profile, workspaceId string, workspacePro return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { diff --git a/pkg/ide/windsurf.go b/pkg/ide/windsurf.go index 0824f23427..5f80faeda1 100644 --- a/pkg/ide/windsurf.go +++ b/pkg/ide/windsurf.go @@ -13,13 +13,13 @@ import ( "github.com/daytonaio/daytona/pkg/build/devcontainer" ) -func OpenWindsurf(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey string) error { +func OpenWindsurf(activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, gpgkey *string) error { path, err := GetWindsurfBinaryPath() if err != nil { return err } - workspaceHostname := config.GetWorkspaceHostname(activeProfile.Id, workspaceId) + workspaceHostname := config.GetHostname(activeProfile.Id, workspaceId) workspaceDir, err := util.GetWorkspaceDir(activeProfile, workspaceId, gpgkey) if err != nil { diff --git a/pkg/models/api_key.go b/pkg/models/api_key.go index 8032a20aad..19d8e5df77 100644 --- a/pkg/models/api_key.go +++ b/pkg/models/api_key.go @@ -13,7 +13,7 @@ const ( type ApiKey struct { KeyHash string `json:"keyHash" validate:"required" gorm:"primaryKey"` - Type ApiKeyType `json:"type" validate:"required"` + Type ApiKeyType `json:"type" validate:"required" gorm:"not null" ` // Workspace or client name - Name string `json:"name" validate:"required" gorm:"uniqueIndex"` + Name string `json:"name" validate:"required" gorm:"uniqueIndex;not null"` } // @name ApiKey diff --git a/pkg/models/build.go b/pkg/models/build.go index 2b6e4f6a44..1f7f2328c3 100644 --- a/pkg/models/build.go +++ b/pkg/models/build.go @@ -15,14 +15,14 @@ type Build struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` Image *string `json:"image" validate:"optional"` User *string `json:"user" validate:"optional"` - ContainerConfig ContainerConfig `json:"containerConfig" validate:"required" gorm:"serializer:json"` + ContainerConfig ContainerConfig `json:"containerConfig" validate:"required" gorm:"serializer:json;not null"` BuildConfig *BuildConfig `json:"buildConfig" validate:"optional" gorm:"serializer:json"` - Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` - LastJob *Job `gorm:"foreignKey:ResourceId;references:Id" validate:"optional"` - PrebuildId string `json:"prebuildId" validate:"required"` - CreatedAt time.Time `json:"createdAt" validate:"required"` - UpdatedAt time.Time `json:"updatedAt" validate:"required"` + Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json;not null"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` + PrebuildId string `json:"prebuildId" validate:"required" gorm:"not null"` + CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` + UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` } // @name Build func (w *Build) GetState() ResourceState { @@ -30,8 +30,8 @@ func (w *Build) GetState() ResourceState { } type ContainerConfig struct { - Image string `json:"image" validate:"required"` - User string `json:"user" validate:"required"` + Image string `json:"image" validate:"required" gorm:"not null"` + User string `json:"user" validate:"required" gorm:"not null"` } // @name ContainerConfig func (b *Build) Compare(other *Build) (bool, error) { diff --git a/pkg/models/env.go b/pkg/models/env.go index ccfa8e3242..5772ed160e 100644 --- a/pkg/models/env.go +++ b/pkg/models/env.go @@ -5,5 +5,5 @@ package models type EnvironmentVariable struct { Key string `json:"key" validate:"required" gorm:"primaryKey"` - Value string `json:"value" validate:"required"` + Value string `json:"value" validate:"required" gorm:"not null"` } // @name EnvironmentVariable diff --git a/pkg/models/git_provider_config.go b/pkg/models/git_provider_config.go index 876db7a207..c012518dd7 100644 --- a/pkg/models/git_provider_config.go +++ b/pkg/models/git_provider_config.go @@ -12,11 +12,11 @@ const ( type GitProviderConfig struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - ProviderId string `json:"providerId" validate:"required"` - Username string `json:"username" validate:"required"` + ProviderId string `json:"providerId" validate:"required" gorm:"not null"` + Username string `json:"username" validate:"required" gorm:"not null"` BaseApiUrl *string `json:"baseApiUrl,omitempty" validate:"optional"` - Token string `json:"token" validate:"required"` - Alias string `json:"alias" validate:"required" gorm:"uniqueIndex"` + Token string `json:"token" validate:"required" gorm:"not null"` + Alias string `json:"alias" validate:"required" gorm:"uniqueIndex;not null"` SigningKey *string `json:"signingKey,omitempty" validate:"optional"` SigningMethod *SigningMethod `json:"signingMethod,omitempty" validate:"optional"` } // @name GitProvider diff --git a/pkg/models/job.go b/pkg/models/job.go index 005c1e5447..0770821690 100644 --- a/pkg/models/job.go +++ b/pkg/models/job.go @@ -9,13 +9,13 @@ import ( type Job struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - ResourceId string `json:"resourceId" validate:"required"` - ResourceType ResourceType `json:"resourceType" validate:"required"` - State JobState `json:"state" validate:"required"` - Action JobAction `json:"action" validate:"required"` + ResourceId string `json:"resourceId" validate:"required" gorm:"not null"` + ResourceType ResourceType `json:"resourceType" validate:"required" gorm:"not null"` + State JobState `json:"state" validate:"required" gorm:"not null"` + Action JobAction `json:"action" validate:"required" gorm:"not null"` Error *string `json:"error" validate:"optional"` - CreatedAt time.Time `json:"createdAt" validate:"required"` - UpdatedAt time.Time `json:"updatedAt" validate:"required"` + CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` + UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` } // @name Job type ResourceType string // @name ResourceType diff --git a/pkg/models/target.go b/pkg/models/target.go index 2fabdd8118..b7d56ee84c 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -16,21 +16,21 @@ var providersWithoutTargetMode = []string{"docker-provider"} type Target struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - Name string `json:"name" validate:"required"` - TargetConfigId string `json:"targetConfigId" validate:"required" gorm:"foreignKey:TargetConfigId;references:Id"` + Name string `json:"name" validate:"required" gorm:"not null"` + TargetConfigId string `json:"targetConfigId" validate:"required" gorm:"not null"` TargetConfig TargetConfig `json:"targetConfig" validate:"required" gorm:"foreignKey:TargetConfigId"` - ApiKey string `json:"-"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` - IsDefault bool `json:"default" validate:"required"` - Workspaces []Workspace `gorm:"foreignKey:TargetId;references:Id"` - Metadata *TargetMetadata `gorm:"foreignKey:TargetId;references:Id" validate:"optional"` - LastJob *Job `gorm:"foreignKey:ResourceId;references:Id" validate:"optional"` + ApiKey string `json:"-" validate:"required" gorm:"not null"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + IsDefault bool `json:"default" validate:"required" gorm:"not null"` + Workspaces []Workspace `json:"workspaces" validate:"required" gorm:"foreignKey:TargetId;references:Id"` + Metadata *TargetMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:TargetId;references:Id"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` } // @name Target type TargetMetadata struct { - TargetId string `json:"targetId" validate:"required" gorm:"primaryKey;foreignKey:TargetId;references:Id"` - UpdatedAt time.Time `json:"updatedAt" validate:"required"` - Uptime uint64 `json:"uptime" validate:"required"` + TargetId string `json:"targetId" validate:"required" gorm:"primaryKey"` + UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` + Uptime uint64 `json:"uptime" validate:"required" gorm:"not null"` } // @name TargetMetadata func (t *Target) GetState() ResourceState { diff --git a/pkg/models/target_config.go b/pkg/models/target_config.go index 00af4d96c5..6e2ffb4d74 100644 --- a/pkg/models/target_config.go +++ b/pkg/models/target_config.go @@ -5,9 +5,9 @@ package models type TargetConfig struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - Name string `json:"name" validate:"required"` - ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json"` + Name string `json:"name" validate:"required" gorm:"not null"` + ProviderInfo ProviderInfo `json:"providerInfo" validate:"required" gorm:"serializer:json;not null"` // JSON encoded map of options - Options string `json:"options" validate:"required"` - Deleted bool `json:"deleted" validate:"required"` + Options string `json:"options" validate:"required" gorm:"not null"` + Deleted bool `json:"deleted" validate:"required" gorm:"not null"` } // @name TargetConfig diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index e29187cbb9..2a334668f2 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -12,24 +12,24 @@ import ( type Workspace struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` - Name string `json:"name" validate:"required"` - Image string `json:"image" validate:"required"` - User string `json:"user" validate:"required"` + Name string `json:"name" validate:"required" gorm:"not null"` + Image string `json:"image" validate:"required" gorm:"not null"` + User string `json:"user" validate:"required" gorm:"not null"` BuildConfig *BuildConfig `json:"buildConfig,omitempty" validate:"optional" gorm:"serializer:json"` - Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` - TargetId string `json:"targetId" validate:"required" gorm:"foreignKey:TargetId;references:Id"` + Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json;not null"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + TargetId string `json:"targetId" validate:"required" gorm:"not null"` Target Target `json:"target" validate:"required" gorm:"foreignKey:TargetId"` - ApiKey string `json:"-"` - Metadata *WorkspaceMetadata `gorm:"foreignKey:WorkspaceId;references:Id" validate:"optional"` + ApiKey string `json:"-" validate:"required" gorm:"not null"` + Metadata *WorkspaceMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:WorkspaceId;references:Id"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` - LastJob *Job `gorm:"foreignKey:ResourceId;references:Id"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` } // @name Workspace type WorkspaceMetadata struct { - WorkspaceId string `json:"workspaceId" validate:"required" gorm:"primaryKey;foreignKey:WorkspaceId;references:Id"` - UpdatedAt time.Time `json:"updatedAt" validate:"required"` - Uptime uint64 `json:"uptime" validate:"required"` + WorkspaceId string `json:"workspaceId" validate:"required" gorm:"primaryKey"` + UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` + Uptime uint64 `json:"uptime" validate:"required" gorm:"not null"` GitStatus *GitStatus `json:"gitStatus" validate:"optional" gorm:"serializer:json"` } // @name WorkspaceMetadata diff --git a/pkg/models/workspace_template.go b/pkg/models/workspace_template.go index a167331844..3df724e176 100644 --- a/pkg/models/workspace_template.go +++ b/pkg/models/workspace_template.go @@ -13,12 +13,12 @@ import ( type WorkspaceTemplate struct { Name string `json:"name" validate:"required" gorm:"primaryKey"` - Image string `json:"image" validate:"required"` - User string `json:"user" validate:"required"` + Image string `json:"image" validate:"required" gorm:"not null"` + User string `json:"user" validate:"required" gorm:"not null"` BuildConfig *BuildConfig `json:"buildConfig,omitempty" validate:"optional" gorm:"serializer:json"` - RepositoryUrl string `json:"repositoryUrl" validate:"required"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json"` - IsDefault bool `json:"default" validate:"required"` + RepositoryUrl string `json:"repositoryUrl" validate:"required" gorm:"not null"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + IsDefault bool `json:"default" validate:"required" gorm:"not null"` Prebuilds []*PrebuildConfig `json:"prebuilds" validate:"optional" gorm:"serializer:json"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` } // @name WorkspaceTemplate @@ -84,11 +84,11 @@ func (wt *WorkspaceTemplate) RemovePrebuild(id string) error { // PrebuildConfig holds configuration for the prebuild process type PrebuildConfig struct { - Id string `json:"id" validate:"required"` - Branch string `json:"branch" validate:"required"` - CommitInterval *int `json:"commitInterval" validate:"required"` - TriggerFiles []string `json:"triggerFiles" validate:"required"` - Retention int `json:"retention" validate:"required"` + Id string `json:"id" validate:"required" gorm:"not null"` + Branch string `json:"branch" validate:"required" gorm:"not null"` + CommitInterval *int `json:"commitInterval" validate:"optional"` + TriggerFiles []string `json:"triggerFiles" validate:"required" gorm:"not null"` + Retention int `json:"retention" validate:"required" gorm:"not null"` } // @name PrebuildConfig func (p *PrebuildConfig) GenerateId() error { From 35d92e5b93027313db98d1d9b4cbe0f005a85ec2 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Thu, 5 Dec 2024 18:10:36 +0100 Subject: [PATCH 26/76] feat: db transaction support (#1411) - all service and store methods expect a context - the context is used to pass a transaction between stores - job concurrency issues fully resolved Signed-off-by: Toma Puljak --- internal/testing/build/store.go | 11 ++- internal/testing/common/store.go | 22 ++++++ internal/testing/job/store.go | 11 ++- internal/testing/server/apikeys/store.go | 14 ++-- internal/testing/server/env/store.go | 10 ++- .../testing/server/targetconfigs/store.go | 10 ++- .../testing/server/targets/metadata_store.go | 10 ++- internal/testing/server/targets/store.go | 11 ++- .../server/workspaces/metadata_store.go | 10 ++- internal/testing/server/workspaces/store.go | 12 ++- .../testing/server/workspacetemplate/store.go | 11 ++- pkg/api/controllers/apikey/apikey.go | 4 +- pkg/api/controllers/apikey/generate.go | 2 +- pkg/api/controllers/build/build.go | 14 ++-- pkg/api/controllers/env/env.go | 6 +- pkg/api/controllers/gitprovider/branches.go | 2 +- pkg/api/controllers/gitprovider/context.go | 4 +- .../controllers/gitprovider/gitprovider.go | 12 +-- pkg/api/controllers/gitprovider/namespaces.go | 2 +- .../controllers/gitprovider/pull_requests.go | 2 +- .../controllers/gitprovider/repositories.go | 2 +- pkg/api/controllers/gitprovider/user.go | 2 +- pkg/api/controllers/job/job.go | 2 +- pkg/api/controllers/log/websocket.go | 60 +++++++------- pkg/api/controllers/target/metadata.go | 2 +- pkg/api/controllers/targetconfig/add.go | 2 +- pkg/api/controllers/targetconfig/list.go | 2 +- pkg/api/controllers/targetconfig/remove.go | 2 +- pkg/api/controllers/workspace/metadata.go | 2 +- .../workspacetemplate/prebuild/prebuild.go | 10 +-- .../prebuild/process_git_event.go | 4 +- .../workspacetemplate/workspace_template.go | 14 ++-- pkg/api/middlewares/auth.go | 6 +- pkg/api/middlewares/workspace.go | 2 +- pkg/build/factory.go | 3 +- pkg/build/mocks/gitprovider_config_store.go | 6 +- pkg/cmd/server/bootstrap/get_job_runner.go | 20 ++--- .../server/bootstrap/get_server_instance.go | 78 ++++++++++--------- .../server/bootstrap/init_provider_manager.go | 8 +- pkg/cmd/server/serve.go | 2 +- pkg/db/api_key_store.go | 41 ++++++---- pkg/db/build_store.go | 32 +++++--- pkg/db/connection.go | 6 ++ pkg/db/db_store.go | 67 ++++++++++++++++ pkg/db/env.go | 57 -------------- pkg/db/env_store.go | 65 ++++++++++++++++ pkg/db/gitprovider_config_store.go | 34 ++++---- pkg/db/job_store.go | 33 +++++--- pkg/db/target_config_store.go | 28 ++++--- pkg/db/target_metadata_store.go | 28 ++++--- pkg/db/target_store.go | 34 +++++--- pkg/db/workspace_metadata_store.go | 28 ++++--- pkg/db/workspace_store.go | 34 +++++--- pkg/db/workspace_template_store.go | 34 +++++--- pkg/server/apikeys/apikeys.go | 16 ++-- pkg/server/apikeys/apikeys_test.go | 20 ++--- pkg/server/apikeys/service_test.go | 5 +- pkg/server/apikeys/validate.go | 14 ++-- pkg/server/apikeys/validate_test.go | 28 ++++--- pkg/server/builds/service.go | 28 ++++--- pkg/server/builds/service_test.go | 17 ++-- pkg/server/env/service.go | 18 +++-- pkg/server/env/service_test.go | 13 ++-- pkg/server/gitproviders/branches.go | 5 +- pkg/server/gitproviders/config.go | 21 ++--- pkg/server/gitproviders/gitprovider.go | 11 +-- pkg/server/gitproviders/namespaces.go | 5 +- pkg/server/gitproviders/prebuild_webhook.go | 13 ++-- pkg/server/gitproviders/pull_requests.go | 5 +- pkg/server/gitproviders/remove.go | 8 +- pkg/server/gitproviders/repositories.go | 5 +- pkg/server/gitproviders/service.go | 14 ++-- pkg/server/gitproviders/user.go | 5 +- pkg/server/jobs/service.go | 39 ++++++---- pkg/server/jobs/service_test.go | 27 +++---- pkg/server/purge.go | 4 +- pkg/server/targetconfigs/service.go | 26 ++++--- pkg/server/targetconfigs/service_test.go | 17 ++-- pkg/server/targets/create.go | 23 +++++- pkg/server/targets/get.go | 2 +- pkg/server/targets/list.go | 2 +- pkg/server/targets/metadata.go | 8 +- pkg/server/targets/remove.go | 61 ++++++++++++--- pkg/server/targets/service_test.go | 10 +-- pkg/server/targets/set-default.go | 18 +++-- pkg/server/targets/start.go | 2 +- pkg/server/targets/stop.go | 2 +- pkg/server/workspaces/create.go | 23 +++++- pkg/server/workspaces/get.go | 2 +- pkg/server/workspaces/list.go | 2 +- pkg/server/workspaces/metadata.go | 8 +- pkg/server/workspaces/remove.go | 61 ++++++++++++--- pkg/server/workspaces/service.go | 2 +- pkg/server/workspaces/service_test.go | 10 +-- pkg/server/workspaces/start.go | 6 +- pkg/server/workspaces/stop.go | 6 +- pkg/server/workspacetemplates/prebuild.go | 42 ++++------ .../workspacetemplates/prebuild_test.go | 19 ++--- pkg/server/workspacetemplates/service.go | 51 +++++++----- pkg/server/workspacetemplates/service_test.go | 18 ++--- pkg/services/api_key.go | 18 +++-- pkg/services/build.go | 15 ++-- pkg/services/env.go | 9 ++- pkg/services/git_provider.go | 35 +++++---- pkg/services/job.go | 11 +-- pkg/services/target.go | 2 +- pkg/services/target_config.go | 12 +-- pkg/services/workspace.go | 4 +- pkg/services/workspace_template.go | 30 +++---- pkg/stores/api_key.go | 12 +-- pkg/stores/build.go | 10 ++- pkg/stores/env.go | 8 +- pkg/stores/git_provider.go | 10 ++- pkg/stores/job_store.go | 10 ++- pkg/stores/store.go | 30 +++++++ pkg/stores/target.go | 10 ++- pkg/stores/target_config.go | 8 +- pkg/stores/target_metadata.go | 8 +- pkg/stores/workspace.go | 10 ++- pkg/stores/workspace_metadata.go | 8 +- pkg/stores/workspace_template.go | 10 ++- 121 files changed, 1210 insertions(+), 732 deletions(-) create mode 100644 internal/testing/common/store.go create mode 100644 pkg/db/db_store.go delete mode 100644 pkg/db/env.go create mode 100644 pkg/db/env_store.go create mode 100644 pkg/stores/store.go diff --git a/internal/testing/build/store.go b/internal/testing/build/store.go index d52630a34b..e65cf2b5a7 100644 --- a/internal/testing/build/store.go +++ b/internal/testing/build/store.go @@ -6,13 +6,16 @@ package build import ( + "context" "fmt" + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryBuildStore struct { + common.InMemoryStore builds map[string]*models.Build } @@ -22,7 +25,7 @@ func NewInMemoryBuildStore() stores.BuildStore { } } -func (s *InMemoryBuildStore) Find(filter *stores.BuildFilter) (*models.Build, error) { +func (s *InMemoryBuildStore) Find(ctx context.Context, filter *stores.BuildFilter) (*models.Build, error) { b, err := s.processFilters(filter) if err != nil { return nil, err @@ -34,7 +37,7 @@ func (s *InMemoryBuildStore) Find(filter *stores.BuildFilter) (*models.Build, er return b[0], nil } -func (s *InMemoryBuildStore) List(filter *stores.BuildFilter) ([]*models.Build, error) { +func (s *InMemoryBuildStore) List(ctx context.Context, filter *stores.BuildFilter) ([]*models.Build, error) { builds, err := s.processFilters(filter) if err != nil { return nil, err @@ -43,12 +46,12 @@ func (s *InMemoryBuildStore) List(filter *stores.BuildFilter) ([]*models.Build, return builds, nil } -func (s *InMemoryBuildStore) Save(result *models.Build) error { +func (s *InMemoryBuildStore) Save(ctx context.Context, result *models.Build) error { s.builds[result.Id] = result return nil } -func (s *InMemoryBuildStore) Delete(id string) error { +func (s *InMemoryBuildStore) Delete(ctx context.Context, id string) error { delete(s.builds, id) return nil } diff --git a/internal/testing/common/store.go b/internal/testing/common/store.go new file mode 100644 index 0000000000..66815e5e9b --- /dev/null +++ b/internal/testing/common/store.go @@ -0,0 +1,22 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import "context" + +type InMemoryStore struct{} + +func (s *InMemoryStore) BeginTransaction(ctx context.Context) (context.Context, error) { + return ctx, nil +} + +func (s *InMemoryStore) CommitTransaction(ctx context.Context) error { + return nil +} + +func (s *InMemoryStore) RollbackTransaction(ctx context.Context, err error) error { + return err +} diff --git a/internal/testing/job/store.go b/internal/testing/job/store.go index 5332679ede..3f793e76c2 100644 --- a/internal/testing/job/store.go +++ b/internal/testing/job/store.go @@ -6,13 +6,16 @@ package job import ( + "context" "fmt" + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryJobStore struct { + common.InMemoryStore jobs map[string]*models.Job } @@ -22,7 +25,7 @@ func NewInMemoryJobStore() stores.JobStore { } } -func (s *InMemoryJobStore) List(filter *stores.JobFilter) ([]*models.Job, error) { +func (s *InMemoryJobStore) List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) { jobs, err := s.processFilters(filter) if err != nil { return nil, err @@ -31,7 +34,7 @@ func (s *InMemoryJobStore) List(filter *stores.JobFilter) ([]*models.Job, error) return jobs, nil } -func (s *InMemoryJobStore) Find(filter *stores.JobFilter) (*models.Job, error) { +func (s *InMemoryJobStore) Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) { jobs, err := s.processFilters(filter) if err != nil { return nil, err @@ -43,12 +46,12 @@ func (s *InMemoryJobStore) Find(filter *stores.JobFilter) (*models.Job, error) { return jobs[0], nil } -func (s *InMemoryJobStore) Save(job *models.Job) error { +func (s *InMemoryJobStore) Save(ctx context.Context, job *models.Job) error { s.jobs[job.Id] = job return nil } -func (s *InMemoryJobStore) Delete(job *models.Job) error { +func (s *InMemoryJobStore) Delete(ctx context.Context, job *models.Job) error { delete(s.jobs, job.Id) return nil } diff --git a/internal/testing/server/apikeys/store.go b/internal/testing/server/apikeys/store.go index 419a8d0bab..d392a64ba6 100644 --- a/internal/testing/server/apikeys/store.go +++ b/internal/testing/server/apikeys/store.go @@ -6,11 +6,15 @@ package apikeys import ( + "context" + + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryApiKeyStore struct { + common.InMemoryStore apiKeys map[string]*models.ApiKey } @@ -20,7 +24,7 @@ func NewInMemoryApiKeyStore() stores.ApiKeyStore { } } -func (s *InMemoryApiKeyStore) List() ([]*models.ApiKey, error) { +func (s *InMemoryApiKeyStore) List(ctx context.Context) ([]*models.ApiKey, error) { apiKeys := []*models.ApiKey{} for _, a := range s.apiKeys { apiKeys = append(apiKeys, a) @@ -29,7 +33,7 @@ func (s *InMemoryApiKeyStore) List() ([]*models.ApiKey, error) { return apiKeys, nil } -func (s *InMemoryApiKeyStore) Find(key string) (*models.ApiKey, error) { +func (s *InMemoryApiKeyStore) Find(ctx context.Context, key string) (*models.ApiKey, error) { apiKey, ok := s.apiKeys[key] if !ok { return nil, stores.ErrApiKeyNotFound @@ -38,7 +42,7 @@ func (s *InMemoryApiKeyStore) Find(key string) (*models.ApiKey, error) { return apiKey, nil } -func (s *InMemoryApiKeyStore) FindByName(name string) (*models.ApiKey, error) { +func (s *InMemoryApiKeyStore) FindByName(ctx context.Context, name string) (*models.ApiKey, error) { for _, a := range s.apiKeys { if a.Name == name { return a, nil @@ -48,12 +52,12 @@ func (s *InMemoryApiKeyStore) FindByName(name string) (*models.ApiKey, error) { return nil, nil } -func (s *InMemoryApiKeyStore) Save(apiKey *models.ApiKey) error { +func (s *InMemoryApiKeyStore) Save(ctx context.Context, apiKey *models.ApiKey) error { s.apiKeys[apiKey.KeyHash] = apiKey return nil } -func (s *InMemoryApiKeyStore) Delete(apiKey *models.ApiKey) error { +func (s *InMemoryApiKeyStore) Delete(ctx context.Context, apiKey *models.ApiKey) error { delete(s.apiKeys, apiKey.KeyHash) return nil } diff --git a/internal/testing/server/env/store.go b/internal/testing/server/env/store.go index a6c30a2395..b1fde9cc2f 100644 --- a/internal/testing/server/env/store.go +++ b/internal/testing/server/env/store.go @@ -6,11 +6,15 @@ package env import ( + "context" + + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryEnvironmentVariableStore struct { + common.InMemoryStore envVars map[string]*models.EnvironmentVariable } @@ -20,7 +24,7 @@ func NewInMemoryEnvironmentVariableStore() stores.EnvironmentVariableStore { } } -func (s *InMemoryEnvironmentVariableStore) List() ([]*models.EnvironmentVariable, error) { +func (s *InMemoryEnvironmentVariableStore) List(ctx context.Context) ([]*models.EnvironmentVariable, error) { envVars := []*models.EnvironmentVariable{} for _, envVar := range s.envVars { envVars = append(envVars, envVar) @@ -29,12 +33,12 @@ func (s *InMemoryEnvironmentVariableStore) List() ([]*models.EnvironmentVariable return envVars, nil } -func (s *InMemoryEnvironmentVariableStore) Save(environmentVariable *models.EnvironmentVariable) error { +func (s *InMemoryEnvironmentVariableStore) Save(ctx context.Context, environmentVariable *models.EnvironmentVariable) error { s.envVars[environmentVariable.Key] = environmentVariable return nil } -func (s *InMemoryEnvironmentVariableStore) Delete(key string) error { +func (s *InMemoryEnvironmentVariableStore) Delete(ctx context.Context, key string) error { _, ok := s.envVars[key] if !ok { return stores.ErrEnvironmentVariableNotFound diff --git a/internal/testing/server/targetconfigs/store.go b/internal/testing/server/targetconfigs/store.go index 20088289de..f942b97e5d 100644 --- a/internal/testing/server/targetconfigs/store.go +++ b/internal/testing/server/targetconfigs/store.go @@ -6,11 +6,15 @@ package targetconfigs import ( + "context" + + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryTargetConfigStore struct { + common.InMemoryStore targetConfigs map[string]*models.TargetConfig } @@ -20,11 +24,11 @@ func NewInMemoryTargetConfigStore() stores.TargetConfigStore { } } -func (s *InMemoryTargetConfigStore) List(allowDeleted bool) ([]*models.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) List(ctx context.Context, allowDeleted bool) ([]*models.TargetConfig, error) { return s.processFilters("", allowDeleted) } -func (s *InMemoryTargetConfigStore) Find(idOrName string, allowDeleted bool) (*models.TargetConfig, error) { +func (s *InMemoryTargetConfigStore) Find(ctx context.Context, idOrName string, allowDeleted bool) (*models.TargetConfig, error) { targets, err := s.processFilters(idOrName, allowDeleted) if err != nil { return nil, err @@ -37,7 +41,7 @@ func (s *InMemoryTargetConfigStore) Find(idOrName string, allowDeleted bool) (*m return targets[0], nil } -func (s *InMemoryTargetConfigStore) Save(targetConfig *models.TargetConfig) error { +func (s *InMemoryTargetConfigStore) Save(ctx context.Context, targetConfig *models.TargetConfig) error { s.targetConfigs[targetConfig.Id] = targetConfig return nil } diff --git a/internal/testing/server/targets/metadata_store.go b/internal/testing/server/targets/metadata_store.go index 6cd25b5683..ac7530b95d 100644 --- a/internal/testing/server/targets/metadata_store.go +++ b/internal/testing/server/targets/metadata_store.go @@ -6,11 +6,15 @@ package targets import ( + "context" + + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryTargetMetadataStore struct { + common.InMemoryStore targetMetadataEntries map[string]*models.TargetMetadata } @@ -20,7 +24,7 @@ func NewInMemoryTargetMetadataStore() stores.TargetMetadataStore { } } -func (s *InMemoryTargetMetadataStore) Find(filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { +func (s *InMemoryTargetMetadataStore) Find(ctx context.Context, filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { metadatas, err := s.processFilters(filter) if err != nil { return nil, err @@ -32,12 +36,12 @@ func (s *InMemoryTargetMetadataStore) Find(filter *stores.TargetMetadataFilter) return metadatas[0], nil } -func (s *InMemoryTargetMetadataStore) Save(targetMetadata *models.TargetMetadata) error { +func (s *InMemoryTargetMetadataStore) Save(ctx context.Context, targetMetadata *models.TargetMetadata) error { s.targetMetadataEntries[targetMetadata.TargetId] = targetMetadata return nil } -func (s *InMemoryTargetMetadataStore) Delete(targetMetadata *models.TargetMetadata) error { +func (s *InMemoryTargetMetadataStore) Delete(ctx context.Context, targetMetadata *models.TargetMetadata) error { delete(s.targetMetadataEntries, targetMetadata.TargetId) return nil } diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go index d929b34b73..8d876ab1bf 100644 --- a/internal/testing/server/targets/store.go +++ b/internal/testing/server/targets/store.go @@ -6,13 +6,16 @@ package targets import ( + "context" "fmt" + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryTargetStore struct { + common.InMemoryStore targets map[string]*models.Target } @@ -22,11 +25,11 @@ func NewInMemoryTargetStore() stores.TargetStore { } } -func (s *InMemoryTargetStore) List(filter *stores.TargetFilter) ([]*models.Target, error) { +func (s *InMemoryTargetStore) List(ctx context.Context, filter *stores.TargetFilter) ([]*models.Target, error) { return s.processFilters(filter) } -func (s *InMemoryTargetStore) Find(filter *stores.TargetFilter) (*models.Target, error) { +func (s *InMemoryTargetStore) Find(ctx context.Context, filter *stores.TargetFilter) (*models.Target, error) { t, err := s.processFilters(filter) if err != nil { return nil, err @@ -39,7 +42,7 @@ func (s *InMemoryTargetStore) Find(filter *stores.TargetFilter) (*models.Target, return t[0], nil } -func (s *InMemoryTargetStore) Save(target *models.Target) error { +func (s *InMemoryTargetStore) Save(ctx context.Context, target *models.Target) error { tg := *target tg.EnvVars = nil tg.ApiKey = "" @@ -48,7 +51,7 @@ func (s *InMemoryTargetStore) Save(target *models.Target) error { return nil } -func (s *InMemoryTargetStore) Delete(target *models.Target) error { +func (s *InMemoryTargetStore) Delete(ctx context.Context, target *models.Target) error { delete(s.targets, target.Id) return nil } diff --git a/internal/testing/server/workspaces/metadata_store.go b/internal/testing/server/workspaces/metadata_store.go index a26c3e1813..57b18df675 100644 --- a/internal/testing/server/workspaces/metadata_store.go +++ b/internal/testing/server/workspaces/metadata_store.go @@ -6,11 +6,15 @@ package workspaces import ( + "context" + + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryWorkspaceMetadataStore struct { + common.InMemoryStore workspaceMetadataEntries map[string]*models.WorkspaceMetadata } @@ -20,7 +24,7 @@ func NewInMemoryWorkspaceMetadataStore() stores.WorkspaceMetadataStore { } } -func (s *InMemoryWorkspaceMetadataStore) Find(filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { +func (s *InMemoryWorkspaceMetadataStore) Find(ctx context.Context, filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { metadatas, err := s.processFilters(filter) if err != nil { return nil, err @@ -32,12 +36,12 @@ func (s *InMemoryWorkspaceMetadataStore) Find(filter *stores.WorkspaceMetadataFi return metadatas[0], nil } -func (s *InMemoryWorkspaceMetadataStore) Save(workspaceMetadata *models.WorkspaceMetadata) error { +func (s *InMemoryWorkspaceMetadataStore) Save(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { s.workspaceMetadataEntries[workspaceMetadata.WorkspaceId] = workspaceMetadata return nil } -func (s *InMemoryWorkspaceMetadataStore) Delete(workspaceMetadata *models.WorkspaceMetadata) error { +func (s *InMemoryWorkspaceMetadataStore) Delete(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { delete(s.workspaceMetadataEntries, workspaceMetadata.WorkspaceId) return nil } diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go index 7ed344e973..6baf5f784e 100644 --- a/internal/testing/server/workspaces/store.go +++ b/internal/testing/server/workspaces/store.go @@ -6,11 +6,15 @@ package workspaces import ( + "context" + + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryWorkspaceStore struct { + common.InMemoryStore workspaces map[string]*models.Workspace } @@ -20,7 +24,7 @@ func NewInMemoryWorkspaceStore() stores.WorkspaceStore { } } -func (s *InMemoryWorkspaceStore) List() ([]*models.Workspace, error) { +func (s *InMemoryWorkspaceStore) List(ctx context.Context) ([]*models.Workspace, error) { workspaces := []*models.Workspace{} for _, w := range s.workspaces { workspaces = append(workspaces, w) @@ -29,7 +33,7 @@ func (s *InMemoryWorkspaceStore) List() ([]*models.Workspace, error) { return workspaces, nil } -func (s *InMemoryWorkspaceStore) Find(idOrName string) (*models.Workspace, error) { +func (s *InMemoryWorkspaceStore) Find(ctx context.Context, idOrName string) (*models.Workspace, error) { w, ok := s.workspaces[idOrName] if !ok { for _, w := range s.workspaces { @@ -43,12 +47,12 @@ func (s *InMemoryWorkspaceStore) Find(idOrName string) (*models.Workspace, error return w, nil } -func (s *InMemoryWorkspaceStore) Save(workspace *models.Workspace) error { +func (s *InMemoryWorkspaceStore) Save(ctx context.Context, workspace *models.Workspace) error { s.workspaces[workspace.Id] = workspace return nil } -func (s *InMemoryWorkspaceStore) Delete(workspace *models.Workspace) error { +func (s *InMemoryWorkspaceStore) Delete(ctx context.Context, workspace *models.Workspace) error { delete(s.workspaces, workspace.Id) return nil } diff --git a/internal/testing/server/workspacetemplate/store.go b/internal/testing/server/workspacetemplate/store.go index 9381ed6dd8..e3de26e4a6 100644 --- a/internal/testing/server/workspacetemplate/store.go +++ b/internal/testing/server/workspacetemplate/store.go @@ -6,13 +6,16 @@ package workspacetemplate import ( + "context" "fmt" + "github.com/daytonaio/daytona/internal/testing/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryWorkspaceTemplateStore struct { + common.InMemoryStore workspaceTemplates map[string]*models.WorkspaceTemplate } @@ -22,11 +25,11 @@ func NewInMemoryWorkspaceTemplateStore() stores.WorkspaceTemplateStore { } } -func (s *InMemoryWorkspaceTemplateStore) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { +func (s *InMemoryWorkspaceTemplateStore) List(ctx context.Context, filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { return s.processFilters(filter) } -func (s *InMemoryWorkspaceTemplateStore) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { +func (s *InMemoryWorkspaceTemplateStore) Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { workspaceTemplates, err := s.processFilters(filter) if err != nil { return nil, err @@ -38,12 +41,12 @@ func (s *InMemoryWorkspaceTemplateStore) Find(filter *stores.WorkspaceTemplateFi return workspaceTemplates[0], nil } -func (s *InMemoryWorkspaceTemplateStore) Save(workspaceTemplate *models.WorkspaceTemplate) error { +func (s *InMemoryWorkspaceTemplateStore) Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { s.workspaceTemplates[workspaceTemplate.Name] = workspaceTemplate return nil } -func (s *InMemoryWorkspaceTemplateStore) Delete(workspaceTemplate *models.WorkspaceTemplate) error { +func (s *InMemoryWorkspaceTemplateStore) Delete(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { delete(s.workspaceTemplates, workspaceTemplate.Name) return nil } diff --git a/pkg/api/controllers/apikey/apikey.go b/pkg/api/controllers/apikey/apikey.go index 811501908c..576fd0b643 100644 --- a/pkg/api/controllers/apikey/apikey.go +++ b/pkg/api/controllers/apikey/apikey.go @@ -24,7 +24,7 @@ import ( func ListClientApiKeys(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.ApiKeyService.ListClientKeys() + response, err := server.ApiKeyService.ListClientKeys(ctx.Request.Context()) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get client API keys: %w", err)) return @@ -48,7 +48,7 @@ func RevokeApiKey(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.ApiKeyService.Revoke(apiKeyName) + err := server.ApiKeyService.Revoke(ctx.Request.Context(), apiKeyName) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to revoke api key: %w", err)) return diff --git a/pkg/api/controllers/apikey/generate.go b/pkg/api/controllers/apikey/generate.go index 25b3aeba2d..c195bc2ee2 100644 --- a/pkg/api/controllers/apikey/generate.go +++ b/pkg/api/controllers/apikey/generate.go @@ -28,7 +28,7 @@ func GenerateApiKey(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.ApiKeyService.Generate(models.ApiKeyTypeClient, apiKeyName) + response, err := server.ApiKeyService.Generate(ctx.Request.Context(), models.ApiKeyTypeClient, apiKeyName) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get API keys: %w", err)) return diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/build.go index 9d9765bcd2..0cf3ba18fa 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/build.go @@ -36,7 +36,7 @@ func CreateBuild(ctx *gin.Context) { s := server.GetInstance(nil) - buildId, err := s.BuildService.Create(createBuildDto) + buildId, err := s.BuildService.Create(ctx.Request.Context(), createBuildDto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create build: %s", err.Error())) return @@ -61,7 +61,7 @@ func GetBuild(ctx *gin.Context) { server := server.GetInstance(nil) - b, err := server.BuildService.Find(&services.BuildFilter{ + b, err := server.BuildService.Find(ctx.Request.Context(), &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Id: &buildId, }, @@ -91,7 +91,7 @@ func GetBuild(ctx *gin.Context) { func ListBuilds(ctx *gin.Context) { server := server.GetInstance(nil) - builds, err := server.BuildService.List(nil) + builds, err := server.BuildService.List(ctx.Request.Context(), nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list builds: %s", err.Error())) return @@ -125,7 +125,7 @@ func DeleteAllBuilds(ctx *gin.Context) { server := server.GetInstance(nil) - errs := server.BuildService.Delete(nil, force) + errs := server.BuildService.Delete(ctx.Request.Context(), nil, force) if len(errs) > 0 { for _, err := range errs { _ = ctx.Error(err) @@ -164,7 +164,7 @@ func DeleteBuild(ctx *gin.Context) { server := server.GetInstance(nil) - errs := server.BuildService.Delete(&services.BuildFilter{ + errs := server.BuildService.Delete(ctx.Request.Context(), &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Id: &buildId, }, @@ -208,7 +208,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { server := server.GetInstance(nil) // Fail if prebuild does not exist - _, err = server.WorkspaceTemplateService.FindPrebuild(nil, &stores.PrebuildFilter{ + _, err = server.WorkspaceTemplateService.FindPrebuild(ctx.Request.Context(), nil, &stores.PrebuildFilter{ Id: &prebuildId, }) if err != nil { @@ -216,7 +216,7 @@ func DeleteBuildsFromPrebuild(ctx *gin.Context) { return } - errs := server.BuildService.Delete(&services.BuildFilter{ + errs := server.BuildService.Delete(ctx.Request.Context(), &services.BuildFilter{ StoreFilter: stores.BuildFilter{ PrebuildIds: &[]string{prebuildId}, }, diff --git a/pkg/api/controllers/env/env.go b/pkg/api/controllers/env/env.go index 3e0dd43efa..6ed12fd388 100644 --- a/pkg/api/controllers/env/env.go +++ b/pkg/api/controllers/env/env.go @@ -25,7 +25,7 @@ import ( // @id ListEnvironmentVariables func ListEnvironmentVariables(ctx *gin.Context) { server := server.GetInstance(nil) - envVars, err := server.EnvironmentVariableService.List() + envVars, err := server.EnvironmentVariableService.List(ctx.Request.Context()) if err != nil { if stores.IsEnvironmentVariableNotFound(err) { ctx.JSON(200, []*models.EnvironmentVariable{}) @@ -58,7 +58,7 @@ func SetEnvironmentVariable(ctx *gin.Context) { } server := server.GetInstance(nil) - err = server.EnvironmentVariableService.Save(&req) + err = server.EnvironmentVariableService.Save(ctx.Request.Context(), &req) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save environment variable: %w", err)) return @@ -82,7 +82,7 @@ func DeleteEnvironmentVariable(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.EnvironmentVariableService.Delete(envVarKey) + err := server.EnvironmentVariableService.Delete(ctx.Request.Context(), envVarKey) if err != nil { if stores.IsEnvironmentVariableNotFound(err) { ctx.Status(204) diff --git a/pkg/api/controllers/gitprovider/branches.go b/pkg/api/controllers/gitprovider/branches.go index c5b4bcc4b3..19b67b38f2 100644 --- a/pkg/api/controllers/gitprovider/branches.go +++ b/pkg/api/controllers/gitprovider/branches.go @@ -53,7 +53,7 @@ func GetRepoBranches(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.GitProviderService.GetRepoBranches(gitProviderId, namespaceId, repositoryId, options) + response, err := server.GitProviderService.GetRepoBranches(ctx.Request.Context(), gitProviderId, namespaceId, repositoryId, options) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/gitprovider/context.go b/pkg/api/controllers/gitprovider/context.go index d43f7f204a..1a933d4bc6 100644 --- a/pkg/api/controllers/gitprovider/context.go +++ b/pkg/api/controllers/gitprovider/context.go @@ -35,7 +35,7 @@ func GetGitContext(ctx *gin.Context) { server := server.GetInstance(nil) - gitProvider, _, err := server.GitProviderService.GetGitProviderForUrl(repositoryContext.Url) + gitProvider, _, err := server.GitProviderService.GetGitProviderForUrl(ctx.Request.Context(), repositoryContext.Url) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -78,7 +78,7 @@ func GetUrlFromRepository(ctx *gin.Context) { server := server.GetInstance(nil) - gitProvider, _, err := server.GitProviderService.GetGitProviderForUrl(repoContext.Url) + gitProvider, _, err := server.GitProviderService.GetGitProviderForUrl(ctx.Request.Context(), repoContext.Url) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/gitprovider/gitprovider.go b/pkg/api/controllers/gitprovider/gitprovider.go index 75ffa842bc..5b91fbcdf5 100644 --- a/pkg/api/controllers/gitprovider/gitprovider.go +++ b/pkg/api/controllers/gitprovider/gitprovider.go @@ -34,7 +34,7 @@ func ListGitProviders(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.GitProviderService.ListConfigs() + response, err := server.GitProviderService.ListConfigs(ctx.Request.Context()) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list git providers: %w", err)) return @@ -70,7 +70,7 @@ func ListGitProvidersForUrl(ctx *gin.Context) { server := server.GetInstance(nil) - gitProviders, err := server.GitProviderService.ListConfigsForUrl(decodedUrl) + gitProviders, err := server.GitProviderService.ListConfigsForUrl(ctx.Request.Context(), decodedUrl) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get git provider for url: %w", err)) return @@ -102,7 +102,7 @@ func GetGitProvider(ctx *gin.Context) { server := server.GetInstance(nil) - gitProvider, err := server.GitProviderService.GetConfig(id) + gitProvider, err := server.GitProviderService.GetConfig(ctx.Request.Context(), id) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -142,7 +142,7 @@ func GetGitProviderIdForUrl(ctx *gin.Context) { server := server.GetInstance(nil) - _, providerId, err := server.GitProviderService.GetGitProviderForUrl(decodedUrl) + _, providerId, err := server.GitProviderService.GetGitProviderForUrl(ctx.Request.Context(), decodedUrl) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -194,7 +194,7 @@ func SetGitProvider(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.GitProviderService.SetGitProviderConfig(&gitProviderConfig) + err = server.GitProviderService.SetGitProviderConfig(ctx.Request.Context(), &gitProviderConfig) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -223,7 +223,7 @@ func RemoveGitProvider(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.GitProviderService.RemoveGitProvider(gitProviderId) + err := server.GitProviderService.RemoveGitProvider(ctx.Request.Context(), gitProviderId) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/gitprovider/namespaces.go b/pkg/api/controllers/gitprovider/namespaces.go index d78c092fc8..433c2c6440 100644 --- a/pkg/api/controllers/gitprovider/namespaces.go +++ b/pkg/api/controllers/gitprovider/namespaces.go @@ -37,7 +37,7 @@ func GetNamespaces(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.GitProviderService.GetNamespaces(gitProviderId, options) + response, err := server.GitProviderService.GetNamespaces(ctx.Request.Context(), gitProviderId, options) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/gitprovider/pull_requests.go b/pkg/api/controllers/gitprovider/pull_requests.go index ef5a079bed..367d47cb98 100644 --- a/pkg/api/controllers/gitprovider/pull_requests.go +++ b/pkg/api/controllers/gitprovider/pull_requests.go @@ -53,7 +53,7 @@ func GetRepoPRs(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.GitProviderService.GetRepoPRs(gitProviderId, namespaceId, repositoryId, options) + response, err := server.GitProviderService.GetRepoPRs(ctx.Request.Context(), gitProviderId, namespaceId, repositoryId, options) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/gitprovider/repositories.go b/pkg/api/controllers/gitprovider/repositories.go index 8c7eb8fb94..ccd5d5963c 100644 --- a/pkg/api/controllers/gitprovider/repositories.go +++ b/pkg/api/controllers/gitprovider/repositories.go @@ -38,7 +38,7 @@ func GetRepositories(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.GitProviderService.GetRepositories(gitProviderId, namespaceId, options) + response, err := server.GitProviderService.GetRepositories(ctx.Request.Context(), gitProviderId, namespaceId, options) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/gitprovider/user.go b/pkg/api/controllers/gitprovider/user.go index 23b85ac95d..2b105e9e8f 100644 --- a/pkg/api/controllers/gitprovider/user.go +++ b/pkg/api/controllers/gitprovider/user.go @@ -27,7 +27,7 @@ func GetGitUser(ctx *gin.Context) { server := server.GetInstance(nil) - response, err := server.GitProviderService.GetGitUser(gitProviderId) + response, err := server.GitProviderService.GetGitUser(ctx.Request.Context(), gitProviderId) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/job/job.go b/pkg/api/controllers/job/job.go index f5700b7d28..136f52310f 100644 --- a/pkg/api/controllers/job/job.go +++ b/pkg/api/controllers/job/job.go @@ -24,7 +24,7 @@ import ( func ListJobs(ctx *gin.Context) { server := server.GetInstance(nil) - jobs, err := server.JobService.List(nil) + jobs, err := server.JobService.List(ctx.Request.Context(), nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list jobs: %s", err.Error())) return diff --git a/pkg/api/controllers/log/websocket.go b/pkg/api/controllers/log/websocket.go index 65c2fbc920..7b6f702bac 100644 --- a/pkg/api/controllers/log/websocket.go +++ b/pkg/api/controllers/log/websocket.go @@ -108,22 +108,22 @@ func ReadLog[T any](ginCtx *gin.Context, logReader io.Reader, readFunc func(cont } } -func ReadServerLog(ginCtx *gin.Context) { +func ReadServerLog(ctx *gin.Context) { s := server.GetInstance(nil) - logFileQuery := ginCtx.Query("file") - retryQuery := ginCtx.DefaultQuery("retry", "true") + logFileQuery := ctx.Query("file") + retryQuery := ctx.DefaultQuery("retry", "true") retry := retryQuery == "true" if retry { for { reader, err := s.GetLogReader(logFileQuery) if err != nil && server.IsLogFileNotFound(err) { - ginCtx.AbortWithError(http.StatusNotFound, err) + ctx.AbortWithError(http.StatusNotFound, err) return } if err == nil { - ReadLog(ginCtx, reader, util.ReadLog, writeToWs) + ReadLog(ctx, reader, util.ReadLog, writeToWs) return } time.Sleep(TIMEOUT) @@ -133,19 +133,19 @@ func ReadServerLog(ginCtx *gin.Context) { reader, err := s.GetLogReader(logFileQuery) if err != nil { if server.IsLogFileNotFound(err) { - ginCtx.AbortWithError(http.StatusNotFound, err) + ctx.AbortWithError(http.StatusNotFound, err) return } - ginCtx.AbortWithError(http.StatusInternalServerError, err) + ctx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ginCtx, reader, util.ReadLog, writeToWs) + ReadLog(ctx, reader, util.ReadLog, writeToWs) } -func ReadTargetLog(ginCtx *gin.Context) { - targetId := ginCtx.Param("targetId") - retryQuery := ginCtx.DefaultQuery("retry", "true") +func ReadTargetLog(ctx *gin.Context) { + targetId := ctx.Param("targetId") + retryQuery := ctx.DefaultQuery("retry", "true") retry := retryQuery == "true" server := server.GetInstance(nil) @@ -154,7 +154,7 @@ func ReadTargetLog(ginCtx *gin.Context) { for { targetLogReader, err := server.TargetService.GetTargetLogReader(targetId) if err == nil { - ReadLog(ginCtx, targetLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, targetLogReader, util.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) @@ -163,64 +163,64 @@ func ReadTargetLog(ginCtx *gin.Context) { targetLogReader, err := server.TargetService.GetTargetLogReader(targetId) if err != nil { - ginCtx.AbortWithError(http.StatusInternalServerError, err) + ctx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ginCtx, targetLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, targetLogReader, util.ReadJSONLog, writeJSONToWs) } -func ReadWorkspaceLog(ginCtx *gin.Context) { - workspaceId := ginCtx.Param("workspaceId") - retryQuery := ginCtx.DefaultQuery("retry", "true") +func ReadWorkspaceLog(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + retryQuery := ctx.DefaultQuery("retry", "true") retry := retryQuery == "true" server := server.GetInstance(nil) if retry { for { - workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(workspaceId) + workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(ctx.Request.Context(), workspaceId) if err == nil { - ReadLog(ginCtx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) } } - workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(workspaceId) + workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(ctx.Request.Context(), workspaceId) if err != nil { - ginCtx.AbortWithError(http.StatusInternalServerError, err) + ctx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ginCtx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) } -func ReadBuildLog(ginCtx *gin.Context) { - buildId := ginCtx.Param("buildId") - retryQuery := ginCtx.DefaultQuery("retry", "true") +func ReadBuildLog(ctx *gin.Context) { + buildId := ctx.Param("buildId") + retryQuery := ctx.DefaultQuery("retry", "true") retry := retryQuery == "true" server := server.GetInstance(nil) if retry { for { - buildLogReader, err := server.BuildService.GetBuildLogReader(buildId) + buildLogReader, err := server.BuildService.GetBuildLogReader(ctx.Request.Context(), buildId) if err == nil { - ReadLog(ginCtx, buildLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, buildLogReader, util.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) } } - buildLogReader, err := server.BuildService.GetBuildLogReader(buildId) + buildLogReader, err := server.BuildService.GetBuildLogReader(ctx.Request.Context(), buildId) if err != nil { - ginCtx.AbortWithError(http.StatusInternalServerError, err) + ctx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ginCtx, buildLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, buildLogReader, util.ReadJSONLog, writeJSONToWs) } diff --git a/pkg/api/controllers/target/metadata.go b/pkg/api/controllers/target/metadata.go index d294b53c2d..e2ee3c28a2 100644 --- a/pkg/api/controllers/target/metadata.go +++ b/pkg/api/controllers/target/metadata.go @@ -36,7 +36,7 @@ func SetTargetMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.TargetService.SetTargetMetadata(targetId, &models.TargetMetadata{ + _, err = server.TargetService.SetTargetMetadata(ctx.Request.Context(), targetId, &models.TargetMetadata{ Uptime: setTargetMetadataDTO.Uptime, }) if err != nil { diff --git a/pkg/api/controllers/targetconfig/add.go b/pkg/api/controllers/targetconfig/add.go index 65334e0e00..5ff40090cd 100644 --- a/pkg/api/controllers/targetconfig/add.go +++ b/pkg/api/controllers/targetconfig/add.go @@ -33,7 +33,7 @@ func AddTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfig, err := server.TargetConfigService.Add(req) + targetConfig, err := server.TargetConfigService.Add(ctx.Request.Context(), req) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target config: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/list.go b/pkg/api/controllers/targetconfig/list.go index dcfa271fd4..e834937576 100644 --- a/pkg/api/controllers/targetconfig/list.go +++ b/pkg/api/controllers/targetconfig/list.go @@ -25,7 +25,7 @@ import ( func ListTargetConfigs(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfigs, err := server.TargetConfigService.List() + targetConfigs, err := server.TargetConfigService.List(ctx.Request.Context()) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list target configs: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/remove.go index 0d0d22207d..e69d6bad2b 100644 --- a/pkg/api/controllers/targetconfig/remove.go +++ b/pkg/api/controllers/targetconfig/remove.go @@ -26,7 +26,7 @@ func RemoveTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.TargetConfigService.Delete(configId) + err := server.TargetConfigService.Delete(ctx.Request.Context(), configId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target config: %w", err)) return diff --git a/pkg/api/controllers/workspace/metadata.go b/pkg/api/controllers/workspace/metadata.go index e26ed310e4..e5eba4755b 100644 --- a/pkg/api/controllers/workspace/metadata.go +++ b/pkg/api/controllers/workspace/metadata.go @@ -36,7 +36,7 @@ func SetWorkspaceMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.WorkspaceService.SetWorkspaceMetadata(workspaceId, &models.WorkspaceMetadata{ + _, err = server.WorkspaceService.SetWorkspaceMetadata(ctx.Request.Context(), workspaceId, &models.WorkspaceMetadata{ Uptime: setWorkspaceMetadataDTO.Uptime, GitStatus: setWorkspaceMetadataDTO.GitStatus, }) diff --git a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go index 6a06b7befe..2d9bff556d 100644 --- a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go @@ -32,7 +32,7 @@ func GetPrebuild(ctx *gin.Context) { prebuildId := ctx.Param("prebuildId") server := server.GetInstance(nil) - res, err := server.WorkspaceTemplateService.FindPrebuild(&stores.WorkspaceTemplateFilter{ + res, err := server.WorkspaceTemplateService.FindPrebuild(ctx.Request.Context(), &stores.WorkspaceTemplateFilter{ Name: &templateName, }, &stores.PrebuildFilter{ Id: &prebuildId, @@ -72,7 +72,7 @@ func SetPrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - prebuild, err := server.WorkspaceTemplateService.SetPrebuild(templateName, dto) + prebuild, err := server.WorkspaceTemplateService.SetPrebuild(ctx.Request.Context(), templateName, dto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set prebuild: %s", err.Error())) return @@ -93,7 +93,7 @@ func SetPrebuild(ctx *gin.Context) { // @id ListPrebuilds func ListPrebuilds(ctx *gin.Context) { server := server.GetInstance(nil) - res, err := server.WorkspaceTemplateService.ListPrebuilds(nil, nil) + res, err := server.WorkspaceTemplateService.ListPrebuilds(ctx.Request.Context(), nil, nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get prebuilds: %s", err.Error())) return @@ -125,7 +125,7 @@ func ListPrebuildsForWorkspaceTemplate(ctx *gin.Context) { } server := server.GetInstance(nil) - res, err := server.WorkspaceTemplateService.ListPrebuilds(workspaceTemplateFilter, nil) + res, err := server.WorkspaceTemplateService.ListPrebuilds(ctx.Request.Context(), workspaceTemplateFilter, nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get prebuilds: %s", err.Error())) return @@ -164,7 +164,7 @@ func DeletePrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - errs := server.WorkspaceTemplateService.DeletePrebuild(templateName, prebuildId, force) + errs := server.WorkspaceTemplateService.DeletePrebuild(ctx.Request.Context(), templateName, prebuildId, force) if len(errs) > 0 { if stores.IsPrebuildNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("prebuild not found")) diff --git a/pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go b/pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go index 86d27c7159..85a66418b6 100644 --- a/pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/process_git_event.go @@ -25,7 +25,7 @@ import ( func ProcessGitEvent(ctx *gin.Context) { server := server.GetInstance(nil) - gitProvider, err := server.GitProviderService.GetGitProviderForHttpRequest(ctx.Request) + gitProvider, err := server.GitProviderService.GetGitProviderForHttpRequest(ctx.Request.Context(), ctx.Request) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get git provider for request: %s", err.Error())) return @@ -41,7 +41,7 @@ func ProcessGitEvent(ctx *gin.Context) { return } - err = server.WorkspaceTemplateService.ProcessGitEvent(*gitEventData) + err = server.WorkspaceTemplateService.ProcessGitEvent(ctx.Request.Context(), *gitEventData) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to process git event: %s", err.Error())) return diff --git a/pkg/api/controllers/workspacetemplate/workspace_template.go b/pkg/api/controllers/workspacetemplate/workspace_template.go index c95a5f0151..1eb86005fa 100644 --- a/pkg/api/controllers/workspacetemplate/workspace_template.go +++ b/pkg/api/controllers/workspacetemplate/workspace_template.go @@ -35,7 +35,7 @@ func GetWorkspaceTemplate(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceTemplate, err := server.WorkspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + workspaceTemplate, err := server.WorkspaceTemplateService.Find(ctx.Request.Context(), &stores.WorkspaceTemplateFilter{ Name: &templateName, }) if err != nil { @@ -68,7 +68,7 @@ func GetDefaultWorkspaceTemplate(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceTemplates, err := server.WorkspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + workspaceTemplates, err := server.WorkspaceTemplateService.Find(ctx.Request.Context(), &stores.WorkspaceTemplateFilter{ Url: &decodedURLParam, Default: util.Pointer(true), }) @@ -100,7 +100,7 @@ func GetDefaultWorkspaceTemplate(ctx *gin.Context) { func ListWorkspaceTemplates(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceTemplates, err := server.WorkspaceTemplateService.List(nil) + workspaceTemplates, err := server.WorkspaceTemplateService.List(ctx.Request.Context(), nil) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspace templates: %s", err.Error())) return @@ -132,7 +132,7 @@ func SetWorkspaceTemplate(ctx *gin.Context) { workspaceTemplate := conversion.ToWorkspaceTemplate(req) - err = s.WorkspaceTemplateService.Save(workspaceTemplate) + err = s.WorkspaceTemplateService.Save(ctx.Request.Context(), workspaceTemplate) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save workspace template: %s", err.Error())) return @@ -156,7 +156,7 @@ func SetDefaultWorkspaceTemplate(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.WorkspaceTemplateService.SetDefault(templateName) + err := server.WorkspaceTemplateService.SetDefault(ctx.Request.Context(), templateName) if err != nil { ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to set workspace template to default: %s", err.Error())) return @@ -193,7 +193,7 @@ func DeleteWorkspaceTemplate(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceTemplate, err := server.WorkspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + workspaceTemplate, err := server.WorkspaceTemplateService.Find(ctx.Request.Context(), &stores.WorkspaceTemplateFilter{ Name: &templateName, }) if err != nil { @@ -201,7 +201,7 @@ func DeleteWorkspaceTemplate(ctx *gin.Context) { return } - errs := server.WorkspaceTemplateService.Delete(workspaceTemplate.Name, force) + errs := server.WorkspaceTemplateService.Delete(ctx.Request.Context(), workspaceTemplate.Name, force) if len(errs) > 0 { if stores.IsWorkspaceTemplateNotFound(errs[0]) { ctx.AbortWithError(http.StatusNotFound, errors.New("workspace template not found")) diff --git a/pkg/api/middlewares/auth.go b/pkg/api/middlewares/auth.go index 1074e4879c..9b4b5fa1bc 100644 --- a/pkg/api/middlewares/auth.go +++ b/pkg/api/middlewares/auth.go @@ -28,16 +28,16 @@ func AuthMiddleware() gin.HandlerFunc { server := server.GetInstance(nil) - if !server.ApiKeyService.IsValidApiKey(token) { + if !server.ApiKeyService.IsValidApiKey(ctx.Request.Context(), token) { ctx.AbortWithError(401, errors.New("unauthorized")) return } apiKeyType := models.ApiKeyTypeClient - if server.ApiKeyService.IsTargetApiKey(token) { + if server.ApiKeyService.IsTargetApiKey(ctx.Request.Context(), token) { apiKeyType = models.ApiKeyTypeTarget - } else if server.ApiKeyService.IsWorkspaceApiKey(token) { + } else if server.ApiKeyService.IsWorkspaceApiKey(ctx.Request.Context(), token) { apiKeyType = models.ApiKeyTypeWorkspace } diff --git a/pkg/api/middlewares/workspace.go b/pkg/api/middlewares/workspace.go index 0dc167eb98..38ad903e74 100644 --- a/pkg/api/middlewares/workspace.go +++ b/pkg/api/middlewares/workspace.go @@ -26,7 +26,7 @@ func WorkspaceAuthMiddleware() gin.HandlerFunc { server := server.GetInstance(nil) - if !server.ApiKeyService.IsWorkspaceApiKey(token) && !server.ApiKeyService.IsTargetApiKey(token) { + if !server.ApiKeyService.IsWorkspaceApiKey(ctx.Request.Context(), token) && !server.ApiKeyService.IsTargetApiKey(ctx.Request.Context(), token) { ctx.AbortWithError(401, errors.New("unauthorized")) } diff --git a/pkg/build/factory.go b/pkg/build/factory.go index fb0d65826d..f542c2e2fd 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -4,6 +4,7 @@ package build import ( + "context" "errors" "fmt" @@ -65,7 +66,7 @@ func (f *BuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, erro return nil, errors.New("repository must be set") } - build, err := f.buildService.Find(&services.BuildFilter{ + build, err := f.buildService.Find(context.Background(), &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Branch: &b.Repository.Branch, RepositoryUrl: &b.Repository.Url, diff --git a/pkg/build/mocks/gitprovider_config_store.go b/pkg/build/mocks/gitprovider_config_store.go index cd9a14aa79..173f166c62 100644 --- a/pkg/build/mocks/gitprovider_config_store.go +++ b/pkg/build/mocks/gitprovider_config_store.go @@ -4,6 +4,8 @@ package build import ( + "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/stretchr/testify/mock" ) @@ -12,7 +14,7 @@ type MockGitProviderConfigStore struct { mock.Mock } -func (s *MockGitProviderConfigStore) ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) { - args := s.Called(url) +func (s *MockGitProviderConfigStore) ListConfigsForUrl(ctx context.Context, url string) ([]*models.GitProviderConfig, error) { + args := s.Called(ctx, url) return args.Get(0).([]*models.GitProviderConfig), args.Error(1) } diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go index 69d1a94bee..d3ce35cb3c 100644 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -49,16 +49,16 @@ func GetJobRunner(c *server.Config, configDir string, version string, telemetryS return runner.NewJobRunner(runner.JobRunnerConfig{ ListPendingJobs: func(ctx context.Context) ([]*models.Job, error) { - return jobService.List(&stores.JobFilter{ + return jobService.List(ctx, &stores.JobFilter{ States: &[]models.JobState{models.JobStatePending}, }) }, UpdateJobState: func(ctx context.Context, job *models.Job, state models.JobState, err *error) error { - job.State = state + var jobErr *string if err != nil { - job.Error = util.Pointer((*err).Error()) + jobErr = util.Pointer((*err).Error()) } - return jobService.Update(job) + return jobService.SetState(ctx, job.Id, state, jobErr) }, WorkspaceJobFactory: workspaceJobFactory, TargetJobFactory: targetJobFactory, @@ -110,10 +110,10 @@ func GetWorkspaceJobFactory(c *server.Config, configDir string, version string, return services.EnvironmentVariables(envVars).FindContainerRegistryByImageName(image) }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(id) + return gitProviderService.GetConfig(ctx, id) }, GetWorkspaceEnvironmentVariables: func(ctx context.Context, w *models.Workspace) (map[string]string, error) { - serverEnvVars, err := envVarService.Map() + serverEnvVars, err := envVarService.Map(ctx) if err != nil { return nil, err } @@ -195,7 +195,7 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele envVarService := server.GetInstance(nil).EnvironmentVariableService - envVars, err := envVarService.Map() + envVars, err := envVarService.Map(context.Background()) if err != nil { builderRegistry = &models.ContainerRegistry{ Server: c.BuilderRegistryServer, @@ -208,14 +208,14 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { - return buildService.Find(&services.BuildFilter{ + return buildService.Find(ctx, &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Id: &buildId, }, }) }, ListSuccessfulBuilds: func(ctx context.Context, repoUrl string) ([]*models.Build, error) { - buildDtos, err := buildService.List(&services.BuildFilter{ + buildDtos, err := buildService.List(ctx, &services.BuildFilter{ StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, StoreFilter: stores.BuildFilter{ RepositoryUrl: &repoUrl, @@ -232,7 +232,7 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele return builds, nil }, ListConfigsForUrl: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { - return server.GetInstance(nil).GitProviderService.ListConfigsForUrl(repoUrl) + return server.GetInstance(nil).GitProviderService.ListConfigsForUrl(ctx, repoUrl) }, CheckImageExists: func(ctx context.Context, image string) bool { _, _, err = cli.ImageInspectWithRaw(context.Background(), image) diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/server/bootstrap/get_server_instance.go index df82e39457..0177273e8f 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/server/bootstrap/get_server_instance.go @@ -57,47 +57,49 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe dbConnection := db.GetSQLiteConnection(dbPath) - apiKeyStore, err := db.NewApiKeyStore(dbConnection) + store := db.NewStore(dbConnection) + + apiKeyStore, err := db.NewApiKeyStore(store) if err != nil { return nil, err } - buildStore, err := db.NewBuildStore(dbConnection) + buildStore, err := db.NewBuildStore(store) if err != nil { return nil, err } - workspaceTemplateStore, err := db.NewWorkspaceTemplateStore(dbConnection) + workspaceTemplateStore, err := db.NewWorkspaceTemplateStore(store) if err != nil { return nil, err } - gitProviderConfigStore, err := db.NewGitProviderConfigStore(dbConnection) + gitProviderConfigStore, err := db.NewGitProviderConfigStore(store) if err != nil { return nil, err } - targetConfigStore, err := db.NewTargetConfigStore(dbConnection) + targetConfigStore, err := db.NewTargetConfigStore(store) if err != nil { return nil, err } - targetStore, err := db.NewTargetStore(dbConnection) + targetStore, err := db.NewTargetStore(store) if err != nil { return nil, err } - targetMetadataStore, err := db.NewTargetMetadataStore(dbConnection) + targetMetadataStore, err := db.NewTargetMetadataStore(store) if err != nil { return nil, err } - envVarStore, err := db.NewEnvironmentVariableStore(dbConnection) + envVarStore, err := db.NewEnvironmentVariableStore(store) if err != nil { return nil, err } - workspaceStore, err := db.NewWorkspaceStore(dbConnection) + workspaceStore, err := db.NewWorkspaceStore(store) if err != nil { return nil, err } - workspaceMetadataStore, err := db.NewWorkspaceMetadataStore(dbConnection) + workspaceMetadataStore, err := db.NewWorkspaceMetadataStore(store) if err != nil { return nil, err } - jobStore, err := db.NewJobStore(dbConnection) + jobStore, err := db.NewJobStore(store) if err != nil { return nil, err } @@ -120,7 +122,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe gitProviderService := gitproviders.NewGitProviderService(gitproviders.GitProviderServiceConfig{ ConfigStore: gitProviderConfigStore, DetachWorkspaceTemplates: func(ctx context.Context, gitProviderConfigId string) error { - workspaceTemplates, err := workspaceTemplateStore.List(&stores.WorkspaceTemplateFilter{ + workspaceTemplates, err := workspaceTemplateStore.List(ctx, &stores.WorkspaceTemplateFilter{ GitProviderConfigId: &gitProviderConfigId, }) @@ -130,7 +132,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe for _, workspaceTemplate := range workspaceTemplates { workspaceTemplate.GitProviderConfigId = nil - err = workspaceTemplateStore.Save(workspaceTemplate) + err = workspaceTemplateStore.Save(ctx, workspaceTemplate) if err != nil { return err } @@ -147,12 +149,12 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe buildService := builds.NewBuildService(builds.BuildServiceConfig{ BuildStore: buildStore, FindWorkspaceTemplate: func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) { - return workspaceTemplateStore.Find(&stores.WorkspaceTemplateFilter{ + return workspaceTemplateStore.Find(ctx, &stores.WorkspaceTemplateFilter{ Name: &name, }) }, GetRepositoryContext: func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) { - gitProvider, _, err := gitProviderService.GetGitProviderForUrl(url) + gitProvider, _, err := gitProviderService.GetGitProviderForUrl(ctx, url) if err != nil { return nil, err } @@ -164,7 +166,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return repo, err }, CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { - return jobService.Create(&models.Job{ + return jobService.Create(ctx, &models.Job{ ResourceId: workspaceId, ResourceType: models.ResourceTypeBuild, Action: action, @@ -180,7 +182,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe PrebuildWebhookEndpoint: prebuildWebhookEndpoint, ConfigStore: workspaceTemplateStore, FindNewestBuild: func(ctx context.Context, prebuildId string) (*services.BuildDTO, error) { - return buildService.Find(&services.BuildFilter{ + return buildService.Find(ctx, &services.BuildFilter{ StoreFilter: stores.BuildFilter{ PrebuildIds: &[]string{prebuildId}, GetNewest: util.Pointer(true), @@ -188,7 +190,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }) }, ListSuccessfulBuilds: func(ctx context.Context) ([]*services.BuildDTO, error) { - return buildService.List(&services.BuildFilter{ + return buildService.List(ctx, &services.BuildFilter{ StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, }) }, @@ -200,7 +202,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe EnvVars: workspaceTemplate.EnvVars, } - _, err := buildService.Create(createBuildDto) + _, err := buildService.Create(ctx, createBuildDto) return err }, DeleteBuilds: func(ctx context.Context, id, prebuildId *string, force bool) []error { @@ -209,7 +211,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe prebuildIds = &[]string{*prebuildId} } - return buildService.Delete(&services.BuildFilter{ + return buildService.Delete(ctx, &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Id: id, PrebuildIds: prebuildIds, @@ -217,7 +219,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }, force) }, GetRepositoryContext: func(ctx context.Context, url string) (*gitprovider.GitRepository, string, error) { - gitProvider, gitProviderId, err := gitProviderService.GetGitProviderForUrl(url) + gitProvider, gitProviderId, err := gitProviderService.GetGitProviderForUrl(ctx, url) if err != nil { return nil, "", err } @@ -229,16 +231,16 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return repo, gitProviderId, err }, FindPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { - return gitProviderService.GetPrebuildWebhook(gitProviderId, repo, endpointUrl) + return gitProviderService.GetPrebuildWebhook(ctx, gitProviderId, repo, endpointUrl) }, UnregisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error { - return gitProviderService.UnregisterPrebuildWebhook(gitProviderId, repo, id) + return gitProviderService.UnregisterPrebuildWebhook(ctx, gitProviderId, repo, id) }, RegisterPrebuildWebhook: func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { - return gitProviderService.RegisterPrebuildWebhook(gitProviderId, repo, endpointUrl) + return gitProviderService.RegisterPrebuildWebhook(ctx, gitProviderId, repo, endpointUrl) }, GetCommitsRange: func(ctx context.Context, repo *gitprovider.GitRepository, initialSha, currentSha string) (int, error) { - gitProvider, _, err := gitProviderService.GetGitProviderForUrl(repo.Url) + gitProvider, _, err := gitProviderService.GetGitProviderForUrl(ctx, repo.Url) if err != nil { return 0, err } @@ -247,7 +249,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }, }) - err = workspaceTemplateService.StartRetentionPoller() + err = workspaceTemplateService.StartRetentionPoller(context.Background()) if err != nil { return nil, err } @@ -256,7 +258,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if c.BuilderRegistryServer != "local" { envVarService := server.GetInstance(nil).EnvironmentVariableService - envVars, err := envVarService.Map() + envVars, err := envVarService.Map(context.Background()) if err != nil || envVars.FindContainerRegistry(c.BuilderRegistryServer) == nil { log.Errorf("Failed to find container registry credentials for builder registry server %s\n", c.BuilderRegistryServer) log.Errorf("Defaulting to local container registry. To use %s as the builder registry, add credentials for the registry server by adding them as environment variables using `daytona env set` and restart the server\n", c.BuilderRegistryServer) @@ -294,16 +296,16 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe TargetStore: targetStore, TargetMetadataStore: targetMetadataStore, FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { - return targetConfigService.Find(name) + return targetConfigService.Find(ctx, name) }, GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(models.ApiKeyTypeTarget, name) + return apiKeyService.Generate(ctx, models.ApiKeyTypeTarget, name) }, RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(name) + return apiKeyService.Revoke(ctx, name) }, CreateJob: func(ctx context.Context, targetId string, action models.JobAction) error { - return jobService.Create(&models.Job{ + return jobService.Create(ctx, &models.Job{ ResourceId: targetId, ResourceType: models.ResourceTypeTarget, Action: action, @@ -336,7 +338,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe models.ResourceStateNameRunSuccessful, } - build, err := buildService.Find(&services.BuildFilter{ + build, err := buildService.Find(ctx, &services.BuildFilter{ StateNames: &validStates, StoreFilter: stores.BuildFilter{ RepositoryUrl: &w.Repository.Url, @@ -360,22 +362,22 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }, nil }, GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(models.ApiKeyTypeWorkspace, name) + return apiKeyService.Generate(ctx, models.ApiKeyTypeWorkspace, name) }, RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(name) + return apiKeyService.Revoke(ctx, name) }, ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { - return gitProviderService.ListConfigsForUrl(repoUrl) + return gitProviderService.ListConfigsForUrl(ctx, repoUrl) }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(id) + return gitProviderService.GetConfig(ctx, id) }, GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { - return gitProviderService.GetLastCommitSha(repo) + return gitProviderService.GetLastCommitSha(ctx, repo) }, CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { - return jobService.Create(&models.Job{ + return jobService.Create(ctx, &models.Job{ ResourceId: workspaceId, ResourceType: models.ResourceTypeWorkspace, Action: action, diff --git a/pkg/cmd/server/bootstrap/init_provider_manager.go b/pkg/cmd/server/bootstrap/init_provider_manager.go index d0eefda6f0..7de47cad66 100644 --- a/pkg/cmd/server/bootstrap/init_provider_manager.go +++ b/pkg/cmd/server/bootstrap/init_provider_manager.go @@ -49,7 +49,9 @@ func InitProviderManager(c *server.Config, configDir string) error { dbConnection := db.GetSQLiteConnection(dbPath) - targetConfigStore, err := db.NewTargetConfigStore(dbConnection) + store := db.NewStore(dbConnection) + + targetConfigStore, err := db.NewTargetConfigStore(store) if err != nil { return err } @@ -72,10 +74,10 @@ func InitProviderManager(c *server.Config, configDir string) error { ServerPort: c.HeadscalePort, ApiPort: c.ApiPort, GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { - return targetConfigService.Map() + return targetConfigService.Map(ctx) }, CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { - _, err := targetConfigService.Add(services.AddTargetConfigDTO{ + _, err := targetConfigService.Add(ctx, services.AddTargetConfigDTO{ Name: name, Options: options, ProviderInfo: providerInfo, diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 1e7b374314..09ea6cfdd3 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -211,7 +211,7 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { } } - apiKey, err := server.ApiKeyService.Generate(models.ApiKeyTypeClient, "default") + apiKey, err := server.ApiKeyService.Generate(context.Background(), models.ApiKeyTypeClient, "default") if err != nil { return err } diff --git a/pkg/db/api_key_store.go b/pkg/db/api_key_store.go index 92afdd4433..01f17eb599 100644 --- a/pkg/db/api_key_store.go +++ b/pkg/db/api_key_store.go @@ -4,27 +4,30 @@ package db import ( + "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" - "gorm.io/gorm" ) type ApiKeyStore struct { - db *gorm.DB + Store } -func NewApiKeyStore(db *gorm.DB) (stores.ApiKeyStore, error) { - err := db.AutoMigrate(&models.ApiKey{}) +func NewApiKeyStore(store Store) (stores.ApiKeyStore, error) { + err := store.db.AutoMigrate(&models.ApiKey{}) if err != nil { return nil, err } - return &ApiKeyStore{db: db}, nil + return &ApiKeyStore{store}, nil } -func (a *ApiKeyStore) List() ([]*models.ApiKey, error) { +func (a *ApiKeyStore) List(ctx context.Context) ([]*models.ApiKey, error) { + tx := a.getTransaction(ctx) + apiKeys := []*models.ApiKey{} - tx := a.db.Find(&apiKeys) + tx = tx.Find(&apiKeys) if tx.Error != nil { return nil, tx.Error } @@ -32,9 +35,11 @@ func (a *ApiKeyStore) List() ([]*models.ApiKey, error) { return apiKeys, nil } -func (a *ApiKeyStore) Find(key string) (*models.ApiKey, error) { +func (a *ApiKeyStore) Find(ctx context.Context, key string) (*models.ApiKey, error) { + tx := a.getTransaction(ctx) + apiKey := &models.ApiKey{} - tx := a.db.Where("key_hash = ?", key).First(apiKey) + tx = tx.Where("key_hash = ?", key).First(apiKey) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrApiKeyNotFound @@ -45,9 +50,11 @@ func (a *ApiKeyStore) Find(key string) (*models.ApiKey, error) { return apiKey, nil } -func (a *ApiKeyStore) FindByName(name string) (*models.ApiKey, error) { +func (a *ApiKeyStore) FindByName(ctx context.Context, name string) (*models.ApiKey, error) { + tx := a.getTransaction(ctx) + apiKey := &models.ApiKey{} - tx := a.db.Where("name = ?", name).First(apiKey) + tx = tx.Where("name = ?", name).First(apiKey) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrApiKeyNotFound @@ -58,8 +65,10 @@ func (a *ApiKeyStore) FindByName(name string) (*models.ApiKey, error) { return apiKey, nil } -func (a *ApiKeyStore) Save(apiKey *models.ApiKey) error { - tx := a.db.Save(apiKey) +func (a *ApiKeyStore) Save(ctx context.Context, apiKey *models.ApiKey) error { + tx := a.getTransaction(ctx) + + tx = tx.Save(apiKey) if tx.Error != nil { return tx.Error } @@ -67,8 +76,10 @@ func (a *ApiKeyStore) Save(apiKey *models.ApiKey) error { return nil } -func (a *ApiKeyStore) Delete(apiKey *models.ApiKey) error { - tx := a.db.Where("key_hash = ?", apiKey.KeyHash).Delete(&models.ApiKey{}) +func (a *ApiKeyStore) Delete(ctx context.Context, apiKey *models.ApiKey) error { + tx := a.getTransaction(ctx) + + tx = tx.Where("key_hash = ?", apiKey.KeyHash).Delete(&models.ApiKey{}) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index b11c5799a8..0d44913794 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -4,6 +4,7 @@ package db import ( + "context" "encoding/json" "fmt" "strings" @@ -15,25 +16,27 @@ import ( ) type BuildStore struct { - db *gorm.DB + Store Lock sync.Mutex } -func NewBuildStore(db *gorm.DB) (stores.BuildStore, error) { - err := db.AutoMigrate(&models.Build{}) +func NewBuildStore(store Store) (stores.BuildStore, error) { + err := store.db.AutoMigrate(&models.Build{}) if err != nil { return nil, err } - return &BuildStore{db: db}, nil + return &BuildStore{store, sync.Mutex{}}, nil } -func (b *BuildStore) Find(filter *stores.BuildFilter) (*models.Build, error) { +func (b *BuildStore) Find(ctx context.Context, filter *stores.BuildFilter) (*models.Build, error) { b.Lock.Lock() defer b.Lock.Unlock() + tx := b.getTransaction(ctx) + build := &models.Build{} - tx := preloadBuildEntities(processBuildFilters(b.db, filter)).First(build) + tx = preloadBuildEntities(processBuildFilters(tx, filter)).First(build) if tx.Error != nil { if tx.Error == gorm.ErrRecordNotFound { @@ -45,12 +48,14 @@ func (b *BuildStore) Find(filter *stores.BuildFilter) (*models.Build, error) { return build, nil } -func (b *BuildStore) List(filter *stores.BuildFilter) ([]*models.Build, error) { +func (b *BuildStore) List(ctx context.Context, filter *stores.BuildFilter) ([]*models.Build, error) { b.Lock.Lock() defer b.Lock.Unlock() + tx := b.getTransaction(ctx) + builds := []*models.Build{} - tx := preloadBuildEntities(processBuildFilters(b.db, filter)).Find(&builds) + tx = preloadBuildEntities(processBuildFilters(tx, filter)).Find(&builds) if tx.Error != nil { return nil, tx.Error @@ -59,11 +64,13 @@ func (b *BuildStore) List(filter *stores.BuildFilter) ([]*models.Build, error) { return builds, nil } -func (b *BuildStore) Save(build *models.Build) error { +func (b *BuildStore) Save(ctx context.Context, build *models.Build) error { b.Lock.Lock() defer b.Lock.Unlock() - tx := b.db.Save(build) + tx := b.getTransaction(ctx) + + tx = tx.Save(build) if tx.Error != nil { return tx.Error } @@ -71,11 +78,12 @@ func (b *BuildStore) Save(build *models.Build) error { return nil } -func (b *BuildStore) Delete(id string) error { +func (b *BuildStore) Delete(ctx context.Context, id string) error { b.Lock.Lock() defer b.Lock.Unlock() + tx := b.getTransaction(ctx) - tx := b.db.Where("id = ?", id).Delete(&models.Build{}) + tx = tx.Where("id = ?", id).Delete(&models.Build{}) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/connection.go b/pkg/db/connection.go index 1d791b6137..3b058722cb 100644 --- a/pkg/db/connection.go +++ b/pkg/db/connection.go @@ -44,6 +44,12 @@ func GetSQLiteConnection(dbPath string) *gorm.DB { if err != nil { panic("failed to connect database") } + sqlDB, err := db.DB() + if err != nil { + panic("failed to connect database") + } + + sqlDB.SetMaxOpenConns(1) _db = db diff --git a/pkg/db/db_store.go b/pkg/db/db_store.go new file mode 100644 index 0000000000..5abb774fe6 --- /dev/null +++ b/pkg/db/db_store.go @@ -0,0 +1,67 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "context" + "fmt" + + "gorm.io/gorm" + + "github.com/daytonaio/daytona/pkg/stores" +) + +type Store struct { + db *gorm.DB +} + +func NewStore(db *gorm.DB) Store { + return Store{db} +} + +func (s *Store) BeginTransaction(ctx context.Context) (context.Context, error) { + if ctx.Value(stores.TransactionKey{}) != nil { + return ctx, nil + } + + tx := s.db.Begin() + if tx.Error != nil { + return nil, tx.Error + } + + ctx = context.WithValue(ctx, stores.TransactionKey{}, tx) + return ctx, nil +} + +func (s *Store) CommitTransaction(ctx context.Context) error { + tx, ok := ctx.Value(stores.TransactionKey{}).(*gorm.DB) + if !ok { + return nil + } + + return tx.Commit().Error +} + +func (s *Store) RollbackTransaction(ctx context.Context, err error) error { + tx, ok := ctx.Value(stores.TransactionKey{}).(*gorm.DB) + if !ok { + return err + } + + txErr := tx.Rollback().Error + if txErr == nil { + return err + } + + return fmt.Errorf("%w. Transaction rollback error: %w", err, txErr) +} + +func (s *Store) getTransaction(ctx context.Context) *gorm.DB { + tx, ok := ctx.Value(stores.TransactionKey{}).(*gorm.DB) + if !ok { + return s.db + } + + return tx +} diff --git a/pkg/db/env.go b/pkg/db/env.go deleted file mode 100644 index c7f08a3c7d..0000000000 --- a/pkg/db/env.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package db - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/stores" - "gorm.io/gorm" -) - -type EnvironmentVariableStore struct { - db *gorm.DB -} - -func NewEnvironmentVariableStore(db *gorm.DB) (*EnvironmentVariableStore, error) { - err := db.AutoMigrate(&models.EnvironmentVariable{}) - if err != nil { - return nil, err - } - - return &EnvironmentVariableStore{db: db}, nil -} - -func (store *EnvironmentVariableStore) List() ([]*models.EnvironmentVariable, error) { - environmentVariables := []*models.EnvironmentVariable{} - tx := store.db.Find(&environmentVariables) - if tx.Error != nil { - if tx.Error == gorm.ErrRecordNotFound { - return nil, stores.ErrEnvironmentVariableNotFound - } - return nil, tx.Error - } - - return environmentVariables, nil -} - -func (store *EnvironmentVariableStore) Save(environmentVariable *models.EnvironmentVariable) error { - tx := store.db.Save(environmentVariable) - if tx.Error != nil { - return tx.Error - } - - return nil -} - -func (store *EnvironmentVariableStore) Delete(key string) error { - tx := store.db.Where("key = ?", key).Delete(&models.EnvironmentVariable{}) - if tx.Error != nil { - return tx.Error - } - if tx.RowsAffected == 0 { - return stores.ErrEnvironmentVariableNotFound - } - - return nil -} diff --git a/pkg/db/env_store.go b/pkg/db/env_store.go new file mode 100644 index 0000000000..5804f1627b --- /dev/null +++ b/pkg/db/env_store.go @@ -0,0 +1,65 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" + "gorm.io/gorm" +) + +type EnvironmentVariableStore struct { + Store +} + +func NewEnvironmentVariableStore(store Store) (stores.EnvironmentVariableStore, error) { + err := store.db.AutoMigrate(&models.EnvironmentVariable{}) + if err != nil { + return nil, err + } + + return &EnvironmentVariableStore{store}, nil +} + +func (store *EnvironmentVariableStore) List(ctx context.Context) ([]*models.EnvironmentVariable, error) { + tx := store.getTransaction(ctx) + + environmentVariables := []*models.EnvironmentVariable{} + tx = tx.Find(&environmentVariables) + if tx.Error != nil { + if tx.Error == gorm.ErrRecordNotFound { + return nil, stores.ErrEnvironmentVariableNotFound + } + return nil, tx.Error + } + + return environmentVariables, nil +} + +func (store *EnvironmentVariableStore) Save(ctx context.Context, environmentVariable *models.EnvironmentVariable) error { + tx := store.getTransaction(ctx) + + tx = tx.Save(environmentVariable) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (store *EnvironmentVariableStore) Delete(ctx context.Context, key string) error { + tx := store.getTransaction(ctx) + + tx = tx.Where("key = ?", key).Delete(&models.EnvironmentVariable{}) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrEnvironmentVariableNotFound + } + + return nil +} diff --git a/pkg/db/gitprovider_config_store.go b/pkg/db/gitprovider_config_store.go index ca398b7567..209aa16d25 100644 --- a/pkg/db/gitprovider_config_store.go +++ b/pkg/db/gitprovider_config_store.go @@ -4,28 +4,30 @@ package db import ( - "gorm.io/gorm" + "context" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type GitProviderConfigStore struct { - db *gorm.DB + Store } -func NewGitProviderConfigStore(db *gorm.DB) (stores.GitProviderConfigStore, error) { - err := db.AutoMigrate(&models.GitProviderConfig{}) +func NewGitProviderConfigStore(store Store) (stores.GitProviderConfigStore, error) { + err := store.db.AutoMigrate(&models.GitProviderConfig{}) if err != nil { return nil, err } - return &GitProviderConfigStore{db: db}, nil + return &GitProviderConfigStore{store}, nil } -func (p *GitProviderConfigStore) List() ([]*models.GitProviderConfig, error) { +func (p *GitProviderConfigStore) List(ctx context.Context) ([]*models.GitProviderConfig, error) { + tx := p.getTransaction(ctx) + gitProviders := []*models.GitProviderConfig{} - tx := p.db.Find(&gitProviders) + tx = tx.Find(&gitProviders) if tx.Error != nil { return nil, tx.Error } @@ -33,9 +35,11 @@ func (p *GitProviderConfigStore) List() ([]*models.GitProviderConfig, error) { return gitProviders, nil } -func (p *GitProviderConfigStore) Find(id string) (*models.GitProviderConfig, error) { +func (p *GitProviderConfigStore) Find(ctx context.Context, id string) (*models.GitProviderConfig, error) { + tx := p.getTransaction(ctx) + gitProvider := &models.GitProviderConfig{} - tx := p.db.Where("id = ?", id).First(gitProvider) + tx = tx.Where("id = ?", id).First(gitProvider) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrGitProviderConfigNotFound @@ -46,8 +50,10 @@ func (p *GitProviderConfigStore) Find(id string) (*models.GitProviderConfig, err return gitProvider, nil } -func (p *GitProviderConfigStore) Save(gitProvider *models.GitProviderConfig) error { - tx := p.db.Save(gitProvider) +func (p *GitProviderConfigStore) Save(ctx context.Context, gitProvider *models.GitProviderConfig) error { + tx := p.getTransaction(ctx) + + tx = tx.Save(gitProvider) if tx.Error != nil { return tx.Error } @@ -55,8 +61,10 @@ func (p *GitProviderConfigStore) Save(gitProvider *models.GitProviderConfig) err return nil } -func (p *GitProviderConfigStore) Delete(gitProvider *models.GitProviderConfig) error { - tx := p.db.Delete(gitProvider) +func (p *GitProviderConfigStore) Delete(ctx context.Context, gitProvider *models.GitProviderConfig) error { + tx := p.getTransaction(ctx) + + tx = tx.Delete(gitProvider) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/job_store.go b/pkg/db/job_store.go index f2d4e6a3fa..e285aee5a8 100644 --- a/pkg/db/job_store.go +++ b/pkg/db/job_store.go @@ -4,6 +4,7 @@ package db import ( + "context" "fmt" "strings" @@ -13,21 +14,23 @@ import ( ) type JobStore struct { - db *gorm.DB + Store } -func NewJobStore(db *gorm.DB) (*JobStore, error) { - err := db.AutoMigrate(&models.Job{}) +func NewJobStore(store Store) (stores.JobStore, error) { + err := store.db.AutoMigrate(&models.Job{}) if err != nil { return nil, err } - return &JobStore{db: db}, nil + return &JobStore{store}, nil } -func (s *JobStore) List(filter *stores.JobFilter) ([]*models.Job, error) { +func (s *JobStore) List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) { + tx := s.getTransaction(ctx) + jobs := []*models.Job{} - tx := processJobFilters(s.db, filter).Find(&jobs) + tx = processJobFilters(tx, filter).Find(&jobs) if tx.Error != nil { return nil, tx.Error @@ -36,9 +39,11 @@ func (s *JobStore) List(filter *stores.JobFilter) ([]*models.Job, error) { return jobs, nil } -func (s *JobStore) Find(filter *stores.JobFilter) (*models.Job, error) { +func (s *JobStore) Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) { + tx := s.getTransaction(ctx) + job := &models.Job{} - tx := processJobFilters(s.db, filter).First(&job) + tx = processJobFilters(tx, filter).First(&job) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrJobNotFound @@ -50,8 +55,10 @@ func (s *JobStore) Find(filter *stores.JobFilter) (*models.Job, error) { } -func (s *JobStore) Save(job *models.Job) error { - tx := s.db.Save(job) +func (s *JobStore) Save(ctx context.Context, job *models.Job) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(job) if tx.Error != nil { return tx.Error } @@ -59,8 +66,10 @@ func (s *JobStore) Save(job *models.Job) error { return nil } -func (s *JobStore) Delete(job *models.Job) error { - tx := s.db.Delete(job) +func (s *JobStore) Delete(ctx context.Context, job *models.Job) error { + tx := s.getTransaction(ctx) + + tx = tx.Delete(job) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index e8f4a9b393..3e13744ad9 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -4,6 +4,8 @@ package db import ( + "context" + "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" @@ -11,21 +13,23 @@ import ( ) type TargetConfigStore struct { - db *gorm.DB + Store } -func NewTargetConfigStore(db *gorm.DB) (stores.TargetConfigStore, error) { - err := db.AutoMigrate(&models.TargetConfig{}) +func NewTargetConfigStore(store Store) (stores.TargetConfigStore, error) { + err := store.db.AutoMigrate(&models.TargetConfig{}) if err != nil { return nil, err } - return &TargetConfigStore{db: db}, nil + return &TargetConfigStore{store}, nil } -func (s *TargetConfigStore) List(allowDeleted bool) ([]*models.TargetConfig, error) { +func (s *TargetConfigStore) List(ctx context.Context, allowDeleted bool) ([]*models.TargetConfig, error) { + tx := s.getTransaction(ctx) + targetConfigs := []*models.TargetConfig{} - tx := processTargetConfigFilters(s.db, "", allowDeleted).Find(&targetConfigs) + tx = processTargetConfigFilters(tx, "", allowDeleted).Find(&targetConfigs) if tx.Error != nil { return nil, tx.Error @@ -34,9 +38,11 @@ func (s *TargetConfigStore) List(allowDeleted bool) ([]*models.TargetConfig, err return targetConfigs, nil } -func (s *TargetConfigStore) Find(idOrName string, allowDeleted bool) (*models.TargetConfig, error) { +func (s *TargetConfigStore) Find(ctx context.Context, idOrName string, allowDeleted bool) (*models.TargetConfig, error) { + tx := s.getTransaction(ctx) + targetConfig := &models.TargetConfig{} - tx := processTargetConfigFilters(s.db, idOrName, allowDeleted).First(targetConfig) + tx = processTargetConfigFilters(tx, idOrName, allowDeleted).First(targetConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { @@ -48,8 +54,10 @@ func (s *TargetConfigStore) Find(idOrName string, allowDeleted bool) (*models.Ta return targetConfig, nil } -func (s *TargetConfigStore) Save(targetConfig *models.TargetConfig) error { - tx := s.db.Save(targetConfig) +func (s *TargetConfigStore) Save(ctx context.Context, targetConfig *models.TargetConfig) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(targetConfig) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/target_metadata_store.go b/pkg/db/target_metadata_store.go index 6bfce8d3e1..d0872815b4 100644 --- a/pkg/db/target_metadata_store.go +++ b/pkg/db/target_metadata_store.go @@ -4,6 +4,8 @@ package db import ( + "context" + "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" @@ -11,21 +13,23 @@ import ( ) type TargetMetadataStore struct { - db *gorm.DB + Store } -func NewTargetMetadataStore(db *gorm.DB) (*TargetMetadataStore, error) { - err := db.AutoMigrate(&models.TargetMetadata{}) +func NewTargetMetadataStore(store Store) (stores.TargetMetadataStore, error) { + err := store.db.AutoMigrate(&models.TargetMetadata{}) if err != nil { return nil, err } - return &TargetMetadataStore{db: db}, nil + return &TargetMetadataStore{store}, nil } -func (s *TargetMetadataStore) Find(filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { +func (s *TargetMetadataStore) Find(ctx context.Context, filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { + tx := s.getTransaction(ctx) + targetMetadata := &models.TargetMetadata{} - tx := processTargetMetadataFilters(s.db, filter).First(&targetMetadata) + tx = processTargetMetadataFilters(tx, filter).First(&targetMetadata) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrTargetMetadataNotFound @@ -36,8 +40,10 @@ func (s *TargetMetadataStore) Find(filter *stores.TargetMetadataFilter) (*models return targetMetadata, nil } -func (s *TargetMetadataStore) Save(targetMetadata *models.TargetMetadata) error { - tx := s.db.Save(targetMetadata) +func (s *TargetMetadataStore) Save(ctx context.Context, targetMetadata *models.TargetMetadata) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(targetMetadata) if tx.Error != nil { return tx.Error } @@ -45,8 +51,10 @@ func (s *TargetMetadataStore) Save(targetMetadata *models.TargetMetadata) error return nil } -func (s *TargetMetadataStore) Delete(targetMetadata *models.TargetMetadata) error { - tx := s.db.Delete(targetMetadata) +func (s *TargetMetadataStore) Delete(ctx context.Context, targetMetadata *models.TargetMetadata) error { + tx := s.getTransaction(ctx) + + tx = tx.Delete(targetMetadata) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index 530cde4345..baeca12483 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -4,6 +4,8 @@ package db import ( + "context" + "gorm.io/gorm" "gorm.io/gorm/clause" @@ -12,32 +14,36 @@ import ( ) type TargetStore struct { - db *gorm.DB + Store } -func NewTargetStore(db *gorm.DB) (stores.TargetStore, error) { - err := db.AutoMigrate(&models.Target{}) +func NewTargetStore(store Store) (stores.TargetStore, error) { + err := store.db.AutoMigrate(&models.Target{}) if err != nil { return nil, err } - return &TargetStore{db: db}, nil + return &TargetStore{store}, nil } -func (s *TargetStore) List(filter *stores.TargetFilter) ([]*models.Target, error) { +func (s *TargetStore) List(ctx context.Context, filter *stores.TargetFilter) ([]*models.Target, error) { + tx := s.getTransaction(ctx) + targets := []*models.Target{} - tx := preloadTargetEntities(processTargetFilters(s.db, filter)).Find(&targets) + tx = preloadTargetEntities(processTargetFilters(tx, filter)).Find(&targets) if tx.Error != nil { return nil, tx.Error } return targets, nil } -func (s *TargetStore) Find(filter *stores.TargetFilter) (*models.Target, error) { +func (s *TargetStore) Find(ctx context.Context, filter *stores.TargetFilter) (*models.Target, error) { + tx := s.getTransaction(ctx) + tg := &models.Target{} - tx := preloadTargetEntities(processTargetFilters(s.db, filter)).First(tg) + tx = preloadTargetEntities(processTargetFilters(tx, filter)).First(tg) if tx.Error != nil { return nil, tx.Error } @@ -51,8 +57,10 @@ func (s *TargetStore) Find(filter *stores.TargetFilter) (*models.Target, error) return tg, nil } -func (s *TargetStore) Save(target *models.Target) error { - tx := s.db.Save(target) +func (s *TargetStore) Save(ctx context.Context, target *models.Target) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(target) if tx.Error != nil { return tx.Error } @@ -60,8 +68,10 @@ func (s *TargetStore) Save(target *models.Target) error { return nil } -func (s *TargetStore) Delete(t *models.Target) error { - tx := s.db.Delete(t) +func (s *TargetStore) Delete(ctx context.Context, t *models.Target) error { + tx := s.getTransaction(ctx) + + tx = tx.Delete(t) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/workspace_metadata_store.go b/pkg/db/workspace_metadata_store.go index 4ce2f626c1..8c27556cd8 100644 --- a/pkg/db/workspace_metadata_store.go +++ b/pkg/db/workspace_metadata_store.go @@ -4,6 +4,8 @@ package db import ( + "context" + "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" @@ -11,21 +13,23 @@ import ( ) type WorkspaceMetadataStore struct { - db *gorm.DB + Store } -func NewWorkspaceMetadataStore(db *gorm.DB) (*WorkspaceMetadataStore, error) { - err := db.AutoMigrate(&models.WorkspaceMetadata{}) +func NewWorkspaceMetadataStore(store Store) (stores.WorkspaceMetadataStore, error) { + err := store.db.AutoMigrate(&models.WorkspaceMetadata{}) if err != nil { return nil, err } - return &WorkspaceMetadataStore{db: db}, nil + return &WorkspaceMetadataStore{store}, nil } -func (s *WorkspaceMetadataStore) Find(filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { +func (s *WorkspaceMetadataStore) Find(ctx context.Context, filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { + tx := s.getTransaction(ctx) + workspaceMetadata := &models.WorkspaceMetadata{} - tx := processWorkspaceMetadataFilters(s.db, filter).First(&workspaceMetadata) + tx = processWorkspaceMetadataFilters(tx, filter).First(&workspaceMetadata) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrWorkspaceMetadataNotFound @@ -36,8 +40,10 @@ func (s *WorkspaceMetadataStore) Find(filter *stores.WorkspaceMetadataFilter) (* return workspaceMetadata, nil } -func (s *WorkspaceMetadataStore) Save(workspaceMetadata *models.WorkspaceMetadata) error { - tx := s.db.Save(workspaceMetadata) +func (s *WorkspaceMetadataStore) Save(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(workspaceMetadata) if tx.Error != nil { return tx.Error } @@ -45,8 +51,10 @@ func (s *WorkspaceMetadataStore) Save(workspaceMetadata *models.WorkspaceMetadat return nil } -func (s *WorkspaceMetadataStore) Delete(workspaceMetadata *models.WorkspaceMetadata) error { - tx := s.db.Delete(workspaceMetadata) +func (s *WorkspaceMetadataStore) Delete(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { + tx := s.getTransaction(ctx) + + tx = tx.Delete(workspaceMetadata) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go index 92cb7cf373..1c715772ce 100644 --- a/pkg/db/workspace_store.go +++ b/pkg/db/workspace_store.go @@ -4,6 +4,8 @@ package db import ( + "context" + "gorm.io/gorm" "gorm.io/gorm/clause" @@ -12,21 +14,23 @@ import ( ) type WorkspaceStore struct { - db *gorm.DB + Store } -func NewWorkspaceStore(db *gorm.DB) (*WorkspaceStore, error) { - err := db.AutoMigrate(&models.Workspace{}) +func NewWorkspaceStore(store Store) (stores.WorkspaceStore, error) { + err := store.db.AutoMigrate(&models.Workspace{}) if err != nil { return nil, err } - return &WorkspaceStore{db: db}, nil + return &WorkspaceStore{store}, nil } -func (s *WorkspaceStore) List() ([]*models.Workspace, error) { +func (s *WorkspaceStore) List(ctx context.Context) ([]*models.Workspace, error) { + tx := s.getTransaction(ctx) + workspaces := []*models.Workspace{} - tx := preloadWorkspaceEntities(s.db).Find(&workspaces) + tx = preloadWorkspaceEntities(tx).Find(&workspaces) if tx.Error != nil { return nil, tx.Error } @@ -34,9 +38,11 @@ func (s *WorkspaceStore) List() ([]*models.Workspace, error) { return workspaces, nil } -func (s *WorkspaceStore) Find(idOrName string) (*models.Workspace, error) { +func (s *WorkspaceStore) Find(ctx context.Context, idOrName string) (*models.Workspace, error) { + tx := s.getTransaction(ctx) + workspace := &models.Workspace{} - tx := preloadWorkspaceEntities(s.db).Where("id = ? OR name = ?", idOrName, idOrName).First(workspace) + tx = preloadWorkspaceEntities(tx).Where("id = ? OR name = ?", idOrName, idOrName).First(workspace) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrWorkspaceNotFound @@ -47,8 +53,10 @@ func (s *WorkspaceStore) Find(idOrName string) (*models.Workspace, error) { return workspace, nil } -func (s *WorkspaceStore) Save(workspace *models.Workspace) error { - tx := s.db.Save(workspace) +func (s *WorkspaceStore) Save(ctx context.Context, workspace *models.Workspace) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(workspace) if tx.Error != nil { return tx.Error } @@ -56,8 +64,10 @@ func (s *WorkspaceStore) Save(workspace *models.Workspace) error { return nil } -func (s *WorkspaceStore) Delete(workspace *models.Workspace) error { - tx := s.db.Delete(workspace) +func (s *WorkspaceStore) Delete(ctx context.Context, workspace *models.Workspace) error { + tx := s.getTransaction(ctx) + + tx = tx.Delete(workspace) if tx.Error != nil { return tx.Error } diff --git a/pkg/db/workspace_template_store.go b/pkg/db/workspace_template_store.go index 0931cea723..183b2f626e 100644 --- a/pkg/db/workspace_template_store.go +++ b/pkg/db/workspace_template_store.go @@ -4,6 +4,8 @@ package db import ( + "context" + "gorm.io/gorm" "github.com/daytonaio/daytona/pkg/models" @@ -11,21 +13,23 @@ import ( ) type WorkspaceTemplateStore struct { - db *gorm.DB + Store } -func NewWorkspaceTemplateStore(db *gorm.DB) (*WorkspaceTemplateStore, error) { - err := db.AutoMigrate(&models.WorkspaceTemplate{}) +func NewWorkspaceTemplateStore(store Store) (stores.WorkspaceTemplateStore, error) { + err := store.db.AutoMigrate(&models.WorkspaceTemplate{}) if err != nil { return nil, err } - return &WorkspaceTemplateStore{db: db}, nil + return &WorkspaceTemplateStore{store}, nil } -func (s *WorkspaceTemplateStore) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { +func (s *WorkspaceTemplateStore) List(ctx context.Context, filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + tx := s.getTransaction(ctx) + workspaceTemplates := []*models.WorkspaceTemplate{} - tx := processWorkspaceTemplateFilters(s.db, filter).Find(&workspaceTemplates) + tx = processWorkspaceTemplateFilters(tx, filter).Find(&workspaceTemplates) if tx.Error != nil { return nil, tx.Error @@ -34,9 +38,11 @@ func (s *WorkspaceTemplateStore) List(filter *stores.WorkspaceTemplateFilter) ([ return workspaceTemplates, nil } -func (s *WorkspaceTemplateStore) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { +func (s *WorkspaceTemplateStore) Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { + tx := s.getTransaction(ctx) + workspaceTemplate := &models.WorkspaceTemplate{} - tx := processWorkspaceTemplateFilters(s.db, filter).First(workspaceTemplate) + tx = processWorkspaceTemplateFilters(tx, filter).First(workspaceTemplate) if tx.Error != nil { if IsRecordNotFound(tx.Error) { @@ -48,8 +54,10 @@ func (s *WorkspaceTemplateStore) Find(filter *stores.WorkspaceTemplateFilter) (* return workspaceTemplate, nil } -func (s *WorkspaceTemplateStore) Save(workspaceTemplate *models.WorkspaceTemplate) error { - tx := s.db.Save(workspaceTemplate) +func (s *WorkspaceTemplateStore) Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { + tx := s.getTransaction(ctx) + + tx = tx.Save(workspaceTemplate) if tx.Error != nil { return tx.Error } @@ -57,8 +65,10 @@ func (s *WorkspaceTemplateStore) Save(workspaceTemplate *models.WorkspaceTemplat return nil } -func (s *WorkspaceTemplateStore) Delete(workspaceTemplate *models.WorkspaceTemplate) error { - tx := s.db.Delete(workspaceTemplate) +func (s *WorkspaceTemplateStore) Delete(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { + tx := s.getTransaction(ctx) + + tx = tx.Delete(workspaceTemplate) if tx.Error != nil { return tx.Error } diff --git a/pkg/server/apikeys/apikeys.go b/pkg/server/apikeys/apikeys.go index 59c8b9fec9..27c303a96f 100644 --- a/pkg/server/apikeys/apikeys.go +++ b/pkg/server/apikeys/apikeys.go @@ -4,12 +4,14 @@ package apikeys import ( + "context" + "github.com/daytonaio/daytona/internal/apikeys" "github.com/daytonaio/daytona/pkg/models" ) -func (s *ApiKeyService) ListClientKeys() ([]*models.ApiKey, error) { - keys, err := s.apiKeyStore.List() +func (s *ApiKeyService) ListClientKeys(ctx context.Context) ([]*models.ApiKey, error) { + keys, err := s.apiKeyStore.List(ctx) if err != nil { return nil, err } @@ -25,16 +27,16 @@ func (s *ApiKeyService) ListClientKeys() ([]*models.ApiKey, error) { return clientKeys, nil } -func (s *ApiKeyService) Revoke(name string) error { - apiKey, err := s.apiKeyStore.FindByName(name) +func (s *ApiKeyService) Revoke(ctx context.Context, name string) error { + apiKey, err := s.apiKeyStore.FindByName(ctx, name) if err != nil { return err } - return s.apiKeyStore.Delete(apiKey) + return s.apiKeyStore.Delete(ctx, apiKey) } -func (s *ApiKeyService) Generate(keyType models.ApiKeyType, name string) (string, error) { +func (s *ApiKeyService) Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) { key := apikeys.GenerateRandomKey() apiKey := &models.ApiKey{ @@ -43,7 +45,7 @@ func (s *ApiKeyService) Generate(keyType models.ApiKeyType, name string) (string Name: name, } - err := s.apiKeyStore.Save(apiKey) + err := s.apiKeyStore.Save(ctx, apiKey) if err != nil { return "", err } diff --git a/pkg/server/apikeys/apikeys_test.go b/pkg/server/apikeys/apikeys_test.go index cbc9ba6e47..bbf21ba0e8 100644 --- a/pkg/server/apikeys/apikeys_test.go +++ b/pkg/server/apikeys/apikeys_test.go @@ -4,6 +4,8 @@ package apikeys_test import ( + "context" + "github.com/daytonaio/daytona/pkg/models" ) @@ -13,13 +15,13 @@ func (s *ApiKeyServiceTestSuite) TestListClientKeys() { keyNames = append(keyNames, clientKeyNames...) for _, keyName := range keyNames { - apiKey, _ := s.apiKeyStore.FindByName(keyName) + apiKey, _ := s.apiKeyStore.FindByName(context.TODO(), keyName) expectedKeys = append(expectedKeys, apiKey) } require := s.Require() - keys, err := s.apiKeyService.ListClientKeys() + keys, err := s.apiKeyService.ListClientKeys(context.TODO()) require.Nil(err) require.ElementsMatch(expectedKeys, keys) @@ -32,16 +34,16 @@ func (s *ApiKeyServiceTestSuite) TestRevoke() { keyNames = append(keyNames, clientKeyNames[1:]...) keyNames = append(keyNames, workspaceKeyNames...) for _, keyName := range keyNames { - apiKey, _ := s.apiKeyStore.FindByName(keyName) + apiKey, _ := s.apiKeyStore.FindByName(context.TODO(), keyName) expectedKeys = append(expectedKeys, apiKey) } require := s.Require() - err := s.apiKeyService.Revoke(clientKeyNames[0]) + err := s.apiKeyService.Revoke(context.TODO(), clientKeyNames[0]) require.Nil(err) - keys, err := s.apiKeyStore.List() + keys, err := s.apiKeyStore.List(context.TODO()) require.Nil(err) require.ElementsMatch(expectedKeys, keys) } @@ -53,7 +55,7 @@ func (s *ApiKeyServiceTestSuite) TestGenerate() { keyNames = append(keyNames, clientKeyNames...) keyNames = append(keyNames, workspaceKeyNames...) for _, keyName := range keyNames { - apiKey, _ := s.apiKeyStore.FindByName(keyName) + apiKey, _ := s.apiKeyStore.FindByName(context.TODO(), keyName) expectedKeys = append(expectedKeys, apiKey) } @@ -61,14 +63,14 @@ func (s *ApiKeyServiceTestSuite) TestGenerate() { require := s.Require() - _, err := s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) + _, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) require.Nil(err) - apiKey, err := s.apiKeyStore.FindByName(keyName) + apiKey, err := s.apiKeyStore.FindByName(context.TODO(), keyName) require.Nil(err) expectedKeys = append(expectedKeys, apiKey) - apiKeys, err := s.apiKeyStore.List() + apiKeys, err := s.apiKeyStore.List(context.TODO()) require.Nil(err) require.ElementsMatch(expectedKeys, apiKeys) } diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index 4e49149558..8d36e10773 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -4,6 +4,7 @@ package apikeys_test import ( + "context" "testing" t_apikeys "github.com/daytonaio/daytona/internal/testing/server/apikeys" @@ -34,11 +35,11 @@ func (s *ApiKeyServiceTestSuite) SetupTest() { }) for _, keyName := range clientKeyNames { - _, _ = s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) + _, _ = s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) } for _, keyName := range workspaceKeyNames { - _, _ = s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, keyName) + _, _ = s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) } } diff --git a/pkg/server/apikeys/validate.go b/pkg/server/apikeys/validate.go index 121b230628..abe4104816 100644 --- a/pkg/server/apikeys/validate.go +++ b/pkg/server/apikeys/validate.go @@ -4,21 +4,23 @@ package apikeys import ( + "context" + "github.com/daytonaio/daytona/internal/apikeys" "github.com/daytonaio/daytona/pkg/models" ) -func (s *ApiKeyService) IsValidApiKey(apiKey string) bool { +func (s *ApiKeyService) IsValidApiKey(ctx context.Context, apiKey string) bool { keyHash := apikeys.HashKey(apiKey) - _, err := s.apiKeyStore.Find(keyHash) + _, err := s.apiKeyStore.Find(ctx, keyHash) return err == nil } -func (s *ApiKeyService) IsWorkspaceApiKey(apiKey string) bool { +func (s *ApiKeyService) IsWorkspaceApiKey(ctx context.Context, apiKey string) bool { keyHash := apikeys.HashKey(apiKey) - key, err := s.apiKeyStore.Find(keyHash) + key, err := s.apiKeyStore.Find(ctx, keyHash) if err != nil { return false } @@ -30,10 +32,10 @@ func (s *ApiKeyService) IsWorkspaceApiKey(apiKey string) bool { return true } -func (s *ApiKeyService) IsTargetApiKey(apiKey string) bool { +func (s *ApiKeyService) IsTargetApiKey(ctx context.Context, apiKey string) bool { keyHash := apikeys.HashKey(apiKey) - key, err := s.apiKeyStore.Find(keyHash) + key, err := s.apiKeyStore.Find(ctx, keyHash) if err != nil { return false } diff --git a/pkg/server/apikeys/validate_test.go b/pkg/server/apikeys/validate_test.go index dc527db45b..22c5b66fb5 100644 --- a/pkg/server/apikeys/validate_test.go +++ b/pkg/server/apikeys/validate_test.go @@ -3,17 +3,21 @@ package apikeys_test -import "github.com/daytonaio/daytona/pkg/models" +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" +) func (s *ApiKeyServiceTestSuite) TestIsValidKey_True() { keyName := "api-key" require := s.Require() - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) require.Nil(err) - res := s.apiKeyService.IsValidApiKey(apiKey) + res := s.apiKeyService.IsValidApiKey(context.TODO(), apiKey) require.True(res) } @@ -22,7 +26,7 @@ func (s *ApiKeyServiceTestSuite) TestIsValidKey_False() { require := s.Require() - res := s.apiKeyService.IsValidApiKey(unknownKey) + res := s.apiKeyService.IsValidApiKey(context.TODO(), unknownKey) require.False(res) } @@ -31,10 +35,10 @@ func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_True() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) require.Nil(err) - res := s.apiKeyService.IsWorkspaceApiKey(apiKey) + res := s.apiKeyService.IsWorkspaceApiKey(context.TODO(), apiKey) require.True(res) } @@ -43,10 +47,10 @@ func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_False() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) + apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) require.Nil(err) - res := s.apiKeyService.IsWorkspaceApiKey(apiKey) + res := s.apiKeyService.IsWorkspaceApiKey(context.TODO(), apiKey) require.False(res) } @@ -55,10 +59,10 @@ func (s *ApiKeyServiceTestSuite) TestIsIsTargetApiKey_True() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeTarget, keyName) + apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeTarget, keyName) require.Nil(err) - res := s.apiKeyService.IsTargetApiKey(apiKey) + res := s.apiKeyService.IsTargetApiKey(context.TODO(), apiKey) require.True(res) } @@ -67,9 +71,9 @@ func (s *ApiKeyServiceTestSuite) TestIsTargetApiKey_False() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(models.ApiKeyTypeClient, keyName) + apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) require.Nil(err) - res := s.apiKeyService.IsTargetApiKey(apiKey) + res := s.apiKeyService.IsTargetApiKey(context.TODO(), apiKey) require.False(res) } diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index 98cc219ca3..107f0dbca8 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -43,10 +43,9 @@ func NewBuildService(config BuildServiceConfig) services.IBuildService { } } -func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { +func (s *BuildService) Create(ctx context.Context, b services.CreateBuildDTO) (string, error) { id := stringid.GenerateRandomID() id = stringid.TruncateID(id) - ctx := context.Background() workspaceTemplate, err := s.findWorkspaceTemplate(ctx, b.WorkspaceTemplateName) if err != nil { @@ -73,7 +72,7 @@ func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { newBuild.PrebuildId = *b.PrebuildId } - err = s.buildStore.Save(&newBuild) + err = s.buildStore.Save(ctx, &newBuild) if err != nil { return "", err } @@ -86,14 +85,14 @@ func (s *BuildService) Create(b services.CreateBuildDTO) (string, error) { return id, nil } -func (s *BuildService) Find(filter *services.BuildFilter) (*services.BuildDTO, error) { +func (s *BuildService) Find(ctx context.Context, filter *services.BuildFilter) (*services.BuildDTO, error) { var storeFilter *stores.BuildFilter if filter != nil { storeFilter = &filter.StoreFilter } - build, err := s.buildStore.Find(storeFilter) + build, err := s.buildStore.Find(ctx, storeFilter) if err != nil { return nil, err } @@ -110,14 +109,14 @@ func (s *BuildService) Find(filter *services.BuildFilter) (*services.BuildDTO, e }, nil } -func (s *BuildService) List(filter *services.BuildFilter) ([]*services.BuildDTO, error) { +func (s *BuildService) List(ctx context.Context, filter *services.BuildFilter) ([]*services.BuildDTO, error) { var storeFilter *stores.BuildFilter if filter != nil { storeFilter = &filter.StoreFilter } - builds, err := s.buildStore.List(storeFilter) + builds, err := s.buildStore.List(ctx, storeFilter) if err != nil { return nil, err } @@ -140,15 +139,14 @@ func (s *BuildService) List(filter *services.BuildFilter) ([]*services.BuildDTO, return result, nil } -func (s *BuildService) HandleSuccessfulRemoval(id string) error { - return s.buildStore.Delete(id) +func (s *BuildService) HandleSuccessfulRemoval(ctx context.Context, id string) error { + return s.buildStore.Delete(ctx, id) } -func (s *BuildService) Delete(filter *services.BuildFilter, force bool) []error { - ctx := context.Background() +func (s *BuildService) Delete(ctx context.Context, filter *services.BuildFilter, force bool) []error { var errors []error - builds, err := s.List(filter) + builds, err := s.List(ctx, filter) if err != nil { return []error{err} } @@ -170,7 +168,7 @@ func (s *BuildService) Delete(filter *services.BuildFilter, force bool) []error return errors } -func (s *BuildService) AwaitEmptyList(waitTime time.Duration) error { +func (s *BuildService) AwaitEmptyList(ctx context.Context, waitTime time.Duration) error { timeout := time.NewTimer(waitTime) defer timeout.Stop() @@ -179,7 +177,7 @@ func (s *BuildService) AwaitEmptyList(waitTime time.Duration) error { case <-timeout.C: return errors.New("awaiting empty build list timed out") default: - builds, err := s.List(&services.BuildFilter{ + builds, err := s.List(ctx, &services.BuildFilter{ ShowDeleted: true, }) if err != nil { @@ -195,6 +193,6 @@ func (s *BuildService) AwaitEmptyList(waitTime time.Duration) error { } } -func (s *BuildService) GetBuildLogReader(buildId string) (io.Reader, error) { +func (s *BuildService) GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) { return s.loggerFactory.CreateBuildLogReader(buildId) } diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 0a7408578c..152b22de4d 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -4,6 +4,7 @@ package builds_test import ( + "context" "testing" build_internal "github.com/daytonaio/daytona/internal/testing/build" @@ -108,7 +109,7 @@ func (s *BuildServiceTestSuite) SetupTest() { }) for _, b := range expectedBuilds { - _ = s.buildStore.Save(b) + _ = s.buildStore.Save(context.TODO(), b) } } @@ -119,7 +120,7 @@ func TestBuildService(t *testing.T) { func (s *BuildServiceTestSuite) TestList() { require := s.Require() - builds, err := s.buildService.List(nil) + builds, err := s.buildService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedBuilds, builds) } @@ -127,7 +128,7 @@ func (s *BuildServiceTestSuite) TestList() { func (s *BuildServiceTestSuite) TestFind() { require := s.Require() - build, err := s.buildService.Find(&services.BuildFilter{ + build, err := s.buildService.Find(context.TODO(), &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Id: &build1.Id, }, @@ -149,10 +150,10 @@ func (s *BuildServiceTestSuite) TestSave() { EnvVars: build4.EnvVars, } - _, err := s.buildService.Create(createBuildDto) + _, err := s.buildService.Create(context.TODO(), createBuildDto) require.Nil(err) - _, err = s.buildService.List(nil) + _, err = s.buildService.List(context.TODO(), nil) require.Nil(err) require.Contains(expectedBuilds, build4) } @@ -162,7 +163,7 @@ func (s *BuildServiceTestSuite) TestDelete() { require := s.Require() - err := s.buildService.Delete(&services.BuildFilter{ + err := s.buildService.Delete(context.TODO(), &services.BuildFilter{ StoreFilter: stores.BuildFilter{ Id: &build3.Id, }, @@ -175,10 +176,10 @@ func (s *BuildServiceTestSuite) TestHandleSuccessfulRemoval() { require := s.Require() - err := s.buildService.HandleSuccessfulRemoval(build3.Id) + err := s.buildService.HandleSuccessfulRemoval(context.TODO(), build3.Id) require.Nil(err) - builds, err := s.buildService.List(nil) + builds, err := s.buildService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedBuilds, builds) } diff --git a/pkg/server/env/service.go b/pkg/server/env/service.go index bcd8c785d6..c7268e7d01 100644 --- a/pkg/server/env/service.go +++ b/pkg/server/env/service.go @@ -4,6 +4,8 @@ package env import ( + "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -23,12 +25,12 @@ type EnvironmentVariableService struct { environmentVariableStore stores.EnvironmentVariableStore } -func (s *EnvironmentVariableService) List() ([]*models.EnvironmentVariable, error) { - return s.environmentVariableStore.List() +func (s *EnvironmentVariableService) List(ctx context.Context) ([]*models.EnvironmentVariable, error) { + return s.environmentVariableStore.List(ctx) } -func (s *EnvironmentVariableService) Map() (services.EnvironmentVariables, error) { - envVars, err := s.List() +func (s *EnvironmentVariableService) Map(ctx context.Context) (services.EnvironmentVariables, error) { + envVars, err := s.List(ctx) if err != nil { return nil, err } @@ -41,10 +43,10 @@ func (s *EnvironmentVariableService) Map() (services.EnvironmentVariables, error return envVarsMap, nil } -func (s *EnvironmentVariableService) Save(environmentVariable *models.EnvironmentVariable) error { - return s.environmentVariableStore.Save(environmentVariable) +func (s *EnvironmentVariableService) Save(ctx context.Context, environmentVariable *models.EnvironmentVariable) error { + return s.environmentVariableStore.Save(ctx, environmentVariable) } -func (s *EnvironmentVariableService) Delete(key string) error { - return s.environmentVariableStore.Delete(key) +func (s *EnvironmentVariableService) Delete(ctx context.Context, key string) error { + return s.environmentVariableStore.Delete(ctx, key) } diff --git a/pkg/server/env/service_test.go b/pkg/server/env/service_test.go index acefc91a51..18b7526051 100644 --- a/pkg/server/env/service_test.go +++ b/pkg/server/env/service_test.go @@ -4,6 +4,7 @@ package env_test import ( + "context" "testing" t_envvar "github.com/daytonaio/daytona/internal/testing/server/env" @@ -36,7 +37,7 @@ func TestEnvironmentVariableService(t *testing.T) { } func (s *EnvironmentVariableServiceTestSuite) TestReturnsEnvironmentVariableNotFound() { - envVar, err := s.environmentVariableService.List() + envVar, err := s.environmentVariableService.List(context.TODO()) s.Require().Nil(envVar) s.Require().True(stores.IsEnvironmentVariableNotFound(err)) } @@ -47,10 +48,10 @@ func (s *EnvironmentVariableServiceTestSuite) TestSaveEnvironmentVariable() { Value: "value1", } - err := s.environmentVariableService.Save(envVar) + err := s.environmentVariableService.Save(context.TODO(), envVar) s.Require().Nil(err) - envVarsFromStore, err := s.environmentVariableStore.List() + envVarsFromStore, err := s.environmentVariableStore.List(context.TODO()) s.Require().Nil(err) s.Require().NotNil(envVarsFromStore) s.Require().Equal(envVar, envVarsFromStore) @@ -62,13 +63,13 @@ func (s *EnvironmentVariableServiceTestSuite) TestDeleteEnvironmentVariable() { Value: "value1", } - err := s.environmentVariableService.Save(envVar) + err := s.environmentVariableService.Save(context.TODO(), envVar) s.Require().Nil(err) - err = s.environmentVariableService.Delete(envVar.Key) + err = s.environmentVariableService.Delete(context.TODO(), envVar.Key) s.Require().Nil(err) - EnvVarsFromStore, err := s.environmentVariableStore.List() + EnvVarsFromStore, err := s.environmentVariableStore.List(context.TODO()) s.Require().Nil(EnvVarsFromStore) s.Require().True(stores.IsEnvironmentVariableNotFound(err)) } diff --git a/pkg/server/gitproviders/branches.go b/pkg/server/gitproviders/branches.go index 186a160f57..27b5f0f2d9 100644 --- a/pkg/server/gitproviders/branches.go +++ b/pkg/server/gitproviders/branches.go @@ -4,13 +4,14 @@ package gitproviders import ( + "context" "fmt" "github.com/daytonaio/daytona/pkg/gitprovider" ) -func (s *GitProviderService) GetRepoBranches(gitProviderId, namespaceId, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) GetRepoBranches(ctx context.Context, gitProviderId, namespaceId, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return nil, fmt.Errorf("failed to get git provider: %w", err) } diff --git a/pkg/server/gitproviders/config.go b/pkg/server/gitproviders/config.go index c28f14b096..e3a8534968 100644 --- a/pkg/server/gitproviders/config.go +++ b/pkg/server/gitproviders/config.go @@ -4,6 +4,7 @@ package gitproviders import ( + "context" "net/url" "strconv" @@ -12,18 +13,18 @@ import ( "github.com/docker/docker/pkg/stringid" ) -func (s *GitProviderService) GetConfig(id string) (*models.GitProviderConfig, error) { - return s.configStore.Find(id) +func (s *GitProviderService) GetConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) { + return s.configStore.Find(ctx, id) } -func (s *GitProviderService) ListConfigs() ([]*models.GitProviderConfig, error) { - return s.configStore.List() +func (s *GitProviderService) ListConfigs(ctx context.Context) ([]*models.GitProviderConfig, error) { + return s.configStore.List(ctx) } -func (s *GitProviderService) ListConfigsForUrl(repoUrl string) ([]*models.GitProviderConfig, error) { +func (s *GitProviderService) ListConfigsForUrl(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { var gpcs []*models.GitProviderConfig - gitProviders, err := s.configStore.List() + gitProviders, err := s.configStore.List(ctx) if err != nil { return nil, err } @@ -32,7 +33,7 @@ func (s *GitProviderService) ListConfigsForUrl(repoUrl string) ([]*models.GitPro p.Token = url.QueryEscape(p.Token) p.Username = url.QueryEscape(p.Username) - gitProvider, err := s.GetGitProvider(p.Id) + gitProvider, err := s.GetGitProvider(ctx, p.Id) if err != nil { return nil, err } @@ -51,7 +52,7 @@ func (s *GitProviderService) ListConfigsForUrl(repoUrl string) ([]*models.GitPro return gpcs, nil } -func (s *GitProviderService) SetGitProviderConfig(providerConfig *models.GitProviderConfig) error { +func (s *GitProviderService) SetGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error { gitProvider, err := s.newGitProvider(providerConfig) if err != nil { return err @@ -69,7 +70,7 @@ func (s *GitProviderService) SetGitProviderConfig(providerConfig *models.GitProv } if providerConfig.Alias == "" { - gitProviderConfigs, err := s.ListConfigs() + gitProviderConfigs, err := s.ListConfigs(ctx) if err != nil { return err } @@ -90,5 +91,5 @@ func (s *GitProviderService) SetGitProviderConfig(providerConfig *models.GitProv providerConfig.Alias = uniqueAlias } - return s.configStore.Save(providerConfig) + return s.configStore.Save(ctx, providerConfig) } diff --git a/pkg/server/gitproviders/gitprovider.go b/pkg/server/gitproviders/gitprovider.go index f5816b54a6..99a6ef1b55 100644 --- a/pkg/server/gitproviders/gitprovider.go +++ b/pkg/server/gitproviders/gitprovider.go @@ -4,6 +4,7 @@ package gitproviders import ( + "context" "errors" "net/http" "net/url" @@ -14,8 +15,8 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -func (s *GitProviderService) GetGitProviderForUrl(repoUrl string) (gitprovider.GitProvider, string, error) { - gitProviders, err := s.configStore.List() +func (s *GitProviderService) GetGitProviderForUrl(ctx context.Context, repoUrl string) (gitprovider.GitProvider, string, error) { + gitProviders, err := s.configStore.List(ctx) if err != nil { return nil, "", err } @@ -24,7 +25,7 @@ func (s *GitProviderService) GetGitProviderForUrl(repoUrl string) (gitprovider.G var eligibleProviderId string for _, p := range gitProviders { - gitProvider, err := s.GetGitProvider(p.Id) + gitProvider, err := s.GetGitProvider(ctx, p.Id) if err != nil { continue } @@ -66,10 +67,10 @@ func (s *GitProviderService) GetGitProviderForUrl(repoUrl string) (gitprovider.G return nil, "", errors.New("can not get public client for the URL " + repoUrl) } -func (s *GitProviderService) GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) { +func (s *GitProviderService) GetGitProviderForHttpRequest(ctx context.Context, req *http.Request) (gitprovider.GitProvider, error) { var provider *models.GitProviderConfig - gitProviders, err := s.configStore.List() + gitProviders, err := s.configStore.List(ctx) if err != nil { return nil, err } diff --git a/pkg/server/gitproviders/namespaces.go b/pkg/server/gitproviders/namespaces.go index 118bc8e6d7..a24ffc0ec2 100644 --- a/pkg/server/gitproviders/namespaces.go +++ b/pkg/server/gitproviders/namespaces.go @@ -4,13 +4,14 @@ package gitproviders import ( + "context" "fmt" "github.com/daytonaio/daytona/pkg/gitprovider" ) -func (s *GitProviderService) GetNamespaces(gitProviderId string, options gitprovider.ListOptions) ([]*gitprovider.GitNamespace, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) GetNamespaces(ctx context.Context, gitProviderId string, options gitprovider.ListOptions) ([]*gitprovider.GitNamespace, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return nil, fmt.Errorf("failed to get git provider: %w", err) } diff --git a/pkg/server/gitproviders/prebuild_webhook.go b/pkg/server/gitproviders/prebuild_webhook.go index cda8a68b00..52ea051f04 100644 --- a/pkg/server/gitproviders/prebuild_webhook.go +++ b/pkg/server/gitproviders/prebuild_webhook.go @@ -4,13 +4,14 @@ package gitproviders import ( + "context" "fmt" "github.com/daytonaio/daytona/pkg/gitprovider" ) -func (s *GitProviderService) GetPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) GetPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return nil, fmt.Errorf("failed to get git provider: %s", err.Error()) } @@ -23,8 +24,8 @@ func (s *GitProviderService) GetPrebuildWebhook(gitProviderId string, repo *gitp return id, nil } -func (s *GitProviderService) RegisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) RegisterPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return "", fmt.Errorf("failed to get git provider: %s", err.Error()) } @@ -37,8 +38,8 @@ func (s *GitProviderService) RegisterPrebuildWebhook(gitProviderId string, repo return id, nil } -func (s *GitProviderService) UnregisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, id string) error { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) UnregisterPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return fmt.Errorf("failed to get git provider: %s", err.Error()) } diff --git a/pkg/server/gitproviders/pull_requests.go b/pkg/server/gitproviders/pull_requests.go index be351ec09e..3f0db9adfd 100644 --- a/pkg/server/gitproviders/pull_requests.go +++ b/pkg/server/gitproviders/pull_requests.go @@ -4,13 +4,14 @@ package gitproviders import ( + "context" "fmt" "github.com/daytonaio/daytona/pkg/gitprovider" ) -func (s *GitProviderService) GetRepoPRs(gitProviderId, namespaceId, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) GetRepoPRs(ctx context.Context, gitProviderId, namespaceId, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return nil, fmt.Errorf("failed to get git provider: %w", err) } diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index 76d2af0929..54b47fd880 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -5,10 +5,8 @@ package gitproviders import "context" -func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { - ctx := context.Background() - - gitProvider, err := s.configStore.Find(gitProviderId) +func (s *GitProviderService) RemoveGitProvider(ctx context.Context, gitProviderId string) error { + gitProvider, err := s.configStore.Find(ctx, gitProviderId) if err != nil { return err } @@ -18,5 +16,5 @@ func (s *GitProviderService) RemoveGitProvider(gitProviderId string) error { return err } - return s.configStore.Delete(gitProvider) + return s.configStore.Delete(ctx, gitProvider) } diff --git a/pkg/server/gitproviders/repositories.go b/pkg/server/gitproviders/repositories.go index bd9fce0896..047c71f9f4 100644 --- a/pkg/server/gitproviders/repositories.go +++ b/pkg/server/gitproviders/repositories.go @@ -4,13 +4,14 @@ package gitproviders import ( + "context" "fmt" "github.com/daytonaio/daytona/pkg/gitprovider" ) -func (s *GitProviderService) GetRepositories(gitProviderId, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) GetRepositories(ctx context.Context, gitProviderId, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return nil, fmt.Errorf("failed to get git provider: %w", err) } diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index e78c6dce48..592770a127 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -35,8 +35,8 @@ func NewGitProviderService(config GitProviderServiceConfig) services.IGitProvide var codebergUrl = "https://codeberg.org" -func (s *GitProviderService) GetGitProvider(id string) (gitprovider.GitProvider, error) { - providerConfig, err := s.configStore.Find(id) +func (s *GitProviderService) GetGitProvider(ctx context.Context, id string) (gitprovider.GitProvider, error) { + providerConfig, err := s.configStore.Find(ctx, id) if err != nil { // If config is not defined, use the default (public) client without token if stores.IsGitProviderNotFound(err) { @@ -55,12 +55,12 @@ func (s *GitProviderService) GetGitProvider(id string) (gitprovider.GitProvider, return s.newGitProvider(providerConfig) } -func (s *GitProviderService) GetLastCommitSha(repo *gitprovider.GitRepository) (string, error) { +func (s *GitProviderService) GetLastCommitSha(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { var err error var provider gitprovider.GitProvider providerFound := false - gitProviders, err := s.configStore.List() + gitProviders, err := s.configStore.List(ctx) if err != nil { return "", err } @@ -69,7 +69,7 @@ func (s *GitProviderService) GetLastCommitSha(repo *gitprovider.GitRepository) ( isAwsUrl := strings.Contains(repo.Url, ".amazonaws.com/") || strings.Contains(repo.Url, ".console.aws.amazon.com/") if p.ProviderId == "aws-codecommit" && isAwsUrl { - provider, err = s.GetGitProvider(p.ProviderId) + provider, err = s.GetGitProvider(ctx, p.ProviderId) if err == nil { return "", err } @@ -78,7 +78,7 @@ func (s *GitProviderService) GetLastCommitSha(repo *gitprovider.GitRepository) ( } if strings.Contains(repo.Url, fmt.Sprintf("%s.", p.ProviderId)) { - provider, err = s.GetGitProvider(p.ProviderId) + provider, err = s.GetGitProvider(ctx, p.ProviderId) if err == nil { return "", err } @@ -92,7 +92,7 @@ func (s *GitProviderService) GetLastCommitSha(repo *gitprovider.GitRepository) ( } if p.BaseApiUrl != nil && strings.Contains(repo.Url, hostname) { - provider, err = s.GetGitProvider(p.ProviderId) + provider, err = s.GetGitProvider(ctx, p.ProviderId) if err == nil { return "", err } diff --git a/pkg/server/gitproviders/user.go b/pkg/server/gitproviders/user.go index 8804734121..583ed05de7 100644 --- a/pkg/server/gitproviders/user.go +++ b/pkg/server/gitproviders/user.go @@ -4,13 +4,14 @@ package gitproviders import ( + "context" "fmt" "github.com/daytonaio/daytona/pkg/gitprovider" ) -func (s *GitProviderService) GetGitUser(gitProviderId string) (*gitprovider.GitUser, error) { - gitProvider, err := s.GetGitProvider(gitProviderId) +func (s *GitProviderService) GetGitUser(ctx context.Context, gitProviderId string) (*gitprovider.GitUser, error) { + gitProvider, err := s.GetGitProvider(ctx, gitProviderId) if err != nil { return nil, fmt.Errorf("failed to get git provider: %w", err) } diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index 3fea5e94f4..097f68621a 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -4,6 +4,8 @@ package jobs import ( + "context" + "errors" "slices" "github.com/daytonaio/daytona/pkg/models" @@ -26,15 +28,15 @@ func NewJobService(config JobServiceConfig) services.IJobService { } } -func (s *JobService) List(filter *stores.JobFilter) ([]*models.Job, error) { - return s.jobStore.List(filter) +func (s *JobService) List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) { + return s.jobStore.List(ctx, filter) } -func (s *JobService) Find(filter *stores.JobFilter) (*models.Job, error) { - return s.jobStore.Find(filter) +func (s *JobService) Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) { + return s.jobStore.Find(ctx, filter) } -func (s *JobService) Create(j *models.Job) error { +func (s *JobService) Create(ctx context.Context, j *models.Job) error { validAction, ok := validResourceActions[j.ResourceType] if !ok { return services.ErrInvalidResourceJobAction @@ -44,7 +46,7 @@ func (s *JobService) Create(j *models.Job) error { return services.ErrInvalidResourceJobAction } - pendingJobs, err := s.List(&stores.JobFilter{ + pendingJobs, err := s.List(ctx, &stores.JobFilter{ ResourceId: &j.ResourceId, ResourceType: &j.ResourceType, States: &[]models.JobState{models.JobStatePending, models.JobStateRunning}, @@ -62,22 +64,29 @@ func (s *JobService) Create(j *models.Job) error { id = stringid.TruncateID(id) j.Id = id } - return s.jobStore.Save(j) + return s.jobStore.Save(ctx, j) } -func (s *JobService) Update(j *models.Job) error { - _, err := s.Find(&stores.JobFilter{ - Id: &j.Id, +func (s *JobService) SetState(ctx context.Context, jobId string, state models.JobState, err *string) error { + job, findErr := s.Find(ctx, &stores.JobFilter{ + Id: &jobId, }) - if err != nil { - return err + if findErr != nil { + return findErr } - return s.jobStore.Save(j) + if job.State == state { + return errors.New("job is already in the specified state") + } + + job.State = state + job.Error = err + + return s.jobStore.Save(ctx, job) } -func (s *JobService) Delete(j *models.Job) error { - return s.jobStore.Delete(j) +func (s *JobService) Delete(ctx context.Context, j *models.Job) error { + return s.jobStore.Delete(ctx, j) } var validResourceActions = map[models.ResourceType][]models.JobAction{ diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go index 237ac4dfc4..f4938d16c1 100644 --- a/pkg/server/jobs/service_test.go +++ b/pkg/server/jobs/service_test.go @@ -4,6 +4,7 @@ package jobs_test import ( + "context" "testing" job_internal "github.com/daytonaio/daytona/internal/testing/job" @@ -65,7 +66,7 @@ func (s *JobServiceTestSuite) SetupTest() { }) for _, j := range expectedJobs { - _ = s.jobStore.Save(j) + _ = s.jobStore.Save(context.TODO(), j) } } @@ -76,7 +77,7 @@ func TestJobService(t *testing.T) { func (s *JobServiceTestSuite) TestList() { require := s.Require() - jobs, err := s.jobService.List(nil) + jobs, err := s.jobService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedJobs, jobs) } @@ -84,7 +85,7 @@ func (s *JobServiceTestSuite) TestList() { func (s *JobServiceTestSuite) TestFind() { require := s.Require() - job, err := s.jobService.Find(&stores.JobFilter{ + job, err := s.jobService.Find(context.TODO(), &stores.JobFilter{ Id: &job1.Id, }) require.Nil(err) @@ -96,27 +97,27 @@ func (s *JobServiceTestSuite) TestCreate() { require := s.Require() - err := s.jobService.Create(job4) + err := s.jobService.Create(context.TODO(), job4) require.Nil(err) - jobs, err := s.jobService.List(nil) + jobs, err := s.jobService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedJobs, jobs) } -func (s *JobServiceTestSuite) TestUpdate() { +func (s *JobServiceTestSuite) TestSetState() { require := s.Require() - err := s.jobService.Create(job4) + err := s.jobService.Create(context.TODO(), job4) require.Nil(err) job4Update := *job4 job4Update.State = models.JobStateSuccess - err = s.jobService.Update(&job4Update) + err = s.jobService.SetState(context.TODO(), job4Update.Id, models.JobStateSuccess, nil) require.Nil(err) - updated, err := s.jobService.Find(&stores.JobFilter{ + updated, err := s.jobService.Find(context.TODO(), &stores.JobFilter{ Id: &job4.Id, }) require.Nil(err) @@ -126,7 +127,7 @@ func (s *JobServiceTestSuite) TestUpdate() { func (s *JobServiceTestSuite) TestCreateWithAnotherJobInProgress() { require := s.Require() - err := s.jobService.Create(job4) + err := s.jobService.Create(context.TODO(), job4) require.Nil(err) var job5 = &models.Job{ @@ -136,7 +137,7 @@ func (s *JobServiceTestSuite) TestCreateWithAnotherJobInProgress() { State: models.JobStatePending, } - err = s.jobService.Create(job5) + err = s.jobService.Create(context.TODO(), job5) require.EqualError(err, stores.ErrJobInProgress.Error()) } @@ -145,10 +146,10 @@ func (s *JobServiceTestSuite) TestDelete() { require := s.Require() - err := s.jobService.Delete(job3) + err := s.jobService.Delete(context.TODO(), job3) require.Nil(err) - jobs, err := s.jobService.List(nil) + jobs, err := s.jobService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedJobs, jobs) } diff --git a/pkg/server/purge.go b/pkg/server/purge.go index 1780714d6a..b68b158af1 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -75,7 +75,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { } fmt.Println("Purging builds...") - errs := s.BuildService.Delete(nil, force) + errs := s.BuildService.Delete(ctx, nil, force) if len(errs) > 0 { s.trackPurgeError(ctx, force, errs[0]) if !force { @@ -85,7 +85,7 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { } } - err = s.BuildService.AwaitEmptyList(time.Minute) + err = s.BuildService.AwaitEmptyList(ctx, time.Minute) if err != nil { s.trackPurgeError(ctx, force, err) if !force { diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index 41985d4ce9..a4d712c4d5 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -4,6 +4,8 @@ package targetconfigs import ( + "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -24,12 +26,12 @@ func NewTargetConfigService(config TargetConfigServiceConfig) services.ITargetCo } } -func (s *TargetConfigService) List() ([]*models.TargetConfig, error) { - return s.targetConfigStore.List(false) +func (s *TargetConfigService) List(ctx context.Context) ([]*models.TargetConfig, error) { + return s.targetConfigStore.List(ctx, false) } -func (s *TargetConfigService) Map() (map[string]*models.TargetConfig, error) { - list, err := s.targetConfigStore.List(false) +func (s *TargetConfigService) Map(ctx context.Context) (map[string]*models.TargetConfig, error) { + list, err := s.targetConfigStore.List(ctx, false) if err != nil { return nil, err } @@ -42,12 +44,12 @@ func (s *TargetConfigService) Map() (map[string]*models.TargetConfig, error) { return targetConfigs, nil } -func (s *TargetConfigService) Find(idOrName string) (*models.TargetConfig, error) { - return s.targetConfigStore.Find(idOrName, false) +func (s *TargetConfigService) Find(ctx context.Context, idOrName string) (*models.TargetConfig, error) { + return s.targetConfigStore.Find(ctx, idOrName, false) } -func (s *TargetConfigService) Add(addTargetConfig services.AddTargetConfigDTO) (*models.TargetConfig, error) { - persistedTargetConfig, err := s.targetConfigStore.Find(addTargetConfig.Name, false) +func (s *TargetConfigService) Add(ctx context.Context, addTargetConfig services.AddTargetConfigDTO) (*models.TargetConfig, error) { + persistedTargetConfig, err := s.targetConfigStore.Find(ctx, addTargetConfig.Name, false) if err != nil && !stores.IsTargetConfigNotFound(err) { return nil, err } @@ -63,15 +65,15 @@ func (s *TargetConfigService) Add(addTargetConfig services.AddTargetConfigDTO) ( Deleted: false, } - return targetConfig, s.targetConfigStore.Save(targetConfig) + return targetConfig, s.targetConfigStore.Save(ctx, targetConfig) } -func (s *TargetConfigService) Delete(targetConfigId string) error { - targetConfig, err := s.targetConfigStore.Find(targetConfigId, false) +func (s *TargetConfigService) Delete(ctx context.Context, targetConfigId string) error { + targetConfig, err := s.targetConfigStore.Find(ctx, targetConfigId, false) if err != nil { return err } targetConfig.Deleted = true - return s.targetConfigStore.Save(targetConfig) + return s.targetConfigStore.Save(ctx, targetConfig) } diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go index ca995e1351..7d20d377e9 100644 --- a/pkg/server/targetconfigs/service_test.go +++ b/pkg/server/targetconfigs/service_test.go @@ -4,6 +4,7 @@ package targetconfigs_test import ( + "context" "testing" t_targetconfigs "github.com/daytonaio/daytona/internal/testing/server/targetconfigs" @@ -80,7 +81,7 @@ func (s *TargetConfigServiceTestSuite) SetupTest() { }) for _, targetConfig := range expectedConfigs { - tc, err := s.targetConfigService.Add(services.AddTargetConfigDTO{ + tc, err := s.targetConfigService.Add(context.TODO(), services.AddTargetConfigDTO{ Name: targetConfig.Name, ProviderInfo: targetConfig.ProviderInfo, Options: targetConfig.Options, @@ -99,7 +100,7 @@ func TestTargetConfigService(t *testing.T) { func (s *TargetConfigServiceTestSuite) TestList() { require := s.Require() - targetConfigs, err := s.targetConfigService.List() + targetConfigs, err := s.targetConfigService.List(context.TODO()) require.Nil(err) require.ElementsMatch(expectedConfigs, targetConfigs) } @@ -107,7 +108,7 @@ func (s *TargetConfigServiceTestSuite) TestList() { func (s *TargetConfigServiceTestSuite) TestMap() { require := s.Require() - targetConfigsMap, err := s.targetConfigService.Map() + targetConfigsMap, err := s.targetConfigService.Map(context.TODO()) require.Nil(err) require.Equal(expectedConfigMap, targetConfigsMap) } @@ -115,7 +116,7 @@ func (s *TargetConfigServiceTestSuite) TestMap() { func (s *TargetConfigServiceTestSuite) TestFind() { require := s.Require() - targetConfig, err := s.targetConfigService.Find(targetConfig1.Id) + targetConfig, err := s.targetConfigService.Find(context.TODO(), targetConfig1.Id) require.Nil(err) require.Equal(targetConfig1, targetConfig) } @@ -123,7 +124,7 @@ func (s *TargetConfigServiceTestSuite) TestFind() { func (s *TargetConfigServiceTestSuite) TestSave() { require := s.Require() - tc, err := s.targetConfigService.Add(services.AddTargetConfigDTO{ + tc, err := s.targetConfigService.Add(context.TODO(), services.AddTargetConfigDTO{ Name: targetConfig4.Name, ProviderInfo: targetConfig4.ProviderInfo, Options: targetConfig4.Options, @@ -133,7 +134,7 @@ func (s *TargetConfigServiceTestSuite) TestSave() { targetConfig4.Id = tc.Id expectedConfigs = append(expectedConfigs, targetConfig4) - targetConfigs, err := s.targetConfigService.List() + targetConfigs, err := s.targetConfigService.List(context.TODO()) require.Nil(err) require.ElementsMatch(expectedConfigs, targetConfigs) } @@ -143,10 +144,10 @@ func (s *TargetConfigServiceTestSuite) TestDelete() { require := s.Require() - err := s.targetConfigService.Delete(targetConfig3.Id) + err := s.targetConfigService.Delete(context.TODO(), targetConfig3.Id) require.Nil(err) - targetConfigs, err := s.targetConfigService.List() + targetConfigs, err := s.targetConfigService.List(context.TODO()) require.Nil(err) require.ElementsMatch(expected, targetConfigs) diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index 3d662e6896..f67fdf804f 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -17,7 +17,15 @@ import ( ) func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTargetDTO) (*models.Target, error) { - _, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &req.Id}) + var err error + ctx, err = s.targetStore.BeginTransaction(ctx) + if err != nil { + return s.handleCreateError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.targetStore) + + _, err = s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &req.Id}) if err == nil { return nil, services.ErrTargetAlreadyExists } @@ -54,12 +62,12 @@ func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTar }) tg.EnvVars = util.MergeEnvVars(daytonaTargetEnvVars, tg.EnvVars) - err = s.targetStore.Save(tg) + err = s.targetStore.Save(ctx, tg) if err != nil { return s.handleCreateError(ctx, nil, err) } - err = s.targetMetadataStore.Save(&models.TargetMetadata{ + err = s.targetMetadataStore.Save(ctx, &models.TargetMetadata{ TargetId: tg.Id, Uptime: 0, }) @@ -68,6 +76,11 @@ func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTar } err = s.createJob(ctx, tg.Id, models.JobActionCreate) + if err != nil { + return s.handleCreateError(ctx, tg, err) + } + + err = s.targetStore.CommitTransaction(ctx) return s.handleCreateError(ctx, tg, err) } @@ -76,6 +89,10 @@ func (s *TargetService) HandleSuccessfulCreation(ctx context.Context, targetId s } func (s *TargetService) handleCreateError(ctx context.Context, target *models.Target, err error) (*models.Target, error) { + if err != nil { + err = s.targetStore.RollbackTransaction(ctx, err) + } + if !telemetry.TelemetryEnabled(ctx) { return target, err } diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 931f1f74dc..8b2785c3a5 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -17,7 +17,7 @@ import ( ) func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { - tg, err := s.targetStore.Find(filter) + tg, err := s.targetStore.Find(ctx, filter) if err != nil { return nil, stores.ErrTargetNotFound } diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index 85d12487d0..88d36333f3 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -18,7 +18,7 @@ import ( ) func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]services.TargetDTO, error) { - targets, err := s.targetStore.List(filter) + targets, err := s.targetStore.List(ctx, filter) if err != nil { return nil, err } diff --git a/pkg/server/targets/metadata.go b/pkg/server/targets/metadata.go index d418f97656..c4850b99cc 100644 --- a/pkg/server/targets/metadata.go +++ b/pkg/server/targets/metadata.go @@ -4,12 +4,14 @@ package targets import ( + "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) -func (s *TargetService) SetTargetMetadata(targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { - m, err := s.targetMetadataStore.Find(&stores.TargetMetadataFilter{ +func (s *TargetService) SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { + m, err := s.targetMetadataStore.Find(ctx, &stores.TargetMetadataFilter{ TargetId: &targetId, }) if err != nil { @@ -18,5 +20,5 @@ func (s *TargetService) SetTargetMetadata(targetId string, metadata *models.Targ m.Uptime = metadata.Uptime m.UpdatedAt = metadata.UpdatedAt - return m, s.targetMetadataStore.Save(m) + return m, s.targetMetadataStore.Save(ctx, m) } diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index c13a419439..384369f6b4 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -14,67 +14,110 @@ import ( ) func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + var err error + ctx, err = s.targetStore.BeginTransaction(ctx) + if err != nil { + return s.handleRemoveError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.targetStore) + + t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, t, stores.ErrTargetNotFound) } t.Name = util.AddDeletedToName(t.Name) - err = s.targetStore.Save(t) + err = s.targetStore.Save(ctx, t) if err != nil { return s.handleRemoveError(ctx, t, err) } err = s.createJob(ctx, t.Id, models.JobActionDelete) + if err != nil { + return s.handleRemoveError(ctx, t, err) + } + + err = s.targetStore.CommitTransaction(ctx) return s.handleRemoveError(ctx, t, err) } // ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + var err error + ctx, err = s.targetStore.BeginTransaction(ctx) + if err != nil { + return s.handleRemoveError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.targetStore) + + t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, nil, stores.ErrTargetNotFound) } t.Name = util.AddDeletedToName(t.Name) - err = s.targetStore.Save(t) + err = s.targetStore.Save(ctx, t) if err != nil { return s.handleRemoveError(ctx, t, err) } err = s.createJob(ctx, t.Id, models.JobActionForceDelete) + if err != nil { + return s.handleRemoveError(ctx, t, err) + } + + err = s.targetStore.CommitTransaction(ctx) return s.handleRemoveError(ctx, t, err) } func (s *TargetService) HandleSuccessfulRemoval(ctx context.Context, targetId string) error { - err := s.revokeApiKey(ctx, targetId) + var err error + ctx, err = s.targetStore.BeginTransaction(ctx) + if err != nil { + return s.handleRemoveError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.targetStore) + + err = s.revokeApiKey(ctx, targetId) if err != nil { // Should not fail the whole operation if the API key cannot be revoked log.Error(err) } - t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleRemoveError(ctx, t, stores.ErrTargetNotFound) } - metadata, err := s.targetMetadataStore.Find(&stores.TargetMetadataFilter{TargetId: &targetId}) + metadata, err := s.targetMetadataStore.Find(ctx, &stores.TargetMetadataFilter{TargetId: &targetId}) if err != nil { return s.handleRemoveError(ctx, t, err) } - err = s.targetMetadataStore.Delete(metadata) + err = s.targetMetadataStore.Delete(ctx, metadata) if err != nil { return s.handleRemoveError(ctx, t, err) } - err = s.targetStore.Delete(t) + err = s.targetStore.Delete(ctx, t) + if err != nil { + return s.handleRemoveError(ctx, t, err) + } + + err = s.targetStore.CommitTransaction(ctx) return s.handleRemoveError(ctx, t, err) } func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Target, err error) error { + if err != nil { + err = s.targetStore.RollbackTransaction(ctx, err) + } + if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 67d0240cae..4f412123ee 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -67,7 +67,7 @@ func TestTargetService(t *testing.T) { targetMetadataStore := t_targets.NewInMemoryTargetMetadataStore() targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() - err := targetConfigStore.Save(&tc) + err := targetConfigStore.Save(ctx, &tc) require.Nil(t, err) apiKeyService := mocks.NewMockApiKeyService() @@ -80,7 +80,7 @@ func TestTargetService(t *testing.T) { TargetStore: targetStore, TargetMetadataStore: targetMetadataStore, FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { - return targetConfigStore.Find(name, false) + return targetConfigStore.Find(ctx, name, false) }, GenerateApiKey: func(ctx context.Context, name string) (string, error) { return apiKeyService.Generate(models.ApiKeyTypeTarget, name) @@ -197,7 +197,7 @@ func TestTargetService(t *testing.T) { }) t.Run("ForceRemoveTarget", func(t *testing.T) { - err := targetStore.Save(tg) + err := targetStore.Save(ctx, tg) require.Nil(t, err) mockProvisioner.On("DestroyTarget", tg).Return(nil) @@ -221,10 +221,10 @@ func TestTargetService(t *testing.T) { }) t.Run("SetTargetMetadata", func(t *testing.T) { - err := targetStore.Save(tg) + err := targetStore.Save(ctx, tg) require.Nil(t, err) - _, err = service.SetTargetMetadata(tg.Id, &models.TargetMetadata{ + _, err = service.SetTargetMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ Uptime: 10, }) require.Nil(t, err) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index 52ab8eabf3..26ef807dfb 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -12,28 +12,36 @@ import ( ) func (s *TargetService) SetDefault(ctx context.Context, id string) error { + var err error + ctx, err = s.targetStore.BeginTransaction(ctx) + if err != nil { + return err + } + + defer stores.RecoverAndRollback(ctx, s.targetStore) + currentTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ IdOrName: &id, }, services.TargetRetrievalParams{}) if err != nil || currentTarget == nil { - return err + return s.targetStore.RollbackTransaction(ctx, err) } defaultTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ Default: util.Pointer(true), }, services.TargetRetrievalParams{}) if err != nil && !stores.IsTargetNotFound(err) { - return err + return s.targetStore.RollbackTransaction(ctx, err) } if defaultTarget != nil { defaultTarget.IsDefault = false - err := s.targetStore.Save(&defaultTarget.Target) + err := s.targetStore.Save(ctx, &defaultTarget.Target) if err != nil { - return err + return s.targetStore.RollbackTransaction(ctx, err) } } currentTarget.IsDefault = true - return s.targetStore.Save(¤tTarget.Target) + return s.targetStore.Save(ctx, ¤tTarget.Target) } diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index a5a7a3a9de..c445514b6b 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -13,7 +13,7 @@ import ( ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStartError(ctx, nil, stores.ErrTargetNotFound) } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index 77d8f2b442..1560d0082e 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -13,7 +13,7 @@ import ( ) func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { - target, err := s.targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStopError(ctx, nil, stores.ErrTargetNotFound) } diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 307f9e225e..8add269a46 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -12,13 +12,22 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.CreateWorkspaceDTO) (*services.WorkspaceDTO, error) { - _, err := s.workspaceStore.Find(req.Name) + var err error + ctx, err = s.workspaceStore.BeginTransaction(ctx) + if err != nil { + return s.handleCreateError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.workspaceStore) + + _, err = s.workspaceStore.Find(ctx, req.Name) if err == nil { return s.handleCreateError(ctx, nil, services.ErrWorkspaceAlreadyExists) } @@ -90,12 +99,12 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre }) w.EnvVars = util.MergeEnvVars(daytonaWorkspaceEnvVars, w.EnvVars) - err = s.workspaceStore.Save(w) + err = s.workspaceStore.Save(ctx, w) if err != nil { return s.handleCreateError(ctx, w, err) } - err = s.workspaceMetadataStore.Save(&models.WorkspaceMetadata{ + err = s.workspaceMetadataStore.Save(ctx, &models.WorkspaceMetadata{ WorkspaceId: w.Id, Uptime: 0, GitStatus: &models.GitStatus{}, @@ -105,11 +114,19 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre } err = s.createJob(ctx, w.Id, models.JobActionCreate) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + err = s.workspaceStore.CommitTransaction(ctx) return s.handleCreateError(ctx, w, err) } func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Workspace, err error) (*services.WorkspaceDTO, error) { + if err != nil { + err = s.workspaceStore.RollbackTransaction(ctx, err) + } + if !telemetry.TelemetryEnabled(ctx) { if w == nil { return nil, err diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index 5e3e28b979..4b7766dce4 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -17,7 +17,7 @@ import ( ) func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { - ws, err := s.workspaceStore.Find(workspaceId) + ws, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceNotFound } diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index 5c9a3159ad..754552aed3 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -17,7 +17,7 @@ import ( ) func (s *WorkspaceService) ListWorkspaces(ctx context.Context, params services.WorkspaceRetrievalParams) ([]services.WorkspaceDTO, error) { - workspaces, err := s.workspaceStore.List() + workspaces, err := s.workspaceStore.List(ctx) if err != nil { return nil, err } diff --git a/pkg/server/workspaces/metadata.go b/pkg/server/workspaces/metadata.go index 70be5271e3..5d4294c717 100644 --- a/pkg/server/workspaces/metadata.go +++ b/pkg/server/workspaces/metadata.go @@ -4,12 +4,14 @@ package workspaces import ( + "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) -func (s *WorkspaceService) SetWorkspaceMetadata(workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { - m, err := s.workspaceMetadataStore.Find(&stores.WorkspaceMetadataFilter{ +func (s *WorkspaceService) SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { + m, err := s.workspaceMetadataStore.Find(ctx, &stores.WorkspaceMetadataFilter{ WorkspaceId: &workspaceId, }) if err != nil { @@ -19,5 +21,5 @@ func (s *WorkspaceService) SetWorkspaceMetadata(workspaceId string, metadata *mo m.GitStatus = metadata.GitStatus m.Uptime = metadata.Uptime m.UpdatedAt = metadata.UpdatedAt - return m, s.workspaceMetadataStore.Save(m) + return m, s.workspaceMetadataStore.Save(ctx, m) } diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index 78c6514076..7934d53863 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -15,67 +15,110 @@ import ( ) func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId string) error { - ws, err := s.workspaceStore.Find(workspaceId) + var err error + ctx, err = s.workspaceStore.BeginTransaction(ctx) + if err != nil { + return s.handleRemoveError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.workspaceStore) + + ws, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) } ws.Name = util.AddDeletedToName(ws.Name) - err = s.workspaceStore.Save(ws) + err = s.workspaceStore.Save(ctx, ws) if err != nil { return s.handleRemoveError(ctx, ws, err) } err = s.createJob(ctx, ws.Id, models.JobActionDelete) + if err != nil { + return s.handleRemoveError(ctx, ws, err) + } + + err = s.workspaceStore.CommitTransaction(ctx) return s.handleRemoveError(ctx, ws, err) } // ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { - ws, err := s.workspaceStore.Find(workspaceId) + var err error + ctx, err = s.workspaceStore.BeginTransaction(ctx) + if err != nil { + return s.handleRemoveError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.workspaceStore) + + ws, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) } ws.Name = util.AddDeletedToName(ws.Name) - err = s.workspaceStore.Save(ws) + err = s.workspaceStore.Save(ctx, ws) if err != nil { return s.handleRemoveError(ctx, ws, err) } err = s.createJob(ctx, ws.Id, models.JobActionForceDelete) + if err != nil { + return s.handleRemoveError(ctx, ws, err) + } + + err = s.workspaceStore.CommitTransaction(ctx) return s.handleRemoveError(ctx, ws, err) } func (s *WorkspaceService) HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error { - err := s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", workspaceId)) + var err error + ctx, err = s.workspaceStore.BeginTransaction(ctx) + if err != nil { + return s.handleRemoveError(ctx, nil, err) + } + + defer stores.RecoverAndRollback(ctx, s.workspaceStore) + + err = s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", workspaceId)) if err != nil { // Should not fail the whole operation if the API key cannot be revoked log.Error(err) } - ws, err := s.workspaceStore.Find(workspaceId) + ws, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) } - metadata, err := s.workspaceMetadataStore.Find(&stores.WorkspaceMetadataFilter{WorkspaceId: &workspaceId}) + metadata, err := s.workspaceMetadataStore.Find(ctx, &stores.WorkspaceMetadataFilter{WorkspaceId: &workspaceId}) if err != nil { return s.handleRemoveError(ctx, ws, err) } - err = s.workspaceMetadataStore.Delete(metadata) + err = s.workspaceMetadataStore.Delete(ctx, metadata) if err != nil { return s.handleRemoveError(ctx, ws, err) } - err = s.workspaceStore.Delete(ws) + err = s.workspaceStore.Delete(ctx, ws) + if err != nil { + return s.handleRemoveError(ctx, ws, err) + } + + err = s.workspaceStore.CommitTransaction(ctx) return s.handleRemoveError(ctx, ws, err) } func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Workspace, err error) error { + if err != nil { + err = s.workspaceStore.RollbackTransaction(ctx, err) + } + if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index ee07cc2638..82f3acd1a3 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -90,6 +90,6 @@ type WorkspaceService struct { loggerFactory logs.LoggerFactory } -func (s *WorkspaceService) GetWorkspaceLogReader(workspaceId string) (io.Reader, error) { +func (s *WorkspaceService) GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) { return s.loggerFactory.CreateWorkspaceLogReader(workspaceId) } diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index f2685dd682..b56bf082bd 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -114,7 +114,7 @@ func TestTargetService(t *testing.T) { ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") targetStore := t_targets.NewInMemoryTargetStore() - err := targetStore.Save(tg) + err := targetStore.Save(ctx, tg) require.Nil(t, err) workspaceStore := t_workspaces.NewInMemoryWorkspaceStore() @@ -128,7 +128,7 @@ func TestTargetService(t *testing.T) { service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - t, err := targetStore.Find(&stores.TargetFilter{IdOrName: &targetId}) + t, err := targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return nil, err } @@ -307,7 +307,7 @@ func TestTargetService(t *testing.T) { }) t.Run("ForceRemoveWorkspace", func(t *testing.T) { - err := workspaceStore.Save(ws) + err := workspaceStore.Save(ctx, ws) require.Nil(t, err) mockProvisioner.On("DestroyWorkspace", mock.Anything, tg).Return(nil) @@ -322,10 +322,10 @@ func TestTargetService(t *testing.T) { }) t.Run("SetWorkspaceMetadata", func(t *testing.T) { - err := workspaceStore.Save(ws) + err := workspaceStore.Save(ctx, ws) require.Nil(t, err) - res, err := service.SetWorkspaceMetadata(createWorkspaceDTO.Id, &models.WorkspaceMetadata{ + res, err := service.SetWorkspaceMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ Uptime: 10, GitStatus: &models.GitStatus{ CurrentBranch: "main", diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index a491a42425..e0ba40f17e 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -13,12 +13,16 @@ import ( ) func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { - ws, err := s.workspaceStore.Find(workspaceId) + ws, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleStartError(ctx, ws, stores.ErrWorkspaceNotFound) } err = s.createJob(ctx, ws.Id, models.JobActionStart) + if err != nil { + return s.handleStartError(ctx, ws, err) + } + return s.handleStartError(ctx, ws, err) } diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 64a16055d0..0af8fb1fd0 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -13,12 +13,16 @@ import ( ) func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { - ws, err := s.workspaceStore.Find(workspaceId) + ws, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleStopError(ctx, ws, stores.ErrWorkspaceNotFound) } err = s.createJob(ctx, ws.Id, models.JobActionStop) + if err != nil { + return s.handleStopError(ctx, ws, err) + } + return s.handleStopError(ctx, ws, err) } diff --git a/pkg/server/workspacetemplates/prebuild.go b/pkg/server/workspacetemplates/prebuild.go index 4ce4749805..89e221aa9e 100644 --- a/pkg/server/workspacetemplates/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -18,10 +18,8 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, createPrebuildDto services.CreatePrebuildDTO) (*services.PrebuildDTO, error) { - ctx := context.Background() - - workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ +func (s *WorkspaceTemplateService) SetPrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto services.CreatePrebuildDTO) (*services.PrebuildDTO, error) { + workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplateName, }) if err != nil { @@ -81,7 +79,7 @@ func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, cre } } - err = s.templateStore.Save(workspaceTemplate) + err = s.templateStore.Save(ctx, workspaceTemplate) if err != nil { if newWebhookId != "" { err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, newWebhookId) @@ -103,8 +101,8 @@ func (s *WorkspaceTemplateService) SetPrebuild(workspaceTemplateName string, cre }, nil } -func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*services.PrebuildDTO, error) { - wt, err := s.templateStore.Find(workspaceTemplateFilter) +func (s *WorkspaceTemplateService) FindPrebuild(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*services.PrebuildDTO, error) { + wt, err := s.templateStore.Find(ctx, workspaceTemplateFilter) if err != nil { return nil, stores.ErrWorkspaceTemplateNotFound } @@ -130,9 +128,9 @@ func (s *WorkspaceTemplateService) FindPrebuild(workspaceTemplateFilter *stores. }, nil } -func (s *WorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*services.PrebuildDTO, error) { +func (s *WorkspaceTemplateService) ListPrebuilds(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*services.PrebuildDTO, error) { var result []*services.PrebuildDTO - wts, err := s.templateStore.List(workspaceTemplateFilter) + wts, err := s.templateStore.List(ctx, workspaceTemplateFilter) if err != nil { return nil, stores.ErrWorkspaceTemplateNotFound } @@ -153,10 +151,8 @@ func (s *WorkspaceTemplateService) ListPrebuilds(workspaceTemplateFilter *stores return result, nil } -func (s *WorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, id string, force bool) []error { - ctx := context.Background() - - workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ +func (s *WorkspaceTemplateService) DeletePrebuild(ctx context.Context, workspaceTemplateName string, id string, force bool) []error { + workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplateName, }) if err != nil { @@ -165,7 +161,7 @@ func (s *WorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, // Get all prebuilds for this workspace template's repository URL and // if this is the last prebuild, unregister the Git provider webhook - prebuilds, err := s.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + prebuilds, err := s.ListPrebuilds(ctx, &stores.WorkspaceTemplateFilter{ Url: &workspaceTemplate.RepositoryUrl, }, nil) if err != nil { @@ -215,7 +211,7 @@ func (s *WorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, return []error{err} } - err = s.templateStore.Save(workspaceTemplate) + err = s.templateStore.Save(ctx, workspaceTemplate) if err != nil { return []error{err} } @@ -225,10 +221,8 @@ func (s *WorkspaceTemplateService) DeletePrebuild(workspaceTemplateName string, // TODO: revise build trigger strategy // We should discuss if the function should throw if the build can not be created or move on to the next one -func (s *WorkspaceTemplateService) ProcessGitEvent(data gitprovider.GitEventData) error { - ctx := context.Background() - - workspaceTemplates, err := s.List(&stores.WorkspaceTemplateFilter{ +func (s *WorkspaceTemplateService) ProcessGitEvent(ctx context.Context, data gitprovider.GitEventData) error { + workspaceTemplates, err := s.List(ctx, &stores.WorkspaceTemplateFilter{ Url: &data.Url, }) if err != nil { @@ -286,10 +280,8 @@ func (s *WorkspaceTemplateService) ProcessGitEvent(data gitprovider.GitEventData } // Marks the [retention] oldest published builds for deletion for each prebuild -func (s *WorkspaceTemplateService) EnforceRetentionPolicy() error { - ctx := context.Background() - - prebuilds, err := s.ListPrebuilds(nil, nil) +func (s *WorkspaceTemplateService) EnforceRetentionPolicy(ctx context.Context) error { + prebuilds, err := s.ListPrebuilds(ctx, nil, nil) if err != nil { return err } @@ -334,11 +326,11 @@ func (s *WorkspaceTemplateService) EnforceRetentionPolicy() error { return nil } -func (s *WorkspaceTemplateService) StartRetentionPoller() error { +func (s *WorkspaceTemplateService) StartRetentionPoller(ctx context.Context) error { scheduler := scheduler.NewCronScheduler() err := scheduler.AddFunc(runners.DEFAULT_JOB_POLL_INTERVAL, func() { - err := s.EnforceRetentionPolicy() + err := s.EnforceRetentionPolicy(ctx) if err != nil { log.Error(err) } diff --git a/pkg/server/workspacetemplates/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go index 4e5bd1368a..37de0b37ff 100644 --- a/pkg/server/workspacetemplates/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -4,6 +4,7 @@ package workspacetemplates_test import ( + "context" "time" "github.com/daytonaio/daytona/internal/util" @@ -67,7 +68,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestSetPrebuild() { }).Return(repository1, nil) s.gitProviderService.On("GetPrebuildWebhook", "github", repository1, "").Return(util.Pointer("webhook-id"), nil) - newPrebuildDto, err := s.workspaceTemplateService.SetPrebuild(workspaceTemplate1.Name, services.CreatePrebuildDTO{ + newPrebuildDto, err := s.workspaceTemplateService.SetPrebuild(context.TODO(), workspaceTemplate1.Name, services.CreatePrebuildDTO{ Id: &prebuild3.Id, Branch: prebuild3.Branch, CommitInterval: prebuild3.CommitInterval, @@ -76,7 +77,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestSetPrebuild() { }) require.Nil(err) - prebuildDtos, err := s.workspaceTemplateService.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + prebuildDtos, err := s.workspaceTemplateService.ListPrebuilds(context.TODO(), &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplate1.Name, }, nil) require.Nil(err) @@ -86,7 +87,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestSetPrebuild() { func (s *WorkspaceTemplateServiceTestSuite) TestFindPrebuild() { require := s.Require() - prebuild, err := s.workspaceTemplateService.FindPrebuild(&stores.WorkspaceTemplateFilter{ + prebuild, err := s.workspaceTemplateService.FindPrebuild(context.TODO(), &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplate1.Name, }, &stores.PrebuildFilter{ Id: &prebuild1.Id, @@ -97,7 +98,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestFindPrebuild() { func (s *WorkspaceTemplateServiceTestSuite) TestListPrebuilds() { require := s.Require() - prebuildDtos, err := s.workspaceTemplateService.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + prebuildDtos, err := s.workspaceTemplateService.ListPrebuilds(context.TODO(), &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplate1.Name, }, nil) require.Nil(err) @@ -114,10 +115,10 @@ func (s *WorkspaceTemplateServiceTestSuite) TestDeletePrebuild() { PrebuildIds: &[]string{prebuild2.Id}, }, false).Return([]error{}) - err := s.workspaceTemplateService.DeletePrebuild(workspaceTemplate1.Name, prebuild2.Id, false) + err := s.workspaceTemplateService.DeletePrebuild(context.TODO(), workspaceTemplate1.Name, prebuild2.Id, false) require.Nil(err) - prebuildDtos, errs := s.workspaceTemplateService.ListPrebuilds(&stores.WorkspaceTemplateFilter{ + prebuildDtos, errs := s.workspaceTemplateService.ListPrebuilds(context.TODO(), &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplate1.Name, }, nil) require.Nil(errs) @@ -160,7 +161,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventCommitInterval() s.gitProvider.On("GetCommitsRange", repository1, repository1.Sha, data.Sha).Return(3, nil) - err := s.workspaceTemplateService.ProcessGitEvent(data) + err := s.workspaceTemplateService.ProcessGitEvent(context.TODO(), data) require.Nil(err) } @@ -189,7 +190,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventTriggerFiles() { }, } - err := s.workspaceTemplateService.ProcessGitEvent(data) + err := s.workspaceTemplateService.ProcessGitEvent(context.TODO(), data) require.Nil(err) } @@ -225,6 +226,6 @@ func (s *WorkspaceTemplateServiceTestSuite) TestEnforceRetentionPolicy() { Id: util.Pointer("1"), }, false).Return([]error{}) - err := s.workspaceTemplateService.EnforceRetentionPolicy() + err := s.workspaceTemplateService.EnforceRetentionPolicy(context.TODO()) require.Nil(err) } diff --git a/pkg/server/workspacetemplates/service.go b/pkg/server/workspacetemplates/service.go index 2487237a96..ac7f2c99ce 100644 --- a/pkg/server/workspacetemplates/service.go +++ b/pkg/server/workspacetemplates/service.go @@ -60,39 +60,52 @@ func NewWorkspaceTemplateService(config WorkspaceTemplateServiceConfig) services } } -func (s *WorkspaceTemplateService) List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { - return s.templateStore.List(filter) +func (s *WorkspaceTemplateService) List(ctx context.Context, filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { + return s.templateStore.List(ctx, filter) } -func (s *WorkspaceTemplateService) SetDefault(workspaceTemplateName string) error { - workspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ +func (s *WorkspaceTemplateService) SetDefault(ctx context.Context, workspaceTemplateName string) error { + var err error + ctx, err = s.templateStore.BeginTransaction(ctx) + if err != nil { + return err + } + + defer stores.RecoverAndRollback(ctx, s.templateStore) + + workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplateName, }) if err != nil { - return err + return s.templateStore.RollbackTransaction(ctx, err) } - defaultWorkspaceTemplate, err := s.Find(&stores.WorkspaceTemplateFilter{ + defaultWorkspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ Url: &workspaceTemplate.RepositoryUrl, Default: util.Pointer(true), }) if err != nil && !stores.IsWorkspaceTemplateNotFound(err) { - return err + return s.templateStore.RollbackTransaction(ctx, err) } if defaultWorkspaceTemplate != nil { defaultWorkspaceTemplate.IsDefault = false - err := s.templateStore.Save(defaultWorkspaceTemplate) + err := s.templateStore.Save(ctx, defaultWorkspaceTemplate) if err != nil { - return err + return s.templateStore.RollbackTransaction(ctx, err) } } workspaceTemplate.IsDefault = true - return s.templateStore.Save(workspaceTemplate) + err = s.templateStore.Save(ctx, workspaceTemplate) + if err != nil { + return s.templateStore.RollbackTransaction(ctx, err) + } + + return s.templateStore.CommitTransaction(ctx) } -func (s *WorkspaceTemplateService) Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { +func (s *WorkspaceTemplateService) Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { if filter != nil && filter.Url != nil { cleanedUrl := util.CleanUpRepositoryUrl(*filter.Url) if !strings.HasSuffix(cleanedUrl, ".git") { @@ -100,22 +113,22 @@ func (s *WorkspaceTemplateService) Find(filter *stores.WorkspaceTemplateFilter) } filter.Url = util.Pointer(cleanedUrl) } - return s.templateStore.Find(filter) + return s.templateStore.Find(ctx, filter) } -func (s *WorkspaceTemplateService) Save(workspaceTemplate *models.WorkspaceTemplate) error { +func (s *WorkspaceTemplateService) Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { workspaceTemplate.RepositoryUrl = util.CleanUpRepositoryUrl(workspaceTemplate.RepositoryUrl) - err := s.templateStore.Save(workspaceTemplate) + err := s.templateStore.Save(ctx, workspaceTemplate) if err != nil { return err } - return s.SetDefault(workspaceTemplate.Name) + return s.SetDefault(ctx, workspaceTemplate.Name) } -func (s *WorkspaceTemplateService) Delete(workspaceTemplateName string, force bool) []error { - wt, err := s.Find(&stores.WorkspaceTemplateFilter{ +func (s *WorkspaceTemplateService) Delete(ctx context.Context, workspaceTemplateName string, force bool) []error { + wt, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplateName, }) if err != nil { @@ -124,13 +137,13 @@ func (s *WorkspaceTemplateService) Delete(workspaceTemplateName string, force bo // DeletePrebuild handles deleting the builds and removing the webhook for _, prebuild := range wt.Prebuilds { - errs := s.DeletePrebuild(wt.Name, prebuild.Id, force) + errs := s.DeletePrebuild(ctx, wt.Name, prebuild.Id, force) if len(errs) > 0 { return errs } } - err = s.templateStore.Delete(wt) + err = s.templateStore.Delete(ctx, wt) if err != nil { return []error{err} } diff --git a/pkg/server/workspacetemplates/service_test.go b/pkg/server/workspacetemplates/service_test.go index 35835e69a5..2c324ab64f 100644 --- a/pkg/server/workspacetemplates/service_test.go +++ b/pkg/server/workspacetemplates/service_test.go @@ -187,7 +187,7 @@ func (s *WorkspaceTemplateServiceTestSuite) SetupTest() { }) for _, wt := range expectedWorkspaceTemplates { - _ = s.workspaceTemplateStore.Save(wt) + _ = s.workspaceTemplateStore.Save(context.TODO(), wt) } } @@ -198,7 +198,7 @@ func TestWorkspaceTemplateService(t *testing.T) { func (s *WorkspaceTemplateServiceTestSuite) TestList() { require := s.Require() - workspaceTemplates, err := s.workspaceTemplateService.List(nil) + workspaceTemplates, err := s.workspaceTemplateService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedWorkspaceTemplates, workspaceTemplates) } @@ -206,7 +206,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestList() { func (s *WorkspaceTemplateServiceTestSuite) TestFind() { require := s.Require() - workspaceTemplate, err := s.workspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + workspaceTemplate, err := s.workspaceTemplateService.Find(context.TODO(), &stores.WorkspaceTemplateFilter{ Name: &workspaceTemplate1.Name, }) require.Nil(err) @@ -215,10 +215,10 @@ func (s *WorkspaceTemplateServiceTestSuite) TestFind() { func (s *WorkspaceTemplateServiceTestSuite) TestSetDefault() { require := s.Require() - err := s.workspaceTemplateService.SetDefault(workspaceTemplate2.Name) + err := s.workspaceTemplateService.SetDefault(context.TODO(), workspaceTemplate2.Name) require.Nil(err) - workspaceTemplate, err := s.workspaceTemplateService.Find(&stores.WorkspaceTemplateFilter{ + workspaceTemplate, err := s.workspaceTemplateService.Find(context.TODO(), &stores.WorkspaceTemplateFilter{ Url: util.Pointer(workspaceTemplate1.RepositoryUrl), Default: util.Pointer(true), }) @@ -232,10 +232,10 @@ func (s *WorkspaceTemplateServiceTestSuite) TestSave() { require := s.Require() - err := s.workspaceTemplateService.Save(workspaceTemplate4) + err := s.workspaceTemplateService.Save(context.TODO(), workspaceTemplate4) require.Nil(err) - workspaceTemplates, err := s.workspaceTemplateService.List(nil) + workspaceTemplates, err := s.workspaceTemplateService.List(context.TODO(), nil) require.Nil(err) require.ElementsMatch(expectedWorkspaceTemplates, workspaceTemplates) } @@ -245,10 +245,10 @@ func (s *WorkspaceTemplateServiceTestSuite) TestDelete() { require := s.Require() - err := s.workspaceTemplateService.Delete(workspaceTemplate3.Name, false) + err := s.workspaceTemplateService.Delete(context.TODO(), workspaceTemplate3.Name, false) require.Nil(err) - workspaceTemplates, errs := s.workspaceTemplateService.List(nil) + workspaceTemplates, errs := s.workspaceTemplateService.List(context.TODO(), nil) require.Nil(errs) require.ElementsMatch(expectedWorkspaceTemplates, workspaceTemplates) } diff --git a/pkg/services/api_key.go b/pkg/services/api_key.go index 536314c404..263645d699 100644 --- a/pkg/services/api_key.go +++ b/pkg/services/api_key.go @@ -3,13 +3,17 @@ package services -import "github.com/daytonaio/daytona/pkg/models" +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" +) type IApiKeyService interface { - Generate(keyType models.ApiKeyType, name string) (string, error) - IsWorkspaceApiKey(apiKey string) bool - IsTargetApiKey(apiKey string) bool - IsValidApiKey(apiKey string) bool - ListClientKeys() ([]*models.ApiKey, error) - Revoke(name string) error + Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) + IsWorkspaceApiKey(ctx context.Context, apiKey string) bool + IsTargetApiKey(ctx context.Context, apiKey string) bool + IsValidApiKey(ctx context.Context, apiKey string) bool + ListClientKeys(ctx context.Context) ([]*models.ApiKey, error) + Revoke(ctx context.Context, name string) error } diff --git a/pkg/services/build.go b/pkg/services/build.go index c5cb3084e2..3be5bebf6e 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -4,6 +4,7 @@ package services import ( + "context" "errors" "io" "time" @@ -13,13 +14,13 @@ import ( ) type IBuildService interface { - Create(CreateBuildDTO) (string, error) - Find(filter *BuildFilter) (*BuildDTO, error) - List(filter *BuildFilter) ([]*BuildDTO, error) - Delete(filter *BuildFilter, force bool) []error - HandleSuccessfulRemoval(id string) error - AwaitEmptyList(time.Duration) error - GetBuildLogReader(buildId string) (io.Reader, error) + Create(ctx context.Context, createBuildDTO CreateBuildDTO) (string, error) + Find(ctx context.Context, filter *BuildFilter) (*BuildDTO, error) + List(ctx context.Context, filter *BuildFilter) ([]*BuildDTO, error) + Delete(ctx context.Context, filter *BuildFilter, force bool) []error + HandleSuccessfulRemoval(ctx context.Context, id string) error + AwaitEmptyList(ctx context.Context, waitTime time.Duration) error + GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) } type BuildDTO struct { diff --git a/pkg/services/env.go b/pkg/services/env.go index 08becbb7ba..84687f1b43 100644 --- a/pkg/services/env.go +++ b/pkg/services/env.go @@ -4,16 +4,17 @@ package services import ( + "context" "strings" "github.com/daytonaio/daytona/pkg/models" ) type IEnvironmentVariableService interface { - List() ([]*models.EnvironmentVariable, error) - Map() (EnvironmentVariables, error) - Save(environmentVariable *models.EnvironmentVariable) error - Delete(key string) error + List(ctx context.Context) ([]*models.EnvironmentVariable, error) + Map(ctx context.Context) (EnvironmentVariables, error) + Save(ctx context.Context, environmentVariable *models.EnvironmentVariable) error + Delete(ctx context.Context, key string) error } type EnvironmentVariables map[string]string diff --git a/pkg/services/git_provider.go b/pkg/services/git_provider.go index 4dde7183c0..5b2648aeb4 100644 --- a/pkg/services/git_provider.go +++ b/pkg/services/git_provider.go @@ -4,6 +4,7 @@ package services import ( + "context" "net/http" "github.com/daytonaio/daytona/pkg/gitprovider" @@ -11,21 +12,21 @@ import ( ) type IGitProviderService interface { - GetConfig(id string) (*models.GitProviderConfig, error) - ListConfigsForUrl(url string) ([]*models.GitProviderConfig, error) - GetGitProvider(id string) (gitprovider.GitProvider, error) - GetGitProviderForUrl(url string) (gitprovider.GitProvider, string, error) - GetGitProviderForHttpRequest(req *http.Request) (gitprovider.GitProvider, error) - GetGitUser(gitProviderId string) (*gitprovider.GitUser, error) - GetNamespaces(gitProviderId string, options gitprovider.ListOptions) ([]*gitprovider.GitNamespace, error) - GetRepoBranches(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) - GetRepoPRs(gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) - GetRepositories(gitProviderId string, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) - ListConfigs() ([]*models.GitProviderConfig, error) - RemoveGitProvider(gitProviderId string) error - SetGitProviderConfig(providerConfig *models.GitProviderConfig) error - GetLastCommitSha(repo *gitprovider.GitRepository) (string, error) - RegisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) - GetPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) - UnregisterPrebuildWebhook(gitProviderId string, repo *gitprovider.GitRepository, id string) error + GetConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) + ListConfigsForUrl(ctx context.Context, url string) ([]*models.GitProviderConfig, error) + GetGitProvider(ctx context.Context, id string) (gitprovider.GitProvider, error) + GetGitProviderForUrl(ctx context.Context, url string) (gitprovider.GitProvider, string, error) + GetGitProviderForHttpRequest(ctx context.Context, req *http.Request) (gitprovider.GitProvider, error) + GetGitUser(ctx context.Context, gitProviderId string) (*gitprovider.GitUser, error) + GetNamespaces(ctx context.Context, gitProviderId string, options gitprovider.ListOptions) ([]*gitprovider.GitNamespace, error) + GetRepoBranches(ctx context.Context, gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) + GetRepoPRs(ctx context.Context, gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) + GetRepositories(ctx context.Context, gitProviderId string, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) + ListConfigs(ctx context.Context) ([]*models.GitProviderConfig, error) + RemoveGitProvider(ctx context.Context, gitProviderId string) error + SetGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error + GetLastCommitSha(ctx context.Context, repo *gitprovider.GitRepository) (string, error) + RegisterPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) + GetPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) + UnregisterPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error } diff --git a/pkg/services/job.go b/pkg/services/job.go index 2cbdaebb5c..2658c85f44 100644 --- a/pkg/services/job.go +++ b/pkg/services/job.go @@ -4,6 +4,7 @@ package services import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" @@ -11,11 +12,11 @@ import ( ) type IJobService interface { - Create(job *models.Job) error - Update(job *models.Job) error - Find(filter *stores.JobFilter) (*models.Job, error) - List(filter *stores.JobFilter) ([]*models.Job, error) - Delete(job *models.Job) error + Create(ctx context.Context, job *models.Job) error + SetState(ctx context.Context, jobId string, state models.JobState, error *string) error + Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) + List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) + Delete(ctx context.Context, job *models.Job) error } var ( diff --git a/pkg/services/target.go b/pkg/services/target.go index 7247b62dd0..96014cbaa8 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -25,7 +25,7 @@ type ITargetService interface { HandleSuccessfulCreation(ctx context.Context, targetId string) error HandleSuccessfulRemoval(ctx context.Context, targetId string) error - SetTargetMetadata(targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) + SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) } type TargetDTO struct { diff --git a/pkg/services/target_config.go b/pkg/services/target_config.go index d14043d93a..d5b91d240c 100644 --- a/pkg/services/target_config.go +++ b/pkg/services/target_config.go @@ -4,6 +4,8 @@ package services import ( + "context" + "github.com/daytonaio/daytona/pkg/models" ) @@ -14,9 +16,9 @@ type AddTargetConfigDTO struct { } // @name AddTargetConfigDTO type ITargetConfigService interface { - Add(targetConfig AddTargetConfigDTO) (*models.TargetConfig, error) - Find(idOrName string) (*models.TargetConfig, error) - List() ([]*models.TargetConfig, error) - Map() (map[string]*models.TargetConfig, error) - Delete(targetConfigId string) error + Add(ctx context.Context, targetConfig AddTargetConfigDTO) (*models.TargetConfig, error) + Find(ctx context.Context, idOrName string) (*models.TargetConfig, error) + List(ctx context.Context) ([]*models.TargetConfig, error) + Map(ctx context.Context) (map[string]*models.TargetConfig, error) + Delete(ctx context.Context, targetConfigId string) error } diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index bff0a5bd76..90d68d52cc 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -22,8 +22,8 @@ type IWorkspaceService interface { ForceRemoveWorkspace(ctx context.Context, workspaceId string) error HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error - GetWorkspaceLogReader(workspaceId string) (io.Reader, error) - SetWorkspaceMetadata(workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) + GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) + SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) } type WorkspaceDTO struct { diff --git a/pkg/services/workspace_template.go b/pkg/services/workspace_template.go index e1da7d5667..b5181839ed 100644 --- a/pkg/services/workspace_template.go +++ b/pkg/services/workspace_template.go @@ -4,26 +4,28 @@ package services import ( + "context" + "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type IWorkspaceTemplateService interface { - Save(workspaceTemplate *models.WorkspaceTemplate) error - Find(filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) - List(filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) - SetDefault(workspaceTemplateName string) error - Delete(workspaceTemplateName string, force bool) []error - - SetPrebuild(workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) - FindPrebuild(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*PrebuildDTO, error) - ListPrebuilds(workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*PrebuildDTO, error) - DeletePrebuild(workspaceTemplateName string, id string, force bool) []error - - StartRetentionPoller() error - EnforceRetentionPolicy() error - ProcessGitEvent(gitprovider.GitEventData) error + Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error + Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) + List(ctx context.Context, filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) + SetDefault(ctx context.Context, workspaceTemplateName string) error + Delete(ctx context.Context, workspaceTemplateName string, force bool) []error + + SetPrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) + FindPrebuild(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*PrebuildDTO, error) + ListPrebuilds(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*PrebuildDTO, error) + DeletePrebuild(ctx context.Context, workspaceTemplateName string, id string, force bool) []error + + StartRetentionPoller(ctx context.Context) error + EnforceRetentionPolicy(ctx context.Context) error + ProcessGitEvent(ctx context.Context, gitEventData gitprovider.GitEventData) error } type CreateWorkspaceTemplateDTO struct { diff --git a/pkg/stores/api_key.go b/pkg/stores/api_key.go index 4dd9a3a351..bb1a4522e0 100644 --- a/pkg/stores/api_key.go +++ b/pkg/stores/api_key.go @@ -4,17 +4,19 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type ApiKeyStore interface { - List() ([]*models.ApiKey, error) - Find(key string) (*models.ApiKey, error) - FindByName(name string) (*models.ApiKey, error) - Save(apiKey *models.ApiKey) error - Delete(apiKey *models.ApiKey) error + IStore + List(ctx context.Context) ([]*models.ApiKey, error) + Find(ctx context.Context, key string) (*models.ApiKey, error) + FindByName(ctx context.Context, name string) (*models.ApiKey, error) + Save(ctx context.Context, apiKey *models.ApiKey) error + Delete(ctx context.Context, apiKey *models.ApiKey) error } var ( diff --git a/pkg/stores/build.go b/pkg/stores/build.go index b6da33c9b1..d05b7fdf9c 100644 --- a/pkg/stores/build.go +++ b/pkg/stores/build.go @@ -4,16 +4,18 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type BuildStore interface { - Find(filter *BuildFilter) (*models.Build, error) - List(filter *BuildFilter) ([]*models.Build, error) - Save(build *models.Build) error - Delete(id string) error + IStore + Find(ctx context.Context, filter *BuildFilter) (*models.Build, error) + List(ctx context.Context, filter *BuildFilter) ([]*models.Build, error) + Save(ctx context.Context, build *models.Build) error + Delete(ctx context.Context, id string) error } var ( diff --git a/pkg/stores/env.go b/pkg/stores/env.go index b8482b44f6..7ab93e0d92 100644 --- a/pkg/stores/env.go +++ b/pkg/stores/env.go @@ -4,15 +4,17 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type EnvironmentVariableStore interface { - List() ([]*models.EnvironmentVariable, error) - Save(environmentVariable *models.EnvironmentVariable) error - Delete(key string) error + IStore + List(ctx context.Context) ([]*models.EnvironmentVariable, error) + Save(ctx context.Context, environmentVariable *models.EnvironmentVariable) error + Delete(ctx context.Context, key string) error } var ( diff --git a/pkg/stores/git_provider.go b/pkg/stores/git_provider.go index dfd70ebb8c..8b96770927 100644 --- a/pkg/stores/git_provider.go +++ b/pkg/stores/git_provider.go @@ -4,16 +4,18 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type GitProviderConfigStore interface { - List() ([]*models.GitProviderConfig, error) - Find(id string) (*models.GitProviderConfig, error) - Save(*models.GitProviderConfig) error - Delete(*models.GitProviderConfig) error + IStore + List(ctx context.Context) ([]*models.GitProviderConfig, error) + Find(ctx context.Context, id string) (*models.GitProviderConfig, error) + Save(ctx context.Context, gpc *models.GitProviderConfig) error + Delete(ctx context.Context, gpc *models.GitProviderConfig) error } var ( diff --git a/pkg/stores/job_store.go b/pkg/stores/job_store.go index 761f4b402f..7da198a1fb 100644 --- a/pkg/stores/job_store.go +++ b/pkg/stores/job_store.go @@ -4,16 +4,18 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type JobStore interface { - List(filter *JobFilter) ([]*models.Job, error) - Find(filter *JobFilter) (*models.Job, error) - Save(job *models.Job) error - Delete(job *models.Job) error + IStore + List(ctx context.Context, filter *JobFilter) ([]*models.Job, error) + Find(ctx context.Context, filter *JobFilter) (*models.Job, error) + Save(ctx context.Context, job *models.Job) error + Delete(ctx context.Context, job *models.Job) error } type JobFilter struct { diff --git a/pkg/stores/store.go b/pkg/stores/store.go new file mode 100644 index 0000000000..f38b868c5e --- /dev/null +++ b/pkg/stores/store.go @@ -0,0 +1,30 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "context" + + log "github.com/sirupsen/logrus" +) + +type TransactionKey struct{} + +type IStore interface { + BeginTransaction(ctx context.Context) (context.Context, error) + CommitTransaction(ctx context.Context) error + // If an error ocurrs while rolling back the transaction, the error should be wrapped and returned, + // otherwise, the original error is returned + RollbackTransaction(ctx context.Context, err error) error +} + +func RecoverAndRollback(ctx context.Context, store IStore) { + if r := recover(); r != nil { + err := store.RollbackTransaction(ctx, nil) + if err != nil { + // TODO: Think about this + log.Error(err) + } + } +} diff --git a/pkg/stores/target.go b/pkg/stores/target.go index 54b179dea3..b89d1d3717 100644 --- a/pkg/stores/target.go +++ b/pkg/stores/target.go @@ -4,6 +4,7 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" @@ -15,10 +16,11 @@ type TargetFilter struct { } type TargetStore interface { - List(filter *TargetFilter) ([]*models.Target, error) - Find(filter *TargetFilter) (*models.Target, error) - Save(target *models.Target) error - Delete(target *models.Target) error + IStore + List(ctx context.Context, filter *TargetFilter) ([]*models.Target, error) + Find(ctx context.Context, filter *TargetFilter) (*models.Target, error) + Save(ctx context.Context, target *models.Target) error + Delete(ctx context.Context, target *models.Target) error } var ( diff --git a/pkg/stores/target_config.go b/pkg/stores/target_config.go index 7fb4bcca75..3aba29dfb1 100644 --- a/pkg/stores/target_config.go +++ b/pkg/stores/target_config.go @@ -4,15 +4,17 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type TargetConfigStore interface { - List(allowDeleted bool) ([]*models.TargetConfig, error) - Find(idOrName string, allowDeleted bool) (*models.TargetConfig, error) - Save(targetConfig *models.TargetConfig) error + IStore + List(ctx context.Context, allowDeleted bool) ([]*models.TargetConfig, error) + Find(ctx context.Context, idOrName string, allowDeleted bool) (*models.TargetConfig, error) + Save(ctx context.Context, targetConfig *models.TargetConfig) error } var ( diff --git a/pkg/stores/target_metadata.go b/pkg/stores/target_metadata.go index 6528243259..cc795695ed 100644 --- a/pkg/stores/target_metadata.go +++ b/pkg/stores/target_metadata.go @@ -4,6 +4,7 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" @@ -15,9 +16,10 @@ type TargetMetadataFilter struct { } type TargetMetadataStore interface { - Find(filter *TargetMetadataFilter) (*models.TargetMetadata, error) - Save(metadata *models.TargetMetadata) error - Delete(metadata *models.TargetMetadata) error + IStore + Find(ctx context.Context, filter *TargetMetadataFilter) (*models.TargetMetadata, error) + Save(ctx context.Context, metadata *models.TargetMetadata) error + Delete(ctx context.Context, metadata *models.TargetMetadata) error } var ( diff --git a/pkg/stores/workspace.go b/pkg/stores/workspace.go index 42ba8939b7..0c75c2a4be 100644 --- a/pkg/stores/workspace.go +++ b/pkg/stores/workspace.go @@ -4,16 +4,18 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" ) type WorkspaceStore interface { - List() ([]*models.Workspace, error) - Find(idOrName string) (*models.Workspace, error) - Save(workspace *models.Workspace) error - Delete(workspace *models.Workspace) error + IStore + List(ctx context.Context) ([]*models.Workspace, error) + Find(ctx context.Context, idOrName string) (*models.Workspace, error) + Save(ctx context.Context, workspace *models.Workspace) error + Delete(ctx context.Context, workspace *models.Workspace) error } var ( diff --git a/pkg/stores/workspace_metadata.go b/pkg/stores/workspace_metadata.go index 7d54fd6c16..cdd69c93b8 100644 --- a/pkg/stores/workspace_metadata.go +++ b/pkg/stores/workspace_metadata.go @@ -4,6 +4,7 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" @@ -15,9 +16,10 @@ type WorkspaceMetadataFilter struct { } type WorkspaceMetadataStore interface { - Find(filter *WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) - Save(metadata *models.WorkspaceMetadata) error - Delete(metadata *models.WorkspaceMetadata) error + IStore + Find(ctx context.Context, filter *WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) + Save(ctx context.Context, metadata *models.WorkspaceMetadata) error + Delete(ctx context.Context, metadata *models.WorkspaceMetadata) error } var ( diff --git a/pkg/stores/workspace_template.go b/pkg/stores/workspace_template.go index 0052d031d9..ddba3d8e3a 100644 --- a/pkg/stores/workspace_template.go +++ b/pkg/stores/workspace_template.go @@ -4,6 +4,7 @@ package stores import ( + "context" "errors" "github.com/daytonaio/daytona/pkg/models" @@ -26,10 +27,11 @@ type PrebuildFilter struct { } type WorkspaceTemplateStore interface { - List(filter *WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) - Find(filter *WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) - Save(workspaceTemplate *models.WorkspaceTemplate) error - Delete(workspaceTemplate *models.WorkspaceTemplate) error + IStore + List(ctx context.Context, filter *WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) + Find(ctx context.Context, filter *WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) + Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error + Delete(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error } var ( From bd385e937fce5ab9630608c17f79bd2fe63ca58c Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 6 Dec 2024 11:56:03 +0000 Subject: [PATCH 27/76] refactor: db store interface Signed-off-by: Toma Puljak --- pkg/db/api_key_store.go | 16 ++++++++-------- pkg/db/build_store.go | 14 +++++++------- pkg/db/db_store.go | 24 +++++++++++++++++------- pkg/db/env_store.go | 12 ++++++------ pkg/db/gitprovider_config_store.go | 14 +++++++------- pkg/db/job_store.go | 14 +++++++------- pkg/db/target_config_store.go | 12 ++++++------ pkg/db/target_metadata_store.go | 12 ++++++------ pkg/db/target_store.go | 14 +++++++------- pkg/db/workspace_metadata_store.go | 12 ++++++------ pkg/db/workspace_store.go | 14 +++++++------- pkg/db/workspace_template_store.go | 14 +++++++------- 12 files changed, 91 insertions(+), 81 deletions(-) diff --git a/pkg/db/api_key_store.go b/pkg/db/api_key_store.go index 01f17eb599..d224bde71b 100644 --- a/pkg/db/api_key_store.go +++ b/pkg/db/api_key_store.go @@ -11,11 +11,11 @@ import ( ) type ApiKeyStore struct { - Store + IStore } -func NewApiKeyStore(store Store) (stores.ApiKeyStore, error) { - err := store.db.AutoMigrate(&models.ApiKey{}) +func NewApiKeyStore(store IStore) (stores.ApiKeyStore, error) { + err := store.AutoMigrate(&models.ApiKey{}) if err != nil { return nil, err } @@ -24,7 +24,7 @@ func NewApiKeyStore(store Store) (stores.ApiKeyStore, error) { } func (a *ApiKeyStore) List(ctx context.Context) ([]*models.ApiKey, error) { - tx := a.getTransaction(ctx) + tx := a.GetTransaction(ctx) apiKeys := []*models.ApiKey{} tx = tx.Find(&apiKeys) @@ -36,7 +36,7 @@ func (a *ApiKeyStore) List(ctx context.Context) ([]*models.ApiKey, error) { } func (a *ApiKeyStore) Find(ctx context.Context, key string) (*models.ApiKey, error) { - tx := a.getTransaction(ctx) + tx := a.GetTransaction(ctx) apiKey := &models.ApiKey{} tx = tx.Where("key_hash = ?", key).First(apiKey) @@ -51,7 +51,7 @@ func (a *ApiKeyStore) Find(ctx context.Context, key string) (*models.ApiKey, err } func (a *ApiKeyStore) FindByName(ctx context.Context, name string) (*models.ApiKey, error) { - tx := a.getTransaction(ctx) + tx := a.GetTransaction(ctx) apiKey := &models.ApiKey{} tx = tx.Where("name = ?", name).First(apiKey) @@ -66,7 +66,7 @@ func (a *ApiKeyStore) FindByName(ctx context.Context, name string) (*models.ApiK } func (a *ApiKeyStore) Save(ctx context.Context, apiKey *models.ApiKey) error { - tx := a.getTransaction(ctx) + tx := a.GetTransaction(ctx) tx = tx.Save(apiKey) if tx.Error != nil { @@ -77,7 +77,7 @@ func (a *ApiKeyStore) Save(ctx context.Context, apiKey *models.ApiKey) error { } func (a *ApiKeyStore) Delete(ctx context.Context, apiKey *models.ApiKey) error { - tx := a.getTransaction(ctx) + tx := a.GetTransaction(ctx) tx = tx.Where("key_hash = ?", apiKey.KeyHash).Delete(&models.ApiKey{}) if tx.Error != nil { diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index 0d44913794..429b66644f 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -16,12 +16,12 @@ import ( ) type BuildStore struct { - Store + IStore Lock sync.Mutex } -func NewBuildStore(store Store) (stores.BuildStore, error) { - err := store.db.AutoMigrate(&models.Build{}) +func NewBuildStore(store IStore) (stores.BuildStore, error) { + err := store.AutoMigrate(&models.Build{}) if err != nil { return nil, err } @@ -33,7 +33,7 @@ func (b *BuildStore) Find(ctx context.Context, filter *stores.BuildFilter) (*mod b.Lock.Lock() defer b.Lock.Unlock() - tx := b.getTransaction(ctx) + tx := b.GetTransaction(ctx) build := &models.Build{} tx = preloadBuildEntities(processBuildFilters(tx, filter)).First(build) @@ -52,7 +52,7 @@ func (b *BuildStore) List(ctx context.Context, filter *stores.BuildFilter) ([]*m b.Lock.Lock() defer b.Lock.Unlock() - tx := b.getTransaction(ctx) + tx := b.GetTransaction(ctx) builds := []*models.Build{} tx = preloadBuildEntities(processBuildFilters(tx, filter)).Find(&builds) @@ -68,7 +68,7 @@ func (b *BuildStore) Save(ctx context.Context, build *models.Build) error { b.Lock.Lock() defer b.Lock.Unlock() - tx := b.getTransaction(ctx) + tx := b.GetTransaction(ctx) tx = tx.Save(build) if tx.Error != nil { @@ -81,7 +81,7 @@ func (b *BuildStore) Save(ctx context.Context, build *models.Build) error { func (b *BuildStore) Delete(ctx context.Context, id string) error { b.Lock.Lock() defer b.Lock.Unlock() - tx := b.getTransaction(ctx) + tx := b.GetTransaction(ctx) tx = tx.Where("id = ?", id).Delete(&models.Build{}) if tx.Error != nil { diff --git a/pkg/db/db_store.go b/pkg/db/db_store.go index 5abb774fe6..297e90ef7b 100644 --- a/pkg/db/db_store.go +++ b/pkg/db/db_store.go @@ -12,15 +12,25 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -type Store struct { +type IStore interface { + stores.IStore + AutoMigrate(interface{}) error + GetTransaction(ctx context.Context) *gorm.DB +} + +type dbStore struct { db *gorm.DB } -func NewStore(db *gorm.DB) Store { - return Store{db} +func NewStore(db *gorm.DB) IStore { + return &dbStore{db} +} + +func (s *dbStore) AutoMigrate(value interface{}) error { + return s.db.AutoMigrate(value) } -func (s *Store) BeginTransaction(ctx context.Context) (context.Context, error) { +func (s *dbStore) BeginTransaction(ctx context.Context) (context.Context, error) { if ctx.Value(stores.TransactionKey{}) != nil { return ctx, nil } @@ -34,7 +44,7 @@ func (s *Store) BeginTransaction(ctx context.Context) (context.Context, error) { return ctx, nil } -func (s *Store) CommitTransaction(ctx context.Context) error { +func (s *dbStore) CommitTransaction(ctx context.Context) error { tx, ok := ctx.Value(stores.TransactionKey{}).(*gorm.DB) if !ok { return nil @@ -43,7 +53,7 @@ func (s *Store) CommitTransaction(ctx context.Context) error { return tx.Commit().Error } -func (s *Store) RollbackTransaction(ctx context.Context, err error) error { +func (s *dbStore) RollbackTransaction(ctx context.Context, err error) error { tx, ok := ctx.Value(stores.TransactionKey{}).(*gorm.DB) if !ok { return err @@ -57,7 +67,7 @@ func (s *Store) RollbackTransaction(ctx context.Context, err error) error { return fmt.Errorf("%w. Transaction rollback error: %w", err, txErr) } -func (s *Store) getTransaction(ctx context.Context) *gorm.DB { +func (s *dbStore) GetTransaction(ctx context.Context) *gorm.DB { tx, ok := ctx.Value(stores.TransactionKey{}).(*gorm.DB) if !ok { return s.db diff --git a/pkg/db/env_store.go b/pkg/db/env_store.go index 5804f1627b..1d7bcad45b 100644 --- a/pkg/db/env_store.go +++ b/pkg/db/env_store.go @@ -12,11 +12,11 @@ import ( ) type EnvironmentVariableStore struct { - Store + IStore } -func NewEnvironmentVariableStore(store Store) (stores.EnvironmentVariableStore, error) { - err := store.db.AutoMigrate(&models.EnvironmentVariable{}) +func NewEnvironmentVariableStore(store IStore) (stores.EnvironmentVariableStore, error) { + err := store.AutoMigrate(&models.EnvironmentVariable{}) if err != nil { return nil, err } @@ -25,7 +25,7 @@ func NewEnvironmentVariableStore(store Store) (stores.EnvironmentVariableStore, } func (store *EnvironmentVariableStore) List(ctx context.Context) ([]*models.EnvironmentVariable, error) { - tx := store.getTransaction(ctx) + tx := store.GetTransaction(ctx) environmentVariables := []*models.EnvironmentVariable{} tx = tx.Find(&environmentVariables) @@ -40,7 +40,7 @@ func (store *EnvironmentVariableStore) List(ctx context.Context) ([]*models.Envi } func (store *EnvironmentVariableStore) Save(ctx context.Context, environmentVariable *models.EnvironmentVariable) error { - tx := store.getTransaction(ctx) + tx := store.GetTransaction(ctx) tx = tx.Save(environmentVariable) if tx.Error != nil { @@ -51,7 +51,7 @@ func (store *EnvironmentVariableStore) Save(ctx context.Context, environmentVari } func (store *EnvironmentVariableStore) Delete(ctx context.Context, key string) error { - tx := store.getTransaction(ctx) + tx := store.GetTransaction(ctx) tx = tx.Where("key = ?", key).Delete(&models.EnvironmentVariable{}) if tx.Error != nil { diff --git a/pkg/db/gitprovider_config_store.go b/pkg/db/gitprovider_config_store.go index 209aa16d25..c1b2c6a731 100644 --- a/pkg/db/gitprovider_config_store.go +++ b/pkg/db/gitprovider_config_store.go @@ -11,11 +11,11 @@ import ( ) type GitProviderConfigStore struct { - Store + IStore } -func NewGitProviderConfigStore(store Store) (stores.GitProviderConfigStore, error) { - err := store.db.AutoMigrate(&models.GitProviderConfig{}) +func NewGitProviderConfigStore(store IStore) (stores.GitProviderConfigStore, error) { + err := store.AutoMigrate(&models.GitProviderConfig{}) if err != nil { return nil, err } @@ -24,7 +24,7 @@ func NewGitProviderConfigStore(store Store) (stores.GitProviderConfigStore, erro } func (p *GitProviderConfigStore) List(ctx context.Context) ([]*models.GitProviderConfig, error) { - tx := p.getTransaction(ctx) + tx := p.GetTransaction(ctx) gitProviders := []*models.GitProviderConfig{} tx = tx.Find(&gitProviders) @@ -36,7 +36,7 @@ func (p *GitProviderConfigStore) List(ctx context.Context) ([]*models.GitProvide } func (p *GitProviderConfigStore) Find(ctx context.Context, id string) (*models.GitProviderConfig, error) { - tx := p.getTransaction(ctx) + tx := p.GetTransaction(ctx) gitProvider := &models.GitProviderConfig{} tx = tx.Where("id = ?", id).First(gitProvider) @@ -51,7 +51,7 @@ func (p *GitProviderConfigStore) Find(ctx context.Context, id string) (*models.G } func (p *GitProviderConfigStore) Save(ctx context.Context, gitProvider *models.GitProviderConfig) error { - tx := p.getTransaction(ctx) + tx := p.GetTransaction(ctx) tx = tx.Save(gitProvider) if tx.Error != nil { @@ -62,7 +62,7 @@ func (p *GitProviderConfigStore) Save(ctx context.Context, gitProvider *models.G } func (p *GitProviderConfigStore) Delete(ctx context.Context, gitProvider *models.GitProviderConfig) error { - tx := p.getTransaction(ctx) + tx := p.GetTransaction(ctx) tx = tx.Delete(gitProvider) if tx.Error != nil { diff --git a/pkg/db/job_store.go b/pkg/db/job_store.go index e285aee5a8..7a814ebfdf 100644 --- a/pkg/db/job_store.go +++ b/pkg/db/job_store.go @@ -14,11 +14,11 @@ import ( ) type JobStore struct { - Store + IStore } -func NewJobStore(store Store) (stores.JobStore, error) { - err := store.db.AutoMigrate(&models.Job{}) +func NewJobStore(store IStore) (stores.JobStore, error) { + err := store.AutoMigrate(&models.Job{}) if err != nil { return nil, err } @@ -27,7 +27,7 @@ func NewJobStore(store Store) (stores.JobStore, error) { } func (s *JobStore) List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) jobs := []*models.Job{} tx = processJobFilters(tx, filter).Find(&jobs) @@ -40,7 +40,7 @@ func (s *JobStore) List(ctx context.Context, filter *stores.JobFilter) ([]*model } func (s *JobStore) Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) job := &models.Job{} tx = processJobFilters(tx, filter).First(&job) @@ -56,7 +56,7 @@ func (s *JobStore) Find(ctx context.Context, filter *stores.JobFilter) (*models. } func (s *JobStore) Save(ctx context.Context, job *models.Job) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(job) if tx.Error != nil { @@ -67,7 +67,7 @@ func (s *JobStore) Save(ctx context.Context, job *models.Job) error { } func (s *JobStore) Delete(ctx context.Context, job *models.Job) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Delete(job) if tx.Error != nil { diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index 3e13744ad9..e79e532555 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -13,11 +13,11 @@ import ( ) type TargetConfigStore struct { - Store + IStore } -func NewTargetConfigStore(store Store) (stores.TargetConfigStore, error) { - err := store.db.AutoMigrate(&models.TargetConfig{}) +func NewTargetConfigStore(store IStore) (stores.TargetConfigStore, error) { + err := store.AutoMigrate(&models.TargetConfig{}) if err != nil { return nil, err } @@ -26,7 +26,7 @@ func NewTargetConfigStore(store Store) (stores.TargetConfigStore, error) { } func (s *TargetConfigStore) List(ctx context.Context, allowDeleted bool) ([]*models.TargetConfig, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) targetConfigs := []*models.TargetConfig{} tx = processTargetConfigFilters(tx, "", allowDeleted).Find(&targetConfigs) @@ -39,7 +39,7 @@ func (s *TargetConfigStore) List(ctx context.Context, allowDeleted bool) ([]*mod } func (s *TargetConfigStore) Find(ctx context.Context, idOrName string, allowDeleted bool) (*models.TargetConfig, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) targetConfig := &models.TargetConfig{} tx = processTargetConfigFilters(tx, idOrName, allowDeleted).First(targetConfig) @@ -55,7 +55,7 @@ func (s *TargetConfigStore) Find(ctx context.Context, idOrName string, allowDele } func (s *TargetConfigStore) Save(ctx context.Context, targetConfig *models.TargetConfig) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(targetConfig) if tx.Error != nil { diff --git a/pkg/db/target_metadata_store.go b/pkg/db/target_metadata_store.go index d0872815b4..05c5e25fd8 100644 --- a/pkg/db/target_metadata_store.go +++ b/pkg/db/target_metadata_store.go @@ -13,11 +13,11 @@ import ( ) type TargetMetadataStore struct { - Store + IStore } -func NewTargetMetadataStore(store Store) (stores.TargetMetadataStore, error) { - err := store.db.AutoMigrate(&models.TargetMetadata{}) +func NewTargetMetadataStore(store IStore) (stores.TargetMetadataStore, error) { + err := store.AutoMigrate(&models.TargetMetadata{}) if err != nil { return nil, err } @@ -26,7 +26,7 @@ func NewTargetMetadataStore(store Store) (stores.TargetMetadataStore, error) { } func (s *TargetMetadataStore) Find(ctx context.Context, filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) targetMetadata := &models.TargetMetadata{} tx = processTargetMetadataFilters(tx, filter).First(&targetMetadata) @@ -41,7 +41,7 @@ func (s *TargetMetadataStore) Find(ctx context.Context, filter *stores.TargetMet } func (s *TargetMetadataStore) Save(ctx context.Context, targetMetadata *models.TargetMetadata) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(targetMetadata) if tx.Error != nil { @@ -52,7 +52,7 @@ func (s *TargetMetadataStore) Save(ctx context.Context, targetMetadata *models.T } func (s *TargetMetadataStore) Delete(ctx context.Context, targetMetadata *models.TargetMetadata) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Delete(targetMetadata) if tx.Error != nil { diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index baeca12483..05bb98541a 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -14,11 +14,11 @@ import ( ) type TargetStore struct { - Store + IStore } -func NewTargetStore(store Store) (stores.TargetStore, error) { - err := store.db.AutoMigrate(&models.Target{}) +func NewTargetStore(store IStore) (stores.TargetStore, error) { + err := store.AutoMigrate(&models.Target{}) if err != nil { return nil, err } @@ -27,7 +27,7 @@ func NewTargetStore(store Store) (stores.TargetStore, error) { } func (s *TargetStore) List(ctx context.Context, filter *stores.TargetFilter) ([]*models.Target, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) targets := []*models.Target{} @@ -39,7 +39,7 @@ func (s *TargetStore) List(ctx context.Context, filter *stores.TargetFilter) ([] } func (s *TargetStore) Find(ctx context.Context, filter *stores.TargetFilter) (*models.Target, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tg := &models.Target{} @@ -58,7 +58,7 @@ func (s *TargetStore) Find(ctx context.Context, filter *stores.TargetFilter) (*m } func (s *TargetStore) Save(ctx context.Context, target *models.Target) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(target) if tx.Error != nil { @@ -69,7 +69,7 @@ func (s *TargetStore) Save(ctx context.Context, target *models.Target) error { } func (s *TargetStore) Delete(ctx context.Context, t *models.Target) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Delete(t) if tx.Error != nil { diff --git a/pkg/db/workspace_metadata_store.go b/pkg/db/workspace_metadata_store.go index 8c27556cd8..4db4a100bf 100644 --- a/pkg/db/workspace_metadata_store.go +++ b/pkg/db/workspace_metadata_store.go @@ -13,11 +13,11 @@ import ( ) type WorkspaceMetadataStore struct { - Store + IStore } -func NewWorkspaceMetadataStore(store Store) (stores.WorkspaceMetadataStore, error) { - err := store.db.AutoMigrate(&models.WorkspaceMetadata{}) +func NewWorkspaceMetadataStore(store IStore) (stores.WorkspaceMetadataStore, error) { + err := store.AutoMigrate(&models.WorkspaceMetadata{}) if err != nil { return nil, err } @@ -26,7 +26,7 @@ func NewWorkspaceMetadataStore(store Store) (stores.WorkspaceMetadataStore, erro } func (s *WorkspaceMetadataStore) Find(ctx context.Context, filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) workspaceMetadata := &models.WorkspaceMetadata{} tx = processWorkspaceMetadataFilters(tx, filter).First(&workspaceMetadata) @@ -41,7 +41,7 @@ func (s *WorkspaceMetadataStore) Find(ctx context.Context, filter *stores.Worksp } func (s *WorkspaceMetadataStore) Save(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(workspaceMetadata) if tx.Error != nil { @@ -52,7 +52,7 @@ func (s *WorkspaceMetadataStore) Save(ctx context.Context, workspaceMetadata *mo } func (s *WorkspaceMetadataStore) Delete(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Delete(workspaceMetadata) if tx.Error != nil { diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go index 1c715772ce..eb762d6135 100644 --- a/pkg/db/workspace_store.go +++ b/pkg/db/workspace_store.go @@ -14,11 +14,11 @@ import ( ) type WorkspaceStore struct { - Store + IStore } -func NewWorkspaceStore(store Store) (stores.WorkspaceStore, error) { - err := store.db.AutoMigrate(&models.Workspace{}) +func NewWorkspaceStore(store IStore) (stores.WorkspaceStore, error) { + err := store.AutoMigrate(&models.Workspace{}) if err != nil { return nil, err } @@ -27,7 +27,7 @@ func NewWorkspaceStore(store Store) (stores.WorkspaceStore, error) { } func (s *WorkspaceStore) List(ctx context.Context) ([]*models.Workspace, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) workspaces := []*models.Workspace{} tx = preloadWorkspaceEntities(tx).Find(&workspaces) @@ -39,7 +39,7 @@ func (s *WorkspaceStore) List(ctx context.Context) ([]*models.Workspace, error) } func (s *WorkspaceStore) Find(ctx context.Context, idOrName string) (*models.Workspace, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) workspace := &models.Workspace{} tx = preloadWorkspaceEntities(tx).Where("id = ? OR name = ?", idOrName, idOrName).First(workspace) @@ -54,7 +54,7 @@ func (s *WorkspaceStore) Find(ctx context.Context, idOrName string) (*models.Wor } func (s *WorkspaceStore) Save(ctx context.Context, workspace *models.Workspace) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(workspace) if tx.Error != nil { @@ -65,7 +65,7 @@ func (s *WorkspaceStore) Save(ctx context.Context, workspace *models.Workspace) } func (s *WorkspaceStore) Delete(ctx context.Context, workspace *models.Workspace) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Delete(workspace) if tx.Error != nil { diff --git a/pkg/db/workspace_template_store.go b/pkg/db/workspace_template_store.go index 183b2f626e..04acc5e1c3 100644 --- a/pkg/db/workspace_template_store.go +++ b/pkg/db/workspace_template_store.go @@ -13,11 +13,11 @@ import ( ) type WorkspaceTemplateStore struct { - Store + IStore } -func NewWorkspaceTemplateStore(store Store) (stores.WorkspaceTemplateStore, error) { - err := store.db.AutoMigrate(&models.WorkspaceTemplate{}) +func NewWorkspaceTemplateStore(store IStore) (stores.WorkspaceTemplateStore, error) { + err := store.AutoMigrate(&models.WorkspaceTemplate{}) if err != nil { return nil, err } @@ -26,7 +26,7 @@ func NewWorkspaceTemplateStore(store Store) (stores.WorkspaceTemplateStore, erro } func (s *WorkspaceTemplateStore) List(ctx context.Context, filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) workspaceTemplates := []*models.WorkspaceTemplate{} tx = processWorkspaceTemplateFilters(tx, filter).Find(&workspaceTemplates) @@ -39,7 +39,7 @@ func (s *WorkspaceTemplateStore) List(ctx context.Context, filter *stores.Worksp } func (s *WorkspaceTemplateStore) Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) workspaceTemplate := &models.WorkspaceTemplate{} tx = processWorkspaceTemplateFilters(tx, filter).First(workspaceTemplate) @@ -55,7 +55,7 @@ func (s *WorkspaceTemplateStore) Find(ctx context.Context, filter *stores.Worksp } func (s *WorkspaceTemplateStore) Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Save(workspaceTemplate) if tx.Error != nil { @@ -66,7 +66,7 @@ func (s *WorkspaceTemplateStore) Save(ctx context.Context, workspaceTemplate *mo } func (s *WorkspaceTemplateStore) Delete(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { - tx := s.getTransaction(ctx) + tx := s.GetTransaction(ctx) tx = tx.Delete(workspaceTemplate) if tx.Error != nil { From 0650dd54f33c375cc81b7185220d8e08a09655bf Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 6 Dec 2024 14:42:37 +0000 Subject: [PATCH 28/76] fix: target set default commit tx Signed-off-by: Toma Puljak --- pkg/server/targets/set-default.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index 26ef807dfb..e47b4421ac 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -43,5 +43,10 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { } currentTarget.IsDefault = true - return s.targetStore.Save(ctx, ¤tTarget.Target) + err = s.targetStore.Save(ctx, ¤tTarget.Target) + if err != nil { + return s.targetStore.RollbackTransaction(ctx, err) + } + + return s.targetStore.CommitTransaction(ctx) } From e9e459acadcc7ea18dfcb97ff6d766714e38f335 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Fri, 6 Dec 2024 17:02:16 +0100 Subject: [PATCH 29/76] fix: properly handle no target mode agent in providers (#1421) Signed-off-by: Ivan Dagelic --- pkg/api/docs/docs.go | 3 ++ pkg/api/docs/swagger.json | 3 ++ pkg/api/docs/swagger.yaml | 2 + pkg/apiclient/api/openapi.yaml | 11 ++++++ pkg/apiclient/docs/TargetProviderInfo.md | 26 +++++++++++++ pkg/apiclient/model_target_provider_info.go | 42 +++++++++++++++++++-- pkg/cmd/common/await_state.go | 2 + pkg/cmd/target/create.go | 4 ++ pkg/cmd/target/restart.go | 21 ++++++----- pkg/cmd/target/ssh.go | 2 +- pkg/cmd/target/start.go | 39 +++++++++++++------ pkg/cmd/target/stop.go | 20 ++++++---- pkg/cmd/workspace/stop.go | 1 + pkg/jobs/target/create.go | 5 +++ pkg/models/target.go | 16 ++++---- pkg/provider/manager/manager.go | 7 ++-- pkg/provider/types.go | 7 ++-- pkg/server/targets/start.go | 11 ++++-- pkg/server/targets/stop.go | 5 +++ pkg/services/target.go | 1 + 20 files changed, 178 insertions(+), 50 deletions(-) diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index e480188405..6132095926 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -5078,6 +5078,9 @@ const docTemplate = `{ "version" ], "properties": { + "agentlessTarget": { + "type": "boolean" + }, "label": { "type": "string" }, diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 421b773f58..618ae19ca4 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -5075,6 +5075,9 @@ "version" ], "properties": { + "agentlessTarget": { + "type": "boolean" + }, "label": { "type": "string" }, diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 047df1b0c6..f1ca8cdfda 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -1232,6 +1232,8 @@ definitions: type: object TargetProviderInfo: properties: + agentlessTarget: + type: boolean label: type: string name: diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index b53fd5a159..06fca875a6 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -2391,6 +2391,7 @@ components: name: name options: options providerInfo: + agentlessTarget: true name: name label: label version: version @@ -3971,6 +3972,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version @@ -4030,6 +4032,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version @@ -4101,6 +4104,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version @@ -4187,6 +4191,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version @@ -4271,6 +4276,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version @@ -4362,10 +4368,13 @@ components: type: object TargetProviderInfo: example: + agentlessTarget: true name: name label: label version: version properties: + agentlessTarget: + type: boolean label: type: string name: @@ -4442,6 +4451,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version @@ -4547,6 +4557,7 @@ components: options: options id: id providerInfo: + agentlessTarget: true name: name label: label version: version diff --git a/pkg/apiclient/docs/TargetProviderInfo.md b/pkg/apiclient/docs/TargetProviderInfo.md index 22bcc30ffa..6e1f86f4ea 100644 --- a/pkg/apiclient/docs/TargetProviderInfo.md +++ b/pkg/apiclient/docs/TargetProviderInfo.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**AgentlessTarget** | Pointer to **bool** | | [optional] **Label** | Pointer to **string** | | [optional] **Name** | **string** | | **Version** | **string** | | @@ -27,6 +28,31 @@ NewTargetProviderInfoWithDefaults instantiates a new TargetProviderInfo object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set +### GetAgentlessTarget + +`func (o *TargetProviderInfo) GetAgentlessTarget() bool` + +GetAgentlessTarget returns the AgentlessTarget field if non-nil, zero value otherwise. + +### GetAgentlessTargetOk + +`func (o *TargetProviderInfo) GetAgentlessTargetOk() (*bool, bool)` + +GetAgentlessTargetOk returns a tuple with the AgentlessTarget field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAgentlessTarget + +`func (o *TargetProviderInfo) SetAgentlessTarget(v bool)` + +SetAgentlessTarget sets AgentlessTarget field to given value. + +### HasAgentlessTarget + +`func (o *TargetProviderInfo) HasAgentlessTarget() bool` + +HasAgentlessTarget returns a boolean if a field has been set. + ### GetLabel `func (o *TargetProviderInfo) GetLabel() string` diff --git a/pkg/apiclient/model_target_provider_info.go b/pkg/apiclient/model_target_provider_info.go index 8209f2b62a..68c3f685fe 100644 --- a/pkg/apiclient/model_target_provider_info.go +++ b/pkg/apiclient/model_target_provider_info.go @@ -21,9 +21,10 @@ var _ MappedNullable = &TargetProviderInfo{} // TargetProviderInfo struct for TargetProviderInfo type TargetProviderInfo struct { - Label *string `json:"label,omitempty"` - Name string `json:"name"` - Version string `json:"version"` + AgentlessTarget *bool `json:"agentlessTarget,omitempty"` + Label *string `json:"label,omitempty"` + Name string `json:"name"` + Version string `json:"version"` } type _TargetProviderInfo TargetProviderInfo @@ -47,6 +48,38 @@ func NewTargetProviderInfoWithDefaults() *TargetProviderInfo { return &this } +// GetAgentlessTarget returns the AgentlessTarget field value if set, zero value otherwise. +func (o *TargetProviderInfo) GetAgentlessTarget() bool { + if o == nil || IsNil(o.AgentlessTarget) { + var ret bool + return ret + } + return *o.AgentlessTarget +} + +// GetAgentlessTargetOk returns a tuple with the AgentlessTarget field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TargetProviderInfo) GetAgentlessTargetOk() (*bool, bool) { + if o == nil || IsNil(o.AgentlessTarget) { + return nil, false + } + return o.AgentlessTarget, true +} + +// HasAgentlessTarget returns a boolean if a field has been set. +func (o *TargetProviderInfo) HasAgentlessTarget() bool { + if o != nil && !IsNil(o.AgentlessTarget) { + return true + } + + return false +} + +// SetAgentlessTarget gets a reference to the given bool and assigns it to the AgentlessTarget field. +func (o *TargetProviderInfo) SetAgentlessTarget(v bool) { + o.AgentlessTarget = &v +} + // GetLabel returns the Label field value if set, zero value otherwise. func (o *TargetProviderInfo) GetLabel() string { if o == nil || IsNil(o.Label) { @@ -137,6 +170,9 @@ func (o TargetProviderInfo) MarshalJSON() ([]byte, error) { func (o TargetProviderInfo) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} + if !IsNil(o.AgentlessTarget) { + toSerialize["agentlessTarget"] = o.AgentlessTarget + } if !IsNil(o.Label) { toSerialize["label"] = o.Label } diff --git a/pkg/cmd/common/await_state.go b/pkg/cmd/common/await_state.go index 4432dae4b7..ca504501c5 100644 --- a/pkg/cmd/common/await_state.go +++ b/pkg/cmd/common/await_state.go @@ -38,9 +38,11 @@ func AwaitTargetState(targetId string, stateName apiclient.ModelsResourceStateNa if err != nil { return err } + if t.State.Name == stateName || t.State.Name == apiclient.ResourceStateNameUndefined { return nil } + if t.State.Name == apiclient.ResourceStateNameError { var errorMessage string if t.State.Error != nil { diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index f123ab0b6d..3ba6abe656 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -6,6 +6,7 @@ package target import ( "context" "fmt" + "time" "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" @@ -86,6 +87,9 @@ var targetCreateCmd = &cobra.Command{ return err } + // Ensure reading remaining logs is complete + time.Sleep(100 * time.Millisecond) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' set successfully and will be used by default", createTargetDto.Name)) return nil }, diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index 748f1736e1..7502272586 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -21,8 +21,7 @@ var restartCmd = &cobra.Command{ Short: "Restart a target", Args: cobra.RangeArgs(0, 1), RunE: func(cmd *cobra.Command, args []string) error { - var targetId string - + var target *apiclient.TargetDTO ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -41,20 +40,22 @@ var restartCmd = &cobra.Command{ return nil } - target := selection.GetTargetFromPrompt(targetList, false, "Restart") + target = selection.GetTargetFromPrompt(targetList, false, "Restart") if target == nil { return nil } - targetId = target.Name } else { - targetId = args[0] + target, _, err = apiclient_util.GetTarget(args[0], false) + if err != nil { + return err + } } - err = RestartTarget(apiClient, targetId) + err = RestartTarget(apiClient, *target) if err != nil { return err } - views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) + views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", target.Name)) return nil }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ -62,10 +63,10 @@ var restartCmd = &cobra.Command{ }, } -func RestartTarget(apiClient *apiclient.APIClient, targetId string) error { - err := StopTarget(apiClient, targetId) +func RestartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) error { + err := StopTarget(apiClient, target) if err != nil { return err } - return StartTarget(apiClient, targetId) + return StartTarget(apiClient, target) } diff --git a/pkg/cmd/target/ssh.go b/pkg/cmd/target/ssh.go index 88ee54f1ad..81d3433b94 100644 --- a/pkg/cmd/target/ssh.go +++ b/pkg/cmd/target/ssh.go @@ -103,7 +103,7 @@ func autoStartTarget(target apiclient.TargetDTO) (bool, error) { return false, err } - err = StartTarget(apiClient, target.Id) + err = StartTarget(apiClient, target) if err != nil { return false, err } diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 1099b40fcb..9821a188da 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -62,20 +62,30 @@ var startCmd = &cobra.Command{ if len(selectedTargetsNames) == 1 { targetName := selectedTargetsNames[0] - err = StartTarget(apiClient, targetName) + target, _, err := apiclient_util.GetTarget(targetName, false) + if err != nil { + return err + } + + err = StartTarget(apiClient, *target) if err != nil { return err } views.RenderInfoMessage(fmt.Sprintf("Target '%s' started successfully", targetName)) } else { - for _, target := range selectedTargetsNames { - err := StartTarget(apiClient, target) + for _, targetName := range selectedTargetsNames { + target, _, err := apiclient_util.GetTarget(targetName, false) + if err != nil { + return err + } + + err = StartTarget(apiClient, *target) if err != nil { - log.Errorf("Failed to start target %s: %v\n\n", target, err) + log.Errorf("Failed to start target %s: %v\n\n", targetName, err) continue } - views.RenderInfoMessage(fmt.Sprintf("- Target '%s' started successfully", target)) + views.RenderInfoMessage(fmt.Sprintf("- Target '%s' started successfully", targetName)) } } return nil @@ -103,7 +113,7 @@ func startAllTargets() error { } for _, target := range targetList { - err := StartTarget(apiClient, target.Name) + err := StartTarget(apiClient, target) if err != nil { log.Errorf("Failed to start target %s: %v\n\n", target.Name, err) continue @@ -146,7 +156,7 @@ func getAllTargetsByState(state *apiclient.ModelsResourceStateName) ([]string, c return choices, cobra.ShellCompDirectiveNoFileComp } -func StartTarget(apiClient *apiclient.APIClient, targetId string) error { +func StartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) error { ctx := context.Background() timeFormat := time.Now().Format("2006-01-02 15:04:05") from, err := time.Parse("2006-01-02 15:04:05", timeFormat) @@ -164,9 +174,8 @@ func StartTarget(apiClient *apiclient.APIClient, targetId string) error { return err } - target, _, err := apiclient_util.GetTarget(targetId, false) - if err != nil { - return err + if target.TargetConfig.ProviderInfo.AgentlessTarget != nil && *target.TargetConfig.ProviderInfo.AgentlessTarget { + return agentlessTargetError(target.TargetConfig.ProviderInfo.Name) } logsContext, stopLogs := context.WithCancel(context.Background()) @@ -178,15 +187,21 @@ func StartTarget(apiClient *apiclient.APIClient, targetId string) error { From: &from, }) - res, err := apiClient.TargetAPI.StartTarget(ctx, targetId).Execute() + res, err := apiClient.TargetAPI.StartTarget(ctx, target.Id).Execute() if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) } - err = cmd_common.AwaitTargetState(targetId, apiclient.ResourceStateNameStarted) + err = cmd_common.AwaitTargetState(target.Id, apiclient.ResourceStateNameStarted) + // Ensure reading remaining logs is completed time.Sleep(100 * time.Millisecond) + stopLogs() return err } + +func agentlessTargetError(providerName string) error { + return fmt.Errorf("%s does not require target state management; you may continue without starting or stopping it", providerName) +} diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go index d359f1864b..c24a7ffb44 100644 --- a/pkg/cmd/target/stop.go +++ b/pkg/cmd/target/stop.go @@ -67,7 +67,7 @@ var stopCmd = &cobra.Command{ selectedTargets := selection.GetTargetsFromPrompt(targetList, "Stop") for _, target := range selectedTargets { - err := StopTarget(apiClient, target.Name) + err := StopTarget(apiClient, *target) if err != nil { log.Errorf("Failed to stop target %s: %v\n\n", target.Name, err) continue @@ -89,12 +89,12 @@ var stopCmd = &cobra.Command{ } else { targetId := args[0] - err = StopTarget(apiClient, targetId) + target, _, err := apiclient_util.GetTarget(targetId, false) if err != nil { return err } - target, _, err := apiclient_util.GetTarget(targetId, false) + err = StopTarget(apiClient, *target) if err != nil { return err } @@ -132,7 +132,7 @@ func stopAllTargets(activeProfile config.Profile, from time.Time) error { } for _, target := range targetList { - err := StopTarget(apiClient, target.Name) + err := StopTarget(apiClient, target) if err != nil { log.Errorf("Failed to stop target %s: %v\n\n", target.Name, err) continue @@ -154,16 +154,20 @@ func stopAllTargets(activeProfile config.Profile, from time.Time) error { return nil } -func StopTarget(apiClient *apiclient.APIClient, targetId string) error { +func StopTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) error { ctx := context.Background() - err := views_util.WithInlineSpinner(fmt.Sprintf("Target '%s' is stopping", targetId), func() error { - res, err := apiClient.TargetAPI.StopTarget(ctx, targetId).Execute() + if target.TargetConfig.ProviderInfo.AgentlessTarget != nil && *target.TargetConfig.ProviderInfo.AgentlessTarget { + return agentlessTargetError(target.TargetConfig.ProviderInfo.Name) + } + + err := views_util.WithInlineSpinner(fmt.Sprintf("Target '%s' is stopping", target.Name), func() error { + res, err := apiClient.TargetAPI.StopTarget(ctx, target.Id).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - return cmd_common.AwaitTargetState(targetId, apiclient.ResourceStateNameStarted) + return cmd_common.AwaitTargetState(target.Id, apiclient.ResourceStateNameStarted) }) if err != nil { return err diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go index 97a41a456d..da868673d6 100644 --- a/pkg/cmd/workspace/stop.go +++ b/pkg/cmd/workspace/stop.go @@ -157,6 +157,7 @@ func StopWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspace return err } + // Ensure reading remaining logs is completed time.Sleep(100 * time.Millisecond) stopLogs() diff --git a/pkg/jobs/target/create.go b/pkg/jobs/target/create.go index 9265ae27fe..541412e604 100644 --- a/pkg/jobs/target/create.go +++ b/pkg/jobs/target/create.go @@ -34,5 +34,10 @@ func (tj *TargetJob) create(ctx context.Context, j *models.Job) error { } targetLogger.Write([]byte(views.GetPrettyLogLine("Target creation complete"))) + + if tg.TargetConfig.ProviderInfo.AgentlessTarget { + return nil + } + return tj.start(ctx, j) } diff --git a/pkg/models/target.go b/pkg/models/target.go index b7d56ee84c..c45e679756 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -4,7 +4,6 @@ package models import ( - "slices" "time" "github.com/daytonaio/daytona/internal/util" @@ -12,8 +11,6 @@ import ( const AGENT_UNRESPONSIVE_THRESHOLD = 30 * time.Second -var providersWithoutTargetMode = []string{"docker-provider"} - type Target struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` Name string `json:"name" validate:"required" gorm:"not null"` @@ -37,7 +34,11 @@ func (t *Target) GetState() ResourceState { state := getResourceStateFromJob(t.LastJob) // Some providers do not utilize agents in target mode - if state.Name != ResourceStateNameDeleted && slices.Contains(providersWithoutTargetMode, t.TargetConfig.ProviderInfo.Name) { + if t.TargetConfig.ProviderInfo.AgentlessTarget { + if state.Name == ResourceStateNameDeleted || state.Name == ResourceStateNamePendingCreate || state.Name == ResourceStateNameCreating { + return state + } + return ResourceState{ Name: ResourceStateNameUndefined, UpdatedAt: time.Now(), @@ -62,7 +63,8 @@ type TargetInfo struct { } // @name TargetInfo type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Version string `json:"version" validate:"required"` - Label *string `json:"label" validate:"optional"` + Name string `json:"name" validate:"required"` + Version string `json:"version" validate:"required"` + AgentlessTarget bool `json:"agentlessTarget" validate:"optional"` + Label *string `json:"label" validate:"optional"` } // @name TargetProviderInfo diff --git a/pkg/provider/manager/manager.go b/pkg/provider/manager/manager.go index a16143de4f..cfeeb69f7b 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/provider/manager/manager.go @@ -191,9 +191,10 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool err = m.createTargetConfig(ctx, targetConfig.Name, targetConfig.Options, models.ProviderInfo{ - Name: providerInfo.Name, - Version: providerInfo.Version, - Label: providerInfo.Label, + Name: providerInfo.Name, + Version: providerInfo.Version, + Label: providerInfo.Label, + AgentlessTarget: providerInfo.AgentlessTarget, }) if err != nil { log.Errorf("Failed to set target config %s: %s", targetConfig.Name, err) diff --git a/pkg/provider/types.go b/pkg/provider/types.go index f559745495..85452ccf2f 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -35,9 +35,10 @@ type WorkspaceRequest struct { } type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Label *string `json:"label" validate:"optional"` - Version string `json:"version" validate:"required"` + Name string `json:"name" validate:"required"` + Label *string `json:"label" validate:"optional"` + AgentlessTarget bool `json:"agentlessTarget" validate:"optional"` + Version string `json:"version" validate:"required"` } type TargetConfig struct { diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index c445514b6b..4d14f24bb0 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -7,19 +7,24 @@ import ( "context" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { - t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) + target, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStartError(ctx, nil, stores.ErrTargetNotFound) } - err = s.createJob(ctx, t.Id, models.JobActionStart) - return s.handleStartError(ctx, t, err) + if target.TargetConfig.ProviderInfo.AgentlessTarget { + return s.handleStartError(ctx, target, services.ErrAgentlessTarget) + } + + err = s.createJob(ctx, target.Id, models.JobActionStart) + return s.handleStartError(ctx, target, err) } func (s *TargetService) handleStartError(ctx context.Context, target *models.Target, err error) error { diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index 1560d0082e..b0f045cd9f 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -7,6 +7,7 @@ import ( "context" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" @@ -18,6 +19,10 @@ func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { return s.handleStopError(ctx, nil, stores.ErrTargetNotFound) } + if target.TargetConfig.ProviderInfo.AgentlessTarget { + return s.handleStartError(ctx, target, services.ErrAgentlessTarget) + } + err = s.createJob(ctx, target.Id, models.JobActionStop) return s.handleStopError(ctx, target, err) } diff --git a/pkg/services/target.go b/pkg/services/target.go index 96014cbaa8..27130706d0 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -49,6 +49,7 @@ var ( ErrTargetAlreadyExists = errors.New("target already exists") ErrInvalidTargetName = errors.New("name is not a valid alphanumeric string") ErrTargetDeleted = errors.New("target is deleted") + ErrAgentlessTarget = errors.New("provider uses an agentless target") ) func IsTargetDeleted(err error) bool { From 871e8deaa1b53c346b0a3abb18fd341b79123db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Fri, 13 Dec 2024 12:44:27 +0100 Subject: [PATCH 30/76] fix: set builder registry server to default frpc domain (#1449) Signed-off-by: Luka Brecic --- pkg/cmd/build/run.go | 1 + pkg/cmd/server/bootstrap/get_job_runner.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index 7eedfcb040..eed1ab4a4f 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -81,6 +81,7 @@ func CreateBuild(apiClient *apiclient.APIClient, workspaceTemplate *apiclient.Wo WorkspaceTemplateName: workspaceTemplate.Name, Branch: branch, PrebuildId: prebuildId, + EnvVars: workspaceTemplate.EnvVars, } buildId, res, err := apiClient.BuildAPI.CreateBuild(ctx).CreateBuildDto(createBuildDto).Execute() diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go index d3ce35cb3c..a79b8c5978 100644 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -204,6 +204,12 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele builderRegistry = envVars.FindContainerRegistry(c.BuilderRegistryServer) } + if builderRegistry == nil { + builderRegistry = &models.ContainerRegistry{ + Server: util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain), + } + } + cr := envVars.FindContainerRegistryByImageName(c.BuilderImage) return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ From 8a6a04d9c1e548bed2cc732e7b8dd1f985aba164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Fri, 13 Dec 2024 13:59:01 +0100 Subject: [PATCH 31/76] feat: implement docker creds helper (#1427) Signed-off-by: Luka Brecic --- pkg/agent/agent.go | 5 + pkg/agent/types.go | 2 + pkg/api/controllers/containerregistry/get.go | 67 ++++++ pkg/api/docs/docs.go | 55 +++++ pkg/api/docs/swagger.json | 55 +++++ pkg/api/docs/swagger.yaml | 37 ++++ pkg/api/server.go | 6 + pkg/apiclient/README.md | 2 + pkg/apiclient/api/openapi.yaml | 43 ++++ pkg/apiclient/api_container_registry.go | 151 +++++++++++++ pkg/apiclient/client.go | 3 + pkg/apiclient/docs/ContainerRegistry.md | 93 ++++++++ pkg/apiclient/docs/ContainerRegistryAPI.md | 81 +++++++ pkg/apiclient/model_container_registry.go | 212 +++++++++++++++++++ pkg/build/builder.go | 3 +- pkg/build/devcontainer.go | 14 +- pkg/build/factory.go | 9 +- pkg/cmd/agent/agent.go | 10 + pkg/cmd/agentmode/agent_mode.go | 1 + pkg/cmd/agentmode/docker_cred.go | 57 +++++ pkg/cmd/server/bootstrap/get_job_runner.go | 14 +- pkg/common/env.go | 54 +++++ pkg/docker/client.go | 16 +- pkg/docker/create.go | 20 +- pkg/docker/create_devcontainer.go | 26 +-- pkg/docker/create_image.go | 3 +- pkg/docker/create_test.go | 14 +- pkg/docker/credential_helper.go | 97 +++++++++ pkg/docker/start_devcontainer.go | 3 +- pkg/jobs/util/env.go | 18 -- pkg/jobs/workspace/create.go | 20 +- pkg/jobs/workspace/factory.go | 2 - pkg/jobs/workspace/start.go | 20 +- pkg/models/container_registry.go | 18 -- pkg/provider/types.go | 10 +- pkg/provisioner/create.go | 9 +- pkg/provisioner/provisioner.go | 12 +- pkg/provisioner/start.go | 9 +- pkg/server/workspaces/service_test.go | 33 +-- 39 files changed, 1151 insertions(+), 153 deletions(-) create mode 100644 pkg/api/controllers/containerregistry/get.go create mode 100644 pkg/apiclient/api_container_registry.go create mode 100644 pkg/apiclient/docs/ContainerRegistry.md create mode 100644 pkg/apiclient/docs/ContainerRegistryAPI.md create mode 100644 pkg/apiclient/model_container_registry.go create mode 100644 pkg/cmd/agentmode/docker_cred.go create mode 100644 pkg/common/env.go create mode 100644 pkg/docker/credential_helper.go delete mode 100644 pkg/jobs/util/env.go diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index d1fd3399a9..1a3db00328 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -160,6 +160,11 @@ func (a *Agent) startWorkspaceMode() error { } } + err := a.DockerCredHelper.SetDockerConfig() + if err != nil { + log.Error(fmt.Sprintf("failed to set docker config: %s", err)) + } + go func() { for { err := a.updateWorkspaceMetadata() diff --git a/pkg/agent/types.go b/pkg/agent/types.go index 1756e47f3a..eb0a613322 100644 --- a/pkg/agent/types.go +++ b/pkg/agent/types.go @@ -8,6 +8,7 @@ import ( "time" "github.com/daytonaio/daytona/pkg/agent/config" + "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/git" "github.com/daytonaio/daytona/pkg/models" ) @@ -27,6 +28,7 @@ type ToolboxServer interface { type Agent struct { Config *config.Config Git git.IGitService + DockerCredHelper docker.IDockerCredHelper Ssh SshServer Toolbox ToolboxServer Tailscale TailscaleServer diff --git a/pkg/api/controllers/containerregistry/get.go b/pkg/api/controllers/containerregistry/get.go new file mode 100644 index 0000000000..9e9691595a --- /dev/null +++ b/pkg/api/controllers/containerregistry/get.go @@ -0,0 +1,67 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package containerregistry + +import ( + "fmt" + "net/http" + + internal_util "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" +) + +// GetContainerRegistry godoc +// +// @Tags container registry +// @Summary Get container registry +// @Description Get container registry +// @Produce json +// @Param server path string true "Container registry server" +// @Param workspaceId query string false "Workspace ID or Name" +// @Success 200 {object} ContainerRegistry +// @Router /container-registry/{server} [get] +// +// @id GetContainerRegistry +func GetContainerRegistry(ctx *gin.Context) { + serverName := ctx.Param("server") + workspaceId := ctx.Query("workspaceId") + + var envVars map[string]string + var err error + + server := server.GetInstance(nil) + + serverEnvVars, err := server.EnvironmentVariableService.Map(ctx.Request.Context()) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to fetch environment variables: %w", err)) + return + } + + envVars = serverEnvVars + + if workspaceId != "" { + w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + if err != nil { + statusCode := http.StatusInternalServerError + if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { + statusCode = http.StatusNotFound + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to find workspace: %w", err)) + return + } + + envVars = internal_util.MergeEnvVars(serverEnvVars, w.EnvVars) + } + + cr := services.EnvironmentVariables(envVars).FindContainerRegistry(serverName) + if cr == nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to find container registry for server: %s", serverName)) + return + } + + ctx.JSON(200, cr) +} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 6132095926..570a046ac0 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -254,6 +254,42 @@ const docTemplate = `{ } } }, + "/container-registry/{server}": { + "get": { + "description": "Get container registry", + "produces": [ + "application/json" + ], + "tags": [ + "container registry" + ], + "summary": "Get container registry", + "operationId": "GetContainerRegistry", + "parameters": [ + { + "type": "string", + "description": "Container registry server", + "name": "server", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/ContainerRegistry" + } + } + } + } + }, "/env": { "get": { "description": "List environment variables", @@ -3509,6 +3545,25 @@ const docTemplate = `{ } } }, + "ContainerRegistry": { + "type": "object", + "required": [ + "password", + "server", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "server": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "CreateBuildDTO": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 618ae19ca4..705f812d43 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -251,6 +251,42 @@ } } }, + "/container-registry/{server}": { + "get": { + "description": "Get container registry", + "produces": [ + "application/json" + ], + "tags": [ + "container registry" + ], + "summary": "Get container registry", + "operationId": "GetContainerRegistry", + "parameters": [ + { + "type": "string", + "description": "Container registry server", + "name": "server", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/ContainerRegistry" + } + } + } + } + }, "/env": { "get": { "description": "List environment variables", @@ -3506,6 +3542,25 @@ } } }, + "ContainerRegistry": { + "type": "object", + "required": [ + "password", + "server", + "username" + ], + "properties": { + "password": { + "type": "string" + }, + "server": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, "CreateBuildDTO": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index f1ca8cdfda..d503132cd8 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -151,6 +151,19 @@ definitions: - image - user type: object + ContainerRegistry: + properties: + password: + type: string + server: + type: string + username: + type: string + required: + - password + - server + - username + type: object CreateBuildDTO: properties: branch: @@ -1648,6 +1661,30 @@ paths: summary: Delete builds tags: - build + /container-registry/{server}: + get: + description: Get container registry + operationId: GetContainerRegistry + parameters: + - description: Container registry server + in: path + name: server + required: true + type: string + - description: Workspace ID or Name + in: query + name: workspaceId + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/ContainerRegistry' + summary: Get container registry + tags: + - container registry /env: get: description: List environment variables diff --git a/pkg/api/server.go b/pkg/api/server.go index 97f1b6e4dc..f86ac028ac 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -35,6 +35,7 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/apikey" "github.com/daytonaio/daytona/pkg/api/controllers/binary" "github.com/daytonaio/daytona/pkg/api/controllers/build" + "github.com/daytonaio/daytona/pkg/api/controllers/containerregistry" "github.com/daytonaio/daytona/pkg/api/controllers/env" "github.com/daytonaio/daytona/pkg/api/controllers/gitprovider" "github.com/daytonaio/daytona/pkg/api/controllers/health" @@ -321,6 +322,11 @@ func (a *ApiServer) Start() error { envVarController.DELETE("/:key", env.DeleteEnvironmentVariable) } + containerRegistryController := protected.Group("/container-registry") + { + containerRegistryController.GET("/:server", containerregistry.GetContainerRegistry) + } + samplesController := protected.Group("/sample") { samplesController.GET("", sample.ListSamples) diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 77604d1296..ffd834604c 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -86,6 +86,7 @@ Class | Method | HTTP request | Description *BuildAPI* | [**DeleteBuildsFromPrebuild**](docs/BuildAPI.md#deletebuildsfromprebuild) | **Delete** /build/prebuild/{prebuildId} | Delete builds *BuildAPI* | [**GetBuild**](docs/BuildAPI.md#getbuild) | **Get** /build/{buildId} | Get build data *BuildAPI* | [**ListBuilds**](docs/BuildAPI.md#listbuilds) | **Get** /build | List builds +*ContainerRegistryAPI* | [**GetContainerRegistry**](docs/ContainerRegistryAPI.md#getcontainerregistry) | **Get** /container-registry/{server} | Get container registry *DefaultAPI* | [**HealthCheck**](docs/DefaultAPI.md#healthcheck) | **Get** /health | Health check *EnvVarAPI* | [**DeleteEnvironmentVariable**](docs/EnvVarAPI.md#deleteenvironmentvariable) | **Delete** /env/{key} | Delete environment variable *EnvVarAPI* | [**ListEnvironmentVariables**](docs/EnvVarAPI.md#listenvironmentvariables) | **Get** /env | List environment variables @@ -192,6 +193,7 @@ Class | Method | HTTP request | Description - [CompletionItem](docs/CompletionItem.md) - [CompletionList](docs/CompletionList.md) - [ContainerConfig](docs/ContainerConfig.md) + - [ContainerRegistry](docs/ContainerRegistry.md) - [CreateBuildDTO](docs/CreateBuildDTO.md) - [CreatePrebuildDTO](docs/CreatePrebuildDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 06fca875a6..52dea2a6a6 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -182,6 +182,32 @@ paths: summary: Get build data tags: - build + /container-registry/{server}: + get: + description: Get container registry + operationId: GetContainerRegistry + parameters: + - description: Container registry server + in: path + name: server + required: true + schema: + type: string + - description: Workspace ID or Name + in: query + name: workspaceId + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/ContainerRegistry' + description: OK + summary: Get container registry + tags: + - container registry /env: get: description: List environment variables @@ -2636,6 +2662,23 @@ components: - image - user type: object + ContainerRegistry: + example: + server: server + password: password + username: username + properties: + password: + type: string + server: + type: string + username: + type: string + required: + - password + - server + - username + type: object CreateBuildDTO: example: prebuildId: prebuildId diff --git a/pkg/apiclient/api_container_registry.go b/pkg/apiclient/api_container_registry.go new file mode 100644 index 0000000000..877be4642c --- /dev/null +++ b/pkg/apiclient/api_container_registry.go @@ -0,0 +1,151 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// ContainerRegistryAPIService ContainerRegistryAPI service +type ContainerRegistryAPIService service + +type ApiGetContainerRegistryRequest struct { + ctx context.Context + ApiService *ContainerRegistryAPIService + server string + workspaceId *string +} + +// Workspace ID or Name +func (r ApiGetContainerRegistryRequest) WorkspaceId(workspaceId string) ApiGetContainerRegistryRequest { + r.workspaceId = &workspaceId + return r +} + +func (r ApiGetContainerRegistryRequest) Execute() (*ContainerRegistry, *http.Response, error) { + return r.ApiService.GetContainerRegistryExecute(r) +} + +/* +GetContainerRegistry Get container registry + +Get container registry + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param server Container registry server + @return ApiGetContainerRegistryRequest +*/ +func (a *ContainerRegistryAPIService) GetContainerRegistry(ctx context.Context, server string) ApiGetContainerRegistryRequest { + return ApiGetContainerRegistryRequest{ + ApiService: a, + ctx: ctx, + server: server, + } +} + +// Execute executes the request +// +// @return ContainerRegistry +func (a *ContainerRegistryAPIService) GetContainerRegistryExecute(r ApiGetContainerRegistryRequest) (*ContainerRegistry, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ContainerRegistry + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.GetContainerRegistry") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/container-registry/{server}" + localVarPath = strings.Replace(localVarPath, "{"+"server"+"}", url.PathEscape(parameterValueToString(r.server, "server")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.workspaceId != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "workspaceId", r.workspaceId, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index 58d913f356..fccca57914 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -52,6 +52,8 @@ type APIClient struct { BuildAPI *BuildAPIService + ContainerRegistryAPI *ContainerRegistryAPIService + DefaultAPI *DefaultAPIService EnvVarAPI *EnvVarAPIService @@ -97,6 +99,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { // API Services c.ApiKeyAPI = (*ApiKeyAPIService)(&c.common) c.BuildAPI = (*BuildAPIService)(&c.common) + c.ContainerRegistryAPI = (*ContainerRegistryAPIService)(&c.common) c.DefaultAPI = (*DefaultAPIService)(&c.common) c.EnvVarAPI = (*EnvVarAPIService)(&c.common) c.GitProviderAPI = (*GitProviderAPIService)(&c.common) diff --git a/pkg/apiclient/docs/ContainerRegistry.md b/pkg/apiclient/docs/ContainerRegistry.md new file mode 100644 index 0000000000..01a8520448 --- /dev/null +++ b/pkg/apiclient/docs/ContainerRegistry.md @@ -0,0 +1,93 @@ +# ContainerRegistry + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Password** | **string** | | +**Server** | **string** | | +**Username** | **string** | | + +## Methods + +### NewContainerRegistry + +`func NewContainerRegistry(password string, server string, username string, ) *ContainerRegistry` + +NewContainerRegistry instantiates a new ContainerRegistry object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewContainerRegistryWithDefaults + +`func NewContainerRegistryWithDefaults() *ContainerRegistry` + +NewContainerRegistryWithDefaults instantiates a new ContainerRegistry object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetPassword + +`func (o *ContainerRegistry) GetPassword() string` + +GetPassword returns the Password field if non-nil, zero value otherwise. + +### GetPasswordOk + +`func (o *ContainerRegistry) GetPasswordOk() (*string, bool)` + +GetPasswordOk returns a tuple with the Password field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetPassword + +`func (o *ContainerRegistry) SetPassword(v string)` + +SetPassword sets Password field to given value. + + +### GetServer + +`func (o *ContainerRegistry) GetServer() string` + +GetServer returns the Server field if non-nil, zero value otherwise. + +### GetServerOk + +`func (o *ContainerRegistry) GetServerOk() (*string, bool)` + +GetServerOk returns a tuple with the Server field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetServer + +`func (o *ContainerRegistry) SetServer(v string)` + +SetServer sets Server field to given value. + + +### GetUsername + +`func (o *ContainerRegistry) GetUsername() string` + +GetUsername returns the Username field if non-nil, zero value otherwise. + +### GetUsernameOk + +`func (o *ContainerRegistry) GetUsernameOk() (*string, bool)` + +GetUsernameOk returns a tuple with the Username field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUsername + +`func (o *ContainerRegistry) SetUsername(v string)` + +SetUsername sets Username field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ContainerRegistryAPI.md b/pkg/apiclient/docs/ContainerRegistryAPI.md new file mode 100644 index 0000000000..bc32b9c632 --- /dev/null +++ b/pkg/apiclient/docs/ContainerRegistryAPI.md @@ -0,0 +1,81 @@ +# \ContainerRegistryAPI + +All URIs are relative to *http://localhost:3986* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**GetContainerRegistry**](ContainerRegistryAPI.md#GetContainerRegistry) | **Get** /container-registry/{server} | Get container registry + + + +## GetContainerRegistry + +> ContainerRegistry GetContainerRegistry(ctx, server).WorkspaceId(workspaceId).Execute() + +Get container registry + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + server := "server_example" // string | Container registry server + workspaceId := "workspaceId_example" // string | Workspace ID or Name (optional) + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.ContainerRegistryAPI.GetContainerRegistry(context.Background(), server).WorkspaceId(workspaceId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.GetContainerRegistry``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetContainerRegistry`: ContainerRegistry + fmt.Fprintf(os.Stdout, "Response from `ContainerRegistryAPI.GetContainerRegistry`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**server** | **string** | Container registry server | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetContainerRegistryRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **workspaceId** | **string** | Workspace ID or Name | + +### Return type + +[**ContainerRegistry**](ContainerRegistry.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/model_container_registry.go b/pkg/apiclient/model_container_registry.go new file mode 100644 index 0000000000..dbe38007b7 --- /dev/null +++ b/pkg/apiclient/model_container_registry.go @@ -0,0 +1,212 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the ContainerRegistry type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ContainerRegistry{} + +// ContainerRegistry struct for ContainerRegistry +type ContainerRegistry struct { + Password string `json:"password"` + Server string `json:"server"` + Username string `json:"username"` +} + +type _ContainerRegistry ContainerRegistry + +// NewContainerRegistry instantiates a new ContainerRegistry object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewContainerRegistry(password string, server string, username string) *ContainerRegistry { + this := ContainerRegistry{} + this.Password = password + this.Server = server + this.Username = username + return &this +} + +// NewContainerRegistryWithDefaults instantiates a new ContainerRegistry object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewContainerRegistryWithDefaults() *ContainerRegistry { + this := ContainerRegistry{} + return &this +} + +// GetPassword returns the Password field value +func (o *ContainerRegistry) GetPassword() string { + if o == nil { + var ret string + return ret + } + + return o.Password +} + +// GetPasswordOk returns a tuple with the Password field value +// and a boolean to check if the value has been set. +func (o *ContainerRegistry) GetPasswordOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Password, true +} + +// SetPassword sets field value +func (o *ContainerRegistry) SetPassword(v string) { + o.Password = v +} + +// GetServer returns the Server field value +func (o *ContainerRegistry) GetServer() string { + if o == nil { + var ret string + return ret + } + + return o.Server +} + +// GetServerOk returns a tuple with the Server field value +// and a boolean to check if the value has been set. +func (o *ContainerRegistry) GetServerOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Server, true +} + +// SetServer sets field value +func (o *ContainerRegistry) SetServer(v string) { + o.Server = v +} + +// GetUsername returns the Username field value +func (o *ContainerRegistry) GetUsername() string { + if o == nil { + var ret string + return ret + } + + return o.Username +} + +// GetUsernameOk returns a tuple with the Username field value +// and a boolean to check if the value has been set. +func (o *ContainerRegistry) GetUsernameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Username, true +} + +// SetUsername sets field value +func (o *ContainerRegistry) SetUsername(v string) { + o.Username = v +} + +func (o ContainerRegistry) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ContainerRegistry) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["password"] = o.Password + toSerialize["server"] = o.Server + toSerialize["username"] = o.Username + return toSerialize, nil +} + +func (o *ContainerRegistry) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "password", + "server", + "username", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varContainerRegistry := _ContainerRegistry{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varContainerRegistry) + + if err != nil { + return err + } + + *o = ContainerRegistry(varContainerRegistry) + + return err +} + +type NullableContainerRegistry struct { + value *ContainerRegistry + isSet bool +} + +func (v NullableContainerRegistry) Get() *ContainerRegistry { + return v.value +} + +func (v *NullableContainerRegistry) Set(val *ContainerRegistry) { + v.value = val + v.isSet = true +} + +func (v NullableContainerRegistry) IsSet() bool { + return v.isSet +} + +func (v *NullableContainerRegistry) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableContainerRegistry(val *ContainerRegistry) *NullableContainerRegistry { + return &NullableContainerRegistry{value: val, isSet: true} +} + +func (v NullableContainerRegistry) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableContainerRegistry) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/build/builder.go b/pkg/build/builder.go index abe9022783..64bb309476 100644 --- a/pkg/build/builder.go +++ b/pkg/build/builder.go @@ -8,6 +8,7 @@ import ( "encoding/hex" "fmt" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" @@ -24,7 +25,7 @@ type Builder struct { id string workspaceDir string image string - containerRegistry *models.ContainerRegistry + containerRegistries common.ContainerRegistries buildImageContainerRegistry *models.ContainerRegistry buildService services.IBuildService buildImageNamespace string diff --git a/pkg/build/devcontainer.go b/pkg/build/devcontainer.go index 59e9f513a7..e4a02d631d 100644 --- a/pkg/build/devcontainer.go +++ b/pkg/build/devcontainer.go @@ -78,18 +78,18 @@ func (b *DevcontainerBuilder) buildDevcontainer(build models.Build) (string, str ApiClient: cli, }) - err = dockerClient.PullImage(b.image, b.containerRegistry, buildLogger) + cr := b.containerRegistries.FindContainerRegistryByImageName(b.image) + err = dockerClient.PullImage(b.image, cr, buildLogger) if err != nil { return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err } containerId, remoteUser, err := dockerClient.CreateFromDevcontainer(docker.CreateDevcontainerOptions{ - BuildConfig: build.BuildConfig, - WorkspaceFolderName: build.Id, - ContainerRegistry: b.buildImageContainerRegistry, - BuilderImage: b.image, - BuilderContainerRegistry: b.containerRegistry, - Prebuild: true, + BuildConfig: build.BuildConfig, + WorkspaceFolderName: build.Id, + ContainerRegistries: b.containerRegistries, + BuilderImage: b.image, + Prebuild: true, IdLabels: map[string]string{ "daytona.build.id": build.Id, }, diff --git a/pkg/build/factory.go b/pkg/build/factory.go index f542c2e2fd..cf5a16c7ca 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" @@ -22,7 +23,7 @@ type IBuilderFactory interface { } type BuilderFactory struct { - containerRegistry *models.ContainerRegistry + containerRegistries common.ContainerRegistries buildImageContainerRegistry *models.ContainerRegistry buildImageNamespace string buildService services.IBuildService @@ -34,7 +35,7 @@ type BuilderFactory struct { type BuilderFactoryConfig struct { Image string - ContainerRegistry *models.ContainerRegistry + ContainerRegistries common.ContainerRegistries BuildImageContainerRegistry *models.ContainerRegistry BuildService services.IBuildService BuildImageNamespace string // Namespace to be used when tagging and pushing the build image @@ -46,7 +47,7 @@ type BuilderFactoryConfig struct { func NewBuilderFactory(config BuilderFactoryConfig) IBuilderFactory { return &BuilderFactory{ image: config.Image, - containerRegistry: config.ContainerRegistry, + containerRegistries: config.ContainerRegistries, buildImageNamespace: config.BuildImageNamespace, buildImageContainerRegistry: config.BuildImageContainerRegistry, buildService: config.BuildService, @@ -96,7 +97,7 @@ func (f *BuilderFactory) newDevcontainerBuilder(workspaceDir string) (*Devcontai id: id, workspaceDir: workspaceDir, image: f.image, - containerRegistry: f.containerRegistry, + containerRegistries: f.containerRegistries, buildImageContainerRegistry: f.buildImageContainerRegistry, buildImageNamespace: f.buildImageNamespace, buildService: f.buildService, diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index c3414ff4e0..699e4c14f7 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -21,6 +21,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/git" "github.com/daytonaio/daytona/pkg/models" log "github.com/sirupsen/logrus" @@ -77,6 +78,7 @@ var AgentCmd = &cobra.Command{ } gitLogWriter := io.MultiWriter(os.Stdout) + dockerCredHelperLogWriter := io.MultiWriter(os.Stdout) var agentLogWriter io.Writer if c.LogFilePath != nil { logFile, err := os.OpenFile(*c.LogFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) @@ -85,6 +87,7 @@ var AgentCmd = &cobra.Command{ } defer logFile.Close() gitLogWriter = io.MultiWriter(os.Stdout, logFile) + dockerCredHelperLogWriter = io.MultiWriter(os.Stdout, logFile) agentLogWriter = logFile } @@ -94,6 +97,12 @@ var AgentCmd = &cobra.Command{ LogWriter: gitLogWriter, } + dockerCredHelper := &docker.DockerCredHelper{ + DockerConfigFileName: filepath.Join(os.Getenv("HOME"), ".docker", "config.json"), + LogWriter: dockerCredHelperLogWriter, + HomeDir: os.Getenv("HOME"), + } + sshServer := &ssh.Server{ WorkspaceDir: c.WorkspaceDir, DefaultWorkspaceDir: os.Getenv("HOME"), @@ -119,6 +128,7 @@ var AgentCmd = &cobra.Command{ agent := agent.Agent{ Config: c, Git: git, + DockerCredHelper: dockerCredHelper, Ssh: sshServer, Toolbox: toolBoxServer, Tailscale: tailscaleServer, diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go index 369b5106f5..f1402c7d2d 100644 --- a/pkg/cmd/agentmode/agent_mode.go +++ b/pkg/cmd/agentmode/agent_mode.go @@ -34,6 +34,7 @@ func Execute() error { cmd.SetupRootCommand(agentModeRootCmd) agentModeRootCmd.AddGroup(&cobra.Group{ID: util.TARGET_GROUP, Title: "Workspace & Target"}) agentModeRootCmd.AddCommand(gitCredCmd) + agentModeRootCmd.AddCommand(dockerCredCmd) agentModeRootCmd.AddCommand(AgentCmd) agentModeRootCmd.AddCommand(startCmd) agentModeRootCmd.AddCommand(stopCmd) diff --git a/pkg/cmd/agentmode/docker_cred.go b/pkg/cmd/agentmode/docker_cred.go new file mode 100644 index 0000000000..ff7863a545 --- /dev/null +++ b/pkg/cmd/agentmode/docker_cred.go @@ -0,0 +1,57 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package agentmode + +import ( + "context" + "fmt" + "io" + "os" + + "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/goccy/go-json" + "github.com/spf13/cobra" +) + +type Credentials struct { + Username string `json:"Username"` + Secret string `json:"Secret"` +} + +var dockerCredCmd = &cobra.Command{ + Use: "docker-cred get", + Hidden: true, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + input, err := io.ReadAll(os.Stdin) + if err != nil { + return err + } + + apiClient, err := apiclient.GetApiClient(nil) + if err != nil { + return err + } + + cr, _, err := apiClient.ContainerRegistryAPI.GetContainerRegistry(ctx, string(input)).WorkspaceId(workspaceId).Execute() + if err != nil { + os.Exit(1) + } + + creds := Credentials{ + Username: cr.Username, + Secret: cr.Password, + } + + data, err := json.MarshalIndent(creds, "", " ") + if err != nil { + return err + } + + fmt.Println(string(data)) + + return nil + }, +} diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go index a79b8c5978..9a2e848164 100644 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ b/pkg/cmd/server/bootstrap/get_job_runner.go @@ -11,6 +11,7 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/docker" jobs_build "github.com/daytonaio/daytona/pkg/jobs/build" "github.com/daytonaio/daytona/pkg/jobs/target" @@ -106,9 +107,6 @@ func GetWorkspaceJobFactory(c *server.Config, configDir string, version string, } return &targetDto.Target, nil }, - FindContainerRegistry: func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry { - return services.EnvironmentVariables(envVars).FindContainerRegistryByImageName(image) - }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { return gitProviderService.GetConfig(ctx, id) }, @@ -210,7 +208,13 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele } } - cr := envVars.FindContainerRegistryByImageName(c.BuilderImage) + if builderRegistry == nil { + builderRegistry = &models.ContainerRegistry{ + Server: util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain), + } + } + + _, containerRegistries := common.ExtractContainerRegistryFromEnvVars(envVars) return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { @@ -253,7 +257,7 @@ func GetBuildJobFactory(c *server.Config, configDir string, version string, tele LoggerFactory: loggerFactory, BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ Image: c.BuilderImage, - ContainerRegistry: cr, + ContainerRegistries: containerRegistries, BuildImageContainerRegistry: builderRegistry, BuildService: buildService, BuildImageNamespace: buildImageNamespace, diff --git a/pkg/common/env.go b/pkg/common/env.go new file mode 100644 index 0000000000..f58795739d --- /dev/null +++ b/pkg/common/env.go @@ -0,0 +1,54 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "strings" + + "github.com/daytonaio/daytona/pkg/models" +) + +const ( + ContainerRegistryServerEnvVarSuffix = "_CONTAINER_REGISTRY_SERVER" + ContainerRegistryUsernameEnvVarSuffix = "_CONTAINER_REGISTRY_USERNAME" + ContainerRegistryPasswordEnvVarSuffix = "_CONTAINER_REGISTRY_PASSWORD" +) + +type ContainerRegistries map[string]*models.ContainerRegistry + +func (c ContainerRegistries) FindContainerRegistryByImageName(image string) *models.ContainerRegistry { + parts := strings.Split(image, "/") + + if len(parts) < 3 { + return c["docker.io"] + } + + return c[parts[0]] +} + +func ExtractContainerRegistryFromEnvVars(envVars map[string]string) (map[string]string, ContainerRegistries) { + resultEnvVars := make(map[string]string) + containerRegistryEnvVars := make(map[string]*models.ContainerRegistry) + + for k, v := range envVars { + if !isContainerRegistryEnvVar(k) { + resultEnvVars[k] = v + } else if strings.HasSuffix(k, ContainerRegistryServerEnvVarSuffix) { + usernameKey := strings.ReplaceAll(k, ContainerRegistryServerEnvVarSuffix, ContainerRegistryUsernameEnvVarSuffix) + passwordKey := strings.ReplaceAll(k, ContainerRegistryServerEnvVarSuffix, ContainerRegistryPasswordEnvVarSuffix) + + containerRegistryEnvVars[v] = &models.ContainerRegistry{ + Server: v, + Username: envVars[usernameKey], + Password: envVars[passwordKey], + } + } + } + + return resultEnvVars, containerRegistryEnvVars +} + +func isContainerRegistryEnvVar(key string) bool { + return strings.HasSuffix(key, ContainerRegistryServerEnvVarSuffix) || strings.HasSuffix(key, ContainerRegistryUsernameEnvVarSuffix) || strings.HasSuffix(key, ContainerRegistryPasswordEnvVarSuffix) +} diff --git a/pkg/docker/client.go b/pkg/docker/client.go index 0578e4e8e1..cc8ec2d5ec 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -8,6 +8,7 @@ import ( "fmt" "io" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" "github.com/docker/docker/api/types" @@ -17,14 +18,13 @@ import ( ) type CreateWorkspaceOptions struct { - Workspace *models.Workspace - WorkspaceDir string - ContainerRegistry *models.ContainerRegistry - LogWriter io.Writer - Gpc *models.GitProviderConfig - SshClient *ssh.Client - BuilderImage string - BuilderContainerRegistry *models.ContainerRegistry + Workspace *models.Workspace + WorkspaceDir string + ContainerRegistries common.ContainerRegistries + LogWriter io.Writer + Gpc *models.GitProviderConfig + SshClient *ssh.Client + BuilderImage string } type IDockerClient interface { diff --git a/pkg/docker/create.go b/pkg/docker/create.go index 9c75cda246..7b0ddf223d 100644 --- a/pkg/docker/create.go +++ b/pkg/docker/create.go @@ -41,7 +41,8 @@ func (d *DockerClient) CreateWorkspace(opts *CreateWorkspaceOptions) error { pulledImages := map[string]bool{} if opts.Workspace.BuildConfig != nil { - err := d.PullImage(opts.BuilderImage, opts.BuilderContainerRegistry, opts.LogWriter) + cr := opts.ContainerRegistries.FindContainerRegistryByImageName(opts.BuilderImage) + err := d.PullImage(opts.BuilderImage, cr, opts.LogWriter) if err != nil { return err } @@ -202,15 +203,14 @@ func (d *DockerClient) updateContainerUserUidGid(containerId string, opts *Creat func (d *DockerClient) toCreateDevcontainerOptions(opts *CreateWorkspaceOptions, prebuild bool) CreateDevcontainerOptions { return CreateDevcontainerOptions{ - WorkspaceDir: opts.WorkspaceDir, - WorkspaceFolderName: opts.Workspace.WorkspaceFolderName(), - BuildConfig: opts.Workspace.BuildConfig, - LogWriter: opts.LogWriter, - SshClient: opts.SshClient, - ContainerRegistry: opts.ContainerRegistry, - BuilderImage: opts.BuilderImage, - BuilderContainerRegistry: opts.BuilderContainerRegistry, - EnvVars: opts.Workspace.EnvVars, + WorkspaceDir: opts.WorkspaceDir, + WorkspaceFolderName: opts.Workspace.WorkspaceFolderName(), + BuildConfig: opts.Workspace.BuildConfig, + LogWriter: opts.LogWriter, + SshClient: opts.SshClient, + ContainerRegistries: opts.ContainerRegistries, + BuilderImage: opts.BuilderImage, + EnvVars: opts.Workspace.EnvVars, IdLabels: map[string]string{ "daytona.target.id": opts.Workspace.TargetId, "daytona.workspace.id": opts.Workspace.Id, diff --git a/pkg/docker/create_devcontainer.go b/pkg/docker/create_devcontainer.go index 5149d376bc..f2faf0539c 100644 --- a/pkg/docker/create_devcontainer.go +++ b/pkg/docker/create_devcontainer.go @@ -19,6 +19,7 @@ import ( "github.com/compose-spec/compose-go/v2/cli" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build/devcontainer" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ssh" "github.com/docker/docker/api/types/container" @@ -41,16 +42,15 @@ type DevcontainerPaths struct { type CreateDevcontainerOptions struct { WorkspaceDir string // Name of the project inside the devcontainer - WorkspaceFolderName string - BuildConfig *models.BuildConfig - LogWriter io.Writer - SshClient *ssh.Client - ContainerRegistry *models.ContainerRegistry - Prebuild bool - EnvVars map[string]string - IdLabels map[string]string - BuilderImage string - BuilderContainerRegistry *models.ContainerRegistry + WorkspaceFolderName string + BuildConfig *models.BuildConfig + LogWriter io.Writer + SshClient *ssh.Client + ContainerRegistries common.ContainerRegistries + Prebuild bool + EnvVars map[string]string + IdLabels map[string]string + BuilderImage string } func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (string, RemoteUser, error) { @@ -67,7 +67,8 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s } } - socketForwardId, err := d.ensureDockerSockForward(opts.BuilderImage, opts.BuilderContainerRegistry, opts.LogWriter) + cr := opts.ContainerRegistries.FindContainerRegistryByImageName(opts.BuilderImage) + socketForwardId, err := d.ensureDockerSockForward(opts.BuilderImage, cr, opts.LogWriter) if err != nil { return "", "", err } @@ -278,7 +279,8 @@ func (d *DockerClient) CreateFromDevcontainer(opts CreateDevcontainerOptions) (s } if opts.BuildConfig.CachedBuild != nil { - err := d.PullImage(opts.BuildConfig.CachedBuild.Image, opts.ContainerRegistry, opts.LogWriter) + cr := opts.ContainerRegistries.FindContainerRegistryByImageName(opts.BuildConfig.CachedBuild.Image) + err := d.PullImage(opts.BuildConfig.CachedBuild.Image, cr, opts.LogWriter) if err != nil { opts.LogWriter.Write([]byte(fmt.Sprintf("Error pulling cached build image: %v. Continuing without cache.\n", err))) } diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index ad6fff06c1..c000f5c8cb 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -24,7 +24,8 @@ func (d *DockerClient) createWorkspaceFromImage(opts *CreateWorkspaceOptions, pu return d.initWorkspaceContainer(opts, mountWorkspaceDir) } - err := d.PullImage(opts.Workspace.Image, opts.ContainerRegistry, opts.LogWriter) + cr := opts.ContainerRegistries.FindContainerRegistryByImageName(opts.Workspace.Image) + err := d.PullImage(opts.Workspace.Image, cr, opts.LogWriter) if err != nil { return err } diff --git a/pkg/docker/create_test.go b/pkg/docker/create_test.go index 2f0aeed15b..7122c97713 100644 --- a/pkg/docker/create_test.go +++ b/pkg/docker/create_test.go @@ -102,13 +102,13 @@ func (s *DockerClientTestSuite) TestCreateWorkspace() { ).Return(container.CreateResponse{ID: "123"}, nil) err := s.dockerClient.CreateWorkspace(&docker.CreateWorkspaceOptions{ - Workspace: workspace1, - WorkspaceDir: workspaceDir, - ContainerRegistry: nil, - LogWriter: nil, - Gpc: nil, - SshClient: nil, - BuilderImage: "daytonaio/workspace-project", + Workspace: workspace1, + WorkspaceDir: workspaceDir, + ContainerRegistries: nil, + LogWriter: nil, + Gpc: nil, + SshClient: nil, + BuilderImage: "daytonaio/workspace-project", }) require.Nil(s.T(), err) } diff --git a/pkg/docker/credential_helper.go b/pkg/docker/credential_helper.go new file mode 100644 index 0000000000..5507d3ced1 --- /dev/null +++ b/pkg/docker/credential_helper.go @@ -0,0 +1,97 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package docker + +import ( + "encoding/json" + "io" + "os" + "path/filepath" + "strings" +) + +type IDockerCredHelper interface { + SetDockerConfig() error +} + +type DockerCredHelper struct { + DockerConfigFileName string + LogWriter io.Writer + HomeDir string +} + +func (d *DockerCredHelper) SetDockerConfig() error { + err := d.createDockerCredHelperExecutable() + if err != nil { + return err + } + + dockerFilePath := strings.TrimSuffix(d.DockerConfigFileName, "/config.json") + _, err = os.Stat(dockerFilePath) + if err != nil && os.IsNotExist(err) { + err := os.MkdirAll(dockerFilePath, 0755) + if err != nil { + return err + } + } + + _, err = os.Stat(d.DockerConfigFileName) + if err != nil && os.IsNotExist(err) { + _, err := os.Create(d.DockerConfigFileName) + if err != nil { + return err + } + } + + var dockerConfigContent []byte + dockerConfigContent, err = os.ReadFile(d.DockerConfigFileName) + if err != nil || len(dockerConfigContent) == 0 { + dockerConfigContent = []byte("{}") + } + + var cfg map[string]interface{} + if err := json.Unmarshal(dockerConfigContent, &cfg); err != nil { + return err + } + + cfg["credsStore"] = "daytona" + + updatedConfigContent, err := json.MarshalIndent(cfg, "", " ") + if err != nil { + return err + } + + return os.WriteFile(d.DockerConfigFileName, updatedConfigContent, 0644) +} + +func (d *DockerCredHelper) createDockerCredHelperExecutable() error { + content := "#!/bin/bash\ndaytona docker-cred\n" + fileName := "docker-credential-daytona" + filePath := "/usr/local/bin" + + _, err := os.Create(filepath.Join(filePath, fileName)) + if err != nil { + filePath = filepath.Join(d.HomeDir, ".local", "bin") + + _, ok := os.Stat(filePath) + if os.IsNotExist(ok) { + err := os.MkdirAll(filePath, 0757) + if err != nil { + return err + } + } + + _, err = os.Create(filepath.Join(filePath, fileName)) + if err != nil { + return err + } + } + + err = os.WriteFile(filepath.Join(filePath, fileName), []byte(content), 0555) + if err != nil { + return err + } + + return os.Chmod(filepath.Join(filePath, fileName), 0555) +} diff --git a/pkg/docker/start_devcontainer.go b/pkg/docker/start_devcontainer.go index 3e598d6399..92aa47cad2 100644 --- a/pkg/docker/start_devcontainer.go +++ b/pkg/docker/start_devcontainer.go @@ -24,7 +24,8 @@ func (d *DockerClient) startDevcontainerWorkspace(opts *CreateWorkspaceOptions) } func (d *DockerClient) runDevcontainerUserCommands(opts *CreateWorkspaceOptions) error { - socketForwardId, err := d.ensureDockerSockForward(opts.BuilderImage, opts.BuilderContainerRegistry, opts.LogWriter) + cr := opts.ContainerRegistries.FindContainerRegistryByImageName(opts.BuilderImage) + socketForwardId, err := d.ensureDockerSockForward(opts.BuilderImage, cr, opts.LogWriter) if err != nil { return err } diff --git a/pkg/jobs/util/env.go b/pkg/jobs/util/env.go deleted file mode 100644 index 189f843a3b..0000000000 --- a/pkg/jobs/util/env.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package util - -import "strings" - -func ExtractContainerRegistryFromEnvVars(envVars map[string]string) map[string]string { - result := make(map[string]string) - - for k, v := range envVars { - if !strings.HasSuffix(k, "CONTAINER_REGISTRY_SERVER") && !strings.HasSuffix(k, "CONTAINER_REGISTRY_USERNAME") && !strings.HasSuffix(k, "CONTAINER_REGISTRY_PASSWORD") { - result[k] = v - } - } - - return result -} diff --git a/pkg/jobs/workspace/create.go b/pkg/jobs/workspace/create.go index f607e5141a..8945aa6cb2 100644 --- a/pkg/jobs/workspace/create.go +++ b/pkg/jobs/workspace/create.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - "github.com/daytonaio/daytona/pkg/jobs/util" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" @@ -30,11 +30,6 @@ func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { if err != nil { return err } - w.EnvVars = workspaceEnvVars - - cr := wj.findContainerRegistry(ctx, w.Image, workspaceEnvVars) - - builderCr := wj.findContainerRegistry(ctx, wj.builderImage, workspaceEnvVars) var gc *models.GitProviderConfig @@ -45,14 +40,15 @@ func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { } } - w.EnvVars = util.ExtractContainerRegistryFromEnvVars(workspaceEnvVars) + extractedEnvVars, containerRegistries := common.ExtractContainerRegistryFromEnvVars(workspaceEnvVars) + + w.EnvVars = extractedEnvVars err = wj.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ - Workspace: w, - ContainerRegistry: cr, - GitProviderConfig: gc, - BuilderImage: wj.builderImage, - BuilderImageContainerRegistry: builderCr, + Workspace: w, + ContainerRegistries: containerRegistries, + GitProviderConfig: gc, + BuilderImage: wj.builderImage, }) if err != nil { return err diff --git a/pkg/jobs/workspace/factory.go b/pkg/jobs/workspace/factory.go index b94f0d49e8..f034ca4df2 100644 --- a/pkg/jobs/workspace/factory.go +++ b/pkg/jobs/workspace/factory.go @@ -24,7 +24,6 @@ type WorkspaceJobFactory struct { type WorkspaceJobFactoryConfig struct { FindWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) FindTarget func(ctx context.Context, targetId string) (*models.Target, error) - FindContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error @@ -46,7 +45,6 @@ func (f *WorkspaceJobFactory) Create(job models.Job) jobs.IJob { findWorkspace: f.config.FindWorkspace, findTarget: f.config.FindTarget, - findContainerRegistry: f.config.FindContainerRegistry, findGitProviderConfig: f.config.FindGitProviderConfig, getWorkspaceEnvironmentVariables: f.config.GetWorkspaceEnvironmentVariables, trackTelemetryEvent: f.config.TrackTelemetryEvent, diff --git a/pkg/jobs/workspace/start.go b/pkg/jobs/workspace/start.go index 438332812c..99deca07dc 100644 --- a/pkg/jobs/workspace/start.go +++ b/pkg/jobs/workspace/start.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - "github.com/daytonaio/daytona/pkg/jobs/util" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provisioner" @@ -30,11 +30,6 @@ func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { if err != nil { return err } - w.EnvVars = workspaceEnvVars - - cr := wj.findContainerRegistry(ctx, w.Image, workspaceEnvVars) - - builderCr := wj.findContainerRegistry(ctx, wj.builderImage, workspaceEnvVars) var gc *models.GitProviderConfig @@ -45,14 +40,15 @@ func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { } } - w.EnvVars = util.ExtractContainerRegistryFromEnvVars(workspaceEnvVars) + extractedEnvVars, containerRegistries := common.ExtractContainerRegistryFromEnvVars(workspaceEnvVars) + + w.EnvVars = extractedEnvVars err = wj.provisioner.StartWorkspace(provisioner.WorkspaceParams{ - Workspace: w, - ContainerRegistry: cr, - GitProviderConfig: gc, - BuilderImage: wj.builderImage, - BuilderImageContainerRegistry: builderCr, + Workspace: w, + ContainerRegistries: containerRegistries, + GitProviderConfig: gc, + BuilderImage: wj.builderImage, }) if err != nil { return err diff --git a/pkg/models/container_registry.go b/pkg/models/container_registry.go index 24993ffc74..c7de259fc6 100644 --- a/pkg/models/container_registry.go +++ b/pkg/models/container_registry.go @@ -3,27 +3,9 @@ package models -import ( - "errors" - "strings" -) - // ContainerRegistry represents a container registry credentials type ContainerRegistry struct { Server string `json:"server" validate:"required" gorm:"primaryKey"` Username string `json:"username" validate:"required"` Password string `json:"password" validate:"required"` } // @name ContainerRegistry - -func GetServerHostname(server string) (string, error) { - server = strings.TrimPrefix(server, "https://") - server = strings.TrimPrefix(server, "http://") - - parts := strings.Split(server, "/") - - if len(parts) == 0 { - return "", errors.New("invalid container registry server URL") - } - - return parts[0], nil -} diff --git a/pkg/provider/types.go b/pkg/provider/types.go index 85452ccf2f..d7fd476872 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -4,6 +4,7 @@ package provider import ( + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/models" ) @@ -27,11 +28,10 @@ type TargetRequest struct { } type WorkspaceRequest struct { - BuilderImage string - BuilderContainerRegistry *models.ContainerRegistry - ContainerRegistry *models.ContainerRegistry - Workspace *models.Workspace - GitProviderConfig *models.GitProviderConfig + BuilderImage string + ContainerRegistries common.ContainerRegistries + Workspace *models.Workspace + GitProviderConfig *models.GitProviderConfig } type ProviderInfo struct { diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go index eac2496e2a..4ead351c49 100644 --- a/pkg/provisioner/create.go +++ b/pkg/provisioner/create.go @@ -28,11 +28,10 @@ func (p *Provisioner) CreateWorkspace(params WorkspaceParams) error { } _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ - Workspace: params.Workspace, - ContainerRegistry: params.ContainerRegistry, - GitProviderConfig: params.GitProviderConfig, - BuilderImage: params.BuilderImage, - BuilderContainerRegistry: params.BuilderImageContainerRegistry, + Workspace: params.Workspace, + ContainerRegistries: params.ContainerRegistries, + GitProviderConfig: params.GitProviderConfig, + BuilderImage: params.BuilderImage, }) return err diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go index 85e93a57e7..813cb29ac9 100644 --- a/pkg/provisioner/provisioner.go +++ b/pkg/provisioner/provisioner.go @@ -6,17 +6,17 @@ package provisioner import ( "context" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/provider/manager" ) type WorkspaceParams struct { - Workspace *models.Workspace - Target *models.Target - ContainerRegistry *models.ContainerRegistry - GitProviderConfig *models.GitProviderConfig - BuilderImage string - BuilderImageContainerRegistry *models.ContainerRegistry + Workspace *models.Workspace + Target *models.Target + ContainerRegistries common.ContainerRegistries + GitProviderConfig *models.GitProviderConfig + BuilderImage string } type IProvisioner interface { diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go index 37065a0b2b..c1fc6e56f8 100644 --- a/pkg/provisioner/start.go +++ b/pkg/provisioner/start.go @@ -28,11 +28,10 @@ func (p *Provisioner) StartWorkspace(params WorkspaceParams) error { } _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ - Workspace: params.Workspace, - ContainerRegistry: params.ContainerRegistry, - GitProviderConfig: params.GitProviderConfig, - BuilderImage: params.BuilderImage, - BuilderContainerRegistry: params.BuilderImageContainerRegistry, + Workspace: params.Workspace, + ContainerRegistries: params.ContainerRegistries, + GitProviderConfig: params.GitProviderConfig, + BuilderImage: params.BuilderImage, }) return err diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index b56bf082bd..c2fcb8b4b5 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -12,6 +12,7 @@ import ( "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" @@ -168,8 +169,6 @@ func TestTargetService(t *testing.T) { }) t.Run("CreateWorkspace", func(t *testing.T) { - var containerRegistry *models.ContainerRegistry - gitProviderService.On("GetLastCommitSha", createWorkspaceDTO.Source.Repository).Return("123", nil) apiKeyService.On("Generate", models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) @@ -192,21 +191,27 @@ func TestTargetService(t *testing.T) { ClientId: "test", }) + containerRegistries := common.ContainerRegistries{ + "test": &models.ContainerRegistry{ + Server: "test", + Username: "test", + Password: "test", + }, + } + mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ - Workspace: ws, - Target: tg, - ContainerRegistry: containerRegistry, - GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultWorkspaceImage, - BuilderImageContainerRegistry: containerRegistry, + Workspace: ws, + Target: tg, + ContainerRegistries: containerRegistries, + GitProviderConfig: &gitProviderConfig, + BuilderImage: defaultWorkspaceImage, }).Return(nil) mockProvisioner.On("StartWorkspace", provisioner.WorkspaceParams{ - Workspace: ws, - Target: tg, - ContainerRegistry: containerRegistry, - GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultWorkspaceImage, - BuilderImageContainerRegistry: containerRegistry, + Workspace: ws, + Target: tg, + ContainerRegistries: containerRegistries, + GitProviderConfig: &gitProviderConfig, + BuilderImage: defaultWorkspaceImage, }).Return(nil) gitProviderService.On("GetConfig", "github").Return(&gitProviderConfig, nil) From 850333bb7c39a74b162265628d43cf6edf5769db Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Tue, 17 Dec 2024 15:59:54 +0000 Subject: [PATCH 32/76] fix: db store AutoMigrate type Signed-off-by: Toma Puljak --- pkg/db/db_store.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/db/db_store.go b/pkg/db/db_store.go index 297e90ef7b..96a53faa87 100644 --- a/pkg/db/db_store.go +++ b/pkg/db/db_store.go @@ -14,7 +14,7 @@ import ( type IStore interface { stores.IStore - AutoMigrate(interface{}) error + AutoMigrate(...interface{}) error GetTransaction(ctx context.Context) *gorm.DB } @@ -26,8 +26,8 @@ func NewStore(db *gorm.DB) IStore { return &dbStore{db} } -func (s *dbStore) AutoMigrate(value interface{}) error { - return s.db.AutoMigrate(value) +func (s *dbStore) AutoMigrate(dst ...interface{}) error { + return s.db.AutoMigrate(dst...) } func (s *dbStore) BeginTransaction(ctx context.Context) (context.Context, error) { From 31484e672e12d1eeea42188ea80b3423fcddccb1 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Thu, 19 Dec 2024 15:38:07 +0000 Subject: [PATCH 33/76] refactor: parametrize headscale user methods Signed-off-by: Toma Puljak --- pkg/api/controllers/server/server.go | 3 ++- pkg/cmd/purge.go | 3 ++- pkg/cmd/server/bootstrap/init_provider_manager.go | 2 +- pkg/cmd/server/serve.go | 3 ++- pkg/server/headscale/auth_keys.go | 4 ++-- pkg/server/headscale/connect.go | 6 +++--- pkg/server/headscale/create_user.go | 8 +++++--- pkg/server/types.go | 6 +++--- 8 files changed, 20 insertions(+), 15 deletions(-) diff --git a/pkg/api/controllers/server/server.go b/pkg/api/controllers/server/server.go index 5e2602bf04..4da10e9cc7 100644 --- a/pkg/api/controllers/server/server.go +++ b/pkg/api/controllers/server/server.go @@ -8,6 +8,7 @@ import ( "net/http" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/gin-gonic/gin" ) @@ -73,7 +74,7 @@ func SetConfig(ctx *gin.Context) { func GenerateNetworkKey(ctx *gin.Context) { s := server.GetInstance(nil) - authKey, err := s.TailscaleServer.CreateAuthKey() + authKey, err := s.TailscaleServer.CreateAuthKey(headscale.HEADSCALE_USERNAME) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to generate network key: %w", err)) return diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 1cd053d401..49ebdff90d 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -16,6 +16,7 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" view "github.com/daytonaio/daytona/pkg/views/purge" @@ -151,7 +152,7 @@ var purgeCmd = &cobra.Command{ select { case <-headscaleServerStartedChan: go func() { - headscaleServerErrChan <- server.TailscaleServer.Connect() + headscaleServerErrChan <- server.TailscaleServer.Connect(headscale.HEADSCALE_USERNAME) }() case err := <-headscaleServerErrChan: return err diff --git a/pkg/cmd/server/bootstrap/init_provider_manager.go b/pkg/cmd/server/bootstrap/init_provider_manager.go index 7de47cad66..1f4241057f 100644 --- a/pkg/cmd/server/bootstrap/init_provider_manager.go +++ b/pkg/cmd/server/bootstrap/init_provider_manager.go @@ -69,7 +69,7 @@ func InitProviderManager(c *server.Config, configDir string) error { RegistryUrl: c.RegistryUrl, BaseDir: c.ProvidersDir, CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { - return headscaleServer.CreateAuthKey() + return headscaleServer.CreateAuthKey(headscale.HEADSCALE_USERNAME) }, ServerPort: c.HeadscalePort, ApiPort: c.ApiPort, diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 09ea6cfdd3..c15fd89aa9 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -19,6 +19,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -119,7 +120,7 @@ var ServeCmd = &cobra.Command{ case <-headscaleServerStartedChan: log.Info("Headscale server started") go func() { - headscaleServerErrChan <- server.TailscaleServer.Connect() + headscaleServerErrChan <- server.TailscaleServer.Connect(headscale.HEADSCALE_USERNAME) }() case err := <-headscaleServerErrChan: return err diff --git a/pkg/server/headscale/auth_keys.go b/pkg/server/headscale/auth_keys.go index 9a26acc389..e1f825cc7d 100644 --- a/pkg/server/headscale/auth_keys.go +++ b/pkg/server/headscale/auth_keys.go @@ -13,12 +13,12 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *HeadscaleServer) CreateAuthKey() (string, error) { +func (s *HeadscaleServer) CreateAuthKey(username string) (string, error) { log.Debug("Creating headscale auth key") request := &v1.CreatePreAuthKeyRequest{ Reusable: false, - User: "daytona", + User: username, Ephemeral: true, Expiration: timestamppb.New(time.Now().Add(100000 * time.Hour)), } diff --git a/pkg/server/headscale/connect.go b/pkg/server/headscale/connect.go index 5e9107194a..b20347d3b5 100644 --- a/pkg/server/headscale/connect.go +++ b/pkg/server/headscale/connect.go @@ -20,13 +20,13 @@ var tsNetServer = &tsnet.Server{ Hostname: "server", } -func (s *HeadscaleServer) Connect() error { - err := s.CreateUser() +func (s *HeadscaleServer) Connect(username string) error { + err := s.CreateUser(username) if err != nil { log.Fatal(err) } - authKey, err := s.CreateAuthKey() + authKey, err := s.CreateAuthKey(username) if err != nil { log.Fatal(err) } diff --git a/pkg/server/headscale/create_user.go b/pkg/server/headscale/create_user.go index 231f650148..e6e9820c8a 100644 --- a/pkg/server/headscale/create_user.go +++ b/pkg/server/headscale/create_user.go @@ -9,7 +9,9 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *HeadscaleServer) CreateUser() error { +const HEADSCALE_USERNAME = "daytona" + +func (s *HeadscaleServer) CreateUser(username string) error { log.Debug("Creating headscale user") ctx, client, conn, cancel, err := s.getClient() @@ -20,7 +22,7 @@ func (s *HeadscaleServer) CreateUser() error { defer conn.Close() _, err = client.GetUser(ctx, &v1.GetUserRequest{ - Name: "daytona", + Name: username, }) if err == nil { log.Debug("User already exists") @@ -28,7 +30,7 @@ func (s *HeadscaleServer) CreateUser() error { } _, err = client.CreateUser(ctx, &v1.CreateUserRequest{ - Name: "daytona", + Name: username, }) return err diff --git a/pkg/server/types.go b/pkg/server/types.go index fa59ede047..fe4dd06b65 100644 --- a/pkg/server/types.go +++ b/pkg/server/types.go @@ -10,9 +10,9 @@ import ( ) type TailscaleServer interface { - Connect() error - CreateAuthKey() (string, error) - CreateUser() error + Connect(username string) error + CreateAuthKey(username string) (string, error) + CreateUser(username string) error HTTPClient() *http.Client Dial(ctx context.Context, network, address string) (net.Conn, error) Start(errChan chan error) error From 14f260f556cb375a40ea4df07fe83a3884674d2b Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Mon, 23 Dec 2024 11:07:58 +0100 Subject: [PATCH 34/76] feat: remote runners (#1462) - remote runners can be used to offload jobs from the server Signed-off-by: Toma Puljak Signed-off-by: Ivan Dagelic Co-authored-by: Toma Puljak --- .vscode/launch.json | 16 + docs/agent_mode/daytona_list.md | 1 - docs/daytona.md | 1 + docs/daytona_list.md | 1 - docs/daytona_runner.md | 22 + docs/daytona_runner_config.md | 25 + docs/daytona_runner_configure.md | 27 + docs/daytona_runner_logs.md | 24 + docs/daytona_runner_purge.md | 18 + docs/daytona_runner_restart.md | 18 + docs/daytona_runner_serve.md | 18 + docs/daytona_runner_start.md | 18 + docs/daytona_runner_stop.md | 18 + docs/daytona_server.md | 1 + docs/daytona_server_runner.md | 18 + docs/daytona_server_runner_list.md | 24 + docs/daytona_server_runner_logs.md | 24 + docs/daytona_server_runner_register.md | 24 + docs/daytona_server_runner_unregister.md | 24 + docs/daytona_target-config_list.md | 1 + docs/daytona_target_info.md | 1 + docs/daytona_target_list.md | 2 +- go.mod | 2 +- hack/docs/agent_mode/daytona_list.yaml | 4 - hack/docs/daytona.yaml | 1 + hack/docs/daytona_list.yaml | 4 - hack/docs/daytona_runner.yaml | 16 + hack/docs/daytona_runner_config.yaml | 17 + hack/docs/daytona_runner_configure.yaml | 18 + hack/docs/daytona_runner_logs.yaml | 14 + hack/docs/daytona_runner_purge.yaml | 9 + hack/docs/daytona_runner_restart.yaml | 9 + hack/docs/daytona_runner_serve.yaml | 9 + hack/docs/daytona_runner_start.yaml | 9 + hack/docs/daytona_runner_stop.yaml | 9 + hack/docs/daytona_server.yaml | 1 + hack/docs/daytona_server_runner.yaml | 12 + hack/docs/daytona_server_runner_list.yaml | 13 + hack/docs/daytona_server_runner_logs.yaml | 14 + hack/docs/daytona_server_runner_register.yaml | 13 + .../daytona_server_runner_unregister.yaml | 14 + hack/docs/daytona_target-config_list.yaml | 4 + hack/docs/daytona_target_info.yaml | 4 + hack/docs/daytona_target_list.yaml | 4 +- internal/testing/agent/mocks/apiserver.go | 1 - internal/testing/docker/mocks/client.go | 10 - internal/testing/logger/mocks/logger.go | 5 + .../testing/server/targets/metadata_store.go | 43 +- .../testing/server/targets/mocks/builder.go | 5 - .../server/targets/mocks/provisioner.go | 72 - .../server/workspaces/metadata_store.go | 42 +- internal/util/apiclient/api_client.go | 35 +- .../util/apiclient/conversion/conversion.go | 26 + .../util/apiclient/conversion/provider.go | 31 + .../util/apiclient/conversion/workspace.go | 176 --- internal/util/cmd.go | 1 + internal/util/config.go | 14 + internal/util/log_formatter.go | 33 + .../util/providermanifest.go | 31 +- .../util/{apiclient => }/websocket_conn.go | 31 +- pkg/agent/agent.go | 24 +- pkg/agent/log.go | 44 - pkg/api/controllers/build/create.go | 43 + .../controllers/build/{build.go => delete.go} | 85 -- pkg/api/controllers/build/get.go | 47 + pkg/api/controllers/build/list.go | 74 ++ pkg/api/controllers/job/job.go | 45 +- .../controllers/log/{websocket.go => read.go} | 215 +-- pkg/api/controllers/log/write.go | 142 ++ pkg/api/controllers/provider/install.go | 56 - pkg/api/controllers/provider/list.go | 45 - pkg/api/controllers/provider/target_config.go | 43 - pkg/api/controllers/runner/dto/dto.go | 14 + pkg/api/controllers/runner/get.go | 42 + pkg/api/controllers/runner/jobs.go | 87 ++ pkg/api/controllers/runner/list.go | 34 + pkg/api/controllers/runner/metadata.go | 51 + .../{ => runner}/provider/dto/dto.go | 0 .../controllers/runner/provider/install.go | 45 + pkg/api/controllers/runner/provider/list.go | 42 + .../{ => runner}/provider/uninstall.go | 16 +- pkg/api/controllers/runner/provider/update.go | 48 + pkg/api/controllers/runner/register.go | 46 + pkg/api/controllers/runner/remove.go | 36 + pkg/api/controllers/target/create.go | 29 +- pkg/api/controllers/target/dto/dto.go | 8 +- pkg/api/controllers/target/metadata.go | 42 +- pkg/api/controllers/target/target.go | 83 +- pkg/api/controllers/targetconfig/add.go | 15 +- pkg/api/controllers/targetconfig/list.go | 17 +- pkg/api/controllers/workspace/dto/dto.go | 8 +- pkg/api/controllers/workspace/metadata.go | 44 +- .../controllers/workspace/toolbox/toolbox.go | 4 +- pkg/api/controllers/workspace/workspace.go | 53 +- .../workspacetemplate/workspace_template.go | 20 +- pkg/api/docs/docs.go | 855 +++++++++--- pkg/api/docs/swagger.json | 855 +++++++++--- pkg/api/docs/swagger.yaml | 590 ++++++-- pkg/api/middlewares/auth.go | 11 +- pkg/api/middlewares/logging.go | 31 +- pkg/api/middlewares/runner.go | 43 + pkg/api/middlewares/telemetry.go | 21 +- pkg/api/middlewares/workspace.go | 15 +- pkg/api/server.go | 69 +- pkg/api/util/hide.go | 34 - pkg/apiclient/README.md | 40 +- pkg/apiclient/api/openapi.yaml | 1184 ++++++++++++++--- pkg/apiclient/api_build.go | 118 ++ pkg/apiclient/api_job.go | 61 +- pkg/apiclient/api_provider.go | 272 ++-- pkg/apiclient/api_runner.go | 845 ++++++++++++ pkg/apiclient/api_target.go | 276 +++- pkg/apiclient/api_target_config.go | 24 +- pkg/apiclient/api_workspace.go | 158 ++- pkg/apiclient/client.go | 3 + pkg/apiclient/docs/AddTargetConfigDTO.md | 10 +- pkg/apiclient/docs/BuildAPI.md | 71 + ...oviderRequest.md => InstallProviderDTO.md} | 26 +- pkg/apiclient/docs/Job.md | 52 + pkg/apiclient/docs/JobAPI.md | 17 +- pkg/apiclient/docs/ModelsApiKeyType.md | 2 + pkg/apiclient/docs/ModelsJobAction.md | 6 + ...e.md => ModelsTargetConfigPropertyType.md} | 2 +- pkg/apiclient/docs/Provider.md | 98 -- pkg/apiclient/docs/ProviderAPI.md | 109 +- pkg/apiclient/docs/ProviderInfo.md | 187 +++ pkg/apiclient/docs/RegisterRunnerDTO.md | 72 + pkg/apiclient/docs/RegisterRunnerResultDTO.md | 119 ++ pkg/apiclient/docs/ResourceType.md | 2 + pkg/apiclient/docs/RunnerAPI.md | 493 +++++++ pkg/apiclient/docs/RunnerDTO.md | 119 ++ pkg/apiclient/docs/RunnerMetadata.md | 140 ++ pkg/apiclient/docs/ServerAPI.md | 2 +- pkg/apiclient/docs/ServerConfig.md | 45 +- pkg/apiclient/docs/Target.md | 26 + pkg/apiclient/docs/TargetAPI.md | 164 ++- pkg/apiclient/docs/TargetConfig.md | 10 +- pkg/apiclient/docs/TargetConfigAPI.md | 19 +- pkg/apiclient/docs/TargetConfigProperty.md | 8 +- pkg/apiclient/docs/TargetDTO.md | 52 +- pkg/apiclient/docs/TargetInfo.md | 77 -- pkg/apiclient/docs/TargetProviderInfo.md | 124 -- pkg/apiclient/docs/UpdateJobState.md | 77 ++ pkg/apiclient/docs/UpdateRunnerMetadataDTO.md | 98 ++ ...Metadata.md => UpdateTargetMetadataDTO.md} | 20 +- .../docs/UpdateTargetProviderMetadataDTO.md | 51 + ...adata.md => UpdateWorkspaceMetadataDTO.md} | 28 +- .../UpdateWorkspaceProviderMetadataDTO.md | 51 + pkg/apiclient/docs/Workspace.md | 49 +- pkg/apiclient/docs/WorkspaceAPI.md | 96 +- pkg/apiclient/docs/WorkspaceDTO.md | 75 +- pkg/apiclient/docs/WorkspaceInfo.md | 140 -- pkg/apiclient/model_add_target_config_dto.go | 16 +- ...quest.go => model_install_provider_dto.go} | 66 +- pkg/apiclient/model_job.go | 89 +- pkg/apiclient/model_models_api_key_type.go | 2 + pkg/apiclient/model_models_job_action.go | 20 +- ...odel_models_target_config_property_type.go | 118 ++ pkg/apiclient/model_provider.go | 220 --- pkg/apiclient/model_provider_info.go | 340 +++++ ...el_provider_target_config_property_type.go | 118 -- pkg/apiclient/model_register_runner_dto.go | 184 +++ .../model_register_runner_result_dto.go | 248 ++++ pkg/apiclient/model_resource_type.go | 2 + pkg/apiclient/model_runner_dto.go | 248 ++++ pkg/apiclient/model_runner_metadata.go | 276 ++++ pkg/apiclient/model_server_config.go | 64 +- pkg/apiclient/model_target.go | 54 +- pkg/apiclient/model_target_config.go | 14 +- pkg/apiclient/model_target_config_property.go | 14 +- pkg/apiclient/model_target_dto.go | 92 +- pkg/apiclient/model_target_info.go | 192 --- pkg/apiclient/model_target_provider_info.go | 256 ---- pkg/apiclient/model_update_job_state.go | 192 +++ .../model_update_runner_metadata_dto.go | 220 +++ ...go => model_update_target_metadata_dto.go} | 60 +- ...del_update_target_provider_metadata_dto.go | 156 +++ ...=> model_update_workspace_metadata_dto.go} | 68 +- ..._update_workspace_provider_metadata_dto.go | 156 +++ pkg/apiclient/model_workspace.go | 66 +- pkg/apiclient/model_workspace_dto.go | 102 +- pkg/apiclient/model_workspace_info.go | 276 ---- pkg/build/builder.go | 11 +- pkg/build/devcontainer.go | 10 +- pkg/build/factory.go | 33 +- pkg/build/logs.go | 19 - pkg/cmd/agent/agent.go | 3 +- pkg/cmd/agent/logs.go | 4 +- pkg/cmd/agentmode/info.go | 2 +- pkg/cmd/bootstrap/get_local_runner.go | 373 ++++++ pkg/cmd/bootstrap/get_remote_runner.go | 476 +++++++ .../bootstrap/get_server_instance.go | 92 +- pkg/cmd/build/logs.go | 15 +- pkg/cmd/cmd.go | 3 + pkg/cmd/common/await_state.go | 45 +- pkg/cmd/{server => common}/daemon/daemon.go | 25 +- pkg/cmd/common/get_runner.go | 50 + .../cmd/common}/websocket_log_reader.go | 50 +- pkg/cmd/provider/install.go | 164 +-- pkg/cmd/provider/list.go | 24 +- pkg/cmd/provider/uninstall.go | 24 +- pkg/cmd/provider/update.go | 41 +- pkg/cmd/purge.go | 13 +- pkg/cmd/runner/config.go | 40 + pkg/cmd/runner/configure.go | 76 ++ pkg/cmd/runner/logs.go | 73 + pkg/cmd/runner/purge.go | 17 + pkg/cmd/runner/restart.go | 43 + pkg/cmd/runner/runner.go | 27 + pkg/cmd/runner/serve.go | 90 ++ pkg/cmd/runner/start.go | 87 ++ pkg/cmd/runner/stop.go | 28 + pkg/cmd/server/bootstrap/get_job_runner.go | 270 ---- .../server/bootstrap/init_provider_manager.go | 95 -- pkg/cmd/server/logs/logs.go | 7 +- pkg/cmd/server/restart.go | 12 +- pkg/cmd/server/runner/list.go | 46 + pkg/cmd/server/runner/logs.go | 100 ++ pkg/cmd/server/runner/register.go | 76 ++ pkg/cmd/server/runner/runner.go | 20 + pkg/cmd/server/runner/unregister.go | 108 ++ pkg/cmd/server/serve.go | 130 +- pkg/cmd/server/server.go | 14 +- pkg/cmd/server/stop.go | 12 +- pkg/cmd/target/create.go | 9 +- pkg/cmd/target/delete.go | 2 +- pkg/cmd/target/info.go | 7 +- pkg/cmd/target/list.go | 8 +- pkg/cmd/target/logs.go | 14 +- pkg/cmd/target/restart.go | 2 +- pkg/cmd/target/setdefault.go | 2 +- pkg/cmd/target/ssh.go | 6 +- pkg/cmd/target/start.go | 19 +- pkg/cmd/target/stop.go | 23 +- pkg/cmd/targetconfig/add.go | 95 +- pkg/cmd/targetconfig/list.go | 7 +- pkg/cmd/workspace/code.go | 4 +- pkg/cmd/workspace/create/cmd.go | 25 +- pkg/cmd/workspace/delete.go | 2 +- pkg/cmd/workspace/info.go | 4 +- pkg/cmd/workspace/list.go | 7 +- pkg/cmd/workspace/logs.go | 18 +- pkg/cmd/workspace/restart.go | 2 +- pkg/cmd/workspace/ssh-proxy.go | 14 +- pkg/cmd/workspace/ssh.go | 2 +- pkg/cmd/workspace/start.go | 22 +- pkg/cmd/workspace/stop.go | 18 +- pkg/db/job_store.go | 3 + pkg/db/runner_metadata_store.go | 76 ++ pkg/db/runner_store.go | 82 ++ pkg/db/target_metadata_store.go | 18 +- pkg/db/workspace_metadata_store.go | 18 +- pkg/docker/client.go | 4 +- pkg/docker/info.go | 74 -- pkg/docker/info_test.go | 69 - pkg/docker/metadata.go | 45 + pkg/docker/metadata_test.go | 38 + pkg/jobs/build/build.go | 2 +- pkg/jobs/build/factory.go | 2 +- pkg/jobs/build/run.go | 5 +- pkg/jobs/runner/factory.go | 38 + pkg/jobs/runner/install.go | 28 + pkg/jobs/runner/runner.go | 32 + pkg/jobs/runner/uninstall.go | 19 + pkg/jobs/runner/update.go | 14 + pkg/jobs/target/create.go | 15 +- pkg/jobs/target/delete.go | 27 +- pkg/jobs/target/factory.go | 20 +- pkg/jobs/target/start.go | 27 +- pkg/jobs/target/stop.go | 16 +- pkg/jobs/target/target.go | 9 +- pkg/jobs/workspace/create.go | 16 +- pkg/jobs/workspace/delete.go | 26 +- pkg/jobs/workspace/factory.go | 12 +- pkg/jobs/workspace/start.go | 28 +- pkg/jobs/workspace/stop.go | 16 +- pkg/jobs/workspace/workspace.go | 10 +- pkg/logs/build.go | 95 -- pkg/logs/factory.go | 98 ++ {internal/util => pkg/logs}/log_reader.go | 12 +- pkg/logs/logger.go | 104 +- pkg/logs/remote_factory.go | 61 + pkg/logs/remote_logger.go | 57 + pkg/logs/target.go | 98 -- pkg/logs/types.go | 92 ++ pkg/logs/workspace.go | 99 -- pkg/models/api_key.go | 1 + pkg/models/job.go | 27 +- pkg/models/provider_info.go | 45 + pkg/models/runner.go | 44 + pkg/models/target.go | 37 +- pkg/models/workspace.go | 13 +- pkg/provider/provider.go | 7 +- pkg/provider/rpc_client.go | 27 +- pkg/provider/rpc_server.go | 24 +- pkg/provider/types.go | 51 +- pkg/provisioner/create.go | 38 - pkg/provisioner/destroy.go | 35 - pkg/provisioner/info.go | 73 - pkg/provisioner/provisioner.go | 48 - pkg/provisioner/start.go | 38 - pkg/provisioner/stop.go | 35 - pkg/runner/config.go | 194 +++ .../providermanager}/error.go | 2 +- .../providermanager}/installer.go | 32 +- .../providermanager}/manager.go | 103 +- pkg/runner/providers.go | 142 ++ pkg/runner/runner.go | 259 ++++ pkg/runners/runner.go | 17 - pkg/runners/runner/runner.go | 105 -- pkg/server/apikeys/validate.go | 10 +- pkg/server/apikeys/validate_test.go | 41 +- pkg/server/builds/service.go | 10 +- pkg/server/config.go | 35 +- pkg/server/defaults.go | 103 +- pkg/server/jobs/service.go | 13 +- pkg/server/jobs/service_test.go | 5 +- pkg/server/log.go | 4 +- pkg/server/providers.go | 142 -- pkg/server/purge.go | 27 +- pkg/server/runners/jobs.go | 19 + pkg/server/runners/provider.go | 62 + pkg/server/runners/register.go | 62 + pkg/server/runners/remove.go | 53 + pkg/server/runners/service.go | 110 ++ pkg/server/server.go | 37 +- pkg/server/targets/create.go | 2 +- pkg/server/targets/get.go | 41 +- pkg/server/targets/list.go | 45 +- pkg/server/targets/metadata.go | 4 +- pkg/server/targets/remove.go | 55 +- pkg/server/targets/service.go | 37 +- pkg/server/targets/service_test.go | 57 +- pkg/server/targets/start.go | 2 +- pkg/server/targets/stop.go | 2 +- pkg/server/types.go | 45 +- pkg/server/workspaces/create.go | 7 +- pkg/server/workspaces/get.go | 47 +- pkg/server/workspaces/list.go | 45 +- pkg/server/workspaces/metadata.go | 4 +- pkg/server/workspaces/remove.go | 84 +- pkg/server/workspaces/service.go | 28 +- pkg/server/workspaces/service_test.go | 93 +- pkg/server/workspaces/start.go | 10 +- pkg/server/workspaces/stop.go | 10 +- pkg/server/workspacetemplates/prebuild.go | 4 +- pkg/services/api_key.go | 3 +- pkg/services/build.go | 2 + pkg/services/job.go | 2 +- pkg/services/runner.go | 62 + pkg/services/target.go | 12 +- pkg/services/workspace.go | 17 +- pkg/stores/job_store.go | 11 +- pkg/stores/runner.go | 27 + pkg/stores/runner_metadata.go | 27 + pkg/stores/target_metadata.go | 7 +- pkg/stores/workspace_metadata.go | 7 +- pkg/telemetry/constants.go | 1 + pkg/telemetry/telemetry.go | 1 + pkg/views/logs/display.go | 42 +- pkg/views/provider/list.go | 18 +- pkg/views/provider/select.go | 24 +- pkg/views/provider/view.go | 13 +- pkg/views/runner/config.go | 48 + pkg/views/runner/configure.go | 200 +++ pkg/views/server/config.go | 4 +- pkg/views/server/configure.go | 8 +- pkg/views/server/runner/info/view.go | 70 + pkg/views/server/runner/list/view.go | 65 + pkg/views/server/runner/notify.go | 32 + pkg/views/server/runner/register.go | 33 + pkg/views/server/runner/selection/select.go | 48 + pkg/views/server/runner/selection/view.go | 66 + pkg/views/target/info/view.go | 6 +- pkg/views/target/list/view.go | 42 +- pkg/views/target/selection/view.go | 10 +- pkg/views/targetconfig/list.go | 21 +- pkg/views/targetconfig/select.go | 37 +- pkg/views/targetconfig/set.go | 13 + pkg/views/targetconfig/view.go | 5 + pkg/views/util/empty_list.go | 9 +- pkg/views/workspace/info/multi.go | 2 +- pkg/views/workspace/info/view.go | 5 +- pkg/views/workspace/list/view.go | 23 +- pkg/views/workspace/selection/workspace.go | 13 +- 385 files changed, 16648 insertions(+), 6705 deletions(-) create mode 100644 docs/daytona_runner.md create mode 100644 docs/daytona_runner_config.md create mode 100644 docs/daytona_runner_configure.md create mode 100644 docs/daytona_runner_logs.md create mode 100644 docs/daytona_runner_purge.md create mode 100644 docs/daytona_runner_restart.md create mode 100644 docs/daytona_runner_serve.md create mode 100644 docs/daytona_runner_start.md create mode 100644 docs/daytona_runner_stop.md create mode 100644 docs/daytona_server_runner.md create mode 100644 docs/daytona_server_runner_list.md create mode 100644 docs/daytona_server_runner_logs.md create mode 100644 docs/daytona_server_runner_register.md create mode 100644 docs/daytona_server_runner_unregister.md create mode 100644 hack/docs/daytona_runner.yaml create mode 100644 hack/docs/daytona_runner_config.yaml create mode 100644 hack/docs/daytona_runner_configure.yaml create mode 100644 hack/docs/daytona_runner_logs.yaml create mode 100644 hack/docs/daytona_runner_purge.yaml create mode 100644 hack/docs/daytona_runner_restart.yaml create mode 100644 hack/docs/daytona_runner_serve.yaml create mode 100644 hack/docs/daytona_runner_start.yaml create mode 100644 hack/docs/daytona_runner_stop.yaml create mode 100644 hack/docs/daytona_server_runner.yaml create mode 100644 hack/docs/daytona_server_runner_list.yaml create mode 100644 hack/docs/daytona_server_runner_logs.yaml create mode 100644 hack/docs/daytona_server_runner_register.yaml create mode 100644 hack/docs/daytona_server_runner_unregister.yaml delete mode 100644 internal/testing/server/targets/mocks/provisioner.go create mode 100644 internal/util/apiclient/conversion/conversion.go create mode 100644 internal/util/apiclient/conversion/provider.go delete mode 100644 internal/util/apiclient/conversion/workspace.go create mode 100644 internal/util/config.go create mode 100644 internal/util/log_formatter.go rename pkg/provider/manager/manifest.go => internal/util/providermanifest.go (80%) rename internal/util/{apiclient => }/websocket_conn.go (57%) delete mode 100644 pkg/agent/log.go create mode 100644 pkg/api/controllers/build/create.go rename pkg/api/controllers/build/{build.go => delete.go} (61%) create mode 100644 pkg/api/controllers/build/get.go create mode 100644 pkg/api/controllers/build/list.go rename pkg/api/controllers/log/{websocket.go => read.go} (78%) create mode 100644 pkg/api/controllers/log/write.go delete mode 100644 pkg/api/controllers/provider/install.go delete mode 100644 pkg/api/controllers/provider/list.go delete mode 100644 pkg/api/controllers/provider/target_config.go create mode 100644 pkg/api/controllers/runner/dto/dto.go create mode 100644 pkg/api/controllers/runner/get.go create mode 100644 pkg/api/controllers/runner/jobs.go create mode 100644 pkg/api/controllers/runner/list.go create mode 100644 pkg/api/controllers/runner/metadata.go rename pkg/api/controllers/{ => runner}/provider/dto/dto.go (100%) create mode 100644 pkg/api/controllers/runner/provider/install.go create mode 100644 pkg/api/controllers/runner/provider/list.go rename pkg/api/controllers/{ => runner}/provider/uninstall.go (53%) create mode 100644 pkg/api/controllers/runner/provider/update.go create mode 100644 pkg/api/controllers/runner/register.go create mode 100644 pkg/api/controllers/runner/remove.go create mode 100644 pkg/api/middlewares/runner.go create mode 100644 pkg/apiclient/api_runner.go rename pkg/apiclient/docs/{InstallProviderRequest.md => InstallProviderDTO.md} (62%) rename pkg/apiclient/docs/{ProviderTargetConfigPropertyType.md => ModelsTargetConfigPropertyType.md} (93%) delete mode 100644 pkg/apiclient/docs/Provider.md create mode 100644 pkg/apiclient/docs/ProviderInfo.md create mode 100644 pkg/apiclient/docs/RegisterRunnerDTO.md create mode 100644 pkg/apiclient/docs/RegisterRunnerResultDTO.md create mode 100644 pkg/apiclient/docs/RunnerAPI.md create mode 100644 pkg/apiclient/docs/RunnerDTO.md create mode 100644 pkg/apiclient/docs/RunnerMetadata.md delete mode 100644 pkg/apiclient/docs/TargetInfo.md delete mode 100644 pkg/apiclient/docs/TargetProviderInfo.md create mode 100644 pkg/apiclient/docs/UpdateJobState.md create mode 100644 pkg/apiclient/docs/UpdateRunnerMetadataDTO.md rename pkg/apiclient/docs/{SetTargetMetadata.md => UpdateTargetMetadataDTO.md} (62%) create mode 100644 pkg/apiclient/docs/UpdateTargetProviderMetadataDTO.md rename pkg/apiclient/docs/{SetWorkspaceMetadata.md => UpdateWorkspaceMetadataDTO.md} (62%) create mode 100644 pkg/apiclient/docs/UpdateWorkspaceProviderMetadataDTO.md delete mode 100644 pkg/apiclient/docs/WorkspaceInfo.md rename pkg/apiclient/{model_install_provider_request.go => model_install_provider_dto.go} (56%) create mode 100644 pkg/apiclient/model_models_target_config_property_type.go delete mode 100644 pkg/apiclient/model_provider.go create mode 100644 pkg/apiclient/model_provider_info.go delete mode 100644 pkg/apiclient/model_provider_target_config_property_type.go create mode 100644 pkg/apiclient/model_register_runner_dto.go create mode 100644 pkg/apiclient/model_register_runner_result_dto.go create mode 100644 pkg/apiclient/model_runner_dto.go create mode 100644 pkg/apiclient/model_runner_metadata.go delete mode 100644 pkg/apiclient/model_target_info.go delete mode 100644 pkg/apiclient/model_target_provider_info.go create mode 100644 pkg/apiclient/model_update_job_state.go create mode 100644 pkg/apiclient/model_update_runner_metadata_dto.go rename pkg/apiclient/{model_set_target_metadata.go => model_update_target_metadata_dto.go} (53%) create mode 100644 pkg/apiclient/model_update_target_provider_metadata_dto.go rename pkg/apiclient/{model_set_workspace_metadata.go => model_update_workspace_metadata_dto.go} (56%) create mode 100644 pkg/apiclient/model_update_workspace_provider_metadata_dto.go delete mode 100644 pkg/apiclient/model_workspace_info.go delete mode 100644 pkg/build/logs.go create mode 100644 pkg/cmd/bootstrap/get_local_runner.go create mode 100644 pkg/cmd/bootstrap/get_remote_runner.go rename pkg/cmd/{server => }/bootstrap/get_server_instance.go (84%) rename pkg/cmd/{server => common}/daemon/daemon.go (86%) create mode 100644 pkg/cmd/common/get_runner.go rename {internal/util/apiclient => pkg/cmd/common}/websocket_log_reader.go (70%) create mode 100644 pkg/cmd/runner/config.go create mode 100644 pkg/cmd/runner/configure.go create mode 100644 pkg/cmd/runner/logs.go create mode 100644 pkg/cmd/runner/purge.go create mode 100644 pkg/cmd/runner/restart.go create mode 100644 pkg/cmd/runner/runner.go create mode 100644 pkg/cmd/runner/serve.go create mode 100644 pkg/cmd/runner/start.go create mode 100644 pkg/cmd/runner/stop.go delete mode 100644 pkg/cmd/server/bootstrap/get_job_runner.go delete mode 100644 pkg/cmd/server/bootstrap/init_provider_manager.go create mode 100644 pkg/cmd/server/runner/list.go create mode 100644 pkg/cmd/server/runner/logs.go create mode 100644 pkg/cmd/server/runner/register.go create mode 100644 pkg/cmd/server/runner/runner.go create mode 100644 pkg/cmd/server/runner/unregister.go create mode 100644 pkg/db/runner_metadata_store.go create mode 100644 pkg/db/runner_store.go delete mode 100644 pkg/docker/info.go delete mode 100644 pkg/docker/info_test.go create mode 100644 pkg/docker/metadata.go create mode 100644 pkg/docker/metadata_test.go create mode 100644 pkg/jobs/runner/factory.go create mode 100644 pkg/jobs/runner/install.go create mode 100644 pkg/jobs/runner/runner.go create mode 100644 pkg/jobs/runner/uninstall.go create mode 100644 pkg/jobs/runner/update.go delete mode 100644 pkg/logs/build.go create mode 100644 pkg/logs/factory.go rename {internal/util => pkg/logs}/log_reader.go (88%) create mode 100644 pkg/logs/remote_factory.go create mode 100644 pkg/logs/remote_logger.go delete mode 100644 pkg/logs/target.go create mode 100644 pkg/logs/types.go delete mode 100644 pkg/logs/workspace.go create mode 100644 pkg/models/provider_info.go create mode 100644 pkg/models/runner.go delete mode 100644 pkg/provisioner/create.go delete mode 100644 pkg/provisioner/destroy.go delete mode 100644 pkg/provisioner/info.go delete mode 100644 pkg/provisioner/provisioner.go delete mode 100644 pkg/provisioner/start.go delete mode 100644 pkg/provisioner/stop.go create mode 100644 pkg/runner/config.go rename pkg/{provider/manager => runner/providermanager}/error.go (95%) rename pkg/{provider/manager => runner/providermanager}/installer.go (51%) rename pkg/{provider/manager => runner/providermanager}/manager.go (73%) create mode 100644 pkg/runner/providers.go create mode 100644 pkg/runner/runner.go delete mode 100644 pkg/runners/runner.go delete mode 100644 pkg/runners/runner/runner.go delete mode 100644 pkg/server/providers.go create mode 100644 pkg/server/runners/jobs.go create mode 100644 pkg/server/runners/provider.go create mode 100644 pkg/server/runners/register.go create mode 100644 pkg/server/runners/remove.go create mode 100644 pkg/server/runners/service.go create mode 100644 pkg/services/runner.go create mode 100644 pkg/stores/runner.go create mode 100644 pkg/stores/runner_metadata.go create mode 100644 pkg/views/runner/config.go create mode 100644 pkg/views/runner/configure.go create mode 100644 pkg/views/server/runner/info/view.go create mode 100644 pkg/views/server/runner/list/view.go create mode 100644 pkg/views/server/runner/notify.go create mode 100644 pkg/views/server/runner/register.go create mode 100644 pkg/views/server/runner/selection/select.go create mode 100644 pkg/views/server/runner/selection/view.go diff --git a/.vscode/launch.json b/.vscode/launch.json index db5687dc81..127c27de76 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -50,6 +50,22 @@ "DAYTONA_DEV": "1", "DAYTONA_CONFIG_DIR": "/home/daytona/.config/daytona-dev", } + }, + { + "name": "Runner", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "${workspaceFolder}/cmd/daytona", + "console": "integratedTerminal", + "args": [ + "runner", + "serve" + ], + "env": { + "DAYTONA_DEV": "1", + "DAYTONA_RUNNER_CONFIG_DIR": "/home/daytona/.config/daytona-runner", + } } ] } \ No newline at end of file diff --git a/docs/agent_mode/daytona_list.md b/docs/agent_mode/daytona_list.md index ea33021b05..0e9b916eb5 100644 --- a/docs/agent_mode/daytona_list.md +++ b/docs/agent_mode/daytona_list.md @@ -10,7 +10,6 @@ daytona list [flags] ``` -f, --format string Output format. Must be one of (yaml, json) - -v, --verbose Show verbose output ``` ### Options inherited from parent commands diff --git a/docs/daytona.md b/docs/daytona.md index 60fa9ba34b..69ca60b99d 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -39,6 +39,7 @@ daytona [flags] * [daytona provider](daytona_provider.md) - Manage providers * [daytona purge](daytona_purge.md) - Purges all Daytona data from the current device * [daytona restart](daytona_restart.md) - Restart a workspace +* [daytona runner](daytona_runner.md) - Manage the runner * [daytona serve](daytona_serve.md) - Run the server process in the current terminal session * [daytona server](daytona_server.md) - Start the server process in daemon mode * [daytona ssh](daytona_ssh.md) - SSH into a workspace using the terminal diff --git a/docs/daytona_list.md b/docs/daytona_list.md index ea33021b05..0e9b916eb5 100644 --- a/docs/daytona_list.md +++ b/docs/daytona_list.md @@ -10,7 +10,6 @@ daytona list [flags] ``` -f, --format string Output format. Must be one of (yaml, json) - -v, --verbose Show verbose output ``` ### Options inherited from parent commands diff --git a/docs/daytona_runner.md b/docs/daytona_runner.md new file mode 100644 index 0000000000..b3249e5b74 --- /dev/null +++ b/docs/daytona_runner.md @@ -0,0 +1,22 @@ +## daytona runner + +Manage the runner + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona runner config](daytona_runner_config.md) - Outputs Daytona Runner config +* [daytona runner configure](daytona_runner_configure.md) - Configure Daytona Runner +* [daytona runner logs](daytona_runner_logs.md) - View runner logs +* [daytona runner purge](daytona_runner_purge.md) - Purges the runner +* [daytona runner restart](daytona_runner_restart.md) - Restarts the runner +* [daytona runner serve](daytona_runner_serve.md) - Starts the runner in the foreground +* [daytona runner start](daytona_runner_start.md) - Starts the runner +* [daytona runner stop](daytona_runner_stop.md) - Stops the runner + diff --git a/docs/daytona_runner_config.md b/docs/daytona_runner_config.md new file mode 100644 index 0000000000..95ba355f15 --- /dev/null +++ b/docs/daytona_runner_config.md @@ -0,0 +1,25 @@ +## daytona runner config + +Outputs Daytona Runner config + +``` +daytona runner config [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) + -k, --key Show API Key +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_configure.md b/docs/daytona_runner_configure.md new file mode 100644 index 0000000000..e32c5f592e --- /dev/null +++ b/docs/daytona_runner_configure.md @@ -0,0 +1,27 @@ +## daytona runner configure + +Configure Daytona Runner + +``` +daytona runner configure [flags] +``` + +### Options + +``` + --api-key string Runner API Key + --api-url string Daytona Server API URL + --id string Runner ID + --name string Runner Name +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_logs.md b/docs/daytona_runner_logs.md new file mode 100644 index 0000000000..5c357d7578 --- /dev/null +++ b/docs/daytona_runner_logs.md @@ -0,0 +1,24 @@ +## daytona runner logs + +View runner logs + +``` +daytona runner logs [flags] +``` + +### Options + +``` + -f, --follow Follow logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_purge.md b/docs/daytona_runner_purge.md new file mode 100644 index 0000000000..8a3d980009 --- /dev/null +++ b/docs/daytona_runner_purge.md @@ -0,0 +1,18 @@ +## daytona runner purge + +Purges the runner + +``` +daytona runner purge [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_restart.md b/docs/daytona_runner_restart.md new file mode 100644 index 0000000000..25274c3682 --- /dev/null +++ b/docs/daytona_runner_restart.md @@ -0,0 +1,18 @@ +## daytona runner restart + +Restarts the runner + +``` +daytona runner restart [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_serve.md b/docs/daytona_runner_serve.md new file mode 100644 index 0000000000..42f9d6ea26 --- /dev/null +++ b/docs/daytona_runner_serve.md @@ -0,0 +1,18 @@ +## daytona runner serve + +Starts the runner in the foreground + +``` +daytona runner serve [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_start.md b/docs/daytona_runner_start.md new file mode 100644 index 0000000000..3cbe65bcc8 --- /dev/null +++ b/docs/daytona_runner_start.md @@ -0,0 +1,18 @@ +## daytona runner start + +Starts the runner + +``` +daytona runner start [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_runner_stop.md b/docs/daytona_runner_stop.md new file mode 100644 index 0000000000..3a5aeba7fc --- /dev/null +++ b/docs/daytona_runner_stop.md @@ -0,0 +1,18 @@ +## daytona runner stop + +Stops the runner + +``` +daytona runner stop [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona runner](daytona_runner.md) - Manage the runner + diff --git a/docs/daytona_server.md b/docs/daytona_server.md index bffb71a5e9..01c5ec5a19 100644 --- a/docs/daytona_server.md +++ b/docs/daytona_server.md @@ -25,6 +25,7 @@ daytona server [flags] * [daytona server configure](daytona_server_configure.md) - Configure Daytona Server * [daytona server logs](daytona_server_logs.md) - Output Daytona Server logs * [daytona server restart](daytona_server_restart.md) - Restarts the Daytona Server daemon +* [daytona server runner](daytona_server_runner.md) - Manage runners * [daytona server start](daytona_server_start.md) - Start the Daytona Server daemon * [daytona server stop](daytona_server_stop.md) - Stops the Daytona Server daemon diff --git a/docs/daytona_server_runner.md b/docs/daytona_server_runner.md new file mode 100644 index 0000000000..61c965e02d --- /dev/null +++ b/docs/daytona_server_runner.md @@ -0,0 +1,18 @@ +## daytona server runner + +Manage runners + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server](daytona_server.md) - Start the server process in daemon mode +* [daytona server runner list](daytona_server_runner_list.md) - List runners +* [daytona server runner logs](daytona_server_runner_logs.md) - View runner logs +* [daytona server runner register](daytona_server_runner_register.md) - Register runner +* [daytona server runner unregister](daytona_server_runner_unregister.md) - Unregister runner + diff --git a/docs/daytona_server_runner_list.md b/docs/daytona_server_runner_list.md new file mode 100644 index 0000000000..eea0953595 --- /dev/null +++ b/docs/daytona_server_runner_list.md @@ -0,0 +1,24 @@ +## daytona server runner list + +List runners + +``` +daytona server runner list [flags] +``` + +### Options + +``` + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server runner](daytona_server_runner.md) - Manage runners + diff --git a/docs/daytona_server_runner_logs.md b/docs/daytona_server_runner_logs.md new file mode 100644 index 0000000000..3ac3c06e45 --- /dev/null +++ b/docs/daytona_server_runner_logs.md @@ -0,0 +1,24 @@ +## daytona server runner logs + +View runner logs + +``` +daytona server runner logs [RUNNER_ID] [flags] +``` + +### Options + +``` + -f, --follow Follow logs +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server runner](daytona_server_runner.md) - Manage runners + diff --git a/docs/daytona_server_runner_register.md b/docs/daytona_server_runner_register.md new file mode 100644 index 0000000000..ab1ec737b7 --- /dev/null +++ b/docs/daytona_server_runner_register.md @@ -0,0 +1,24 @@ +## daytona server runner register + +Register runner + +``` +daytona server runner register [flags] +``` + +### Options + +``` + -n, --name string Runner name +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server runner](daytona_server_runner.md) - Manage runners + diff --git a/docs/daytona_server_runner_unregister.md b/docs/daytona_server_runner_unregister.md new file mode 100644 index 0000000000..66f10cce53 --- /dev/null +++ b/docs/daytona_server_runner_unregister.md @@ -0,0 +1,24 @@ +## daytona server runner unregister + +Unregister runner + +``` +daytona server runner unregister [RUNNER] [flags] +``` + +### Options + +``` + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona server runner](daytona_server_runner.md) - Manage runners + diff --git a/docs/daytona_target-config_list.md b/docs/daytona_target-config_list.md index b14c9641fd..7eb1d87777 100644 --- a/docs/daytona_target-config_list.md +++ b/docs/daytona_target-config_list.md @@ -10,6 +10,7 @@ daytona target-config list [flags] ``` -f, --format string Output format. Must be one of (yaml, json) + -v, --show-options Show target options ``` ### Options inherited from parent commands diff --git a/docs/daytona_target_info.md b/docs/daytona_target_info.md index 4a6f443995..911d8c7126 100644 --- a/docs/daytona_target_info.md +++ b/docs/daytona_target_info.md @@ -10,6 +10,7 @@ daytona target info [TARGET] [flags] ``` -f, --format string Output format. Must be one of (yaml, json) + -v, --show-options Show target options ``` ### Options inherited from parent commands diff --git a/docs/daytona_target_list.md b/docs/daytona_target_list.md index d14e23a888..7a88340dc5 100644 --- a/docs/daytona_target_list.md +++ b/docs/daytona_target_list.md @@ -10,7 +10,7 @@ daytona target list [flags] ``` -f, --format string Output format. Must be one of (yaml, json) - -v, --verbose Show verbose output + -v, --show-options Show target options ``` ### Options inherited from parent commands diff --git a/go.mod b/go.mod index fa397b18eb..d52446c12a 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/go-git/go-git/v5 v5.12.1-0.20240617075238-c127d1b35535 github.com/go-playground/validator/v10 v10.19.0 github.com/go-playground/webhooks/v6 v6.4.0 + github.com/goccy/go-json v0.10.2 github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 @@ -149,7 +150,6 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-viper/mapstructure/v2 v2.1.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect github.com/gofrs/uuid/v5 v5.3.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/hack/docs/agent_mode/daytona_list.yaml b/hack/docs/agent_mode/daytona_list.yaml index e4efaaea82..66e58fe21b 100644 --- a/hack/docs/agent_mode/daytona_list.yaml +++ b/hack/docs/agent_mode/daytona_list.yaml @@ -5,10 +5,6 @@ options: - name: format shorthand: f usage: Output format. Must be one of (yaml, json) - - name: verbose - shorthand: v - default_value: "false" - usage: Show verbose output inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 7e56e486ad..8829e81c59 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -31,6 +31,7 @@ see_also: - daytona provider - Manage providers - daytona purge - Purges all Daytona data from the current device - daytona restart - Restart a workspace + - daytona runner - Manage the runner - daytona serve - Run the server process in the current terminal session - daytona server - Start the server process in daemon mode - daytona ssh - SSH into a workspace using the terminal diff --git a/hack/docs/daytona_list.yaml b/hack/docs/daytona_list.yaml index e4efaaea82..66e58fe21b 100644 --- a/hack/docs/daytona_list.yaml +++ b/hack/docs/daytona_list.yaml @@ -5,10 +5,6 @@ options: - name: format shorthand: f usage: Output format. Must be one of (yaml, json) - - name: verbose - shorthand: v - default_value: "false" - usage: Show verbose output inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_runner.yaml b/hack/docs/daytona_runner.yaml new file mode 100644 index 0000000000..c4b9db1b6c --- /dev/null +++ b/hack/docs/daytona_runner.yaml @@ -0,0 +1,16 @@ +name: daytona runner +synopsis: Manage the runner +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona runner config - Outputs Daytona Runner config + - daytona runner configure - Configure Daytona Runner + - daytona runner logs - View runner logs + - daytona runner purge - Purges the runner + - daytona runner restart - Restarts the runner + - daytona runner serve - Starts the runner in the foreground + - daytona runner start - Starts the runner + - daytona runner stop - Stops the runner diff --git a/hack/docs/daytona_runner_config.yaml b/hack/docs/daytona_runner_config.yaml new file mode 100644 index 0000000000..b417336250 --- /dev/null +++ b/hack/docs/daytona_runner_config.yaml @@ -0,0 +1,17 @@ +name: daytona runner config +synopsis: Outputs Daytona Runner config +usage: daytona runner config [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) + - name: key + shorthand: k + default_value: "false" + usage: Show API Key +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_configure.yaml b/hack/docs/daytona_runner_configure.yaml new file mode 100644 index 0000000000..4e09afb182 --- /dev/null +++ b/hack/docs/daytona_runner_configure.yaml @@ -0,0 +1,18 @@ +name: daytona runner configure +synopsis: Configure Daytona Runner +usage: daytona runner configure [flags] +options: + - name: api-key + usage: Runner API Key + - name: api-url + usage: Daytona Server API URL + - name: id + usage: Runner ID + - name: name + usage: Runner Name +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_logs.yaml b/hack/docs/daytona_runner_logs.yaml new file mode 100644 index 0000000000..69e7d65072 --- /dev/null +++ b/hack/docs/daytona_runner_logs.yaml @@ -0,0 +1,14 @@ +name: daytona runner logs +synopsis: View runner logs +usage: daytona runner logs [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_purge.yaml b/hack/docs/daytona_runner_purge.yaml new file mode 100644 index 0000000000..67596d919d --- /dev/null +++ b/hack/docs/daytona_runner_purge.yaml @@ -0,0 +1,9 @@ +name: daytona runner purge +synopsis: Purges the runner +usage: daytona runner purge [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_restart.yaml b/hack/docs/daytona_runner_restart.yaml new file mode 100644 index 0000000000..b788c67085 --- /dev/null +++ b/hack/docs/daytona_runner_restart.yaml @@ -0,0 +1,9 @@ +name: daytona runner restart +synopsis: Restarts the runner +usage: daytona runner restart [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_serve.yaml b/hack/docs/daytona_runner_serve.yaml new file mode 100644 index 0000000000..8f2bc20ada --- /dev/null +++ b/hack/docs/daytona_runner_serve.yaml @@ -0,0 +1,9 @@ +name: daytona runner serve +synopsis: Starts the runner in the foreground +usage: daytona runner serve [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_start.yaml b/hack/docs/daytona_runner_start.yaml new file mode 100644 index 0000000000..6ada5f90d1 --- /dev/null +++ b/hack/docs/daytona_runner_start.yaml @@ -0,0 +1,9 @@ +name: daytona runner start +synopsis: Starts the runner +usage: daytona runner start [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_runner_stop.yaml b/hack/docs/daytona_runner_stop.yaml new file mode 100644 index 0000000000..d8e0d3fed8 --- /dev/null +++ b/hack/docs/daytona_runner_stop.yaml @@ -0,0 +1,9 @@ +name: daytona runner stop +synopsis: Stops the runner +usage: daytona runner stop [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona runner - Manage the runner diff --git a/hack/docs/daytona_server.yaml b/hack/docs/daytona_server.yaml index 6f19f3150f..a0fa4433c4 100644 --- a/hack/docs/daytona_server.yaml +++ b/hack/docs/daytona_server.yaml @@ -16,5 +16,6 @@ see_also: - daytona server configure - Configure Daytona Server - daytona server logs - Output Daytona Server logs - daytona server restart - Restarts the Daytona Server daemon + - daytona server runner - Manage runners - daytona server start - Start the Daytona Server daemon - daytona server stop - Stops the Daytona Server daemon diff --git a/hack/docs/daytona_server_runner.yaml b/hack/docs/daytona_server_runner.yaml new file mode 100644 index 0000000000..5bd530e25d --- /dev/null +++ b/hack/docs/daytona_server_runner.yaml @@ -0,0 +1,12 @@ +name: daytona server runner +synopsis: Manage runners +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server - Start the server process in daemon mode + - daytona server runner list - List runners + - daytona server runner logs - View runner logs + - daytona server runner register - Register runner + - daytona server runner unregister - Unregister runner diff --git a/hack/docs/daytona_server_runner_list.yaml b/hack/docs/daytona_server_runner_list.yaml new file mode 100644 index 0000000000..ee0dcf3d08 --- /dev/null +++ b/hack/docs/daytona_server_runner_list.yaml @@ -0,0 +1,13 @@ +name: daytona server runner list +synopsis: List runners +usage: daytona server runner list [flags] +options: + - name: format + shorthand: f + usage: Output format. Must be one of (yaml, json) +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server runner - Manage runners diff --git a/hack/docs/daytona_server_runner_logs.yaml b/hack/docs/daytona_server_runner_logs.yaml new file mode 100644 index 0000000000..78f53a7db6 --- /dev/null +++ b/hack/docs/daytona_server_runner_logs.yaml @@ -0,0 +1,14 @@ +name: daytona server runner logs +synopsis: View runner logs +usage: daytona server runner logs [RUNNER_ID] [flags] +options: + - name: follow + shorthand: f + default_value: "false" + usage: Follow logs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server runner - Manage runners diff --git a/hack/docs/daytona_server_runner_register.yaml b/hack/docs/daytona_server_runner_register.yaml new file mode 100644 index 0000000000..34888f1c7e --- /dev/null +++ b/hack/docs/daytona_server_runner_register.yaml @@ -0,0 +1,13 @@ +name: daytona server runner register +synopsis: Register runner +usage: daytona server runner register [flags] +options: + - name: name + shorthand: "n" + usage: Runner name +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server runner - Manage runners diff --git a/hack/docs/daytona_server_runner_unregister.yaml b/hack/docs/daytona_server_runner_unregister.yaml new file mode 100644 index 0000000000..196903503c --- /dev/null +++ b/hack/docs/daytona_server_runner_unregister.yaml @@ -0,0 +1,14 @@ +name: daytona server runner unregister +synopsis: Unregister runner +usage: daytona server runner unregister [RUNNER] [flags] +options: + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Confirm deletion without prompt +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona server runner - Manage runners diff --git a/hack/docs/daytona_target-config_list.yaml b/hack/docs/daytona_target-config_list.yaml index a96c7f7908..e909c29023 100644 --- a/hack/docs/daytona_target-config_list.yaml +++ b/hack/docs/daytona_target-config_list.yaml @@ -5,6 +5,10 @@ options: - name: format shorthand: f usage: Output format. Must be one of (yaml, json) + - name: show-options + shorthand: v + default_value: "false" + usage: Show target options inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_target_info.yaml b/hack/docs/daytona_target_info.yaml index b8305ad0cc..41d83cf4fb 100644 --- a/hack/docs/daytona_target_info.yaml +++ b/hack/docs/daytona_target_info.yaml @@ -5,6 +5,10 @@ options: - name: format shorthand: f usage: Output format. Must be one of (yaml, json) + - name: show-options + shorthand: v + default_value: "false" + usage: Show target options inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_target_list.yaml b/hack/docs/daytona_target_list.yaml index 7837a01f3b..d65a2dd9fd 100644 --- a/hack/docs/daytona_target_list.yaml +++ b/hack/docs/daytona_target_list.yaml @@ -5,10 +5,10 @@ options: - name: format shorthand: f usage: Output format. Must be one of (yaml, json) - - name: verbose + - name: show-options shorthand: v default_value: "false" - usage: Show verbose output + usage: Show target options inherited_options: - name: help default_value: "false" diff --git a/internal/testing/agent/mocks/apiserver.go b/internal/testing/agent/mocks/apiserver.go index 4ef0a85a6f..cfdb2a0b91 100644 --- a/internal/testing/agent/mocks/apiserver.go +++ b/internal/testing/agent/mocks/apiserver.go @@ -21,7 +21,6 @@ func NewMockRestServer(t *testing.T) *httptest.Server { { serverController.GET("/config", func(ctx *gin.Context) { ctx.JSON(200, &server.Config{ - ProvidersDir: "", RegistryUrl: "", Id: "", ServerDownloadUrl: "", diff --git a/internal/testing/docker/mocks/client.go b/internal/testing/docker/mocks/client.go index 0b52a04ae6..a119cb5c38 100644 --- a/internal/testing/docker/mocks/client.go +++ b/internal/testing/docker/mocks/client.go @@ -53,16 +53,6 @@ func (c *MockClient) StopWorkspace(w *models.Workspace) error { return args.Error(0) } -func (c *MockClient) GetWorkspaceInfo(w *models.Workspace) (*models.WorkspaceInfo, error) { - args := c.Called(w) - return args.Get(0).(*models.WorkspaceInfo), args.Error(1) -} - -func (c *MockClient) GetTargetInfo(t *models.Target) (*models.TargetInfo, error) { - args := c.Called(t) - return args.Get(0).(*models.TargetInfo), args.Error(1) -} - func (c *MockClient) GetWorkspaceContainerName(w *models.Workspace) string { args := c.Called(w) return args.String(0) diff --git a/internal/testing/logger/mocks/logger.go b/internal/testing/logger/mocks/logger.go index a61ba56ff3..55b916b731 100644 --- a/internal/testing/logger/mocks/logger.go +++ b/internal/testing/logger/mocks/logger.go @@ -53,6 +53,11 @@ func (m *mockLogger) Write(p []byte) (n int, err error) { return args.Int(0), args.Error(1) } +func (m *mockLogger) ConstructJsonLogEntry(p []byte) ([]byte, error) { + args := m.Called(p) + return args.Get(0).([]byte), args.Error(1) +} + func (m *mockLogger) Close() error { args := m.Called() return args.Error(0) diff --git a/internal/testing/server/targets/metadata_store.go b/internal/testing/server/targets/metadata_store.go index ac7530b95d..e3ad8e6201 100644 --- a/internal/testing/server/targets/metadata_store.go +++ b/internal/testing/server/targets/metadata_store.go @@ -24,16 +24,13 @@ func NewInMemoryTargetMetadataStore() stores.TargetMetadataStore { } } -func (s *InMemoryTargetMetadataStore) Find(ctx context.Context, filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { - metadatas, err := s.processFilters(filter) - if err != nil { - return nil, err - } - if len(metadatas) == 0 { +func (s *InMemoryTargetMetadataStore) Find(ctx context.Context, targetId string) (*models.TargetMetadata, error) { + metadata, ok := s.targetMetadataEntries[targetId] + if !ok { return nil, stores.ErrTargetMetadataNotFound } - return metadatas[0], nil + return metadata, nil } func (s *InMemoryTargetMetadataStore) Save(ctx context.Context, targetMetadata *models.TargetMetadata) error { @@ -45,35 +42,3 @@ func (s *InMemoryTargetMetadataStore) Delete(ctx context.Context, targetMetadata delete(s.targetMetadataEntries, targetMetadata.TargetId) return nil } - -func (s *InMemoryTargetMetadataStore) processFilters(filter *stores.TargetMetadataFilter) ([]*models.TargetMetadata, error) { - var result []*models.TargetMetadata - filteredTargetMetadata := make(map[string]*models.TargetMetadata) - for k, v := range s.targetMetadataEntries { - filteredTargetMetadata[k] = v - } - - if filter != nil { - if filter.Id != nil { - m, ok := s.targetMetadataEntries[*filter.Id] - if ok { - return []*models.TargetMetadata{m}, nil - } else { - return []*models.TargetMetadata{}, nil - } - } - if filter.TargetId != nil { - for _, m := range filteredTargetMetadata { - if m.TargetId != *filter.TargetId { - delete(filteredTargetMetadata, m.TargetId) - } - } - } - } - - for _, m := range filteredTargetMetadata { - result = append(result, m) - } - - return result, nil -} diff --git a/internal/testing/server/targets/mocks/builder.go b/internal/testing/server/targets/mocks/builder.go index 4f566c174a..baff40d775 100644 --- a/internal/testing/server/targets/mocks/builder.go +++ b/internal/testing/server/targets/mocks/builder.go @@ -39,11 +39,6 @@ func (f *MockBuilderFactory) Create(build models.Build, workspaceDir string) (bu return args.Get(0).(*MockBuilder), args.Error(1) } -func (f *MockBuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, error) { - args := f.Called(b) - return args.Get(0).(*models.Build), args.Error(1) -} - type MockBuilder struct { mock.Mock } diff --git a/internal/testing/server/targets/mocks/provisioner.go b/internal/testing/server/targets/mocks/provisioner.go deleted file mode 100644 index c227cc21c4..0000000000 --- a/internal/testing/server/targets/mocks/provisioner.go +++ /dev/null @@ -1,72 +0,0 @@ -//go:build testing - -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package mocks - -import ( - "context" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/stretchr/testify/mock" -) - -type mockProvisioner struct { - mock.Mock -} - -func NewMockProvisioner() *mockProvisioner { - return &mockProvisioner{} -} - -func (p *mockProvisioner) CreateWorkspace(params provisioner.WorkspaceParams) error { - args := p.Called(params) - return args.Error(0) -} - -func (p *mockProvisioner) CreateTarget(t *models.Target) error { - args := p.Called(t) - return args.Error(0) -} - -func (p *mockProvisioner) DestroyWorkspace(ws *models.Workspace) error { - args := p.Called(ws) - return args.Error(0) -} - -func (p *mockProvisioner) DestroyTarget(t *models.Target) error { - args := p.Called(t) - return args.Error(0) -} - -func (p *mockProvisioner) GetTargetInfo(ctx context.Context, t *models.Target) (*models.TargetInfo, error) { - args := p.Called(ctx, t) - return args.Get(0).(*models.TargetInfo), args.Error(1) -} - -func (p *mockProvisioner) StartWorkspace(params provisioner.WorkspaceParams) error { - args := p.Called(params) - return args.Error(0) -} - -func (p *mockProvisioner) StartTarget(t *models.Target) error { - args := p.Called(t) - return args.Error(0) -} - -func (p *mockProvisioner) StopWorkspace(ws *models.Workspace) error { - args := p.Called(ws) - return args.Error(0) -} - -func (p *mockProvisioner) StopTarget(t *models.Target) error { - args := p.Called(t) - return args.Error(0) -} - -func (p *mockProvisioner) GetWorkspaceInfo(ctx context.Context, w *models.Workspace) (*models.WorkspaceInfo, error) { - args := p.Called(ctx, w) - return args.Get(0).(*models.WorkspaceInfo), args.Error(1) -} diff --git a/internal/testing/server/workspaces/metadata_store.go b/internal/testing/server/workspaces/metadata_store.go index 57b18df675..12844edd44 100644 --- a/internal/testing/server/workspaces/metadata_store.go +++ b/internal/testing/server/workspaces/metadata_store.go @@ -24,16 +24,12 @@ func NewInMemoryWorkspaceMetadataStore() stores.WorkspaceMetadataStore { } } -func (s *InMemoryWorkspaceMetadataStore) Find(ctx context.Context, filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { - metadatas, err := s.processFilters(filter) - if err != nil { - return nil, err - } - if len(metadatas) == 0 { +func (s *InMemoryWorkspaceMetadataStore) Find(ctx context.Context, workspaceId string) (*models.WorkspaceMetadata, error) { + if _, ok := s.workspaceMetadataEntries[workspaceId]; !ok { return nil, stores.ErrWorkspaceMetadataNotFound } - return metadatas[0], nil + return s.workspaceMetadataEntries[workspaceId], nil } func (s *InMemoryWorkspaceMetadataStore) Save(ctx context.Context, workspaceMetadata *models.WorkspaceMetadata) error { @@ -45,35 +41,3 @@ func (s *InMemoryWorkspaceMetadataStore) Delete(ctx context.Context, workspaceMe delete(s.workspaceMetadataEntries, workspaceMetadata.WorkspaceId) return nil } - -func (s *InMemoryWorkspaceMetadataStore) processFilters(filter *stores.WorkspaceMetadataFilter) ([]*models.WorkspaceMetadata, error) { - var result []*models.WorkspaceMetadata - filteredWorkspaceMetadata := make(map[string]*models.WorkspaceMetadata) - for k, v := range s.workspaceMetadataEntries { - filteredWorkspaceMetadata[k] = v - } - - if filter != nil { - if filter.Id != nil { - m, ok := s.workspaceMetadataEntries[*filter.Id] - if ok { - return []*models.WorkspaceMetadata{m}, nil - } else { - return []*models.WorkspaceMetadata{}, nil - } - } - if filter.WorkspaceId != nil { - for _, m := range filteredWorkspaceMetadata { - if m.WorkspaceId != *filter.WorkspaceId { - delete(filteredWorkspaceMetadata, m.WorkspaceId) - } - } - } - } - - for _, m := range filteredWorkspaceMetadata { - result = append(result, m) - } - - return result, nil -} diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index 9456cbf02e..730338ff60 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -87,6 +87,33 @@ func GetApiClient(profile *config.Profile) (*apiclient.APIClient, error) { return apiClient, nil } +func GetRunnerApiClient(apiUrl, apiKey, clientId string, telemetryEnabled bool) (*apiclient.APIClient, error) { + clientConfig := apiclient.NewConfiguration() + clientConfig.Servers = apiclient.ServerConfigurations{ + { + URL: apiUrl, + }, + } + + clientConfig.AddDefaultHeader("Authorization", fmt.Sprintf("Bearer %s", apiKey)) + clientConfig.AddDefaultHeader(CLIENT_VERSION_HEADER, internal.Version) + + if telemetryEnabled { + clientConfig.AddDefaultHeader(telemetry.ENABLED_HEADER, "true") + clientConfig.AddDefaultHeader(telemetry.SESSION_ID_HEADER, internal.SESSION_ID) + clientConfig.AddDefaultHeader(telemetry.CLIENT_ID_HEADER, clientId) + clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.RUNNER_SOURCE)) + } + + apiClient = apiclient.NewAPIClient(clientConfig) + + apiClient.GetConfig().HTTPClient = &http.Client{ + Transport: http.DefaultTransport, + } + + return apiClient, nil +} + func GetAgentApiClient(apiUrl, apiKey, clientId string, telemetryEnabled bool) (*apiclient.APIClient, error) { clientConfig := apiclient.NewConfiguration() clientConfig.Servers = apiclient.ServerConfigurations{ @@ -114,7 +141,7 @@ func GetAgentApiClient(apiUrl, apiKey, clientId string, telemetryEnabled bool) ( return apiClient, nil } -func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, int, error) { +func GetTarget(targetNameOrId string) (*apiclient.TargetDTO, int, error) { ctx := context.Background() apiClient, err := GetApiClient(nil) @@ -122,7 +149,7 @@ func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, int, return nil, -1, err } - target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetNameOrId).Verbose(verbose).Execute() + target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetNameOrId).Execute() if err != nil { return nil, res.StatusCode, HandleErrorResponse(res, err) } @@ -130,7 +157,7 @@ func GetTarget(targetNameOrId string, verbose bool) (*apiclient.TargetDTO, int, return target, res.StatusCode, nil } -func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceDTO, int, error) { +func GetWorkspace(workspaceNameOrId string) (*apiclient.WorkspaceDTO, int, error) { ctx := context.Background() apiClient, err := GetApiClient(nil) @@ -138,7 +165,7 @@ func GetWorkspace(workspaceNameOrId string, verbose bool) (*apiclient.WorkspaceD return nil, -1, err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceNameOrId).Verbose(verbose).Execute() + workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceNameOrId).Execute() if err != nil { return nil, res.StatusCode, HandleErrorResponse(res, err) } diff --git a/internal/util/apiclient/conversion/conversion.go b/internal/util/apiclient/conversion/conversion.go new file mode 100644 index 0000000000..3c37079563 --- /dev/null +++ b/internal/util/apiclient/conversion/conversion.go @@ -0,0 +1,26 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package conversion + +import ( + "encoding/json" +) + +func Convert[F any, T any](from *F) (*T, error) { + if from == nil { + return nil, nil + } + + fromBytes, err := json.Marshal(from) + if err != nil { + return nil, err + } + + var to T + err = json.Unmarshal(fromBytes, &to) + if err != nil { + return nil, err + } + return &to, nil +} diff --git a/internal/util/apiclient/conversion/provider.go b/internal/util/apiclient/conversion/provider.go new file mode 100644 index 0000000000..d8f6014a50 --- /dev/null +++ b/internal/util/apiclient/conversion/provider.go @@ -0,0 +1,31 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package conversion + +import ( + "slices" + "strings" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/apiclient" +) + +func GetProviderListFromManifest(manifest *util.ProvidersManifest) []apiclient.ProviderInfo { + providerList := []apiclient.ProviderInfo{} + for providerName, providerManifest := range *manifest { + for version := range providerManifest.Versions { + providerList = append(providerList, apiclient.ProviderInfo{ + Name: providerName, + Label: providerManifest.Label, + Version: version, + }) + } + } + + slices.SortFunc(providerList, func(a, b apiclient.ProviderInfo) int { + return strings.Compare(a.Name, b.Name) + }) + + return providerList +} diff --git a/internal/util/apiclient/conversion/workspace.go b/internal/util/apiclient/conversion/workspace.go deleted file mode 100644 index d5b6362f58..0000000000 --- a/internal/util/apiclient/conversion/workspace.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package conversion - -import ( - "time" - - "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/gitprovider" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/services" -) - -func ToWorkspace(workspaceDTO *apiclient.WorkspaceDTO) *models.Workspace { - if workspaceDTO == nil { - return nil - } - - repository := &gitprovider.GitRepository{ - Id: workspaceDTO.Repository.Id, - Name: workspaceDTO.Repository.Name, - Branch: workspaceDTO.Repository.Branch, - Owner: workspaceDTO.Repository.Owner, - Path: workspaceDTO.Repository.Path, - Sha: workspaceDTO.Repository.Sha, - Source: workspaceDTO.Repository.Source, - Url: workspaceDTO.Repository.Url, - } - - var workspaceMetadata *models.WorkspaceMetadata - if workspaceDTO.Metadata != nil { - updatedAt, err := time.Parse(time.RFC3339, workspaceDTO.Metadata.UpdatedAt) - if err != nil { - updatedAt = time.Unix(0, 0) - } - uptime := workspaceDTO.Metadata.Uptime - workspaceMetadata = &models.WorkspaceMetadata{ - UpdatedAt: updatedAt, - Uptime: uint64(uptime), - GitStatus: ToGitStatus(workspaceDTO.Metadata.GitStatus), - } - } - - var workspaceBuild *models.BuildConfig - if workspaceDTO.BuildConfig != nil { - workspaceBuild = &models.BuildConfig{} - if workspaceDTO.BuildConfig.Devcontainer != nil { - workspaceBuild.Devcontainer = &models.DevcontainerConfig{ - FilePath: workspaceDTO.BuildConfig.Devcontainer.FilePath, - } - } - } - - workspace := &models.Workspace{ - Id: workspaceDTO.Id, - Name: workspaceDTO.Name, - Image: workspaceDTO.Image, - User: workspaceDTO.User, - BuildConfig: workspaceBuild, - Repository: repository, - TargetId: workspaceDTO.TargetId, - Metadata: workspaceMetadata, - GitProviderConfigId: workspaceDTO.GitProviderConfigId, - } - - if workspaceDTO.Repository.PrNumber != nil { - prNumber := uint32(*workspaceDTO.Repository.PrNumber) - workspace.Repository.PrNumber = &prNumber - } - - return workspace -} - -func ToGitStatus(gitStatusDTO *apiclient.GitStatus) *models.GitStatus { - if gitStatusDTO == nil { - return nil - } - - files := []*models.FileStatus{} - for _, fileDTO := range gitStatusDTO.FileStatus { - staging := models.Status(string(fileDTO.Staging)) - worktree := models.Status(string(fileDTO.Worktree)) - file := &models.FileStatus{ - Name: fileDTO.Name, - Extra: fileDTO.Extra, - Staging: staging, - Worktree: worktree, - } - files = append(files, file) - } - - var ahead, behind int - if gitStatusDTO.Ahead != nil { - ahead = int(*gitStatusDTO.Ahead) - } - if gitStatusDTO.Behind != nil { - behind = int(*gitStatusDTO.Behind) - } - - var branchPublished bool - if gitStatusDTO.BranchPublished != nil { - branchPublished = *gitStatusDTO.BranchPublished - } - - return &models.GitStatus{ - CurrentBranch: gitStatusDTO.CurrentBranch, - Files: files, - BranchPublished: branchPublished, - Ahead: ahead, - Behind: behind, - } -} - -func ToGitStatusDTO(gitStatus *models.GitStatus) *apiclient.GitStatus { - if gitStatus == nil { - return nil - } - - fileStatusDTO := []apiclient.FileStatus{} - for _, file := range gitStatus.Files { - staging := apiclient.Status(string(file.Staging)) - worktree := apiclient.Status(string(file.Worktree)) - fileDTO := apiclient.FileStatus{ - Name: file.Name, - Extra: file.Extra, - Staging: staging, - Worktree: worktree, - } - fileStatusDTO = append(fileStatusDTO, fileDTO) - } - - var ahead, behind *int32 - if gitStatus.Ahead != 0 { - value := int32(gitStatus.Ahead) - ahead = &value - } - if gitStatus.Behind != 0 { - value := int32(gitStatus.Behind) - behind = &value - } - var branchPublished *bool - if gitStatus.BranchPublished { - value := true - branchPublished = &value - } - - return &apiclient.GitStatus{ - CurrentBranch: gitStatus.CurrentBranch, - FileStatus: fileStatusDTO, - BranchPublished: branchPublished, - Ahead: ahead, - Behind: behind, - } -} - -func ToWorkspaceTemplate(createWorkspaceTemplateDto services.CreateWorkspaceTemplateDTO) *models.WorkspaceTemplate { - result := &models.WorkspaceTemplate{ - Name: createWorkspaceTemplateDto.Name, - BuildConfig: createWorkspaceTemplateDto.BuildConfig, - EnvVars: createWorkspaceTemplateDto.EnvVars, - GitProviderConfigId: createWorkspaceTemplateDto.GitProviderConfigId, - } - - result.RepositoryUrl = createWorkspaceTemplateDto.RepositoryUrl - - if createWorkspaceTemplateDto.Image != nil { - result.Image = *createWorkspaceTemplateDto.Image - } - - if createWorkspaceTemplateDto.User != nil { - result.User = *createWorkspaceTemplateDto.User - } - - return result -} diff --git a/internal/util/cmd.go b/internal/util/cmd.go index d34be9d4f6..6fb29228e7 100644 --- a/internal/util/cmd.go +++ b/internal/util/cmd.go @@ -7,4 +7,5 @@ const ( TARGET_GROUP = "target" SERVER_GROUP = "server" PROFILE_GROUP = "profile" + RUNNER_GROUP = "runner" ) diff --git a/internal/util/config.go b/internal/util/config.go new file mode 100644 index 0000000000..dbeb49e2c6 --- /dev/null +++ b/internal/util/config.go @@ -0,0 +1,14 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import "os" + +func DirectoryValidator(path *string) error { + _, err := os.Stat(*path) + if os.IsNotExist(err) { + return os.MkdirAll(*path, 0700) + } + return err +} diff --git a/internal/util/log_formatter.go b/internal/util/log_formatter.go new file mode 100644 index 0000000000..7b215807da --- /dev/null +++ b/internal/util/log_formatter.go @@ -0,0 +1,33 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "io" + + log "github.com/sirupsen/logrus" +) + +type LogFormatter struct { + TextFormatter *log.TextFormatter + ProcessLogWriter io.Writer +} + +func (f *LogFormatter) Format(entry *log.Entry) ([]byte, error) { + formatted, err := f.TextFormatter.Format(entry) + if err != nil { + return nil, err + } + + if f.ProcessLogWriter != nil { + _, err = f.ProcessLogWriter.Write(formatted) + if err != nil { + return nil, err + } + } + + // Return the original message without log decoration + // We don't want decoration to show up in the target creation logs + return []byte(entry.Message + "\n"), nil +} diff --git a/pkg/provider/manager/manifest.go b/internal/util/providermanifest.go similarity index 80% rename from pkg/provider/manager/manifest.go rename to internal/util/providermanifest.go index fe00fb815a..e6b52112ab 100644 --- a/pkg/provider/manager/manifest.go +++ b/internal/util/providermanifest.go @@ -1,9 +1,14 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package manager +package util import ( + "encoding/json" + "fmt" + "io" + "net/http" + "github.com/daytonaio/daytona/pkg/os" "golang.org/x/mod/semver" ) @@ -20,6 +25,30 @@ type ProviderManifest struct { Versions map[string]Version `json:"versions"` } +func GetProvidersManifest(registryUrl string) (*ProvidersManifest, error) { + manifestUrl := fmt.Sprintf("%s/providers/manifest.json", registryUrl) + + resp, err := http.Get(manifestUrl) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + manifestJson, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + var manifest ProvidersManifest + err = json.Unmarshal(manifestJson, &manifest) + if err != nil { + return nil, err + } + + return &manifest, nil +} + func (p *ProviderManifest) FindLatestVersion() (string, *Version) { var latestVersion string = "v0.0.0" diff --git a/internal/util/apiclient/websocket_conn.go b/internal/util/websocket_conn.go similarity index 57% rename from internal/util/apiclient/websocket_conn.go rename to internal/util/websocket_conn.go index 417d4d9cb4..421f3fab09 100644 --- a/internal/util/apiclient/websocket_conn.go +++ b/internal/util/websocket_conn.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package apiclient +package util import ( "context" @@ -11,39 +11,16 @@ import ( "net/url" "regexp" - "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/gorilla/websocket" ) -func GetWebsocketConn(ctx context.Context, path string, profile *config.Profile, query *string) (*websocket.Conn, *http.Response, error) { - c, err := config.GetConfig() - if err != nil { - return nil, nil, err - } - - var serverUrl string - var apiKey string - - var activeProfile config.Profile - if profile == nil { - var err error - activeProfile, err = c.GetActiveProfile() - if err != nil { - return nil, nil, err - } - } else { - activeProfile = *profile - } - - serverUrl = activeProfile.Api.Url - apiKey = activeProfile.Api.Key - +func GetWebsocketConn(ctx context.Context, path string, serverUrl string, apiKey string, query *string) (*websocket.Conn, *http.Response, error) { url, err := url.JoinPath(serverUrl, path) if err != nil { return nil, nil, err } - wsUrl, err := GetWebSocketUrl(url) + wsUrl, err := getWebSocketUrl(url) if err != nil { return nil, nil, err } @@ -57,7 +34,7 @@ func GetWebsocketConn(ctx context.Context, path string, profile *config.Profile, }) } -func GetWebSocketUrl(apiUrl string) (string, error) { +func getWebSocketUrl(apiUrl string) (string, error) { hostRegex := regexp.MustCompile(`(https*)://(.*)`) matches := hostRegex.FindStringSubmatch(apiUrl) diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 1a3db00328..b1bdcf3e90 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -14,6 +14,7 @@ import ( "time" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" agent_config "github.com/daytonaio/daytona/pkg/agent/config" @@ -264,9 +265,15 @@ func (a *Agent) updateWorkspaceMetadata() error { } uptime := a.uptime() - res, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), a.Config.WorkspaceId).SetMetadata(apiclient.SetWorkspaceMetadata{ + + gitStatusDto, err := conversion.Convert[models.GitStatus, apiclient.GitStatus](gitStatus) + if err != nil { + return err + } + + res, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), a.Config.WorkspaceId).WorkspaceMetadata(apiclient.UpdateWorkspaceMetadataDTO{ Uptime: uptime, - GitStatus: conversion.ToGitStatusDTO(gitStatus), + GitStatus: gitStatusDto, }).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) @@ -282,7 +289,7 @@ func (a *Agent) updateTargetMetadata() error { } uptime := a.uptime() - res, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), a.Config.TargetId).SetMetadata(apiclient.SetTargetMetadata{ + res, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), a.Config.TargetId).TargetMetadata(apiclient.UpdateTargetMetadataDTO{ Uptime: uptime, }).Execute() if err != nil { @@ -291,3 +298,14 @@ func (a *Agent) updateTargetMetadata() error { return nil } + +func (s *Agent) initLogs() { + logFormatter := &util.LogFormatter{ + TextFormatter: &log.TextFormatter{ + ForceColors: true, + }, + ProcessLogWriter: s.LogWriter, + } + + log.SetFormatter(logFormatter) +} diff --git a/pkg/agent/log.go b/pkg/agent/log.go deleted file mode 100644 index 85c7a3ef1c..0000000000 --- a/pkg/agent/log.go +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package agent - -import ( - "io" - - log "github.com/sirupsen/logrus" -) - -type logFormatter struct { - textFormatter *log.TextFormatter - agentLogWriter io.Writer -} - -func (f *logFormatter) Format(entry *log.Entry) ([]byte, error) { - formatted, err := f.textFormatter.Format(entry) - if err != nil { - return nil, err - } - - if f.agentLogWriter != nil { - _, err = f.agentLogWriter.Write(formatted) - if err != nil { - return nil, err - } - } - - // Return the original message without log decoration - // We don't want decoration to show up in the target creation logs - return []byte(entry.Message + "\n"), nil -} - -func (s *Agent) initLogs() { - logFormatter := &logFormatter{ - textFormatter: &log.TextFormatter{ - ForceColors: true, - }, - agentLogWriter: s.LogWriter, - } - - log.SetFormatter(logFormatter) -} diff --git a/pkg/api/controllers/build/create.go b/pkg/api/controllers/build/create.go new file mode 100644 index 0000000000..93f2c7180a --- /dev/null +++ b/pkg/api/controllers/build/create.go @@ -0,0 +1,43 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/gin-gonic/gin" +) + +// CreateBuild godoc +// +// @Tags build +// @Summary Create a build +// @Description Create a build +// @Accept json +// @Param createBuildDto body CreateBuildDTO true "Create Build DTO" +// @Success 201 {string} buildId +// @Router /build [post] +// +// @id CreateBuild +func CreateBuild(ctx *gin.Context) { + var createBuildDto services.CreateBuildDTO + err := ctx.BindJSON(&createBuildDto) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) + return + } + + s := server.GetInstance(nil) + + buildId, err := s.BuildService.Create(ctx.Request.Context(), createBuildDto) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create build: %s", err.Error())) + return + } + + ctx.String(201, buildId) +} diff --git a/pkg/api/controllers/build/build.go b/pkg/api/controllers/build/delete.go similarity index 61% rename from pkg/api/controllers/build/build.go rename to pkg/api/controllers/build/delete.go index 0cf3ba18fa..a3fff19231 100644 --- a/pkg/api/controllers/build/build.go +++ b/pkg/api/controllers/build/delete.go @@ -15,91 +15,6 @@ import ( "github.com/gin-gonic/gin" ) -// CreateBuild godoc -// -// @Tags build -// @Summary Create a build -// @Description Create a build -// @Accept json -// @Param createBuildDto body CreateBuildDTO true "Create Build DTO" -// @Success 201 {string} buildId -// @Router /build [post] -// -// @id CreateBuild -func CreateBuild(ctx *gin.Context) { - var createBuildDto services.CreateBuildDTO - err := ctx.BindJSON(&createBuildDto) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) - return - } - - s := server.GetInstance(nil) - - buildId, err := s.BuildService.Create(ctx.Request.Context(), createBuildDto) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create build: %s", err.Error())) - return - } - - ctx.String(201, buildId) -} - -// GetBuild godoc -// -// @Tags build -// @Summary Get build data -// @Description Get build data -// @Accept json -// @Param buildId path string true "Build ID" -// @Success 200 {object} BuildDTO -// @Router /build/{buildId} [get] -// -// @id GetBuild -func GetBuild(ctx *gin.Context) { - buildId := ctx.Param("buildId") - - server := server.GetInstance(nil) - - b, err := server.BuildService.Find(ctx.Request.Context(), &services.BuildFilter{ - StoreFilter: stores.BuildFilter{ - Id: &buildId, - }, - }) - if err != nil { - statusCode := http.StatusInternalServerError - if stores.IsBuildNotFound(err) || services.IsBuildDeleted(err) { - statusCode = http.StatusNotFound - } - ctx.AbortWithError(statusCode, fmt.Errorf("failed to find build: %w", err)) - return - } - - ctx.JSON(200, b) -} - -// ListBuilds godoc -// -// @Tags build -// @Summary List builds -// @Description List builds -// @Produce json -// @Success 200 {array} BuildDTO -// @Router /build [get] -// -// @id ListBuilds -func ListBuilds(ctx *gin.Context) { - server := server.GetInstance(nil) - - builds, err := server.BuildService.List(ctx.Request.Context(), nil) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list builds: %s", err.Error())) - return - } - - ctx.JSON(200, builds) -} - // DeleteAllBuilds godoc // // @Tags build diff --git a/pkg/api/controllers/build/get.go b/pkg/api/controllers/build/get.go new file mode 100644 index 0000000000..be74ee9a4c --- /dev/null +++ b/pkg/api/controllers/build/get.go @@ -0,0 +1,47 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" +) + +// GetBuild godoc +// +// @Tags build +// @Summary Get build data +// @Description Get build data +// @Accept json +// @Param buildId path string true "Build ID" +// @Success 200 {object} BuildDTO +// @Router /build/{buildId} [get] +// +// @id GetBuild +func GetBuild(ctx *gin.Context) { + buildId := ctx.Param("buildId") + + server := server.GetInstance(nil) + + b, err := server.BuildService.Find(ctx.Request.Context(), &services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &buildId, + }, + }) + if err != nil { + statusCode := http.StatusInternalServerError + if stores.IsBuildNotFound(err) || services.IsBuildDeleted(err) { + statusCode = http.StatusNotFound + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to find build: %w", err)) + return + } + + ctx.JSON(200, b) +} diff --git a/pkg/api/controllers/build/list.go b/pkg/api/controllers/build/list.go new file mode 100644 index 0000000000..654c362356 --- /dev/null +++ b/pkg/api/controllers/build/list.go @@ -0,0 +1,74 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + "net/http" + "net/url" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" +) + +// ListBuilds godoc +// +// @Tags build +// @Summary List builds +// @Description List builds +// @Produce json +// @Success 200 {array} BuildDTO +// @Router /build [get] +// +// @id ListBuilds +func ListBuilds(ctx *gin.Context) { + server := server.GetInstance(nil) + + builds, err := server.BuildService.List(ctx.Request.Context(), nil) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list builds: %s", err.Error())) + return + } + + ctx.JSON(200, builds) +} + +// ListSuccessfulBuilds godoc +// +// @Tags build +// @Summary List successful builds for Git repository +// @Description List successful builds for Git repository +// @Produce json +// @Param repoUrl path string true "Repository URL" +// @Success 200 {array} BuildDTO +// @Router /build/successful/{repoUrl} [get] +// +// @id ListSuccessfulBuilds +func ListSuccessfulBuilds(ctx *gin.Context) { + urlParam := ctx.Param("url") + + decodedUrl, err := url.QueryUnescape(urlParam) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to decode query param: %w", err)) + return + } + + server := server.GetInstance(nil) + + builds, err := server.BuildService.List(ctx.Request.Context(), &services.BuildFilter{ + StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, + StoreFilter: stores.BuildFilter{ + RepositoryUrl: &decodedUrl, + }, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list successful builds: %s", err.Error())) + return + } + + ctx.JSON(200, builds) +} diff --git a/pkg/api/controllers/job/job.go b/pkg/api/controllers/job/job.go index 136f52310f..077f76b62a 100644 --- a/pkg/api/controllers/job/job.go +++ b/pkg/api/controllers/job/job.go @@ -7,7 +7,9 @@ import ( "fmt" "net/http" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/stores" "github.com/gin-gonic/gin" ) @@ -16,15 +18,54 @@ import ( // @Tags job // @Summary List jobs // @Description List jobs +// @Param states query []string false "Job States" collectionFormat(multi) +// @Param actions query []string false "Job Actions" collectionFormat(multi) +// @Param resourceId query string false "Resource ID" +// @Param resourceType query string false "Resource Type" // @Produce json -// @Success 200 {array} Job +// @Success 200 {array} Job // @Router /job [get] // // @id ListJobs func ListJobs(ctx *gin.Context) { + states := ctx.QueryArray("states") + var jobStates *[]models.JobState + if len(states) > 0 { + jobStates = &[]models.JobState{} + for _, s := range states { + *jobStates = append(*jobStates, models.JobState(s)) + } + } + + resourceIdQuery := ctx.Query("resourceId") + var resourceId *string + if resourceIdQuery != "" { + resourceId = &resourceIdQuery + } + + resourceTypeQuery := ctx.Query("resourceType") + var resourceType *models.ResourceType + if resourceTypeQuery != "" { + resourceType = (*models.ResourceType)(&resourceTypeQuery) + } + + actions := ctx.QueryArray("actions") + var jobActions *[]models.JobAction + if len(actions) > 0 { + jobActions = &[]models.JobAction{} + for _, a := range actions { + *jobActions = append(*jobActions, models.JobAction(a)) + } + } + server := server.GetInstance(nil) - jobs, err := server.JobService.List(ctx.Request.Context(), nil) + jobs, err := server.JobService.List(ctx.Request.Context(), &stores.JobFilter{ + States: jobStates, + ResourceId: resourceId, + ResourceType: resourceType, + Actions: jobActions, + }) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list jobs: %s", err.Error())) return diff --git a/pkg/api/controllers/log/websocket.go b/pkg/api/controllers/log/read.go similarity index 78% rename from pkg/api/controllers/log/websocket.go rename to pkg/api/controllers/log/read.go index 7b6f702bac..2932e48af7 100644 --- a/pkg/api/controllers/log/websocket.go +++ b/pkg/api/controllers/log/read.go @@ -10,7 +10,7 @@ import ( "net/http" "time" - "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" @@ -25,89 +25,6 @@ var upgrader = websocket.Upgrader{ }, } -func writeToWs(ws *websocket.Conn, c chan []byte, errChan chan error) { - for { - err := ws.WriteMessage(websocket.TextMessage, <-c) - if err != nil { - errChan <- err - break - } - } -} - -func writeJSONToWs(ws *websocket.Conn, c chan interface{}, errChan chan error) { - for { - err := ws.WriteJSON(<-c) - if err != nil { - errChan <- err - break - } - } -} - -// ReadLog reads from the logReader and writes to the websocket. -// T is the type of the message to be read from the logReader -func ReadLog[T any](ginCtx *gin.Context, logReader io.Reader, readFunc func(context.Context, io.Reader, bool, chan T, chan error), wsWriteFunc func(*websocket.Conn, chan T, chan error)) { - followQuery := ginCtx.Query("follow") - follow := followQuery == "true" - - ws, err := upgrader.Upgrade(ginCtx.Writer, ginCtx.Request, nil) - if err != nil { - log.Error(err) - return - } - - defer func() { - closeErr := websocket.CloseNormalClosure - if !errors.Is(err, io.EOF) { - closeErr = websocket.CloseInternalServerErr - } - err := ws.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(closeErr, ""), time.Now().Add(time.Second)) - if err != nil { - log.Trace(err) - } - ws.Close() - }() - - msgChannel := make(chan T) - errChannel := make(chan error) - ctx, cancel := context.WithCancel(ginCtx.Request.Context()) - - defer cancel() - go readFunc(ctx, logReader, follow, msgChannel, errChannel) - go wsWriteFunc(ws, msgChannel, errChannel) - - readErr := make(chan error) - go func() { - for { - _, _, err := ws.ReadMessage() - readErr <- err - } - }() - - for { - select { - case <-ctx.Done(): - return - case err = <-errChannel: - if err != nil { - if !errors.Is(err, io.EOF) { - log.Error(err) - } - cancel() - return - } - case err := <-readErr: - if websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) { - log.Error(err) - } - if err != nil { - return - } - } - } -} - func ReadServerLog(ctx *gin.Context) { s := server.GetInstance(nil) @@ -123,7 +40,7 @@ func ReadServerLog(ctx *gin.Context) { return } if err == nil { - ReadLog(ctx, reader, util.ReadLog, writeToWs) + ReadLog(ctx, reader, logs.ReadLog, writeToWs) return } time.Sleep(TIMEOUT) @@ -140,7 +57,7 @@ func ReadServerLog(ctx *gin.Context) { return } - ReadLog(ctx, reader, util.ReadLog, writeToWs) + ReadLog(ctx, reader, logs.ReadLog, writeToWs) } func ReadTargetLog(ctx *gin.Context) { @@ -152,22 +69,22 @@ func ReadTargetLog(ctx *gin.Context) { if retry { for { - targetLogReader, err := server.TargetService.GetTargetLogReader(targetId) + targetLogReader, err := server.TargetService.GetTargetLogReader(ctx.Request.Context(), targetId) if err == nil { - ReadLog(ctx, targetLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, targetLogReader, logs.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) } } - targetLogReader, err := server.TargetService.GetTargetLogReader(targetId) + targetLogReader, err := server.TargetService.GetTargetLogReader(ctx.Request.Context(), targetId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, err) return } - ReadLog(ctx, targetLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, targetLogReader, logs.ReadJSONLog, writeJSONToWs) } func ReadWorkspaceLog(ctx *gin.Context) { @@ -181,7 +98,7 @@ func ReadWorkspaceLog(ctx *gin.Context) { for { workspaceLogReader, err := server.WorkspaceService.GetWorkspaceLogReader(ctx.Request.Context(), workspaceId) if err == nil { - ReadLog(ctx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, workspaceLogReader, logs.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) @@ -194,7 +111,7 @@ func ReadWorkspaceLog(ctx *gin.Context) { return } - ReadLog(ctx, workspaceLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, workspaceLogReader, logs.ReadJSONLog, writeJSONToWs) } func ReadBuildLog(ctx *gin.Context) { @@ -209,7 +126,7 @@ func ReadBuildLog(ctx *gin.Context) { buildLogReader, err := server.BuildService.GetBuildLogReader(ctx.Request.Context(), buildId) if err == nil { - ReadLog(ctx, buildLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, buildLogReader, logs.ReadJSONLog, writeJSONToWs) return } time.Sleep(TIMEOUT) @@ -222,5 +139,115 @@ func ReadBuildLog(ctx *gin.Context) { return } - ReadLog(ctx, buildLogReader, util.ReadJSONLog, writeJSONToWs) + ReadLog(ctx, buildLogReader, logs.ReadJSONLog, writeJSONToWs) +} + +func ReadRunnerLog(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + retryQuery := ctx.DefaultQuery("retry", "true") + retry := retryQuery == "true" + + server := server.GetInstance(nil) + + if retry { + for { + runnerLogReader, err := server.RunnerService.GetRunnerLogReader(ctx.Request.Context(), runnerId) + if err == nil { + ReadLog(ctx, runnerLogReader, logs.ReadJSONLog, writeJSONToWs) + return + } + time.Sleep(TIMEOUT) + } + } + + runnerLogReader, err := server.RunnerService.GetRunnerLogReader(ctx.Request.Context(), runnerId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, err) + return + } + + ReadLog(ctx, runnerLogReader, logs.ReadJSONLog, writeJSONToWs) +} + +func writeToWs(ws *websocket.Conn, c chan []byte, errChan chan error) { + for { + err := ws.WriteMessage(websocket.TextMessage, <-c) + if err != nil { + errChan <- err + break + } + } +} + +func writeJSONToWs(ws *websocket.Conn, c chan interface{}, errChan chan error) { + for { + err := ws.WriteJSON(<-c) + if err != nil { + errChan <- err + break + } + } +} + +// ReadLog reads from the logReader and writes to the websocket. +// T is the type of the message to be read from the logReader +func ReadLog[T any](ginCtx *gin.Context, logReader io.Reader, readFunc func(context.Context, io.Reader, bool, chan T, chan error), wsWriteFunc func(*websocket.Conn, chan T, chan error)) { + followQuery := ginCtx.Query("follow") + follow := followQuery == "true" + + ws, err := upgrader.Upgrade(ginCtx.Writer, ginCtx.Request, nil) + if err != nil { + log.Error(err) + return + } + + defer func() { + closeErr := websocket.CloseNormalClosure + if !errors.Is(err, io.EOF) { + closeErr = websocket.CloseInternalServerErr + } + err := ws.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(closeErr, ""), time.Now().Add(time.Second)) + if err != nil { + log.Trace(err) + } + ws.Close() + }() + + msgChannel := make(chan T) + errChannel := make(chan error) + ctx, cancel := context.WithCancel(ginCtx.Request.Context()) + + defer cancel() + go readFunc(ctx, logReader, follow, msgChannel, errChannel) + go wsWriteFunc(ws, msgChannel, errChannel) + + readErr := make(chan error) + go func() { + for { + _, _, err := ws.ReadMessage() + readErr <- err + } + }() + + for { + select { + case <-ctx.Done(): + return + case err = <-errChannel: + if err != nil { + if !errors.Is(err, io.EOF) { + log.Error(err) + } + cancel() + return + } + case err := <-readErr: + if websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) { + log.Error(err) + } + if err != nil { + return + } + } + } } diff --git a/pkg/api/controllers/log/write.go b/pkg/api/controllers/log/write.go new file mode 100644 index 0000000000..e71a771f62 --- /dev/null +++ b/pkg/api/controllers/log/write.go @@ -0,0 +1,142 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package log + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "time" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + log "github.com/sirupsen/logrus" +) + +func WriteWorkspaceLog(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + server := server.GetInstance(nil) + + logWriter, err := server.WorkspaceService.GetWorkspaceLogWriter(ctx, workspaceId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get workspace log writer: %w", err)) + return + } + defer logWriter.Close() + + writeLog(ctx, logWriter) +} + +func WriteTargetLog(ctx *gin.Context) { + targetId := ctx.Param("targetId") + + server := server.GetInstance(nil) + + logWriter, err := server.TargetService.GetTargetLogWriter(ctx, targetId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get target log writer: %w", err)) + return + } + defer logWriter.Close() + + writeLog(ctx, logWriter) +} + +func WriteBuildLog(ctx *gin.Context) { + buildId := ctx.Param("buildId") + + server := server.GetInstance(nil) + + logWriter, err := server.BuildService.GetBuildLogWriter(ctx, buildId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get build log writer: %w", err)) + return + } + defer logWriter.Close() + + writeLog(ctx, logWriter) +} + +func WriteRunnerLog(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + + server := server.GetInstance(nil) + + logWriter, err := server.RunnerService.GetRunnerLogWriter(ctx, runnerId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get runner log writer: %w", err)) + return + } + defer logWriter.Close() + + writeLog(ctx, logWriter) +} + +func writeLog(ginCtx *gin.Context, logWriter io.WriteCloser) { + ws, err := upgrader.Upgrade(ginCtx.Writer, ginCtx.Request, nil) + if err != nil { + log.Error(err) + return + } + + defer func() { + closeErr := websocket.CloseNormalClosure + if !errors.Is(err, io.EOF) { + closeErr = websocket.CloseInternalServerErr + } + err := ws.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(closeErr, ""), time.Now().Add(time.Second)) + if err != nil { + log.Trace(err) + } + ws.Close() + }() + + errChannel := make(chan error) + ctx, cancel := context.WithCancel(ginCtx.Request.Context()) + + defer cancel() + + readErr := make(chan error) + go func() { + for { + _, msg, err := ws.ReadMessage() + if err != nil { + readErr <- err + return + } + + _, err = logWriter.Write(msg) + if err != nil { + readErr <- err + return + } + } + }() + + for { + select { + case <-ctx.Done(): + return + case err = <-errChannel: + if err != nil { + if !errors.Is(err, io.EOF) { + log.Error(err) + } + cancel() + return + } + case err := <-readErr: + if websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) { + log.Error(err) + } + if err != nil { + return + } + } + } +} diff --git a/pkg/api/controllers/provider/install.go b/pkg/api/controllers/provider/install.go deleted file mode 100644 index 4cfc8a5d68..0000000000 --- a/pkg/api/controllers/provider/install.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provider - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/api/controllers/provider/dto" - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// InstallProvider godoc -// -// @Tags provider -// @Summary Install a provider -// @Description Install a provider -// @Accept json -// @Param provider body InstallProviderRequest true "Provider to install" -// @Success 200 -// @Router /provider/install [post] -// -// @id InstallProvider -func InstallProvider(ctx *gin.Context) { - var req dto.InstallProviderRequest - err := ctx.BindJSON(&req) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) - return - } - - server := server.GetInstance(nil) - if _, err := server.ProviderManager.GetProvider(req.Name); err == nil { - err := server.ProviderManager.UninstallProvider(req.Name) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to uninstall current provider: %w", err)) - return - } - } - - downloadPath, err := server.ProviderManager.DownloadProvider(ctx.Request.Context(), req.DownloadUrls, req.Name) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to download provider: %w", err)) - return - } - - err = server.ProviderManager.RegisterProvider(downloadPath, true) - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to register provider: %w", err)) - return - } - - ctx.Status(200) -} diff --git a/pkg/api/controllers/provider/list.go b/pkg/api/controllers/provider/list.go deleted file mode 100644 index fe793f3f16..0000000000 --- a/pkg/api/controllers/provider/list.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provider - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/api/controllers/provider/dto" - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// ListProviders godoc -// -// @Tags provider -// @Summary List providers -// @Description List providers -// @Produce json -// @Success 200 {array} dto.Provider -// @Router /provider [get] -// -// @id ListProviders -func ListProviders(ctx *gin.Context) { - server := server.GetInstance(nil) - providers := server.ProviderManager.GetProviders() - - result := []dto.Provider{} - for _, provider := range providers { - info, err := provider.GetInfo() - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get provider: %w", err)) - return - } - - result = append(result, dto.Provider{ - Name: info.Name, - Label: info.Label, - Version: info.Version, - }) - } - - ctx.JSON(200, result) -} diff --git a/pkg/api/controllers/provider/target_config.go b/pkg/api/controllers/provider/target_config.go deleted file mode 100644 index 4b43d146c8..0000000000 --- a/pkg/api/controllers/provider/target_config.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provider - -import ( - "fmt" - "net/http" - - "github.com/daytonaio/daytona/pkg/server" - "github.com/gin-gonic/gin" -) - -// GetTargetConfigManifest godoc -// -// @Tags provider -// @Summary Get provider target config manifest -// @Description Get provider target config manifest -// @Param provider path string true "Provider name" -// @Success 200 -// @Success 200 {object} TargetConfigManifest -// @Router /provider/{provider}/target-config-manifest [get] -// -// @id GetTargetConfigManifest -func GetTargetConfigManifest(ctx *gin.Context) { - providerName := ctx.Param("provider") - - server := server.GetInstance(nil) - - p, err := server.ProviderManager.GetProvider(providerName) - if err != nil { - ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("provider not found: %w", err)) - return - } - - manifest, err := (*p).GetTargetConfigManifest() - if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get provider manifest: %w", err)) - return - } - - ctx.JSON(200, manifest) -} diff --git a/pkg/api/controllers/runner/dto/dto.go b/pkg/api/controllers/runner/dto/dto.go new file mode 100644 index 0000000000..9590b77732 --- /dev/null +++ b/pkg/api/controllers/runner/dto/dto.go @@ -0,0 +1,14 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import ( + "github.com/daytonaio/daytona/pkg/models" +) + +type UpdateRunnerMetadataDTO struct { + Uptime uint64 `json:"uptime" validate:"required" gorm:"not null"` + RunningJobs *uint64 `json:"runningJobs" validate:"optional" gorm:"not null"` + Providers []models.ProviderInfo `json:"providers" validate:"required" gorm:"serializer:json;not null"` +} // @name UpdateRunnerMetadataDTO diff --git a/pkg/api/controllers/runner/get.go b/pkg/api/controllers/runner/get.go new file mode 100644 index 0000000000..d0c9b99117 --- /dev/null +++ b/pkg/api/controllers/runner/get.go @@ -0,0 +1,42 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" +) + +// GetRunner godoc +// +// @Tags runner +// @Summary Get a runner +// @Description Get a runner +// @Param runnerId path string true "Runner ID" +// @Produce json +// @Success 200 {object} RunnerDTO +// @Router /runner/{runnerId} [get] +// +// @id GetRunner +func GetRunner(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + + server := server.GetInstance(nil) + + r, err := server.RunnerService.GetRunner(ctx.Request.Context(), runnerId) + if err != nil { + statusCode := http.StatusInternalServerError + if stores.IsRunnerNotFound(err) { + statusCode = http.StatusNotFound + } + ctx.AbortWithError(statusCode, fmt.Errorf("failed to get runner: %w", err)) + return + } + + ctx.JSON(200, r) +} diff --git a/pkg/api/controllers/runner/jobs.go b/pkg/api/controllers/runner/jobs.go new file mode 100644 index 0000000000..3b26b1298a --- /dev/null +++ b/pkg/api/controllers/runner/jobs.go @@ -0,0 +1,87 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/gin-gonic/gin" +) + +// ListRunnerJobs godoc +// +// @Tags runner +// @Summary List runner jobs +// @Description List runner jobs +// @Param runnerId path string true "Runner ID" +// @Produce json +// @Success 200 {array} Job +// @Router /runner/{runnerId}/jobs [get] +// +// @id ListRunnerJobs +func ListRunnerJobs(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + + server := server.GetInstance(nil) + + jobs, err := server.RunnerService.ListRunnerJobs(ctx.Request.Context(), runnerId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get runner: %w", err)) + return + } + + ctx.JSON(200, jobs) +} + +// UpdateJobState godoc +// +// @Tags runner +// @Summary Update job state +// @Description Update job state +// @Param runnerId path string true "Runner ID" +// @Param jobId path string true "Job ID" +// @Param updateJobState body UpdateJobState true "Update job state" +// @Produce json +// @Success 200 +// @Router /runner/{runnerId}/jobs/{jobId}/state [post] +// +// @id UpdateJobState +func UpdateJobState(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + jobId := ctx.Param("jobId") + + var updateJobState services.UpdateJobStateDTO + err := ctx.BindJSON(&updateJobState) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + job, err := server.JobService.Find(ctx.Request.Context(), &stores.JobFilter{ + Id: &jobId, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get job: %w", err)) + return + } + + if job.RunnerId != nil && *job.RunnerId != runnerId { + ctx.AbortWithError(http.StatusUnauthorized, fmt.Errorf("job does not belong to runner")) + return + } + + err = server.RunnerService.UpdateJobState(ctx.Request.Context(), jobId, updateJobState) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update job state: %w", err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/runner/list.go b/pkg/api/controllers/runner/list.go new file mode 100644 index 0000000000..724258c32e --- /dev/null +++ b/pkg/api/controllers/runner/list.go @@ -0,0 +1,34 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// ListRunners godoc +// +// @Tags runner +// @Summary List runners +// @Description List runners +// @Produce json +// @Success 200 {array} RunnerDTO +// @Router /runner [get] +// +// @id ListRunners +func ListRunners(ctx *gin.Context) { + server := server.GetInstance(nil) + + runners, err := server.RunnerService.ListRunners(ctx.Request.Context()) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to register runner: %w", err)) + return + } + + ctx.JSON(200, runners) +} diff --git a/pkg/api/controllers/runner/metadata.go b/pkg/api/controllers/runner/metadata.go new file mode 100644 index 0000000000..4866f01c97 --- /dev/null +++ b/pkg/api/controllers/runner/metadata.go @@ -0,0 +1,51 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/api/controllers/runner/dto" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// SetRunnerMetadata godoc +// +// @Tags runner +// @Summary Set runner metadata +// @Description Set runner metadata +// @Param runnerId path string true "Runner ID" +// @Param runnerMetadata body UpdateRunnerMetadataDTO true "Runner Metadata" +// @Success 200 +// @Router /runner/{runnerId}/metadata [post] +// +// @id SetRunnerMetadata +func SetRunnerMetadata(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + + var runnerMetadata dto.UpdateRunnerMetadataDTO + err := ctx.BindJSON(&runnerMetadata) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + err = server.RunnerService.SetRunnerMetadata(ctx.Request.Context(), runnerId, &models.RunnerMetadata{ + RunnerId: runnerId, + Uptime: runnerMetadata.Uptime, + Providers: runnerMetadata.Providers, + RunningJobs: runnerMetadata.RunningJobs, + }) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set runner metadata for %s: %w", runnerId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/provider/dto/dto.go b/pkg/api/controllers/runner/provider/dto/dto.go similarity index 100% rename from pkg/api/controllers/provider/dto/dto.go rename to pkg/api/controllers/runner/provider/dto/dto.go diff --git a/pkg/api/controllers/runner/provider/install.go b/pkg/api/controllers/runner/provider/install.go new file mode 100644 index 0000000000..17ed18f96c --- /dev/null +++ b/pkg/api/controllers/runner/provider/install.go @@ -0,0 +1,45 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package provider + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/gin-gonic/gin" +) + +// InstallProvider godoc +// +// @Tags provider +// @Summary Install provider +// @Description Install provider +// @Param installProviderDto body InstallProviderDTO true "Install provider" +// @Param runnerId path string true "Runner ID" +// @Success 200 +// @Router /runner/{runnerId}/provider/install [post] +// +// @id InstallProvider +func InstallProvider(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + + var installProviderMetadataDto services.InstallProviderDTO + err := ctx.BindJSON(&installProviderMetadataDto) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + err = server.RunnerService.InstallProvider(ctx.Request.Context(), runnerId, installProviderMetadataDto) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to install provider: %w", err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/runner/provider/list.go b/pkg/api/controllers/runner/provider/list.go new file mode 100644 index 0000000000..052afa3b22 --- /dev/null +++ b/pkg/api/controllers/runner/provider/list.go @@ -0,0 +1,42 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package provider + +import ( + "fmt" + "net/http" + + _ "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// ListProviders godoc +// +// @Tags provider +// @Summary List providers +// @Description List providers +// @Param runnerId query string false "Runner ID" +// @Produce json +// @Success 200 {array} models.ProviderInfo +// @Router /runner/provider [get] +// +// @id ListProviders +func ListProviders(ctx *gin.Context) { + runnerIdQuery := ctx.Query("runnerId") + + var runnerId *string + if runnerIdQuery != "" { + runnerId = &runnerIdQuery + } + + server := server.GetInstance(nil) + providers, err := server.RunnerService.ListProviders(ctx.Request.Context(), runnerId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list providers: %w", err)) + return + } + + ctx.JSON(200, providers) +} diff --git a/pkg/api/controllers/provider/uninstall.go b/pkg/api/controllers/runner/provider/uninstall.go similarity index 53% rename from pkg/api/controllers/provider/uninstall.go rename to pkg/api/controllers/runner/provider/uninstall.go index 08af2a8846..73929cfa23 100644 --- a/pkg/api/controllers/provider/uninstall.go +++ b/pkg/api/controllers/runner/provider/uninstall.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" + _ "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -14,20 +15,21 @@ import ( // UninstallProvider godoc // // @Tags provider -// @Summary Uninstall a provider -// @Description Uninstall a provider -// @Accept json -// @Param provider path string true "Provider to uninstall" +// @Summary Uninstall provider +// @Description Uninstall provider +// @Param runnerId path string true "Runner ID" +// @Param providerName path string true "Provider name" // @Success 200 -// @Router /provider/{provider}/uninstall [post] +// @Router /runner/{runnerId}/provider/{providerName}/uninstall [post] // // @id UninstallProvider func UninstallProvider(ctx *gin.Context) { - provider := ctx.Param("provider") + runnerId := ctx.Param("runnerId") + providerName := ctx.Param("providerName") server := server.GetInstance(nil) - err := server.ProviderManager.UninstallProvider(provider) + err := server.RunnerService.UninstallProvider(ctx.Request.Context(), runnerId, providerName) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to uninstall provider: %w", err)) return diff --git a/pkg/api/controllers/runner/provider/update.go b/pkg/api/controllers/runner/provider/update.go new file mode 100644 index 0000000000..9f81fc3b49 --- /dev/null +++ b/pkg/api/controllers/runner/provider/update.go @@ -0,0 +1,48 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package provider + +import ( + "fmt" + "net/http" + + _ "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/gin-gonic/gin" +) + +// UpdateProvider godoc +// +// @Tags provider +// @Summary Update provider +// @Description Update provider +// @Param downloadUrls body DownloadUrls true "Provider download URLs" +// @Param runnerId path string true "Runner ID" +// @Param providerName path string true "Provider name" +// @Success 200 +// @Router /runner/{runnerId}/provider/{providerName}/update [post] +// +// @id UpdateProvider +func UpdateProvider(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + providerName := ctx.Param("providerName") + + var downloadUrls services.DownloadUrls + err := ctx.BindJSON(&downloadUrls) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + err = server.RunnerService.UpdateProvider(ctx.Request.Context(), runnerId, providerName, downloadUrls) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update provider: %w", err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/runner/register.go b/pkg/api/controllers/runner/register.go new file mode 100644 index 0000000000..eed21c7bf0 --- /dev/null +++ b/pkg/api/controllers/runner/register.go @@ -0,0 +1,46 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" + "github.com/gin-gonic/gin" +) + +// RegisterRunner godoc +// +// @Tags runner +// @Summary Register a runner +// @Description Register a runner +// @Param runner body RegisterRunnerDTO true "Register runner" +// @Produce json +// @Success 200 {object} RegisterRunnerResultDTO +// @Router /runner [post] +// +// @id RegisterRunner +func RegisterRunner(ctx *gin.Context) { + var registerRunnerReq services.RegisterRunnerDTO + err := ctx.BindJSON(®isterRunnerReq) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + r, err := server.RunnerService.RegisterRunner(ctx.Request.Context(), registerRunnerReq) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to register runner: %w", err)) + return + } + + ctx.JSON(200, services.RegisterRunnerResultDTO{ + Runner: r.Runner, + ApiKey: r.ApiKey, + }) +} diff --git a/pkg/api/controllers/runner/remove.go b/pkg/api/controllers/runner/remove.go new file mode 100644 index 0000000000..4741ccbfa7 --- /dev/null +++ b/pkg/api/controllers/runner/remove.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// RemoveRunner godoc +// +// @Tags runner +// @Summary Remove runner +// @Description Remove runner +// @Param runnerId path string true "Runner ID" +// @Success 200 +// @Router /runner/{runnerId} [delete] +// +// @id RemoveRunner +func RemoveRunner(ctx *gin.Context) { + runnerId := ctx.Param("runnerId") + + server := server.GetInstance(nil) + + err := server.RunnerService.RemoveRunner(ctx.Request.Context(), runnerId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove runner: %w", err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go index 981752561a..f85faa82b4 100644 --- a/pkg/api/controllers/target/create.go +++ b/pkg/api/controllers/target/create.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" @@ -40,12 +39,30 @@ func CreateTarget(ctx *gin.Context) { return } - maskedOptions, err := util.GetMaskedOptions(server, t.TargetConfig.ProviderInfo.Name, t.TargetConfig.Options) + t.TargetConfig.Options = "" + ctx.JSON(200, t) +} + +// HandleSuccessfulCreation godoc +// +// @Tags target +// @Summary Handles successful creation of the target +// @Description Handles successful creation of the target +// @Param targetId path string true "Target ID or name" +// @Success 200 +// @Router /target/{targetId}/handle-successful-creation [post] +// +// @id HandleSuccessfulCreation +func HandleSuccessfulCreation(ctx *gin.Context) { + targetId := ctx.Param("targetId") + + server := server.GetInstance(nil) + + err := server.TargetService.HandleSuccessfulCreation(ctx.Request.Context(), targetId) if err != nil { - t.TargetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - } else { - t.TargetConfig.Options = maskedOptions + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to handle successful creation of target: %s", err.Error())) + return } - ctx.JSON(200, t) + ctx.Status(200) } diff --git a/pkg/api/controllers/target/dto/dto.go b/pkg/api/controllers/target/dto/dto.go index 88b3b7003c..84527b3f18 100644 --- a/pkg/api/controllers/target/dto/dto.go +++ b/pkg/api/controllers/target/dto/dto.go @@ -3,6 +3,10 @@ package dto -type SetTargetMetadata struct { +type UpdateTargetMetadataDTO struct { Uptime uint64 `json:"uptime" validate:"required"` -} // @name SetTargetMetadata +} // @name UpdateTargetMetadataDTO + +type UpdateTargetProviderMetadataDTO struct { + Metadata string `json:"metadata" validate:"required"` +} // @name UpdateTargetProviderMetadataDTO diff --git a/pkg/api/controllers/target/metadata.go b/pkg/api/controllers/target/metadata.go index e2ee3c28a2..aeac798c1e 100644 --- a/pkg/api/controllers/target/metadata.go +++ b/pkg/api/controllers/target/metadata.go @@ -18,8 +18,8 @@ import ( // @Tags target // @Summary Set target metadata // @Description Set target metadata -// @Param targetId path string true "Target ID" -// @Param setMetadata body SetTargetMetadata true "Set Metadata" +// @Param targetId path string true "Target ID" +// @Param targetMetadata body UpdateTargetMetadataDTO true "Target Metadata" // @Success 200 // @Router /target/{targetId}/metadata [post] // @@ -27,8 +27,8 @@ import ( func SetTargetMetadata(ctx *gin.Context) { targetId := ctx.Param("targetId") - var setTargetMetadataDTO dto.SetTargetMetadata - err := ctx.BindJSON(&setTargetMetadataDTO) + var updateDTO dto.UpdateTargetMetadataDTO + err := ctx.BindJSON(&updateDTO) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) return @@ -37,7 +37,7 @@ func SetTargetMetadata(ctx *gin.Context) { server := server.GetInstance(nil) _, err = server.TargetService.SetTargetMetadata(ctx.Request.Context(), targetId, &models.TargetMetadata{ - Uptime: setTargetMetadataDTO.Uptime, + Uptime: updateDTO.Uptime, }) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target metadata for %s: %w", targetId, err)) @@ -46,3 +46,35 @@ func SetTargetMetadata(ctx *gin.Context) { ctx.Status(200) } + +// UpdateTargetProviderMetadata godoc +// +// @Tags target +// @Summary Update target provider metadata +// @Description Update target provider metadata +// @Param targetId path string true "Target ID" +// @Param metadata body UpdateTargetProviderMetadataDTO true "Provider metadata" +// @Success 200 +// @Router /target/{targetId}/provider-metadata [post] +// +// @id UpdateTargetProviderMetadata +func UpdateTargetProviderMetadata(ctx *gin.Context) { + targetId := ctx.Param("targetId") + + var metadata dto.UpdateTargetProviderMetadataDTO + err := ctx.BindJSON(&metadata) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + err = server.TargetService.UpdateTargetProviderMetadata(ctx.Request.Context(), targetId, metadata.Metadata) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update target provider metadata for %s: %w", targetId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index 56151189f2..33b2c63225 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -4,12 +4,11 @@ package target import ( - "errors" "fmt" "net/http" - "strconv" "github.com/daytonaio/daytona/pkg/api/util" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -23,28 +22,22 @@ import ( // @Description Get target info // @Produce json // @Param targetId path string true "Target ID or Name" -// @Param verbose query bool false "Verbose" +// @Param showOptions query bool false "Show target config options" // @Success 200 {object} TargetDTO // @Router /target/{targetId} [get] // // @id GetTarget func GetTarget(ctx *gin.Context) { targetId := ctx.Param("targetId") - verboseQuery := ctx.Query("verbose") - verbose := false - var err error - - if verboseQuery != "" { - verbose, err = strconv.ParseBool(verboseQuery) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for verbose flag")) - return - } + showTargetConfigOptionsQuery := ctx.Query("showOptions") + var showTargetConfigOptions bool + if showTargetConfigOptionsQuery == "true" { + showTargetConfigOptions = true } server := server.GetInstance(nil) - t, err := server.TargetService.GetTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{Verbose: verbose}) + t, err := server.TargetService.GetTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsTargetNotFound(err) || services.IsTargetDeleted(err) { @@ -54,18 +47,20 @@ func GetTarget(ctx *gin.Context) { return } - maskedOptions, err := util.GetMaskedOptions(server, t.TargetConfig.ProviderInfo.Name, t.TargetConfig.Options) - if err != nil { - t.TargetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - } else { - t.TargetConfig.Options = maskedOptions + if !showTargetConfigOptions { + t.TargetConfig.Options = "" } - for i := range t.Workspaces { - util.HideDaytonaEnvVars(&t.Workspaces[i].EnvVars) - } + apiKeyType, ok := ctx.Get("apiKeyType") + if !ok || apiKeyType == models.ApiKeyTypeClient { + for i := range t.Workspaces { + util.HideDaytonaEnvVars(&t.Workspaces[i].EnvVars) + t.Workspaces[i].ApiKey = "" + } - util.HideDaytonaEnvVars(&t.EnvVars) + util.HideDaytonaEnvVars(&t.EnvVars) + t.ApiKey = "" + } ctx.JSON(200, t) } @@ -75,47 +70,41 @@ func GetTarget(ctx *gin.Context) { // @Tags target // @Summary List targets // @Description List targets +// @Param showOptions query bool false "Show target config options" // @Produce json // @Success 200 {array} TargetDTO // @Router /target [get] -// @Param verbose query bool false "Verbose" // // @id ListTargets func ListTargets(ctx *gin.Context) { - verboseQuery := ctx.Query("verbose") - verbose := false - var err error - - if verboseQuery != "" { - verbose, err = strconv.ParseBool(verboseQuery) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for verbose flag")) - return - } - } - server := server.GetInstance(nil) + showTargetConfigOptionsQuery := ctx.Query("showOptions") + var showTargetConfigOptions bool + if showTargetConfigOptionsQuery == "true" { + showTargetConfigOptions = true + } - targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), nil, services.TargetRetrievalParams{Verbose: verbose}) + targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), nil, services.TargetRetrievalParams{}) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list targets: %w", err)) return } - for i, t := range targetList { - maskedOptions, err := util.GetMaskedOptions(server, t.TargetConfig.ProviderInfo.Name, t.TargetConfig.Options) - if err != nil { - targetList[i].TargetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - continue + for i := range targetList { + if !showTargetConfigOptions { + targetList[i].TargetConfig.Options = "" } - targetList[i].TargetConfig.Options = maskedOptions + apiKeyType, ok := ctx.Get("apiKeyType") + if !ok || apiKeyType == models.ApiKeyTypeClient { + for j := range targetList[i].Workspaces { + util.HideDaytonaEnvVars(&targetList[i].Workspaces[j].EnvVars) + targetList[i].Workspaces[j].ApiKey = "" + } - for j := range targetList[i].Workspaces { - util.HideDaytonaEnvVars(&targetList[i].Workspaces[j].EnvVars) + util.HideDaytonaEnvVars(&targetList[i].EnvVars) + targetList[i].ApiKey = "" } - - util.HideDaytonaEnvVars(&targetList[i].EnvVars) } ctx.JSON(200, targetList) diff --git a/pkg/api/controllers/targetconfig/add.go b/pkg/api/controllers/targetconfig/add.go index 5ff40090cd..85babd5673 100644 --- a/pkg/api/controllers/targetconfig/add.go +++ b/pkg/api/controllers/targetconfig/add.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" @@ -19,11 +18,18 @@ import ( // @Summary Add a target config // @Description Add a target config // @Param targetConfig body AddTargetConfigDTO true "Target config to add" +// @Param showOptions query bool false "Show target config options" // @Success 200 {object} TargetConfig // @Router /target-config [put] // // @id AddTargetConfig func AddTargetConfig(ctx *gin.Context) { + showTargetConfigOptionsQuery := ctx.Query("showOptions") + var showTargetConfigOptions bool + if showTargetConfigOptionsQuery == "true" { + showTargetConfigOptions = true + } + var req services.AddTargetConfigDTO err := ctx.BindJSON(&req) if err != nil { @@ -39,11 +45,8 @@ func AddTargetConfig(ctx *gin.Context) { return } - maskedOptions, err := util.GetMaskedOptions(server, targetConfig.ProviderInfo.Name, targetConfig.Options) - if err != nil { - targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - } else { - targetConfig.Options = maskedOptions + if !showTargetConfigOptions { + targetConfig.Options = "" } ctx.JSON(200, targetConfig) diff --git a/pkg/api/controllers/targetconfig/list.go b/pkg/api/controllers/targetconfig/list.go index e834937576..ac2be887ed 100644 --- a/pkg/api/controllers/targetconfig/list.go +++ b/pkg/api/controllers/targetconfig/list.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" - "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -17,6 +16,7 @@ import ( // @Tags target-config // @Summary List target configs // @Description List target configs +// @Param showOptions query bool false "Show target config options" // @Produce json // @Success 200 {array} TargetConfig // @Router /target-config [get] @@ -24,6 +24,11 @@ import ( // @id ListTargetConfigs func ListTargetConfigs(ctx *gin.Context) { server := server.GetInstance(nil) + showTargetConfigOptionsQuery := ctx.Query("showOptions") + var showTargetConfigOptions bool + if showTargetConfigOptionsQuery == "true" { + showTargetConfigOptions = true + } targetConfigs, err := server.TargetConfigService.List(ctx.Request.Context()) if err != nil { @@ -31,14 +36,10 @@ func ListTargetConfigs(ctx *gin.Context) { return } - for _, targetConfig := range targetConfigs { - maskedOptions, err := util.GetMaskedOptions(server, targetConfig.ProviderInfo.Name, targetConfig.Options) - if err != nil { - targetConfig.Options = fmt.Sprintf("Error: %s", err.Error()) - continue + if !showTargetConfigOptions { + for _, targetConfig := range targetConfigs { + targetConfig.Options = "" } - - targetConfig.Options = maskedOptions } ctx.JSON(200, targetConfigs) diff --git a/pkg/api/controllers/workspace/dto/dto.go b/pkg/api/controllers/workspace/dto/dto.go index dfd11eb3fc..de4672f098 100644 --- a/pkg/api/controllers/workspace/dto/dto.go +++ b/pkg/api/controllers/workspace/dto/dto.go @@ -7,7 +7,11 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -type SetWorkspaceMetadata struct { +type UpdateWorkspaceMetadataDTO struct { Uptime uint64 `json:"uptime" validate:"required"` GitStatus *models.GitStatus `json:"gitStatus,omitempty" validate:"optional"` -} // @name SetWorkspaceMetadata +} // @name UpdateWorkspaceMetadataDTO + +type UpdateWorkspaceProviderMetadataDTO struct { + Metadata string `json:"metadata" validate:"required"` +} // @name UpdateWorkspaceProviderMetadataDTO diff --git a/pkg/api/controllers/workspace/metadata.go b/pkg/api/controllers/workspace/metadata.go index e5eba4755b..8a375cee97 100644 --- a/pkg/api/controllers/workspace/metadata.go +++ b/pkg/api/controllers/workspace/metadata.go @@ -18,8 +18,8 @@ import ( // @Tags workspace // @Summary Set workspace metadata // @Description Set workspace metadata -// @Param workspaceId path string true "Workspace ID" -// @Param setMetadata body SetWorkspaceMetadata true "Set Metadata" +// @Param workspaceId path string true "Workspace ID" +// @Param workspaceMetadata body UpdateWorkspaceMetadataDTO true "Workspace Metadata" // @Success 200 // @Router /workspace/{workspaceId}/metadata [post] // @@ -27,8 +27,8 @@ import ( func SetWorkspaceMetadata(ctx *gin.Context) { workspaceId := ctx.Param("workspaceId") - var setWorkspaceMetadataDTO dto.SetWorkspaceMetadata - err := ctx.BindJSON(&setWorkspaceMetadataDTO) + var updateDTO dto.UpdateWorkspaceMetadataDTO + err := ctx.BindJSON(&updateDTO) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) return @@ -37,8 +37,8 @@ func SetWorkspaceMetadata(ctx *gin.Context) { server := server.GetInstance(nil) _, err = server.WorkspaceService.SetWorkspaceMetadata(ctx.Request.Context(), workspaceId, &models.WorkspaceMetadata{ - Uptime: setWorkspaceMetadataDTO.Uptime, - GitStatus: setWorkspaceMetadataDTO.GitStatus, + Uptime: updateDTO.Uptime, + GitStatus: updateDTO.GitStatus, }) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set workspace metadata for %s: %w", workspaceId, err)) @@ -47,3 +47,35 @@ func SetWorkspaceMetadata(ctx *gin.Context) { ctx.Status(200) } + +// UpdateWorkspaceProviderMetadata godoc +// +// @Tags workspace +// @Summary Update workspace provider metadata +// @Description Update workspace provider metadata +// @Param workspaceId path string true "Workspace ID" +// @Param metadata body UpdateWorkspaceProviderMetadataDTO true "Provider metadata" +// @Success 200 +// @Router /workspace/{workspaceId}/provider-metadata [post] +// +// @id UpdateWorkspaceProviderMetadata +func UpdateWorkspaceProviderMetadata(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + var metadata dto.UpdateWorkspaceProviderMetadataDTO + err := ctx.BindJSON(&metadata) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) + return + } + + server := server.GetInstance(nil) + + err = server.WorkspaceService.UpdateWorkspaceProviderMetadata(ctx.Request.Context(), workspaceId, metadata.Metadata) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update workspace provider metadata for %s: %w", workspaceId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index 5f35f4010f..fa07f821dc 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -77,9 +77,9 @@ func forwardRequestToToolbox(ctx *gin.Context) { }, } - if w.TargetId == "local" && w.Info != nil && w.Info.ProviderMetadata != "" { + if w.TargetId == "local" && w.ProviderMetadata != nil && *w.ProviderMetadata != "" { var metadata map[string]interface{} - err := json.Unmarshal([]byte(w.Info.ProviderMetadata), &metadata) + err := json.Unmarshal([]byte(*w.ProviderMetadata), &metadata) if err == nil { if toolboxPortString, ok := metadata["daytona.toolbox.api.hostPort"]; ok { toolboxPort, err := strconv.ParseUint(toolboxPortString.(string), 10, 16) diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go index 84bf144863..62cb401d7c 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/workspace/workspace.go @@ -4,12 +4,11 @@ package workspace import ( - "errors" "fmt" "net/http" - "strconv" "github.com/daytonaio/daytona/pkg/api/util" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -23,28 +22,15 @@ import ( // @Description Get workspace info // @Produce json // @Param workspaceId path string true "Workspace ID or Name" -// @Param verbose query bool false "Verbose" // @Success 200 {object} WorkspaceDTO // @Router /workspace/{workspaceId} [get] // // @id GetWorkspace func GetWorkspace(ctx *gin.Context) { workspaceId := ctx.Param("workspaceId") - verboseQuery := ctx.Query("verbose") - verbose := false - var err error - - if verboseQuery != "" { - verbose, err = strconv.ParseBool(verboseQuery) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for verbose flag")) - return - } - } - server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{Verbose: verbose}) + w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { @@ -54,8 +40,13 @@ func GetWorkspace(ctx *gin.Context) { return } - util.HideDaytonaEnvVars(&w.EnvVars) - util.HideDaytonaEnvVars(&w.Target.EnvVars) + apiKeyType, ok := ctx.Get("apiKeyType") + if !ok || apiKeyType == models.ApiKeyTypeClient { + util.HideDaytonaEnvVars(&w.EnvVars) + util.HideDaytonaEnvVars(&w.Target.EnvVars) + w.ApiKey = "" + w.Target.ApiKey = "" + } ctx.JSON(200, w) } @@ -68,33 +59,25 @@ func GetWorkspace(ctx *gin.Context) { // @Produce json // @Success 200 {array} WorkspaceDTO // @Router /workspace [get] -// @Param verbose query bool false "Verbose" // // @id ListWorkspaces func ListWorkspaces(ctx *gin.Context) { - verboseQuery := ctx.Query("verbose") - verbose := false - var err error - - if verboseQuery != "" { - verbose, err = strconv.ParseBool(verboseQuery) - if err != nil { - ctx.AbortWithError(http.StatusBadRequest, errors.New("invalid value for verbose flag")) - return - } - } - server := server.GetInstance(nil) - workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), services.WorkspaceRetrievalParams{Verbose: verbose}) + workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), services.WorkspaceRetrievalParams{}) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspaces: %w", err)) return } - for i, _ := range workspaceList { - util.HideDaytonaEnvVars(&workspaceList[i].EnvVars) - util.HideDaytonaEnvVars(&workspaceList[i].Target.EnvVars) + apiKeyType, ok := ctx.Get("apiKeyType") + if !ok || apiKeyType == models.ApiKeyTypeClient { + for i, _ := range workspaceList { + util.HideDaytonaEnvVars(&workspaceList[i].EnvVars) + util.HideDaytonaEnvVars(&workspaceList[i].Target.EnvVars) + workspaceList[i].ApiKey = "" + workspaceList[i].Target.ApiKey = "" + } } ctx.JSON(200, workspaceList) diff --git a/pkg/api/controllers/workspacetemplate/workspace_template.go b/pkg/api/controllers/workspacetemplate/workspace_template.go index 1eb86005fa..650846c6ac 100644 --- a/pkg/api/controllers/workspacetemplate/workspace_template.go +++ b/pkg/api/controllers/workspacetemplate/workspace_template.go @@ -11,7 +11,7 @@ import ( "strconv" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/internal/util/apiclient/conversion" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -130,9 +130,23 @@ func SetWorkspaceTemplate(ctx *gin.Context) { s := server.GetInstance(nil) - workspaceTemplate := conversion.ToWorkspaceTemplate(req) + workspaceTemplate := models.WorkspaceTemplate{ + Name: req.Name, + BuildConfig: req.BuildConfig, + RepositoryUrl: req.RepositoryUrl, + EnvVars: req.EnvVars, + GitProviderConfigId: req.GitProviderConfigId, + } + + if req.Image != nil { + workspaceTemplate.Image = *req.Image + } + + if req.User != nil { + workspaceTemplate.User = *req.User + } - err = s.WorkspaceTemplateService.Save(ctx.Request.Context(), workspaceTemplate) + err = s.WorkspaceTemplateService.Save(ctx.Request.Context(), &workspaceTemplate) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to save workspace template: %s", err.Error())) return diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 570a046ac0..00d02a04d6 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -196,6 +196,39 @@ const docTemplate = `{ } } }, + "/build/successful/{repoUrl}": { + "get": { + "description": "List successful builds for Git repository", + "produces": [ + "application/json" + ], + "tags": [ + "build" + ], + "summary": "List successful builds for Git repository", + "operationId": "ListSuccessfulBuilds", + "parameters": [ + { + "type": "string", + "description": "Repository URL", + "name": "repoUrl", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/BuildDTO" + } + } + } + } + } + }, "/build/{buildId}": { "get": { "description": "Get build data", @@ -875,6 +908,40 @@ const docTemplate = `{ ], "summary": "List jobs", "operationId": "ListJobs", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Job States", + "name": "states", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Job Actions", + "name": "actions", + "in": "query" + }, + { + "type": "string", + "description": "Resource ID", + "name": "resourceId", + "in": "query" + }, + { + "type": "string", + "description": "Resource Type", + "name": "resourceType", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -888,7 +955,61 @@ const docTemplate = `{ } } }, - "/provider": { + "/runner": { + "get": { + "description": "List runners", + "produces": [ + "application/json" + ], + "tags": [ + "runner" + ], + "summary": "List runners", + "operationId": "ListRunners", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/RunnerDTO" + } + } + } + } + }, + "post": { + "description": "Register a runner", + "produces": [ + "application/json" + ], + "tags": [ + "runner" + ], + "summary": "Register a runner", + "operationId": "RegisterRunner", + "parameters": [ + { + "description": "Register runner", + "name": "runner", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/RegisterRunnerDTO" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/RegisterRunnerResultDTO" + } + } + } + } + }, + "/runner/provider": { "get": { "description": "List providers", "produces": [ @@ -899,40 +1020,71 @@ const docTemplate = `{ ], "summary": "List providers", "operationId": "ListProviders", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "query" + } + ], "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/Provider" + "$ref": "#/definitions/ProviderInfo" } } } } } }, - "/provider/install": { - "post": { - "description": "Install a provider", - "consumes": [ + "/runner/{runnerId}": { + "get": { + "description": "Get a runner", + "produces": [ "application/json" ], "tags": [ - "provider" + "runner" ], - "summary": "Install a provider", - "operationId": "InstallProvider", + "summary": "Get a runner", + "operationId": "GetRunner", "parameters": [ { - "description": "Provider to install", - "name": "provider", - "in": "body", - "required": true, + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", "schema": { - "$ref": "#/definitions/InstallProviderRequest" + "$ref": "#/definitions/RunnerDTO" } } + } + }, + "delete": { + "description": "Remove runner", + "tags": [ + "runner" + ], + "summary": "Remove runner", + "operationId": "RemoveRunner", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + } ], "responses": { "200": { @@ -941,19 +1093,22 @@ const docTemplate = `{ } } }, - "/provider/{provider}/target-config-manifest": { + "/runner/{runnerId}/jobs": { "get": { - "description": "Get provider target config manifest", + "description": "List runner jobs", + "produces": [ + "application/json" + ], "tags": [ - "provider" + "runner" ], - "summary": "Get provider target config manifest", - "operationId": "GetTargetConfigManifest", + "summary": "List runner jobs", + "operationId": "ListRunnerJobs", "parameters": [ { "type": "string", - "description": "Provider name", - "name": "provider", + "description": "Runner ID", + "name": "runnerId", "in": "path", "required": true } @@ -962,28 +1117,184 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/TargetConfigManifest" + "type": "array", + "items": { + "$ref": "#/definitions/Job" + } } } } } }, - "/provider/{provider}/uninstall": { + "/runner/{runnerId}/jobs/{jobId}/state": { "post": { - "description": "Uninstall a provider", - "consumes": [ + "description": "Update job state", + "produces": [ "application/json" ], + "tags": [ + "runner" + ], + "summary": "Update job state", + "operationId": "UpdateJobState", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Job ID", + "name": "jobId", + "in": "path", + "required": true + }, + { + "description": "Update job state", + "name": "updateJobState", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateJobState" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/metadata": { + "post": { + "description": "Set runner metadata", + "tags": [ + "runner" + ], + "summary": "Set runner metadata", + "operationId": "SetRunnerMetadata", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "description": "Runner Metadata", + "name": "runnerMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateRunnerMetadataDTO" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/provider/install": { + "post": { + "description": "Install provider", + "tags": [ + "provider" + ], + "summary": "Install provider", + "operationId": "InstallProvider", + "parameters": [ + { + "description": "Install provider", + "name": "installProviderDto", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/InstallProviderDTO" + } + }, + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/provider/{providerName}/uninstall": { + "post": { + "description": "Uninstall provider", "tags": [ "provider" ], - "summary": "Uninstall a provider", + "summary": "Uninstall provider", "operationId": "UninstallProvider", "parameters": [ { "type": "string", - "description": "Provider to uninstall", - "name": "provider", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Provider name", + "name": "providerName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/provider/{providerName}/update": { + "post": { + "description": "Update provider", + "tags": [ + "provider" + ], + "summary": "Update provider", + "operationId": "UpdateProvider", + "parameters": [ + { + "description": "Provider download URLs", + "name": "downloadUrls", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/DownloadUrls" + } + }, + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Provider name", + "name": "providerName", "in": "path", "required": true } @@ -1132,8 +1443,8 @@ const docTemplate = `{ "parameters": [ { "type": "boolean", - "description": "Verbose", - "name": "verbose", + "description": "Show target config options", + "name": "showOptions", "in": "query" } ], @@ -1191,6 +1502,14 @@ const docTemplate = `{ ], "summary": "List target configs", "operationId": "ListTargetConfigs", + "parameters": [ + { + "type": "boolean", + "description": "Show target config options", + "name": "showOptions", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -1219,6 +1538,12 @@ const docTemplate = `{ "schema": { "$ref": "#/definitions/AddTargetConfigDTO" } + }, + { + "type": "boolean", + "description": "Show target config options", + "name": "showOptions", + "in": "query" } ], "responses": { @@ -1276,8 +1601,8 @@ const docTemplate = `{ }, { "type": "boolean", - "description": "Verbose", - "name": "verbose", + "description": "Show target config options", + "name": "showOptions", "in": "query" } ], @@ -1319,6 +1644,30 @@ const docTemplate = `{ } } }, + "/target/{targetId}/handle-successful-creation": { + "post": { + "description": "Handles successful creation of the target", + "tags": [ + "target" + ], + "summary": "Handles successful creation of the target", + "operationId": "HandleSuccessfulCreation", + "parameters": [ + { + "type": "string", + "description": "Target ID or name", + "name": "targetId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/metadata": { "post": { "description": "Set target metadata", @@ -1336,12 +1685,45 @@ const docTemplate = `{ "required": true }, { - "description": "Set Metadata", - "name": "setMetadata", + "description": "Target Metadata", + "name": "targetMetadata", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/SetTargetMetadata" + "$ref": "#/definitions/UpdateTargetMetadataDTO" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/target/{targetId}/provider-metadata": { + "post": { + "description": "Update target provider metadata", + "tags": [ + "target" + ], + "summary": "Update target provider metadata", + "operationId": "UpdateTargetProviderMetadata", + "parameters": [ + { + "type": "string", + "description": "Target ID", + "name": "targetId", + "in": "path", + "required": true + }, + { + "description": "Provider metadata", + "name": "metadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateTargetProviderMetadataDTO" } } ], @@ -1435,14 +1817,6 @@ const docTemplate = `{ ], "summary": "List workspaces", "operationId": "ListWorkspaces", - "parameters": [ - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" - } - ], "responses": { "200": { "description": "OK", @@ -1862,12 +2236,6 @@ const docTemplate = `{ "name": "workspaceId", "in": "path", "required": true - }, - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" } ], "responses": { @@ -1884,8 +2252,38 @@ const docTemplate = `{ "tags": [ "workspace" ], - "summary": "Remove workspace", - "operationId": "RemoveWorkspace", + "summary": "Remove workspace", + "operationId": "RemoveWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/metadata": { + "post": { + "description": "Set workspace metadata", + "tags": [ + "workspace" + ], + "summary": "Set workspace metadata", + "operationId": "SetWorkspaceMetadata", "parameters": [ { "type": "string", @@ -1895,10 +2293,13 @@ const docTemplate = `{ "required": true }, { - "type": "boolean", - "description": "Force", - "name": "force", - "in": "query" + "description": "Workspace Metadata", + "name": "workspaceMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateWorkspaceMetadataDTO" + } } ], "responses": { @@ -1908,14 +2309,14 @@ const docTemplate = `{ } } }, - "/workspace/{workspaceId}/metadata": { + "/workspace/{workspaceId}/provider-metadata": { "post": { - "description": "Set workspace metadata", + "description": "Update workspace provider metadata", "tags": [ "workspace" ], - "summary": "Set workspace metadata", - "operationId": "SetWorkspaceMetadata", + "summary": "Update workspace provider metadata", + "operationId": "UpdateWorkspaceProviderMetadata", "parameters": [ { "type": "string", @@ -1925,12 +2326,12 @@ const docTemplate = `{ "required": true }, { - "description": "Set Metadata", - "name": "setMetadata", + "description": "Provider metadata", + "name": "metadata", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/SetWorkspaceMetadata" + "$ref": "#/definitions/UpdateWorkspaceProviderMetadataDTO" } } ], @@ -3338,7 +3739,7 @@ const docTemplate = `{ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" + "$ref": "#/definitions/ProviderInfo" } } }, @@ -3743,6 +4144,12 @@ const docTemplate = `{ } } }, + "DownloadUrls": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "EnvironmentVariable": { "type": "object", "required": [ @@ -4238,7 +4645,7 @@ const docTemplate = `{ } } }, - "InstallProviderRequest": { + "InstallProviderDTO": { "type": "object", "required": [ "downloadUrls", @@ -4246,10 +4653,7 @@ const docTemplate = `{ ], "properties": { "downloadUrls": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/DownloadUrls" }, "name": { "type": "string" @@ -4280,12 +4684,19 @@ const docTemplate = `{ "id": { "type": "string" }, + "metadata": { + "description": "JSON encoded metadata", + "type": "string" + }, "resourceId": { "type": "string" }, "resourceType": { "$ref": "#/definitions/ResourceType" }, + "runnerId": { + "type": "string" + }, "state": { "$ref": "#/definitions/JobState" }, @@ -4582,24 +4993,76 @@ const docTemplate = `{ } } }, - "Provider": { + "ProviderInfo": { "type": "object", "required": [ "name", + "runnerId", + "runnerName", + "targetConfigManifest", "version" ], "properties": { + "agentlessTarget": { + "type": "boolean" + }, "label": { "type": "string" }, "name": { "type": "string" }, + "runnerId": { + "type": "string" + }, + "runnerName": { + "type": "string" + }, + "targetConfigManifest": { + "$ref": "#/definitions/TargetConfigManifest" + }, "version": { "type": "string" } } }, + "RegisterRunnerDTO": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "RegisterRunnerResultDTO": { + "type": "object", + "required": [ + "apiKey", + "id", + "name" + ], + "properties": { + "apiKey": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/RunnerMetadata" + }, + "name": { + "type": "string" + } + } + }, "ReplaceRequest": { "type": "object", "required": [ @@ -4670,14 +5133,67 @@ const docTemplate = `{ "enum": [ "workspace", "target", - "build" + "build", + "runner" ], "x-enum-varnames": [ "ResourceTypeWorkspace", "ResourceTypeTarget", - "ResourceTypeBuild" + "ResourceTypeBuild", + "ResourceTypeRunner" ] }, + "RunnerDTO": { + "type": "object", + "required": [ + "id", + "name", + "state" + ], + "properties": { + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/RunnerMetadata" + }, + "name": { + "type": "string" + }, + "state": { + "$ref": "#/definitions/ResourceState" + } + } + }, + "RunnerMetadata": { + "type": "object", + "required": [ + "providers", + "runnerId", + "updatedAt", + "uptime" + ], + "properties": { + "providers": { + "type": "array", + "items": { + "$ref": "#/definitions/ProviderInfo" + } + }, + "runnerId": { + "type": "string" + }, + "runningJobs": { + "type": "integer" + }, + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" + } + } + }, "Sample": { "type": "object", "required": [ @@ -4725,7 +5241,6 @@ const docTemplate = `{ "localBuilderRegistryImage", "localBuilderRegistryPort", "logFile", - "providersDir", "registryUrl", "serverDownloadUrl" ], @@ -4766,12 +5281,12 @@ const docTemplate = `{ "localBuilderRegistryPort": { "type": "integer" }, + "localRunnerDisabled": { + "type": "boolean" + }, "logFile": { "$ref": "#/definitions/LogFileConfig" }, - "providersDir": { - "type": "string" - }, "registryUrl": { "type": "string" }, @@ -4862,31 +5377,6 @@ const docTemplate = `{ } } }, - "SetTargetMetadata": { - "type": "object", - "required": [ - "uptime" - ], - "properties": { - "uptime": { - "type": "integer" - } - } - }, - "SetWorkspaceMetadata": { - "type": "object", - "required": [ - "uptime" - ], - "properties": { - "gitStatus": { - "$ref": "#/definitions/GitStatus" - }, - "uptime": { - "type": "integer" - } - } - }, "SigningMethod": { "type": "string", "enum": [ @@ -4954,6 +5444,9 @@ const docTemplate = `{ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "targetConfig": { "$ref": "#/definitions/TargetConfig" }, @@ -4992,7 +5485,7 @@ const docTemplate = `{ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" + "$ref": "#/definitions/ProviderInfo" } } }, @@ -5035,7 +5528,7 @@ const docTemplate = `{ } }, "type": { - "$ref": "#/definitions/provider.TargetConfigPropertyType" + "$ref": "#/definitions/models.TargetConfigPropertyType" } } }, @@ -5064,9 +5557,6 @@ const docTemplate = `{ "id": { "type": "string" }, - "info": { - "$ref": "#/definitions/TargetInfo" - }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5076,6 +5566,9 @@ const docTemplate = `{ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "state": { "$ref": "#/definitions/ResourceState" }, @@ -5093,56 +5586,103 @@ const docTemplate = `{ } } }, - "TargetInfo": { + "TargetMetadata": { "type": "object", "required": [ - "name" + "targetId", + "updatedAt", + "uptime" ], "properties": { - "name": { + "targetId": { "type": "string" }, - "providerMetadata": { + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" + } + } + }, + "UpdateJobState": { + "type": "object", + "required": [ + "state" + ], + "properties": { + "errorMessage": { "type": "string" + }, + "state": { + "$ref": "#/definitions/JobState" } } }, - "TargetMetadata": { + "UpdateRunnerMetadataDTO": { "type": "object", "required": [ - "targetId", - "updatedAt", + "providers", "uptime" ], "properties": { - "targetId": { - "type": "string" + "providers": { + "type": "array", + "items": { + "$ref": "#/definitions/ProviderInfo" + } }, - "updatedAt": { - "type": "string" + "runningJobs": { + "type": "integer" }, "uptime": { "type": "integer" } } }, - "TargetProviderInfo": { + "UpdateTargetMetadataDTO": { "type": "object", "required": [ - "name", - "version" + "uptime" ], "properties": { - "agentlessTarget": { - "type": "boolean" - }, - "label": { - "type": "string" - }, - "name": { + "uptime": { + "type": "integer" + } + } + }, + "UpdateTargetProviderMetadataDTO": { + "type": "object", + "required": [ + "metadata" + ], + "properties": { + "metadata": { "type": "string" + } + } + }, + "UpdateWorkspaceMetadataDTO": { + "type": "object", + "required": [ + "uptime" + ], + "properties": { + "gitStatus": { + "$ref": "#/definitions/GitStatus" }, - "version": { + "uptime": { + "type": "integer" + } + } + }, + "UpdateWorkspaceProviderMetadataDTO": { + "type": "object", + "required": [ + "metadata" + ], + "properties": { + "metadata": { "type": "string" } } @@ -5150,6 +5690,7 @@ const docTemplate = `{ "Workspace": { "type": "object", "required": [ + "apiKey", "envVars", "id", "image", @@ -5160,6 +5701,9 @@ const docTemplate = `{ "user" ], "properties": { + "apiKey": { + "type": "string" + }, "buildConfig": { "$ref": "#/definitions/BuildConfig" }, @@ -5187,6 +5731,9 @@ const docTemplate = `{ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "repository": { "$ref": "#/definitions/GitRepository" }, @@ -5204,6 +5751,7 @@ const docTemplate = `{ "WorkspaceDTO": { "type": "object", "required": [ + "apiKey", "envVars", "id", "image", @@ -5215,6 +5763,9 @@ const docTemplate = `{ "user" ], "properties": { + "apiKey": { + "type": "string" + }, "buildConfig": { "$ref": "#/definitions/BuildConfig" }, @@ -5233,9 +5784,6 @@ const docTemplate = `{ "image": { "type": "string" }, - "info": { - "$ref": "#/definitions/WorkspaceInfo" - }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5245,6 +5793,9 @@ const docTemplate = `{ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "repository": { "$ref": "#/definitions/GitRepository" }, @@ -5270,32 +5821,6 @@ const docTemplate = `{ } } }, - "WorkspaceInfo": { - "type": "object", - "required": [ - "created", - "isRunning", - "name", - "targetId" - ], - "properties": { - "created": { - "type": "string" - }, - "isRunning": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "providerMetadata": { - "type": "string" - }, - "targetId": { - "type": "string" - } - } - }, "WorkspaceMetadata": { "type": "object", "required": [ @@ -5369,12 +5894,14 @@ const docTemplate = `{ "enum": [ "client", "workspace", - "target" + "target", + "runner" ], "x-enum-varnames": [ "ApiKeyTypeClient", "ApiKeyTypeWorkspace", - "ApiKeyTypeTarget" + "ApiKeyTypeTarget", + "ApiKeyTypeRunner" ] }, "models.JobAction": { @@ -5386,7 +5913,10 @@ const docTemplate = `{ "restart", "delete", "force-delete", - "run" + "run", + "install-provider", + "uninstall-provider", + "update-provider" ], "x-enum-varnames": [ "JobActionCreate", @@ -5395,7 +5925,10 @@ const docTemplate = `{ "JobActionRestart", "JobActionDelete", "JobActionForceDelete", - "JobActionRun" + "JobActionRun", + "JobActionInstallProvider", + "JobActionUninstallProvider", + "JobActionUpdateProvider" ] }, "models.ResourceStateName": { @@ -5443,7 +5976,7 @@ const docTemplate = `{ "ResourceStateNameDeleted" ] }, - "provider.TargetConfigPropertyType": { + "models.TargetConfigPropertyType": { "type": "string", "enum": [ "string", diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 705f812d43..7bda2d048a 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -193,6 +193,39 @@ } } }, + "/build/successful/{repoUrl}": { + "get": { + "description": "List successful builds for Git repository", + "produces": [ + "application/json" + ], + "tags": [ + "build" + ], + "summary": "List successful builds for Git repository", + "operationId": "ListSuccessfulBuilds", + "parameters": [ + { + "type": "string", + "description": "Repository URL", + "name": "repoUrl", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/BuildDTO" + } + } + } + } + } + }, "/build/{buildId}": { "get": { "description": "Get build data", @@ -872,6 +905,40 @@ ], "summary": "List jobs", "operationId": "ListJobs", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Job States", + "name": "states", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Job Actions", + "name": "actions", + "in": "query" + }, + { + "type": "string", + "description": "Resource ID", + "name": "resourceId", + "in": "query" + }, + { + "type": "string", + "description": "Resource Type", + "name": "resourceType", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -885,7 +952,61 @@ } } }, - "/provider": { + "/runner": { + "get": { + "description": "List runners", + "produces": [ + "application/json" + ], + "tags": [ + "runner" + ], + "summary": "List runners", + "operationId": "ListRunners", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/RunnerDTO" + } + } + } + } + }, + "post": { + "description": "Register a runner", + "produces": [ + "application/json" + ], + "tags": [ + "runner" + ], + "summary": "Register a runner", + "operationId": "RegisterRunner", + "parameters": [ + { + "description": "Register runner", + "name": "runner", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/RegisterRunnerDTO" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/RegisterRunnerResultDTO" + } + } + } + } + }, + "/runner/provider": { "get": { "description": "List providers", "produces": [ @@ -896,40 +1017,71 @@ ], "summary": "List providers", "operationId": "ListProviders", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "query" + } + ], "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { - "$ref": "#/definitions/Provider" + "$ref": "#/definitions/ProviderInfo" } } } } } }, - "/provider/install": { - "post": { - "description": "Install a provider", - "consumes": [ + "/runner/{runnerId}": { + "get": { + "description": "Get a runner", + "produces": [ "application/json" ], "tags": [ - "provider" + "runner" ], - "summary": "Install a provider", - "operationId": "InstallProvider", + "summary": "Get a runner", + "operationId": "GetRunner", "parameters": [ { - "description": "Provider to install", - "name": "provider", - "in": "body", - "required": true, + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", "schema": { - "$ref": "#/definitions/InstallProviderRequest" + "$ref": "#/definitions/RunnerDTO" } } + } + }, + "delete": { + "description": "Remove runner", + "tags": [ + "runner" + ], + "summary": "Remove runner", + "operationId": "RemoveRunner", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + } ], "responses": { "200": { @@ -938,19 +1090,22 @@ } } }, - "/provider/{provider}/target-config-manifest": { + "/runner/{runnerId}/jobs": { "get": { - "description": "Get provider target config manifest", + "description": "List runner jobs", + "produces": [ + "application/json" + ], "tags": [ - "provider" + "runner" ], - "summary": "Get provider target config manifest", - "operationId": "GetTargetConfigManifest", + "summary": "List runner jobs", + "operationId": "ListRunnerJobs", "parameters": [ { "type": "string", - "description": "Provider name", - "name": "provider", + "description": "Runner ID", + "name": "runnerId", "in": "path", "required": true } @@ -959,28 +1114,184 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/TargetConfigManifest" + "type": "array", + "items": { + "$ref": "#/definitions/Job" + } } } } } }, - "/provider/{provider}/uninstall": { + "/runner/{runnerId}/jobs/{jobId}/state": { "post": { - "description": "Uninstall a provider", - "consumes": [ + "description": "Update job state", + "produces": [ "application/json" ], + "tags": [ + "runner" + ], + "summary": "Update job state", + "operationId": "UpdateJobState", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Job ID", + "name": "jobId", + "in": "path", + "required": true + }, + { + "description": "Update job state", + "name": "updateJobState", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateJobState" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/metadata": { + "post": { + "description": "Set runner metadata", + "tags": [ + "runner" + ], + "summary": "Set runner metadata", + "operationId": "SetRunnerMetadata", + "parameters": [ + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "description": "Runner Metadata", + "name": "runnerMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateRunnerMetadataDTO" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/provider/install": { + "post": { + "description": "Install provider", + "tags": [ + "provider" + ], + "summary": "Install provider", + "operationId": "InstallProvider", + "parameters": [ + { + "description": "Install provider", + "name": "installProviderDto", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/InstallProviderDTO" + } + }, + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/provider/{providerName}/uninstall": { + "post": { + "description": "Uninstall provider", "tags": [ "provider" ], - "summary": "Uninstall a provider", + "summary": "Uninstall provider", "operationId": "UninstallProvider", "parameters": [ { "type": "string", - "description": "Provider to uninstall", - "name": "provider", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Provider name", + "name": "providerName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/runner/{runnerId}/provider/{providerName}/update": { + "post": { + "description": "Update provider", + "tags": [ + "provider" + ], + "summary": "Update provider", + "operationId": "UpdateProvider", + "parameters": [ + { + "description": "Provider download URLs", + "name": "downloadUrls", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/DownloadUrls" + } + }, + { + "type": "string", + "description": "Runner ID", + "name": "runnerId", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Provider name", + "name": "providerName", "in": "path", "required": true } @@ -1129,8 +1440,8 @@ "parameters": [ { "type": "boolean", - "description": "Verbose", - "name": "verbose", + "description": "Show target config options", + "name": "showOptions", "in": "query" } ], @@ -1188,6 +1499,14 @@ ], "summary": "List target configs", "operationId": "ListTargetConfigs", + "parameters": [ + { + "type": "boolean", + "description": "Show target config options", + "name": "showOptions", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -1216,6 +1535,12 @@ "schema": { "$ref": "#/definitions/AddTargetConfigDTO" } + }, + { + "type": "boolean", + "description": "Show target config options", + "name": "showOptions", + "in": "query" } ], "responses": { @@ -1273,8 +1598,8 @@ }, { "type": "boolean", - "description": "Verbose", - "name": "verbose", + "description": "Show target config options", + "name": "showOptions", "in": "query" } ], @@ -1316,6 +1641,30 @@ } } }, + "/target/{targetId}/handle-successful-creation": { + "post": { + "description": "Handles successful creation of the target", + "tags": [ + "target" + ], + "summary": "Handles successful creation of the target", + "operationId": "HandleSuccessfulCreation", + "parameters": [ + { + "type": "string", + "description": "Target ID or name", + "name": "targetId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/metadata": { "post": { "description": "Set target metadata", @@ -1333,12 +1682,45 @@ "required": true }, { - "description": "Set Metadata", - "name": "setMetadata", + "description": "Target Metadata", + "name": "targetMetadata", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/SetTargetMetadata" + "$ref": "#/definitions/UpdateTargetMetadataDTO" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/target/{targetId}/provider-metadata": { + "post": { + "description": "Update target provider metadata", + "tags": [ + "target" + ], + "summary": "Update target provider metadata", + "operationId": "UpdateTargetProviderMetadata", + "parameters": [ + { + "type": "string", + "description": "Target ID", + "name": "targetId", + "in": "path", + "required": true + }, + { + "description": "Provider metadata", + "name": "metadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateTargetProviderMetadataDTO" } } ], @@ -1432,14 +1814,6 @@ ], "summary": "List workspaces", "operationId": "ListWorkspaces", - "parameters": [ - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" - } - ], "responses": { "200": { "description": "OK", @@ -1859,12 +2233,6 @@ "name": "workspaceId", "in": "path", "required": true - }, - { - "type": "boolean", - "description": "Verbose", - "name": "verbose", - "in": "query" } ], "responses": { @@ -1881,8 +2249,38 @@ "tags": [ "workspace" ], - "summary": "Remove workspace", - "operationId": "RemoveWorkspace", + "summary": "Remove workspace", + "operationId": "RemoveWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Force", + "name": "force", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspace/{workspaceId}/metadata": { + "post": { + "description": "Set workspace metadata", + "tags": [ + "workspace" + ], + "summary": "Set workspace metadata", + "operationId": "SetWorkspaceMetadata", "parameters": [ { "type": "string", @@ -1892,10 +2290,13 @@ "required": true }, { - "type": "boolean", - "description": "Force", - "name": "force", - "in": "query" + "description": "Workspace Metadata", + "name": "workspaceMetadata", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateWorkspaceMetadataDTO" + } } ], "responses": { @@ -1905,14 +2306,14 @@ } } }, - "/workspace/{workspaceId}/metadata": { + "/workspace/{workspaceId}/provider-metadata": { "post": { - "description": "Set workspace metadata", + "description": "Update workspace provider metadata", "tags": [ "workspace" ], - "summary": "Set workspace metadata", - "operationId": "SetWorkspaceMetadata", + "summary": "Update workspace provider metadata", + "operationId": "UpdateWorkspaceProviderMetadata", "parameters": [ { "type": "string", @@ -1922,12 +2323,12 @@ "required": true }, { - "description": "Set Metadata", - "name": "setMetadata", + "description": "Provider metadata", + "name": "metadata", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/SetWorkspaceMetadata" + "$ref": "#/definitions/UpdateWorkspaceProviderMetadataDTO" } } ], @@ -3335,7 +3736,7 @@ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" + "$ref": "#/definitions/ProviderInfo" } } }, @@ -3740,6 +4141,12 @@ } } }, + "DownloadUrls": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "EnvironmentVariable": { "type": "object", "required": [ @@ -4235,7 +4642,7 @@ } } }, - "InstallProviderRequest": { + "InstallProviderDTO": { "type": "object", "required": [ "downloadUrls", @@ -4243,10 +4650,7 @@ ], "properties": { "downloadUrls": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "$ref": "#/definitions/DownloadUrls" }, "name": { "type": "string" @@ -4277,12 +4681,19 @@ "id": { "type": "string" }, + "metadata": { + "description": "JSON encoded metadata", + "type": "string" + }, "resourceId": { "type": "string" }, "resourceType": { "$ref": "#/definitions/ResourceType" }, + "runnerId": { + "type": "string" + }, "state": { "$ref": "#/definitions/JobState" }, @@ -4579,24 +4990,76 @@ } } }, - "Provider": { + "ProviderInfo": { "type": "object", "required": [ "name", + "runnerId", + "runnerName", + "targetConfigManifest", "version" ], "properties": { + "agentlessTarget": { + "type": "boolean" + }, "label": { "type": "string" }, "name": { "type": "string" }, + "runnerId": { + "type": "string" + }, + "runnerName": { + "type": "string" + }, + "targetConfigManifest": { + "$ref": "#/definitions/TargetConfigManifest" + }, "version": { "type": "string" } } }, + "RegisterRunnerDTO": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "RegisterRunnerResultDTO": { + "type": "object", + "required": [ + "apiKey", + "id", + "name" + ], + "properties": { + "apiKey": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/RunnerMetadata" + }, + "name": { + "type": "string" + } + } + }, "ReplaceRequest": { "type": "object", "required": [ @@ -4667,14 +5130,67 @@ "enum": [ "workspace", "target", - "build" + "build", + "runner" ], "x-enum-varnames": [ "ResourceTypeWorkspace", "ResourceTypeTarget", - "ResourceTypeBuild" + "ResourceTypeBuild", + "ResourceTypeRunner" ] }, + "RunnerDTO": { + "type": "object", + "required": [ + "id", + "name", + "state" + ], + "properties": { + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/RunnerMetadata" + }, + "name": { + "type": "string" + }, + "state": { + "$ref": "#/definitions/ResourceState" + } + } + }, + "RunnerMetadata": { + "type": "object", + "required": [ + "providers", + "runnerId", + "updatedAt", + "uptime" + ], + "properties": { + "providers": { + "type": "array", + "items": { + "$ref": "#/definitions/ProviderInfo" + } + }, + "runnerId": { + "type": "string" + }, + "runningJobs": { + "type": "integer" + }, + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" + } + } + }, "Sample": { "type": "object", "required": [ @@ -4722,7 +5238,6 @@ "localBuilderRegistryImage", "localBuilderRegistryPort", "logFile", - "providersDir", "registryUrl", "serverDownloadUrl" ], @@ -4763,12 +5278,12 @@ "localBuilderRegistryPort": { "type": "integer" }, + "localRunnerDisabled": { + "type": "boolean" + }, "logFile": { "$ref": "#/definitions/LogFileConfig" }, - "providersDir": { - "type": "string" - }, "registryUrl": { "type": "string" }, @@ -4859,31 +5374,6 @@ } } }, - "SetTargetMetadata": { - "type": "object", - "required": [ - "uptime" - ], - "properties": { - "uptime": { - "type": "integer" - } - } - }, - "SetWorkspaceMetadata": { - "type": "object", - "required": [ - "uptime" - ], - "properties": { - "gitStatus": { - "$ref": "#/definitions/GitStatus" - }, - "uptime": { - "type": "integer" - } - } - }, "SigningMethod": { "type": "string", "enum": [ @@ -4951,6 +5441,9 @@ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "targetConfig": { "$ref": "#/definitions/TargetConfig" }, @@ -4989,7 +5482,7 @@ "type": "string" }, "providerInfo": { - "$ref": "#/definitions/TargetProviderInfo" + "$ref": "#/definitions/ProviderInfo" } } }, @@ -5032,7 +5525,7 @@ } }, "type": { - "$ref": "#/definitions/provider.TargetConfigPropertyType" + "$ref": "#/definitions/models.TargetConfigPropertyType" } } }, @@ -5061,9 +5554,6 @@ "id": { "type": "string" }, - "info": { - "$ref": "#/definitions/TargetInfo" - }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5073,6 +5563,9 @@ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "state": { "$ref": "#/definitions/ResourceState" }, @@ -5090,56 +5583,103 @@ } } }, - "TargetInfo": { + "TargetMetadata": { "type": "object", "required": [ - "name" + "targetId", + "updatedAt", + "uptime" ], "properties": { - "name": { + "targetId": { "type": "string" }, - "providerMetadata": { + "updatedAt": { + "type": "string" + }, + "uptime": { + "type": "integer" + } + } + }, + "UpdateJobState": { + "type": "object", + "required": [ + "state" + ], + "properties": { + "errorMessage": { "type": "string" + }, + "state": { + "$ref": "#/definitions/JobState" } } }, - "TargetMetadata": { + "UpdateRunnerMetadataDTO": { "type": "object", "required": [ - "targetId", - "updatedAt", + "providers", "uptime" ], "properties": { - "targetId": { - "type": "string" + "providers": { + "type": "array", + "items": { + "$ref": "#/definitions/ProviderInfo" + } }, - "updatedAt": { - "type": "string" + "runningJobs": { + "type": "integer" }, "uptime": { "type": "integer" } } }, - "TargetProviderInfo": { + "UpdateTargetMetadataDTO": { "type": "object", "required": [ - "name", - "version" + "uptime" ], "properties": { - "agentlessTarget": { - "type": "boolean" - }, - "label": { - "type": "string" - }, - "name": { + "uptime": { + "type": "integer" + } + } + }, + "UpdateTargetProviderMetadataDTO": { + "type": "object", + "required": [ + "metadata" + ], + "properties": { + "metadata": { "type": "string" + } + } + }, + "UpdateWorkspaceMetadataDTO": { + "type": "object", + "required": [ + "uptime" + ], + "properties": { + "gitStatus": { + "$ref": "#/definitions/GitStatus" }, - "version": { + "uptime": { + "type": "integer" + } + } + }, + "UpdateWorkspaceProviderMetadataDTO": { + "type": "object", + "required": [ + "metadata" + ], + "properties": { + "metadata": { "type": "string" } } @@ -5147,6 +5687,7 @@ "Workspace": { "type": "object", "required": [ + "apiKey", "envVars", "id", "image", @@ -5157,6 +5698,9 @@ "user" ], "properties": { + "apiKey": { + "type": "string" + }, "buildConfig": { "$ref": "#/definitions/BuildConfig" }, @@ -5184,6 +5728,9 @@ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "repository": { "$ref": "#/definitions/GitRepository" }, @@ -5201,6 +5748,7 @@ "WorkspaceDTO": { "type": "object", "required": [ + "apiKey", "envVars", "id", "image", @@ -5212,6 +5760,9 @@ "user" ], "properties": { + "apiKey": { + "type": "string" + }, "buildConfig": { "$ref": "#/definitions/BuildConfig" }, @@ -5230,9 +5781,6 @@ "image": { "type": "string" }, - "info": { - "$ref": "#/definitions/WorkspaceInfo" - }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5242,6 +5790,9 @@ "name": { "type": "string" }, + "providerMetadata": { + "type": "string" + }, "repository": { "$ref": "#/definitions/GitRepository" }, @@ -5267,32 +5818,6 @@ } } }, - "WorkspaceInfo": { - "type": "object", - "required": [ - "created", - "isRunning", - "name", - "targetId" - ], - "properties": { - "created": { - "type": "string" - }, - "isRunning": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "providerMetadata": { - "type": "string" - }, - "targetId": { - "type": "string" - } - } - }, "WorkspaceMetadata": { "type": "object", "required": [ @@ -5366,12 +5891,14 @@ "enum": [ "client", "workspace", - "target" + "target", + "runner" ], "x-enum-varnames": [ "ApiKeyTypeClient", "ApiKeyTypeWorkspace", - "ApiKeyTypeTarget" + "ApiKeyTypeTarget", + "ApiKeyTypeRunner" ] }, "models.JobAction": { @@ -5383,7 +5910,10 @@ "restart", "delete", "force-delete", - "run" + "run", + "install-provider", + "uninstall-provider", + "update-provider" ], "x-enum-varnames": [ "JobActionCreate", @@ -5392,7 +5922,10 @@ "JobActionRestart", "JobActionDelete", "JobActionForceDelete", - "JobActionRun" + "JobActionRun", + "JobActionInstallProvider", + "JobActionUninstallProvider", + "JobActionUpdateProvider" ] }, "models.ResourceStateName": { @@ -5440,7 +5973,7 @@ "ResourceStateNameDeleted" ] }, - "provider.TargetConfigPropertyType": { + "models.TargetConfigPropertyType": { "type": "string", "enum": [ "string", diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index d503132cd8..de5951bc7b 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -7,7 +7,7 @@ definitions: options: type: string providerInfo: - $ref: '#/definitions/TargetProviderInfo' + $ref: '#/definitions/ProviderInfo' required: - name - options @@ -284,6 +284,10 @@ definitions: required: - filePath type: object + DownloadUrls: + additionalProperties: + type: string + type: object EnvironmentVariable: properties: key: @@ -623,12 +627,10 @@ definitions: - name - username type: object - InstallProviderRequest: + InstallProviderDTO: properties: downloadUrls: - additionalProperties: - type: string - type: object + $ref: '#/definitions/DownloadUrls' name: type: string required: @@ -645,10 +647,15 @@ definitions: type: string id: type: string + metadata: + description: JSON encoded metadata + type: string resourceId: type: string resourceType: $ref: '#/definitions/ResourceType' + runnerId: + type: string state: $ref: '#/definitions/JobState' updatedAt: @@ -859,18 +866,54 @@ definitions: - retention - workspaceTemplateName type: object - Provider: + ProviderInfo: properties: + agentlessTarget: + type: boolean label: type: string name: type: string + runnerId: + type: string + runnerName: + type: string + targetConfigManifest: + $ref: '#/definitions/TargetConfigManifest' version: type: string required: - name + - runnerId + - runnerName + - targetConfigManifest - version type: object + RegisterRunnerDTO: + properties: + id: + type: string + name: + type: string + required: + - id + - name + type: object + RegisterRunnerResultDTO: + properties: + apiKey: + type: string + id: + type: string + metadata: + $ref: '#/definitions/RunnerMetadata' + name: + type: string + required: + - apiKey + - id + - name + type: object ReplaceRequest: properties: files: @@ -919,11 +962,48 @@ definitions: - workspace - target - build + - runner type: string x-enum-varnames: - ResourceTypeWorkspace - ResourceTypeTarget - ResourceTypeBuild + - ResourceTypeRunner + RunnerDTO: + properties: + id: + type: string + metadata: + $ref: '#/definitions/RunnerMetadata' + name: + type: string + state: + $ref: '#/definitions/ResourceState' + required: + - id + - name + - state + type: object + RunnerMetadata: + properties: + providers: + items: + $ref: '#/definitions/ProviderInfo' + type: array + runnerId: + type: string + runningJobs: + type: integer + updatedAt: + type: string + uptime: + type: integer + required: + - providers + - runnerId + - updatedAt + - uptime + type: object Sample: properties: description: @@ -972,10 +1052,10 @@ definitions: type: string localBuilderRegistryPort: type: integer + localRunnerDisabled: + type: boolean logFile: $ref: '#/definitions/LogFileConfig' - providersDir: - type: string registryUrl: type: string samplesIndexUrl: @@ -994,7 +1074,6 @@ definitions: - localBuilderRegistryImage - localBuilderRegistryPort - logFile - - providersDir - registryUrl - serverDownloadUrl type: object @@ -1050,22 +1129,6 @@ definitions: - providerId - token type: object - SetTargetMetadata: - properties: - uptime: - type: integer - required: - - uptime - type: object - SetWorkspaceMetadata: - properties: - gitStatus: - $ref: '#/definitions/GitStatus' - uptime: - type: integer - required: - - uptime - type: object SigningMethod: enum: - ssh @@ -1110,6 +1173,8 @@ definitions: $ref: '#/definitions/TargetMetadata' name: type: string + providerMetadata: + type: string targetConfig: $ref: '#/definitions/TargetConfig' targetConfigId: @@ -1139,7 +1204,7 @@ definitions: description: JSON encoded map of options type: string providerInfo: - $ref: '#/definitions/TargetProviderInfo' + $ref: '#/definitions/ProviderInfo' required: - deleted - id @@ -1181,7 +1246,7 @@ definitions: type: string type: array type: - $ref: '#/definitions/provider.TargetConfigPropertyType' + $ref: '#/definitions/models.TargetConfigPropertyType' type: object TargetDTO: properties: @@ -1193,14 +1258,14 @@ definitions: type: object id: type: string - info: - $ref: '#/definitions/TargetInfo' lastJob: $ref: '#/definitions/Job' metadata: $ref: '#/definitions/TargetMetadata' name: type: string + providerMetadata: + type: string state: $ref: '#/definitions/ResourceState' targetConfig: @@ -1221,15 +1286,6 @@ definitions: - targetConfigId - workspaces type: object - TargetInfo: - properties: - name: - type: string - providerMetadata: - type: string - required: - - name - type: object TargetMetadata: properties: targetId: @@ -1243,22 +1299,63 @@ definitions: - updatedAt - uptime type: object - TargetProviderInfo: + UpdateJobState: properties: - agentlessTarget: - type: boolean - label: + errorMessage: type: string - name: + state: + $ref: '#/definitions/JobState' + required: + - state + type: object + UpdateRunnerMetadataDTO: + properties: + providers: + items: + $ref: '#/definitions/ProviderInfo' + type: array + runningJobs: + type: integer + uptime: + type: integer + required: + - providers + - uptime + type: object + UpdateTargetMetadataDTO: + properties: + uptime: + type: integer + required: + - uptime + type: object + UpdateTargetProviderMetadataDTO: + properties: + metadata: type: string - version: + required: + - metadata + type: object + UpdateWorkspaceMetadataDTO: + properties: + gitStatus: + $ref: '#/definitions/GitStatus' + uptime: + type: integer + required: + - uptime + type: object + UpdateWorkspaceProviderMetadataDTO: + properties: + metadata: type: string required: - - name - - version + - metadata type: object Workspace: properties: + apiKey: + type: string buildConfig: $ref: '#/definitions/BuildConfig' envVars: @@ -1277,6 +1374,8 @@ definitions: $ref: '#/definitions/WorkspaceMetadata' name: type: string + providerMetadata: + type: string repository: $ref: '#/definitions/GitRepository' target: @@ -1286,6 +1385,7 @@ definitions: user: type: string required: + - apiKey - envVars - id - image @@ -1297,6 +1397,8 @@ definitions: type: object WorkspaceDTO: properties: + apiKey: + type: string buildConfig: $ref: '#/definitions/BuildConfig' envVars: @@ -1309,14 +1411,14 @@ definitions: type: string image: type: string - info: - $ref: '#/definitions/WorkspaceInfo' lastJob: $ref: '#/definitions/Job' metadata: $ref: '#/definitions/WorkspaceMetadata' name: type: string + providerMetadata: + type: string repository: $ref: '#/definitions/GitRepository' state: @@ -1328,6 +1430,7 @@ definitions: user: type: string required: + - apiKey - envVars - id - image @@ -1343,24 +1446,6 @@ definitions: dir: type: string type: object - WorkspaceInfo: - properties: - created: - type: string - isRunning: - type: boolean - name: - type: string - providerMetadata: - type: string - targetId: - type: string - required: - - created - - isRunning - - name - - targetId - type: object WorkspaceMetadata: properties: gitStatus: @@ -1413,11 +1498,13 @@ definitions: - client - workspace - target + - runner type: string x-enum-varnames: - ApiKeyTypeClient - ApiKeyTypeWorkspace - ApiKeyTypeTarget + - ApiKeyTypeRunner models.JobAction: enum: - create @@ -1427,6 +1514,9 @@ definitions: - delete - force-delete - run + - install-provider + - uninstall-provider + - update-provider type: string x-enum-varnames: - JobActionCreate @@ -1436,6 +1526,9 @@ definitions: - JobActionDelete - JobActionForceDelete - JobActionRun + - JobActionInstallProvider + - JobActionUninstallProvider + - JobActionUpdateProvider models.ResourceStateName: enum: - undefined @@ -1478,7 +1571,7 @@ definitions: - ResourceStateNamePendingForcedDelete - ResourceStateNameDeleting - ResourceStateNameDeleted - provider.TargetConfigPropertyType: + models.TargetConfigPropertyType: enum: - string - option @@ -1661,6 +1754,28 @@ paths: summary: Delete builds tags: - build + /build/successful/{repoUrl}: + get: + description: List successful builds for Git repository + operationId: ListSuccessfulBuilds + parameters: + - description: Repository URL + in: path + name: repoUrl + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/BuildDTO' + type: array + summary: List successful builds for Git repository + tags: + - build /container-registry/{server}: get: description: Get container registry @@ -2073,6 +2188,29 @@ paths: get: description: List jobs operationId: ListJobs + parameters: + - collectionFormat: multi + description: Job States + in: query + items: + type: string + name: states + type: array + - collectionFormat: multi + description: Job Actions + in: query + items: + type: string + name: actions + type: array + - description: Resource ID + in: query + name: resourceId + type: string + - description: Resource Type + in: query + name: resourceType + type: string produces: - application/json responses: @@ -2085,10 +2223,10 @@ paths: summary: List jobs tags: - job - /provider: + /runner: get: - description: List providers - operationId: ListProviders + description: List runners + operationId: ListRunners produces: - application/json responses: @@ -2096,64 +2234,228 @@ paths: description: OK schema: items: - $ref: '#/definitions/Provider' + $ref: '#/definitions/RunnerDTO' type: array - summary: List providers + summary: List runners tags: - - provider - /provider/{provider}/target-config-manifest: + - runner + post: + description: Register a runner + operationId: RegisterRunner + parameters: + - description: Register runner + in: body + name: runner + required: true + schema: + $ref: '#/definitions/RegisterRunnerDTO' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/RegisterRunnerResultDTO' + summary: Register a runner + tags: + - runner + /runner/{runnerId}: + delete: + description: Remove runner + operationId: RemoveRunner + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + type: string + responses: + "200": + description: OK + summary: Remove runner + tags: + - runner get: - description: Get provider target config manifest - operationId: GetTargetConfigManifest + description: Get a runner + operationId: GetRunner parameters: - - description: Provider name + - description: Runner ID in: path - name: provider + name: runnerId required: true type: string + produces: + - application/json responses: "200": description: OK schema: - $ref: '#/definitions/TargetConfigManifest' - summary: Get provider target config manifest + $ref: '#/definitions/RunnerDTO' + summary: Get a runner tags: - - provider - /provider/{provider}/uninstall: + - runner + /runner/{runnerId}/jobs: + get: + description: List runner jobs + operationId: ListRunnerJobs + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/Job' + type: array + summary: List runner jobs + tags: + - runner + /runner/{runnerId}/jobs/{jobId}/state: post: - consumes: + description: Update job state + operationId: UpdateJobState + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + type: string + - description: Job ID + in: path + name: jobId + required: true + type: string + - description: Update job state + in: body + name: updateJobState + required: true + schema: + $ref: '#/definitions/UpdateJobState' + produces: - application/json - description: Uninstall a provider + responses: + "200": + description: OK + summary: Update job state + tags: + - runner + /runner/{runnerId}/metadata: + post: + description: Set runner metadata + operationId: SetRunnerMetadata + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + type: string + - description: Runner Metadata + in: body + name: runnerMetadata + required: true + schema: + $ref: '#/definitions/UpdateRunnerMetadataDTO' + responses: + "200": + description: OK + summary: Set runner metadata + tags: + - runner + /runner/{runnerId}/provider/{providerName}/uninstall: + post: + description: Uninstall provider operationId: UninstallProvider parameters: - - description: Provider to uninstall + - description: Runner ID in: path - name: provider + name: runnerId + required: true + type: string + - description: Provider name + in: path + name: providerName required: true type: string responses: "200": description: OK - summary: Uninstall a provider + summary: Uninstall provider tags: - provider - /provider/install: + /runner/{runnerId}/provider/{providerName}/update: post: - consumes: - - application/json - description: Install a provider + description: Update provider + operationId: UpdateProvider + parameters: + - description: Provider download URLs + in: body + name: downloadUrls + required: true + schema: + $ref: '#/definitions/DownloadUrls' + - description: Runner ID + in: path + name: runnerId + required: true + type: string + - description: Provider name + in: path + name: providerName + required: true + type: string + responses: + "200": + description: OK + summary: Update provider + tags: + - provider + /runner/{runnerId}/provider/install: + post: + description: Install provider operationId: InstallProvider parameters: - - description: Provider to install + - description: Install provider in: body - name: provider + name: installProviderDto required: true schema: - $ref: '#/definitions/InstallProviderRequest' + $ref: '#/definitions/InstallProviderDTO' + - description: Runner ID + in: path + name: runnerId + required: true + type: string responses: "200": description: OK - summary: Install a provider + summary: Install provider + tags: + - provider + /runner/provider: + get: + description: List providers + operationId: ListProviders + parameters: + - description: Runner ID + in: query + name: runnerId + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/ProviderInfo' + type: array + summary: List providers tags: - provider /sample: @@ -2243,9 +2545,9 @@ paths: description: List targets operationId: ListTargets parameters: - - description: Verbose + - description: Show target config options in: query - name: verbose + name: showOptions type: boolean produces: - application/json @@ -2283,6 +2585,11 @@ paths: get: description: List target configs operationId: ListTargetConfigs + parameters: + - description: Show target config options + in: query + name: showOptions + type: boolean produces: - application/json responses: @@ -2305,6 +2612,10 @@ paths: required: true schema: $ref: '#/definitions/AddTargetConfigDTO' + - description: Show target config options + in: query + name: showOptions + type: boolean responses: "200": description: OK @@ -2358,9 +2669,9 @@ paths: name: targetId required: true type: string - - description: Verbose + - description: Show target config options in: query - name: verbose + name: showOptions type: boolean produces: - application/json @@ -2372,6 +2683,22 @@ paths: summary: Get target info tags: - target + /target/{targetId}/handle-successful-creation: + post: + description: Handles successful creation of the target + operationId: HandleSuccessfulCreation + parameters: + - description: Target ID or name + in: path + name: targetId + required: true + type: string + responses: + "200": + description: OK + summary: Handles successful creation of the target + tags: + - target /target/{targetId}/metadata: post: description: Set target metadata @@ -2382,18 +2709,40 @@ paths: name: targetId required: true type: string - - description: Set Metadata + - description: Target Metadata in: body - name: setMetadata + name: targetMetadata required: true schema: - $ref: '#/definitions/SetTargetMetadata' + $ref: '#/definitions/UpdateTargetMetadataDTO' responses: "200": description: OK summary: Set target metadata tags: - target + /target/{targetId}/provider-metadata: + post: + description: Update target provider metadata + operationId: UpdateTargetProviderMetadata + parameters: + - description: Target ID + in: path + name: targetId + required: true + type: string + - description: Provider metadata + in: body + name: metadata + required: true + schema: + $ref: '#/definitions/UpdateTargetProviderMetadataDTO' + responses: + "200": + description: OK + summary: Update target provider metadata + tags: + - target /target/{targetId}/set-default: patch: description: Set target to be used by default @@ -2446,11 +2795,6 @@ paths: get: description: List workspaces operationId: ListWorkspaces - parameters: - - description: Verbose - in: query - name: verbose - type: boolean produces: - application/json responses: @@ -2752,10 +3096,6 @@ paths: name: workspaceId required: true type: string - - description: Verbose - in: query - name: verbose - type: boolean produces: - application/json responses: @@ -2776,18 +3116,40 @@ paths: name: workspaceId required: true type: string - - description: Set Metadata + - description: Workspace Metadata in: body - name: setMetadata + name: workspaceMetadata required: true schema: - $ref: '#/definitions/SetWorkspaceMetadata' + $ref: '#/definitions/UpdateWorkspaceMetadataDTO' responses: "200": description: OK summary: Set workspace metadata tags: - workspace + /workspace/{workspaceId}/provider-metadata: + post: + description: Update workspace provider metadata + operationId: UpdateWorkspaceProviderMetadata + parameters: + - description: Workspace ID + in: path + name: workspaceId + required: true + type: string + - description: Provider metadata + in: body + name: metadata + required: true + schema: + $ref: '#/definitions/UpdateWorkspaceProviderMetadataDTO' + responses: + "200": + description: OK + summary: Update workspace provider metadata + tags: + - workspace /workspace/{workspaceId}/start: post: description: Start workspace diff --git a/pkg/api/middlewares/auth.go b/pkg/api/middlewares/auth.go index 9b4b5fa1bc..3f7f5ee4d6 100644 --- a/pkg/api/middlewares/auth.go +++ b/pkg/api/middlewares/auth.go @@ -7,7 +7,6 @@ import ( "errors" "strings" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -33,12 +32,10 @@ func AuthMiddleware() gin.HandlerFunc { return } - apiKeyType := models.ApiKeyTypeClient - - if server.ApiKeyService.IsTargetApiKey(ctx.Request.Context(), token) { - apiKeyType = models.ApiKeyTypeTarget - } else if server.ApiKeyService.IsWorkspaceApiKey(ctx.Request.Context(), token) { - apiKeyType = models.ApiKeyTypeWorkspace + apiKeyType, err := server.ApiKeyService.GetApiKeyType(ctx.Request.Context(), token) + if err != nil { + ctx.AbortWithError(401, errors.New("unauthorized")) + return } ctx.Set("apiKeyType", apiKeyType) diff --git a/pkg/api/middlewares/logging.go b/pkg/api/middlewares/logging.go index 044b3bc7fd..d6559a4791 100644 --- a/pkg/api/middlewares/logging.go +++ b/pkg/api/middlewares/logging.go @@ -11,6 +11,15 @@ import ( log "github.com/sirupsen/logrus" ) +var ignoreLoggingPaths = map[string]bool{ + "/job/": true, + "/workspace/:workspaceId/metadata": true, + "/target/:targetId/metadata": true, + "/runner/:runnerId/jobs": true, + "/runner/:runnerId/metadata": true, + "/runner/:runnerId/jobs/:jobId/state": true, +} + func LoggingMiddleware() gin.HandlerFunc { return func(ctx *gin.Context) { startTime := time.Now() @@ -31,12 +40,22 @@ func LoggingMiddleware() gin.HandlerFunc { }).Error("API ERROR") ctx.JSON(statusCode, gin.H{"error": ctx.Errors[0].Err.Error()}) } else { - log.WithFields(log.Fields{ - "method": reqMethod, - "URI": reqUri, - "status": statusCode, - "latency": latencyTime, - }).Info("API REQUEST") + fullPath := ctx.FullPath() + if ignoreLoggingPaths[fullPath] { + log.WithFields(log.Fields{ + "method": reqMethod, + "URI": reqUri, + "status": statusCode, + "latency": latencyTime, + }).Debug("API REQUEST") + } else { + log.WithFields(log.Fields{ + "method": reqMethod, + "URI": reqUri, + "status": statusCode, + "latency": latencyTime, + }).Info("API REQUEST") + } } ctx.Next() diff --git a/pkg/api/middlewares/runner.go b/pkg/api/middlewares/runner.go new file mode 100644 index 0000000000..07d500823b --- /dev/null +++ b/pkg/api/middlewares/runner.go @@ -0,0 +1,43 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package middlewares + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +func RunnerAuthMiddleware() gin.HandlerFunc { + return func(ctx *gin.Context) { + bearerToken := ctx.GetHeader("Authorization") + if bearerToken == "" { + ctx.AbortWithError(401, errors.New("unauthorized")) + return + } + + token := ExtractToken(bearerToken) + if token == "" { + ctx.AbortWithError(401, errors.New("unauthorized")) + return + } + + server := server.GetInstance(nil) + + apiKeyType, err := server.ApiKeyService.GetApiKeyType(ctx.Request.Context(), token) + if err != nil { + ctx.AbortWithError(401, errors.New("unauthorized")) + return + } + + if apiKeyType != models.ApiKeyTypeRunner { + ctx.AbortWithError(401, errors.New("unauthorized")) + return + } + + ctx.Next() + } +} diff --git a/pkg/api/middlewares/telemetry.go b/pkg/api/middlewares/telemetry.go index d2a8620659..e503d0fd61 100644 --- a/pkg/api/middlewares/telemetry.go +++ b/pkg/api/middlewares/telemetry.go @@ -16,13 +16,18 @@ import ( log "github.com/sirupsen/logrus" ) -var ignorePaths = map[string]bool{ - "/health": true, - "/target/:targetId/metadata": true, - "/target/:targetId": true, - "/workspace/:workspaceId/metadata": true, - "/workspace/:workspaceId": true, - "/server/network-key": true, +var ignoreTelemetryPaths = map[string]bool{ + "/health": true, + "/target/:targetId/metadata": true, + "/target/:targetId": true, + "/workspace/:workspaceId/metadata": true, + "/workspace/:workspaceId": true, + "/runner/:runnerId/metadata": true, + "/runner/:runnerId": true, + "/server/network-key": true, + "/job/": true, + "/runner/:runnerId/jobs": true, + "/runner/:runnerId/jobs/:jobId/state": true, } func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.HandlerFunc { @@ -38,7 +43,7 @@ func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.Handle } reqUri := ctx.FullPath() - if ignorePaths[reqUri] { + if ignoreTelemetryPaths[reqUri] { ctx.Next() return } diff --git a/pkg/api/middlewares/workspace.go b/pkg/api/middlewares/workspace.go index 38ad903e74..7f512559c9 100644 --- a/pkg/api/middlewares/workspace.go +++ b/pkg/api/middlewares/workspace.go @@ -6,6 +6,7 @@ package middlewares import ( "errors" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) @@ -26,8 +27,20 @@ func WorkspaceAuthMiddleware() gin.HandlerFunc { server := server.GetInstance(nil) - if !server.ApiKeyService.IsWorkspaceApiKey(ctx.Request.Context(), token) && !server.ApiKeyService.IsTargetApiKey(ctx.Request.Context(), token) { + apiKeyType, err := server.ApiKeyService.GetApiKeyType(ctx.Request.Context(), token) + if err != nil { ctx.AbortWithError(401, errors.New("unauthorized")) + return + } + + switch apiKeyType { + case models.ApiKeyTypeWorkspace: + fallthrough + case models.ApiKeyTypeTarget: + ctx.Next() + default: + ctx.AbortWithError(401, errors.New("unauthorized")) + return } ctx.Next() diff --git a/pkg/api/server.go b/pkg/api/server.go index f86ac028ac..c92b4fbe9d 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -41,7 +41,8 @@ import ( "github.com/daytonaio/daytona/pkg/api/controllers/health" "github.com/daytonaio/daytona/pkg/api/controllers/job" log_controller "github.com/daytonaio/daytona/pkg/api/controllers/log" - "github.com/daytonaio/daytona/pkg/api/controllers/provider" + "github.com/daytonaio/daytona/pkg/api/controllers/runner" + "github.com/daytonaio/daytona/pkg/api/controllers/runner/provider" "github.com/daytonaio/daytona/pkg/api/controllers/sample" "github.com/daytonaio/daytona/pkg/api/controllers/server" "github.com/daytonaio/daytona/pkg/api/controllers/target" @@ -102,15 +103,14 @@ func (a *ApiServer) Start() error { binding.Validator = new(DefaultValidator) + a.router = gin.New() + a.router.Use(gin.Recovery()) if mode, ok := os.LookupEnv("DAYTONA_SERVER_MODE"); ok && mode == "development" { - a.router = gin.Default() a.router.Use(cors.New(cors.Config{ AllowAllOrigins: true, })) } else { gin.SetMode(gin.ReleaseMode) - a.router = gin.New() - a.router.Use(gin.Recovery()) } a.router.Use(middlewares.TelemetryMiddleware(a.telemetryService)) @@ -150,6 +150,8 @@ func (a *ApiServer) Start() error { targetController.POST("/:targetId/start", target.StartTarget) targetController.POST("/:targetId/stop", target.StopTarget) targetController.PATCH("/:targetId/set-default", target.SetDefaultTarget) + targetController.POST("/:targetId/handle-successful-creation", target.HandleSuccessfulCreation) + targetController.POST("/:targetId/provider-metadata", target.UpdateTargetProviderMetadata) targetController.DELETE("/:targetId", target.RemoveTarget) } @@ -223,11 +225,7 @@ func (a *ApiServer) Start() error { workspaceController.DELETE("/:workspaceId", workspace.RemoveWorkspace) workspaceController.POST("/:workspaceId/start", workspace.StartWorkspace) workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) - } - - jobController := protected.Group("/job") - { - jobController.GET("", job.ListJobs) + workspaceController.POST("/:workspaceId/provider-metadata", workspace.UpdateWorkspaceProviderMetadata) } workspaceTemplateController := protected.Group("/workspace-template") @@ -258,19 +256,12 @@ func (a *ApiServer) Start() error { public.POST(constants.WEBHOOK_EVENT_ROUTE, prebuild.ProcessGitEvent) - providerController := protected.Group("/provider") - { - providerController.POST("/install", provider.InstallProvider) - providerController.GET("", provider.ListProviders) - providerController.POST("/:provider/uninstall", provider.UninstallProvider) - providerController.GET("/:provider/target-config-manifest", provider.GetTargetConfigManifest) - } - buildController := protected.Group("/build") { buildController.POST("", build.CreateBuild) buildController.GET("/:buildId", build.GetBuild) buildController.GET("", build.ListBuilds) + buildController.GET("/successful/:repoUrl", build.ListSuccessfulBuilds) buildController.DELETE("", build.DeleteAllBuilds) buildController.DELETE("/:buildId", build.DeleteBuild) buildController.DELETE("/prebuild/:prebuildId", build.DeleteBuildsFromPrebuild) @@ -287,8 +278,13 @@ func (a *ApiServer) Start() error { { logController.GET("/server", log_controller.ReadServerLog) logController.GET("/target/:targetId", log_controller.ReadTargetLog) + logController.GET("/target/:targetId/write", log_controller.WriteTargetLog) logController.GET("/workspace/:workspaceId", log_controller.ReadWorkspaceLog) + logController.GET("/workspace/:workspaceId/write", log_controller.WriteWorkspaceLog) logController.GET("/build/:buildId", log_controller.ReadBuildLog) + logController.GET("/build/:buildId/write", log_controller.WriteBuildLog) + logController.GET("/runner/:runnerId", log_controller.ReadRunnerLog) + logController.GET("/runner/:runnerId/write", log_controller.WriteRunnerLog) } gitProviderController := protected.Group("/gitprovider") @@ -327,11 +323,42 @@ func (a *ApiServer) Start() error { containerRegistryController.GET("/:server", containerregistry.GetContainerRegistry) } + jobController := protected.Group("/job") + { + jobController.GET("", job.ListJobs) + } + samplesController := protected.Group("/sample") { samplesController.GET("", sample.ListSamples) } + runnerController := protected.Group("/runner") + { + // Defining the provider routes first to avoid conflicts with the runner routes + providerRoutePath := "/provider" + providersGroup := runnerController.Group(providerRoutePath) + { + providersGroup.GET("", provider.ListProviders) + } + + runnerIdGroup := runnerController.Group(":runnerId") + { + runnerIdProviderGroup := runnerIdGroup.Group(providerRoutePath) + { + runnerIdProviderGroup.POST("/install", provider.InstallProvider) + runnerIdProviderGroup.POST("/:providerName/uninstall", provider.UninstallProvider) + runnerIdProviderGroup.POST("/:providerName/update", provider.UpdateProvider) + } + + runnerIdGroup.GET("", runner.GetRunner) + runnerIdGroup.DELETE("", runner.RemoveRunner) + } + + runnerController.GET("", runner.ListRunners) + runnerController.POST("", runner.RegisterRunner) + } + workspaceGroup := protected.Group("/") workspaceGroup.Use(middlewares.WorkspaceAuthMiddleware()) { @@ -339,6 +366,14 @@ func (a *ApiServer) Start() error { workspaceGroup.POST(targetController.BasePath()+"/:targetId/metadata", target.SetTargetMetadata) } + runnerGroup := protected.Group("/") + runnerGroup.Use(middlewares.RunnerAuthMiddleware()) + { + runnerGroup.POST(runnerController.BasePath()+"/:runnerId/metadata", runner.SetRunnerMetadata) + runnerGroup.GET(runnerController.BasePath()+"/:runnerId/jobs", runner.ListRunnerJobs) + runnerGroup.POST(runnerController.BasePath()+"/:runnerId/jobs/:jobId/state", runner.UpdateJobState) + } + a.httpServer = &http.Server{ Addr: fmt.Sprintf(":%d", a.apiPort), Handler: a.router, diff --git a/pkg/api/util/hide.go b/pkg/api/util/hide.go index fe5439d4e8..34fb5046d3 100644 --- a/pkg/api/util/hide.go +++ b/pkg/api/util/hide.go @@ -4,47 +4,13 @@ package util import ( - "encoding/json" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/workspaces" ) -func GetMaskedOptions(server *server.Server, providerName, options string) (string, error) { - p, err := server.ProviderManager.GetProvider(providerName) - if err != nil { - return "", err - } - - manifest, err := (*p).GetTargetConfigManifest() - if err != nil { - return "", err - } - - var opts map[string]interface{} - err = json.Unmarshal([]byte(options), &opts) - if err != nil { - return "", err - } - - for name, property := range *manifest { - if property.InputMasked { - delete(opts, name) - } - } - - updatedOptions, err := json.MarshalIndent(opts, "", " ") - if err != nil { - return "", err - } - - return string(updatedOptions), nil -} - func HideDaytonaEnvVars(envVars *map[string]string) { for _, daytonaEnvVarKey := range getDaytonaEnvVarKeys() { delete(*envVars, daytonaEnvVarKey) diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index ffd834604c..a3f6d088c0 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -86,6 +86,7 @@ Class | Method | HTTP request | Description *BuildAPI* | [**DeleteBuildsFromPrebuild**](docs/BuildAPI.md#deletebuildsfromprebuild) | **Delete** /build/prebuild/{prebuildId} | Delete builds *BuildAPI* | [**GetBuild**](docs/BuildAPI.md#getbuild) | **Get** /build/{buildId} | Get build data *BuildAPI* | [**ListBuilds**](docs/BuildAPI.md#listbuilds) | **Get** /build | List builds +*BuildAPI* | [**ListSuccessfulBuilds**](docs/BuildAPI.md#listsuccessfulbuilds) | **Get** /build/successful/{repoUrl} | List successful builds for Git repository *ContainerRegistryAPI* | [**GetContainerRegistry**](docs/ContainerRegistryAPI.md#getcontainerregistry) | **Get** /container-registry/{server} | Get container registry *DefaultAPI* | [**HealthCheck**](docs/DefaultAPI.md#healthcheck) | **Get** /health | Health check *EnvVarAPI* | [**DeleteEnvironmentVariable**](docs/EnvVarAPI.md#deleteenvironmentvariable) | **Delete** /env/{key} | Delete environment variable @@ -111,10 +112,17 @@ Class | Method | HTTP request | Description *PrebuildAPI* | [**ListPrebuildsForWorkspaceTemplate**](docs/PrebuildAPI.md#listprebuildsforworkspacetemplate) | **Get** /workspace-template/{templateName}/prebuild | List prebuilds for workspace template *PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /workspace-template/prebuild/process-git-event | ProcessGitEvent *PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /workspace-template/{templateName}/prebuild | Set prebuild -*ProviderAPI* | [**GetTargetConfigManifest**](docs/ProviderAPI.md#gettargetconfigmanifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest -*ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /provider/install | Install a provider -*ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /provider | List providers -*ProviderAPI* | [**UninstallProvider**](docs/ProviderAPI.md#uninstallprovider) | **Post** /provider/{provider}/uninstall | Uninstall a provider +*ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /runner/{runnerId}/provider/install | Install provider +*ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /runner/provider | List providers +*ProviderAPI* | [**UninstallProvider**](docs/ProviderAPI.md#uninstallprovider) | **Post** /runner/{runnerId}/provider/{providerName}/uninstall | Uninstall provider +*ProviderAPI* | [**UpdateProvider**](docs/ProviderAPI.md#updateprovider) | **Post** /runner/{runnerId}/provider/{providerName}/update | Update provider +*RunnerAPI* | [**GetRunner**](docs/RunnerAPI.md#getrunner) | **Get** /runner/{runnerId} | Get a runner +*RunnerAPI* | [**ListRunnerJobs**](docs/RunnerAPI.md#listrunnerjobs) | **Get** /runner/{runnerId}/jobs | List runner jobs +*RunnerAPI* | [**ListRunners**](docs/RunnerAPI.md#listrunners) | **Get** /runner | List runners +*RunnerAPI* | [**RegisterRunner**](docs/RunnerAPI.md#registerrunner) | **Post** /runner | Register a runner +*RunnerAPI* | [**RemoveRunner**](docs/RunnerAPI.md#removerunner) | **Delete** /runner/{runnerId} | Remove runner +*RunnerAPI* | [**SetRunnerMetadata**](docs/RunnerAPI.md#setrunnermetadata) | **Post** /runner/{runnerId}/metadata | Set runner metadata +*RunnerAPI* | [**UpdateJobState**](docs/RunnerAPI.md#updatejobstate) | **Post** /runner/{runnerId}/jobs/{jobId}/state | Update job state *SampleAPI* | [**ListSamples**](docs/SampleAPI.md#listsamples) | **Get** /sample | List samples *ServerAPI* | [**GenerateNetworkKey**](docs/ServerAPI.md#generatenetworkkey) | **Post** /server/network-key | Generate a new authentication key *ServerAPI* | [**GetConfig**](docs/ServerAPI.md#getconfig) | **Get** /server/config | Get the server configuration @@ -122,12 +130,14 @@ Class | Method | HTTP request | Description *ServerAPI* | [**SetConfig**](docs/ServerAPI.md#setconfig) | **Post** /server/config | Set the server configuration *TargetAPI* | [**CreateTarget**](docs/TargetAPI.md#createtarget) | **Post** /target | Create a target *TargetAPI* | [**GetTarget**](docs/TargetAPI.md#gettarget) | **Get** /target/{targetId} | Get target info +*TargetAPI* | [**HandleSuccessfulCreation**](docs/TargetAPI.md#handlesuccessfulcreation) | **Post** /target/{targetId}/handle-successful-creation | Handles successful creation of the target *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets *TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target *TargetAPI* | [**SetDefaultTarget**](docs/TargetAPI.md#setdefaulttarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default *TargetAPI* | [**SetTargetMetadata**](docs/TargetAPI.md#settargetmetadata) | **Post** /target/{targetId}/metadata | Set target metadata *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target +*TargetAPI* | [**UpdateTargetProviderMetadata**](docs/TargetAPI.md#updatetargetprovidermetadata) | **Post** /target/{targetId}/provider-metadata | Update target provider metadata *TargetConfigAPI* | [**AddTargetConfig**](docs/TargetConfigAPI.md#addtargetconfig) | **Put** /target-config | Add a target config *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs *TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configId} | Remove a target config @@ -138,6 +148,7 @@ Class | Method | HTTP request | Description *WorkspaceAPI* | [**SetWorkspaceMetadata**](docs/WorkspaceAPI.md#setworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata *WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace *WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +*WorkspaceAPI* | [**UpdateWorkspaceProviderMetadata**](docs/WorkspaceAPI.md#updateworkspaceprovidermetadata) | **Post** /workspace/{workspaceId}/provider-metadata | Update workspace provider metadata *WorkspaceTemplateAPI* | [**DeleteWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#deleteworkspacetemplate) | **Delete** /workspace-template/{templateName} | Delete workspace template data *WorkspaceTemplateAPI* | [**GetDefaultWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getdefaultworkspacetemplate) | **Get** /workspace-template/default/{gitUrl} | Get workspace templates by git url *WorkspaceTemplateAPI* | [**GetWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getworkspacetemplate) | **Get** /workspace-template/{templateName} | Get workspace template data @@ -223,7 +234,7 @@ Class | Method | HTTP request | Description - [GitRepository](docs/GitRepository.md) - [GitStatus](docs/GitStatus.md) - [GitUser](docs/GitUser.md) - - [InstallProviderRequest](docs/InstallProviderRequest.md) + - [InstallProviderDTO](docs/InstallProviderDTO.md) - [Job](docs/Job.md) - [JobState](docs/JobState.md) - [ListBranchResponse](docs/ListBranchResponse.md) @@ -239,17 +250,21 @@ Class | Method | HTTP request | Description - [ModelsApiKeyType](docs/ModelsApiKeyType.md) - [ModelsJobAction](docs/ModelsJobAction.md) - [ModelsResourceStateName](docs/ModelsResourceStateName.md) + - [ModelsTargetConfigPropertyType](docs/ModelsTargetConfigPropertyType.md) - [NetworkKey](docs/NetworkKey.md) - [Position](docs/Position.md) - [PrebuildConfig](docs/PrebuildConfig.md) - [PrebuildDTO](docs/PrebuildDTO.md) - - [Provider](docs/Provider.md) - - [ProviderTargetConfigPropertyType](docs/ProviderTargetConfigPropertyType.md) + - [ProviderInfo](docs/ProviderInfo.md) + - [RegisterRunnerDTO](docs/RegisterRunnerDTO.md) + - [RegisterRunnerResultDTO](docs/RegisterRunnerResultDTO.md) - [ReplaceRequest](docs/ReplaceRequest.md) - [ReplaceResult](docs/ReplaceResult.md) - [RepositoryUrl](docs/RepositoryUrl.md) - [ResourceState](docs/ResourceState.md) - [ResourceType](docs/ResourceType.md) + - [RunnerDTO](docs/RunnerDTO.md) + - [RunnerMetadata](docs/RunnerMetadata.md) - [Sample](docs/Sample.md) - [SearchFilesResponse](docs/SearchFilesResponse.md) - [ServerConfig](docs/ServerConfig.md) @@ -257,21 +272,22 @@ Class | Method | HTTP request | Description - [SessionExecuteRequest](docs/SessionExecuteRequest.md) - [SessionExecuteResponse](docs/SessionExecuteResponse.md) - [SetGitProviderConfig](docs/SetGitProviderConfig.md) - - [SetTargetMetadata](docs/SetTargetMetadata.md) - - [SetWorkspaceMetadata](docs/SetWorkspaceMetadata.md) - [SigningMethod](docs/SigningMethod.md) - [Status](docs/Status.md) - [Target](docs/Target.md) - [TargetConfig](docs/TargetConfig.md) - [TargetConfigProperty](docs/TargetConfigProperty.md) - [TargetDTO](docs/TargetDTO.md) - - [TargetInfo](docs/TargetInfo.md) - [TargetMetadata](docs/TargetMetadata.md) - - [TargetProviderInfo](docs/TargetProviderInfo.md) + - [UpdateJobState](docs/UpdateJobState.md) + - [UpdateRunnerMetadataDTO](docs/UpdateRunnerMetadataDTO.md) + - [UpdateTargetMetadataDTO](docs/UpdateTargetMetadataDTO.md) + - [UpdateTargetProviderMetadataDTO](docs/UpdateTargetProviderMetadataDTO.md) + - [UpdateWorkspaceMetadataDTO](docs/UpdateWorkspaceMetadataDTO.md) + - [UpdateWorkspaceProviderMetadataDTO](docs/UpdateWorkspaceProviderMetadataDTO.md) - [Workspace](docs/Workspace.md) - [WorkspaceDTO](docs/WorkspaceDTO.md) - [WorkspaceDirResponse](docs/WorkspaceDirResponse.md) - - [WorkspaceInfo](docs/WorkspaceInfo.md) - [WorkspaceMetadata](docs/WorkspaceMetadata.md) - [WorkspaceTemplate](docs/WorkspaceTemplate.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 52dea2a6a6..9fb76a2112 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -139,6 +139,29 @@ paths: summary: Delete builds tags: - build + /build/successful/{repoUrl}: + get: + description: List successful builds for Git repository + operationId: ListSuccessfulBuilds + parameters: + - description: Repository URL + in: path + name: repoUrl + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/BuildDTO' + type: array + description: OK + summary: List successful builds for Git repository + tags: + - build /build/{buildId}: delete: description: Delete build @@ -621,6 +644,35 @@ paths: get: description: List jobs operationId: ListJobs + parameters: + - description: Job States + explode: true + in: query + name: states + schema: + items: + type: string + type: array + style: form + - description: Job Actions + explode: true + in: query + name: actions + schema: + items: + type: string + type: array + style: form + - description: Resource ID + in: query + name: resourceId + schema: + type: string + - description: Resource Type + in: query + name: resourceType + schema: + type: string responses: "200": content: @@ -633,80 +685,266 @@ paths: summary: List jobs tags: - job - /provider: + /runner: + get: + description: List runners + operationId: ListRunners + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/RunnerDTO' + type: array + description: OK + summary: List runners + tags: + - runner + post: + description: Register a runner + operationId: RegisterRunner + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/RegisterRunnerDTO' + description: Register runner + required: true + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterRunnerResultDTO' + description: OK + summary: Register a runner + tags: + - runner + x-codegen-request-body-name: runner + /runner/provider: get: description: List providers operationId: ListProviders + parameters: + - description: Runner ID + in: query + name: runnerId + schema: + type: string responses: "200": content: application/json: schema: items: - $ref: '#/components/schemas/Provider' + $ref: '#/components/schemas/ProviderInfo' type: array description: OK summary: List providers tags: - provider - /provider/install: + /runner/{runnerId}: + delete: + description: Remove runner + operationId: RemoveRunner + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Remove runner + tags: + - runner + get: + description: Get a runner + operationId: GetRunner + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + $ref: '#/components/schemas/RunnerDTO' + description: OK + summary: Get a runner + tags: + - runner + /runner/{runnerId}/jobs: + get: + description: List runner jobs + operationId: ListRunnerJobs + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string + responses: + "200": + content: + application/json: + schema: + items: + $ref: '#/components/schemas/Job' + type: array + description: OK + summary: List runner jobs + tags: + - runner + /runner/{runnerId}/jobs/{jobId}/state: + post: + description: Update job state + operationId: UpdateJobState + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string + - description: Job ID + in: path + name: jobId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/UpdateJobState' + description: Update job state + required: true + responses: + "200": + content: {} + description: OK + summary: Update job state + tags: + - runner + x-codegen-request-body-name: updateJobState + /runner/{runnerId}/metadata: + post: + description: Set runner metadata + operationId: SetRunnerMetadata + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/UpdateRunnerMetadataDTO' + description: Runner Metadata + required: true + responses: + "200": + content: {} + description: OK + summary: Set runner metadata + tags: + - runner + x-codegen-request-body-name: runnerMetadata + /runner/{runnerId}/provider/install: post: - description: Install a provider + description: Install provider operationId: InstallProvider + parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string requestBody: content: - application/json: + '*/*': schema: - $ref: '#/components/schemas/InstallProviderRequest' - description: Provider to install + $ref: '#/components/schemas/InstallProviderDTO' + description: Install provider required: true responses: "200": content: {} description: OK - summary: Install a provider + summary: Install provider tags: - provider - x-codegen-request-body-name: provider - /provider/{provider}/target-config-manifest: - get: - description: Get provider target config manifest - operationId: GetTargetConfigManifest + x-codegen-request-body-name: installProviderDto + /runner/{runnerId}/provider/{providerName}/uninstall: + post: + description: Uninstall provider + operationId: UninstallProvider parameters: + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string - description: Provider name in: path - name: provider + name: providerName required: true schema: type: string responses: "200": - content: - '*/*': - schema: - $ref: '#/components/schemas/TargetConfigManifest' + content: {} description: OK - summary: Get provider target config manifest + summary: Uninstall provider tags: - provider - /provider/{provider}/uninstall: + /runner/{runnerId}/provider/{providerName}/update: post: - description: Uninstall a provider - operationId: UninstallProvider + description: Update provider + operationId: UpdateProvider parameters: - - description: Provider to uninstall + - description: Runner ID + in: path + name: runnerId + required: true + schema: + type: string + - description: Provider name in: path - name: provider + name: providerName required: true schema: type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/DownloadUrls' + description: Provider download URLs + required: true responses: "200": content: {} description: OK - summary: Uninstall a provider + summary: Update provider tags: - provider + x-codegen-request-body-name: downloadUrls /sample: get: description: List samples @@ -793,9 +1031,9 @@ paths: description: List targets operationId: ListTargets parameters: - - description: Verbose + - description: Show target config options in: query - name: verbose + name: showOptions schema: type: boolean responses: @@ -835,6 +1073,12 @@ paths: get: description: List target configs operationId: ListTargetConfigs + parameters: + - description: Show target config options + in: query + name: showOptions + schema: + type: boolean responses: "200": content: @@ -850,6 +1094,12 @@ paths: put: description: Add a target config operationId: AddTargetConfig + parameters: + - description: Show target config options + in: query + name: showOptions + schema: + type: boolean requestBody: content: '*/*': @@ -919,9 +1169,9 @@ paths: required: true schema: type: string - - description: Verbose + - description: Show target config options in: query - name: verbose + name: showOptions schema: type: boolean responses: @@ -934,6 +1184,24 @@ paths: summary: Get target info tags: - target + /target/{targetId}/handle-successful-creation: + post: + description: Handles successful creation of the target + operationId: HandleSuccessfulCreation + parameters: + - description: Target ID or name + in: path + name: targetId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Handles successful creation of the target + tags: + - target /target/{targetId}/metadata: post: description: Set target metadata @@ -949,8 +1217,8 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/SetTargetMetadata' - description: Set Metadata + $ref: '#/components/schemas/UpdateTargetMetadataDTO' + description: Target Metadata required: true responses: "200": @@ -959,7 +1227,33 @@ paths: summary: Set target metadata tags: - target - x-codegen-request-body-name: setMetadata + x-codegen-request-body-name: targetMetadata + /target/{targetId}/provider-metadata: + post: + description: Update target provider metadata + operationId: UpdateTargetProviderMetadata + parameters: + - description: Target ID + in: path + name: targetId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/UpdateTargetProviderMetadataDTO' + description: Provider metadata + required: true + responses: + "200": + content: {} + description: OK + summary: Update target provider metadata + tags: + - target + x-codegen-request-body-name: metadata /target/{targetId}/set-default: patch: description: Set target to be used by default @@ -1018,12 +1312,6 @@ paths: get: description: List workspaces operationId: ListWorkspaces - parameters: - - description: Verbose - in: query - name: verbose - schema: - type: boolean responses: "200": content: @@ -1347,11 +1635,6 @@ paths: required: true schema: type: string - - description: Verbose - in: query - name: verbose - schema: - type: boolean responses: "200": content: @@ -1377,8 +1660,8 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/SetWorkspaceMetadata' - description: Set Metadata + $ref: '#/components/schemas/UpdateWorkspaceMetadataDTO' + description: Workspace Metadata required: true responses: "200": @@ -1387,7 +1670,33 @@ paths: summary: Set workspace metadata tags: - workspace - x-codegen-request-body-name: setMetadata + x-codegen-request-body-name: workspaceMetadata + /workspace/{workspaceId}/provider-metadata: + post: + description: Update workspace provider metadata + operationId: UpdateWorkspaceProviderMetadata + parameters: + - description: Workspace ID + in: path + name: workspaceId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: '#/components/schemas/UpdateWorkspaceProviderMetadataDTO' + description: Provider metadata + required: true + responses: + "200": + content: {} + description: OK + summary: Update workspace provider metadata + tags: + - workspace + x-codegen-request-body-name: metadata /workspace/{workspaceId}/start: post: description: Start workspace @@ -2417,8 +2726,23 @@ components: name: name options: options providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version properties: @@ -2427,7 +2751,7 @@ components: options: type: string providerInfo: - $ref: '#/components/schemas/TargetProviderInfo' + $ref: '#/components/schemas/ProviderInfo' required: - name - options @@ -2480,8 +2804,10 @@ components: prebuildId: prebuildId lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -2874,6 +3200,10 @@ components: required: - filePath type: object + DownloadUrls: + additionalProperties: + type: string + type: object EnvironmentVariable: example: value: value @@ -3335,7 +3665,7 @@ components: - name - username type: object - InstallProviderRequest: + InstallProviderDTO: example: downloadUrls: key: downloadUrls @@ -3354,8 +3684,10 @@ components: Job: example: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -3370,10 +3702,15 @@ components: type: string id: type: string + metadata: + description: JSON encoded metadata + type: string resourceId: type: string resourceType: $ref: '#/components/schemas/ResourceType' + runnerId: + type: string state: $ref: '#/components/schemas/JobState' updatedAt: @@ -3669,33 +4006,138 @@ components: - retention - workspaceTemplateName type: object - Provider: + ProviderInfo: example: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true name: name + runnerId: runnerId label: label version: version properties: + agentlessTarget: + type: boolean label: type: string name: type: string + runnerId: + type: string + runnerName: + type: string + targetConfigManifest: + additionalProperties: + $ref: '#/components/schemas/TargetConfigProperty' + type: object version: type: string required: - name + - runnerId + - runnerName + - targetConfigManifest - version type: object - ReplaceRequest: + RegisterRunnerDTO: example: - newValue: newValue - pattern: pattern - files: - - files - - files + name: name + id: id properties: - files: - items: - type: string + id: + type: string + name: + type: string + required: + - id + - name + type: object + RegisterRunnerResultDTO: + example: + metadata: + runningJobs: 0 + runnerId: runnerId + providers: + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + updatedAt: updatedAt + uptime: 6 + apiKey: apiKey + name: name + id: id + properties: + apiKey: + type: string + id: + type: string + metadata: + $ref: '#/components/schemas/RunnerMetadata' + name: + type: string + required: + - apiKey + - id + - name + type: object + ReplaceRequest: + example: + newValue: newValue + pattern: pattern + files: + - files + - files + properties: + files: + items: + type: string type: array newValue: type: string @@ -3749,11 +4191,143 @@ components: - workspace - target - build + - runner type: string x-enum-varnames: - ResourceTypeWorkspace - ResourceTypeTarget - ResourceTypeBuild + - ResourceTypeRunner + RunnerDTO: + example: + metadata: + runningJobs: 0 + runnerId: runnerId + providers: + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + updatedAt: updatedAt + uptime: 6 + name: name + id: id + state: + name: null + error: error + updatedAt: updatedAt + properties: + id: + type: string + metadata: + $ref: '#/components/schemas/RunnerMetadata' + name: + type: string + state: + $ref: '#/components/schemas/ResourceState' + required: + - id + - name + - state + type: object + RunnerMetadata: + example: + runningJobs: 0 + runnerId: runnerId + providers: + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + updatedAt: updatedAt + uptime: 6 + properties: + providers: + items: + $ref: '#/components/schemas/ProviderInfo' + type: array + runnerId: + type: string + runningJobs: + type: integer + updatedAt: + type: string + uptime: + type: integer + required: + - providers + - runnerId + - updatedAt + - uptime + type: object Sample: example: name: name @@ -3794,6 +4368,7 @@ components: defaultWorkspaceImage: defaultWorkspaceImage apiPort: 0 headscalePort: 1 + localRunnerDisabled: true buildImageNamespace: buildImageNamespace serverDownloadUrl: serverDownloadUrl binariesPath: binariesPath @@ -3805,7 +4380,6 @@ components: maxBackups: 2 maxSize: 7 samplesIndexUrl: samplesIndexUrl - providersDir: providersDir defaultWorkspaceUser: defaultWorkspaceUser id: id frps: @@ -3837,10 +4411,10 @@ components: type: string localBuilderRegistryPort: type: integer + localRunnerDisabled: + type: boolean logFile: $ref: '#/components/schemas/LogFileConfig' - providersDir: - type: string registryUrl: type: string samplesIndexUrl: @@ -3859,7 +4433,6 @@ components: - localBuilderRegistryImage - localBuilderRegistryPort - logFile - - providersDir - registryUrl - serverDownloadUrl type: object @@ -3940,40 +4513,6 @@ components: - providerId - token type: object - SetTargetMetadata: - example: - uptime: 0 - properties: - uptime: - type: integer - required: - - uptime - type: object - SetWorkspaceMetadata: - example: - gitStatus: - behind: 1 - fileStatus: - - extra: extra - name: name - staging: null - worktree: null - - extra: extra - name: name - staging: null - worktree: null - ahead: 6 - branchPublished: true - currentBranch: currentBranch - uptime: 0 - properties: - gitStatus: - $ref: '#/components/schemas/GitStatus' - uptime: - type: integer - required: - - uptime - type: object SigningMethod: enum: - ssh @@ -4015,14 +4554,32 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version + providerMetadata: providerMetadata lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4051,6 +4608,8 @@ components: $ref: '#/components/schemas/TargetMetadata' name: type: string + providerMetadata: + type: string targetConfig: $ref: '#/components/schemas/TargetConfig' targetConfigId: @@ -4075,8 +4634,23 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version properties: @@ -4090,7 +4664,7 @@ components: description: JSON encoded map of options type: string providerInfo: - $ref: '#/components/schemas/TargetProviderInfo' + $ref: '#/components/schemas/ProviderInfo' required: - deleted - id @@ -4103,6 +4677,18 @@ components: $ref: '#/components/schemas/TargetConfigProperty' type: object TargetConfigProperty: + example: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true properties: defaultValue: description: |- @@ -4132,7 +4718,7 @@ components: type: string type: array type: - $ref: '#/components/schemas/provider.TargetConfigPropertyType' + $ref: '#/components/schemas/models.TargetConfigPropertyType' type: object TargetDTO: example: @@ -4147,14 +4733,32 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version + providerMetadata: providerMetadata lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4170,13 +4774,7 @@ components: error: error updatedAt: updatedAt workspaces: - - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath - gitProviderConfigId: gitProviderConfigId + - gitProviderConfigId: gitProviderConfigId image: image metadata: gitStatus: @@ -4196,20 +4794,11 @@ components: updatedAt: updatedAt uptime: 5 workspaceId: workspaceId + providerMetadata: providerMetadata + apiKey: apiKey targetId: targetId - lastJob: - createdAt: createdAt - resourceId: resourceId - action: null - id: id - state: null - error: error - resourceType: null - updatedAt: updatedAt envVars: key: envVars - name: name - id: id repository: owner: owner path: path @@ -4221,7 +4810,6 @@ components: cloneTarget: null sha: sha url: url - user: user target: default: true metadata: @@ -4234,14 +4822,32 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version + providerMetadata: providerMetadata lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4255,13 +4861,27 @@ components: workspaces: - null - null - - buildConfig: + buildConfig: cachedBuild: image: image user: user devcontainer: filePath: filePath - gitProviderConfigId: gitProviderConfigId + lastJob: + createdAt: createdAt + metadata: metadata + resourceId: resourceId + action: null + runnerId: runnerId + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + name: name + id: id + user: user + - gitProviderConfigId: gitProviderConfigId image: image metadata: gitStatus: @@ -4281,20 +4901,11 @@ components: updatedAt: updatedAt uptime: 5 workspaceId: workspaceId + providerMetadata: providerMetadata + apiKey: apiKey targetId: targetId - lastJob: - createdAt: createdAt - resourceId: resourceId - action: null - id: id - state: null - error: error - resourceType: null - updatedAt: updatedAt envVars: key: envVars - name: name - id: id repository: owner: owner path: path @@ -4306,7 +4917,6 @@ components: cloneTarget: null sha: sha url: url - user: user target: default: true metadata: @@ -4319,14 +4929,32 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version + providerMetadata: providerMetadata lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4340,9 +4968,26 @@ components: workspaces: - null - null - info: - providerMetadata: providerMetadata + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + lastJob: + createdAt: createdAt + metadata: metadata + resourceId: resourceId + action: null + runnerId: runnerId + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt name: name + id: id + user: user properties: default: type: boolean @@ -4352,14 +4997,14 @@ components: type: object id: type: string - info: - $ref: '#/components/schemas/TargetInfo' lastJob: $ref: '#/components/schemas/Job' metadata: $ref: '#/components/schemas/TargetMetadata' name: type: string + providerMetadata: + type: string state: $ref: '#/components/schemas/ResourceState' targetConfig: @@ -4380,18 +5025,6 @@ components: - targetConfigId - workspaces type: object - TargetInfo: - example: - providerMetadata: providerMetadata - name: name - properties: - name: - type: string - providerMetadata: - type: string - required: - - name - type: object TargetMetadata: example: targetId: targetId @@ -4409,33 +5042,128 @@ components: - updatedAt - uptime type: object - TargetProviderInfo: + UpdateJobState: example: - agentlessTarget: true - name: name - label: label - version: version + errorMessage: errorMessage + state: null properties: - agentlessTarget: - type: boolean - label: + errorMessage: type: string - name: + state: + $ref: '#/components/schemas/JobState' + required: + - state + type: object + UpdateRunnerMetadataDTO: + example: + runningJobs: 0 + providers: + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + uptime: 6 + properties: + providers: + items: + $ref: '#/components/schemas/ProviderInfo' + type: array + runningJobs: + type: integer + uptime: + type: integer + required: + - providers + - uptime + type: object + UpdateTargetMetadataDTO: + example: + uptime: 0 + properties: + uptime: + type: integer + required: + - uptime + type: object + UpdateTargetProviderMetadataDTO: + example: + metadata: metadata + properties: + metadata: type: string - version: + required: + - metadata + type: object + UpdateWorkspaceMetadataDTO: + example: + gitStatus: + behind: 1 + fileStatus: + - extra: extra + name: name + staging: null + worktree: null + - extra: extra + name: name + staging: null + worktree: null + ahead: 6 + branchPublished: true + currentBranch: currentBranch + uptime: 0 + properties: + gitStatus: + $ref: '#/components/schemas/GitStatus' + uptime: + type: integer + required: + - uptime + type: object + UpdateWorkspaceProviderMetadataDTO: + example: + metadata: metadata + properties: + metadata: type: string required: - - name - - version + - metadata type: object Workspace: example: - buildConfig: - cachedBuild: - image: image - user: user - devcontainer: - filePath: filePath gitProviderConfigId: gitProviderConfigId image: image metadata: @@ -4456,20 +5184,11 @@ components: updatedAt: updatedAt uptime: 5 workspaceId: workspaceId + providerMetadata: providerMetadata + apiKey: apiKey targetId: targetId - lastJob: - createdAt: createdAt - resourceId: resourceId - action: null - id: id - state: null - error: error - resourceType: null - updatedAt: updatedAt envVars: key: envVars - name: name - id: id repository: owner: owner path: path @@ -4481,7 +5200,6 @@ components: cloneTarget: null sha: sha url: url - user: user target: default: true metadata: @@ -4494,14 +5212,32 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version + providerMetadata: providerMetadata lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4515,7 +5251,29 @@ components: workspaces: - null - null + buildConfig: + cachedBuild: + image: image + user: user + devcontainer: + filePath: filePath + lastJob: + createdAt: createdAt + metadata: metadata + resourceId: resourceId + action: null + runnerId: runnerId + id: id + state: null + error: error + resourceType: null + updatedAt: updatedAt + name: name + id: id + user: user properties: + apiKey: + type: string buildConfig: $ref: '#/components/schemas/BuildConfig' envVars: @@ -4534,6 +5292,8 @@ components: $ref: '#/components/schemas/WorkspaceMetadata' name: type: string + providerMetadata: + type: string repository: $ref: '#/components/schemas/GitRepository' target: @@ -4543,6 +5303,7 @@ components: user: type: string required: + - apiKey - envVars - id - image @@ -4574,6 +5335,8 @@ components: updatedAt: updatedAt uptime: 5 workspaceId: workspaceId + providerMetadata: providerMetadata + apiKey: apiKey targetId: targetId envVars: key: envVars @@ -4600,14 +5363,32 @@ components: options: options id: id providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true agentlessTarget: true name: name + runnerId: runnerId label: label version: version + providerMetadata: providerMetadata lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4629,8 +5410,10 @@ components: filePath: filePath lastJob: createdAt: createdAt + metadata: metadata resourceId: resourceId action: null + runnerId: runnerId id: id state: null error: error @@ -4643,13 +5426,9 @@ components: error: error updatedAt: updatedAt user: user - info: - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name properties: + apiKey: + type: string buildConfig: $ref: '#/components/schemas/BuildConfig' envVars: @@ -4662,14 +5441,14 @@ components: type: string image: type: string - info: - $ref: '#/components/schemas/WorkspaceInfo' lastJob: $ref: '#/components/schemas/Job' metadata: $ref: '#/components/schemas/WorkspaceMetadata' name: type: string + providerMetadata: + type: string repository: $ref: '#/components/schemas/GitRepository' state: @@ -4681,6 +5460,7 @@ components: user: type: string required: + - apiKey - envVars - id - image @@ -4698,30 +5478,6 @@ components: dir: type: string type: object - WorkspaceInfo: - example: - providerMetadata: providerMetadata - targetId: targetId - isRunning: true - created: created - name: name - properties: - created: - type: string - isRunning: - type: boolean - name: - type: string - providerMetadata: - type: string - targetId: - type: string - required: - - created - - isRunning - - name - - targetId - type: object WorkspaceMetadata: example: gitStatus: @@ -4822,11 +5578,13 @@ components: - client - workspace - target + - runner type: string x-enum-varnames: - ApiKeyTypeClient - ApiKeyTypeWorkspace - ApiKeyTypeTarget + - ApiKeyTypeRunner models.JobAction: enum: - create @@ -4836,6 +5594,9 @@ components: - delete - force-delete - run + - install-provider + - uninstall-provider + - update-provider type: string x-enum-varnames: - JobActionCreate @@ -4845,6 +5606,9 @@ components: - JobActionDelete - JobActionForceDelete - JobActionRun + - JobActionInstallProvider + - JobActionUninstallProvider + - JobActionUpdateProvider models.ResourceStateName: enum: - undefined @@ -4887,7 +5651,7 @@ components: - ResourceStateNamePendingForcedDelete - ResourceStateNameDeleting - ResourceStateNameDeleted - provider.TargetConfigPropertyType: + models.TargetConfigPropertyType: enum: - string - option diff --git a/pkg/apiclient/api_build.go b/pkg/apiclient/api_build.go index bdb342bec5..f454edf3a7 100644 --- a/pkg/apiclient/api_build.go +++ b/pkg/apiclient/api_build.go @@ -723,3 +723,121 @@ func (a *BuildAPIService) ListBuildsExecute(r ApiListBuildsRequest) ([]BuildDTO, return localVarReturnValue, localVarHTTPResponse, nil } + +type ApiListSuccessfulBuildsRequest struct { + ctx context.Context + ApiService *BuildAPIService + repoUrl string +} + +func (r ApiListSuccessfulBuildsRequest) Execute() ([]BuildDTO, *http.Response, error) { + return r.ApiService.ListSuccessfulBuildsExecute(r) +} + +/* +ListSuccessfulBuilds List successful builds for Git repository + +List successful builds for Git repository + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param repoUrl Repository URL + @return ApiListSuccessfulBuildsRequest +*/ +func (a *BuildAPIService) ListSuccessfulBuilds(ctx context.Context, repoUrl string) ApiListSuccessfulBuildsRequest { + return ApiListSuccessfulBuildsRequest{ + ApiService: a, + ctx: ctx, + repoUrl: repoUrl, + } +} + +// Execute executes the request +// +// @return []BuildDTO +func (a *BuildAPIService) ListSuccessfulBuildsExecute(r ApiListSuccessfulBuildsRequest) ([]BuildDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []BuildDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BuildAPIService.ListSuccessfulBuilds") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/build/successful/{repoUrl}" + localVarPath = strings.Replace(localVarPath, "{"+"repoUrl"+"}", url.PathEscape(parameterValueToString(r.repoUrl, "repoUrl")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/api_job.go b/pkg/apiclient/api_job.go index 0f2a3b60b1..dfc2b0652e 100644 --- a/pkg/apiclient/api_job.go +++ b/pkg/apiclient/api_job.go @@ -16,14 +16,43 @@ import ( "io" "net/http" "net/url" + "reflect" ) // JobAPIService JobAPI service type JobAPIService service type ApiListJobsRequest struct { - ctx context.Context - ApiService *JobAPIService + ctx context.Context + ApiService *JobAPIService + states *[]string + actions *[]string + resourceId *string + resourceType *string +} + +// Job States +func (r ApiListJobsRequest) States(states []string) ApiListJobsRequest { + r.states = &states + return r +} + +// Job Actions +func (r ApiListJobsRequest) Actions(actions []string) ApiListJobsRequest { + r.actions = &actions + return r +} + +// Resource ID +func (r ApiListJobsRequest) ResourceId(resourceId string) ApiListJobsRequest { + r.resourceId = &resourceId + return r +} + +// Resource Type +func (r ApiListJobsRequest) ResourceType(resourceType string) ApiListJobsRequest { + r.resourceType = &resourceType + return r } func (r ApiListJobsRequest) Execute() ([]Job, *http.Response, error) { @@ -67,6 +96,34 @@ func (a *JobAPIService) ListJobsExecute(r ApiListJobsRequest) ([]Job, *http.Resp localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.states != nil { + t := *r.states + if reflect.TypeOf(t).Kind() == reflect.Slice { + s := reflect.ValueOf(t) + for i := 0; i < s.Len(); i++ { + parameterAddToHeaderOrQuery(localVarQueryParams, "states", s.Index(i).Interface(), "multi") + } + } else { + parameterAddToHeaderOrQuery(localVarQueryParams, "states", t, "multi") + } + } + if r.actions != nil { + t := *r.actions + if reflect.TypeOf(t).Kind() == reflect.Slice { + s := reflect.ValueOf(t) + for i := 0; i < s.Len(); i++ { + parameterAddToHeaderOrQuery(localVarQueryParams, "actions", s.Index(i).Interface(), "multi") + } + } else { + parameterAddToHeaderOrQuery(localVarQueryParams, "actions", t, "multi") + } + } + if r.resourceId != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "resourceId", r.resourceId, "") + } + if r.resourceType != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "resourceType", r.resourceType, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} diff --git a/pkg/apiclient/api_provider.go b/pkg/apiclient/api_provider.go index 168806cc22..df01d66586 100644 --- a/pkg/apiclient/api_provider.go +++ b/pkg/apiclient/api_provider.go @@ -22,55 +22,62 @@ import ( // ProviderAPIService ProviderAPI service type ProviderAPIService service -type ApiGetTargetConfigManifestRequest struct { - ctx context.Context - ApiService *ProviderAPIService - provider string +type ApiInstallProviderRequest struct { + ctx context.Context + ApiService *ProviderAPIService + runnerId string + installProviderDto *InstallProviderDTO +} + +// Install provider +func (r ApiInstallProviderRequest) InstallProviderDto(installProviderDto InstallProviderDTO) ApiInstallProviderRequest { + r.installProviderDto = &installProviderDto + return r } -func (r ApiGetTargetConfigManifestRequest) Execute() (*map[string]TargetConfigProperty, *http.Response, error) { - return r.ApiService.GetTargetConfigManifestExecute(r) +func (r ApiInstallProviderRequest) Execute() (*http.Response, error) { + return r.ApiService.InstallProviderExecute(r) } /* -GetTargetConfigManifest Get provider target config manifest +InstallProvider Install provider -Get provider target config manifest +Install provider @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param provider Provider name - @return ApiGetTargetConfigManifestRequest + @param runnerId Runner ID + @return ApiInstallProviderRequest */ -func (a *ProviderAPIService) GetTargetConfigManifest(ctx context.Context, provider string) ApiGetTargetConfigManifestRequest { - return ApiGetTargetConfigManifestRequest{ +func (a *ProviderAPIService) InstallProvider(ctx context.Context, runnerId string) ApiInstallProviderRequest { + return ApiInstallProviderRequest{ ApiService: a, ctx: ctx, - provider: provider, + runnerId: runnerId, } } // Execute executes the request -// -// @return map[string]TargetConfigProperty -func (a *ProviderAPIService) GetTargetConfigManifestExecute(r ApiGetTargetConfigManifestRequest) (*map[string]TargetConfigProperty, *http.Response, error) { +func (a *ProviderAPIService) InstallProviderExecute(r ApiInstallProviderRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *map[string]TargetConfigProperty + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.GetTargetConfigManifest") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.InstallProvider") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/provider/{provider}/target-config-manifest" - localVarPath = strings.Replace(localVarPath, "{"+"provider"+"}", url.PathEscape(parameterValueToString(r.provider, "provider")), -1) + localVarPath := localBasePath + "/runner/{runnerId}/provider/install" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.installProviderDto == nil { + return nil, reportError("installProviderDto is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -82,13 +89,15 @@ func (a *ProviderAPIService) GetTargetConfigManifestExecute(r ApiGetTargetConfig } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"*/*"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.installProviderDto if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -105,19 +114,19 @@ func (a *ProviderAPIService) GetTargetConfigManifestExecute(r ApiGetTargetConfig } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -125,76 +134,70 @@ func (a *ProviderAPIService) GetTargetConfigManifestExecute(r ApiGetTargetConfig body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } -type ApiInstallProviderRequest struct { +type ApiListProvidersRequest struct { ctx context.Context ApiService *ProviderAPIService - provider *InstallProviderRequest + runnerId *string } -// Provider to install -func (r ApiInstallProviderRequest) Provider(provider InstallProviderRequest) ApiInstallProviderRequest { - r.provider = &provider +// Runner ID +func (r ApiListProvidersRequest) RunnerId(runnerId string) ApiListProvidersRequest { + r.runnerId = &runnerId return r } -func (r ApiInstallProviderRequest) Execute() (*http.Response, error) { - return r.ApiService.InstallProviderExecute(r) +func (r ApiListProvidersRequest) Execute() ([]ProviderInfo, *http.Response, error) { + return r.ApiService.ListProvidersExecute(r) } /* -InstallProvider Install a provider +ListProviders List providers -Install a provider +List providers @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiInstallProviderRequest + @return ApiListProvidersRequest */ -func (a *ProviderAPIService) InstallProvider(ctx context.Context) ApiInstallProviderRequest { - return ApiInstallProviderRequest{ +func (a *ProviderAPIService) ListProviders(ctx context.Context) ApiListProvidersRequest { + return ApiListProvidersRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *ProviderAPIService) InstallProviderExecute(r ApiInstallProviderRequest) (*http.Response, error) { +// +// @return []ProviderInfo +func (a *ProviderAPIService) ListProvidersExecute(r ApiListProvidersRequest) ([]ProviderInfo, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []ProviderInfo ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.InstallProvider") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.ListProviders") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/provider/install" + localVarPath := localBasePath + "/runner/provider" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.provider == nil { - return nil, reportError("provider is required and must be specified") - } + if r.runnerId != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "runnerId", r.runnerId, "") + } // to determine the Content-Type header - localVarHTTPContentTypes := []string{"application/json"} + localVarHTTPContentTypes := []string{} // set Content-Type header localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) @@ -203,15 +206,13 @@ func (a *ProviderAPIService) InstallProviderExecute(r ApiInstallProviderRequest) } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.provider if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -228,19 +229,19 @@ func (a *ProviderAPIService) InstallProviderExecute(r ApiInstallProviderRequest) } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -248,53 +249,67 @@ func (a *ProviderAPIService) InstallProviderExecute(r ApiInstallProviderRequest) body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListProvidersRequest struct { - ctx context.Context - ApiService *ProviderAPIService +type ApiUninstallProviderRequest struct { + ctx context.Context + ApiService *ProviderAPIService + runnerId string + providerName string } -func (r ApiListProvidersRequest) Execute() ([]Provider, *http.Response, error) { - return r.ApiService.ListProvidersExecute(r) +func (r ApiUninstallProviderRequest) Execute() (*http.Response, error) { + return r.ApiService.UninstallProviderExecute(r) } /* -ListProviders List providers +UninstallProvider Uninstall provider -List providers +Uninstall provider @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListProvidersRequest + @param runnerId Runner ID + @param providerName Provider name + @return ApiUninstallProviderRequest */ -func (a *ProviderAPIService) ListProviders(ctx context.Context) ApiListProvidersRequest { - return ApiListProvidersRequest{ - ApiService: a, - ctx: ctx, +func (a *ProviderAPIService) UninstallProvider(ctx context.Context, runnerId string, providerName string) ApiUninstallProviderRequest { + return ApiUninstallProviderRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + providerName: providerName, } } // Execute executes the request -// -// @return []Provider -func (a *ProviderAPIService) ListProvidersExecute(r ApiListProvidersRequest) ([]Provider, *http.Response, error) { +func (a *ProviderAPIService) UninstallProviderExecute(r ApiUninstallProviderRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue []Provider + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.ListProviders") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.UninstallProvider") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/provider" + localVarPath := localBasePath + "/runner/{runnerId}/provider/{providerName}/uninstall" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"providerName"+"}", url.PathEscape(parameterValueToString(r.providerName, "providerName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -310,7 +325,7 @@ func (a *ProviderAPIService) ListProvidersExecute(r ApiListProvidersRequest) ([] } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -333,19 +348,19 @@ func (a *ProviderAPIService) ListProvidersExecute(r ApiListProvidersRequest) ([] } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -353,67 +368,72 @@ func (a *ProviderAPIService) ListProvidersExecute(r ApiListProvidersRequest) ([] body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr - } + return localVarHTTPResponse, nil +} - return localVarReturnValue, localVarHTTPResponse, nil +type ApiUpdateProviderRequest struct { + ctx context.Context + ApiService *ProviderAPIService + runnerId string + providerName string + downloadUrls *map[string]string } -type ApiUninstallProviderRequest struct { - ctx context.Context - ApiService *ProviderAPIService - provider string +// Provider download URLs +func (r ApiUpdateProviderRequest) DownloadUrls(downloadUrls map[string]string) ApiUpdateProviderRequest { + r.downloadUrls = &downloadUrls + return r } -func (r ApiUninstallProviderRequest) Execute() (*http.Response, error) { - return r.ApiService.UninstallProviderExecute(r) +func (r ApiUpdateProviderRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateProviderExecute(r) } /* -UninstallProvider Uninstall a provider +UpdateProvider Update provider -Uninstall a provider +Update provider @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param provider Provider to uninstall - @return ApiUninstallProviderRequest + @param runnerId Runner ID + @param providerName Provider name + @return ApiUpdateProviderRequest */ -func (a *ProviderAPIService) UninstallProvider(ctx context.Context, provider string) ApiUninstallProviderRequest { - return ApiUninstallProviderRequest{ - ApiService: a, - ctx: ctx, - provider: provider, +func (a *ProviderAPIService) UpdateProvider(ctx context.Context, runnerId string, providerName string) ApiUpdateProviderRequest { + return ApiUpdateProviderRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + providerName: providerName, } } // Execute executes the request -func (a *ProviderAPIService) UninstallProviderExecute(r ApiUninstallProviderRequest) (*http.Response, error) { +func (a *ProviderAPIService) UpdateProviderExecute(r ApiUpdateProviderRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.UninstallProvider") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ProviderAPIService.UpdateProvider") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/provider/{provider}/uninstall" - localVarPath = strings.Replace(localVarPath, "{"+"provider"+"}", url.PathEscape(parameterValueToString(r.provider, "provider")), -1) + localVarPath := localBasePath + "/runner/{runnerId}/provider/{providerName}/update" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"providerName"+"}", url.PathEscape(parameterValueToString(r.providerName, "providerName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.downloadUrls == nil { + return nil, reportError("downloadUrls is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -432,6 +452,8 @@ func (a *ProviderAPIService) UninstallProviderExecute(r ApiUninstallProviderRequ if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.downloadUrls if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/api_runner.go b/pkg/apiclient/api_runner.go new file mode 100644 index 0000000000..7c1afbe486 --- /dev/null +++ b/pkg/apiclient/api_runner.go @@ -0,0 +1,845 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// RunnerAPIService RunnerAPI service +type RunnerAPIService service + +type ApiGetRunnerRequest struct { + ctx context.Context + ApiService *RunnerAPIService + runnerId string +} + +func (r ApiGetRunnerRequest) Execute() (*RunnerDTO, *http.Response, error) { + return r.ApiService.GetRunnerExecute(r) +} + +/* +GetRunner Get a runner + +Get a runner + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param runnerId Runner ID + @return ApiGetRunnerRequest +*/ +func (a *RunnerAPIService) GetRunner(ctx context.Context, runnerId string) ApiGetRunnerRequest { + return ApiGetRunnerRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + } +} + +// Execute executes the request +// +// @return RunnerDTO +func (a *RunnerAPIService) GetRunnerExecute(r ApiGetRunnerRequest) (*RunnerDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RunnerDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.GetRunner") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner/{runnerId}" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListRunnerJobsRequest struct { + ctx context.Context + ApiService *RunnerAPIService + runnerId string +} + +func (r ApiListRunnerJobsRequest) Execute() ([]Job, *http.Response, error) { + return r.ApiService.ListRunnerJobsExecute(r) +} + +/* +ListRunnerJobs List runner jobs + +List runner jobs + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param runnerId Runner ID + @return ApiListRunnerJobsRequest +*/ +func (a *RunnerAPIService) ListRunnerJobs(ctx context.Context, runnerId string) ApiListRunnerJobsRequest { + return ApiListRunnerJobsRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + } +} + +// Execute executes the request +// +// @return []Job +func (a *RunnerAPIService) ListRunnerJobsExecute(r ApiListRunnerJobsRequest) ([]Job, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []Job + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.ListRunnerJobs") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner/{runnerId}/jobs" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiListRunnersRequest struct { + ctx context.Context + ApiService *RunnerAPIService +} + +func (r ApiListRunnersRequest) Execute() ([]RunnerDTO, *http.Response, error) { + return r.ApiService.ListRunnersExecute(r) +} + +/* +ListRunners List runners + +List runners + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiListRunnersRequest +*/ +func (a *RunnerAPIService) ListRunners(ctx context.Context) ApiListRunnersRequest { + return ApiListRunnersRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return []RunnerDTO +func (a *RunnerAPIService) ListRunnersExecute(r ApiListRunnersRequest) ([]RunnerDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []RunnerDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.ListRunners") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiRegisterRunnerRequest struct { + ctx context.Context + ApiService *RunnerAPIService + runner *RegisterRunnerDTO +} + +// Register runner +func (r ApiRegisterRunnerRequest) Runner(runner RegisterRunnerDTO) ApiRegisterRunnerRequest { + r.runner = &runner + return r +} + +func (r ApiRegisterRunnerRequest) Execute() (*RegisterRunnerResultDTO, *http.Response, error) { + return r.ApiService.RegisterRunnerExecute(r) +} + +/* +RegisterRunner Register a runner + +Register a runner + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiRegisterRunnerRequest +*/ +func (a *RunnerAPIService) RegisterRunner(ctx context.Context) ApiRegisterRunnerRequest { + return ApiRegisterRunnerRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return RegisterRunnerResultDTO +func (a *RunnerAPIService) RegisterRunnerExecute(r ApiRegisterRunnerRequest) (*RegisterRunnerResultDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisterRunnerResultDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.RegisterRunner") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.runner == nil { + return localVarReturnValue, nil, reportError("runner is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.runner + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiRemoveRunnerRequest struct { + ctx context.Context + ApiService *RunnerAPIService + runnerId string +} + +func (r ApiRemoveRunnerRequest) Execute() (*http.Response, error) { + return r.ApiService.RemoveRunnerExecute(r) +} + +/* +RemoveRunner Remove runner + +Remove runner + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param runnerId Runner ID + @return ApiRemoveRunnerRequest +*/ +func (a *RunnerAPIService) RemoveRunner(ctx context.Context, runnerId string) ApiRemoveRunnerRequest { + return ApiRemoveRunnerRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + } +} + +// Execute executes the request +func (a *RunnerAPIService) RemoveRunnerExecute(r ApiRemoveRunnerRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.RemoveRunner") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner/{runnerId}" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiSetRunnerMetadataRequest struct { + ctx context.Context + ApiService *RunnerAPIService + runnerId string + runnerMetadata *UpdateRunnerMetadataDTO +} + +// Runner Metadata +func (r ApiSetRunnerMetadataRequest) RunnerMetadata(runnerMetadata UpdateRunnerMetadataDTO) ApiSetRunnerMetadataRequest { + r.runnerMetadata = &runnerMetadata + return r +} + +func (r ApiSetRunnerMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.SetRunnerMetadataExecute(r) +} + +/* +SetRunnerMetadata Set runner metadata + +Set runner metadata + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param runnerId Runner ID + @return ApiSetRunnerMetadataRequest +*/ +func (a *RunnerAPIService) SetRunnerMetadata(ctx context.Context, runnerId string) ApiSetRunnerMetadataRequest { + return ApiSetRunnerMetadataRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + } +} + +// Execute executes the request +func (a *RunnerAPIService) SetRunnerMetadataExecute(r ApiSetRunnerMetadataRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.SetRunnerMetadata") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner/{runnerId}/metadata" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.runnerMetadata == nil { + return nil, reportError("runnerMetadata is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.runnerMetadata + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiUpdateJobStateRequest struct { + ctx context.Context + ApiService *RunnerAPIService + runnerId string + jobId string + updateJobState *UpdateJobState +} + +// Update job state +func (r ApiUpdateJobStateRequest) UpdateJobState(updateJobState UpdateJobState) ApiUpdateJobStateRequest { + r.updateJobState = &updateJobState + return r +} + +func (r ApiUpdateJobStateRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateJobStateExecute(r) +} + +/* +UpdateJobState Update job state + +Update job state + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param runnerId Runner ID + @param jobId Job ID + @return ApiUpdateJobStateRequest +*/ +func (a *RunnerAPIService) UpdateJobState(ctx context.Context, runnerId string, jobId string) ApiUpdateJobStateRequest { + return ApiUpdateJobStateRequest{ + ApiService: a, + ctx: ctx, + runnerId: runnerId, + jobId: jobId, + } +} + +// Execute executes the request +func (a *RunnerAPIService) UpdateJobStateExecute(r ApiUpdateJobStateRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.UpdateJobState") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/runner/{runnerId}/jobs/{jobId}/state" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"jobId"+"}", url.PathEscape(parameterValueToString(r.jobId, "jobId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.updateJobState == nil { + return nil, reportError("updateJobState is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.updateJobState + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index 5cacc61d1a..5dff658d29 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -149,15 +149,15 @@ func (a *TargetAPIService) CreateTargetExecute(r ApiCreateTargetRequest) (*Targe } type ApiGetTargetRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - verbose *bool + ctx context.Context + ApiService *TargetAPIService + targetId string + showOptions *bool } -// Verbose -func (r ApiGetTargetRequest) Verbose(verbose bool) ApiGetTargetRequest { - r.verbose = &verbose +// Show target config options +func (r ApiGetTargetRequest) ShowOptions(showOptions bool) ApiGetTargetRequest { + r.showOptions = &showOptions return r } @@ -205,8 +205,8 @@ func (a *TargetAPIService) GetTargetExecute(r ApiGetTargetRequest) (*TargetDTO, localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.verbose != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "verbose", r.verbose, "") + if r.showOptions != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "showOptions", r.showOptions, "") } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -276,15 +276,121 @@ func (a *TargetAPIService) GetTargetExecute(r ApiGetTargetRequest) (*TargetDTO, return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListTargetsRequest struct { +type ApiHandleSuccessfulCreationRequest struct { ctx context.Context ApiService *TargetAPIService - verbose *bool + targetId string +} + +func (r ApiHandleSuccessfulCreationRequest) Execute() (*http.Response, error) { + return r.ApiService.HandleSuccessfulCreationExecute(r) +} + +/* +HandleSuccessfulCreation Handles successful creation of the target + +Handles successful creation of the target + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param targetId Target ID or name + @return ApiHandleSuccessfulCreationRequest +*/ +func (a *TargetAPIService) HandleSuccessfulCreation(ctx context.Context, targetId string) ApiHandleSuccessfulCreationRequest { + return ApiHandleSuccessfulCreationRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + } +} + +// Execute executes the request +func (a *TargetAPIService) HandleSuccessfulCreationExecute(r ApiHandleSuccessfulCreationRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.HandleSuccessfulCreation") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/target/{targetId}/handle-successful-creation" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiListTargetsRequest struct { + ctx context.Context + ApiService *TargetAPIService + showOptions *bool } -// Verbose -func (r ApiListTargetsRequest) Verbose(verbose bool) ApiListTargetsRequest { - r.verbose = &verbose +// Show target config options +func (r ApiListTargetsRequest) ShowOptions(showOptions bool) ApiListTargetsRequest { + r.showOptions = &showOptions return r } @@ -329,8 +435,8 @@ func (a *TargetAPIService) ListTargetsExecute(r ApiListTargetsRequest) ([]Target localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.verbose != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "verbose", r.verbose, "") + if r.showOptions != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "showOptions", r.showOptions, "") } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -623,15 +729,15 @@ func (a *TargetAPIService) SetDefaultTargetExecute(r ApiSetDefaultTargetRequest) } type ApiSetTargetMetadataRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - setMetadata *SetTargetMetadata + ctx context.Context + ApiService *TargetAPIService + targetId string + targetMetadata *UpdateTargetMetadataDTO } -// Set Metadata -func (r ApiSetTargetMetadataRequest) SetMetadata(setMetadata SetTargetMetadata) ApiSetTargetMetadataRequest { - r.setMetadata = &setMetadata +// Target Metadata +func (r ApiSetTargetMetadataRequest) TargetMetadata(targetMetadata UpdateTargetMetadataDTO) ApiSetTargetMetadataRequest { + r.targetMetadata = &targetMetadata return r } @@ -675,8 +781,8 @@ func (a *TargetAPIService) SetTargetMetadataExecute(r ApiSetTargetMetadataReques localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.setMetadata == nil { - return nil, reportError("setMetadata is required and must be specified") + if r.targetMetadata == nil { + return nil, reportError("targetMetadata is required and must be specified") } // to determine the Content-Type header @@ -697,7 +803,7 @@ func (a *TargetAPIService) SetTargetMetadataExecute(r ApiSetTargetMetadataReques localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.setMetadata + localVarPostBody = r.targetMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -951,3 +1057,121 @@ func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Resp return localVarHTTPResponse, nil } + +type ApiUpdateTargetProviderMetadataRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + metadata *UpdateTargetProviderMetadataDTO +} + +// Provider metadata +func (r ApiUpdateTargetProviderMetadataRequest) Metadata(metadata UpdateTargetProviderMetadataDTO) ApiUpdateTargetProviderMetadataRequest { + r.metadata = &metadata + return r +} + +func (r ApiUpdateTargetProviderMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateTargetProviderMetadataExecute(r) +} + +/* +UpdateTargetProviderMetadata Update target provider metadata + +Update target provider metadata + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param targetId Target ID + @return ApiUpdateTargetProviderMetadataRequest +*/ +func (a *TargetAPIService) UpdateTargetProviderMetadata(ctx context.Context, targetId string) ApiUpdateTargetProviderMetadataRequest { + return ApiUpdateTargetProviderMetadataRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + } +} + +// Execute executes the request +func (a *TargetAPIService) UpdateTargetProviderMetadataExecute(r ApiUpdateTargetProviderMetadataRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.UpdateTargetProviderMetadata") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/target/{targetId}/provider-metadata" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.metadata == nil { + return nil, reportError("metadata is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.metadata + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/api_target_config.go b/pkg/apiclient/api_target_config.go index d67edc250c..16a800a966 100644 --- a/pkg/apiclient/api_target_config.go +++ b/pkg/apiclient/api_target_config.go @@ -26,6 +26,7 @@ type ApiAddTargetConfigRequest struct { ctx context.Context ApiService *TargetConfigAPIService targetConfig *AddTargetConfigDTO + showOptions *bool } // Target config to add @@ -34,6 +35,12 @@ func (r ApiAddTargetConfigRequest) TargetConfig(targetConfig AddTargetConfigDTO) return r } +// Show target config options +func (r ApiAddTargetConfigRequest) ShowOptions(showOptions bool) ApiAddTargetConfigRequest { + r.showOptions = &showOptions + return r +} + func (r ApiAddTargetConfigRequest) Execute() (*TargetConfig, *http.Response, error) { return r.ApiService.AddTargetConfigExecute(r) } @@ -78,6 +85,9 @@ func (a *TargetConfigAPIService) AddTargetConfigExecute(r ApiAddTargetConfigRequ return localVarReturnValue, nil, reportError("targetConfig is required and must be specified") } + if r.showOptions != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "showOptions", r.showOptions, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -149,8 +159,15 @@ func (a *TargetConfigAPIService) AddTargetConfigExecute(r ApiAddTargetConfigRequ } type ApiListTargetConfigsRequest struct { - ctx context.Context - ApiService *TargetConfigAPIService + ctx context.Context + ApiService *TargetConfigAPIService + showOptions *bool +} + +// Show target config options +func (r ApiListTargetConfigsRequest) ShowOptions(showOptions bool) ApiListTargetConfigsRequest { + r.showOptions = &showOptions + return r } func (r ApiListTargetConfigsRequest) Execute() ([]TargetConfig, *http.Response, error) { @@ -194,6 +211,9 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.showOptions != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "showOptions", r.showOptions, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index 56f533a7a3..a390d4f43f 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -152,13 +152,6 @@ type ApiGetWorkspaceRequest struct { ctx context.Context ApiService *WorkspaceAPIService workspaceId string - verbose *bool -} - -// Verbose -func (r ApiGetWorkspaceRequest) Verbose(verbose bool) ApiGetWorkspaceRequest { - r.verbose = &verbose - return r } func (r ApiGetWorkspaceRequest) Execute() (*WorkspaceDTO, *http.Response, error) { @@ -205,9 +198,6 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.verbose != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "verbose", r.verbose, "") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -279,13 +269,6 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo type ApiListWorkspacesRequest struct { ctx context.Context ApiService *WorkspaceAPIService - verbose *bool -} - -// Verbose -func (r ApiListWorkspacesRequest) Verbose(verbose bool) ApiListWorkspacesRequest { - r.verbose = &verbose - return r } func (r ApiListWorkspacesRequest) Execute() ([]WorkspaceDTO, *http.Response, error) { @@ -329,9 +312,6 @@ func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.verbose != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "verbose", r.verbose, "") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -517,15 +497,15 @@ func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest } type ApiSetWorkspaceMetadataRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - setMetadata *SetWorkspaceMetadata + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + workspaceMetadata *UpdateWorkspaceMetadataDTO } -// Set Metadata -func (r ApiSetWorkspaceMetadataRequest) SetMetadata(setMetadata SetWorkspaceMetadata) ApiSetWorkspaceMetadataRequest { - r.setMetadata = &setMetadata +// Workspace Metadata +func (r ApiSetWorkspaceMetadataRequest) WorkspaceMetadata(workspaceMetadata UpdateWorkspaceMetadataDTO) ApiSetWorkspaceMetadataRequest { + r.workspaceMetadata = &workspaceMetadata return r } @@ -569,8 +549,8 @@ func (a *WorkspaceAPIService) SetWorkspaceMetadataExecute(r ApiSetWorkspaceMetad localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.setMetadata == nil { - return nil, reportError("setMetadata is required and must be specified") + if r.workspaceMetadata == nil { + return nil, reportError("workspaceMetadata is required and must be specified") } // to determine the Content-Type header @@ -591,7 +571,7 @@ func (a *WorkspaceAPIService) SetWorkspaceMetadataExecute(r ApiSetWorkspaceMetad localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.setMetadata + localVarPostBody = r.workspaceMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -845,3 +825,121 @@ func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (* return localVarHTTPResponse, nil } + +type ApiUpdateWorkspaceProviderMetadataRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + metadata *UpdateWorkspaceProviderMetadataDTO +} + +// Provider metadata +func (r ApiUpdateWorkspaceProviderMetadataRequest) Metadata(metadata UpdateWorkspaceProviderMetadataDTO) ApiUpdateWorkspaceProviderMetadataRequest { + r.metadata = &metadata + return r +} + +func (r ApiUpdateWorkspaceProviderMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateWorkspaceProviderMetadataExecute(r) +} + +/* +UpdateWorkspaceProviderMetadata Update workspace provider metadata + +Update workspace provider metadata + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID + @return ApiUpdateWorkspaceProviderMetadataRequest +*/ +func (a *WorkspaceAPIService) UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId string) ApiUpdateWorkspaceProviderMetadataRequest { + return ApiUpdateWorkspaceProviderMetadataRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +func (a *WorkspaceAPIService) UpdateWorkspaceProviderMetadataExecute(r ApiUpdateWorkspaceProviderMetadataRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.UpdateWorkspaceProviderMetadata") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}/provider-metadata" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.metadata == nil { + return nil, reportError("metadata is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.metadata + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} diff --git a/pkg/apiclient/client.go b/pkg/apiclient/client.go index fccca57914..03b6cbd9ed 100644 --- a/pkg/apiclient/client.go +++ b/pkg/apiclient/client.go @@ -66,6 +66,8 @@ type APIClient struct { ProviderAPI *ProviderAPIService + RunnerAPI *RunnerAPIService + SampleAPI *SampleAPIService ServerAPI *ServerAPIService @@ -106,6 +108,7 @@ func NewAPIClient(cfg *Configuration) *APIClient { c.JobAPI = (*JobAPIService)(&c.common) c.PrebuildAPI = (*PrebuildAPIService)(&c.common) c.ProviderAPI = (*ProviderAPIService)(&c.common) + c.RunnerAPI = (*RunnerAPIService)(&c.common) c.SampleAPI = (*SampleAPIService)(&c.common) c.ServerAPI = (*ServerAPIService)(&c.common) c.TargetAPI = (*TargetAPIService)(&c.common) diff --git a/pkg/apiclient/docs/AddTargetConfigDTO.md b/pkg/apiclient/docs/AddTargetConfigDTO.md index 2fa3915d71..9354521a6f 100644 --- a/pkg/apiclient/docs/AddTargetConfigDTO.md +++ b/pkg/apiclient/docs/AddTargetConfigDTO.md @@ -6,13 +6,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Name** | **string** | | **Options** | **string** | | -**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | +**ProviderInfo** | [**ProviderInfo**](ProviderInfo.md) | | ## Methods ### NewAddTargetConfigDTO -`func NewAddTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo, ) *AddTargetConfigDTO` +`func NewAddTargetConfigDTO(name string, options string, providerInfo ProviderInfo, ) *AddTargetConfigDTO` NewAddTargetConfigDTO instantiates a new AddTargetConfigDTO object This constructor will assign default values to properties that have it defined, @@ -69,20 +69,20 @@ SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *AddTargetConfigDTO) GetProviderInfo() TargetProviderInfo` +`func (o *AddTargetConfigDTO) GetProviderInfo() ProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *AddTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool)` +`func (o *AddTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *AddTargetConfigDTO) SetProviderInfo(v TargetProviderInfo)` +`func (o *AddTargetConfigDTO) SetProviderInfo(v ProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/BuildAPI.md b/pkg/apiclient/docs/BuildAPI.md index a98f28c917..6f3085334b 100644 --- a/pkg/apiclient/docs/BuildAPI.md +++ b/pkg/apiclient/docs/BuildAPI.md @@ -10,6 +10,7 @@ Method | HTTP request | Description [**DeleteBuildsFromPrebuild**](BuildAPI.md#DeleteBuildsFromPrebuild) | **Delete** /build/prebuild/{prebuildId} | Delete builds [**GetBuild**](BuildAPI.md#GetBuild) | **Get** /build/{buildId} | Get build data [**ListBuilds**](BuildAPI.md#ListBuilds) | **Get** /build | List builds +[**ListSuccessfulBuilds**](BuildAPI.md#ListSuccessfulBuilds) | **Get** /build/successful/{repoUrl} | List successful builds for Git repository @@ -413,3 +414,73 @@ Other parameters are passed through a pointer to a apiListBuildsRequest struct v [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +## ListSuccessfulBuilds + +> []BuildDTO ListSuccessfulBuilds(ctx, repoUrl).Execute() + +List successful builds for Git repository + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + repoUrl := "repoUrl_example" // string | Repository URL + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.BuildAPI.ListSuccessfulBuilds(context.Background(), repoUrl).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `BuildAPI.ListSuccessfulBuilds``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListSuccessfulBuilds`: []BuildDTO + fmt.Fprintf(os.Stdout, "Response from `BuildAPI.ListSuccessfulBuilds`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**repoUrl** | **string** | Repository URL | + +### Other Parameters + +Other parameters are passed through a pointer to a apiListSuccessfulBuildsRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**[]BuildDTO**](BuildDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/InstallProviderRequest.md b/pkg/apiclient/docs/InstallProviderDTO.md similarity index 62% rename from pkg/apiclient/docs/InstallProviderRequest.md rename to pkg/apiclient/docs/InstallProviderDTO.md index 4e1677ed24..0c62eab37b 100644 --- a/pkg/apiclient/docs/InstallProviderRequest.md +++ b/pkg/apiclient/docs/InstallProviderDTO.md @@ -1,4 +1,4 @@ -# InstallProviderRequest +# InstallProviderDTO ## Properties @@ -9,59 +9,59 @@ Name | Type | Description | Notes ## Methods -### NewInstallProviderRequest +### NewInstallProviderDTO -`func NewInstallProviderRequest(downloadUrls map[string]string, name string, ) *InstallProviderRequest` +`func NewInstallProviderDTO(downloadUrls map[string]string, name string, ) *InstallProviderDTO` -NewInstallProviderRequest instantiates a new InstallProviderRequest object +NewInstallProviderDTO instantiates a new InstallProviderDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewInstallProviderRequestWithDefaults +### NewInstallProviderDTOWithDefaults -`func NewInstallProviderRequestWithDefaults() *InstallProviderRequest` +`func NewInstallProviderDTOWithDefaults() *InstallProviderDTO` -NewInstallProviderRequestWithDefaults instantiates a new InstallProviderRequest object +NewInstallProviderDTOWithDefaults instantiates a new InstallProviderDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetDownloadUrls -`func (o *InstallProviderRequest) GetDownloadUrls() map[string]string` +`func (o *InstallProviderDTO) GetDownloadUrls() map[string]string` GetDownloadUrls returns the DownloadUrls field if non-nil, zero value otherwise. ### GetDownloadUrlsOk -`func (o *InstallProviderRequest) GetDownloadUrlsOk() (*map[string]string, bool)` +`func (o *InstallProviderDTO) GetDownloadUrlsOk() (*map[string]string, bool)` GetDownloadUrlsOk returns a tuple with the DownloadUrls field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetDownloadUrls -`func (o *InstallProviderRequest) SetDownloadUrls(v map[string]string)` +`func (o *InstallProviderDTO) SetDownloadUrls(v map[string]string)` SetDownloadUrls sets DownloadUrls field to given value. ### GetName -`func (o *InstallProviderRequest) GetName() string` +`func (o *InstallProviderDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *InstallProviderRequest) GetNameOk() (*string, bool)` +`func (o *InstallProviderDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *InstallProviderRequest) SetName(v string)` +`func (o *InstallProviderDTO) SetName(v string)` SetName sets Name field to given value. diff --git a/pkg/apiclient/docs/Job.md b/pkg/apiclient/docs/Job.md index f6a49470d7..3b28ec77ea 100644 --- a/pkg/apiclient/docs/Job.md +++ b/pkg/apiclient/docs/Job.md @@ -8,8 +8,10 @@ Name | Type | Description | Notes **CreatedAt** | **string** | | **Error** | Pointer to **string** | | [optional] **Id** | **string** | | +**Metadata** | Pointer to **string** | JSON encoded metadata | [optional] **ResourceId** | **string** | | **ResourceType** | [**ResourceType**](ResourceType.md) | | +**RunnerId** | Pointer to **string** | | [optional] **State** | [**JobState**](JobState.md) | | **UpdatedAt** | **string** | | @@ -117,6 +119,31 @@ and a boolean to check if the value has been set. SetId sets Id field to given value. +### GetMetadata + +`func (o *Job) GetMetadata() string` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *Job) GetMetadataOk() (*string, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *Job) SetMetadata(v string)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *Job) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + ### GetResourceId `func (o *Job) GetResourceId() string` @@ -157,6 +184,31 @@ and a boolean to check if the value has been set. SetResourceType sets ResourceType field to given value. +### GetRunnerId + +`func (o *Job) GetRunnerId() string` + +GetRunnerId returns the RunnerId field if non-nil, zero value otherwise. + +### GetRunnerIdOk + +`func (o *Job) GetRunnerIdOk() (*string, bool)` + +GetRunnerIdOk returns a tuple with the RunnerId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRunnerId + +`func (o *Job) SetRunnerId(v string)` + +SetRunnerId sets RunnerId field to given value. + +### HasRunnerId + +`func (o *Job) HasRunnerId() bool` + +HasRunnerId returns a boolean if a field has been set. + ### GetState `func (o *Job) GetState() JobState` diff --git a/pkg/apiclient/docs/JobAPI.md b/pkg/apiclient/docs/JobAPI.md index 038ff50c2f..198bafb941 100644 --- a/pkg/apiclient/docs/JobAPI.md +++ b/pkg/apiclient/docs/JobAPI.md @@ -10,7 +10,7 @@ Method | HTTP request | Description ## ListJobs -> []Job ListJobs(ctx).Execute() +> []Job ListJobs(ctx).States(states).Actions(actions).ResourceId(resourceId).ResourceType(resourceType).Execute() List jobs @@ -29,10 +29,14 @@ import ( ) func main() { + states := []string{"Inner_example"} // []string | Job States (optional) + actions := []string{"Inner_example"} // []string | Job Actions (optional) + resourceId := "resourceId_example" // string | Resource ID (optional) + resourceType := "resourceType_example" // string | Resource Type (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.JobAPI.ListJobs(context.Background()).Execute() + resp, r, err := apiClient.JobAPI.ListJobs(context.Background()).States(states).Actions(actions).ResourceId(resourceId).ResourceType(resourceType).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `JobAPI.ListJobs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -44,13 +48,20 @@ func main() { ### Path Parameters -This endpoint does not need any parameter. + ### Other Parameters Other parameters are passed through a pointer to a apiListJobsRequest struct via the builder pattern +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **states** | **[]string** | Job States | + **actions** | **[]string** | Job Actions | + **resourceId** | **string** | Resource ID | + **resourceType** | **string** | Resource Type | + ### Return type [**[]Job**](Job.md) diff --git a/pkg/apiclient/docs/ModelsApiKeyType.md b/pkg/apiclient/docs/ModelsApiKeyType.md index 28da6f6fb4..370b7fd53d 100644 --- a/pkg/apiclient/docs/ModelsApiKeyType.md +++ b/pkg/apiclient/docs/ModelsApiKeyType.md @@ -9,6 +9,8 @@ * `ApiKeyTypeTarget` (value: `"target"`) +* `ApiKeyTypeRunner` (value: `"runner"`) + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/ModelsJobAction.md b/pkg/apiclient/docs/ModelsJobAction.md index 5e131d5365..d05b3c15af 100644 --- a/pkg/apiclient/docs/ModelsJobAction.md +++ b/pkg/apiclient/docs/ModelsJobAction.md @@ -17,6 +17,12 @@ * `JobActionRun` (value: `"run"`) +* `JobActionInstallProvider` (value: `"install-provider"`) + +* `JobActionUninstallProvider` (value: `"uninstall-provider"`) + +* `JobActionUpdateProvider` (value: `"update-provider"`) + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/ProviderTargetConfigPropertyType.md b/pkg/apiclient/docs/ModelsTargetConfigPropertyType.md similarity index 93% rename from pkg/apiclient/docs/ProviderTargetConfigPropertyType.md rename to pkg/apiclient/docs/ModelsTargetConfigPropertyType.md index c3e0c6dadf..233b8411db 100644 --- a/pkg/apiclient/docs/ProviderTargetConfigPropertyType.md +++ b/pkg/apiclient/docs/ModelsTargetConfigPropertyType.md @@ -1,4 +1,4 @@ -# ProviderTargetConfigPropertyType +# ModelsTargetConfigPropertyType ## Enum diff --git a/pkg/apiclient/docs/Provider.md b/pkg/apiclient/docs/Provider.md deleted file mode 100644 index fae62455f1..0000000000 --- a/pkg/apiclient/docs/Provider.md +++ /dev/null @@ -1,98 +0,0 @@ -# Provider - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**Label** | Pointer to **string** | | [optional] -**Name** | **string** | | -**Version** | **string** | | - -## Methods - -### NewProvider - -`func NewProvider(name string, version string, ) *Provider` - -NewProvider instantiates a new Provider object -This constructor will assign default values to properties that have it defined, -and makes sure properties required by API are set, but the set of arguments -will change when the set of required properties is changed - -### NewProviderWithDefaults - -`func NewProviderWithDefaults() *Provider` - -NewProviderWithDefaults instantiates a new Provider object -This constructor will only assign default values to properties that have it defined, -but it doesn't guarantee that properties required by API are set - -### GetLabel - -`func (o *Provider) GetLabel() string` - -GetLabel returns the Label field if non-nil, zero value otherwise. - -### GetLabelOk - -`func (o *Provider) GetLabelOk() (*string, bool)` - -GetLabelOk returns a tuple with the Label field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetLabel - -`func (o *Provider) SetLabel(v string)` - -SetLabel sets Label field to given value. - -### HasLabel - -`func (o *Provider) HasLabel() bool` - -HasLabel returns a boolean if a field has been set. - -### GetName - -`func (o *Provider) GetName() string` - -GetName returns the Name field if non-nil, zero value otherwise. - -### GetNameOk - -`func (o *Provider) GetNameOk() (*string, bool)` - -GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetName - -`func (o *Provider) SetName(v string)` - -SetName sets Name field to given value. - - -### GetVersion - -`func (o *Provider) GetVersion() string` - -GetVersion returns the Version field if non-nil, zero value otherwise. - -### GetVersionOk - -`func (o *Provider) GetVersionOk() (*string, bool)` - -GetVersionOk returns a tuple with the Version field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetVersion - -`func (o *Provider) SetVersion(v string)` - -SetVersion sets Version field to given value. - - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/docs/ProviderAPI.md b/pkg/apiclient/docs/ProviderAPI.md index 8098525c67..13db2ba603 100644 --- a/pkg/apiclient/docs/ProviderAPI.md +++ b/pkg/apiclient/docs/ProviderAPI.md @@ -4,18 +4,18 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GetTargetConfigManifest**](ProviderAPI.md#GetTargetConfigManifest) | **Get** /provider/{provider}/target-config-manifest | Get provider target config manifest -[**InstallProvider**](ProviderAPI.md#InstallProvider) | **Post** /provider/install | Install a provider -[**ListProviders**](ProviderAPI.md#ListProviders) | **Get** /provider | List providers -[**UninstallProvider**](ProviderAPI.md#UninstallProvider) | **Post** /provider/{provider}/uninstall | Uninstall a provider +[**InstallProvider**](ProviderAPI.md#InstallProvider) | **Post** /runner/{runnerId}/provider/install | Install provider +[**ListProviders**](ProviderAPI.md#ListProviders) | **Get** /runner/provider | List providers +[**UninstallProvider**](ProviderAPI.md#UninstallProvider) | **Post** /runner/{runnerId}/provider/{providerName}/uninstall | Uninstall provider +[**UpdateProvider**](ProviderAPI.md#UpdateProvider) | **Post** /runner/{runnerId}/provider/{providerName}/update | Update provider -## GetTargetConfigManifest +## InstallProvider -> map[string]TargetConfigProperty GetTargetConfigManifest(ctx, provider).Execute() +> InstallProvider(ctx, runnerId).InstallProviderDto(installProviderDto).Execute() -Get provider target config manifest +Install provider @@ -32,17 +32,16 @@ import ( ) func main() { - provider := "provider_example" // string | Provider name + runnerId := "runnerId_example" // string | Runner ID + installProviderDto := *openapiclient.NewInstallProviderDTO(map[string]string{"key": "Inner_example"}, "Name_example") // InstallProviderDTO | Install provider configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), provider).Execute() + r, err := apiClient.ProviderAPI.InstallProvider(context.Background(), runnerId).InstallProviderDto(installProviderDto).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.GetTargetConfigManifest``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.InstallProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetTargetConfigManifest`: map[string]TargetConfigProperty - fmt.Fprintf(os.Stdout, "Response from `ProviderAPI.GetTargetConfigManifest`: %v\n", resp) } ``` @@ -52,20 +51,21 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**provider** | **string** | Provider name | +**runnerId** | **string** | Runner ID | ### Other Parameters -Other parameters are passed through a pointer to a apiGetTargetConfigManifestRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiInstallProviderRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **installProviderDto** | [**InstallProviderDTO**](InstallProviderDTO.md) | Install provider | ### Return type -[**map[string]TargetConfigProperty**](TargetConfigProperty.md) + (empty response body) ### Authorization @@ -74,18 +74,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: */* +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## InstallProvider +## ListProviders -> InstallProvider(ctx).Provider(provider).Execute() +> []ProviderInfo ListProviders(ctx).RunnerId(runnerId).Execute() -Install a provider +List providers @@ -102,15 +102,17 @@ import ( ) func main() { - provider := *openapiclient.NewInstallProviderRequest(map[string]string{"key": "Inner_example"}, "Name_example") // InstallProviderRequest | Provider to install + runnerId := "runnerId_example" // string | Runner ID (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProviderAPI.InstallProvider(context.Background()).Provider(provider).Execute() + resp, r, err := apiClient.ProviderAPI.ListProviders(context.Background()).RunnerId(runnerId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.InstallProvider``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.ListProviders``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListProviders`: []ProviderInfo + fmt.Fprintf(os.Stdout, "Response from `ProviderAPI.ListProviders`: %v\n", resp) } ``` @@ -120,16 +122,16 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiInstallProviderRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListProvidersRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **provider** | [**InstallProviderRequest**](InstallProviderRequest.md) | Provider to install | + **runnerId** | **string** | Runner ID | ### Return type - (empty response body) +[**[]ProviderInfo**](ProviderInfo.md) ### Authorization @@ -137,19 +139,19 @@ Name | Type | Description | Notes ### HTTP request headers -- **Content-Type**: application/json -- **Accept**: Not defined +- **Content-Type**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## ListProviders +## UninstallProvider -> []Provider ListProviders(ctx).Execute() +> UninstallProvider(ctx, runnerId, providerName).Execute() -List providers +Uninstall provider @@ -166,31 +168,41 @@ import ( ) func main() { + runnerId := "runnerId_example" // string | Runner ID + providerName := "providerName_example" // string | Provider name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ProviderAPI.ListProviders(context.Background()).Execute() + r, err := apiClient.ProviderAPI.UninstallProvider(context.Background(), runnerId, providerName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.ListProviders``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.UninstallProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListProviders`: []Provider - fmt.Fprintf(os.Stdout, "Response from `ProviderAPI.ListProviders`: %v\n", resp) } ``` ### Path Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | +**providerName** | **string** | Provider name | ### Other Parameters -Other parameters are passed through a pointer to a apiListProvidersRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiUninstallProviderRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + ### Return type -[**[]Provider**](Provider.md) + (empty response body) ### Authorization @@ -199,18 +211,18 @@ Other parameters are passed through a pointer to a apiListProvidersRequest struc ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## UninstallProvider +## UpdateProvider -> UninstallProvider(ctx, provider).Execute() +> UpdateProvider(ctx, runnerId, providerName).DownloadUrls(downloadUrls).Execute() -Uninstall a provider +Update provider @@ -227,13 +239,15 @@ import ( ) func main() { - provider := "provider_example" // string | Provider to uninstall + runnerId := "runnerId_example" // string | Runner ID + providerName := "providerName_example" // string | Provider name + downloadUrls := map[string]string{"key": "Inner_example"} // map[string]string | Provider download URLs configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProviderAPI.UninstallProvider(context.Background(), provider).Execute() + r, err := apiClient.ProviderAPI.UpdateProvider(context.Background(), runnerId, providerName).DownloadUrls(downloadUrls).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.UninstallProvider``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.UpdateProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -245,17 +259,20 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**provider** | **string** | Provider to uninstall | +**runnerId** | **string** | Runner ID | +**providerName** | **string** | Provider name | ### Other Parameters -Other parameters are passed through a pointer to a apiUninstallProviderRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiUpdateProviderRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **downloadUrls** | **map[string]string** | Provider download URLs | + ### Return type (empty response body) diff --git a/pkg/apiclient/docs/ProviderInfo.md b/pkg/apiclient/docs/ProviderInfo.md new file mode 100644 index 0000000000..66f4004039 --- /dev/null +++ b/pkg/apiclient/docs/ProviderInfo.md @@ -0,0 +1,187 @@ +# ProviderInfo + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AgentlessTarget** | Pointer to **bool** | | [optional] +**Label** | Pointer to **string** | | [optional] +**Name** | **string** | | +**RunnerId** | **string** | | +**RunnerName** | **string** | | +**TargetConfigManifest** | [**map[string]TargetConfigProperty**](TargetConfigProperty.md) | | +**Version** | **string** | | + +## Methods + +### NewProviderInfo + +`func NewProviderInfo(name string, runnerId string, runnerName string, targetConfigManifest map[string]TargetConfigProperty, version string, ) *ProviderInfo` + +NewProviderInfo instantiates a new ProviderInfo object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewProviderInfoWithDefaults + +`func NewProviderInfoWithDefaults() *ProviderInfo` + +NewProviderInfoWithDefaults instantiates a new ProviderInfo object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetAgentlessTarget + +`func (o *ProviderInfo) GetAgentlessTarget() bool` + +GetAgentlessTarget returns the AgentlessTarget field if non-nil, zero value otherwise. + +### GetAgentlessTargetOk + +`func (o *ProviderInfo) GetAgentlessTargetOk() (*bool, bool)` + +GetAgentlessTargetOk returns a tuple with the AgentlessTarget field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetAgentlessTarget + +`func (o *ProviderInfo) SetAgentlessTarget(v bool)` + +SetAgentlessTarget sets AgentlessTarget field to given value. + +### HasAgentlessTarget + +`func (o *ProviderInfo) HasAgentlessTarget() bool` + +HasAgentlessTarget returns a boolean if a field has been set. + +### GetLabel + +`func (o *ProviderInfo) GetLabel() string` + +GetLabel returns the Label field if non-nil, zero value otherwise. + +### GetLabelOk + +`func (o *ProviderInfo) GetLabelOk() (*string, bool)` + +GetLabelOk returns a tuple with the Label field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabel + +`func (o *ProviderInfo) SetLabel(v string)` + +SetLabel sets Label field to given value. + +### HasLabel + +`func (o *ProviderInfo) HasLabel() bool` + +HasLabel returns a boolean if a field has been set. + +### GetName + +`func (o *ProviderInfo) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *ProviderInfo) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *ProviderInfo) SetName(v string)` + +SetName sets Name field to given value. + + +### GetRunnerId + +`func (o *ProviderInfo) GetRunnerId() string` + +GetRunnerId returns the RunnerId field if non-nil, zero value otherwise. + +### GetRunnerIdOk + +`func (o *ProviderInfo) GetRunnerIdOk() (*string, bool)` + +GetRunnerIdOk returns a tuple with the RunnerId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRunnerId + +`func (o *ProviderInfo) SetRunnerId(v string)` + +SetRunnerId sets RunnerId field to given value. + + +### GetRunnerName + +`func (o *ProviderInfo) GetRunnerName() string` + +GetRunnerName returns the RunnerName field if non-nil, zero value otherwise. + +### GetRunnerNameOk + +`func (o *ProviderInfo) GetRunnerNameOk() (*string, bool)` + +GetRunnerNameOk returns a tuple with the RunnerName field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRunnerName + +`func (o *ProviderInfo) SetRunnerName(v string)` + +SetRunnerName sets RunnerName field to given value. + + +### GetTargetConfigManifest + +`func (o *ProviderInfo) GetTargetConfigManifest() map[string]TargetConfigProperty` + +GetTargetConfigManifest returns the TargetConfigManifest field if non-nil, zero value otherwise. + +### GetTargetConfigManifestOk + +`func (o *ProviderInfo) GetTargetConfigManifestOk() (*map[string]TargetConfigProperty, bool)` + +GetTargetConfigManifestOk returns a tuple with the TargetConfigManifest field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetTargetConfigManifest + +`func (o *ProviderInfo) SetTargetConfigManifest(v map[string]TargetConfigProperty)` + +SetTargetConfigManifest sets TargetConfigManifest field to given value. + + +### GetVersion + +`func (o *ProviderInfo) GetVersion() string` + +GetVersion returns the Version field if non-nil, zero value otherwise. + +### GetVersionOk + +`func (o *ProviderInfo) GetVersionOk() (*string, bool)` + +GetVersionOk returns a tuple with the Version field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetVersion + +`func (o *ProviderInfo) SetVersion(v string)` + +SetVersion sets Version field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/RegisterRunnerDTO.md b/pkg/apiclient/docs/RegisterRunnerDTO.md new file mode 100644 index 0000000000..2537de4e93 --- /dev/null +++ b/pkg/apiclient/docs/RegisterRunnerDTO.md @@ -0,0 +1,72 @@ +# RegisterRunnerDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | +**Name** | **string** | | + +## Methods + +### NewRegisterRunnerDTO + +`func NewRegisterRunnerDTO(id string, name string, ) *RegisterRunnerDTO` + +NewRegisterRunnerDTO instantiates a new RegisterRunnerDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewRegisterRunnerDTOWithDefaults + +`func NewRegisterRunnerDTOWithDefaults() *RegisterRunnerDTO` + +NewRegisterRunnerDTOWithDefaults instantiates a new RegisterRunnerDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetId + +`func (o *RegisterRunnerDTO) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *RegisterRunnerDTO) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *RegisterRunnerDTO) SetId(v string)` + +SetId sets Id field to given value. + + +### GetName + +`func (o *RegisterRunnerDTO) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *RegisterRunnerDTO) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *RegisterRunnerDTO) SetName(v string)` + +SetName sets Name field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/RegisterRunnerResultDTO.md b/pkg/apiclient/docs/RegisterRunnerResultDTO.md new file mode 100644 index 0000000000..45bc033c23 --- /dev/null +++ b/pkg/apiclient/docs/RegisterRunnerResultDTO.md @@ -0,0 +1,119 @@ +# RegisterRunnerResultDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ApiKey** | **string** | | +**Id** | **string** | | +**Metadata** | Pointer to [**RunnerMetadata**](RunnerMetadata.md) | | [optional] +**Name** | **string** | | + +## Methods + +### NewRegisterRunnerResultDTO + +`func NewRegisterRunnerResultDTO(apiKey string, id string, name string, ) *RegisterRunnerResultDTO` + +NewRegisterRunnerResultDTO instantiates a new RegisterRunnerResultDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewRegisterRunnerResultDTOWithDefaults + +`func NewRegisterRunnerResultDTOWithDefaults() *RegisterRunnerResultDTO` + +NewRegisterRunnerResultDTOWithDefaults instantiates a new RegisterRunnerResultDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetApiKey + +`func (o *RegisterRunnerResultDTO) GetApiKey() string` + +GetApiKey returns the ApiKey field if non-nil, zero value otherwise. + +### GetApiKeyOk + +`func (o *RegisterRunnerResultDTO) GetApiKeyOk() (*string, bool)` + +GetApiKeyOk returns a tuple with the ApiKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetApiKey + +`func (o *RegisterRunnerResultDTO) SetApiKey(v string)` + +SetApiKey sets ApiKey field to given value. + + +### GetId + +`func (o *RegisterRunnerResultDTO) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *RegisterRunnerResultDTO) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *RegisterRunnerResultDTO) SetId(v string)` + +SetId sets Id field to given value. + + +### GetMetadata + +`func (o *RegisterRunnerResultDTO) GetMetadata() RunnerMetadata` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *RegisterRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *RegisterRunnerResultDTO) SetMetadata(v RunnerMetadata)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *RegisterRunnerResultDTO) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + +### GetName + +`func (o *RegisterRunnerResultDTO) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *RegisterRunnerResultDTO) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *RegisterRunnerResultDTO) SetName(v string)` + +SetName sets Name field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ResourceType.md b/pkg/apiclient/docs/ResourceType.md index cebd8a5e58..de1ee5cfba 100644 --- a/pkg/apiclient/docs/ResourceType.md +++ b/pkg/apiclient/docs/ResourceType.md @@ -9,6 +9,8 @@ * `ResourceTypeBuild` (value: `"build"`) +* `ResourceTypeRunner` (value: `"runner"`) + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/RunnerAPI.md b/pkg/apiclient/docs/RunnerAPI.md new file mode 100644 index 0000000000..83ae39a597 --- /dev/null +++ b/pkg/apiclient/docs/RunnerAPI.md @@ -0,0 +1,493 @@ +# \RunnerAPI + +All URIs are relative to *http://localhost:3986* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**GetRunner**](RunnerAPI.md#GetRunner) | **Get** /runner/{runnerId} | Get a runner +[**ListRunnerJobs**](RunnerAPI.md#ListRunnerJobs) | **Get** /runner/{runnerId}/jobs | List runner jobs +[**ListRunners**](RunnerAPI.md#ListRunners) | **Get** /runner | List runners +[**RegisterRunner**](RunnerAPI.md#RegisterRunner) | **Post** /runner | Register a runner +[**RemoveRunner**](RunnerAPI.md#RemoveRunner) | **Delete** /runner/{runnerId} | Remove runner +[**SetRunnerMetadata**](RunnerAPI.md#SetRunnerMetadata) | **Post** /runner/{runnerId}/metadata | Set runner metadata +[**UpdateJobState**](RunnerAPI.md#UpdateJobState) | **Post** /runner/{runnerId}/jobs/{jobId}/state | Update job state + + + +## GetRunner + +> RunnerDTO GetRunner(ctx, runnerId).Execute() + +Get a runner + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + runnerId := "runnerId_example" // string | Runner ID + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.RunnerAPI.GetRunner(context.Background(), runnerId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.GetRunner``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetRunner`: RunnerDTO + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.GetRunner`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetRunnerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**RunnerDTO**](RunnerDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListRunnerJobs + +> []Job ListRunnerJobs(ctx, runnerId).Execute() + +List runner jobs + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + runnerId := "runnerId_example" // string | Runner ID + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.RunnerAPI.ListRunnerJobs(context.Background(), runnerId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.ListRunnerJobs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListRunnerJobs`: []Job + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.ListRunnerJobs`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiListRunnerJobsRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + +[**[]Job**](Job.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## ListRunners + +> []RunnerDTO ListRunners(ctx).Execute() + +List runners + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.RunnerAPI.ListRunners(context.Background()).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.ListRunners``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `ListRunners`: []RunnerDTO + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.ListRunners`: %v\n", resp) +} +``` + +### Path Parameters + +This endpoint does not need any parameter. + +### Other Parameters + +Other parameters are passed through a pointer to a apiListRunnersRequest struct via the builder pattern + + +### Return type + +[**[]RunnerDTO**](RunnerDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## RegisterRunner + +> RegisterRunnerResultDTO RegisterRunner(ctx).Runner(runner).Execute() + +Register a runner + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + runner := *openapiclient.NewRegisterRunnerDTO("Id_example", "Name_example") // RegisterRunnerDTO | Register runner + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.RunnerAPI.RegisterRunner(context.Background()).Runner(runner).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.RegisterRunner``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `RegisterRunner`: RegisterRunnerResultDTO + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.RegisterRunner`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiRegisterRunnerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **runner** | [**RegisterRunnerDTO**](RegisterRunnerDTO.md) | Register runner | + +### Return type + +[**RegisterRunnerResultDTO**](RegisterRunnerResultDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## RemoveRunner + +> RemoveRunner(ctx, runnerId).Execute() + +Remove runner + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + runnerId := "runnerId_example" // string | Runner ID + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.RunnerAPI.RemoveRunner(context.Background(), runnerId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.RemoveRunner``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiRemoveRunnerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## SetRunnerMetadata + +> SetRunnerMetadata(ctx, runnerId).RunnerMetadata(runnerMetadata).Execute() + +Set runner metadata + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + runnerId := "runnerId_example" // string | Runner ID + runnerMetadata := *openapiclient.NewUpdateRunnerMetadataDTO([]openapiclient.ProviderInfo{*openapiclient.NewProviderInfo("Name_example", "RunnerId_example", "RunnerName_example", map[string]TargetConfigProperty{"key": *openapiclient.NewTargetConfigProperty()}, "Version_example")}, int32(123)) // UpdateRunnerMetadataDTO | Runner Metadata + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.RunnerAPI.SetRunnerMetadata(context.Background(), runnerId).RunnerMetadata(runnerMetadata).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.SetRunnerMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiSetRunnerMetadataRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **runnerMetadata** | [**UpdateRunnerMetadataDTO**](UpdateRunnerMetadataDTO.md) | Runner Metadata | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + +## UpdateJobState + +> UpdateJobState(ctx, runnerId, jobId).UpdateJobState(updateJobState).Execute() + +Update job state + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + runnerId := "runnerId_example" // string | Runner ID + jobId := "jobId_example" // string | Job ID + updateJobState := *openapiclient.NewUpdateJobState(openapiclient.JobState("pending")) // UpdateJobState | Update job state + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.RunnerAPI.UpdateJobState(context.Background(), runnerId, jobId).UpdateJobState(updateJobState).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.UpdateJobState``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | +**jobId** | **string** | Job ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateJobStateRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + + **updateJobState** | [**UpdateJobState**](UpdateJobState.md) | Update job state | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/RunnerDTO.md b/pkg/apiclient/docs/RunnerDTO.md new file mode 100644 index 0000000000..75f7d5ac21 --- /dev/null +++ b/pkg/apiclient/docs/RunnerDTO.md @@ -0,0 +1,119 @@ +# RunnerDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Id** | **string** | | +**Metadata** | Pointer to [**RunnerMetadata**](RunnerMetadata.md) | | [optional] +**Name** | **string** | | +**State** | [**ResourceState**](ResourceState.md) | | + +## Methods + +### NewRunnerDTO + +`func NewRunnerDTO(id string, name string, state ResourceState, ) *RunnerDTO` + +NewRunnerDTO instantiates a new RunnerDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewRunnerDTOWithDefaults + +`func NewRunnerDTOWithDefaults() *RunnerDTO` + +NewRunnerDTOWithDefaults instantiates a new RunnerDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetId + +`func (o *RunnerDTO) GetId() string` + +GetId returns the Id field if non-nil, zero value otherwise. + +### GetIdOk + +`func (o *RunnerDTO) GetIdOk() (*string, bool)` + +GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetId + +`func (o *RunnerDTO) SetId(v string)` + +SetId sets Id field to given value. + + +### GetMetadata + +`func (o *RunnerDTO) GetMetadata() RunnerMetadata` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *RunnerDTO) GetMetadataOk() (*RunnerMetadata, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *RunnerDTO) SetMetadata(v RunnerMetadata)` + +SetMetadata sets Metadata field to given value. + +### HasMetadata + +`func (o *RunnerDTO) HasMetadata() bool` + +HasMetadata returns a boolean if a field has been set. + +### GetName + +`func (o *RunnerDTO) GetName() string` + +GetName returns the Name field if non-nil, zero value otherwise. + +### GetNameOk + +`func (o *RunnerDTO) GetNameOk() (*string, bool)` + +GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetName + +`func (o *RunnerDTO) SetName(v string)` + +SetName sets Name field to given value. + + +### GetState + +`func (o *RunnerDTO) GetState() ResourceState` + +GetState returns the State field if non-nil, zero value otherwise. + +### GetStateOk + +`func (o *RunnerDTO) GetStateOk() (*ResourceState, bool)` + +GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetState + +`func (o *RunnerDTO) SetState(v ResourceState)` + +SetState sets State field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/RunnerMetadata.md b/pkg/apiclient/docs/RunnerMetadata.md new file mode 100644 index 0000000000..645d6f01df --- /dev/null +++ b/pkg/apiclient/docs/RunnerMetadata.md @@ -0,0 +1,140 @@ +# RunnerMetadata + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Providers** | [**[]ProviderInfo**](ProviderInfo.md) | | +**RunnerId** | **string** | | +**RunningJobs** | Pointer to **int32** | | [optional] +**UpdatedAt** | **string** | | +**Uptime** | **int32** | | + +## Methods + +### NewRunnerMetadata + +`func NewRunnerMetadata(providers []ProviderInfo, runnerId string, updatedAt string, uptime int32, ) *RunnerMetadata` + +NewRunnerMetadata instantiates a new RunnerMetadata object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewRunnerMetadataWithDefaults + +`func NewRunnerMetadataWithDefaults() *RunnerMetadata` + +NewRunnerMetadataWithDefaults instantiates a new RunnerMetadata object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetProviders + +`func (o *RunnerMetadata) GetProviders() []ProviderInfo` + +GetProviders returns the Providers field if non-nil, zero value otherwise. + +### GetProvidersOk + +`func (o *RunnerMetadata) GetProvidersOk() (*[]ProviderInfo, bool)` + +GetProvidersOk returns a tuple with the Providers field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviders + +`func (o *RunnerMetadata) SetProviders(v []ProviderInfo)` + +SetProviders sets Providers field to given value. + + +### GetRunnerId + +`func (o *RunnerMetadata) GetRunnerId() string` + +GetRunnerId returns the RunnerId field if non-nil, zero value otherwise. + +### GetRunnerIdOk + +`func (o *RunnerMetadata) GetRunnerIdOk() (*string, bool)` + +GetRunnerIdOk returns a tuple with the RunnerId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRunnerId + +`func (o *RunnerMetadata) SetRunnerId(v string)` + +SetRunnerId sets RunnerId field to given value. + + +### GetRunningJobs + +`func (o *RunnerMetadata) GetRunningJobs() int32` + +GetRunningJobs returns the RunningJobs field if non-nil, zero value otherwise. + +### GetRunningJobsOk + +`func (o *RunnerMetadata) GetRunningJobsOk() (*int32, bool)` + +GetRunningJobsOk returns a tuple with the RunningJobs field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRunningJobs + +`func (o *RunnerMetadata) SetRunningJobs(v int32)` + +SetRunningJobs sets RunningJobs field to given value. + +### HasRunningJobs + +`func (o *RunnerMetadata) HasRunningJobs() bool` + +HasRunningJobs returns a boolean if a field has been set. + +### GetUpdatedAt + +`func (o *RunnerMetadata) GetUpdatedAt() string` + +GetUpdatedAt returns the UpdatedAt field if non-nil, zero value otherwise. + +### GetUpdatedAtOk + +`func (o *RunnerMetadata) GetUpdatedAtOk() (*string, bool)` + +GetUpdatedAtOk returns a tuple with the UpdatedAt field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUpdatedAt + +`func (o *RunnerMetadata) SetUpdatedAt(v string)` + +SetUpdatedAt sets UpdatedAt field to given value. + + +### GetUptime + +`func (o *RunnerMetadata) GetUptime() int32` + +GetUptime returns the Uptime field if non-nil, zero value otherwise. + +### GetUptimeOk + +`func (o *RunnerMetadata) GetUptimeOk() (*int32, bool)` + +GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUptime + +`func (o *RunnerMetadata) SetUptime(v int32)` + +SetUptime sets Uptime field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/ServerAPI.md b/pkg/apiclient/docs/ServerAPI.md index 8cf9dfa538..5d57f00026 100644 --- a/pkg/apiclient/docs/ServerAPI.md +++ b/pkg/apiclient/docs/ServerAPI.md @@ -215,7 +215,7 @@ import ( ) func main() { - config := *openapiclient.NewServerConfig(int32(123), "BinariesPath_example", "BuilderImage_example", "BuilderRegistryServer_example", "DefaultWorkspaceImage_example", "DefaultWorkspaceUser_example", int32(123), "Id_example", "LocalBuilderRegistryImage_example", int32(123), *openapiclient.NewLogFileConfig(int32(123), int32(123), int32(123), "Path_example"), "ProvidersDir_example", "RegistryUrl_example", "ServerDownloadUrl_example") // ServerConfig | Server configuration + config := *openapiclient.NewServerConfig(int32(123), "BinariesPath_example", "BuilderImage_example", "BuilderRegistryServer_example", "DefaultWorkspaceImage_example", "DefaultWorkspaceUser_example", int32(123), "Id_example", "LocalBuilderRegistryImage_example", int32(123), *openapiclient.NewLogFileConfig(int32(123), int32(123), int32(123), "Path_example"), "RegistryUrl_example", "ServerDownloadUrl_example") // ServerConfig | Server configuration configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/docs/ServerConfig.md b/pkg/apiclient/docs/ServerConfig.md index e4bf2fea6b..2bb5baaa29 100644 --- a/pkg/apiclient/docs/ServerConfig.md +++ b/pkg/apiclient/docs/ServerConfig.md @@ -16,8 +16,8 @@ Name | Type | Description | Notes **Id** | **string** | | **LocalBuilderRegistryImage** | **string** | | **LocalBuilderRegistryPort** | **int32** | | +**LocalRunnerDisabled** | Pointer to **bool** | | [optional] **LogFile** | [**LogFileConfig**](LogFileConfig.md) | | -**ProvidersDir** | **string** | | **RegistryUrl** | **string** | | **SamplesIndexUrl** | Pointer to **string** | | [optional] **ServerDownloadUrl** | **string** | | @@ -26,7 +26,7 @@ Name | Type | Description | Notes ### NewServerConfig -`func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultWorkspaceImage string, defaultWorkspaceUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, providersDir string, registryUrl string, serverDownloadUrl string, ) *ServerConfig` +`func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultWorkspaceImage string, defaultWorkspaceUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, registryUrl string, serverDownloadUrl string, ) *ServerConfig` NewServerConfig instantiates a new ServerConfig object This constructor will assign default values to properties that have it defined, @@ -291,44 +291,49 @@ and a boolean to check if the value has been set. SetLocalBuilderRegistryPort sets LocalBuilderRegistryPort field to given value. -### GetLogFile +### GetLocalRunnerDisabled -`func (o *ServerConfig) GetLogFile() LogFileConfig` +`func (o *ServerConfig) GetLocalRunnerDisabled() bool` -GetLogFile returns the LogFile field if non-nil, zero value otherwise. +GetLocalRunnerDisabled returns the LocalRunnerDisabled field if non-nil, zero value otherwise. -### GetLogFileOk +### GetLocalRunnerDisabledOk -`func (o *ServerConfig) GetLogFileOk() (*LogFileConfig, bool)` +`func (o *ServerConfig) GetLocalRunnerDisabledOk() (*bool, bool)` -GetLogFileOk returns a tuple with the LogFile field if it's non-nil, zero value otherwise +GetLocalRunnerDisabledOk returns a tuple with the LocalRunnerDisabled field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetLogFile +### SetLocalRunnerDisabled -`func (o *ServerConfig) SetLogFile(v LogFileConfig)` +`func (o *ServerConfig) SetLocalRunnerDisabled(v bool)` -SetLogFile sets LogFile field to given value. +SetLocalRunnerDisabled sets LocalRunnerDisabled field to given value. + +### HasLocalRunnerDisabled +`func (o *ServerConfig) HasLocalRunnerDisabled() bool` -### GetProvidersDir +HasLocalRunnerDisabled returns a boolean if a field has been set. -`func (o *ServerConfig) GetProvidersDir() string` +### GetLogFile -GetProvidersDir returns the ProvidersDir field if non-nil, zero value otherwise. +`func (o *ServerConfig) GetLogFile() LogFileConfig` -### GetProvidersDirOk +GetLogFile returns the LogFile field if non-nil, zero value otherwise. + +### GetLogFileOk -`func (o *ServerConfig) GetProvidersDirOk() (*string, bool)` +`func (o *ServerConfig) GetLogFileOk() (*LogFileConfig, bool)` -GetProvidersDirOk returns a tuple with the ProvidersDir field if it's non-nil, zero value otherwise +GetLogFileOk returns a tuple with the LogFile field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetProvidersDir +### SetLogFile -`func (o *ServerConfig) SetProvidersDir(v string)` +`func (o *ServerConfig) SetLogFile(v LogFileConfig)` -SetProvidersDir sets ProvidersDir field to given value. +SetLogFile sets LogFile field to given value. ### GetRegistryUrl diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index bd0e3681ff..ccbfeecdb0 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | +**ProviderMetadata** | Pointer to **string** | | [optional] **TargetConfig** | [**TargetConfig**](TargetConfig.md) | | **TargetConfigId** | **string** | | **Workspaces** | [**[]Workspace**](Workspace.md) | | @@ -163,6 +164,31 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. +### GetProviderMetadata + +`func (o *Target) GetProviderMetadata() string` + +GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. + +### GetProviderMetadataOk + +`func (o *Target) GetProviderMetadataOk() (*string, bool)` + +GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviderMetadata + +`func (o *Target) SetProviderMetadata(v string)` + +SetProviderMetadata sets ProviderMetadata field to given value. + +### HasProviderMetadata + +`func (o *Target) HasProviderMetadata() bool` + +HasProviderMetadata returns a boolean if a field has been set. + ### GetTargetConfig `func (o *Target) GetTargetConfig() TargetConfig` diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index 94285097a4..2d4f24451d 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -6,12 +6,14 @@ Method | HTTP request | Description ------------- | ------------- | ------------- [**CreateTarget**](TargetAPI.md#CreateTarget) | **Post** /target | Create a target [**GetTarget**](TargetAPI.md#GetTarget) | **Get** /target/{targetId} | Get target info +[**HandleSuccessfulCreation**](TargetAPI.md#HandleSuccessfulCreation) | **Post** /target/{targetId}/handle-successful-creation | Handles successful creation of the target [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets [**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target [**SetDefaultTarget**](TargetAPI.md#SetDefaultTarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default [**SetTargetMetadata**](TargetAPI.md#SetTargetMetadata) | **Post** /target/{targetId}/metadata | Set target metadata [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target +[**UpdateTargetProviderMetadata**](TargetAPI.md#UpdateTargetProviderMetadata) | **Post** /target/{targetId}/provider-metadata | Update target provider metadata @@ -83,7 +85,7 @@ Name | Type | Description | Notes ## GetTarget -> TargetDTO GetTarget(ctx, targetId).Verbose(verbose).Execute() +> TargetDTO GetTarget(ctx, targetId).ShowOptions(showOptions).Execute() Get target info @@ -103,11 +105,11 @@ import ( func main() { targetId := "targetId_example" // string | Target ID or Name - verbose := true // bool | Verbose (optional) + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetAPI.GetTarget(context.Background(), targetId).Verbose(verbose).Execute() + resp, r, err := apiClient.TargetAPI.GetTarget(context.Background(), targetId).ShowOptions(showOptions).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.GetTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -133,7 +135,7 @@ Other parameters are passed through a pointer to a apiGetTargetRequest struct vi Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **verbose** | **bool** | Verbose | + **showOptions** | **bool** | Show target config options | ### Return type @@ -153,9 +155,77 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## HandleSuccessfulCreation + +> HandleSuccessfulCreation(ctx, targetId).Execute() + +Handles successful creation of the target + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + targetId := "targetId_example" // string | Target ID or name + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.TargetAPI.HandleSuccessfulCreation(context.Background(), targetId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.HandleSuccessfulCreation``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**targetId** | **string** | Target ID or name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiHandleSuccessfulCreationRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## ListTargets -> []TargetDTO ListTargets(ctx).Verbose(verbose).Execute() +> []TargetDTO ListTargets(ctx).ShowOptions(showOptions).Execute() List targets @@ -174,11 +244,11 @@ import ( ) func main() { - verbose := true // bool | Verbose (optional) + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetAPI.ListTargets(context.Background()).Verbose(verbose).Execute() + resp, r, err := apiClient.TargetAPI.ListTargets(context.Background()).ShowOptions(showOptions).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.ListTargets``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -199,7 +269,7 @@ Other parameters are passed through a pointer to a apiListTargetsRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **verbose** | **bool** | Verbose | + **showOptions** | **bool** | Show target config options | ### Return type @@ -359,7 +429,7 @@ Name | Type | Description | Notes ## SetTargetMetadata -> SetTargetMetadata(ctx, targetId).SetMetadata(setMetadata).Execute() +> SetTargetMetadata(ctx, targetId).TargetMetadata(targetMetadata).Execute() Set target metadata @@ -379,11 +449,11 @@ import ( func main() { targetId := "targetId_example" // string | Target ID - setMetadata := *openapiclient.NewSetTargetMetadata(int32(123)) // SetTargetMetadata | Set Metadata + targetMetadata := *openapiclient.NewUpdateTargetMetadataDTO(int32(123)) // UpdateTargetMetadataDTO | Target Metadata configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), targetId).SetMetadata(setMetadata).Execute() + r, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), targetId).TargetMetadata(targetMetadata).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetTargetMetadata``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -407,7 +477,7 @@ Other parameters are passed through a pointer to a apiSetTargetMetadataRequest s Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **setMetadata** | [**SetTargetMetadata**](SetTargetMetadata.md) | Set Metadata | + **targetMetadata** | [**UpdateTargetMetadataDTO**](UpdateTargetMetadataDTO.md) | Target Metadata | ### Return type @@ -562,3 +632,73 @@ Name | Type | Description | Notes [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +## UpdateTargetProviderMetadata + +> UpdateTargetProviderMetadata(ctx, targetId).Metadata(metadata).Execute() + +Update target provider metadata + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + targetId := "targetId_example" // string | Target ID + metadata := *openapiclient.NewUpdateTargetProviderMetadataDTO("Metadata_example") // UpdateTargetProviderMetadataDTO | Provider metadata + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.TargetAPI.UpdateTargetProviderMetadata(context.Background(), targetId).Metadata(metadata).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.UpdateTargetProviderMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**targetId** | **string** | Target ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateTargetProviderMetadataRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **metadata** | [**UpdateTargetProviderMetadataDTO**](UpdateTargetProviderMetadataDTO.md) | Provider metadata | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/TargetConfig.md b/pkg/apiclient/docs/TargetConfig.md index 78c61cbbe2..665ffb3061 100644 --- a/pkg/apiclient/docs/TargetConfig.md +++ b/pkg/apiclient/docs/TargetConfig.md @@ -8,13 +8,13 @@ Name | Type | Description | Notes **Id** | **string** | | **Name** | **string** | | **Options** | **string** | JSON encoded map of options | -**ProviderInfo** | [**TargetProviderInfo**](TargetProviderInfo.md) | | +**ProviderInfo** | [**ProviderInfo**](ProviderInfo.md) | | ## Methods ### NewTargetConfig -`func NewTargetConfig(deleted bool, id string, name string, options string, providerInfo TargetProviderInfo, ) *TargetConfig` +`func NewTargetConfig(deleted bool, id string, name string, options string, providerInfo ProviderInfo, ) *TargetConfig` NewTargetConfig instantiates a new TargetConfig object This constructor will assign default values to properties that have it defined, @@ -111,20 +111,20 @@ SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *TargetConfig) GetProviderInfo() TargetProviderInfo` +`func (o *TargetConfig) GetProviderInfo() ProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *TargetConfig) GetProviderInfoOk() (*TargetProviderInfo, bool)` +`func (o *TargetConfig) GetProviderInfoOk() (*ProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *TargetConfig) SetProviderInfo(v TargetProviderInfo)` +`func (o *TargetConfig) SetProviderInfo(v ProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/TargetConfigAPI.md b/pkg/apiclient/docs/TargetConfigAPI.md index 6696f26fd8..c565235755 100644 --- a/pkg/apiclient/docs/TargetConfigAPI.md +++ b/pkg/apiclient/docs/TargetConfigAPI.md @@ -12,7 +12,7 @@ Method | HTTP request | Description ## AddTargetConfig -> TargetConfig AddTargetConfig(ctx).TargetConfig(targetConfig).Execute() +> TargetConfig AddTargetConfig(ctx).TargetConfig(targetConfig).ShowOptions(showOptions).Execute() Add a target config @@ -31,11 +31,12 @@ import ( ) func main() { - targetConfig := *openapiclient.NewAddTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewTargetProviderInfo("Name_example", "Version_example")) // AddTargetConfigDTO | Target config to add + targetConfig := *openapiclient.NewAddTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewProviderInfo("Name_example", "RunnerId_example", "RunnerName_example", map[string]TargetConfigProperty{"key": *openapiclient.NewTargetConfigProperty()}, "Version_example")) // AddTargetConfigDTO | Target config to add + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetConfigAPI.AddTargetConfig(context.Background()).TargetConfig(targetConfig).Execute() + resp, r, err := apiClient.TargetConfigAPI.AddTargetConfig(context.Background()).TargetConfig(targetConfig).ShowOptions(showOptions).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.AddTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -57,6 +58,7 @@ Other parameters are passed through a pointer to a apiAddTargetConfigRequest str Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **targetConfig** | [**AddTargetConfigDTO**](AddTargetConfigDTO.md) | Target config to add | + **showOptions** | **bool** | Show target config options | ### Return type @@ -78,7 +80,7 @@ Name | Type | Description | Notes ## ListTargetConfigs -> []TargetConfig ListTargetConfigs(ctx).Execute() +> []TargetConfig ListTargetConfigs(ctx).ShowOptions(showOptions).Execute() List target configs @@ -97,10 +99,11 @@ import ( ) func main() { + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).Execute() + resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).ShowOptions(showOptions).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.ListTargetConfigs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -112,13 +115,17 @@ func main() { ### Path Parameters -This endpoint does not need any parameter. + ### Other Parameters Other parameters are passed through a pointer to a apiListTargetConfigsRequest struct via the builder pattern +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **showOptions** | **bool** | Show target config options | + ### Return type [**[]TargetConfig**](TargetConfig.md) diff --git a/pkg/apiclient/docs/TargetConfigProperty.md b/pkg/apiclient/docs/TargetConfigProperty.md index b547b9e4da..7142de8a44 100644 --- a/pkg/apiclient/docs/TargetConfigProperty.md +++ b/pkg/apiclient/docs/TargetConfigProperty.md @@ -10,7 +10,7 @@ Name | Type | Description | Notes **InputMasked** | Pointer to **bool** | | [optional] **Options** | Pointer to **[]string** | Options is only used if the Type is TargetConfigPropertyTypeOption | [optional] **Suggestions** | Pointer to **[]string** | Suggestions is an optional list of auto-complete values to assist the user while filling the field | [optional] -**Type** | Pointer to [**ProviderTargetConfigPropertyType**](ProviderTargetConfigPropertyType.md) | | [optional] +**Type** | Pointer to [**ModelsTargetConfigPropertyType**](ModelsTargetConfigPropertyType.md) | | [optional] ## Methods @@ -183,20 +183,20 @@ HasSuggestions returns a boolean if a field has been set. ### GetType -`func (o *TargetConfigProperty) GetType() ProviderTargetConfigPropertyType` +`func (o *TargetConfigProperty) GetType() ModelsTargetConfigPropertyType` GetType returns the Type field if non-nil, zero value otherwise. ### GetTypeOk -`func (o *TargetConfigProperty) GetTypeOk() (*ProviderTargetConfigPropertyType, bool)` +`func (o *TargetConfigProperty) GetTypeOk() (*ModelsTargetConfigPropertyType, bool)` GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetType -`func (o *TargetConfigProperty) SetType(v ProviderTargetConfigPropertyType)` +`func (o *TargetConfigProperty) SetType(v ModelsTargetConfigPropertyType)` SetType sets Type field to given value. diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index 67a9a19eb5..bed80d7999 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -7,10 +7,10 @@ Name | Type | Description | Notes **Default** | **bool** | | **EnvVars** | **map[string]string** | | **Id** | **string** | | -**Info** | Pointer to [**TargetInfo**](TargetInfo.md) | | [optional] **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | +**ProviderMetadata** | Pointer to **string** | | [optional] **State** | [**ResourceState**](ResourceState.md) | | **TargetConfig** | [**TargetConfig**](TargetConfig.md) | | **TargetConfigId** | **string** | | @@ -95,31 +95,6 @@ and a boolean to check if the value has been set. SetId sets Id field to given value. -### GetInfo - -`func (o *TargetDTO) GetInfo() TargetInfo` - -GetInfo returns the Info field if non-nil, zero value otherwise. - -### GetInfoOk - -`func (o *TargetDTO) GetInfoOk() (*TargetInfo, bool)` - -GetInfoOk returns a tuple with the Info field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetInfo - -`func (o *TargetDTO) SetInfo(v TargetInfo)` - -SetInfo sets Info field to given value. - -### HasInfo - -`func (o *TargetDTO) HasInfo() bool` - -HasInfo returns a boolean if a field has been set. - ### GetLastJob `func (o *TargetDTO) GetLastJob() Job` @@ -190,6 +165,31 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. +### GetProviderMetadata + +`func (o *TargetDTO) GetProviderMetadata() string` + +GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. + +### GetProviderMetadataOk + +`func (o *TargetDTO) GetProviderMetadataOk() (*string, bool)` + +GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviderMetadata + +`func (o *TargetDTO) SetProviderMetadata(v string)` + +SetProviderMetadata sets ProviderMetadata field to given value. + +### HasProviderMetadata + +`func (o *TargetDTO) HasProviderMetadata() bool` + +HasProviderMetadata returns a boolean if a field has been set. + ### GetState `func (o *TargetDTO) GetState() ResourceState` diff --git a/pkg/apiclient/docs/TargetInfo.md b/pkg/apiclient/docs/TargetInfo.md deleted file mode 100644 index c82cdc9401..0000000000 --- a/pkg/apiclient/docs/TargetInfo.md +++ /dev/null @@ -1,77 +0,0 @@ -# TargetInfo - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**Name** | **string** | | -**ProviderMetadata** | Pointer to **string** | | [optional] - -## Methods - -### NewTargetInfo - -`func NewTargetInfo(name string, ) *TargetInfo` - -NewTargetInfo instantiates a new TargetInfo object -This constructor will assign default values to properties that have it defined, -and makes sure properties required by API are set, but the set of arguments -will change when the set of required properties is changed - -### NewTargetInfoWithDefaults - -`func NewTargetInfoWithDefaults() *TargetInfo` - -NewTargetInfoWithDefaults instantiates a new TargetInfo object -This constructor will only assign default values to properties that have it defined, -but it doesn't guarantee that properties required by API are set - -### GetName - -`func (o *TargetInfo) GetName() string` - -GetName returns the Name field if non-nil, zero value otherwise. - -### GetNameOk - -`func (o *TargetInfo) GetNameOk() (*string, bool)` - -GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetName - -`func (o *TargetInfo) SetName(v string)` - -SetName sets Name field to given value. - - -### GetProviderMetadata - -`func (o *TargetInfo) GetProviderMetadata() string` - -GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. - -### GetProviderMetadataOk - -`func (o *TargetInfo) GetProviderMetadataOk() (*string, bool)` - -GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetProviderMetadata - -`func (o *TargetInfo) SetProviderMetadata(v string)` - -SetProviderMetadata sets ProviderMetadata field to given value. - -### HasProviderMetadata - -`func (o *TargetInfo) HasProviderMetadata() bool` - -HasProviderMetadata returns a boolean if a field has been set. - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/docs/TargetProviderInfo.md b/pkg/apiclient/docs/TargetProviderInfo.md deleted file mode 100644 index 6e1f86f4ea..0000000000 --- a/pkg/apiclient/docs/TargetProviderInfo.md +++ /dev/null @@ -1,124 +0,0 @@ -# TargetProviderInfo - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**AgentlessTarget** | Pointer to **bool** | | [optional] -**Label** | Pointer to **string** | | [optional] -**Name** | **string** | | -**Version** | **string** | | - -## Methods - -### NewTargetProviderInfo - -`func NewTargetProviderInfo(name string, version string, ) *TargetProviderInfo` - -NewTargetProviderInfo instantiates a new TargetProviderInfo object -This constructor will assign default values to properties that have it defined, -and makes sure properties required by API are set, but the set of arguments -will change when the set of required properties is changed - -### NewTargetProviderInfoWithDefaults - -`func NewTargetProviderInfoWithDefaults() *TargetProviderInfo` - -NewTargetProviderInfoWithDefaults instantiates a new TargetProviderInfo object -This constructor will only assign default values to properties that have it defined, -but it doesn't guarantee that properties required by API are set - -### GetAgentlessTarget - -`func (o *TargetProviderInfo) GetAgentlessTarget() bool` - -GetAgentlessTarget returns the AgentlessTarget field if non-nil, zero value otherwise. - -### GetAgentlessTargetOk - -`func (o *TargetProviderInfo) GetAgentlessTargetOk() (*bool, bool)` - -GetAgentlessTargetOk returns a tuple with the AgentlessTarget field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetAgentlessTarget - -`func (o *TargetProviderInfo) SetAgentlessTarget(v bool)` - -SetAgentlessTarget sets AgentlessTarget field to given value. - -### HasAgentlessTarget - -`func (o *TargetProviderInfo) HasAgentlessTarget() bool` - -HasAgentlessTarget returns a boolean if a field has been set. - -### GetLabel - -`func (o *TargetProviderInfo) GetLabel() string` - -GetLabel returns the Label field if non-nil, zero value otherwise. - -### GetLabelOk - -`func (o *TargetProviderInfo) GetLabelOk() (*string, bool)` - -GetLabelOk returns a tuple with the Label field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetLabel - -`func (o *TargetProviderInfo) SetLabel(v string)` - -SetLabel sets Label field to given value. - -### HasLabel - -`func (o *TargetProviderInfo) HasLabel() bool` - -HasLabel returns a boolean if a field has been set. - -### GetName - -`func (o *TargetProviderInfo) GetName() string` - -GetName returns the Name field if non-nil, zero value otherwise. - -### GetNameOk - -`func (o *TargetProviderInfo) GetNameOk() (*string, bool)` - -GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetName - -`func (o *TargetProviderInfo) SetName(v string)` - -SetName sets Name field to given value. - - -### GetVersion - -`func (o *TargetProviderInfo) GetVersion() string` - -GetVersion returns the Version field if non-nil, zero value otherwise. - -### GetVersionOk - -`func (o *TargetProviderInfo) GetVersionOk() (*string, bool)` - -GetVersionOk returns a tuple with the Version field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetVersion - -`func (o *TargetProviderInfo) SetVersion(v string)` - -SetVersion sets Version field to given value. - - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/docs/UpdateJobState.md b/pkg/apiclient/docs/UpdateJobState.md new file mode 100644 index 0000000000..565f46888f --- /dev/null +++ b/pkg/apiclient/docs/UpdateJobState.md @@ -0,0 +1,77 @@ +# UpdateJobState + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ErrorMessage** | Pointer to **string** | | [optional] +**State** | [**JobState**](JobState.md) | | + +## Methods + +### NewUpdateJobState + +`func NewUpdateJobState(state JobState, ) *UpdateJobState` + +NewUpdateJobState instantiates a new UpdateJobState object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUpdateJobStateWithDefaults + +`func NewUpdateJobStateWithDefaults() *UpdateJobState` + +NewUpdateJobStateWithDefaults instantiates a new UpdateJobState object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetErrorMessage + +`func (o *UpdateJobState) GetErrorMessage() string` + +GetErrorMessage returns the ErrorMessage field if non-nil, zero value otherwise. + +### GetErrorMessageOk + +`func (o *UpdateJobState) GetErrorMessageOk() (*string, bool)` + +GetErrorMessageOk returns a tuple with the ErrorMessage field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetErrorMessage + +`func (o *UpdateJobState) SetErrorMessage(v string)` + +SetErrorMessage sets ErrorMessage field to given value. + +### HasErrorMessage + +`func (o *UpdateJobState) HasErrorMessage() bool` + +HasErrorMessage returns a boolean if a field has been set. + +### GetState + +`func (o *UpdateJobState) GetState() JobState` + +GetState returns the State field if non-nil, zero value otherwise. + +### GetStateOk + +`func (o *UpdateJobState) GetStateOk() (*JobState, bool)` + +GetStateOk returns a tuple with the State field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetState + +`func (o *UpdateJobState) SetState(v JobState)` + +SetState sets State field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/UpdateRunnerMetadataDTO.md b/pkg/apiclient/docs/UpdateRunnerMetadataDTO.md new file mode 100644 index 0000000000..c4ebd6c663 --- /dev/null +++ b/pkg/apiclient/docs/UpdateRunnerMetadataDTO.md @@ -0,0 +1,98 @@ +# UpdateRunnerMetadataDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Providers** | [**[]ProviderInfo**](ProviderInfo.md) | | +**RunningJobs** | Pointer to **int32** | | [optional] +**Uptime** | **int32** | | + +## Methods + +### NewUpdateRunnerMetadataDTO + +`func NewUpdateRunnerMetadataDTO(providers []ProviderInfo, uptime int32, ) *UpdateRunnerMetadataDTO` + +NewUpdateRunnerMetadataDTO instantiates a new UpdateRunnerMetadataDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUpdateRunnerMetadataDTOWithDefaults + +`func NewUpdateRunnerMetadataDTOWithDefaults() *UpdateRunnerMetadataDTO` + +NewUpdateRunnerMetadataDTOWithDefaults instantiates a new UpdateRunnerMetadataDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetProviders + +`func (o *UpdateRunnerMetadataDTO) GetProviders() []ProviderInfo` + +GetProviders returns the Providers field if non-nil, zero value otherwise. + +### GetProvidersOk + +`func (o *UpdateRunnerMetadataDTO) GetProvidersOk() (*[]ProviderInfo, bool)` + +GetProvidersOk returns a tuple with the Providers field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviders + +`func (o *UpdateRunnerMetadataDTO) SetProviders(v []ProviderInfo)` + +SetProviders sets Providers field to given value. + + +### GetRunningJobs + +`func (o *UpdateRunnerMetadataDTO) GetRunningJobs() int32` + +GetRunningJobs returns the RunningJobs field if non-nil, zero value otherwise. + +### GetRunningJobsOk + +`func (o *UpdateRunnerMetadataDTO) GetRunningJobsOk() (*int32, bool)` + +GetRunningJobsOk returns a tuple with the RunningJobs field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetRunningJobs + +`func (o *UpdateRunnerMetadataDTO) SetRunningJobs(v int32)` + +SetRunningJobs sets RunningJobs field to given value. + +### HasRunningJobs + +`func (o *UpdateRunnerMetadataDTO) HasRunningJobs() bool` + +HasRunningJobs returns a boolean if a field has been set. + +### GetUptime + +`func (o *UpdateRunnerMetadataDTO) GetUptime() int32` + +GetUptime returns the Uptime field if non-nil, zero value otherwise. + +### GetUptimeOk + +`func (o *UpdateRunnerMetadataDTO) GetUptimeOk() (*int32, bool)` + +GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetUptime + +`func (o *UpdateRunnerMetadataDTO) SetUptime(v int32)` + +SetUptime sets Uptime field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/SetTargetMetadata.md b/pkg/apiclient/docs/UpdateTargetMetadataDTO.md similarity index 62% rename from pkg/apiclient/docs/SetTargetMetadata.md rename to pkg/apiclient/docs/UpdateTargetMetadataDTO.md index 3e6080311f..d15a2c6812 100644 --- a/pkg/apiclient/docs/SetTargetMetadata.md +++ b/pkg/apiclient/docs/UpdateTargetMetadataDTO.md @@ -1,4 +1,4 @@ -# SetTargetMetadata +# UpdateTargetMetadataDTO ## Properties @@ -8,39 +8,39 @@ Name | Type | Description | Notes ## Methods -### NewSetTargetMetadata +### NewUpdateTargetMetadataDTO -`func NewSetTargetMetadata(uptime int32, ) *SetTargetMetadata` +`func NewUpdateTargetMetadataDTO(uptime int32, ) *UpdateTargetMetadataDTO` -NewSetTargetMetadata instantiates a new SetTargetMetadata object +NewUpdateTargetMetadataDTO instantiates a new UpdateTargetMetadataDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewSetTargetMetadataWithDefaults +### NewUpdateTargetMetadataDTOWithDefaults -`func NewSetTargetMetadataWithDefaults() *SetTargetMetadata` +`func NewUpdateTargetMetadataDTOWithDefaults() *UpdateTargetMetadataDTO` -NewSetTargetMetadataWithDefaults instantiates a new SetTargetMetadata object +NewUpdateTargetMetadataDTOWithDefaults instantiates a new UpdateTargetMetadataDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetUptime -`func (o *SetTargetMetadata) GetUptime() int32` +`func (o *UpdateTargetMetadataDTO) GetUptime() int32` GetUptime returns the Uptime field if non-nil, zero value otherwise. ### GetUptimeOk -`func (o *SetTargetMetadata) GetUptimeOk() (*int32, bool)` +`func (o *UpdateTargetMetadataDTO) GetUptimeOk() (*int32, bool)` GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUptime -`func (o *SetTargetMetadata) SetUptime(v int32)` +`func (o *UpdateTargetMetadataDTO) SetUptime(v int32)` SetUptime sets Uptime field to given value. diff --git a/pkg/apiclient/docs/UpdateTargetProviderMetadataDTO.md b/pkg/apiclient/docs/UpdateTargetProviderMetadataDTO.md new file mode 100644 index 0000000000..8f062e03cf --- /dev/null +++ b/pkg/apiclient/docs/UpdateTargetProviderMetadataDTO.md @@ -0,0 +1,51 @@ +# UpdateTargetProviderMetadataDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Metadata** | **string** | | + +## Methods + +### NewUpdateTargetProviderMetadataDTO + +`func NewUpdateTargetProviderMetadataDTO(metadata string, ) *UpdateTargetProviderMetadataDTO` + +NewUpdateTargetProviderMetadataDTO instantiates a new UpdateTargetProviderMetadataDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUpdateTargetProviderMetadataDTOWithDefaults + +`func NewUpdateTargetProviderMetadataDTOWithDefaults() *UpdateTargetProviderMetadataDTO` + +NewUpdateTargetProviderMetadataDTOWithDefaults instantiates a new UpdateTargetProviderMetadataDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetMetadata + +`func (o *UpdateTargetProviderMetadataDTO) GetMetadata() string` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *UpdateTargetProviderMetadataDTO) GetMetadataOk() (*string, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *UpdateTargetProviderMetadataDTO) SetMetadata(v string)` + +SetMetadata sets Metadata field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/SetWorkspaceMetadata.md b/pkg/apiclient/docs/UpdateWorkspaceMetadataDTO.md similarity index 62% rename from pkg/apiclient/docs/SetWorkspaceMetadata.md rename to pkg/apiclient/docs/UpdateWorkspaceMetadataDTO.md index b81ca44ddd..4da7eedeac 100644 --- a/pkg/apiclient/docs/SetWorkspaceMetadata.md +++ b/pkg/apiclient/docs/UpdateWorkspaceMetadataDTO.md @@ -1,4 +1,4 @@ -# SetWorkspaceMetadata +# UpdateWorkspaceMetadataDTO ## Properties @@ -9,64 +9,64 @@ Name | Type | Description | Notes ## Methods -### NewSetWorkspaceMetadata +### NewUpdateWorkspaceMetadataDTO -`func NewSetWorkspaceMetadata(uptime int32, ) *SetWorkspaceMetadata` +`func NewUpdateWorkspaceMetadataDTO(uptime int32, ) *UpdateWorkspaceMetadataDTO` -NewSetWorkspaceMetadata instantiates a new SetWorkspaceMetadata object +NewUpdateWorkspaceMetadataDTO instantiates a new UpdateWorkspaceMetadataDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewSetWorkspaceMetadataWithDefaults +### NewUpdateWorkspaceMetadataDTOWithDefaults -`func NewSetWorkspaceMetadataWithDefaults() *SetWorkspaceMetadata` +`func NewUpdateWorkspaceMetadataDTOWithDefaults() *UpdateWorkspaceMetadataDTO` -NewSetWorkspaceMetadataWithDefaults instantiates a new SetWorkspaceMetadata object +NewUpdateWorkspaceMetadataDTOWithDefaults instantiates a new UpdateWorkspaceMetadataDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetGitStatus -`func (o *SetWorkspaceMetadata) GetGitStatus() GitStatus` +`func (o *UpdateWorkspaceMetadataDTO) GetGitStatus() GitStatus` GetGitStatus returns the GitStatus field if non-nil, zero value otherwise. ### GetGitStatusOk -`func (o *SetWorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool)` +`func (o *UpdateWorkspaceMetadataDTO) GetGitStatusOk() (*GitStatus, bool)` GetGitStatusOk returns a tuple with the GitStatus field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetGitStatus -`func (o *SetWorkspaceMetadata) SetGitStatus(v GitStatus)` +`func (o *UpdateWorkspaceMetadataDTO) SetGitStatus(v GitStatus)` SetGitStatus sets GitStatus field to given value. ### HasGitStatus -`func (o *SetWorkspaceMetadata) HasGitStatus() bool` +`func (o *UpdateWorkspaceMetadataDTO) HasGitStatus() bool` HasGitStatus returns a boolean if a field has been set. ### GetUptime -`func (o *SetWorkspaceMetadata) GetUptime() int32` +`func (o *UpdateWorkspaceMetadataDTO) GetUptime() int32` GetUptime returns the Uptime field if non-nil, zero value otherwise. ### GetUptimeOk -`func (o *SetWorkspaceMetadata) GetUptimeOk() (*int32, bool)` +`func (o *UpdateWorkspaceMetadataDTO) GetUptimeOk() (*int32, bool)` GetUptimeOk returns a tuple with the Uptime field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetUptime -`func (o *SetWorkspaceMetadata) SetUptime(v int32)` +`func (o *UpdateWorkspaceMetadataDTO) SetUptime(v int32)` SetUptime sets Uptime field to given value. diff --git a/pkg/apiclient/docs/UpdateWorkspaceProviderMetadataDTO.md b/pkg/apiclient/docs/UpdateWorkspaceProviderMetadataDTO.md new file mode 100644 index 0000000000..0a521d7b9a --- /dev/null +++ b/pkg/apiclient/docs/UpdateWorkspaceProviderMetadataDTO.md @@ -0,0 +1,51 @@ +# UpdateWorkspaceProviderMetadataDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Metadata** | **string** | | + +## Methods + +### NewUpdateWorkspaceProviderMetadataDTO + +`func NewUpdateWorkspaceProviderMetadataDTO(metadata string, ) *UpdateWorkspaceProviderMetadataDTO` + +NewUpdateWorkspaceProviderMetadataDTO instantiates a new UpdateWorkspaceProviderMetadataDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUpdateWorkspaceProviderMetadataDTOWithDefaults + +`func NewUpdateWorkspaceProviderMetadataDTOWithDefaults() *UpdateWorkspaceProviderMetadataDTO` + +NewUpdateWorkspaceProviderMetadataDTOWithDefaults instantiates a new UpdateWorkspaceProviderMetadataDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetMetadata + +`func (o *UpdateWorkspaceProviderMetadataDTO) GetMetadata() string` + +GetMetadata returns the Metadata field if non-nil, zero value otherwise. + +### GetMetadataOk + +`func (o *UpdateWorkspaceProviderMetadataDTO) GetMetadataOk() (*string, bool)` + +GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetMetadata + +`func (o *UpdateWorkspaceProviderMetadataDTO) SetMetadata(v string)` + +SetMetadata sets Metadata field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/Workspace.md index acdee1e9b5..014445287d 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/Workspace.md @@ -4,6 +4,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**ApiKey** | **string** | | **BuildConfig** | Pointer to [**BuildConfig**](BuildConfig.md) | | [optional] **EnvVars** | **map[string]string** | | **GitProviderConfigId** | Pointer to **string** | | [optional] @@ -12,6 +13,7 @@ Name | Type | Description | Notes **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] **Name** | **string** | | +**ProviderMetadata** | Pointer to **string** | | [optional] **Repository** | [**GitRepository**](GitRepository.md) | | **Target** | [**Target**](Target.md) | | **TargetId** | **string** | | @@ -21,7 +23,7 @@ Name | Type | Description | Notes ### NewWorkspace -`func NewWorkspace(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string, ) *Workspace` +`func NewWorkspace(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string, ) *Workspace` NewWorkspace instantiates a new Workspace object This constructor will assign default values to properties that have it defined, @@ -36,6 +38,26 @@ NewWorkspaceWithDefaults instantiates a new Workspace object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set +### GetApiKey + +`func (o *Workspace) GetApiKey() string` + +GetApiKey returns the ApiKey field if non-nil, zero value otherwise. + +### GetApiKeyOk + +`func (o *Workspace) GetApiKeyOk() (*string, bool)` + +GetApiKeyOk returns a tuple with the ApiKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetApiKey + +`func (o *Workspace) SetApiKey(v string)` + +SetApiKey sets ApiKey field to given value. + + ### GetBuildConfig `func (o *Workspace) GetBuildConfig() BuildConfig` @@ -216,6 +238,31 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. +### GetProviderMetadata + +`func (o *Workspace) GetProviderMetadata() string` + +GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. + +### GetProviderMetadataOk + +`func (o *Workspace) GetProviderMetadataOk() (*string, bool)` + +GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviderMetadata + +`func (o *Workspace) SetProviderMetadata(v string)` + +SetProviderMetadata sets ProviderMetadata field to given value. + +### HasProviderMetadata + +`func (o *Workspace) HasProviderMetadata() bool` + +HasProviderMetadata returns a boolean if a field has been set. + ### GetRepository `func (o *Workspace) GetRepository() GitRepository` diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 8b6e6e494a..263855322b 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -11,6 +11,7 @@ Method | HTTP request | Description [**SetWorkspaceMetadata**](WorkspaceAPI.md#SetWorkspaceMetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata [**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace [**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +[**UpdateWorkspaceProviderMetadata**](WorkspaceAPI.md#UpdateWorkspaceProviderMetadata) | **Post** /workspace/{workspaceId}/provider-metadata | Update workspace provider metadata @@ -82,7 +83,7 @@ Name | Type | Description | Notes ## GetWorkspace -> WorkspaceDTO GetWorkspace(ctx, workspaceId).Verbose(verbose).Execute() +> WorkspaceDTO GetWorkspace(ctx, workspaceId).Execute() Get workspace info @@ -102,11 +103,10 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID or Name - verbose := true // bool | Verbose (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.GetWorkspace(context.Background(), workspaceId).Verbose(verbose).Execute() + resp, r, err := apiClient.WorkspaceAPI.GetWorkspace(context.Background(), workspaceId).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.GetWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -132,7 +132,6 @@ Other parameters are passed through a pointer to a apiGetWorkspaceRequest struct Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **verbose** | **bool** | Verbose | ### Return type @@ -154,7 +153,7 @@ Name | Type | Description | Notes ## ListWorkspaces -> []WorkspaceDTO ListWorkspaces(ctx).Verbose(verbose).Execute() +> []WorkspaceDTO ListWorkspaces(ctx).Execute() List workspaces @@ -173,11 +172,10 @@ import ( ) func main() { - verbose := true // bool | Verbose (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Verbose(verbose).Execute() + resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.ListWorkspaces``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -189,17 +187,13 @@ func main() { ### Path Parameters - +This endpoint does not need any parameter. ### Other Parameters Other parameters are passed through a pointer to a apiListWorkspacesRequest struct via the builder pattern -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - **verbose** | **bool** | Verbose | - ### Return type [**[]WorkspaceDTO**](WorkspaceDTO.md) @@ -290,7 +284,7 @@ Name | Type | Description | Notes ## SetWorkspaceMetadata -> SetWorkspaceMetadata(ctx, workspaceId).SetMetadata(setMetadata).Execute() +> SetWorkspaceMetadata(ctx, workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() Set workspace metadata @@ -310,11 +304,11 @@ import ( func main() { workspaceId := "workspaceId_example" // string | Workspace ID - setMetadata := *openapiclient.NewSetWorkspaceMetadata(int32(123)) // SetWorkspaceMetadata | Set Metadata + workspaceMetadata := *openapiclient.NewUpdateWorkspaceMetadataDTO(int32(123)) // UpdateWorkspaceMetadataDTO | Workspace Metadata configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), workspaceId).SetMetadata(setMetadata).Execute() + r, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.SetWorkspaceMetadata``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -338,7 +332,7 @@ Other parameters are passed through a pointer to a apiSetWorkspaceMetadataReques Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **setMetadata** | [**SetWorkspaceMetadata**](SetWorkspaceMetadata.md) | Set Metadata | + **workspaceMetadata** | [**UpdateWorkspaceMetadataDTO**](UpdateWorkspaceMetadataDTO.md) | Workspace Metadata | ### Return type @@ -493,3 +487,73 @@ Name | Type | Description | Notes [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +## UpdateWorkspaceProviderMetadata + +> UpdateWorkspaceProviderMetadata(ctx, workspaceId).Metadata(metadata).Execute() + +Update workspace provider metadata + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID + metadata := *openapiclient.NewUpdateWorkspaceProviderMetadataDTO("Metadata_example") // UpdateWorkspaceProviderMetadataDTO | Provider metadata + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.WorkspaceAPI.UpdateWorkspaceProviderMetadata(context.Background(), workspaceId).Metadata(metadata).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.UpdateWorkspaceProviderMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateWorkspaceProviderMetadataRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **metadata** | [**UpdateWorkspaceProviderMetadataDTO**](UpdateWorkspaceProviderMetadataDTO.md) | Provider metadata | + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md index 0ac7e19c8d..6ee85c1900 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -4,15 +4,16 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- +**ApiKey** | **string** | | **BuildConfig** | Pointer to [**BuildConfig**](BuildConfig.md) | | [optional] **EnvVars** | **map[string]string** | | **GitProviderConfigId** | Pointer to **string** | | [optional] **Id** | **string** | | **Image** | **string** | | -**Info** | Pointer to [**WorkspaceInfo**](WorkspaceInfo.md) | | [optional] **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] **Name** | **string** | | +**ProviderMetadata** | Pointer to **string** | | [optional] **Repository** | [**GitRepository**](GitRepository.md) | | **State** | [**ResourceState**](ResourceState.md) | | **Target** | [**Target**](Target.md) | | @@ -23,7 +24,7 @@ Name | Type | Description | Notes ### NewWorkspaceDTO -`func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string, ) *WorkspaceDTO` +`func NewWorkspaceDTO(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string, ) *WorkspaceDTO` NewWorkspaceDTO instantiates a new WorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -38,6 +39,26 @@ NewWorkspaceDTOWithDefaults instantiates a new WorkspaceDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set +### GetApiKey + +`func (o *WorkspaceDTO) GetApiKey() string` + +GetApiKey returns the ApiKey field if non-nil, zero value otherwise. + +### GetApiKeyOk + +`func (o *WorkspaceDTO) GetApiKeyOk() (*string, bool)` + +GetApiKeyOk returns a tuple with the ApiKey field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetApiKey + +`func (o *WorkspaceDTO) SetApiKey(v string)` + +SetApiKey sets ApiKey field to given value. + + ### GetBuildConfig `func (o *WorkspaceDTO) GetBuildConfig() BuildConfig` @@ -148,31 +169,6 @@ and a boolean to check if the value has been set. SetImage sets Image field to given value. -### GetInfo - -`func (o *WorkspaceDTO) GetInfo() WorkspaceInfo` - -GetInfo returns the Info field if non-nil, zero value otherwise. - -### GetInfoOk - -`func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool)` - -GetInfoOk returns a tuple with the Info field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetInfo - -`func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo)` - -SetInfo sets Info field to given value. - -### HasInfo - -`func (o *WorkspaceDTO) HasInfo() bool` - -HasInfo returns a boolean if a field has been set. - ### GetLastJob `func (o *WorkspaceDTO) GetLastJob() Job` @@ -243,6 +239,31 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. +### GetProviderMetadata + +`func (o *WorkspaceDTO) GetProviderMetadata() string` + +GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. + +### GetProviderMetadataOk + +`func (o *WorkspaceDTO) GetProviderMetadataOk() (*string, bool)` + +GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetProviderMetadata + +`func (o *WorkspaceDTO) SetProviderMetadata(v string)` + +SetProviderMetadata sets ProviderMetadata field to given value. + +### HasProviderMetadata + +`func (o *WorkspaceDTO) HasProviderMetadata() bool` + +HasProviderMetadata returns a boolean if a field has been set. + ### GetRepository `func (o *WorkspaceDTO) GetRepository() GitRepository` diff --git a/pkg/apiclient/docs/WorkspaceInfo.md b/pkg/apiclient/docs/WorkspaceInfo.md deleted file mode 100644 index 330770d20d..0000000000 --- a/pkg/apiclient/docs/WorkspaceInfo.md +++ /dev/null @@ -1,140 +0,0 @@ -# WorkspaceInfo - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**Created** | **string** | | -**IsRunning** | **bool** | | -**Name** | **string** | | -**ProviderMetadata** | Pointer to **string** | | [optional] -**TargetId** | **string** | | - -## Methods - -### NewWorkspaceInfo - -`func NewWorkspaceInfo(created string, isRunning bool, name string, targetId string, ) *WorkspaceInfo` - -NewWorkspaceInfo instantiates a new WorkspaceInfo object -This constructor will assign default values to properties that have it defined, -and makes sure properties required by API are set, but the set of arguments -will change when the set of required properties is changed - -### NewWorkspaceInfoWithDefaults - -`func NewWorkspaceInfoWithDefaults() *WorkspaceInfo` - -NewWorkspaceInfoWithDefaults instantiates a new WorkspaceInfo object -This constructor will only assign default values to properties that have it defined, -but it doesn't guarantee that properties required by API are set - -### GetCreated - -`func (o *WorkspaceInfo) GetCreated() string` - -GetCreated returns the Created field if non-nil, zero value otherwise. - -### GetCreatedOk - -`func (o *WorkspaceInfo) GetCreatedOk() (*string, bool)` - -GetCreatedOk returns a tuple with the Created field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetCreated - -`func (o *WorkspaceInfo) SetCreated(v string)` - -SetCreated sets Created field to given value. - - -### GetIsRunning - -`func (o *WorkspaceInfo) GetIsRunning() bool` - -GetIsRunning returns the IsRunning field if non-nil, zero value otherwise. - -### GetIsRunningOk - -`func (o *WorkspaceInfo) GetIsRunningOk() (*bool, bool)` - -GetIsRunningOk returns a tuple with the IsRunning field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetIsRunning - -`func (o *WorkspaceInfo) SetIsRunning(v bool)` - -SetIsRunning sets IsRunning field to given value. - - -### GetName - -`func (o *WorkspaceInfo) GetName() string` - -GetName returns the Name field if non-nil, zero value otherwise. - -### GetNameOk - -`func (o *WorkspaceInfo) GetNameOk() (*string, bool)` - -GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetName - -`func (o *WorkspaceInfo) SetName(v string)` - -SetName sets Name field to given value. - - -### GetProviderMetadata - -`func (o *WorkspaceInfo) GetProviderMetadata() string` - -GetProviderMetadata returns the ProviderMetadata field if non-nil, zero value otherwise. - -### GetProviderMetadataOk - -`func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool)` - -GetProviderMetadataOk returns a tuple with the ProviderMetadata field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetProviderMetadata - -`func (o *WorkspaceInfo) SetProviderMetadata(v string)` - -SetProviderMetadata sets ProviderMetadata field to given value. - -### HasProviderMetadata - -`func (o *WorkspaceInfo) HasProviderMetadata() bool` - -HasProviderMetadata returns a boolean if a field has been set. - -### GetTargetId - -`func (o *WorkspaceInfo) GetTargetId() string` - -GetTargetId returns the TargetId field if non-nil, zero value otherwise. - -### GetTargetIdOk - -`func (o *WorkspaceInfo) GetTargetIdOk() (*string, bool)` - -GetTargetIdOk returns a tuple with the TargetId field if it's non-nil, zero value otherwise -and a boolean to check if the value has been set. - -### SetTargetId - -`func (o *WorkspaceInfo) SetTargetId(v string)` - -SetTargetId sets TargetId field to given value. - - - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/pkg/apiclient/model_add_target_config_dto.go b/pkg/apiclient/model_add_target_config_dto.go index 3947838597..b66fa5ed3c 100644 --- a/pkg/apiclient/model_add_target_config_dto.go +++ b/pkg/apiclient/model_add_target_config_dto.go @@ -21,9 +21,9 @@ var _ MappedNullable = &AddTargetConfigDTO{} // AddTargetConfigDTO struct for AddTargetConfigDTO type AddTargetConfigDTO struct { - Name string `json:"name"` - Options string `json:"options"` - ProviderInfo TargetProviderInfo `json:"providerInfo"` + Name string `json:"name"` + Options string `json:"options"` + ProviderInfo ProviderInfo `json:"providerInfo"` } type _AddTargetConfigDTO AddTargetConfigDTO @@ -32,7 +32,7 @@ type _AddTargetConfigDTO AddTargetConfigDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewAddTargetConfigDTO(name string, options string, providerInfo TargetProviderInfo) *AddTargetConfigDTO { +func NewAddTargetConfigDTO(name string, options string, providerInfo ProviderInfo) *AddTargetConfigDTO { this := AddTargetConfigDTO{} this.Name = name this.Options = options @@ -97,9 +97,9 @@ func (o *AddTargetConfigDTO) SetOptions(v string) { } // GetProviderInfo returns the ProviderInfo field value -func (o *AddTargetConfigDTO) GetProviderInfo() TargetProviderInfo { +func (o *AddTargetConfigDTO) GetProviderInfo() ProviderInfo { if o == nil { - var ret TargetProviderInfo + var ret ProviderInfo return ret } @@ -108,7 +108,7 @@ func (o *AddTargetConfigDTO) GetProviderInfo() TargetProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *AddTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { +func (o *AddTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool) { if o == nil { return nil, false } @@ -116,7 +116,7 @@ func (o *AddTargetConfigDTO) GetProviderInfoOk() (*TargetProviderInfo, bool) { } // SetProviderInfo sets field value -func (o *AddTargetConfigDTO) SetProviderInfo(v TargetProviderInfo) { +func (o *AddTargetConfigDTO) SetProviderInfo(v ProviderInfo) { o.ProviderInfo = v } diff --git a/pkg/apiclient/model_install_provider_request.go b/pkg/apiclient/model_install_provider_dto.go similarity index 56% rename from pkg/apiclient/model_install_provider_request.go rename to pkg/apiclient/model_install_provider_dto.go index de1ab67098..bf9863e53f 100644 --- a/pkg/apiclient/model_install_provider_request.go +++ b/pkg/apiclient/model_install_provider_dto.go @@ -16,38 +16,38 @@ import ( "fmt" ) -// checks if the InstallProviderRequest type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &InstallProviderRequest{} +// checks if the InstallProviderDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &InstallProviderDTO{} -// InstallProviderRequest struct for InstallProviderRequest -type InstallProviderRequest struct { +// InstallProviderDTO struct for InstallProviderDTO +type InstallProviderDTO struct { DownloadUrls map[string]string `json:"downloadUrls"` Name string `json:"name"` } -type _InstallProviderRequest InstallProviderRequest +type _InstallProviderDTO InstallProviderDTO -// NewInstallProviderRequest instantiates a new InstallProviderRequest object +// NewInstallProviderDTO instantiates a new InstallProviderDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewInstallProviderRequest(downloadUrls map[string]string, name string) *InstallProviderRequest { - this := InstallProviderRequest{} +func NewInstallProviderDTO(downloadUrls map[string]string, name string) *InstallProviderDTO { + this := InstallProviderDTO{} this.DownloadUrls = downloadUrls this.Name = name return &this } -// NewInstallProviderRequestWithDefaults instantiates a new InstallProviderRequest object +// NewInstallProviderDTOWithDefaults instantiates a new InstallProviderDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewInstallProviderRequestWithDefaults() *InstallProviderRequest { - this := InstallProviderRequest{} +func NewInstallProviderDTOWithDefaults() *InstallProviderDTO { + this := InstallProviderDTO{} return &this } // GetDownloadUrls returns the DownloadUrls field value -func (o *InstallProviderRequest) GetDownloadUrls() map[string]string { +func (o *InstallProviderDTO) GetDownloadUrls() map[string]string { if o == nil { var ret map[string]string return ret @@ -58,7 +58,7 @@ func (o *InstallProviderRequest) GetDownloadUrls() map[string]string { // GetDownloadUrlsOk returns a tuple with the DownloadUrls field value // and a boolean to check if the value has been set. -func (o *InstallProviderRequest) GetDownloadUrlsOk() (*map[string]string, bool) { +func (o *InstallProviderDTO) GetDownloadUrlsOk() (*map[string]string, bool) { if o == nil { return nil, false } @@ -66,12 +66,12 @@ func (o *InstallProviderRequest) GetDownloadUrlsOk() (*map[string]string, bool) } // SetDownloadUrls sets field value -func (o *InstallProviderRequest) SetDownloadUrls(v map[string]string) { +func (o *InstallProviderDTO) SetDownloadUrls(v map[string]string) { o.DownloadUrls = v } // GetName returns the Name field value -func (o *InstallProviderRequest) GetName() string { +func (o *InstallProviderDTO) GetName() string { if o == nil { var ret string return ret @@ -82,7 +82,7 @@ func (o *InstallProviderRequest) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *InstallProviderRequest) GetNameOk() (*string, bool) { +func (o *InstallProviderDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -90,11 +90,11 @@ func (o *InstallProviderRequest) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *InstallProviderRequest) SetName(v string) { +func (o *InstallProviderDTO) SetName(v string) { o.Name = v } -func (o InstallProviderRequest) MarshalJSON() ([]byte, error) { +func (o InstallProviderDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -102,14 +102,14 @@ func (o InstallProviderRequest) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o InstallProviderRequest) ToMap() (map[string]interface{}, error) { +func (o InstallProviderDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["downloadUrls"] = o.DownloadUrls toSerialize["name"] = o.Name return toSerialize, nil } -func (o *InstallProviderRequest) UnmarshalJSON(data []byte) (err error) { +func (o *InstallProviderDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -132,53 +132,53 @@ func (o *InstallProviderRequest) UnmarshalJSON(data []byte) (err error) { } } - varInstallProviderRequest := _InstallProviderRequest{} + varInstallProviderDTO := _InstallProviderDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varInstallProviderRequest) + err = decoder.Decode(&varInstallProviderDTO) if err != nil { return err } - *o = InstallProviderRequest(varInstallProviderRequest) + *o = InstallProviderDTO(varInstallProviderDTO) return err } -type NullableInstallProviderRequest struct { - value *InstallProviderRequest +type NullableInstallProviderDTO struct { + value *InstallProviderDTO isSet bool } -func (v NullableInstallProviderRequest) Get() *InstallProviderRequest { +func (v NullableInstallProviderDTO) Get() *InstallProviderDTO { return v.value } -func (v *NullableInstallProviderRequest) Set(val *InstallProviderRequest) { +func (v *NullableInstallProviderDTO) Set(val *InstallProviderDTO) { v.value = val v.isSet = true } -func (v NullableInstallProviderRequest) IsSet() bool { +func (v NullableInstallProviderDTO) IsSet() bool { return v.isSet } -func (v *NullableInstallProviderRequest) Unset() { +func (v *NullableInstallProviderDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableInstallProviderRequest(val *InstallProviderRequest) *NullableInstallProviderRequest { - return &NullableInstallProviderRequest{value: val, isSet: true} +func NewNullableInstallProviderDTO(val *InstallProviderDTO) *NullableInstallProviderDTO { + return &NullableInstallProviderDTO{value: val, isSet: true} } -func (v NullableInstallProviderRequest) MarshalJSON() ([]byte, error) { +func (v NullableInstallProviderDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableInstallProviderRequest) UnmarshalJSON(src []byte) error { +func (v *NullableInstallProviderDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_job.go b/pkg/apiclient/model_job.go index 6550dfe097..6561bc1a92 100644 --- a/pkg/apiclient/model_job.go +++ b/pkg/apiclient/model_job.go @@ -21,14 +21,17 @@ var _ MappedNullable = &Job{} // Job struct for Job type Job struct { - Action ModelsJobAction `json:"action"` - CreatedAt string `json:"createdAt"` - Error *string `json:"error,omitempty"` - Id string `json:"id"` - ResourceId string `json:"resourceId"` - ResourceType ResourceType `json:"resourceType"` - State JobState `json:"state"` - UpdatedAt string `json:"updatedAt"` + Action ModelsJobAction `json:"action"` + CreatedAt string `json:"createdAt"` + Error *string `json:"error,omitempty"` + Id string `json:"id"` + // JSON encoded metadata + Metadata *string `json:"metadata,omitempty"` + ResourceId string `json:"resourceId"` + ResourceType ResourceType `json:"resourceType"` + RunnerId *string `json:"runnerId,omitempty"` + State JobState `json:"state"` + UpdatedAt string `json:"updatedAt"` } type _Job Job @@ -161,6 +164,38 @@ func (o *Job) SetId(v string) { o.Id = v } +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *Job) GetMetadata() string { + if o == nil || IsNil(o.Metadata) { + var ret string + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Job) GetMetadataOk() (*string, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *Job) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given string and assigns it to the Metadata field. +func (o *Job) SetMetadata(v string) { + o.Metadata = &v +} + // GetResourceId returns the ResourceId field value func (o *Job) GetResourceId() string { if o == nil { @@ -209,6 +244,38 @@ func (o *Job) SetResourceType(v ResourceType) { o.ResourceType = v } +// GetRunnerId returns the RunnerId field value if set, zero value otherwise. +func (o *Job) GetRunnerId() string { + if o == nil || IsNil(o.RunnerId) { + var ret string + return ret + } + return *o.RunnerId +} + +// GetRunnerIdOk returns a tuple with the RunnerId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Job) GetRunnerIdOk() (*string, bool) { + if o == nil || IsNil(o.RunnerId) { + return nil, false + } + return o.RunnerId, true +} + +// HasRunnerId returns a boolean if a field has been set. +func (o *Job) HasRunnerId() bool { + if o != nil && !IsNil(o.RunnerId) { + return true + } + + return false +} + +// SetRunnerId gets a reference to the given string and assigns it to the RunnerId field. +func (o *Job) SetRunnerId(v string) { + o.RunnerId = &v +} + // GetState returns the State field value func (o *Job) GetState() JobState { if o == nil { @@ -273,8 +340,14 @@ func (o Job) ToMap() (map[string]interface{}, error) { toSerialize["error"] = o.Error } toSerialize["id"] = o.Id + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } toSerialize["resourceId"] = o.ResourceId toSerialize["resourceType"] = o.ResourceType + if !IsNil(o.RunnerId) { + toSerialize["runnerId"] = o.RunnerId + } toSerialize["state"] = o.State toSerialize["updatedAt"] = o.UpdatedAt return toSerialize, nil diff --git a/pkg/apiclient/model_models_api_key_type.go b/pkg/apiclient/model_models_api_key_type.go index 94ef5ef217..b202669443 100644 --- a/pkg/apiclient/model_models_api_key_type.go +++ b/pkg/apiclient/model_models_api_key_type.go @@ -23,6 +23,7 @@ const ( ApiKeyTypeClient ModelsApiKeyType = "client" ApiKeyTypeWorkspace ModelsApiKeyType = "workspace" ApiKeyTypeTarget ModelsApiKeyType = "target" + ApiKeyTypeRunner ModelsApiKeyType = "runner" ) // All allowed values of ModelsApiKeyType enum @@ -30,6 +31,7 @@ var AllowedModelsApiKeyTypeEnumValues = []ModelsApiKeyType{ "client", "workspace", "target", + "runner", } func (v *ModelsApiKeyType) UnmarshalJSON(src []byte) error { diff --git a/pkg/apiclient/model_models_job_action.go b/pkg/apiclient/model_models_job_action.go index cbc619f622..5463e65323 100644 --- a/pkg/apiclient/model_models_job_action.go +++ b/pkg/apiclient/model_models_job_action.go @@ -20,13 +20,16 @@ type ModelsJobAction string // List of models.JobAction const ( - JobActionCreate ModelsJobAction = "create" - JobActionStart ModelsJobAction = "start" - JobActionStop ModelsJobAction = "stop" - JobActionRestart ModelsJobAction = "restart" - JobActionDelete ModelsJobAction = "delete" - JobActionForceDelete ModelsJobAction = "force-delete" - JobActionRun ModelsJobAction = "run" + JobActionCreate ModelsJobAction = "create" + JobActionStart ModelsJobAction = "start" + JobActionStop ModelsJobAction = "stop" + JobActionRestart ModelsJobAction = "restart" + JobActionDelete ModelsJobAction = "delete" + JobActionForceDelete ModelsJobAction = "force-delete" + JobActionRun ModelsJobAction = "run" + JobActionInstallProvider ModelsJobAction = "install-provider" + JobActionUninstallProvider ModelsJobAction = "uninstall-provider" + JobActionUpdateProvider ModelsJobAction = "update-provider" ) // All allowed values of ModelsJobAction enum @@ -38,6 +41,9 @@ var AllowedModelsJobActionEnumValues = []ModelsJobAction{ "delete", "force-delete", "run", + "install-provider", + "uninstall-provider", + "update-provider", } func (v *ModelsJobAction) UnmarshalJSON(src []byte) error { diff --git a/pkg/apiclient/model_models_target_config_property_type.go b/pkg/apiclient/model_models_target_config_property_type.go new file mode 100644 index 0000000000..bd675825c1 --- /dev/null +++ b/pkg/apiclient/model_models_target_config_property_type.go @@ -0,0 +1,118 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "encoding/json" + "fmt" +) + +// ModelsTargetConfigPropertyType the model 'ModelsTargetConfigPropertyType' +type ModelsTargetConfigPropertyType string + +// List of models.TargetConfigPropertyType +const ( + TargetConfigPropertyTypeString ModelsTargetConfigPropertyType = "string" + TargetConfigPropertyTypeOption ModelsTargetConfigPropertyType = "option" + TargetConfigPropertyTypeBoolean ModelsTargetConfigPropertyType = "boolean" + TargetConfigPropertyTypeInt ModelsTargetConfigPropertyType = "int" + TargetConfigPropertyTypeFloat ModelsTargetConfigPropertyType = "float" + TargetConfigPropertyTypeFilePath ModelsTargetConfigPropertyType = "file-path" +) + +// All allowed values of ModelsTargetConfigPropertyType enum +var AllowedModelsTargetConfigPropertyTypeEnumValues = []ModelsTargetConfigPropertyType{ + "string", + "option", + "boolean", + "int", + "float", + "file-path", +} + +func (v *ModelsTargetConfigPropertyType) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ModelsTargetConfigPropertyType(value) + for _, existing := range AllowedModelsTargetConfigPropertyTypeEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ModelsTargetConfigPropertyType", value) +} + +// NewModelsTargetConfigPropertyTypeFromValue returns a pointer to a valid ModelsTargetConfigPropertyType +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewModelsTargetConfigPropertyTypeFromValue(v string) (*ModelsTargetConfigPropertyType, error) { + ev := ModelsTargetConfigPropertyType(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ModelsTargetConfigPropertyType: valid values are %v", v, AllowedModelsTargetConfigPropertyTypeEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ModelsTargetConfigPropertyType) IsValid() bool { + for _, existing := range AllowedModelsTargetConfigPropertyTypeEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to models.TargetConfigPropertyType value +func (v ModelsTargetConfigPropertyType) Ptr() *ModelsTargetConfigPropertyType { + return &v +} + +type NullableModelsTargetConfigPropertyType struct { + value *ModelsTargetConfigPropertyType + isSet bool +} + +func (v NullableModelsTargetConfigPropertyType) Get() *ModelsTargetConfigPropertyType { + return v.value +} + +func (v *NullableModelsTargetConfigPropertyType) Set(val *ModelsTargetConfigPropertyType) { + v.value = val + v.isSet = true +} + +func (v NullableModelsTargetConfigPropertyType) IsSet() bool { + return v.isSet +} + +func (v *NullableModelsTargetConfigPropertyType) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelsTargetConfigPropertyType(val *ModelsTargetConfigPropertyType) *NullableModelsTargetConfigPropertyType { + return &NullableModelsTargetConfigPropertyType{value: val, isSet: true} +} + +func (v NullableModelsTargetConfigPropertyType) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelsTargetConfigPropertyType) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_provider.go b/pkg/apiclient/model_provider.go deleted file mode 100644 index b5c025dfba..0000000000 --- a/pkg/apiclient/model_provider.go +++ /dev/null @@ -1,220 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "encoding/json" - "fmt" -) - -// checks if the Provider type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &Provider{} - -// Provider struct for Provider -type Provider struct { - Label *string `json:"label,omitempty"` - Name string `json:"name"` - Version string `json:"version"` -} - -type _Provider Provider - -// NewProvider instantiates a new Provider object -// This constructor will assign default values to properties that have it defined, -// and makes sure properties required by API are set, but the set of arguments -// will change when the set of required properties is changed -func NewProvider(name string, version string) *Provider { - this := Provider{} - this.Name = name - this.Version = version - return &this -} - -// NewProviderWithDefaults instantiates a new Provider object -// This constructor will only assign default values to properties that have it defined, -// but it doesn't guarantee that properties required by API are set -func NewProviderWithDefaults() *Provider { - this := Provider{} - return &this -} - -// GetLabel returns the Label field value if set, zero value otherwise. -func (o *Provider) GetLabel() string { - if o == nil || IsNil(o.Label) { - var ret string - return ret - } - return *o.Label -} - -// GetLabelOk returns a tuple with the Label field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *Provider) GetLabelOk() (*string, bool) { - if o == nil || IsNil(o.Label) { - return nil, false - } - return o.Label, true -} - -// HasLabel returns a boolean if a field has been set. -func (o *Provider) HasLabel() bool { - if o != nil && !IsNil(o.Label) { - return true - } - - return false -} - -// SetLabel gets a reference to the given string and assigns it to the Label field. -func (o *Provider) SetLabel(v string) { - o.Label = &v -} - -// GetName returns the Name field value -func (o *Provider) GetName() string { - if o == nil { - var ret string - return ret - } - - return o.Name -} - -// GetNameOk returns a tuple with the Name field value -// and a boolean to check if the value has been set. -func (o *Provider) GetNameOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Name, true -} - -// SetName sets field value -func (o *Provider) SetName(v string) { - o.Name = v -} - -// GetVersion returns the Version field value -func (o *Provider) GetVersion() string { - if o == nil { - var ret string - return ret - } - - return o.Version -} - -// GetVersionOk returns a tuple with the Version field value -// and a boolean to check if the value has been set. -func (o *Provider) GetVersionOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Version, true -} - -// SetVersion sets field value -func (o *Provider) SetVersion(v string) { - o.Version = v -} - -func (o Provider) MarshalJSON() ([]byte, error) { - toSerialize, err := o.ToMap() - if err != nil { - return []byte{}, err - } - return json.Marshal(toSerialize) -} - -func (o Provider) ToMap() (map[string]interface{}, error) { - toSerialize := map[string]interface{}{} - if !IsNil(o.Label) { - toSerialize["label"] = o.Label - } - toSerialize["name"] = o.Name - toSerialize["version"] = o.Version - return toSerialize, nil -} - -func (o *Provider) UnmarshalJSON(data []byte) (err error) { - // This validates that all required properties are included in the JSON object - // by unmarshalling the object into a generic map with string keys and checking - // that every required field exists as a key in the generic map. - requiredProperties := []string{ - "name", - "version", - } - - allProperties := make(map[string]interface{}) - - err = json.Unmarshal(data, &allProperties) - - if err != nil { - return err - } - - for _, requiredProperty := range requiredProperties { - if _, exists := allProperties[requiredProperty]; !exists { - return fmt.Errorf("no value given for required property %v", requiredProperty) - } - } - - varProvider := _Provider{} - - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(&varProvider) - - if err != nil { - return err - } - - *o = Provider(varProvider) - - return err -} - -type NullableProvider struct { - value *Provider - isSet bool -} - -func (v NullableProvider) Get() *Provider { - return v.value -} - -func (v *NullableProvider) Set(val *Provider) { - v.value = val - v.isSet = true -} - -func (v NullableProvider) IsSet() bool { - return v.isSet -} - -func (v *NullableProvider) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableProvider(val *Provider) *NullableProvider { - return &NullableProvider{value: val, isSet: true} -} - -func (v NullableProvider) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableProvider) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_provider_info.go b/pkg/apiclient/model_provider_info.go new file mode 100644 index 0000000000..0f1d3ad2b1 --- /dev/null +++ b/pkg/apiclient/model_provider_info.go @@ -0,0 +1,340 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the ProviderInfo type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ProviderInfo{} + +// ProviderInfo struct for ProviderInfo +type ProviderInfo struct { + AgentlessTarget *bool `json:"agentlessTarget,omitempty"` + Label *string `json:"label,omitempty"` + Name string `json:"name"` + RunnerId string `json:"runnerId"` + RunnerName string `json:"runnerName"` + TargetConfigManifest map[string]TargetConfigProperty `json:"targetConfigManifest"` + Version string `json:"version"` +} + +type _ProviderInfo ProviderInfo + +// NewProviderInfo instantiates a new ProviderInfo object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewProviderInfo(name string, runnerId string, runnerName string, targetConfigManifest map[string]TargetConfigProperty, version string) *ProviderInfo { + this := ProviderInfo{} + this.Name = name + this.RunnerId = runnerId + this.RunnerName = runnerName + this.TargetConfigManifest = targetConfigManifest + this.Version = version + return &this +} + +// NewProviderInfoWithDefaults instantiates a new ProviderInfo object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewProviderInfoWithDefaults() *ProviderInfo { + this := ProviderInfo{} + return &this +} + +// GetAgentlessTarget returns the AgentlessTarget field value if set, zero value otherwise. +func (o *ProviderInfo) GetAgentlessTarget() bool { + if o == nil || IsNil(o.AgentlessTarget) { + var ret bool + return ret + } + return *o.AgentlessTarget +} + +// GetAgentlessTargetOk returns a tuple with the AgentlessTarget field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetAgentlessTargetOk() (*bool, bool) { + if o == nil || IsNil(o.AgentlessTarget) { + return nil, false + } + return o.AgentlessTarget, true +} + +// HasAgentlessTarget returns a boolean if a field has been set. +func (o *ProviderInfo) HasAgentlessTarget() bool { + if o != nil && !IsNil(o.AgentlessTarget) { + return true + } + + return false +} + +// SetAgentlessTarget gets a reference to the given bool and assigns it to the AgentlessTarget field. +func (o *ProviderInfo) SetAgentlessTarget(v bool) { + o.AgentlessTarget = &v +} + +// GetLabel returns the Label field value if set, zero value otherwise. +func (o *ProviderInfo) GetLabel() string { + if o == nil || IsNil(o.Label) { + var ret string + return ret + } + return *o.Label +} + +// GetLabelOk returns a tuple with the Label field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetLabelOk() (*string, bool) { + if o == nil || IsNil(o.Label) { + return nil, false + } + return o.Label, true +} + +// HasLabel returns a boolean if a field has been set. +func (o *ProviderInfo) HasLabel() bool { + if o != nil && !IsNil(o.Label) { + return true + } + + return false +} + +// SetLabel gets a reference to the given string and assigns it to the Label field. +func (o *ProviderInfo) SetLabel(v string) { + o.Label = &v +} + +// GetName returns the Name field value +func (o *ProviderInfo) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *ProviderInfo) SetName(v string) { + o.Name = v +} + +// GetRunnerId returns the RunnerId field value +func (o *ProviderInfo) GetRunnerId() string { + if o == nil { + var ret string + return ret + } + + return o.RunnerId +} + +// GetRunnerIdOk returns a tuple with the RunnerId field value +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetRunnerIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.RunnerId, true +} + +// SetRunnerId sets field value +func (o *ProviderInfo) SetRunnerId(v string) { + o.RunnerId = v +} + +// GetRunnerName returns the RunnerName field value +func (o *ProviderInfo) GetRunnerName() string { + if o == nil { + var ret string + return ret + } + + return o.RunnerName +} + +// GetRunnerNameOk returns a tuple with the RunnerName field value +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetRunnerNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.RunnerName, true +} + +// SetRunnerName sets field value +func (o *ProviderInfo) SetRunnerName(v string) { + o.RunnerName = v +} + +// GetTargetConfigManifest returns the TargetConfigManifest field value +func (o *ProviderInfo) GetTargetConfigManifest() map[string]TargetConfigProperty { + if o == nil { + var ret map[string]TargetConfigProperty + return ret + } + + return o.TargetConfigManifest +} + +// GetTargetConfigManifestOk returns a tuple with the TargetConfigManifest field value +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetTargetConfigManifestOk() (*map[string]TargetConfigProperty, bool) { + if o == nil { + return nil, false + } + return &o.TargetConfigManifest, true +} + +// SetTargetConfigManifest sets field value +func (o *ProviderInfo) SetTargetConfigManifest(v map[string]TargetConfigProperty) { + o.TargetConfigManifest = v +} + +// GetVersion returns the Version field value +func (o *ProviderInfo) GetVersion() string { + if o == nil { + var ret string + return ret + } + + return o.Version +} + +// GetVersionOk returns a tuple with the Version field value +// and a boolean to check if the value has been set. +func (o *ProviderInfo) GetVersionOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Version, true +} + +// SetVersion sets field value +func (o *ProviderInfo) SetVersion(v string) { + o.Version = v +} + +func (o ProviderInfo) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ProviderInfo) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.AgentlessTarget) { + toSerialize["agentlessTarget"] = o.AgentlessTarget + } + if !IsNil(o.Label) { + toSerialize["label"] = o.Label + } + toSerialize["name"] = o.Name + toSerialize["runnerId"] = o.RunnerId + toSerialize["runnerName"] = o.RunnerName + toSerialize["targetConfigManifest"] = o.TargetConfigManifest + toSerialize["version"] = o.Version + return toSerialize, nil +} + +func (o *ProviderInfo) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "name", + "runnerId", + "runnerName", + "targetConfigManifest", + "version", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varProviderInfo := _ProviderInfo{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varProviderInfo) + + if err != nil { + return err + } + + *o = ProviderInfo(varProviderInfo) + + return err +} + +type NullableProviderInfo struct { + value *ProviderInfo + isSet bool +} + +func (v NullableProviderInfo) Get() *ProviderInfo { + return v.value +} + +func (v *NullableProviderInfo) Set(val *ProviderInfo) { + v.value = val + v.isSet = true +} + +func (v NullableProviderInfo) IsSet() bool { + return v.isSet +} + +func (v *NullableProviderInfo) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableProviderInfo(val *ProviderInfo) *NullableProviderInfo { + return &NullableProviderInfo{value: val, isSet: true} +} + +func (v NullableProviderInfo) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableProviderInfo) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_provider_target_config_property_type.go b/pkg/apiclient/model_provider_target_config_property_type.go deleted file mode 100644 index b493484787..0000000000 --- a/pkg/apiclient/model_provider_target_config_property_type.go +++ /dev/null @@ -1,118 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "encoding/json" - "fmt" -) - -// ProviderTargetConfigPropertyType the model 'ProviderTargetConfigPropertyType' -type ProviderTargetConfigPropertyType string - -// List of provider.TargetConfigPropertyType -const ( - TargetConfigPropertyTypeString ProviderTargetConfigPropertyType = "string" - TargetConfigPropertyTypeOption ProviderTargetConfigPropertyType = "option" - TargetConfigPropertyTypeBoolean ProviderTargetConfigPropertyType = "boolean" - TargetConfigPropertyTypeInt ProviderTargetConfigPropertyType = "int" - TargetConfigPropertyTypeFloat ProviderTargetConfigPropertyType = "float" - TargetConfigPropertyTypeFilePath ProviderTargetConfigPropertyType = "file-path" -) - -// All allowed values of ProviderTargetConfigPropertyType enum -var AllowedProviderTargetConfigPropertyTypeEnumValues = []ProviderTargetConfigPropertyType{ - "string", - "option", - "boolean", - "int", - "float", - "file-path", -} - -func (v *ProviderTargetConfigPropertyType) UnmarshalJSON(src []byte) error { - var value string - err := json.Unmarshal(src, &value) - if err != nil { - return err - } - enumTypeValue := ProviderTargetConfigPropertyType(value) - for _, existing := range AllowedProviderTargetConfigPropertyTypeEnumValues { - if existing == enumTypeValue { - *v = enumTypeValue - return nil - } - } - - return fmt.Errorf("%+v is not a valid ProviderTargetConfigPropertyType", value) -} - -// NewProviderTargetConfigPropertyTypeFromValue returns a pointer to a valid ProviderTargetConfigPropertyType -// for the value passed as argument, or an error if the value passed is not allowed by the enum -func NewProviderTargetConfigPropertyTypeFromValue(v string) (*ProviderTargetConfigPropertyType, error) { - ev := ProviderTargetConfigPropertyType(v) - if ev.IsValid() { - return &ev, nil - } else { - return nil, fmt.Errorf("invalid value '%v' for ProviderTargetConfigPropertyType: valid values are %v", v, AllowedProviderTargetConfigPropertyTypeEnumValues) - } -} - -// IsValid return true if the value is valid for the enum, false otherwise -func (v ProviderTargetConfigPropertyType) IsValid() bool { - for _, existing := range AllowedProviderTargetConfigPropertyTypeEnumValues { - if existing == v { - return true - } - } - return false -} - -// Ptr returns reference to provider.TargetConfigPropertyType value -func (v ProviderTargetConfigPropertyType) Ptr() *ProviderTargetConfigPropertyType { - return &v -} - -type NullableProviderTargetConfigPropertyType struct { - value *ProviderTargetConfigPropertyType - isSet bool -} - -func (v NullableProviderTargetConfigPropertyType) Get() *ProviderTargetConfigPropertyType { - return v.value -} - -func (v *NullableProviderTargetConfigPropertyType) Set(val *ProviderTargetConfigPropertyType) { - v.value = val - v.isSet = true -} - -func (v NullableProviderTargetConfigPropertyType) IsSet() bool { - return v.isSet -} - -func (v *NullableProviderTargetConfigPropertyType) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableProviderTargetConfigPropertyType(val *ProviderTargetConfigPropertyType) *NullableProviderTargetConfigPropertyType { - return &NullableProviderTargetConfigPropertyType{value: val, isSet: true} -} - -func (v NullableProviderTargetConfigPropertyType) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableProviderTargetConfigPropertyType) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_register_runner_dto.go b/pkg/apiclient/model_register_runner_dto.go new file mode 100644 index 0000000000..9be610e366 --- /dev/null +++ b/pkg/apiclient/model_register_runner_dto.go @@ -0,0 +1,184 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the RegisterRunnerDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RegisterRunnerDTO{} + +// RegisterRunnerDTO struct for RegisterRunnerDTO +type RegisterRunnerDTO struct { + Id string `json:"id"` + Name string `json:"name"` +} + +type _RegisterRunnerDTO RegisterRunnerDTO + +// NewRegisterRunnerDTO instantiates a new RegisterRunnerDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRegisterRunnerDTO(id string, name string) *RegisterRunnerDTO { + this := RegisterRunnerDTO{} + this.Id = id + this.Name = name + return &this +} + +// NewRegisterRunnerDTOWithDefaults instantiates a new RegisterRunnerDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRegisterRunnerDTOWithDefaults() *RegisterRunnerDTO { + this := RegisterRunnerDTO{} + return &this +} + +// GetId returns the Id field value +func (o *RegisterRunnerDTO) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *RegisterRunnerDTO) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *RegisterRunnerDTO) SetId(v string) { + o.Id = v +} + +// GetName returns the Name field value +func (o *RegisterRunnerDTO) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *RegisterRunnerDTO) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *RegisterRunnerDTO) SetName(v string) { + o.Name = v +} + +func (o RegisterRunnerDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RegisterRunnerDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["id"] = o.Id + toSerialize["name"] = o.Name + return toSerialize, nil +} + +func (o *RegisterRunnerDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "id", + "name", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varRegisterRunnerDTO := _RegisterRunnerDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varRegisterRunnerDTO) + + if err != nil { + return err + } + + *o = RegisterRunnerDTO(varRegisterRunnerDTO) + + return err +} + +type NullableRegisterRunnerDTO struct { + value *RegisterRunnerDTO + isSet bool +} + +func (v NullableRegisterRunnerDTO) Get() *RegisterRunnerDTO { + return v.value +} + +func (v *NullableRegisterRunnerDTO) Set(val *RegisterRunnerDTO) { + v.value = val + v.isSet = true +} + +func (v NullableRegisterRunnerDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisterRunnerDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisterRunnerDTO(val *RegisterRunnerDTO) *NullableRegisterRunnerDTO { + return &NullableRegisterRunnerDTO{value: val, isSet: true} +} + +func (v NullableRegisterRunnerDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisterRunnerDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_register_runner_result_dto.go b/pkg/apiclient/model_register_runner_result_dto.go new file mode 100644 index 0000000000..59f0cb702f --- /dev/null +++ b/pkg/apiclient/model_register_runner_result_dto.go @@ -0,0 +1,248 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the RegisterRunnerResultDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RegisterRunnerResultDTO{} + +// RegisterRunnerResultDTO struct for RegisterRunnerResultDTO +type RegisterRunnerResultDTO struct { + ApiKey string `json:"apiKey"` + Id string `json:"id"` + Metadata *RunnerMetadata `json:"metadata,omitempty"` + Name string `json:"name"` +} + +type _RegisterRunnerResultDTO RegisterRunnerResultDTO + +// NewRegisterRunnerResultDTO instantiates a new RegisterRunnerResultDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRegisterRunnerResultDTO(apiKey string, id string, name string) *RegisterRunnerResultDTO { + this := RegisterRunnerResultDTO{} + this.ApiKey = apiKey + this.Id = id + this.Name = name + return &this +} + +// NewRegisterRunnerResultDTOWithDefaults instantiates a new RegisterRunnerResultDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRegisterRunnerResultDTOWithDefaults() *RegisterRunnerResultDTO { + this := RegisterRunnerResultDTO{} + return &this +} + +// GetApiKey returns the ApiKey field value +func (o *RegisterRunnerResultDTO) GetApiKey() string { + if o == nil { + var ret string + return ret + } + + return o.ApiKey +} + +// GetApiKeyOk returns a tuple with the ApiKey field value +// and a boolean to check if the value has been set. +func (o *RegisterRunnerResultDTO) GetApiKeyOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ApiKey, true +} + +// SetApiKey sets field value +func (o *RegisterRunnerResultDTO) SetApiKey(v string) { + o.ApiKey = v +} + +// GetId returns the Id field value +func (o *RegisterRunnerResultDTO) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *RegisterRunnerResultDTO) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *RegisterRunnerResultDTO) SetId(v string) { + o.Id = v +} + +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *RegisterRunnerResultDTO) GetMetadata() RunnerMetadata { + if o == nil || IsNil(o.Metadata) { + var ret RunnerMetadata + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisterRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *RegisterRunnerResultDTO) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given RunnerMetadata and assigns it to the Metadata field. +func (o *RegisterRunnerResultDTO) SetMetadata(v RunnerMetadata) { + o.Metadata = &v +} + +// GetName returns the Name field value +func (o *RegisterRunnerResultDTO) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *RegisterRunnerResultDTO) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *RegisterRunnerResultDTO) SetName(v string) { + o.Name = v +} + +func (o RegisterRunnerResultDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RegisterRunnerResultDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["apiKey"] = o.ApiKey + toSerialize["id"] = o.Id + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } + toSerialize["name"] = o.Name + return toSerialize, nil +} + +func (o *RegisterRunnerResultDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "apiKey", + "id", + "name", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varRegisterRunnerResultDTO := _RegisterRunnerResultDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varRegisterRunnerResultDTO) + + if err != nil { + return err + } + + *o = RegisterRunnerResultDTO(varRegisterRunnerResultDTO) + + return err +} + +type NullableRegisterRunnerResultDTO struct { + value *RegisterRunnerResultDTO + isSet bool +} + +func (v NullableRegisterRunnerResultDTO) Get() *RegisterRunnerResultDTO { + return v.value +} + +func (v *NullableRegisterRunnerResultDTO) Set(val *RegisterRunnerResultDTO) { + v.value = val + v.isSet = true +} + +func (v NullableRegisterRunnerResultDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisterRunnerResultDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisterRunnerResultDTO(val *RegisterRunnerResultDTO) *NullableRegisterRunnerResultDTO { + return &NullableRegisterRunnerResultDTO{value: val, isSet: true} +} + +func (v NullableRegisterRunnerResultDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisterRunnerResultDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_resource_type.go b/pkg/apiclient/model_resource_type.go index ac7954ac59..d9a330dd9d 100644 --- a/pkg/apiclient/model_resource_type.go +++ b/pkg/apiclient/model_resource_type.go @@ -23,6 +23,7 @@ const ( ResourceTypeWorkspace ResourceType = "workspace" ResourceTypeTarget ResourceType = "target" ResourceTypeBuild ResourceType = "build" + ResourceTypeRunner ResourceType = "runner" ) // All allowed values of ResourceType enum @@ -30,6 +31,7 @@ var AllowedResourceTypeEnumValues = []ResourceType{ "workspace", "target", "build", + "runner", } func (v *ResourceType) UnmarshalJSON(src []byte) error { diff --git a/pkg/apiclient/model_runner_dto.go b/pkg/apiclient/model_runner_dto.go new file mode 100644 index 0000000000..97ec0212e9 --- /dev/null +++ b/pkg/apiclient/model_runner_dto.go @@ -0,0 +1,248 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the RunnerDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RunnerDTO{} + +// RunnerDTO struct for RunnerDTO +type RunnerDTO struct { + Id string `json:"id"` + Metadata *RunnerMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + State ResourceState `json:"state"` +} + +type _RunnerDTO RunnerDTO + +// NewRunnerDTO instantiates a new RunnerDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRunnerDTO(id string, name string, state ResourceState) *RunnerDTO { + this := RunnerDTO{} + this.Id = id + this.Name = name + this.State = state + return &this +} + +// NewRunnerDTOWithDefaults instantiates a new RunnerDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRunnerDTOWithDefaults() *RunnerDTO { + this := RunnerDTO{} + return &this +} + +// GetId returns the Id field value +func (o *RunnerDTO) GetId() string { + if o == nil { + var ret string + return ret + } + + return o.Id +} + +// GetIdOk returns a tuple with the Id field value +// and a boolean to check if the value has been set. +func (o *RunnerDTO) GetIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Id, true +} + +// SetId sets field value +func (o *RunnerDTO) SetId(v string) { + o.Id = v +} + +// GetMetadata returns the Metadata field value if set, zero value otherwise. +func (o *RunnerDTO) GetMetadata() RunnerMetadata { + if o == nil || IsNil(o.Metadata) { + var ret RunnerMetadata + return ret + } + return *o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RunnerDTO) GetMetadataOk() (*RunnerMetadata, bool) { + if o == nil || IsNil(o.Metadata) { + return nil, false + } + return o.Metadata, true +} + +// HasMetadata returns a boolean if a field has been set. +func (o *RunnerDTO) HasMetadata() bool { + if o != nil && !IsNil(o.Metadata) { + return true + } + + return false +} + +// SetMetadata gets a reference to the given RunnerMetadata and assigns it to the Metadata field. +func (o *RunnerDTO) SetMetadata(v RunnerMetadata) { + o.Metadata = &v +} + +// GetName returns the Name field value +func (o *RunnerDTO) GetName() string { + if o == nil { + var ret string + return ret + } + + return o.Name +} + +// GetNameOk returns a tuple with the Name field value +// and a boolean to check if the value has been set. +func (o *RunnerDTO) GetNameOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Name, true +} + +// SetName sets field value +func (o *RunnerDTO) SetName(v string) { + o.Name = v +} + +// GetState returns the State field value +func (o *RunnerDTO) GetState() ResourceState { + if o == nil { + var ret ResourceState + return ret + } + + return o.State +} + +// GetStateOk returns a tuple with the State field value +// and a boolean to check if the value has been set. +func (o *RunnerDTO) GetStateOk() (*ResourceState, bool) { + if o == nil { + return nil, false + } + return &o.State, true +} + +// SetState sets field value +func (o *RunnerDTO) SetState(v ResourceState) { + o.State = v +} + +func (o RunnerDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RunnerDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["id"] = o.Id + if !IsNil(o.Metadata) { + toSerialize["metadata"] = o.Metadata + } + toSerialize["name"] = o.Name + toSerialize["state"] = o.State + return toSerialize, nil +} + +func (o *RunnerDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "id", + "name", + "state", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varRunnerDTO := _RunnerDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varRunnerDTO) + + if err != nil { + return err + } + + *o = RunnerDTO(varRunnerDTO) + + return err +} + +type NullableRunnerDTO struct { + value *RunnerDTO + isSet bool +} + +func (v NullableRunnerDTO) Get() *RunnerDTO { + return v.value +} + +func (v *NullableRunnerDTO) Set(val *RunnerDTO) { + v.value = val + v.isSet = true +} + +func (v NullableRunnerDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableRunnerDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRunnerDTO(val *RunnerDTO) *NullableRunnerDTO { + return &NullableRunnerDTO{value: val, isSet: true} +} + +func (v NullableRunnerDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRunnerDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_runner_metadata.go b/pkg/apiclient/model_runner_metadata.go new file mode 100644 index 0000000000..d5d9ef3cbf --- /dev/null +++ b/pkg/apiclient/model_runner_metadata.go @@ -0,0 +1,276 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the RunnerMetadata type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RunnerMetadata{} + +// RunnerMetadata struct for RunnerMetadata +type RunnerMetadata struct { + Providers []ProviderInfo `json:"providers"` + RunnerId string `json:"runnerId"` + RunningJobs *int32 `json:"runningJobs,omitempty"` + UpdatedAt string `json:"updatedAt"` + Uptime int32 `json:"uptime"` +} + +type _RunnerMetadata RunnerMetadata + +// NewRunnerMetadata instantiates a new RunnerMetadata object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRunnerMetadata(providers []ProviderInfo, runnerId string, updatedAt string, uptime int32) *RunnerMetadata { + this := RunnerMetadata{} + this.Providers = providers + this.RunnerId = runnerId + this.UpdatedAt = updatedAt + this.Uptime = uptime + return &this +} + +// NewRunnerMetadataWithDefaults instantiates a new RunnerMetadata object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRunnerMetadataWithDefaults() *RunnerMetadata { + this := RunnerMetadata{} + return &this +} + +// GetProviders returns the Providers field value +func (o *RunnerMetadata) GetProviders() []ProviderInfo { + if o == nil { + var ret []ProviderInfo + return ret + } + + return o.Providers +} + +// GetProvidersOk returns a tuple with the Providers field value +// and a boolean to check if the value has been set. +func (o *RunnerMetadata) GetProvidersOk() ([]ProviderInfo, bool) { + if o == nil { + return nil, false + } + return o.Providers, true +} + +// SetProviders sets field value +func (o *RunnerMetadata) SetProviders(v []ProviderInfo) { + o.Providers = v +} + +// GetRunnerId returns the RunnerId field value +func (o *RunnerMetadata) GetRunnerId() string { + if o == nil { + var ret string + return ret + } + + return o.RunnerId +} + +// GetRunnerIdOk returns a tuple with the RunnerId field value +// and a boolean to check if the value has been set. +func (o *RunnerMetadata) GetRunnerIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.RunnerId, true +} + +// SetRunnerId sets field value +func (o *RunnerMetadata) SetRunnerId(v string) { + o.RunnerId = v +} + +// GetRunningJobs returns the RunningJobs field value if set, zero value otherwise. +func (o *RunnerMetadata) GetRunningJobs() int32 { + if o == nil || IsNil(o.RunningJobs) { + var ret int32 + return ret + } + return *o.RunningJobs +} + +// GetRunningJobsOk returns a tuple with the RunningJobs field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RunnerMetadata) GetRunningJobsOk() (*int32, bool) { + if o == nil || IsNil(o.RunningJobs) { + return nil, false + } + return o.RunningJobs, true +} + +// HasRunningJobs returns a boolean if a field has been set. +func (o *RunnerMetadata) HasRunningJobs() bool { + if o != nil && !IsNil(o.RunningJobs) { + return true + } + + return false +} + +// SetRunningJobs gets a reference to the given int32 and assigns it to the RunningJobs field. +func (o *RunnerMetadata) SetRunningJobs(v int32) { + o.RunningJobs = &v +} + +// GetUpdatedAt returns the UpdatedAt field value +func (o *RunnerMetadata) GetUpdatedAt() string { + if o == nil { + var ret string + return ret + } + + return o.UpdatedAt +} + +// GetUpdatedAtOk returns a tuple with the UpdatedAt field value +// and a boolean to check if the value has been set. +func (o *RunnerMetadata) GetUpdatedAtOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.UpdatedAt, true +} + +// SetUpdatedAt sets field value +func (o *RunnerMetadata) SetUpdatedAt(v string) { + o.UpdatedAt = v +} + +// GetUptime returns the Uptime field value +func (o *RunnerMetadata) GetUptime() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Uptime +} + +// GetUptimeOk returns a tuple with the Uptime field value +// and a boolean to check if the value has been set. +func (o *RunnerMetadata) GetUptimeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Uptime, true +} + +// SetUptime sets field value +func (o *RunnerMetadata) SetUptime(v int32) { + o.Uptime = v +} + +func (o RunnerMetadata) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RunnerMetadata) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["providers"] = o.Providers + toSerialize["runnerId"] = o.RunnerId + if !IsNil(o.RunningJobs) { + toSerialize["runningJobs"] = o.RunningJobs + } + toSerialize["updatedAt"] = o.UpdatedAt + toSerialize["uptime"] = o.Uptime + return toSerialize, nil +} + +func (o *RunnerMetadata) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "providers", + "runnerId", + "updatedAt", + "uptime", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varRunnerMetadata := _RunnerMetadata{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varRunnerMetadata) + + if err != nil { + return err + } + + *o = RunnerMetadata(varRunnerMetadata) + + return err +} + +type NullableRunnerMetadata struct { + value *RunnerMetadata + isSet bool +} + +func (v NullableRunnerMetadata) Get() *RunnerMetadata { + return v.value +} + +func (v *NullableRunnerMetadata) Set(val *RunnerMetadata) { + v.value = val + v.isSet = true +} + +func (v NullableRunnerMetadata) IsSet() bool { + return v.isSet +} + +func (v *NullableRunnerMetadata) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRunnerMetadata(val *RunnerMetadata) *NullableRunnerMetadata { + return &NullableRunnerMetadata{value: val, isSet: true} +} + +func (v NullableRunnerMetadata) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRunnerMetadata) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_server_config.go b/pkg/apiclient/model_server_config.go index bd30e9e1bc..a0104dd64c 100644 --- a/pkg/apiclient/model_server_config.go +++ b/pkg/apiclient/model_server_config.go @@ -33,8 +33,8 @@ type ServerConfig struct { Id string `json:"id"` LocalBuilderRegistryImage string `json:"localBuilderRegistryImage"` LocalBuilderRegistryPort int32 `json:"localBuilderRegistryPort"` + LocalRunnerDisabled *bool `json:"localRunnerDisabled,omitempty"` LogFile LogFileConfig `json:"logFile"` - ProvidersDir string `json:"providersDir"` RegistryUrl string `json:"registryUrl"` SamplesIndexUrl *string `json:"samplesIndexUrl,omitempty"` ServerDownloadUrl string `json:"serverDownloadUrl"` @@ -46,7 +46,7 @@ type _ServerConfig ServerConfig // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultWorkspaceImage string, defaultWorkspaceUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, providersDir string, registryUrl string, serverDownloadUrl string) *ServerConfig { +func NewServerConfig(apiPort int32, binariesPath string, builderImage string, builderRegistryServer string, defaultWorkspaceImage string, defaultWorkspaceUser string, headscalePort int32, id string, localBuilderRegistryImage string, localBuilderRegistryPort int32, logFile LogFileConfig, registryUrl string, serverDownloadUrl string) *ServerConfig { this := ServerConfig{} this.ApiPort = apiPort this.BinariesPath = binariesPath @@ -59,7 +59,6 @@ func NewServerConfig(apiPort int32, binariesPath string, builderImage string, bu this.LocalBuilderRegistryImage = localBuilderRegistryImage this.LocalBuilderRegistryPort = localBuilderRegistryPort this.LogFile = logFile - this.ProvidersDir = providersDir this.RegistryUrl = registryUrl this.ServerDownloadUrl = serverDownloadUrl return &this @@ -377,52 +376,60 @@ func (o *ServerConfig) SetLocalBuilderRegistryPort(v int32) { o.LocalBuilderRegistryPort = v } -// GetLogFile returns the LogFile field value -func (o *ServerConfig) GetLogFile() LogFileConfig { - if o == nil { - var ret LogFileConfig +// GetLocalRunnerDisabled returns the LocalRunnerDisabled field value if set, zero value otherwise. +func (o *ServerConfig) GetLocalRunnerDisabled() bool { + if o == nil || IsNil(o.LocalRunnerDisabled) { + var ret bool return ret } - - return o.LogFile + return *o.LocalRunnerDisabled } -// GetLogFileOk returns a tuple with the LogFile field value +// GetLocalRunnerDisabledOk returns a tuple with the LocalRunnerDisabled field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *ServerConfig) GetLogFileOk() (*LogFileConfig, bool) { - if o == nil { +func (o *ServerConfig) GetLocalRunnerDisabledOk() (*bool, bool) { + if o == nil || IsNil(o.LocalRunnerDisabled) { return nil, false } - return &o.LogFile, true + return o.LocalRunnerDisabled, true } -// SetLogFile sets field value -func (o *ServerConfig) SetLogFile(v LogFileConfig) { - o.LogFile = v +// HasLocalRunnerDisabled returns a boolean if a field has been set. +func (o *ServerConfig) HasLocalRunnerDisabled() bool { + if o != nil && !IsNil(o.LocalRunnerDisabled) { + return true + } + + return false +} + +// SetLocalRunnerDisabled gets a reference to the given bool and assigns it to the LocalRunnerDisabled field. +func (o *ServerConfig) SetLocalRunnerDisabled(v bool) { + o.LocalRunnerDisabled = &v } -// GetProvidersDir returns the ProvidersDir field value -func (o *ServerConfig) GetProvidersDir() string { +// GetLogFile returns the LogFile field value +func (o *ServerConfig) GetLogFile() LogFileConfig { if o == nil { - var ret string + var ret LogFileConfig return ret } - return o.ProvidersDir + return o.LogFile } -// GetProvidersDirOk returns a tuple with the ProvidersDir field value +// GetLogFileOk returns a tuple with the LogFile field value // and a boolean to check if the value has been set. -func (o *ServerConfig) GetProvidersDirOk() (*string, bool) { +func (o *ServerConfig) GetLogFileOk() (*LogFileConfig, bool) { if o == nil { return nil, false } - return &o.ProvidersDir, true + return &o.LogFile, true } -// SetProvidersDir sets field value -func (o *ServerConfig) SetProvidersDir(v string) { - o.ProvidersDir = v +// SetLogFile sets field value +func (o *ServerConfig) SetLogFile(v LogFileConfig) { + o.LogFile = v } // GetRegistryUrl returns the RegistryUrl field value @@ -531,8 +538,10 @@ func (o ServerConfig) ToMap() (map[string]interface{}, error) { toSerialize["id"] = o.Id toSerialize["localBuilderRegistryImage"] = o.LocalBuilderRegistryImage toSerialize["localBuilderRegistryPort"] = o.LocalBuilderRegistryPort + if !IsNil(o.LocalRunnerDisabled) { + toSerialize["localRunnerDisabled"] = o.LocalRunnerDisabled + } toSerialize["logFile"] = o.LogFile - toSerialize["providersDir"] = o.ProvidersDir toSerialize["registryUrl"] = o.RegistryUrl if !IsNil(o.SamplesIndexUrl) { toSerialize["samplesIndexUrl"] = o.SamplesIndexUrl @@ -557,7 +566,6 @@ func (o *ServerConfig) UnmarshalJSON(data []byte) (err error) { "localBuilderRegistryImage", "localBuilderRegistryPort", "logFile", - "providersDir", "registryUrl", "serverDownloadUrl", } diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index f4b43698e7..325c61bf50 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -21,15 +21,16 @@ var _ MappedNullable = &Target{} // Target struct for Target type Target struct { - Default bool `json:"default"` - EnvVars map[string]string `json:"envVars"` - Id string `json:"id"` - LastJob *Job `json:"lastJob,omitempty"` - Metadata *TargetMetadata `json:"metadata,omitempty"` - Name string `json:"name"` - TargetConfig TargetConfig `json:"targetConfig"` - TargetConfigId string `json:"targetConfigId"` - Workspaces []Workspace `json:"workspaces"` + Default bool `json:"default"` + EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *TargetMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + ProviderMetadata *string `json:"providerMetadata,omitempty"` + TargetConfig TargetConfig `json:"targetConfig"` + TargetConfigId string `json:"targetConfigId"` + Workspaces []Workspace `json:"workspaces"` } type _Target Target @@ -218,6 +219,38 @@ func (o *Target) SetName(v string) { o.Name = v } +// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. +func (o *Target) GetProviderMetadata() string { + if o == nil || IsNil(o.ProviderMetadata) { + var ret string + return ret + } + return *o.ProviderMetadata +} + +// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Target) GetProviderMetadataOk() (*string, bool) { + if o == nil || IsNil(o.ProviderMetadata) { + return nil, false + } + return o.ProviderMetadata, true +} + +// HasProviderMetadata returns a boolean if a field has been set. +func (o *Target) HasProviderMetadata() bool { + if o != nil && !IsNil(o.ProviderMetadata) { + return true + } + + return false +} + +// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. +func (o *Target) SetProviderMetadata(v string) { + o.ProviderMetadata = &v +} + // GetTargetConfig returns the TargetConfig field value func (o *Target) GetTargetConfig() TargetConfig { if o == nil { @@ -310,6 +343,9 @@ func (o Target) ToMap() (map[string]interface{}, error) { toSerialize["metadata"] = o.Metadata } toSerialize["name"] = o.Name + if !IsNil(o.ProviderMetadata) { + toSerialize["providerMetadata"] = o.ProviderMetadata + } toSerialize["targetConfig"] = o.TargetConfig toSerialize["targetConfigId"] = o.TargetConfigId toSerialize["workspaces"] = o.Workspaces diff --git a/pkg/apiclient/model_target_config.go b/pkg/apiclient/model_target_config.go index 40dff22f24..99c639126c 100644 --- a/pkg/apiclient/model_target_config.go +++ b/pkg/apiclient/model_target_config.go @@ -25,8 +25,8 @@ type TargetConfig struct { Id string `json:"id"` Name string `json:"name"` // JSON encoded map of options - Options string `json:"options"` - ProviderInfo TargetProviderInfo `json:"providerInfo"` + Options string `json:"options"` + ProviderInfo ProviderInfo `json:"providerInfo"` } type _TargetConfig TargetConfig @@ -35,7 +35,7 @@ type _TargetConfig TargetConfig // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewTargetConfig(deleted bool, id string, name string, options string, providerInfo TargetProviderInfo) *TargetConfig { +func NewTargetConfig(deleted bool, id string, name string, options string, providerInfo ProviderInfo) *TargetConfig { this := TargetConfig{} this.Deleted = deleted this.Id = id @@ -150,9 +150,9 @@ func (o *TargetConfig) SetOptions(v string) { } // GetProviderInfo returns the ProviderInfo field value -func (o *TargetConfig) GetProviderInfo() TargetProviderInfo { +func (o *TargetConfig) GetProviderInfo() ProviderInfo { if o == nil { - var ret TargetProviderInfo + var ret ProviderInfo return ret } @@ -161,7 +161,7 @@ func (o *TargetConfig) GetProviderInfo() TargetProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *TargetConfig) GetProviderInfoOk() (*TargetProviderInfo, bool) { +func (o *TargetConfig) GetProviderInfoOk() (*ProviderInfo, bool) { if o == nil { return nil, false } @@ -169,7 +169,7 @@ func (o *TargetConfig) GetProviderInfoOk() (*TargetProviderInfo, bool) { } // SetProviderInfo sets field value -func (o *TargetConfig) SetProviderInfo(v TargetProviderInfo) { +func (o *TargetConfig) SetProviderInfo(v ProviderInfo) { o.ProviderInfo = v } diff --git a/pkg/apiclient/model_target_config_property.go b/pkg/apiclient/model_target_config_property.go index 3a7b4e6ea3..a341a887bb 100644 --- a/pkg/apiclient/model_target_config_property.go +++ b/pkg/apiclient/model_target_config_property.go @@ -29,8 +29,8 @@ type TargetConfigProperty struct { // Options is only used if the Type is TargetConfigPropertyTypeOption Options []string `json:"options,omitempty"` // Suggestions is an optional list of auto-complete values to assist the user while filling the field - Suggestions []string `json:"suggestions,omitempty"` - Type *ProviderTargetConfigPropertyType `json:"type,omitempty"` + Suggestions []string `json:"suggestions,omitempty"` + Type *ModelsTargetConfigPropertyType `json:"type,omitempty"` } // NewTargetConfigProperty instantiates a new TargetConfigProperty object @@ -243,9 +243,9 @@ func (o *TargetConfigProperty) SetSuggestions(v []string) { } // GetType returns the Type field value if set, zero value otherwise. -func (o *TargetConfigProperty) GetType() ProviderTargetConfigPropertyType { +func (o *TargetConfigProperty) GetType() ModelsTargetConfigPropertyType { if o == nil || IsNil(o.Type) { - var ret ProviderTargetConfigPropertyType + var ret ModelsTargetConfigPropertyType return ret } return *o.Type @@ -253,7 +253,7 @@ func (o *TargetConfigProperty) GetType() ProviderTargetConfigPropertyType { // GetTypeOk returns a tuple with the Type field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *TargetConfigProperty) GetTypeOk() (*ProviderTargetConfigPropertyType, bool) { +func (o *TargetConfigProperty) GetTypeOk() (*ModelsTargetConfigPropertyType, bool) { if o == nil || IsNil(o.Type) { return nil, false } @@ -269,8 +269,8 @@ func (o *TargetConfigProperty) HasType() bool { return false } -// SetType gets a reference to the given ProviderTargetConfigPropertyType and assigns it to the Type field. -func (o *TargetConfigProperty) SetType(v ProviderTargetConfigPropertyType) { +// SetType gets a reference to the given ModelsTargetConfigPropertyType and assigns it to the Type field. +func (o *TargetConfigProperty) SetType(v ModelsTargetConfigPropertyType) { o.Type = &v } diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 1594473a28..6bcf3f050a 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -21,17 +21,17 @@ var _ MappedNullable = &TargetDTO{} // TargetDTO struct for TargetDTO type TargetDTO struct { - Default bool `json:"default"` - EnvVars map[string]string `json:"envVars"` - Id string `json:"id"` - Info *TargetInfo `json:"info,omitempty"` - LastJob *Job `json:"lastJob,omitempty"` - Metadata *TargetMetadata `json:"metadata,omitempty"` - Name string `json:"name"` - State ResourceState `json:"state"` - TargetConfig TargetConfig `json:"targetConfig"` - TargetConfigId string `json:"targetConfigId"` - Workspaces []Workspace `json:"workspaces"` + Default bool `json:"default"` + EnvVars map[string]string `json:"envVars"` + Id string `json:"id"` + LastJob *Job `json:"lastJob,omitempty"` + Metadata *TargetMetadata `json:"metadata,omitempty"` + Name string `json:"name"` + ProviderMetadata *string `json:"providerMetadata,omitempty"` + State ResourceState `json:"state"` + TargetConfig TargetConfig `json:"targetConfig"` + TargetConfigId string `json:"targetConfigId"` + Workspaces []Workspace `json:"workspaces"` } type _TargetDTO TargetDTO @@ -133,38 +133,6 @@ func (o *TargetDTO) SetId(v string) { o.Id = v } -// GetInfo returns the Info field value if set, zero value otherwise. -func (o *TargetDTO) GetInfo() TargetInfo { - if o == nil || IsNil(o.Info) { - var ret TargetInfo - return ret - } - return *o.Info -} - -// GetInfoOk returns a tuple with the Info field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *TargetDTO) GetInfoOk() (*TargetInfo, bool) { - if o == nil || IsNil(o.Info) { - return nil, false - } - return o.Info, true -} - -// HasInfo returns a boolean if a field has been set. -func (o *TargetDTO) HasInfo() bool { - if o != nil && !IsNil(o.Info) { - return true - } - - return false -} - -// SetInfo gets a reference to the given TargetInfo and assigns it to the Info field. -func (o *TargetDTO) SetInfo(v TargetInfo) { - o.Info = &v -} - // GetLastJob returns the LastJob field value if set, zero value otherwise. func (o *TargetDTO) GetLastJob() Job { if o == nil || IsNil(o.LastJob) { @@ -253,6 +221,38 @@ func (o *TargetDTO) SetName(v string) { o.Name = v } +// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. +func (o *TargetDTO) GetProviderMetadata() string { + if o == nil || IsNil(o.ProviderMetadata) { + var ret string + return ret + } + return *o.ProviderMetadata +} + +// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetProviderMetadataOk() (*string, bool) { + if o == nil || IsNil(o.ProviderMetadata) { + return nil, false + } + return o.ProviderMetadata, true +} + +// HasProviderMetadata returns a boolean if a field has been set. +func (o *TargetDTO) HasProviderMetadata() bool { + if o != nil && !IsNil(o.ProviderMetadata) { + return true + } + + return false +} + +// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. +func (o *TargetDTO) SetProviderMetadata(v string) { + o.ProviderMetadata = &v +} + // GetState returns the State field value func (o *TargetDTO) GetState() ResourceState { if o == nil { @@ -362,9 +362,6 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["default"] = o.Default toSerialize["envVars"] = o.EnvVars toSerialize["id"] = o.Id - if !IsNil(o.Info) { - toSerialize["info"] = o.Info - } if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } @@ -372,6 +369,9 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { toSerialize["metadata"] = o.Metadata } toSerialize["name"] = o.Name + if !IsNil(o.ProviderMetadata) { + toSerialize["providerMetadata"] = o.ProviderMetadata + } toSerialize["state"] = o.State toSerialize["targetConfig"] = o.TargetConfig toSerialize["targetConfigId"] = o.TargetConfigId diff --git a/pkg/apiclient/model_target_info.go b/pkg/apiclient/model_target_info.go deleted file mode 100644 index 834c6a23d9..0000000000 --- a/pkg/apiclient/model_target_info.go +++ /dev/null @@ -1,192 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "encoding/json" - "fmt" -) - -// checks if the TargetInfo type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &TargetInfo{} - -// TargetInfo struct for TargetInfo -type TargetInfo struct { - Name string `json:"name"` - ProviderMetadata *string `json:"providerMetadata,omitempty"` -} - -type _TargetInfo TargetInfo - -// NewTargetInfo instantiates a new TargetInfo object -// This constructor will assign default values to properties that have it defined, -// and makes sure properties required by API are set, but the set of arguments -// will change when the set of required properties is changed -func NewTargetInfo(name string) *TargetInfo { - this := TargetInfo{} - this.Name = name - return &this -} - -// NewTargetInfoWithDefaults instantiates a new TargetInfo object -// This constructor will only assign default values to properties that have it defined, -// but it doesn't guarantee that properties required by API are set -func NewTargetInfoWithDefaults() *TargetInfo { - this := TargetInfo{} - return &this -} - -// GetName returns the Name field value -func (o *TargetInfo) GetName() string { - if o == nil { - var ret string - return ret - } - - return o.Name -} - -// GetNameOk returns a tuple with the Name field value -// and a boolean to check if the value has been set. -func (o *TargetInfo) GetNameOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Name, true -} - -// SetName sets field value -func (o *TargetInfo) SetName(v string) { - o.Name = v -} - -// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. -func (o *TargetInfo) GetProviderMetadata() string { - if o == nil || IsNil(o.ProviderMetadata) { - var ret string - return ret - } - return *o.ProviderMetadata -} - -// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *TargetInfo) GetProviderMetadataOk() (*string, bool) { - if o == nil || IsNil(o.ProviderMetadata) { - return nil, false - } - return o.ProviderMetadata, true -} - -// HasProviderMetadata returns a boolean if a field has been set. -func (o *TargetInfo) HasProviderMetadata() bool { - if o != nil && !IsNil(o.ProviderMetadata) { - return true - } - - return false -} - -// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. -func (o *TargetInfo) SetProviderMetadata(v string) { - o.ProviderMetadata = &v -} - -func (o TargetInfo) MarshalJSON() ([]byte, error) { - toSerialize, err := o.ToMap() - if err != nil { - return []byte{}, err - } - return json.Marshal(toSerialize) -} - -func (o TargetInfo) ToMap() (map[string]interface{}, error) { - toSerialize := map[string]interface{}{} - toSerialize["name"] = o.Name - if !IsNil(o.ProviderMetadata) { - toSerialize["providerMetadata"] = o.ProviderMetadata - } - return toSerialize, nil -} - -func (o *TargetInfo) UnmarshalJSON(data []byte) (err error) { - // This validates that all required properties are included in the JSON object - // by unmarshalling the object into a generic map with string keys and checking - // that every required field exists as a key in the generic map. - requiredProperties := []string{ - "name", - } - - allProperties := make(map[string]interface{}) - - err = json.Unmarshal(data, &allProperties) - - if err != nil { - return err - } - - for _, requiredProperty := range requiredProperties { - if _, exists := allProperties[requiredProperty]; !exists { - return fmt.Errorf("no value given for required property %v", requiredProperty) - } - } - - varTargetInfo := _TargetInfo{} - - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(&varTargetInfo) - - if err != nil { - return err - } - - *o = TargetInfo(varTargetInfo) - - return err -} - -type NullableTargetInfo struct { - value *TargetInfo - isSet bool -} - -func (v NullableTargetInfo) Get() *TargetInfo { - return v.value -} - -func (v *NullableTargetInfo) Set(val *TargetInfo) { - v.value = val - v.isSet = true -} - -func (v NullableTargetInfo) IsSet() bool { - return v.isSet -} - -func (v *NullableTargetInfo) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableTargetInfo(val *TargetInfo) *NullableTargetInfo { - return &NullableTargetInfo{value: val, isSet: true} -} - -func (v NullableTargetInfo) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableTargetInfo) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_target_provider_info.go b/pkg/apiclient/model_target_provider_info.go deleted file mode 100644 index 68c3f685fe..0000000000 --- a/pkg/apiclient/model_target_provider_info.go +++ /dev/null @@ -1,256 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "encoding/json" - "fmt" -) - -// checks if the TargetProviderInfo type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &TargetProviderInfo{} - -// TargetProviderInfo struct for TargetProviderInfo -type TargetProviderInfo struct { - AgentlessTarget *bool `json:"agentlessTarget,omitempty"` - Label *string `json:"label,omitempty"` - Name string `json:"name"` - Version string `json:"version"` -} - -type _TargetProviderInfo TargetProviderInfo - -// NewTargetProviderInfo instantiates a new TargetProviderInfo object -// This constructor will assign default values to properties that have it defined, -// and makes sure properties required by API are set, but the set of arguments -// will change when the set of required properties is changed -func NewTargetProviderInfo(name string, version string) *TargetProviderInfo { - this := TargetProviderInfo{} - this.Name = name - this.Version = version - return &this -} - -// NewTargetProviderInfoWithDefaults instantiates a new TargetProviderInfo object -// This constructor will only assign default values to properties that have it defined, -// but it doesn't guarantee that properties required by API are set -func NewTargetProviderInfoWithDefaults() *TargetProviderInfo { - this := TargetProviderInfo{} - return &this -} - -// GetAgentlessTarget returns the AgentlessTarget field value if set, zero value otherwise. -func (o *TargetProviderInfo) GetAgentlessTarget() bool { - if o == nil || IsNil(o.AgentlessTarget) { - var ret bool - return ret - } - return *o.AgentlessTarget -} - -// GetAgentlessTargetOk returns a tuple with the AgentlessTarget field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *TargetProviderInfo) GetAgentlessTargetOk() (*bool, bool) { - if o == nil || IsNil(o.AgentlessTarget) { - return nil, false - } - return o.AgentlessTarget, true -} - -// HasAgentlessTarget returns a boolean if a field has been set. -func (o *TargetProviderInfo) HasAgentlessTarget() bool { - if o != nil && !IsNil(o.AgentlessTarget) { - return true - } - - return false -} - -// SetAgentlessTarget gets a reference to the given bool and assigns it to the AgentlessTarget field. -func (o *TargetProviderInfo) SetAgentlessTarget(v bool) { - o.AgentlessTarget = &v -} - -// GetLabel returns the Label field value if set, zero value otherwise. -func (o *TargetProviderInfo) GetLabel() string { - if o == nil || IsNil(o.Label) { - var ret string - return ret - } - return *o.Label -} - -// GetLabelOk returns a tuple with the Label field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *TargetProviderInfo) GetLabelOk() (*string, bool) { - if o == nil || IsNil(o.Label) { - return nil, false - } - return o.Label, true -} - -// HasLabel returns a boolean if a field has been set. -func (o *TargetProviderInfo) HasLabel() bool { - if o != nil && !IsNil(o.Label) { - return true - } - - return false -} - -// SetLabel gets a reference to the given string and assigns it to the Label field. -func (o *TargetProviderInfo) SetLabel(v string) { - o.Label = &v -} - -// GetName returns the Name field value -func (o *TargetProviderInfo) GetName() string { - if o == nil { - var ret string - return ret - } - - return o.Name -} - -// GetNameOk returns a tuple with the Name field value -// and a boolean to check if the value has been set. -func (o *TargetProviderInfo) GetNameOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Name, true -} - -// SetName sets field value -func (o *TargetProviderInfo) SetName(v string) { - o.Name = v -} - -// GetVersion returns the Version field value -func (o *TargetProviderInfo) GetVersion() string { - if o == nil { - var ret string - return ret - } - - return o.Version -} - -// GetVersionOk returns a tuple with the Version field value -// and a boolean to check if the value has been set. -func (o *TargetProviderInfo) GetVersionOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Version, true -} - -// SetVersion sets field value -func (o *TargetProviderInfo) SetVersion(v string) { - o.Version = v -} - -func (o TargetProviderInfo) MarshalJSON() ([]byte, error) { - toSerialize, err := o.ToMap() - if err != nil { - return []byte{}, err - } - return json.Marshal(toSerialize) -} - -func (o TargetProviderInfo) ToMap() (map[string]interface{}, error) { - toSerialize := map[string]interface{}{} - if !IsNil(o.AgentlessTarget) { - toSerialize["agentlessTarget"] = o.AgentlessTarget - } - if !IsNil(o.Label) { - toSerialize["label"] = o.Label - } - toSerialize["name"] = o.Name - toSerialize["version"] = o.Version - return toSerialize, nil -} - -func (o *TargetProviderInfo) UnmarshalJSON(data []byte) (err error) { - // This validates that all required properties are included in the JSON object - // by unmarshalling the object into a generic map with string keys and checking - // that every required field exists as a key in the generic map. - requiredProperties := []string{ - "name", - "version", - } - - allProperties := make(map[string]interface{}) - - err = json.Unmarshal(data, &allProperties) - - if err != nil { - return err - } - - for _, requiredProperty := range requiredProperties { - if _, exists := allProperties[requiredProperty]; !exists { - return fmt.Errorf("no value given for required property %v", requiredProperty) - } - } - - varTargetProviderInfo := _TargetProviderInfo{} - - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(&varTargetProviderInfo) - - if err != nil { - return err - } - - *o = TargetProviderInfo(varTargetProviderInfo) - - return err -} - -type NullableTargetProviderInfo struct { - value *TargetProviderInfo - isSet bool -} - -func (v NullableTargetProviderInfo) Get() *TargetProviderInfo { - return v.value -} - -func (v *NullableTargetProviderInfo) Set(val *TargetProviderInfo) { - v.value = val - v.isSet = true -} - -func (v NullableTargetProviderInfo) IsSet() bool { - return v.isSet -} - -func (v *NullableTargetProviderInfo) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableTargetProviderInfo(val *TargetProviderInfo) *NullableTargetProviderInfo { - return &NullableTargetProviderInfo{value: val, isSet: true} -} - -func (v NullableTargetProviderInfo) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableTargetProviderInfo) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/apiclient/model_update_job_state.go b/pkg/apiclient/model_update_job_state.go new file mode 100644 index 0000000000..87d667a09f --- /dev/null +++ b/pkg/apiclient/model_update_job_state.go @@ -0,0 +1,192 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the UpdateJobState type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateJobState{} + +// UpdateJobState struct for UpdateJobState +type UpdateJobState struct { + ErrorMessage *string `json:"errorMessage,omitempty"` + State JobState `json:"state"` +} + +type _UpdateJobState UpdateJobState + +// NewUpdateJobState instantiates a new UpdateJobState object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUpdateJobState(state JobState) *UpdateJobState { + this := UpdateJobState{} + this.State = state + return &this +} + +// NewUpdateJobStateWithDefaults instantiates a new UpdateJobState object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUpdateJobStateWithDefaults() *UpdateJobState { + this := UpdateJobState{} + return &this +} + +// GetErrorMessage returns the ErrorMessage field value if set, zero value otherwise. +func (o *UpdateJobState) GetErrorMessage() string { + if o == nil || IsNil(o.ErrorMessage) { + var ret string + return ret + } + return *o.ErrorMessage +} + +// GetErrorMessageOk returns a tuple with the ErrorMessage field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UpdateJobState) GetErrorMessageOk() (*string, bool) { + if o == nil || IsNil(o.ErrorMessage) { + return nil, false + } + return o.ErrorMessage, true +} + +// HasErrorMessage returns a boolean if a field has been set. +func (o *UpdateJobState) HasErrorMessage() bool { + if o != nil && !IsNil(o.ErrorMessage) { + return true + } + + return false +} + +// SetErrorMessage gets a reference to the given string and assigns it to the ErrorMessage field. +func (o *UpdateJobState) SetErrorMessage(v string) { + o.ErrorMessage = &v +} + +// GetState returns the State field value +func (o *UpdateJobState) GetState() JobState { + if o == nil { + var ret JobState + return ret + } + + return o.State +} + +// GetStateOk returns a tuple with the State field value +// and a boolean to check if the value has been set. +func (o *UpdateJobState) GetStateOk() (*JobState, bool) { + if o == nil { + return nil, false + } + return &o.State, true +} + +// SetState sets field value +func (o *UpdateJobState) SetState(v JobState) { + o.State = v +} + +func (o UpdateJobState) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o UpdateJobState) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.ErrorMessage) { + toSerialize["errorMessage"] = o.ErrorMessage + } + toSerialize["state"] = o.State + return toSerialize, nil +} + +func (o *UpdateJobState) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "state", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varUpdateJobState := _UpdateJobState{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varUpdateJobState) + + if err != nil { + return err + } + + *o = UpdateJobState(varUpdateJobState) + + return err +} + +type NullableUpdateJobState struct { + value *UpdateJobState + isSet bool +} + +func (v NullableUpdateJobState) Get() *UpdateJobState { + return v.value +} + +func (v *NullableUpdateJobState) Set(val *UpdateJobState) { + v.value = val + v.isSet = true +} + +func (v NullableUpdateJobState) IsSet() bool { + return v.isSet +} + +func (v *NullableUpdateJobState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUpdateJobState(val *UpdateJobState) *NullableUpdateJobState { + return &NullableUpdateJobState{value: val, isSet: true} +} + +func (v NullableUpdateJobState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUpdateJobState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_update_runner_metadata_dto.go b/pkg/apiclient/model_update_runner_metadata_dto.go new file mode 100644 index 0000000000..0e3446e401 --- /dev/null +++ b/pkg/apiclient/model_update_runner_metadata_dto.go @@ -0,0 +1,220 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the UpdateRunnerMetadataDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateRunnerMetadataDTO{} + +// UpdateRunnerMetadataDTO struct for UpdateRunnerMetadataDTO +type UpdateRunnerMetadataDTO struct { + Providers []ProviderInfo `json:"providers"` + RunningJobs *int32 `json:"runningJobs,omitempty"` + Uptime int32 `json:"uptime"` +} + +type _UpdateRunnerMetadataDTO UpdateRunnerMetadataDTO + +// NewUpdateRunnerMetadataDTO instantiates a new UpdateRunnerMetadataDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUpdateRunnerMetadataDTO(providers []ProviderInfo, uptime int32) *UpdateRunnerMetadataDTO { + this := UpdateRunnerMetadataDTO{} + this.Providers = providers + this.Uptime = uptime + return &this +} + +// NewUpdateRunnerMetadataDTOWithDefaults instantiates a new UpdateRunnerMetadataDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUpdateRunnerMetadataDTOWithDefaults() *UpdateRunnerMetadataDTO { + this := UpdateRunnerMetadataDTO{} + return &this +} + +// GetProviders returns the Providers field value +func (o *UpdateRunnerMetadataDTO) GetProviders() []ProviderInfo { + if o == nil { + var ret []ProviderInfo + return ret + } + + return o.Providers +} + +// GetProvidersOk returns a tuple with the Providers field value +// and a boolean to check if the value has been set. +func (o *UpdateRunnerMetadataDTO) GetProvidersOk() ([]ProviderInfo, bool) { + if o == nil { + return nil, false + } + return o.Providers, true +} + +// SetProviders sets field value +func (o *UpdateRunnerMetadataDTO) SetProviders(v []ProviderInfo) { + o.Providers = v +} + +// GetRunningJobs returns the RunningJobs field value if set, zero value otherwise. +func (o *UpdateRunnerMetadataDTO) GetRunningJobs() int32 { + if o == nil || IsNil(o.RunningJobs) { + var ret int32 + return ret + } + return *o.RunningJobs +} + +// GetRunningJobsOk returns a tuple with the RunningJobs field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UpdateRunnerMetadataDTO) GetRunningJobsOk() (*int32, bool) { + if o == nil || IsNil(o.RunningJobs) { + return nil, false + } + return o.RunningJobs, true +} + +// HasRunningJobs returns a boolean if a field has been set. +func (o *UpdateRunnerMetadataDTO) HasRunningJobs() bool { + if o != nil && !IsNil(o.RunningJobs) { + return true + } + + return false +} + +// SetRunningJobs gets a reference to the given int32 and assigns it to the RunningJobs field. +func (o *UpdateRunnerMetadataDTO) SetRunningJobs(v int32) { + o.RunningJobs = &v +} + +// GetUptime returns the Uptime field value +func (o *UpdateRunnerMetadataDTO) GetUptime() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Uptime +} + +// GetUptimeOk returns a tuple with the Uptime field value +// and a boolean to check if the value has been set. +func (o *UpdateRunnerMetadataDTO) GetUptimeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Uptime, true +} + +// SetUptime sets field value +func (o *UpdateRunnerMetadataDTO) SetUptime(v int32) { + o.Uptime = v +} + +func (o UpdateRunnerMetadataDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o UpdateRunnerMetadataDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["providers"] = o.Providers + if !IsNil(o.RunningJobs) { + toSerialize["runningJobs"] = o.RunningJobs + } + toSerialize["uptime"] = o.Uptime + return toSerialize, nil +} + +func (o *UpdateRunnerMetadataDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "providers", + "uptime", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varUpdateRunnerMetadataDTO := _UpdateRunnerMetadataDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varUpdateRunnerMetadataDTO) + + if err != nil { + return err + } + + *o = UpdateRunnerMetadataDTO(varUpdateRunnerMetadataDTO) + + return err +} + +type NullableUpdateRunnerMetadataDTO struct { + value *UpdateRunnerMetadataDTO + isSet bool +} + +func (v NullableUpdateRunnerMetadataDTO) Get() *UpdateRunnerMetadataDTO { + return v.value +} + +func (v *NullableUpdateRunnerMetadataDTO) Set(val *UpdateRunnerMetadataDTO) { + v.value = val + v.isSet = true +} + +func (v NullableUpdateRunnerMetadataDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableUpdateRunnerMetadataDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUpdateRunnerMetadataDTO(val *UpdateRunnerMetadataDTO) *NullableUpdateRunnerMetadataDTO { + return &NullableUpdateRunnerMetadataDTO{value: val, isSet: true} +} + +func (v NullableUpdateRunnerMetadataDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUpdateRunnerMetadataDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_set_target_metadata.go b/pkg/apiclient/model_update_target_metadata_dto.go similarity index 53% rename from pkg/apiclient/model_set_target_metadata.go rename to pkg/apiclient/model_update_target_metadata_dto.go index b608715103..da46e7e7c3 100644 --- a/pkg/apiclient/model_set_target_metadata.go +++ b/pkg/apiclient/model_update_target_metadata_dto.go @@ -16,36 +16,36 @@ import ( "fmt" ) -// checks if the SetTargetMetadata type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &SetTargetMetadata{} +// checks if the UpdateTargetMetadataDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateTargetMetadataDTO{} -// SetTargetMetadata struct for SetTargetMetadata -type SetTargetMetadata struct { +// UpdateTargetMetadataDTO struct for UpdateTargetMetadataDTO +type UpdateTargetMetadataDTO struct { Uptime int32 `json:"uptime"` } -type _SetTargetMetadata SetTargetMetadata +type _UpdateTargetMetadataDTO UpdateTargetMetadataDTO -// NewSetTargetMetadata instantiates a new SetTargetMetadata object +// NewUpdateTargetMetadataDTO instantiates a new UpdateTargetMetadataDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewSetTargetMetadata(uptime int32) *SetTargetMetadata { - this := SetTargetMetadata{} +func NewUpdateTargetMetadataDTO(uptime int32) *UpdateTargetMetadataDTO { + this := UpdateTargetMetadataDTO{} this.Uptime = uptime return &this } -// NewSetTargetMetadataWithDefaults instantiates a new SetTargetMetadata object +// NewUpdateTargetMetadataDTOWithDefaults instantiates a new UpdateTargetMetadataDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewSetTargetMetadataWithDefaults() *SetTargetMetadata { - this := SetTargetMetadata{} +func NewUpdateTargetMetadataDTOWithDefaults() *UpdateTargetMetadataDTO { + this := UpdateTargetMetadataDTO{} return &this } // GetUptime returns the Uptime field value -func (o *SetTargetMetadata) GetUptime() int32 { +func (o *UpdateTargetMetadataDTO) GetUptime() int32 { if o == nil { var ret int32 return ret @@ -56,7 +56,7 @@ func (o *SetTargetMetadata) GetUptime() int32 { // GetUptimeOk returns a tuple with the Uptime field value // and a boolean to check if the value has been set. -func (o *SetTargetMetadata) GetUptimeOk() (*int32, bool) { +func (o *UpdateTargetMetadataDTO) GetUptimeOk() (*int32, bool) { if o == nil { return nil, false } @@ -64,11 +64,11 @@ func (o *SetTargetMetadata) GetUptimeOk() (*int32, bool) { } // SetUptime sets field value -func (o *SetTargetMetadata) SetUptime(v int32) { +func (o *UpdateTargetMetadataDTO) SetUptime(v int32) { o.Uptime = v } -func (o SetTargetMetadata) MarshalJSON() ([]byte, error) { +func (o UpdateTargetMetadataDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -76,13 +76,13 @@ func (o SetTargetMetadata) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o SetTargetMetadata) ToMap() (map[string]interface{}, error) { +func (o UpdateTargetMetadataDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["uptime"] = o.Uptime return toSerialize, nil } -func (o *SetTargetMetadata) UnmarshalJSON(data []byte) (err error) { +func (o *UpdateTargetMetadataDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -104,53 +104,53 @@ func (o *SetTargetMetadata) UnmarshalJSON(data []byte) (err error) { } } - varSetTargetMetadata := _SetTargetMetadata{} + varUpdateTargetMetadataDTO := _UpdateTargetMetadataDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varSetTargetMetadata) + err = decoder.Decode(&varUpdateTargetMetadataDTO) if err != nil { return err } - *o = SetTargetMetadata(varSetTargetMetadata) + *o = UpdateTargetMetadataDTO(varUpdateTargetMetadataDTO) return err } -type NullableSetTargetMetadata struct { - value *SetTargetMetadata +type NullableUpdateTargetMetadataDTO struct { + value *UpdateTargetMetadataDTO isSet bool } -func (v NullableSetTargetMetadata) Get() *SetTargetMetadata { +func (v NullableUpdateTargetMetadataDTO) Get() *UpdateTargetMetadataDTO { return v.value } -func (v *NullableSetTargetMetadata) Set(val *SetTargetMetadata) { +func (v *NullableUpdateTargetMetadataDTO) Set(val *UpdateTargetMetadataDTO) { v.value = val v.isSet = true } -func (v NullableSetTargetMetadata) IsSet() bool { +func (v NullableUpdateTargetMetadataDTO) IsSet() bool { return v.isSet } -func (v *NullableSetTargetMetadata) Unset() { +func (v *NullableUpdateTargetMetadataDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableSetTargetMetadata(val *SetTargetMetadata) *NullableSetTargetMetadata { - return &NullableSetTargetMetadata{value: val, isSet: true} +func NewNullableUpdateTargetMetadataDTO(val *UpdateTargetMetadataDTO) *NullableUpdateTargetMetadataDTO { + return &NullableUpdateTargetMetadataDTO{value: val, isSet: true} } -func (v NullableSetTargetMetadata) MarshalJSON() ([]byte, error) { +func (v NullableUpdateTargetMetadataDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableSetTargetMetadata) UnmarshalJSON(src []byte) error { +func (v *NullableUpdateTargetMetadataDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_update_target_provider_metadata_dto.go b/pkg/apiclient/model_update_target_provider_metadata_dto.go new file mode 100644 index 0000000000..280accbccf --- /dev/null +++ b/pkg/apiclient/model_update_target_provider_metadata_dto.go @@ -0,0 +1,156 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the UpdateTargetProviderMetadataDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateTargetProviderMetadataDTO{} + +// UpdateTargetProviderMetadataDTO struct for UpdateTargetProviderMetadataDTO +type UpdateTargetProviderMetadataDTO struct { + Metadata string `json:"metadata"` +} + +type _UpdateTargetProviderMetadataDTO UpdateTargetProviderMetadataDTO + +// NewUpdateTargetProviderMetadataDTO instantiates a new UpdateTargetProviderMetadataDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUpdateTargetProviderMetadataDTO(metadata string) *UpdateTargetProviderMetadataDTO { + this := UpdateTargetProviderMetadataDTO{} + this.Metadata = metadata + return &this +} + +// NewUpdateTargetProviderMetadataDTOWithDefaults instantiates a new UpdateTargetProviderMetadataDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUpdateTargetProviderMetadataDTOWithDefaults() *UpdateTargetProviderMetadataDTO { + this := UpdateTargetProviderMetadataDTO{} + return &this +} + +// GetMetadata returns the Metadata field value +func (o *UpdateTargetProviderMetadataDTO) GetMetadata() string { + if o == nil { + var ret string + return ret + } + + return o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value +// and a boolean to check if the value has been set. +func (o *UpdateTargetProviderMetadataDTO) GetMetadataOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Metadata, true +} + +// SetMetadata sets field value +func (o *UpdateTargetProviderMetadataDTO) SetMetadata(v string) { + o.Metadata = v +} + +func (o UpdateTargetProviderMetadataDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o UpdateTargetProviderMetadataDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["metadata"] = o.Metadata + return toSerialize, nil +} + +func (o *UpdateTargetProviderMetadataDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "metadata", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varUpdateTargetProviderMetadataDTO := _UpdateTargetProviderMetadataDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varUpdateTargetProviderMetadataDTO) + + if err != nil { + return err + } + + *o = UpdateTargetProviderMetadataDTO(varUpdateTargetProviderMetadataDTO) + + return err +} + +type NullableUpdateTargetProviderMetadataDTO struct { + value *UpdateTargetProviderMetadataDTO + isSet bool +} + +func (v NullableUpdateTargetProviderMetadataDTO) Get() *UpdateTargetProviderMetadataDTO { + return v.value +} + +func (v *NullableUpdateTargetProviderMetadataDTO) Set(val *UpdateTargetProviderMetadataDTO) { + v.value = val + v.isSet = true +} + +func (v NullableUpdateTargetProviderMetadataDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableUpdateTargetProviderMetadataDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUpdateTargetProviderMetadataDTO(val *UpdateTargetProviderMetadataDTO) *NullableUpdateTargetProviderMetadataDTO { + return &NullableUpdateTargetProviderMetadataDTO{value: val, isSet: true} +} + +func (v NullableUpdateTargetProviderMetadataDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUpdateTargetProviderMetadataDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_set_workspace_metadata.go b/pkg/apiclient/model_update_workspace_metadata_dto.go similarity index 56% rename from pkg/apiclient/model_set_workspace_metadata.go rename to pkg/apiclient/model_update_workspace_metadata_dto.go index 17f3968544..55d663cdb3 100644 --- a/pkg/apiclient/model_set_workspace_metadata.go +++ b/pkg/apiclient/model_update_workspace_metadata_dto.go @@ -16,37 +16,37 @@ import ( "fmt" ) -// checks if the SetWorkspaceMetadata type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &SetWorkspaceMetadata{} +// checks if the UpdateWorkspaceMetadataDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateWorkspaceMetadataDTO{} -// SetWorkspaceMetadata struct for SetWorkspaceMetadata -type SetWorkspaceMetadata struct { +// UpdateWorkspaceMetadataDTO struct for UpdateWorkspaceMetadataDTO +type UpdateWorkspaceMetadataDTO struct { GitStatus *GitStatus `json:"gitStatus,omitempty"` Uptime int32 `json:"uptime"` } -type _SetWorkspaceMetadata SetWorkspaceMetadata +type _UpdateWorkspaceMetadataDTO UpdateWorkspaceMetadataDTO -// NewSetWorkspaceMetadata instantiates a new SetWorkspaceMetadata object +// NewUpdateWorkspaceMetadataDTO instantiates a new UpdateWorkspaceMetadataDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewSetWorkspaceMetadata(uptime int32) *SetWorkspaceMetadata { - this := SetWorkspaceMetadata{} +func NewUpdateWorkspaceMetadataDTO(uptime int32) *UpdateWorkspaceMetadataDTO { + this := UpdateWorkspaceMetadataDTO{} this.Uptime = uptime return &this } -// NewSetWorkspaceMetadataWithDefaults instantiates a new SetWorkspaceMetadata object +// NewUpdateWorkspaceMetadataDTOWithDefaults instantiates a new UpdateWorkspaceMetadataDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewSetWorkspaceMetadataWithDefaults() *SetWorkspaceMetadata { - this := SetWorkspaceMetadata{} +func NewUpdateWorkspaceMetadataDTOWithDefaults() *UpdateWorkspaceMetadataDTO { + this := UpdateWorkspaceMetadataDTO{} return &this } // GetGitStatus returns the GitStatus field value if set, zero value otherwise. -func (o *SetWorkspaceMetadata) GetGitStatus() GitStatus { +func (o *UpdateWorkspaceMetadataDTO) GetGitStatus() GitStatus { if o == nil || IsNil(o.GitStatus) { var ret GitStatus return ret @@ -56,7 +56,7 @@ func (o *SetWorkspaceMetadata) GetGitStatus() GitStatus { // GetGitStatusOk returns a tuple with the GitStatus field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *SetWorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool) { +func (o *UpdateWorkspaceMetadataDTO) GetGitStatusOk() (*GitStatus, bool) { if o == nil || IsNil(o.GitStatus) { return nil, false } @@ -64,7 +64,7 @@ func (o *SetWorkspaceMetadata) GetGitStatusOk() (*GitStatus, bool) { } // HasGitStatus returns a boolean if a field has been set. -func (o *SetWorkspaceMetadata) HasGitStatus() bool { +func (o *UpdateWorkspaceMetadataDTO) HasGitStatus() bool { if o != nil && !IsNil(o.GitStatus) { return true } @@ -73,12 +73,12 @@ func (o *SetWorkspaceMetadata) HasGitStatus() bool { } // SetGitStatus gets a reference to the given GitStatus and assigns it to the GitStatus field. -func (o *SetWorkspaceMetadata) SetGitStatus(v GitStatus) { +func (o *UpdateWorkspaceMetadataDTO) SetGitStatus(v GitStatus) { o.GitStatus = &v } // GetUptime returns the Uptime field value -func (o *SetWorkspaceMetadata) GetUptime() int32 { +func (o *UpdateWorkspaceMetadataDTO) GetUptime() int32 { if o == nil { var ret int32 return ret @@ -89,7 +89,7 @@ func (o *SetWorkspaceMetadata) GetUptime() int32 { // GetUptimeOk returns a tuple with the Uptime field value // and a boolean to check if the value has been set. -func (o *SetWorkspaceMetadata) GetUptimeOk() (*int32, bool) { +func (o *UpdateWorkspaceMetadataDTO) GetUptimeOk() (*int32, bool) { if o == nil { return nil, false } @@ -97,11 +97,11 @@ func (o *SetWorkspaceMetadata) GetUptimeOk() (*int32, bool) { } // SetUptime sets field value -func (o *SetWorkspaceMetadata) SetUptime(v int32) { +func (o *UpdateWorkspaceMetadataDTO) SetUptime(v int32) { o.Uptime = v } -func (o SetWorkspaceMetadata) MarshalJSON() ([]byte, error) { +func (o UpdateWorkspaceMetadataDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -109,7 +109,7 @@ func (o SetWorkspaceMetadata) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o SetWorkspaceMetadata) ToMap() (map[string]interface{}, error) { +func (o UpdateWorkspaceMetadataDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.GitStatus) { toSerialize["gitStatus"] = o.GitStatus @@ -118,7 +118,7 @@ func (o SetWorkspaceMetadata) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *SetWorkspaceMetadata) UnmarshalJSON(data []byte) (err error) { +func (o *UpdateWorkspaceMetadataDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -140,53 +140,53 @@ func (o *SetWorkspaceMetadata) UnmarshalJSON(data []byte) (err error) { } } - varSetWorkspaceMetadata := _SetWorkspaceMetadata{} + varUpdateWorkspaceMetadataDTO := _UpdateWorkspaceMetadataDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varSetWorkspaceMetadata) + err = decoder.Decode(&varUpdateWorkspaceMetadataDTO) if err != nil { return err } - *o = SetWorkspaceMetadata(varSetWorkspaceMetadata) + *o = UpdateWorkspaceMetadataDTO(varUpdateWorkspaceMetadataDTO) return err } -type NullableSetWorkspaceMetadata struct { - value *SetWorkspaceMetadata +type NullableUpdateWorkspaceMetadataDTO struct { + value *UpdateWorkspaceMetadataDTO isSet bool } -func (v NullableSetWorkspaceMetadata) Get() *SetWorkspaceMetadata { +func (v NullableUpdateWorkspaceMetadataDTO) Get() *UpdateWorkspaceMetadataDTO { return v.value } -func (v *NullableSetWorkspaceMetadata) Set(val *SetWorkspaceMetadata) { +func (v *NullableUpdateWorkspaceMetadataDTO) Set(val *UpdateWorkspaceMetadataDTO) { v.value = val v.isSet = true } -func (v NullableSetWorkspaceMetadata) IsSet() bool { +func (v NullableUpdateWorkspaceMetadataDTO) IsSet() bool { return v.isSet } -func (v *NullableSetWorkspaceMetadata) Unset() { +func (v *NullableUpdateWorkspaceMetadataDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableSetWorkspaceMetadata(val *SetWorkspaceMetadata) *NullableSetWorkspaceMetadata { - return &NullableSetWorkspaceMetadata{value: val, isSet: true} +func NewNullableUpdateWorkspaceMetadataDTO(val *UpdateWorkspaceMetadataDTO) *NullableUpdateWorkspaceMetadataDTO { + return &NullableUpdateWorkspaceMetadataDTO{value: val, isSet: true} } -func (v NullableSetWorkspaceMetadata) MarshalJSON() ([]byte, error) { +func (v NullableUpdateWorkspaceMetadataDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableSetWorkspaceMetadata) UnmarshalJSON(src []byte) error { +func (v *NullableUpdateWorkspaceMetadataDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_update_workspace_provider_metadata_dto.go b/pkg/apiclient/model_update_workspace_provider_metadata_dto.go new file mode 100644 index 0000000000..f17f720aac --- /dev/null +++ b/pkg/apiclient/model_update_workspace_provider_metadata_dto.go @@ -0,0 +1,156 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the UpdateWorkspaceProviderMetadataDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateWorkspaceProviderMetadataDTO{} + +// UpdateWorkspaceProviderMetadataDTO struct for UpdateWorkspaceProviderMetadataDTO +type UpdateWorkspaceProviderMetadataDTO struct { + Metadata string `json:"metadata"` +} + +type _UpdateWorkspaceProviderMetadataDTO UpdateWorkspaceProviderMetadataDTO + +// NewUpdateWorkspaceProviderMetadataDTO instantiates a new UpdateWorkspaceProviderMetadataDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUpdateWorkspaceProviderMetadataDTO(metadata string) *UpdateWorkspaceProviderMetadataDTO { + this := UpdateWorkspaceProviderMetadataDTO{} + this.Metadata = metadata + return &this +} + +// NewUpdateWorkspaceProviderMetadataDTOWithDefaults instantiates a new UpdateWorkspaceProviderMetadataDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUpdateWorkspaceProviderMetadataDTOWithDefaults() *UpdateWorkspaceProviderMetadataDTO { + this := UpdateWorkspaceProviderMetadataDTO{} + return &this +} + +// GetMetadata returns the Metadata field value +func (o *UpdateWorkspaceProviderMetadataDTO) GetMetadata() string { + if o == nil { + var ret string + return ret + } + + return o.Metadata +} + +// GetMetadataOk returns a tuple with the Metadata field value +// and a boolean to check if the value has been set. +func (o *UpdateWorkspaceProviderMetadataDTO) GetMetadataOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Metadata, true +} + +// SetMetadata sets field value +func (o *UpdateWorkspaceProviderMetadataDTO) SetMetadata(v string) { + o.Metadata = v +} + +func (o UpdateWorkspaceProviderMetadataDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o UpdateWorkspaceProviderMetadataDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["metadata"] = o.Metadata + return toSerialize, nil +} + +func (o *UpdateWorkspaceProviderMetadataDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "metadata", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varUpdateWorkspaceProviderMetadataDTO := _UpdateWorkspaceProviderMetadataDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varUpdateWorkspaceProviderMetadataDTO) + + if err != nil { + return err + } + + *o = UpdateWorkspaceProviderMetadataDTO(varUpdateWorkspaceProviderMetadataDTO) + + return err +} + +type NullableUpdateWorkspaceProviderMetadataDTO struct { + value *UpdateWorkspaceProviderMetadataDTO + isSet bool +} + +func (v NullableUpdateWorkspaceProviderMetadataDTO) Get() *UpdateWorkspaceProviderMetadataDTO { + return v.value +} + +func (v *NullableUpdateWorkspaceProviderMetadataDTO) Set(val *UpdateWorkspaceProviderMetadataDTO) { + v.value = val + v.isSet = true +} + +func (v NullableUpdateWorkspaceProviderMetadataDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableUpdateWorkspaceProviderMetadataDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUpdateWorkspaceProviderMetadataDTO(val *UpdateWorkspaceProviderMetadataDTO) *NullableUpdateWorkspaceProviderMetadataDTO { + return &NullableUpdateWorkspaceProviderMetadataDTO{value: val, isSet: true} +} + +func (v NullableUpdateWorkspaceProviderMetadataDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUpdateWorkspaceProviderMetadataDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_workspace.go index 9f9c374c76..c0bca449d3 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_workspace.go @@ -21,6 +21,7 @@ var _ MappedNullable = &Workspace{} // Workspace struct for Workspace type Workspace struct { + ApiKey string `json:"apiKey"` BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` @@ -29,6 +30,7 @@ type Workspace struct { LastJob *Job `json:"lastJob,omitempty"` Metadata *WorkspaceMetadata `json:"metadata,omitempty"` Name string `json:"name"` + ProviderMetadata *string `json:"providerMetadata,omitempty"` Repository GitRepository `json:"repository"` Target Target `json:"target"` TargetId string `json:"targetId"` @@ -41,8 +43,9 @@ type _Workspace Workspace // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspace(envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string) *Workspace { +func NewWorkspace(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string) *Workspace { this := Workspace{} + this.ApiKey = apiKey this.EnvVars = envVars this.Id = id this.Image = image @@ -62,6 +65,30 @@ func NewWorkspaceWithDefaults() *Workspace { return &this } +// GetApiKey returns the ApiKey field value +func (o *Workspace) GetApiKey() string { + if o == nil { + var ret string + return ret + } + + return o.ApiKey +} + +// GetApiKeyOk returns a tuple with the ApiKey field value +// and a boolean to check if the value has been set. +func (o *Workspace) GetApiKeyOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ApiKey, true +} + +// SetApiKey sets field value +func (o *Workspace) SetApiKey(v string) { + o.ApiKey = v +} + // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. func (o *Workspace) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { @@ -286,6 +313,38 @@ func (o *Workspace) SetName(v string) { o.Name = v } +// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. +func (o *Workspace) GetProviderMetadata() string { + if o == nil || IsNil(o.ProviderMetadata) { + var ret string + return ret + } + return *o.ProviderMetadata +} + +// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Workspace) GetProviderMetadataOk() (*string, bool) { + if o == nil || IsNil(o.ProviderMetadata) { + return nil, false + } + return o.ProviderMetadata, true +} + +// HasProviderMetadata returns a boolean if a field has been set. +func (o *Workspace) HasProviderMetadata() bool { + if o != nil && !IsNil(o.ProviderMetadata) { + return true + } + + return false +} + +// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. +func (o *Workspace) SetProviderMetadata(v string) { + o.ProviderMetadata = &v +} + // GetRepository returns the Repository field value func (o *Workspace) GetRepository() GitRepository { if o == nil { @@ -392,6 +451,7 @@ func (o Workspace) MarshalJSON() ([]byte, error) { func (o Workspace) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} + toSerialize["apiKey"] = o.ApiKey if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig } @@ -408,6 +468,9 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { toSerialize["metadata"] = o.Metadata } toSerialize["name"] = o.Name + if !IsNil(o.ProviderMetadata) { + toSerialize["providerMetadata"] = o.ProviderMetadata + } toSerialize["repository"] = o.Repository toSerialize["target"] = o.Target toSerialize["targetId"] = o.TargetId @@ -420,6 +483,7 @@ func (o *Workspace) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ + "apiKey", "envVars", "id", "image", diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go index 72554fcb6c..5d6a6a1e56 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_workspace_dto.go @@ -21,15 +21,16 @@ var _ MappedNullable = &WorkspaceDTO{} // WorkspaceDTO struct for WorkspaceDTO type WorkspaceDTO struct { + ApiKey string `json:"apiKey"` BuildConfig *BuildConfig `json:"buildConfig,omitempty"` EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` Id string `json:"id"` Image string `json:"image"` - Info *WorkspaceInfo `json:"info,omitempty"` LastJob *Job `json:"lastJob,omitempty"` Metadata *WorkspaceMetadata `json:"metadata,omitempty"` Name string `json:"name"` + ProviderMetadata *string `json:"providerMetadata,omitempty"` Repository GitRepository `json:"repository"` State ResourceState `json:"state"` Target Target `json:"target"` @@ -43,8 +44,9 @@ type _WorkspaceDTO WorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceDTO(envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string) *WorkspaceDTO { +func NewWorkspaceDTO(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string) *WorkspaceDTO { this := WorkspaceDTO{} + this.ApiKey = apiKey this.EnvVars = envVars this.Id = id this.Image = image @@ -65,6 +67,30 @@ func NewWorkspaceDTOWithDefaults() *WorkspaceDTO { return &this } +// GetApiKey returns the ApiKey field value +func (o *WorkspaceDTO) GetApiKey() string { + if o == nil { + var ret string + return ret + } + + return o.ApiKey +} + +// GetApiKeyOk returns a tuple with the ApiKey field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetApiKeyOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ApiKey, true +} + +// SetApiKey sets field value +func (o *WorkspaceDTO) SetApiKey(v string) { + o.ApiKey = v +} + // GetBuildConfig returns the BuildConfig field value if set, zero value otherwise. func (o *WorkspaceDTO) GetBuildConfig() BuildConfig { if o == nil || IsNil(o.BuildConfig) { @@ -201,38 +227,6 @@ func (o *WorkspaceDTO) SetImage(v string) { o.Image = v } -// GetInfo returns the Info field value if set, zero value otherwise. -func (o *WorkspaceDTO) GetInfo() WorkspaceInfo { - if o == nil || IsNil(o.Info) { - var ret WorkspaceInfo - return ret - } - return *o.Info -} - -// GetInfoOk returns a tuple with the Info field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *WorkspaceDTO) GetInfoOk() (*WorkspaceInfo, bool) { - if o == nil || IsNil(o.Info) { - return nil, false - } - return o.Info, true -} - -// HasInfo returns a boolean if a field has been set. -func (o *WorkspaceDTO) HasInfo() bool { - if o != nil && !IsNil(o.Info) { - return true - } - - return false -} - -// SetInfo gets a reference to the given WorkspaceInfo and assigns it to the Info field. -func (o *WorkspaceDTO) SetInfo(v WorkspaceInfo) { - o.Info = &v -} - // GetLastJob returns the LastJob field value if set, zero value otherwise. func (o *WorkspaceDTO) GetLastJob() Job { if o == nil || IsNil(o.LastJob) { @@ -321,6 +315,38 @@ func (o *WorkspaceDTO) SetName(v string) { o.Name = v } +// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetProviderMetadata() string { + if o == nil || IsNil(o.ProviderMetadata) { + var ret string + return ret + } + return *o.ProviderMetadata +} + +// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetProviderMetadataOk() (*string, bool) { + if o == nil || IsNil(o.ProviderMetadata) { + return nil, false + } + return o.ProviderMetadata, true +} + +// HasProviderMetadata returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasProviderMetadata() bool { + if o != nil && !IsNil(o.ProviderMetadata) { + return true + } + + return false +} + +// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. +func (o *WorkspaceDTO) SetProviderMetadata(v string) { + o.ProviderMetadata = &v +} + // GetRepository returns the Repository field value func (o *WorkspaceDTO) GetRepository() GitRepository { if o == nil { @@ -451,6 +477,7 @@ func (o WorkspaceDTO) MarshalJSON() ([]byte, error) { func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} + toSerialize["apiKey"] = o.ApiKey if !IsNil(o.BuildConfig) { toSerialize["buildConfig"] = o.BuildConfig } @@ -460,9 +487,6 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { } toSerialize["id"] = o.Id toSerialize["image"] = o.Image - if !IsNil(o.Info) { - toSerialize["info"] = o.Info - } if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } @@ -470,6 +494,9 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { toSerialize["metadata"] = o.Metadata } toSerialize["name"] = o.Name + if !IsNil(o.ProviderMetadata) { + toSerialize["providerMetadata"] = o.ProviderMetadata + } toSerialize["repository"] = o.Repository toSerialize["state"] = o.State toSerialize["target"] = o.Target @@ -483,6 +510,7 @@ func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ + "apiKey", "envVars", "id", "image", diff --git a/pkg/apiclient/model_workspace_info.go b/pkg/apiclient/model_workspace_info.go deleted file mode 100644 index 9d65cb3e74..0000000000 --- a/pkg/apiclient/model_workspace_info.go +++ /dev/null @@ -1,276 +0,0 @@ -/* -Daytona Server API - -Daytona Server API - -API version: v0.0.0-dev -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. - -package apiclient - -import ( - "bytes" - "encoding/json" - "fmt" -) - -// checks if the WorkspaceInfo type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &WorkspaceInfo{} - -// WorkspaceInfo struct for WorkspaceInfo -type WorkspaceInfo struct { - Created string `json:"created"` - IsRunning bool `json:"isRunning"` - Name string `json:"name"` - ProviderMetadata *string `json:"providerMetadata,omitempty"` - TargetId string `json:"targetId"` -} - -type _WorkspaceInfo WorkspaceInfo - -// NewWorkspaceInfo instantiates a new WorkspaceInfo object -// This constructor will assign default values to properties that have it defined, -// and makes sure properties required by API are set, but the set of arguments -// will change when the set of required properties is changed -func NewWorkspaceInfo(created string, isRunning bool, name string, targetId string) *WorkspaceInfo { - this := WorkspaceInfo{} - this.Created = created - this.IsRunning = isRunning - this.Name = name - this.TargetId = targetId - return &this -} - -// NewWorkspaceInfoWithDefaults instantiates a new WorkspaceInfo object -// This constructor will only assign default values to properties that have it defined, -// but it doesn't guarantee that properties required by API are set -func NewWorkspaceInfoWithDefaults() *WorkspaceInfo { - this := WorkspaceInfo{} - return &this -} - -// GetCreated returns the Created field value -func (o *WorkspaceInfo) GetCreated() string { - if o == nil { - var ret string - return ret - } - - return o.Created -} - -// GetCreatedOk returns a tuple with the Created field value -// and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetCreatedOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Created, true -} - -// SetCreated sets field value -func (o *WorkspaceInfo) SetCreated(v string) { - o.Created = v -} - -// GetIsRunning returns the IsRunning field value -func (o *WorkspaceInfo) GetIsRunning() bool { - if o == nil { - var ret bool - return ret - } - - return o.IsRunning -} - -// GetIsRunningOk returns a tuple with the IsRunning field value -// and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetIsRunningOk() (*bool, bool) { - if o == nil { - return nil, false - } - return &o.IsRunning, true -} - -// SetIsRunning sets field value -func (o *WorkspaceInfo) SetIsRunning(v bool) { - o.IsRunning = v -} - -// GetName returns the Name field value -func (o *WorkspaceInfo) GetName() string { - if o == nil { - var ret string - return ret - } - - return o.Name -} - -// GetNameOk returns a tuple with the Name field value -// and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetNameOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.Name, true -} - -// SetName sets field value -func (o *WorkspaceInfo) SetName(v string) { - o.Name = v -} - -// GetProviderMetadata returns the ProviderMetadata field value if set, zero value otherwise. -func (o *WorkspaceInfo) GetProviderMetadata() string { - if o == nil || IsNil(o.ProviderMetadata) { - var ret string - return ret - } - return *o.ProviderMetadata -} - -// GetProviderMetadataOk returns a tuple with the ProviderMetadata field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetProviderMetadataOk() (*string, bool) { - if o == nil || IsNil(o.ProviderMetadata) { - return nil, false - } - return o.ProviderMetadata, true -} - -// HasProviderMetadata returns a boolean if a field has been set. -func (o *WorkspaceInfo) HasProviderMetadata() bool { - if o != nil && !IsNil(o.ProviderMetadata) { - return true - } - - return false -} - -// SetProviderMetadata gets a reference to the given string and assigns it to the ProviderMetadata field. -func (o *WorkspaceInfo) SetProviderMetadata(v string) { - o.ProviderMetadata = &v -} - -// GetTargetId returns the TargetId field value -func (o *WorkspaceInfo) GetTargetId() string { - if o == nil { - var ret string - return ret - } - - return o.TargetId -} - -// GetTargetIdOk returns a tuple with the TargetId field value -// and a boolean to check if the value has been set. -func (o *WorkspaceInfo) GetTargetIdOk() (*string, bool) { - if o == nil { - return nil, false - } - return &o.TargetId, true -} - -// SetTargetId sets field value -func (o *WorkspaceInfo) SetTargetId(v string) { - o.TargetId = v -} - -func (o WorkspaceInfo) MarshalJSON() ([]byte, error) { - toSerialize, err := o.ToMap() - if err != nil { - return []byte{}, err - } - return json.Marshal(toSerialize) -} - -func (o WorkspaceInfo) ToMap() (map[string]interface{}, error) { - toSerialize := map[string]interface{}{} - toSerialize["created"] = o.Created - toSerialize["isRunning"] = o.IsRunning - toSerialize["name"] = o.Name - if !IsNil(o.ProviderMetadata) { - toSerialize["providerMetadata"] = o.ProviderMetadata - } - toSerialize["targetId"] = o.TargetId - return toSerialize, nil -} - -func (o *WorkspaceInfo) UnmarshalJSON(data []byte) (err error) { - // This validates that all required properties are included in the JSON object - // by unmarshalling the object into a generic map with string keys and checking - // that every required field exists as a key in the generic map. - requiredProperties := []string{ - "created", - "isRunning", - "name", - "targetId", - } - - allProperties := make(map[string]interface{}) - - err = json.Unmarshal(data, &allProperties) - - if err != nil { - return err - } - - for _, requiredProperty := range requiredProperties { - if _, exists := allProperties[requiredProperty]; !exists { - return fmt.Errorf("no value given for required property %v", requiredProperty) - } - } - - varWorkspaceInfo := _WorkspaceInfo{} - - decoder := json.NewDecoder(bytes.NewReader(data)) - decoder.DisallowUnknownFields() - err = decoder.Decode(&varWorkspaceInfo) - - if err != nil { - return err - } - - *o = WorkspaceInfo(varWorkspaceInfo) - - return err -} - -type NullableWorkspaceInfo struct { - value *WorkspaceInfo - isSet bool -} - -func (v NullableWorkspaceInfo) Get() *WorkspaceInfo { - return v.value -} - -func (v *NullableWorkspaceInfo) Set(val *WorkspaceInfo) { - v.value = val - v.isSet = true -} - -func (v NullableWorkspaceInfo) IsSet() bool { - return v.isSet -} - -func (v *NullableWorkspaceInfo) Unset() { - v.value = nil - v.isSet = false -} - -func NewNullableWorkspaceInfo(val *WorkspaceInfo) *NullableWorkspaceInfo { - return &NullableWorkspaceInfo{value: val, isSet: true} -} - -func (v NullableWorkspaceInfo) MarshalJSON() ([]byte, error) { - return json.Marshal(v.value) -} - -func (v *NullableWorkspaceInfo) UnmarshalJSON(src []byte) error { - v.isSet = true - return json.Unmarshal(src, &v.value) -} diff --git a/pkg/build/builder.go b/pkg/build/builder.go index 64bb309476..277d9b63a5 100644 --- a/pkg/build/builder.go +++ b/pkg/build/builder.go @@ -11,7 +11,6 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/services" ) type IBuilder interface { @@ -27,11 +26,11 @@ type Builder struct { image string containerRegistries common.ContainerRegistries buildImageContainerRegistry *models.ContainerRegistry - buildService services.IBuildService - buildImageNamespace string - loggerFactory logs.LoggerFactory - defaultWorkspaceImage string - defaultWorkspaceUser string + + buildImageNamespace string + loggerFactory logs.ILoggerFactory + defaultWorkspaceImage string + defaultWorkspaceUser string } func (b *Builder) GetImageName(build models.Build) (string, error) { diff --git a/pkg/build/devcontainer.go b/pkg/build/devcontainer.go index e4a02d631d..374e298c7e 100644 --- a/pkg/build/devcontainer.go +++ b/pkg/build/devcontainer.go @@ -46,7 +46,10 @@ func (b *DevcontainerBuilder) CleanUp() error { } func (b *DevcontainerBuilder) Publish(build models.Build) error { - buildLogger := b.loggerFactory.CreateBuildLogger(build.Id, logs.LogSourceBuilder) + buildLogger, err := b.loggerFactory.CreateLogger(build.Id, build.Id, logs.LogSourceBuilder) + if err != nil { + return err + } defer buildLogger.Close() cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) @@ -66,7 +69,10 @@ func (b *DevcontainerBuilder) Publish(build models.Build) error { } func (b *DevcontainerBuilder) buildDevcontainer(build models.Build) (string, string, error) { - buildLogger := b.loggerFactory.CreateBuildLogger(build.Id, logs.LogSourceBuilder) + buildLogger, err := b.loggerFactory.CreateLogger(build.Id, build.Id, logs.LogSourceBuilder) + if err != nil { + return b.defaultWorkspaceImage, b.defaultWorkspaceUser, err + } defer buildLogger.Close() cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) diff --git a/pkg/build/factory.go b/pkg/build/factory.go index cf5a16c7ca..4eceab7108 100644 --- a/pkg/build/factory.go +++ b/pkg/build/factory.go @@ -4,30 +4,24 @@ package build import ( - "context" - "errors" "fmt" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" "github.com/docker/docker/pkg/stringid" ) type IBuilderFactory interface { Create(build models.Build, workspaceDir string) (IBuilder, error) - CheckExistingBuild(build models.Build) (*models.Build, error) } type BuilderFactory struct { containerRegistries common.ContainerRegistries buildImageContainerRegistry *models.ContainerRegistry buildImageNamespace string - buildService services.IBuildService - loggerFactory logs.LoggerFactory + loggerFactory logs.ILoggerFactory image string defaultWorkspaceImage string defaultWorkspaceUser string @@ -37,9 +31,8 @@ type BuilderFactoryConfig struct { Image string ContainerRegistries common.ContainerRegistries BuildImageContainerRegistry *models.ContainerRegistry - BuildService services.IBuildService BuildImageNamespace string // Namespace to be used when tagging and pushing the build image - LoggerFactory logs.LoggerFactory + LoggerFactory logs.ILoggerFactory DefaultWorkspaceImage string DefaultWorkspaceUser string } @@ -50,7 +43,6 @@ func NewBuilderFactory(config BuilderFactoryConfig) IBuilderFactory { containerRegistries: config.ContainerRegistries, buildImageNamespace: config.BuildImageNamespace, buildImageContainerRegistry: config.BuildImageContainerRegistry, - buildService: config.BuildService, loggerFactory: config.LoggerFactory, defaultWorkspaceImage: config.DefaultWorkspaceImage, defaultWorkspaceUser: config.DefaultWorkspaceUser, @@ -62,26 +54,6 @@ func (f *BuilderFactory) Create(build models.Build, workspaceDir string) (IBuild return f.newDevcontainerBuilder(workspaceDir) } -func (f *BuilderFactory) CheckExistingBuild(b models.Build) (*models.Build, error) { - if b.Repository == nil { - return nil, errors.New("repository must be set") - } - - build, err := f.buildService.Find(context.Background(), &services.BuildFilter{ - StoreFilter: stores.BuildFilter{ - Branch: &b.Repository.Branch, - RepositoryUrl: &b.Repository.Url, - BuildConfig: b.BuildConfig, - EnvVars: &b.EnvVars, - }, - }) - if err != nil { - return nil, err - } - - return &build.Build, nil -} - func (f *BuilderFactory) newDevcontainerBuilder(workspaceDir string) (*DevcontainerBuilder, error) { builderDockerPort, err := ports.GetAvailableEphemeralPort() if err != nil { @@ -100,7 +72,6 @@ func (f *BuilderFactory) newDevcontainerBuilder(workspaceDir string) (*Devcontai containerRegistries: f.containerRegistries, buildImageContainerRegistry: f.buildImageContainerRegistry, buildImageNamespace: f.buildImageNamespace, - buildService: f.buildService, loggerFactory: f.loggerFactory, defaultWorkspaceImage: f.defaultWorkspaceImage, defaultWorkspaceUser: f.defaultWorkspaceUser, diff --git a/pkg/build/logs.go b/pkg/build/logs.go deleted file mode 100644 index b976e57cd5..0000000000 --- a/pkg/build/logs.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package build - -import ( - "path/filepath" - - "github.com/daytonaio/daytona/cmd/daytona/config" -) - -func GetBuildLogsDir() (string, error) { - configDir, err := config.GetConfigDir() - if err != nil { - return "", err - } - - return filepath.Join(configDir, "builds", "logs"), nil -} diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index 699e4c14f7..a7960cd1ed 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -20,6 +20,7 @@ import ( "github.com/daytonaio/daytona/pkg/agent/ssh" "github.com/daytonaio/daytona/pkg/agent/tailscale" "github.com/daytonaio/daytona/pkg/agent/toolbox" + "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/git" @@ -173,5 +174,5 @@ func getWorkspace(c *agent_config.Config, telemetryEnabled bool) (*models.Worksp return nil, apiclient_util.HandleErrorResponse(res, err) } - return conversion.ToWorkspace(workspace), nil + return conversion.Convert[apiclient.WorkspaceDTO, models.Workspace](workspace) } diff --git a/pkg/cmd/agent/logs.go b/pkg/cmd/agent/logs.go index 219aff530a..6767c85217 100644 --- a/pkg/cmd/agent/logs.go +++ b/pkg/cmd/agent/logs.go @@ -10,8 +10,8 @@ import ( "io" "os" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/agent/config" + "github.com/daytonaio/daytona/pkg/logs" "github.com/spf13/cobra" ) @@ -36,7 +36,7 @@ var logsCmd = &cobra.Command{ msgChan := make(chan []byte) errChan := make(chan error) - go util.ReadLog(context.Background(), file, followFlag, msgChan, errChan) + go logs.ReadLog(context.Background(), file, followFlag, msgChan, errChan) for { select { diff --git a/pkg/cmd/agentmode/info.go b/pkg/cmd/agentmode/info.go index 105ea795d4..bfa94a9b2f 100644 --- a/pkg/cmd/agentmode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -21,7 +21,7 @@ var infoCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var target *apiclient.TargetDTO - target, _, err := apiclient_util.GetTarget(targetId, true) + target, _, err := apiclient_util.GetTarget(targetId) if err != nil { return err } diff --git a/pkg/cmd/bootstrap/get_local_runner.go b/pkg/cmd/bootstrap/get_local_runner.go new file mode 100644 index 0000000000..6e5304a652 --- /dev/null +++ b/pkg/cmd/bootstrap/get_local_runner.go @@ -0,0 +1,373 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package bootstrap + +import ( + "context" + "fmt" + "io" + "net/url" + "os" + "path/filepath" + "strings" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/db" + "github.com/daytonaio/daytona/pkg/docker" + jobs_build "github.com/daytonaio/daytona/pkg/jobs/build" + jobs_runner "github.com/daytonaio/daytona/pkg/jobs/runner" + "github.com/daytonaio/daytona/pkg/jobs/target" + "github.com/daytonaio/daytona/pkg/jobs/workspace" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/runner/providermanager" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/server/headscale" + "github.com/daytonaio/daytona/pkg/server/targetconfigs" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/docker/docker/client" + log "github.com/sirupsen/logrus" +) + +const LOCAL_RUNNER_ID = "local" + +type LocalRunnerParams struct { + ServerConfig *server.Config + RunnerConfig *runner.Config + ConfigDir string + TelemetryService telemetry.TelemetryService +} + +type LocalJobFactoryParams struct { + ServerConfig *server.Config + ConfigDir string + TelemetryService telemetry.TelemetryService + ProviderManager providermanager.IProviderManager +} + +func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetRunnerLogsDir(params.ConfigDir)}) + + runnerLogger, err := loggerFactory.CreateLogger(LOCAL_RUNNER_ID, LOCAL_RUNNER_ID, logs.LogSourceRunner) + if err != nil { + return nil, err + } + + logger := &log.Logger{ + Out: io.MultiWriter(runnerLogger, os.Stdout), + Formatter: &log.TextFormatter{ + ForceColors: true, + }, + Hooks: make(log.LevelHooks), + Level: log.DebugLevel, + } + + jobService := server.GetInstance(nil).JobService + + providerManager, err := getProviderManager(params, logger) + if err != nil { + return nil, err + } + + jobFactoryParams := LocalJobFactoryParams{ + ServerConfig: params.ServerConfig, + ConfigDir: params.ConfigDir, + TelemetryService: params.TelemetryService, + ProviderManager: providerManager, + } + + runnerService := server.GetInstance(nil).RunnerService + + workspaceJobFactory, err := getLocalWorkspaceJobFactory(jobFactoryParams) + if err != nil { + return nil, err + } + + targetJobFactory, err := getLocalTargetJobFactory(jobFactoryParams) + if err != nil { + return nil, err + } + + buildJobFactory, err := getLocalBuildJobFactory(jobFactoryParams) + if err != nil { + return nil, err + } + + runnerJobFactory := jobs_runner.NewRunnerJobFactory(jobs_runner.RunnerJobFactoryConfig{ + TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackBuildRunnerEvent(event, clientId, props) + }, + ProviderManager: providerManager, + }) + + return runner.NewRunner(runner.RunnerConfig{ + Config: params.RunnerConfig, + Logger: logger, + ProviderManager: providerManager, + RegistryUrl: params.ServerConfig.RegistryUrl, + ListPendingJobs: func(ctx context.Context) ([]*models.Job, int, error) { + jobs, err := jobService.List(ctx, &stores.JobFilter{ + RunnerIdOrIsNil: util.Pointer(LOCAL_RUNNER_ID), + States: &[]models.JobState{models.JobStatePending}, + }) + return jobs, 0, err + }, + UpdateJobState: func(ctx context.Context, jobId string, state models.JobState, err *error) error { + var jobErr *string + if err != nil { + jobErr = util.Pointer((*err).Error()) + } + return jobService.SetState(ctx, jobId, services.UpdateJobStateDTO{ + State: state, + ErrorMessage: jobErr, + }) + }, + SetRunnerMetadata: func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error { + return runnerService.SetRunnerMetadata(context.Background(), runnerId, &models.RunnerMetadata{ + Uptime: uint64(metadata.Uptime), + Providers: metadata.Providers, + RunningJobs: metadata.RunningJobs, + }) + }, + WorkspaceJobFactory: workspaceJobFactory, + TargetJobFactory: targetJobFactory, + BuildJobFactory: buildJobFactory, + RunnerJobFactory: runnerJobFactory, + }), nil +} + +func getLocalWorkspaceJobFactory(params LocalJobFactoryParams) (workspace.IWorkspaceJobFactory, error) { + workspaceLogsFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetWorkspaceLogsDir(params.ConfigDir)}) + + envVarService := server.GetInstance(nil).EnvironmentVariableService + + gitProviderService := server.GetInstance(nil).GitProviderService + + targetService := server.GetInstance(nil).TargetService + + workspaceService := server.GetInstance(nil).WorkspaceService + + return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ + FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { + workspaceDto, err := workspaceService.GetWorkspace(ctx, workspaceId, services.WorkspaceRetrievalParams{}) + if err != nil { + return nil, err + } + return &workspaceDto.Workspace, nil + }, + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + if err != nil { + return nil, err + } + return &targetDto.Target, nil + }, + UpdateWorkspaceProviderMetadata: workspaceService.UpdateWorkspaceProviderMetadata, + FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { + return gitProviderService.GetConfig(ctx, id) + }, + GetWorkspaceEnvironmentVariables: func(ctx context.Context, w *models.Workspace) (map[string]string, error) { + serverEnvVars, err := envVarService.Map(ctx) + if err != nil { + return nil, err + } + + return util.MergeEnvVars(serverEnvVars, w.EnvVars), nil + }, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackServerEvent(event, clientId, props) + }, + LoggerFactory: workspaceLogsFactory, + ProviderManager: params.ProviderManager, + BuilderImage: params.ServerConfig.BuilderImage, + }), nil +} + +func getLocalTargetJobFactory(params LocalJobFactoryParams) (target.ITargetJobFactory, error) { + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetTargetLogsDir(params.ConfigDir)}) + + targetService := server.GetInstance(nil).TargetService + + return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + if err != nil { + return nil, err + } + return &targetDto.Target, nil + }, + HandleSuccessfulCreation: func(ctx context.Context, targetId string) error { + return targetService.HandleSuccessfulCreation(ctx, targetId) + }, + UpdateTargetProviderMetadata: targetService.UpdateTargetProviderMetadata, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackServerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + ProviderManager: params.ProviderManager, + }), nil +} + +func getLocalBuildJobFactory(params LocalJobFactoryParams) (jobs_build.IBuildJobFactory, error) { + buildLogsFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetBuildLogsDir(params.ConfigDir)}) + + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return nil, err + } + + dockerClient := docker.NewDockerClient(docker.DockerClientConfig{ + ApiClient: cli, + }) + + buildService := server.GetInstance(nil).BuildService + + buildImageNamespace := params.ServerConfig.BuildImageNamespace + if buildImageNamespace != "" { + buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) + } + buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") + + var builderRegistry *models.ContainerRegistry + + envVarService := server.GetInstance(nil).EnvironmentVariableService + + envVars, err := envVarService.Map(context.Background()) + if err != nil { + builderRegistry = &models.ContainerRegistry{ + Server: params.ServerConfig.BuilderRegistryServer, + } + } else { + builderRegistry = envVars.FindContainerRegistry(params.ServerConfig.BuilderRegistryServer) + } + + if builderRegistry == nil { + builderRegistry = &models.ContainerRegistry{ + Server: util.GetFrpcRegistryDomain(params.ServerConfig.Id, params.ServerConfig.Frps.Domain), + } + } + + _, containerRegistries := common.ExtractContainerRegistryFromEnvVars(envVars) + + return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ + FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { + return buildService.Find(ctx, &services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: &buildId, + }, + }) + }, + ListSuccessfulBuilds: func(ctx context.Context, repoUrl string) ([]*models.Build, error) { + buildDtos, err := buildService.List(ctx, &services.BuildFilter{ + StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, + StoreFilter: stores.BuildFilter{ + RepositoryUrl: &repoUrl, + }, + }) + if err != nil { + return nil, err + } + + var builds []*models.Build + for _, buildDto := range buildDtos { + builds = append(builds, &buildDto.Build) + } + return builds, nil + }, + ListConfigsForUrl: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { + return server.GetInstance(nil).GitProviderService.ListConfigsForUrl(ctx, repoUrl) + }, + CheckImageExists: func(ctx context.Context, image string) bool { + _, _, err = cli.ImageInspectWithRaw(context.Background(), image) + return err == nil + }, + DeleteImage: func(ctx context.Context, image string, force bool) error { + return dockerClient.DeleteImage(image, force, nil) + }, + TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackBuildRunnerEvent(event, clientId, props) + }, + LoggerFactory: buildLogsFactory, + BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ + ContainerRegistries: containerRegistries, + Image: params.ServerConfig.BuilderImage, + BuildImageContainerRegistry: builderRegistry, + + BuildImageNamespace: buildImageNamespace, + LoggerFactory: buildLogsFactory, + DefaultWorkspaceImage: params.ServerConfig.DefaultWorkspaceImage, + DefaultWorkspaceUser: params.ServerConfig.DefaultWorkspaceUser, + }), + BasePath: filepath.Join(params.ConfigDir, "builds"), + }), nil +} + +func getProviderManager(params LocalRunnerParams, logger *log.Logger) (providermanager.IProviderManager, error) { + headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ + ServerId: params.ServerConfig.Id, + FrpsDomain: params.ServerConfig.Frps.Domain, + FrpsProtocol: params.ServerConfig.Frps.Protocol, + HeadscalePort: params.ServerConfig.HeadscalePort, + ConfigDir: filepath.Join(params.ConfigDir, "headscale"), + Frps: params.ServerConfig.Frps, + }) + err := headscaleServer.Init() + if err != nil { + return nil, err + } + + headscaleUrl := util.GetFrpcHeadscaleUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain) + binaryUrl, _ := url.JoinPath(util.GetFrpcApiUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain), "binary", "script") + + dbPath, err := getDbPath() + if err != nil { + return nil, err + } + + dbConnection := db.GetSQLiteConnection(dbPath) + + store := db.NewStore(dbConnection) + + targetConfigStore, err := db.NewTargetConfigStore(store) + if err != nil { + return nil, err + } + + targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ + TargetConfigStore: targetConfigStore, + }) + + return providermanager.GetProviderManager(&providermanager.ProviderManagerConfig{ + TargetLogsDir: server.GetTargetLogsDir(params.ConfigDir), + WorkspaceLogsDir: server.GetWorkspaceLogsDir(params.ConfigDir), + Logger: logger, + ApiUrl: util.GetFrpcApiUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain), + RunnerName: params.RunnerConfig.Name, + RunnerId: params.RunnerConfig.Id, + DaytonaDownloadUrl: binaryUrl, + ServerUrl: headscaleUrl, + BaseDir: params.RunnerConfig.ProvidersDir, + CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { + return headscaleServer.CreateAuthKey(headscale.HEADSCALE_USERNAME) + }, + ServerPort: params.ServerConfig.HeadscalePort, + ApiPort: params.ServerConfig.ApiPort, + GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { + return targetConfigService.Map(ctx) + }, + CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { + _, err := targetConfigService.Add(ctx, services.AddTargetConfigDTO{ + Name: name, + Options: options, + ProviderInfo: providerInfo, + }) + return err + }, + }), nil +} diff --git a/pkg/cmd/bootstrap/get_remote_runner.go b/pkg/cmd/bootstrap/get_remote_runner.go new file mode 100644 index 0000000000..c4e6beb4d7 --- /dev/null +++ b/pkg/cmd/bootstrap/get_remote_runner.go @@ -0,0 +1,476 @@ +// Copyright 2024 Daytona Platforms Inparams.ServerConfig. +// SPDX-License-Identifier: Apache-2.0 + +package bootstrap + +import ( + "context" + "errors" + "fmt" + "io" + "net/url" + "os" + "path/filepath" + "strings" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/build" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/docker" + jobs_build "github.com/daytonaio/daytona/pkg/jobs/build" + jobs_runner "github.com/daytonaio/daytona/pkg/jobs/runner" + "github.com/daytonaio/daytona/pkg/jobs/target" + "github.com/daytonaio/daytona/pkg/jobs/workspace" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runner/providermanager" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/docker/docker/client" + log "github.com/sirupsen/logrus" + + "github.com/daytonaio/daytona/pkg/runner" +) + +type RemoteRunnerParams struct { + ApiClient *apiclient.APIClient + ServerConfig *apiclient.ServerConfig + RunnerConfig *runner.Config + ConfigDir string + LogWriter io.Writer + TelemetryService telemetry.TelemetryService +} + +type RemoteJobFactoryParams struct { + ApiClient *apiclient.APIClient + ServerConfig *apiclient.ServerConfig + RunnerConfig *runner.Config + ConfigDir string + TelemetryService telemetry.TelemetryService + ProviderManager providermanager.IProviderManager +} + +func GetRemoteRunner(params RemoteRunnerParams) (runner.IRunner, error) { + runnerLogsDir := runner.GetLogsDir(params.ConfigDir) + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{ + LogsDir: runnerLogsDir, + ApiUrl: ¶ms.RunnerConfig.ServerApiUrl, + ApiKey: ¶ms.RunnerConfig.ServerApiKey, + ApiBasePath: &logs.ApiBasePathRunner, + }) + + runnerLogger, err := loggerFactory.CreateLogger(params.RunnerConfig.Id, params.RunnerConfig.Name, logs.LogSourceRunner) + if err != nil { + return nil, err + } + + logger := &log.Logger{ + Out: io.MultiWriter(runnerLogger, os.Stdout), + Formatter: &log.TextFormatter{ + ForceColors: true, + }, + Hooks: make(log.LevelHooks), + Level: log.DebugLevel, + } + + providerManager := getRemoteProviderManager(params, logger) + + jobFactoryParams := RemoteJobFactoryParams{ + ApiClient: params.ApiClient, + ServerConfig: params.ServerConfig, + RunnerConfig: params.RunnerConfig, + ConfigDir: params.ConfigDir, + TelemetryService: params.TelemetryService, + ProviderManager: providerManager, + } + + workspaceJobFactory, err := getRemoteWorkspaceJobFactory(jobFactoryParams) + if err != nil { + return nil, err + } + + targetJobFactory, err := getRemoteTargetJobFactory(jobFactoryParams) + if err != nil { + return nil, err + } + + buildJobFactory, err := getRemoteBuildJobFactory(jobFactoryParams) + if err != nil { + return nil, err + } + + runnerJobFactory := jobs_runner.NewRunnerJobFactory(jobs_runner.RunnerJobFactoryConfig{ + TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackRunnerEvent(event, clientId, props) + }, + ProviderManager: providerManager, + }) + + return runner.NewRunner(runner.RunnerConfig{ + Config: params.RunnerConfig, + Logger: logger, + ProviderManager: providerManager, + RegistryUrl: params.ServerConfig.RegistryUrl, + ListPendingJobs: func(ctx context.Context) ([]*models.Job, int, error) { + jobs, res, err := params.ApiClient.RunnerAPI.ListRunnerJobs(ctx, params.RunnerConfig.Id).Execute() + if err != nil { + statusCode := -1 + if res != nil { + statusCode = res.StatusCode + } + return nil, statusCode, err + } + + var response []*models.Job + for _, job := range jobs { + response = append(response, &models.Job{ + Id: job.Id, + ResourceId: job.ResourceId, + RunnerId: job.RunnerId, + ResourceType: models.ResourceType(job.ResourceType), + State: models.JobState(job.State), + Action: models.JobAction(job.Action), + Metadata: job.Metadata, + Error: job.Error, + // TODO: Convert + // CreatedAt: parseTime(job.CreatedAt), + // UpdatedAt: parseTime(job.UpdatedAt), + }) + } + return response, res.StatusCode, nil + }, + UpdateJobState: func(ctx context.Context, jobId string, state models.JobState, jobError *error) error { + var jobErr *string + if jobError != nil { + jobErr = util.Pointer((*jobError).Error()) + } + _, err := params.ApiClient.RunnerAPI.UpdateJobState(ctx, params.RunnerConfig.Id, jobId).UpdateJobState(apiclient.UpdateJobState{ + State: apiclient.JobState(state), + ErrorMessage: jobErr, + }).Execute() + return err + }, + SetRunnerMetadata: func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error { + var providers []apiclient.ProviderInfo + + for _, provider := range metadata.Providers { + providerInfoDto, err := conversion.Convert[models.ProviderInfo, apiclient.ProviderInfo](&provider) + if err != nil { + return err + } + if providerInfoDto == nil { + continue + } + + providers = append(providers, *providerInfoDto) + } + + runnerMetadata := apiclient.UpdateRunnerMetadataDTO{ + Uptime: int32(metadata.Uptime), + Providers: providers, + } + + if metadata.RunningJobs != nil { + runnerMetadata.RunningJobs = util.Pointer(int32(*metadata.RunningJobs)) + } + + _, err := params.ApiClient.RunnerAPI.SetRunnerMetadata(ctx, runnerId).RunnerMetadata(runnerMetadata).Execute() + return err + }, + WorkspaceJobFactory: workspaceJobFactory, + TargetJobFactory: targetJobFactory, + BuildJobFactory: buildJobFactory, + RunnerJobFactory: runnerJobFactory, + }), nil +} + +func getRemoteProviderManager(params RemoteRunnerParams, logger *log.Logger) providermanager.IProviderManager { + headscaleUrl := util.GetFrpcHeadscaleUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain) + binaryUrl, _ := url.JoinPath(params.RunnerConfig.ServerApiUrl, "binary", "script") + + return providermanager.GetProviderManager(&providermanager.ProviderManagerConfig{ + WorkspaceLogsDir: filepath.Join(params.ConfigDir, "workspaces", "logs"), + TargetLogsDir: filepath.Join(params.ConfigDir, "targets", "logs"), + ApiUrl: util.GetFrpcApiUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain), + ApiKey: ¶ms.RunnerConfig.ServerApiKey, + RunnerId: params.RunnerConfig.Id, + RunnerName: params.RunnerConfig.Name, + Logger: logger, + DaytonaDownloadUrl: binaryUrl, + ServerUrl: headscaleUrl, + BaseDir: params.RunnerConfig.ProvidersDir, + CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { + key, _, err := params.ApiClient.ServerAPI.GenerateNetworkKey(ctx).Execute() + if err != nil { + return "", err + } + + return key.Key, nil + }, + ServerPort: uint32(params.ServerConfig.HeadscalePort), + ApiPort: uint32(params.ServerConfig.ApiPort), + GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { + list, _, err := params.ApiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() + if err != nil { + return nil, err + } + + targetConfigs := make(map[string]*models.TargetConfig) + for _, targetConfig := range list { + tc, err := conversion.Convert[apiclient.TargetConfig, models.TargetConfig](&targetConfig) + if err != nil { + return nil, err + } + if tc == nil { + continue + } + + if tc.ProviderInfo.RunnerId != params.RunnerConfig.Id { + continue + } + + targetConfigs[targetConfig.Name] = tc + } + + return targetConfigs, nil + }, + CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { + providerInfoDto, err := conversion.Convert[models.ProviderInfo, apiclient.ProviderInfo](&providerInfo) + if err != nil { + return err + } + if providerInfoDto == nil { + return errors.New("invalid provider info") + } + + _, _, err = params.ApiClient.TargetConfigAPI.AddTargetConfig(ctx).TargetConfig(apiclient.AddTargetConfigDTO{ + Name: fmt.Sprintf("%s-runner-%s", name, params.RunnerConfig.Id), + Options: options, + ProviderInfo: *providerInfoDto, + }).Execute() + return err + }, + }) +} + +func getRemoteWorkspaceJobFactory(params RemoteJobFactoryParams) (workspace.IWorkspaceJobFactory, error) { + logsDir := filepath.Join(params.ConfigDir, "workspaces", "logs") + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{ + LogsDir: logsDir, + ApiUrl: ¶ms.RunnerConfig.ServerApiUrl, + ApiKey: ¶ms.RunnerConfig.ServerApiKey, + ApiBasePath: &logs.ApiBasePathWorkspace, + }) + + return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ + FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { + workspaceDto, _, err := params.ApiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + if err != nil { + return nil, err + } + return conversion.Convert[apiclient.WorkspaceDTO, models.Workspace](workspaceDto) + }, + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + targetDto, _, err := params.ApiClient.TargetAPI.GetTarget(ctx, targetId).ShowOptions(true).Execute() + if err != nil { + return nil, err + } + return conversion.Convert[apiclient.TargetDTO, models.Target](targetDto) + }, + UpdateWorkspaceProviderMetadata: func(ctx context.Context, workspaceId, metadata string) error { + _, err := params.ApiClient.WorkspaceAPI.UpdateWorkspaceProviderMetadata(ctx, workspaceId).Metadata(apiclient.UpdateWorkspaceProviderMetadataDTO{ + Metadata: metadata, + }).Execute() + return err + }, + FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { + gp, _, err := params.ApiClient.GitProviderAPI.GetGitProvider(ctx, id).Execute() + if err != nil { + return nil, err + } + + return conversion.Convert[apiclient.GitProvider, models.GitProviderConfig](gp) + }, + GetWorkspaceEnvironmentVariables: func(ctx context.Context, w *models.Workspace) (map[string]string, error) { + envVars, _, err := params.ApiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() + if err != nil { + return nil, err + } + + envVarsMap := make(map[string]string) + for _, envVar := range envVars { + envVarsMap[envVar.Key] = envVar.Value + } + + return util.MergeEnvVars(envVarsMap, w.EnvVars), nil + }, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackServerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + ProviderManager: params.ProviderManager, + BuilderImage: params.ServerConfig.BuilderImage, + }), nil +} + +func getRemoteTargetJobFactory(params RemoteJobFactoryParams) (target.ITargetJobFactory, error) { + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{ + LogsDir: filepath.Join(params.ConfigDir, "targets", "logs"), + ApiUrl: ¶ms.RunnerConfig.ServerApiUrl, + ApiKey: ¶ms.RunnerConfig.ServerApiKey, + ApiBasePath: &logs.ApiBasePathTarget, + }) + + return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ + FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { + targetDto, _, err := params.ApiClient.TargetAPI.GetTarget(ctx, targetId).ShowOptions(true).Execute() + if err != nil { + return nil, err + } + + return conversion.Convert[apiclient.TargetDTO, models.Target](targetDto) + }, + HandleSuccessfulCreation: func(ctx context.Context, targetId string) error { + _, err := params.ApiClient.TargetAPI.HandleSuccessfulCreation(ctx, targetId).Execute() + return err + }, + UpdateTargetProviderMetadata: func(ctx context.Context, targetId, metadata string) error { + _, err := params.ApiClient.TargetAPI.UpdateTargetProviderMetadata(ctx, targetId).Metadata(apiclient.UpdateTargetProviderMetadataDTO{ + Metadata: metadata, + }).Execute() + return err + }, + TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackServerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + ProviderManager: params.ProviderManager, + }), nil +} + +func getRemoteBuildJobFactory(params RemoteJobFactoryParams) (jobs_build.IBuildJobFactory, error) { + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{ + LogsDir: filepath.Join(params.ConfigDir, "builds", "logs"), + ApiUrl: ¶ms.RunnerConfig.ServerApiUrl, + ApiKey: ¶ms.RunnerConfig.ServerApiKey, + ApiBasePath: &logs.ApiBasePathBuild, + }) + + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return nil, err + } + + dockerClient := docker.NewDockerClient(docker.DockerClientConfig{ + ApiClient: cli, + }) + + var buildImageNamespace string + + if params.ServerConfig.BuildImageNamespace != nil { + buildImageNamespace = *params.ServerConfig.BuildImageNamespace + if buildImageNamespace != "" { + buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) + buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") + } + } + + var builderRegistry *models.ContainerRegistry + + envVars, _, err := params.ApiClient.EnvVarAPI.ListEnvironmentVariables(context.Background()).Execute() + if err != nil { + builderRegistry = &models.ContainerRegistry{ + Server: params.ServerConfig.BuilderRegistryServer, + } + } + + envVarsMap := make(services.EnvironmentVariables) + for _, envVar := range envVars { + envVarsMap[envVar.Key] = envVar.Value + } + + if len(envVarsMap) > 0 { + builderRegistry = envVarsMap.FindContainerRegistry(params.ServerConfig.BuilderRegistryServer) + } + + if builderRegistry == nil { + builderRegistry = &models.ContainerRegistry{ + Server: util.GetFrpcRegistryDomain(params.ServerConfig.Id, params.ServerConfig.Frps.Domain), + } + } + + _, containerRegistries := common.ExtractContainerRegistryFromEnvVars(envVarsMap) + + return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ + FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { + build, _, err := params.ApiClient.BuildAPI.GetBuild(ctx, buildId).Execute() + if err != nil { + return nil, err + } + + return conversion.Convert[apiclient.BuildDTO, services.BuildDTO](build) + }, + ListSuccessfulBuilds: func(ctx context.Context, repoUrl string) ([]*models.Build, error) { + apiclientBuildDtos, _, err := params.ApiClient.BuildAPI.ListSuccessfulBuilds(ctx, url.QueryEscape(repoUrl)).Execute() + if err != nil { + return nil, err + } + + var builds []*models.Build + for _, apiclientBuildDto := range apiclientBuildDtos { + buildDto, err := conversion.Convert[apiclient.BuildDTO, services.BuildDTO](&apiclientBuildDto) + if err != nil { + return nil, err + } + if buildDto == nil { + continue + } + builds = append(builds, &buildDto.Build) + } + return builds, nil + }, + ListConfigsForUrl: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { + gitProviders, _, err := params.ApiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(repoUrl)).Execute() + if err != nil { + return nil, err + } + + var gitProviderConfigs []*models.GitProviderConfig + for _, gitProvider := range gitProviders { + gitProviderConfigDto, err := conversion.Convert[apiclient.GitProvider, models.GitProviderConfig](&gitProvider) + if err != nil { + return nil, err + } + if gitProviderConfigDto == nil { + continue + } + gitProviderConfigs = append(gitProviderConfigs, gitProviderConfigDto) + } + + return gitProviderConfigs, nil + }, + CheckImageExists: func(ctx context.Context, image string) bool { + _, _, err = cli.ImageInspectWithRaw(ctx, image) + return err == nil + }, + DeleteImage: func(ctx context.Context, image string, force bool) error { + return dockerClient.DeleteImage(image, force, nil) + }, + TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { + return params.TelemetryService.TrackBuildRunnerEvent(event, clientId, props) + }, + LoggerFactory: loggerFactory, + BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ + Image: params.ServerConfig.BuilderImage, + ContainerRegistries: containerRegistries, + BuildImageContainerRegistry: builderRegistry, + BuildImageNamespace: buildImageNamespace, + LoggerFactory: loggerFactory, + DefaultWorkspaceImage: params.ServerConfig.DefaultWorkspaceImage, + DefaultWorkspaceUser: params.ServerConfig.DefaultWorkspaceUser, + }), + BasePath: filepath.Join(params.ConfigDir, "builds"), + }), nil +} diff --git a/pkg/cmd/server/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go similarity index 84% rename from pkg/cmd/server/bootstrap/get_server_instance.go rename to pkg/cmd/bootstrap/get_server_instance.go index 0177273e8f..ea07d3f0e1 100644 --- a/pkg/cmd/server/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -13,13 +13,10 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/db" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/server/builds" @@ -28,6 +25,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/jobs" "github.com/daytonaio/daytona/pkg/server/registry" + "github.com/daytonaio/daytona/pkg/server/runners" "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/server/targets" "github.com/daytonaio/daytona/pkg/server/workspaces" @@ -40,16 +38,6 @@ import ( ) func GetInstance(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (*server.Server, error) { - targetLogsDir, err := server.GetTargetLogsDir(configDir) - if err != nil { - return nil, err - } - buildLogsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) - dbPath, err := getDbPath() if err != nil { return nil, err @@ -103,8 +91,14 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe if err != nil { return nil, err } - - providerManager := manager.GetProviderManager(nil) + runnerStore, err := db.NewRunnerStore(store) + if err != nil { + return nil, err + } + runnerMetadataStore, err := db.NewRunnerMetadataStore(store) + if err != nil { + return nil, err + } headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ ServerId: c.Id, @@ -173,7 +167,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe State: models.JobStatePending, }) }, - LoggerFactory: loggerFactory, + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetBuildLogsDir(configDir)}), }) prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) @@ -288,10 +282,6 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) - provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ - ProviderManager: providerManager, - }) - targetService := targets.NewTargetService(targets.TargetServiceConfig{ TargetStore: targetStore, TargetMetadataStore: targetMetadataStore, @@ -304,9 +294,10 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe RevokeApiKey: func(ctx context.Context, name string) error { return apiKeyService.Revoke(ctx, name) }, - CreateJob: func(ctx context.Context, targetId string, action models.JobAction) error { + CreateJob: func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error { return jobService.Create(ctx, &models.Job{ ResourceId: targetId, + RunnerId: &runnerId, ResourceType: models.ResourceTypeTarget, Action: action, State: models.JobStatePending, @@ -315,8 +306,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), ServerVersion: version, ServerUrl: headscaleUrl, - Provisioner: provisioner, - LoggerFactory: loggerFactory, + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetTargetLogsDir(configDir)}), TelemetryService: telemetryService, }) @@ -376,9 +366,10 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { return gitProviderService.GetLastCommitSha(ctx, repo) }, - CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { + CreateJob: func(ctx context.Context, workspaceId string, runnerId string, action models.JobAction) error { return jobService.Create(ctx, &models.Job{ ResourceId: workspaceId, + RunnerId: &runnerId, ResourceType: models.ResourceTypeWorkspace, Action: action, State: models.JobStatePending, @@ -390,14 +381,61 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ServerUrl: headscaleUrl, DefaultWorkspaceImage: c.DefaultWorkspaceImage, DefaultWorkspaceUser: c.DefaultWorkspaceUser, - Provisioner: provisioner, - LoggerFactory: loggerFactory, + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetWorkspaceLogsDir(configDir)}), }) envVarService := env.NewEnvironmentVariableService(env.EnvironmentVariableServiceConfig{ EnvironmentVariableStore: envVarStore, }) + runnerService := runners.NewRunnerService(runners.RunnerServiceConfig{ + RunnerStore: runnerStore, + RunnerMetadataStore: runnerMetadataStore, + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetRunnerLogsDir(configDir)}), + CreateJob: func(ctx context.Context, runnerId string, action models.JobAction, metadata string) error { + return jobService.Create(ctx, &models.Job{ + ResourceId: runnerId, + RunnerId: &runnerId, + ResourceType: models.ResourceTypeRunner, + Action: action, + State: models.JobStatePending, + Metadata: &metadata, + }) + }, + ListJobsForRunner: func(ctx context.Context, runnerId string) ([]*models.Job, error) { + return jobService.List(ctx, &stores.JobFilter{ + RunnerIdOrIsNil: &runnerId, + States: &[]models.JobState{models.JobStatePending}, + }) + }, + UpdateJobState: func(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { + return jobService.SetState(ctx, jobId, updateJobStateDto) + }, + GenerateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Generate(ctx, models.ApiKeyTypeRunner, name) + }, + RevokeApiKey: apiKeyService.Revoke, + UnsetDefaultTarget: func(ctx context.Context, runnerId string) error { + targets, err := targetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) + if err != nil { + return err + } + + for _, t := range targets { + if t.TargetConfig.ProviderInfo.RunnerId == runnerId && t.IsDefault { + t.IsDefault = false + err = targetService.SaveTarget(ctx, &t.Target) + if err != nil { + return err + } + break + } + } + return nil + }, + TrackTelemetryEvent: telemetryService.TrackServerEvent, + }) + s := server.GetInstance(&server.ServerInstanceConfig{ Config: *c, Version: version, @@ -410,9 +448,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe ApiKeyService: apiKeyService, TargetService: targetService, GitProviderService: gitProviderService, - ProviderManager: providerManager, EnvironmentVariableService: envVarService, JobService: jobService, + RunnerService: runnerService, TelemetryService: telemetryService, }) diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index 2d2213a251..4051995c95 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" @@ -30,11 +31,6 @@ var buildLogsCmd = &cobra.Command{ return err } - query := "" - if followFlag { - query += "follow=true" - } - ctx := context.Background() var buildId string @@ -68,10 +64,11 @@ var buildLogsCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(nil, err) } - apiclient_util.ReadBuildLogs(ctx, apiclient_util.ReadLogParams{ - Id: buildId, - ActiveProfile: activeProfile, - Query: &query, + cmd_common.ReadBuildLogs(ctx, cmd_common.ReadLogParams{ + Id: buildId, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Follow: &followFlag, }) // Make sure the terminal cursor is reset diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index ccd3d38314..46ac580968 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -23,6 +23,7 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/prebuild" . "github.com/daytonaio/daytona/pkg/cmd/profile" . "github.com/daytonaio/daytona/pkg/cmd/provider" + . "github.com/daytonaio/daytona/pkg/cmd/runner" . "github.com/daytonaio/daytona/pkg/cmd/server" . "github.com/daytonaio/daytona/pkg/cmd/target" . "github.com/daytonaio/daytona/pkg/cmd/targetconfig" @@ -53,6 +54,7 @@ func Execute() error { rootCmd.AddGroup(&cobra.Group{ID: TARGET_GROUP, Title: "Targets & Workspaces"}) rootCmd.AddGroup(&cobra.Group{ID: SERVER_GROUP, Title: "Server"}) rootCmd.AddGroup(&cobra.Group{ID: PROFILE_GROUP, Title: "Profile"}) + rootCmd.AddGroup(&cobra.Group{ID: RUNNER_GROUP, Title: "Runner"}) rootCmd.AddCommand(CodeCmd) rootCmd.AddCommand(SshCmd) @@ -68,6 +70,7 @@ func Execute() error { rootCmd.AddCommand(TargetConfigCmd) rootCmd.AddCommand(configCmd) rootCmd.AddCommand(ideCmd) + rootCmd.AddCommand(RunnerCmd) rootCmd.AddCommand(ProfileCmd) rootCmd.AddCommand(ProfileUseCmd) rootCmd.AddCommand(whoamiCmd) diff --git a/pkg/cmd/common/await_state.go b/pkg/cmd/common/await_state.go index ca504501c5..36ed28b471 100644 --- a/pkg/cmd/common/await_state.go +++ b/pkg/cmd/common/await_state.go @@ -4,6 +4,7 @@ package common import ( + "context" "errors" "net/http" "time" @@ -14,7 +15,7 @@ import ( func AwaitWorkspaceState(workspaceId string, stateName apiclient.ModelsResourceStateName) error { for { - ws, _, err := apiclient_util.GetWorkspace(workspaceId, false) + ws, _, err := apiclient_util.GetWorkspace(workspaceId) if err != nil { return err } @@ -28,13 +29,13 @@ func AwaitWorkspaceState(workspaceId string, stateName apiclient.ModelsResourceS } return errors.New(errorMessage) } - time.Sleep(time.Second) + time.Sleep(200 * time.Millisecond) } } func AwaitTargetState(targetId string, stateName apiclient.ModelsResourceStateName) error { for { - t, _, err := apiclient_util.GetTarget(targetId, false) + t, _, err := apiclient_util.GetTarget(targetId) if err != nil { return err } @@ -50,32 +51,60 @@ func AwaitTargetState(targetId string, stateName apiclient.ModelsResourceStateNa } return errors.New(errorMessage) } - time.Sleep(time.Second) + time.Sleep(200 * time.Millisecond) + } +} + +func AwaitProviderInstalled(runnerId, providerName, version string) error { + for { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + runner, res, err := apiClient.RunnerAPI.GetRunner(ctx, runnerId).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if runner.Metadata == nil { + continue + } + + for _, provider := range runner.Metadata.Providers { + if provider.Name == providerName && provider.Version == version { + return nil + } + } + + time.Sleep(200 * time.Millisecond) } } func AwaitWorkspaceDeleted(workspaceId string) error { for { - _, statusCode, err := apiclient_util.GetWorkspace(workspaceId, false) + _, statusCode, err := apiclient_util.GetWorkspace(workspaceId) if err != nil { if statusCode == http.StatusNotFound { return nil } return err } - time.Sleep(time.Second) + time.Sleep(200 * time.Millisecond) } } func AwaitTargetDeleted(workspaceId string) error { for { - _, statusCode, err := apiclient_util.GetTarget(workspaceId, false) + _, statusCode, err := apiclient_util.GetTarget(workspaceId) if err != nil { if statusCode == http.StatusNotFound { return nil } return err } - time.Sleep(time.Second) + time.Sleep(200 * time.Millisecond) } } diff --git a/pkg/cmd/server/daemon/daemon.go b/pkg/cmd/common/daemon/daemon.go similarity index 86% rename from pkg/cmd/server/daemon/daemon.go rename to pkg/cmd/common/daemon/daemon.go index fc47f518e4..9feb3928b7 100644 --- a/pkg/cmd/server/daemon/daemon.go +++ b/pkg/cmd/common/daemon/daemon.go @@ -16,14 +16,14 @@ import ( "github.com/kardianos/service" ) -const serviceName = "DaytonaServerDaemon" - type program struct { service.Interface } -func Start(logFilePath string) error { - cfg, err := getServiceConfig() +var ErrDaemonNotInstalled = errors.New("daemon not installed") + +func Start(logFilePath string, svcConfig *service.Config) error { + cfg, err := getServiceConfig(svcConfig) if err != nil { return err } @@ -88,7 +88,7 @@ func Start(logFilePath string) error { return nil } - err = Stop() + err = Stop(svcConfig) if err != nil { return err } @@ -100,8 +100,8 @@ func Start(logFilePath string) error { } } -func Stop() error { - cfg, err := getServiceConfig() +func Stop(svcConfig *service.Config) error { + cfg, err := getServiceConfig(svcConfig) if err != nil { return err } @@ -115,7 +115,7 @@ func Stop() error { return err } if _, err := os.Stat(serviceFilePath); os.IsNotExist(err) { - return errors.New("daemon not installed. Run `daytona server` to start the server") + return ErrDaemonNotInstalled } err = s.Stop() @@ -126,7 +126,7 @@ func Stop() error { return s.Uninstall() } -func getServiceConfig() (*service.Config, error) { +func getServiceConfig(svcConfig *service.Config) (*service.Config, error) { if runtime.GOOS == "windows" { return nil, errors.New("daemon mode not supported on Windows") } @@ -136,13 +136,6 @@ func getServiceConfig() (*service.Config, error) { return nil, errors.New("could not determine user") } - svcConfig := &service.Config{ - Name: serviceName, - DisplayName: "Daytona Server", - Description: "Daytona Server daemon.", - Arguments: []string{"daemon-serve"}, - } - switch runtime.GOOS { case "linux": // Fix for running as root on Linux diff --git a/pkg/cmd/common/get_runner.go b/pkg/cmd/common/get_runner.go new file mode 100644 index 0000000000..9e8ab58de7 --- /dev/null +++ b/pkg/cmd/common/get_runner.go @@ -0,0 +1,50 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "context" + + "github.com/daytonaio/daytona/cmd/daytona/config" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/common" + runner "github.com/daytonaio/daytona/pkg/views/server/runner/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" +) + +func GetRunnerFlow(apiClient *apiclient.APIClient, action string) (*runner.RunnerView, error) { + ctx := context.Background() + + c, err := config.GetConfig() + if err != nil { + return nil, err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return nil, err + } + + runners, res, err := apiClient.RunnerAPI.ListRunners(ctx).Execute() + if err != nil { + return nil, apiclient_util.HandleErrorResponse(res, err) + } + + if len(runners) == 0 { + views_util.NotifyEmptyRunnerList(true) + return nil, nil + } + + selectedRunner, err := runner.GetRunnerFromPrompt(runners, activeProfile.Name, action) + if err != nil { + if common.IsCtrlCAbort(err) { + return nil, nil + } else { + return nil, err + } + } + + return selectedRunner, nil +} diff --git a/internal/util/apiclient/websocket_log_reader.go b/pkg/cmd/common/websocket_log_reader.go similarity index 70% rename from internal/util/apiclient/websocket_log_reader.go rename to pkg/cmd/common/websocket_log_reader.go index 92c15289e3..262df9756b 100644 --- a/internal/util/apiclient/websocket_log_reader.go +++ b/pkg/cmd/common/websocket_log_reader.go @@ -1,14 +1,15 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package apiclient +package common import ( "context" "fmt" "time" - "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/logs" logs_view "github.com/daytonaio/daytona/pkg/views/logs" "github.com/gorilla/websocket" @@ -18,11 +19,11 @@ import ( type ReadLogParams struct { Id string Label *string - ActiveProfile config.Profile + ServerUrl string + ApiKey string SkipPrefixLengthSetup bool Index *int Follow *bool - Query *string From *time.Time } @@ -37,10 +38,10 @@ func ReadTargetLogs(ctx context.Context, params ReadLogParams) { } for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", params.Id), ¶ms.ActiveProfile, &query) + ws, res, err := util.GetWebsocketConn(ctx, fmt.Sprintf("/log/target/%s", params.Id), params.ServerUrl, params.ApiKey, &query) // We want to retry getting the logs if it fails if err != nil { - log.Trace(HandleErrorResponse(res, err)) + log.Trace(apiclient.HandleErrorResponse(res, err)) time.Sleep(250 * time.Millisecond) continue } @@ -60,10 +61,10 @@ func ReadWorkspaceLogs(ctx context.Context, params ReadLogParams) { } for { - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s", params.Id), ¶ms.ActiveProfile, &query) + ws, res, err := util.GetWebsocketConn(ctx, fmt.Sprintf("/log/workspace/%s", params.Id), params.ServerUrl, params.ApiKey, &query) // We want to retry getting the logs if it fails if err != nil { - log.Trace(HandleErrorResponse(res, err)) + log.Trace(apiclient.HandleErrorResponse(res, err)) time.Sleep(500 * time.Millisecond) continue } @@ -83,15 +84,38 @@ func ReadBuildLogs(ctx context.Context, params ReadLogParams) { checkAndSetupLongestPrefixLength(params.SkipPrefixLengthSetup, params.Id, params.Label) for { - var query string - if params.Query != nil { - query = *params.Query + query := "" + if params.Follow != nil && *params.Follow { + query = "follow=true" } - ws, res, err := GetWebsocketConn(ctx, fmt.Sprintf("/log/build/%s", params.Id), ¶ms.ActiveProfile, &query) + ws, res, err := util.GetWebsocketConn(ctx, fmt.Sprintf("/log/build/%s", params.Id), params.ServerUrl, params.ApiKey, &query) // We want to retry getting the logs if it fails if err != nil { - log.Trace(HandleErrorResponse(res, err)) + log.Trace(apiclient.HandleErrorResponse(res, err)) + time.Sleep(250 * time.Millisecond) + continue + } + + readJSONLog(ctx, ws, logs_view.FIRST_WORKSPACE_INDEX, nil) + ws.Close() + break + } +} + +func ReadRunnerLogs(ctx context.Context, params ReadLogParams) { + checkAndSetupLongestPrefixLength(params.SkipPrefixLengthSetup, params.Id, params.Label) + + for { + query := "" + if params.Follow != nil && *params.Follow { + query = "follow=true" + } + + ws, res, err := util.GetWebsocketConn(ctx, fmt.Sprintf("/log/runner/%s", params.Id), params.ServerUrl, params.ApiKey, &query) + // We want to retry getting the logs if it fails + if err != nil { + log.Trace(apiclient.HandleErrorResponse(res, err)) time.Sleep(250 * time.Millisecond) continue } diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index 13c3ae0ada..4153d544a2 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -7,20 +7,17 @@ import ( "context" "errors" "fmt" - "slices" - "strings" - "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/os" - "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/provider" - "github.com/daytonaio/daytona/pkg/views/targetconfig" views_util "github.com/daytonaio/daytona/pkg/views/util" - "github.com/docker/docker/pkg/stringid" "github.com/spf13/cobra" ) @@ -29,39 +26,54 @@ var yesFlag bool var providerInstallCmd = &cobra.Command{ Use: "install", Short: "Install provider", - Args: cobra.NoArgs, + Args: cobra.MaximumNArgs(1), Aliases: []string{"i"}, RunE: func(cmd *cobra.Command, args []string) error { + var selectedRunnerId string + apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } + if len(args) == 0 { + selectedRunner, err := cmd_common.GetRunnerFlow(apiClient, "Manage Providers") + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + + if selectedRunner == nil { + return nil + } + + selectedRunnerId = selectedRunner.Id + } else { + selectedRunnerId = args[0] + } + serverConfig, res, err := apiClient.ServerAPI.GetConfigExecute(apiclient.ApiGetConfigRequest{}) if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - providerManager := manager.GetProviderManager(&manager.ProviderManagerConfig{RegistryUrl: serverConfig.RegistryUrl}) - - providersManifest, err := providerManager.GetProvidersManifest() + providersManifest, err := util.GetProvidersManifest(serverConfig.RegistryUrl) if err != nil { return err } - if providersManifest == nil { - return errors.New("could not get providers manifest") - } - providersManifestLatest := providersManifest.GetLatestVersions() if providersManifestLatest == nil { return errors.New("could not get providers manifest") } - providerList := GetProviderListFromManifest(providersManifestLatest) + providerList := conversion.GetProviderListFromManifest(providersManifestLatest) specificProviderName := "Select a specific version" specificProviderVersion := "" - providerList = append(providerList, apiclient.Provider{Name: specificProviderName, Label: &specificProviderName, Version: specificProviderVersion}) + providerList = append(providerList, apiclient.ProviderInfo{Name: specificProviderName, Label: &specificProviderName, Version: specificProviderVersion}) providerToInstall, err := provider.GetProviderFromPrompt(provider.ProviderListToView(providerList), "Choose a Provider to Install", false) if err != nil { @@ -77,7 +89,7 @@ var providerInstallCmd = &cobra.Command{ } if providerToInstall.Name == specificProviderName { - providerList = GetProviderListFromManifest(providersManifest) + providerList = conversion.GetProviderListFromManifest(providersManifest) providerToInstall, err = provider.GetProviderFromPrompt(provider.ProviderListToView(providerList), "Choose a specific provider to install", false) if err != nil { @@ -93,83 +105,12 @@ var providerInstallCmd = &cobra.Command{ } } - err = InstallProvider(apiClient, *providerToInstall, providersManifest) + err = InstallProvider(apiClient, selectedRunnerId, *providerToInstall, providersManifest) if err != nil { return err } views.RenderInfoMessageBold(fmt.Sprintf("Provider %s has been successfully installed", providerToInstall.Name)) - - targets, res, err := apiClient.TargetAPI.ListTargets(context.Background()).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - if slices.ContainsFunc(targets, func(t apiclient.TargetDTO) bool { - return t.TargetConfig.ProviderInfo.Name == providerToInstall.Name - }) { - return nil - } - - if !yesFlag { - form := huh.NewForm( - huh.NewGroup( - huh.NewConfirm(). - Title("Add a Target?"). - Value(&yesFlag), - ), - ).WithTheme(views.GetCustomTheme()) - - err := form.Run() - if err != nil { - return err - } - } - - if yesFlag { - targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), providerToInstall.Name).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - targetConfigToSet := &targetconfig.TargetConfigView{ - Options: "{}", - ProviderInfo: targetconfig.ProviderInfo{ - Name: providerToInstall.Name, - Version: providerToInstall.Version, - Label: providerToInstall.Label, - }, - } - - err = targetconfig.NewTargetConfigNameInput(&targetConfigToSet.Name, []string{}) - if err != nil { - return err - } - - err = targetconfig.SetTargetConfigForm(targetConfigToSet, *targetConfigManifest) - if err != nil { - return err - } - - id := stringid.GenerateRandomID() - id = stringid.TruncateID(id) - - targetData := apiclient.CreateTargetDTO{ - Id: id, - Name: targetConfigToSet.Name, - TargetConfigName: targetConfigToSet.Name, - } - - _, res, err = apiClient.TargetAPI.CreateTarget(context.Background()).Target(targetData).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - if err != nil { - return err - } - - views.RenderInfoMessage("Target set successfully") - } return nil }, } @@ -178,26 +119,25 @@ func init() { providerInstallCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") } -func GetProviderListFromManifest(manifest *manager.ProvidersManifest) []apiclient.Provider { - providerList := []apiclient.Provider{} - for providerName, providerManifest := range *manifest { - for version := range providerManifest.Versions { - providerList = append(providerList, apiclient.Provider{ - Name: providerName, - Label: providerManifest.Label, - Version: version, - }) +func InstallProvider(apiClient *apiclient.APIClient, runnerId string, providerToInstall provider.ProviderView, providersManifest *util.ProvidersManifest) error { + downloadUrls := convertOSToStringMap((*providersManifest)[providerToInstall.Name].Versions[providerToInstall.Version].DownloadUrls) + + err := views_util.WithInlineSpinner("Installing", func() error { + res, err := apiClient.ProviderAPI.InstallProvider(context.Background(), runnerId).InstallProviderDto(apiclient.InstallProviderDTO{ + Name: providerToInstall.Name, + DownloadUrls: downloadUrls, + }).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) } - } - slices.SortFunc(providerList, func(a, b apiclient.Provider) int { - return strings.Compare(a.Name, b.Name) + return cmd_common.AwaitProviderInstalled(runnerId, providerToInstall.Name, providerToInstall.Version) }) - return providerList + return err } -func ConvertOSToStringMap(downloadUrls map[os.OperatingSystem]string) map[string]string { +func convertOSToStringMap(downloadUrls map[os.OperatingSystem]string) map[string]string { stringMap := map[string]string{} for os, url := range downloadUrls { stringMap[string(os)] = url @@ -205,21 +145,3 @@ func ConvertOSToStringMap(downloadUrls map[os.OperatingSystem]string) map[string return stringMap } - -func InstallProvider(apiClient *apiclient.APIClient, providerToInstall provider.ProviderView, providersManifest *manager.ProvidersManifest) error { - downloadUrls := ConvertOSToStringMap((*providersManifest)[providerToInstall.Name].Versions[providerToInstall.Version].DownloadUrls) - err := views_util.WithInlineSpinner("Installing", func() error { - res, err := apiClient.ProviderAPI.InstallProviderExecute(apiclient.ApiInstallProviderRequest{}.Provider(apiclient.InstallProviderRequest{ - Name: providerToInstall.Name, - DownloadUrls: downloadUrls, - })) - - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - - return nil - }) - - return err -} diff --git a/pkg/cmd/provider/list.go b/pkg/cmd/provider/list.go index bce26c5394..90fddbd935 100644 --- a/pkg/cmd/provider/list.go +++ b/pkg/cmd/provider/list.go @@ -43,7 +43,7 @@ var providerListCmd = &cobra.Command{ }, } -func GetProviderViewOptions(apiClient *apiclient.APIClient, latestProviders []apiclient.Provider, ctx context.Context) ([]provider.ProviderView, error) { +func GetProviderViewOptions(ctx context.Context, apiClient *apiclient.APIClient, latestProviders []apiclient.ProviderInfo) ([]provider.ProviderView, error) { var result []provider.ProviderView installedProviders, res, err := apiClient.ProviderAPI.ListProviders(ctx).Execute() @@ -55,20 +55,26 @@ func GetProviderViewOptions(apiClient *apiclient.APIClient, latestProviders []ap for _, installedProvider := range installedProviders { providerMap[installedProvider.Name] = provider.ProviderView{ - Name: installedProvider.Name, - Label: installedProvider.Label, - Version: installedProvider.Version, - Installed: util.Pointer(true), + Name: installedProvider.Name, + Label: installedProvider.Label, + Version: installedProvider.Version, + Installed: util.Pointer(true), + RunnerId: installedProvider.RunnerId, + RunnerName: installedProvider.RunnerName, + TargetConfigManifest: installedProvider.TargetConfigManifest, } } for _, latestProvider := range latestProviders { if _, exists := providerMap[latestProvider.Name]; !exists { providerMap[latestProvider.Name] = provider.ProviderView{ - Name: latestProvider.Name, - Label: latestProvider.Label, - Version: latestProvider.Version, - Installed: util.Pointer(false), + Name: latestProvider.Name, + Label: latestProvider.Label, + Version: latestProvider.Version, + Installed: util.Pointer(false), + RunnerId: latestProvider.RunnerId, + RunnerName: latestProvider.RunnerName, + TargetConfigManifest: latestProvider.TargetConfigManifest, } } } diff --git a/pkg/cmd/provider/uninstall.go b/pkg/cmd/provider/uninstall.go index 01475c9176..51d9ac403a 100644 --- a/pkg/cmd/provider/uninstall.go +++ b/pkg/cmd/provider/uninstall.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/provider" @@ -21,6 +22,8 @@ var providerUninstallCmd = &cobra.Command{ Args: cobra.NoArgs, Aliases: []string{"u"}, RunE: func(cmd *cobra.Command, args []string) error { + var selectedRunnerId string + ctx := context.Background() apiClient, err := apiclient.GetApiClient(nil) @@ -28,6 +31,25 @@ var providerUninstallCmd = &cobra.Command{ return err } + if len(args) == 0 { + selectedRunner, err := cmd_common.GetRunnerFlow(apiClient, "Manage Providers") + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + + if selectedRunner == nil { + return nil + } + + selectedRunnerId = selectedRunner.Id + } else { + selectedRunnerId = args[0] + } + providerList, res, err := apiClient.ProviderAPI.ListProviders(ctx).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) @@ -51,7 +73,7 @@ var providerUninstallCmd = &cobra.Command{ return nil } - res, err = apiClient.ProviderAPI.UninstallProvider(ctx, providerToUninstall.Name).Execute() + res, err = apiClient.ProviderAPI.UninstallProvider(ctx, selectedRunnerId, providerToUninstall.Name).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/provider/update.go b/pkg/cmd/provider/update.go index 86b5edfea4..2f53dfd4cd 100644 --- a/pkg/cmd/provider/update.go +++ b/pkg/cmd/provider/update.go @@ -7,10 +7,11 @@ import ( "context" "fmt" + "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/views/provider" views_util "github.com/daytonaio/daytona/pkg/views/util" log "github.com/sirupsen/logrus" @@ -25,6 +26,8 @@ var providerUpdateCmd = &cobra.Command{ Args: cobra.NoArgs, Aliases: []string{"up"}, RunE: func(cmd *cobra.Command, args []string) error { + var selectedRunnerId string + ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -32,6 +35,25 @@ var providerUpdateCmd = &cobra.Command{ return err } + if len(args) == 0 { + selectedRunner, err := cmd_common.GetRunnerFlow(apiClient, "Manage Providers") + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + + if selectedRunner == nil { + return nil + } + + selectedRunnerId = selectedRunner.Id + } else { + selectedRunnerId = args[0] + } + providerList, res, err := apiClient.ProviderAPI.ListProviders(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) @@ -47,9 +69,7 @@ var providerUpdateCmd = &cobra.Command{ return apiclient_util.HandleErrorResponse(res, err) } - providerManager := manager.GetProviderManager(&manager.ProviderManagerConfig{RegistryUrl: serverConfig.RegistryUrl}) - - providersManifest, err := providerManager.GetProvidersManifest() + providersManifest, err := util.GetProvidersManifest(serverConfig.RegistryUrl) if err != nil { return err } @@ -57,7 +77,7 @@ var providerUpdateCmd = &cobra.Command{ if allFlag { for _, provider := range providerList { fmt.Printf("Updating provider %s\n", provider.Name) - err := updateProvider(provider.Name, providersManifest, apiClient) + err := updateProvider(selectedRunnerId, provider.Name, providersManifest, apiClient) if err != nil { log.Error(fmt.Sprintf("Failed to update provider %s: %s", provider.Name, err)) } else { @@ -80,7 +100,7 @@ var providerUpdateCmd = &cobra.Command{ return nil } - err = updateProvider(providerToUpdate.Name, providersManifest, apiClient) + err = updateProvider(selectedRunnerId, providerToUpdate.Name, providersManifest, apiClient) if err != nil { return err } @@ -90,7 +110,7 @@ var providerUpdateCmd = &cobra.Command{ }, } -func updateProvider(providerName string, providersManifest *manager.ProvidersManifest, apiClient *apiclient.APIClient) error { +func updateProvider(runnerId string, providerName string, providersManifest *util.ProvidersManifest, apiClient *apiclient.APIClient) error { providerManifest, ok := (*providersManifest)[providerName] if !ok { return fmt.Errorf("provider %s not found in manifest", providerName) @@ -102,12 +122,9 @@ func updateProvider(providerName string, providersManifest *manager.ProvidersMan version = *latest } - downloadUrls := ConvertOSToStringMap(version.DownloadUrls) + downloadUrls := convertOSToStringMap(version.DownloadUrls) - res, err := apiClient.ProviderAPI.InstallProviderExecute(apiclient.ApiInstallProviderRequest{}.Provider(apiclient.InstallProviderRequest{ - Name: providerName, - DownloadUrls: downloadUrls, - })) + res, err := apiClient.ProviderAPI.UpdateProvider(context.Background(), runnerId, providerName).DownloadUrls(downloadUrls).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 49ebdff90d..0bb001231b 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/server/bootstrap" + "github.com/daytonaio/daytona/pkg/cmd/bootstrap" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/server" @@ -46,6 +46,12 @@ var purgeCmd = &cobra.Command{ return err } + // FIXME: TODO + // runnerConfig, err := runner.GetConfig() + // if err != nil { + // return err + // } + serverConfigDir, err := server.GetConfigDir() if err != nil { return err @@ -101,11 +107,6 @@ var purgeCmd = &cobra.Command{ defer telemetryService.Close() - err = bootstrap.InitProviderManager(serverConfig, serverConfigDir) - if err != nil { - return err - } - fmt.Println("Purging the server") server, err := bootstrap.GetInstance(serverConfig, serverConfigDir, internal.Version, telemetryService) if err != nil { diff --git a/pkg/cmd/runner/config.go b/pkg/cmd/runner/config.go new file mode 100644 index 0000000000..a3da208356 --- /dev/null +++ b/pkg/cmd/runner/config.go @@ -0,0 +1,40 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + view "github.com/daytonaio/daytona/pkg/views/runner" + "github.com/spf13/cobra" + + "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/runner" +) + +var configCmd = &cobra.Command{ + Use: "config", + Aliases: []string{"info"}, + Short: "Outputs Daytona Runner config", + RunE: func(cmd *cobra.Command, args []string) error { + config, err := runner.GetConfig() + if err != nil { + return err + } + + if format.FormatFlag != "" { + formattedData := format.NewFormatter(config) + formattedData.Print() + return nil + } + + view.RenderConfig(config, showKeyFlag) + return nil + }, +} + +var showKeyFlag bool + +func init() { + configCmd.Flags().BoolVarP(&showKeyFlag, "key", "k", false, "Show API Key") + format.RegisterFormatFlag(configCmd) +} diff --git a/pkg/cmd/runner/configure.go b/pkg/cmd/runner/configure.go new file mode 100644 index 0000000000..0d0a3b7529 --- /dev/null +++ b/pkg/cmd/runner/configure.go @@ -0,0 +1,76 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/views" + runner_view "github.com/daytonaio/daytona/pkg/views/runner" + "github.com/spf13/cobra" +) + +var configureCmd = &cobra.Command{ + Use: "configure", + Short: "Configure Daytona Runner", + RunE: func(cmd *cobra.Command, args []string) error { + var configExisted bool + + config, err := runner.GetConfig() + if err != nil { + if errors.Is(err, runner.ErrConfigNotFound) { + configExisted = false + config, err = runner.GetDefaultConfig() + if err != nil { + return err + } + } else { + return err + } + } + + if idFlag != "" && nameFlag != "" && apiUrlFlag != "" && apiKeyFlag != "" { + config.Id = idFlag + config.Name = nameFlag + config.ServerApiUrl = apiUrlFlag + config.ServerApiKey = apiKeyFlag + } else { + config, err = runner_view.ConfigurationForm(config) + if err != nil { + return err + } + } + + config.ClientId = idFlag + + err = runner.Save(*config) + if err != nil { + return err + } + + infoMessage := "Runner configuration updated. " + + if configExisted { + infoMessage += "You need to restart the runner for the changes to take effect." + } else { + infoMessage += "To start running jobs, run 'daytona runner start'" + } + + views.RenderContainerLayout(views.GetInfoMessage(infoMessage)) + return nil + }, +} + +var idFlag string +var nameFlag string +var apiUrlFlag string +var apiKeyFlag string + +func init() { + configureCmd.Flags().StringVar(&idFlag, "id", "", "Runner ID") + configureCmd.Flags().StringVar(&nameFlag, "name", "", "Runner Name") + configureCmd.Flags().StringVar(&apiUrlFlag, "api-url", "", "Daytona Server API URL") + configureCmd.Flags().StringVar(&apiKeyFlag, "api-key", "", "Runner API Key") +} diff --git a/pkg/cmd/runner/logs.go b/pkg/cmd/runner/logs.go new file mode 100644 index 0000000000..a5cdc2f0bf --- /dev/null +++ b/pkg/cmd/runner/logs.go @@ -0,0 +1,73 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "errors" + "io" + + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/runner" + logs_view "github.com/daytonaio/daytona/pkg/views/logs" + "github.com/spf13/cobra" +) + +var followFlag bool + +var logsCmd = &cobra.Command{ + Use: "logs", + Short: "View runner logs", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + c, err := runner.GetConfig() + if err != nil { + return err + } + + configDir, err := runner.GetConfigDir() + if err != nil { + return err + } + + loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{ + LogsDir: runner.GetLogsDir(configDir), + }) + + logReader, err := loggerFactory.CreateLogReader(c.Id) + if err != nil { + return err + } + + logs_view.SetupLongestPrefixLength([]string{c.Name}) + + entryChan := make(chan interface{}) + errChan := make(chan error) + go func() { + logs.ReadJSONLog(context.Background(), logReader, followFlag, entryChan, errChan) + }() + + go func() { + for entry := range entryChan { + logEntry, ok := entry.(logs.LogEntry) + if !ok || logEntry == (logs.LogEntry{}) { + continue + } + + logs_view.DisplayLogEntry(logEntry, logs_view.STATIC_INDEX) + } + }() + + err = <-errChan + if err != nil && !errors.Is(err, io.EOF) { + return err + } + + return nil + }, +} + +func init() { + logsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") +} diff --git a/pkg/cmd/runner/purge.go b/pkg/cmd/runner/purge.go new file mode 100644 index 0000000000..daeb504ae7 --- /dev/null +++ b/pkg/cmd/runner/purge.go @@ -0,0 +1,17 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "github.com/spf13/cobra" +) + +var purgeCmd = &cobra.Command{ + Use: "purge", + Short: "Purges the runner", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + return nil + }, +} diff --git a/pkg/cmd/runner/restart.go b/pkg/cmd/runner/restart.go new file mode 100644 index 0000000000..bd1cbf78eb --- /dev/null +++ b/pkg/cmd/runner/restart.go @@ -0,0 +1,43 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "errors" + "fmt" + + "github.com/daytonaio/daytona/pkg/cmd/common/daemon" + "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/views" + "github.com/spf13/cobra" +) + +var restartCmd = &cobra.Command{ + Use: "restart", + Short: "Restarts the runner", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + views.RenderInfoMessage("Stopping the Daytona Runner daemon...") + err := daemon.Stop(svcConfig) + if err != nil { + if errors.Is(err, daemon.ErrDaemonNotInstalled) { + return fmt.Errorf("%w. First run 'daytona runner start' to start the runner daemon", err) + } + return err + } + + c, err := server.GetConfig() + if err != nil { + return err + } + + views.RenderInfoMessage("Starting the Daytona Runner daemon...") + err = daemon.Start(c.LogFile.Path, svcConfig) + if err != nil { + return err + } + views.RenderContainerLayout(views.GetBoldedInfoMessage("Daytona Runner daemon restarted successfully")) + return nil + }, +} diff --git a/pkg/cmd/runner/runner.go b/pkg/cmd/runner/runner.go new file mode 100644 index 0000000000..dafb361c75 --- /dev/null +++ b/pkg/cmd/runner/runner.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "github.com/daytonaio/daytona/internal/util" + "github.com/spf13/cobra" +) + +var RunnerCmd = &cobra.Command{ + Use: "runner", + Short: "Manage the runner", + GroupID: util.RUNNER_GROUP, +} + +func init() { + RunnerCmd.AddCommand(configCmd) + RunnerCmd.AddCommand(configureCmd) + RunnerCmd.AddCommand(startCmd) + RunnerCmd.AddCommand(serveCmd) + RunnerCmd.AddCommand(daemonServeCmd) + RunnerCmd.AddCommand(stopCmd) + RunnerCmd.AddCommand(restartCmd) + RunnerCmd.AddCommand(logsCmd) + RunnerCmd.AddCommand(purgeCmd) +} diff --git a/pkg/cmd/runner/serve.go b/pkg/cmd/runner/serve.go new file mode 100644 index 0000000000..2c5b6050a1 --- /dev/null +++ b/pkg/cmd/runner/serve.go @@ -0,0 +1,90 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "io" + "os" + + "github.com/daytonaio/daytona/internal" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/bootstrap" + "github.com/daytonaio/daytona/pkg/posthogservice" + "github.com/daytonaio/daytona/pkg/runner" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var daemonServeCmd = &cobra.Command{ + Use: "daemon-serve", + Short: "Used by the daemon to start the Daytona Runner", + Args: cobra.NoArgs, + Hidden: true, + RunE: serveCmd.RunE, +} + +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Starts the runner in the foreground", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + if log.GetLevel() < log.InfoLevel { + log.SetLevel(log.InfoLevel) + } + + runnerConfig, err := runner.GetConfig() + if err != nil { + return err + } + + runnerConfigDir, err := runner.GetConfigDir() + if err != nil { + return err + } + + telemetryService := posthogservice.NewTelemetryService(posthogservice.PosthogServiceConfig{ + ApiKey: internal.PosthogApiKey, + Endpoint: internal.PosthogEndpoint, + Version: internal.Version, + }) + + apiClient, err := apiclient_util.GetRunnerApiClient(runnerConfig.ServerApiUrl, runnerConfig.ServerApiKey, runnerConfig.ClientId, runnerConfig.TelemetryEnabled) + if err != nil { + return err + } + + serverConfig, _, err := apiClient.ServerAPI.GetConfig(ctx).Execute() + if err != nil { + return err + } + + var runnerLogWriter io.Writer + + if runnerConfig.LogFile != nil { + logFile, err := os.OpenFile(runnerConfig.LogFile.Path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer logFile.Close() + runnerLogWriter = logFile + } + + runner, err := bootstrap.GetRemoteRunner(bootstrap.RemoteRunnerParams{ + ApiClient: apiClient, + ServerConfig: serverConfig, + RunnerConfig: runnerConfig, + ConfigDir: runnerConfigDir, + LogWriter: runnerLogWriter, + TelemetryService: telemetryService, + }) + if err != nil { + return err + } + + return runner.Start(ctx) + }, +} diff --git a/pkg/cmd/runner/start.go b/pkg/cmd/runner/start.go new file mode 100644 index 0000000000..695e2cee68 --- /dev/null +++ b/pkg/cmd/runner/start.go @@ -0,0 +1,87 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "fmt" + "os" + "runtime" + "time" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common/daemon" + "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/views" + "github.com/kardianos/service" + "github.com/spf13/cobra" + + log "github.com/sirupsen/logrus" +) + +var svcConfig = &service.Config{ + Name: "DaytonaRunnerDaemon", + DisplayName: "Daytona Runner", + Description: "Daytona Runner daemon.", + Arguments: []string{"runner", "daemon-serve"}, +} + +var startCmd = &cobra.Command{ + Use: "start", + Short: "Starts the runner", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + if log.GetLevel() < log.InfoLevel { + // for now, force the log level to info when running the server + log.SetLevel(log.InfoLevel) + } + + c, err := runner.GetConfig() + if err != nil { + return err + } + + if c.ServerApiUrl == "" || c.ServerApiKey == "" { + views.RenderInfoMessage("Configure the runner by using 'daytona runner configure' before starting it.") + return nil + } + + views.RenderInfoMessageBold("Starting the Daytona Runner daemon...") + + err = daemon.Start(c.LogFile.Path, svcConfig) + if err != nil { + return err + } + + err = checkServerConnection(*c) + if err != nil { + return err + } + + switch runtime.GOOS { + case "linux": + fmt.Printf("Use `loginctl enable-linger %s` to allow the service to run after logging out.\n", os.Getenv("USER")) + } + return nil + }, +} + +func checkServerConnection(c runner.Config) error { + apiClient, err := apiclient_util.GetRunnerApiClient(c.ServerApiUrl, c.ServerApiKey, c.ClientId, c.TelemetryEnabled) + if err != nil { + return err + } + + for i := 0; i < 30; i++ { + time.Sleep(1 * time.Second) + _, _, err = apiClient.DefaultAPI.HealthCheck(context.Background()).Execute() + if err != nil { + continue + } + + return nil + } + + return err +} diff --git a/pkg/cmd/runner/stop.go b/pkg/cmd/runner/stop.go new file mode 100644 index 0000000000..f928d007bf --- /dev/null +++ b/pkg/cmd/runner/stop.go @@ -0,0 +1,28 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "errors" + "fmt" + + "github.com/daytonaio/daytona/pkg/cmd/common/daemon" + "github.com/daytonaio/daytona/pkg/views" + "github.com/spf13/cobra" +) + +var stopCmd = &cobra.Command{ + Use: "stop", + Short: "Stops the runner", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + views.RenderInfoMessageBold("Stopping the Daytona Runner daemon...") + err := daemon.Stop(svcConfig) + if errors.Is(err, daemon.ErrDaemonNotInstalled) { + return fmt.Errorf("%w. First run 'daytona runner start' to start the runner daemon", err) + } + + return err + }, +} diff --git a/pkg/cmd/server/bootstrap/get_job_runner.go b/pkg/cmd/server/bootstrap/get_job_runner.go deleted file mode 100644 index 9a2e848164..0000000000 --- a/pkg/cmd/server/bootstrap/get_job_runner.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package bootstrap - -import ( - "context" - "fmt" - "path/filepath" - "strings" - - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/build" - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/docker" - jobs_build "github.com/daytonaio/daytona/pkg/jobs/build" - "github.com/daytonaio/daytona/pkg/jobs/target" - "github.com/daytonaio/daytona/pkg/jobs/workspace" - "github.com/daytonaio/daytona/pkg/logs" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/provisioner" - "github.com/daytonaio/daytona/pkg/runners" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/stores" - "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/docker/docker/client" - - "github.com/daytonaio/daytona/pkg/runners/runner" -) - -func GetJobRunner(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (runners.IJobRunner, error) { - jobService := server.GetInstance(nil).JobService - - workspaceJobFactory, err := GetWorkspaceJobFactory(c, configDir, version, telemetryService) - if err != nil { - return nil, err - } - - targetJobFactory, err := GetTargetJobFactory(c, configDir, version, telemetryService) - if err != nil { - return nil, err - } - - buildJobFactory, err := GetBuildJobFactory(c, configDir, version, telemetryService) - if err != nil { - return nil, err - } - - return runner.NewJobRunner(runner.JobRunnerConfig{ - ListPendingJobs: func(ctx context.Context) ([]*models.Job, error) { - return jobService.List(ctx, &stores.JobFilter{ - States: &[]models.JobState{models.JobStatePending}, - }) - }, - UpdateJobState: func(ctx context.Context, job *models.Job, state models.JobState, err *error) error { - var jobErr *string - if err != nil { - jobErr = util.Pointer((*err).Error()) - } - return jobService.SetState(ctx, job.Id, state, jobErr) - }, - WorkspaceJobFactory: workspaceJobFactory, - TargetJobFactory: targetJobFactory, - BuildJobFactory: buildJobFactory, - }), nil -} - -func GetWorkspaceJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (workspace.IWorkspaceJobFactory, error) { - envVarService := server.GetInstance(nil).EnvironmentVariableService - - gitProviderService := server.GetInstance(nil).GitProviderService - - targetLogsDir, err := server.GetTargetLogsDir(configDir) - if err != nil { - return nil, err - } - buildLogsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) - - providerManager := manager.GetProviderManager(nil) - - provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ - ProviderManager: providerManager, - }) - - targetService := server.GetInstance(nil).TargetService - - workspaceService := server.GetInstance(nil).WorkspaceService - - return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ - FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { - workspaceDto, err := workspaceService.GetWorkspace(ctx, workspaceId, services.WorkspaceRetrievalParams{Verbose: false}) - if err != nil { - return nil, err - } - return &workspaceDto.Workspace, nil - }, - FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) - if err != nil { - return nil, err - } - return &targetDto.Target, nil - }, - FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(ctx, id) - }, - GetWorkspaceEnvironmentVariables: func(ctx context.Context, w *models.Workspace) (map[string]string, error) { - serverEnvVars, err := envVarService.Map(ctx) - if err != nil { - return nil, err - } - - return util.MergeEnvVars(serverEnvVars, w.EnvVars), nil - }, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { - return telemetryService.TrackServerEvent(event, clientId, props) - }, - LoggerFactory: loggerFactory, - Provisioner: provisioner, - BuilderImage: c.BuilderImage, - }), nil -} - -func GetTargetJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (target.ITargetJobFactory, error) { - targetLogsDir, err := server.GetTargetLogsDir(configDir) - if err != nil { - return nil, err - } - buildLogsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(&targetLogsDir, &buildLogsDir) - - providerManager := manager.GetProviderManager(nil) - - provisioner := provisioner.NewProvisioner(provisioner.ProvisionerConfig{ - ProviderManager: providerManager, - }) - - targetService := server.GetInstance(nil).TargetService - - return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ - FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) - if err != nil { - return nil, err - } - return &targetDto.Target, nil - }, - HandleSuccessfulCreation: func(ctx context.Context, targetId string) error { - return targetService.HandleSuccessfulCreation(ctx, targetId) - }, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { - return telemetryService.TrackServerEvent(event, clientId, props) - }, - LoggerFactory: loggerFactory, - Provisioner: provisioner, - }), nil -} - -func GetBuildJobFactory(c *server.Config, configDir string, version string, telemetryService telemetry.TelemetryService) (jobs_build.IBuildJobFactory, error) { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - return nil, err - } - - dockerClient := docker.NewDockerClient(docker.DockerClientConfig{ - ApiClient: cli, - }) - - logsDir, err := build.GetBuildLogsDir() - if err != nil { - return nil, err - } - loggerFactory := logs.NewLoggerFactory(nil, &logsDir) - - buildService := server.GetInstance(nil).BuildService - - buildImageNamespace := c.BuildImageNamespace - if buildImageNamespace != "" { - buildImageNamespace = fmt.Sprintf("/%s", buildImageNamespace) - } - buildImageNamespace = strings.TrimSuffix(buildImageNamespace, "/") - - var builderRegistry *models.ContainerRegistry - - envVarService := server.GetInstance(nil).EnvironmentVariableService - - envVars, err := envVarService.Map(context.Background()) - if err != nil { - builderRegistry = &models.ContainerRegistry{ - Server: c.BuilderRegistryServer, - } - } else { - builderRegistry = envVars.FindContainerRegistry(c.BuilderRegistryServer) - } - - if builderRegistry == nil { - builderRegistry = &models.ContainerRegistry{ - Server: util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain), - } - } - - if builderRegistry == nil { - builderRegistry = &models.ContainerRegistry{ - Server: util.GetFrpcRegistryDomain(c.Id, c.Frps.Domain), - } - } - - _, containerRegistries := common.ExtractContainerRegistryFromEnvVars(envVars) - - return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ - FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { - return buildService.Find(ctx, &services.BuildFilter{ - StoreFilter: stores.BuildFilter{ - Id: &buildId, - }, - }) - }, - ListSuccessfulBuilds: func(ctx context.Context, repoUrl string) ([]*models.Build, error) { - buildDtos, err := buildService.List(ctx, &services.BuildFilter{ - StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, - StoreFilter: stores.BuildFilter{ - RepositoryUrl: &repoUrl, - }, - }) - if err != nil { - return nil, err - } - - var builds []*models.Build - for _, buildDto := range buildDtos { - builds = append(builds, &buildDto.Build) - } - return builds, nil - }, - ListConfigsForUrl: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { - return server.GetInstance(nil).GitProviderService.ListConfigsForUrl(ctx, repoUrl) - }, - CheckImageExists: func(ctx context.Context, image string) bool { - _, _, err = cli.ImageInspectWithRaw(context.Background(), image) - return err == nil - }, - DeleteImage: func(ctx context.Context, image string, force bool) error { - return dockerClient.DeleteImage(image, force, nil) - }, - TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { - return telemetryService.TrackBuildRunnerEvent(event, clientId, props) - }, - LoggerFactory: loggerFactory, - BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ - Image: c.BuilderImage, - ContainerRegistries: containerRegistries, - BuildImageContainerRegistry: builderRegistry, - BuildService: buildService, - BuildImageNamespace: buildImageNamespace, - LoggerFactory: loggerFactory, - DefaultWorkspaceImage: c.DefaultWorkspaceImage, - DefaultWorkspaceUser: c.DefaultWorkspaceUser, - }), - BasePath: filepath.Join(configDir, "builds"), - }), nil -} diff --git a/pkg/cmd/server/bootstrap/init_provider_manager.go b/pkg/cmd/server/bootstrap/init_provider_manager.go deleted file mode 100644 index 1f4241057f..0000000000 --- a/pkg/cmd/server/bootstrap/init_provider_manager.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package bootstrap - -import ( - "context" - "net/url" - "path/filepath" - - "github.com/daytonaio/daytona/internal" - "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/db" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider/manager" - "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/headscale" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" - "github.com/daytonaio/daytona/pkg/services" -) - -func InitProviderManager(c *server.Config, configDir string) error { - targetLogsDir, err := server.GetTargetLogsDir(configDir) - if err != nil { - return err - } - - headscaleServer := headscale.NewHeadscaleServer(&headscale.HeadscaleServerConfig{ - ServerId: c.Id, - FrpsDomain: c.Frps.Domain, - FrpsProtocol: c.Frps.Protocol, - HeadscalePort: c.HeadscalePort, - ConfigDir: filepath.Join(configDir, "headscale"), - Frps: c.Frps, - }) - err = headscaleServer.Init() - if err != nil { - return err - } - - headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) - - version := internal.Version - - dbPath, err := getDbPath() - if err != nil { - return err - } - - dbConnection := db.GetSQLiteConnection(dbPath) - - store := db.NewStore(dbConnection) - - targetConfigStore, err := db.NewTargetConfigStore(store) - if err != nil { - return err - } - - targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ - TargetConfigStore: targetConfigStore, - }) - - _ = manager.GetProviderManager(&manager.ProviderManagerConfig{ - LogsDir: targetLogsDir, - ApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - DaytonaDownloadUrl: getDaytonaScriptUrl(c), - ServerUrl: headscaleUrl, - ServerVersion: version, - RegistryUrl: c.RegistryUrl, - BaseDir: c.ProvidersDir, - CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { - return headscaleServer.CreateAuthKey(headscale.HEADSCALE_USERNAME) - }, - ServerPort: c.HeadscalePort, - ApiPort: c.ApiPort, - GetTargetConfigMap: func(ctx context.Context) (map[string]*models.TargetConfig, error) { - return targetConfigService.Map(ctx) - }, - CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { - _, err := targetConfigService.Add(ctx, services.AddTargetConfigDTO{ - Name: name, - Options: options, - ProviderInfo: providerInfo, - }) - return err - }, - }) - - return nil -} - -func getDaytonaScriptUrl(config *server.Config) string { - url, _ := url.JoinPath(util.GetFrpcApiUrl(config.Frps.Protocol, config.Id, config.Frps.Domain), "binary", "script") - return url -} diff --git a/pkg/cmd/server/logs/logs.go b/pkg/cmd/server/logs/logs.go index 92b2facf0f..ede3996f00 100644 --- a/pkg/cmd/server/logs/logs.go +++ b/pkg/cmd/server/logs/logs.go @@ -17,6 +17,7 @@ import ( "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/server/selection" @@ -101,7 +102,7 @@ func readRemoteServerLogFile(ctx context.Context, activeProfile config.Profile, query += fmt.Sprintf("file=%s", filepath.Base(fileFlag)) } - ws, res, err := apiclient_util.GetWebsocketConn(context.Background(), "/log/server", &activeProfile, &query) + ws, res, err := util.GetWebsocketConn(context.Background(), "/log/server", activeProfile.Api.Url, activeProfile.Api.Key, &query) if res.StatusCode == http.StatusNotFound { return apiclient_util.HandleErrorResponse(res, err) } @@ -177,7 +178,7 @@ func readLocalServerLogFile() error { var reader io.Reader if regexp.MustCompile(constants.ZIP_LOG_FILE_NAME_SUFFIX_PATTERN).MatchString(logFile) { - reader, err = util.ReadCompressedFile(logFile) + reader, err = logs.ReadCompressedFile(logFile) } else { reader, err = os.Open(logFile) } @@ -188,7 +189,7 @@ func readLocalServerLogFile() error { msgChan := make(chan []byte) errChan := make(chan error) - go util.ReadLog(context.Background(), reader, followFlag, msgChan, errChan) + go logs.ReadLog(context.Background(), reader, followFlag, msgChan, errChan) for { select { diff --git a/pkg/cmd/server/restart.go b/pkg/cmd/server/restart.go index 3234a02145..f46ac28b82 100644 --- a/pkg/cmd/server/restart.go +++ b/pkg/cmd/server/restart.go @@ -4,9 +4,12 @@ package server import ( + "errors" + "fmt" + "github.com/spf13/cobra" - "github.com/daytonaio/daytona/pkg/cmd/server/daemon" + "github.com/daytonaio/daytona/pkg/cmd/common/daemon" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/views" ) @@ -16,8 +19,11 @@ var restartCmd = &cobra.Command{ Short: "Restarts the Daytona Server daemon", RunE: func(cmd *cobra.Command, args []string) error { views.RenderInfoMessage("Stopping the Daytona Server daemon...") - err := daemon.Stop() + err := daemon.Stop(svcConfig) if err != nil { + if errors.Is(err, daemon.ErrDaemonNotInstalled) { + return fmt.Errorf("%w. First run 'daytona server' to start the server daemon", err) + } return err } @@ -27,7 +33,7 @@ var restartCmd = &cobra.Command{ } views.RenderInfoMessage("Starting the Daytona Server daemon...") - err = daemon.Start(c.LogFile.Path) + err = daemon.Start(c.LogFile.Path, svcConfig) if err != nil { return err } diff --git a/pkg/cmd/server/runner/list.go b/pkg/cmd/server/runner/list.go new file mode 100644 index 0000000000..07e20e94f2 --- /dev/null +++ b/pkg/cmd/server/runner/list.go @@ -0,0 +1,46 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/cmd/format" + "github.com/daytonaio/daytona/pkg/views/server/runner/list" + + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/spf13/cobra" +) + +var listCmd = &cobra.Command{ + Use: "list", + Short: "List runners", + Aliases: []string{"ls"}, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + runners, res, err := apiClient.RunnerAPI.ListRunners(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if format.FormatFlag != "" { + formattedData := format.NewFormatter(runners) + formattedData.Print() + return nil + } + + list.ListRunners(runners) + return nil + }, +} + +func init() { + format.RegisterFormatFlag(listCmd) +} diff --git a/pkg/cmd/server/runner/logs.go b/pkg/cmd/server/runner/logs.go new file mode 100644 index 0000000000..cadc1e29bc --- /dev/null +++ b/pkg/cmd/server/runner/logs.go @@ -0,0 +1,100 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "fmt" + "net/http" + + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" + "github.com/daytonaio/daytona/pkg/common" + runner "github.com/daytonaio/daytona/pkg/views/server/runner/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + + "github.com/spf13/cobra" +) + +var followFlag bool + +var logsCmd = &cobra.Command{ + Use: "logs [RUNNER_ID]", + Short: "View runner logs", + Args: cobra.MaximumNArgs(1), + Aliases: []string{"log"}, + RunE: func(cmd *cobra.Command, args []string) error { + var selectedRunnerId string + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + if len(args) == 0 { + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + runners, res, err := apiClient.RunnerAPI.ListRunners(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(runners) == 0 { + views_util.NotifyEmptyRunnerList(false) + return nil + } + + selectedRunner, err := runner.GetRunnerFromPrompt(runners, activeProfile.Name, "View Logs") + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + + selectedRunnerId = selectedRunner.Name + } else { + selectedRunnerId = args[0] + } + + runner, res, err := apiClient.RunnerAPI.GetRunner(ctx, selectedRunnerId).Execute() + if err != nil { + if res.StatusCode == http.StatusNotFound { + return fmt.Errorf("runner %s not found", selectedRunnerId) + } + return apiclient_util.HandleErrorResponse(res, err) + } + + cmd_common.ReadRunnerLogs(ctx, cmd_common.ReadLogParams{ + Id: runner.Id, + Label: &runner.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Index: util.Pointer(0), + Follow: &followFlag, + }) + return nil + }, +} + +func init() { + logsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") +} diff --git a/pkg/cmd/server/runner/register.go b/pkg/cmd/server/runner/register.go new file mode 100644 index 0000000000..6cf9aa992d --- /dev/null +++ b/pkg/cmd/server/runner/register.go @@ -0,0 +1,76 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + + "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views/server/runner" + runner_view "github.com/daytonaio/daytona/pkg/views/server/runner" + "github.com/docker/docker/pkg/stringid" + + "github.com/spf13/cobra" +) + +var registerCmd = &cobra.Command{ + Use: "register", + Short: "Register runner", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + runnerList, res, err := apiClient.RunnerAPI.ListRunners(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + existingRunnerNames := util.ArrayMap(runnerList, func(r apiclient.RunnerDTO) string { + return r.Name + }) + + name := nameFlag + + if name == "" { + err = runner.RunnerRegistrationView(&name, existingRunnerNames) + if err != nil { + return err + } + } + + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + + runner, res, err := apiClient.RunnerAPI.RegisterRunner(ctx).Runner(apiclient.RegisterRunnerDTO{ + Id: id, + Name: name, + }).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + apiServerConfig, res, err := apiClient.ServerAPI.GetConfig(context.Background()).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + apiUrl := util.GetFrpcApiUrl(apiServerConfig.Frps.Protocol, apiServerConfig.Id, apiServerConfig.Frps.Domain) + runner_view.Notify(runner, apiUrl) + + return nil + }, +} + +var nameFlag string + +func init() { + registerCmd.Flags().StringVarP(&nameFlag, "name", "n", "", "Runner name") +} diff --git a/pkg/cmd/server/runner/runner.go b/pkg/cmd/server/runner/runner.go new file mode 100644 index 0000000000..4271f18b58 --- /dev/null +++ b/pkg/cmd/server/runner/runner.go @@ -0,0 +1,20 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "github.com/spf13/cobra" +) + +var RunnerCmd = &cobra.Command{ + Use: "runner", + Short: "Manage runners", +} + +func init() { + RunnerCmd.AddCommand(logsCmd) + RunnerCmd.AddCommand(listCmd) + RunnerCmd.AddCommand(registerCmd) + RunnerCmd.AddCommand(unregisterCmd) +} diff --git a/pkg/cmd/server/runner/unregister.go b/pkg/cmd/server/runner/unregister.go new file mode 100644 index 0000000000..759179e75d --- /dev/null +++ b/pkg/cmd/server/runner/unregister.go @@ -0,0 +1,108 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "errors" + "fmt" + + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/cmd/daytona/config" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/bootstrap" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views" + runner "github.com/daytonaio/daytona/pkg/views/server/runner/selection" + views_util "github.com/daytonaio/daytona/pkg/views/util" + + "github.com/spf13/cobra" +) + +var unregisterCmd = &cobra.Command{ + Use: "unregister [RUNNER]", + Short: "Unregister runner", + Args: cobra.RangeArgs(0, 1), + RunE: func(cmd *cobra.Command, args []string) error { + + var selectedRunnerId string + + ctx := context.Background() + apiClient, err := apiclient_util.GetApiClient(nil) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + if len(args) == 0 { + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + runners, res, err := apiClient.RunnerAPI.ListRunners(ctx).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + if len(runners) == 0 { + views_util.NotifyEmptyRunnerList(false) + return nil + } + + selectedRunner, err := runner.GetRunnerFromPrompt(runners, activeProfile.Name, "Unregister") + if err != nil { + if common.IsCtrlCAbort(err) { + return nil + } else { + return err + } + } + + selectedRunnerId = selectedRunner.Id + } else { + selectedRunnerId = args[0] + } + + if selectedRunnerId == bootstrap.LOCAL_RUNNER_ID { + return errors.New("to disable the local runner, use the 'daytona server configure' form") + } + + var confirm bool + + if !yesFlag { + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title(fmt.Sprintf("Unregister runner %s?", selectedRunnerId)). + Description("It is recommended that you remove all target configs, targets and workspaces associated with it."). + Value(&confirm), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + } + + res, err := apiClient.RunnerAPI.RemoveRunner(ctx, selectedRunnerId).Execute() + if err != nil { + return apiclient_util.HandleErrorResponse(res, err) + } + + views.RenderInfoMessageBold(fmt.Sprintf("Runner %s unregistered successfully", selectedRunnerId)) + return nil + }, +} + +var yesFlag bool + +func init() { + unregisterCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") +} diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index c15fd89aa9..baf4da6f43 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -9,18 +9,23 @@ import ( "fmt" "os" "os/signal" + "path/filepath" "time" "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/api" - "github.com/daytonaio/daytona/pkg/cmd/server/bootstrap" + "github.com/daytonaio/daytona/pkg/cmd/bootstrap" + "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" + "github.com/daytonaio/daytona/pkg/runner" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/headscale" "github.com/daytonaio/daytona/pkg/server/registry" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -75,11 +80,6 @@ var ServeCmd = &cobra.Command{ Frps: c.Frps, }) - err = bootstrap.InitProviderManager(c, configDir) - if err != nil { - return err - } - server, err := bootstrap.GetInstance(c, configDir, internal.Version, telemetryService) if err != nil { return err @@ -126,23 +126,26 @@ var ServeCmd = &cobra.Command{ return err } - err = server.Start() - if err != nil { - return err - } + localRunnerErrChan := make(chan error) - log.Info("Starting job runner...") - jobRunner, err := bootstrap.GetJobRunner(c, configDir, internal.Version, telemetryService) - if err != nil { - return err - } + go func() { + if c.LocalRunnerDisabled != nil && *c.LocalRunnerDisabled { + err = handleDisabledLocalRunner() + if err != nil { + localRunnerErrChan <- err + } + return + } - // TODO: context? - err = jobRunner.StartRunner(context.Background()) - if err != nil { - return err - } - log.Info("Job runner started") + localRunnerConfig := getLocalRunnerConfig(filepath.Join(configDir, "local-runner")) + + localRunnerErrChan <- startLocalRunner(bootstrap.LocalRunnerParams{ + ServerConfig: c, + RunnerConfig: localRunnerConfig, + ConfigDir: configDir, + TelemetryService: telemetryService, + }) + }() err = waitForApiServerToStart(apiServer) if err != nil { @@ -154,6 +157,13 @@ var ServeCmd = &cobra.Command{ log.Errorf("Failed to start local container registry: %v\nBuilds may not work properly.\nRestart the server to restart the registry.", err) } + if c.LocalRunnerDisabled != nil && !*c.LocalRunnerDisabled { + err = awaitLocalRunnerStarted() + if err != nil { + localRunnerErrChan <- err + } + } + printServerStartedMessage(c, false) err = ensureDefaultProfile(server, c.ApiPort) @@ -165,6 +175,8 @@ var ServeCmd = &cobra.Command{ signal.Notify(interruptChannel, os.Interrupt) select { + case err := <-localRunnerErrChan: + return err case err := <-apiServerErrChan: return err case err := <-headscaleServerErrChan: @@ -226,3 +238,79 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { }, }) } + +func startLocalRunner(params bootstrap.LocalRunnerParams) error { + runnerService := server.GetInstance(nil).RunnerService + + _, err := runnerService.GetRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + if err != nil { + if stores.IsRunnerNotFound(err) { + _, err := runnerService.RegisterRunner(context.Background(), services.RegisterRunnerDTO{ + Id: bootstrap.LOCAL_RUNNER_ID, + Name: bootstrap.LOCAL_RUNNER_ID, + }) + if err != nil { + return err + } + } else { + return err + } + } + + runner, err := bootstrap.GetLocalRunner(params) + if err != nil { + return err + } + + return runner.Start(context.Background()) +} + +func getLocalRunnerConfig(configDir string) *runner.Config { + providersDir := filepath.Join(configDir, "providers") + logFilePath := filepath.Join(configDir, "runner.log") + + return &runner.Config{ + Id: bootstrap.LOCAL_RUNNER_ID, + Name: bootstrap.LOCAL_RUNNER_ID, + ProvidersDir: providersDir, + LogFile: logs.GetDefaultLogFileConfig(logFilePath), + } +} + +func awaitLocalRunnerStarted() error { + server := server.GetInstance(nil) + startTime := time.Now() + + for { + r, err := server.RunnerService.GetRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + if err != nil { + return err + } + + if r.Metadata.Uptime > 0 { + break + } + + if time.Since(startTime) > 10*time.Second { + log.Info("Waiting for runner ...") + startTime = time.Now() + } + + time.Sleep(1 * time.Second) + } + + return nil +} + +func handleDisabledLocalRunner() error { + runnerService := server.GetInstance(nil).RunnerService + + _, err := runnerService.GetRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + if err != nil { + if stores.IsRunnerNotFound(err) { + return nil + } + } + + return runnerService.RemoveRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) +} diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go index ce3681c7e9..4e1815cd36 100644 --- a/pkg/cmd/server/server.go +++ b/pkg/cmd/server/server.go @@ -10,11 +10,13 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/api" - "github.com/daytonaio/daytona/pkg/cmd/server/daemon" + "github.com/daytonaio/daytona/pkg/cmd/common/daemon" "github.com/daytonaio/daytona/pkg/cmd/server/logs" + "github.com/daytonaio/daytona/pkg/cmd/server/runner" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/views" view "github.com/daytonaio/daytona/pkg/views/server" + "github.com/kardianos/service" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -22,6 +24,13 @@ import ( var yesFlag bool +var svcConfig = &service.Config{ + Name: "DaytonaServerDaemon", + DisplayName: "Daytona Server", + Description: "Daytona Server daemon.", + Arguments: []string{"daemon-serve"}, +} + var ServerCmd = &cobra.Command{ Use: "server", Short: "Start the server process in daemon mode", @@ -53,7 +62,7 @@ var ServerCmd = &cobra.Command{ }) views.RenderInfoMessageBold("Starting the Daytona Server daemon...") - err = daemon.Start(c.LogFile.Path) + err = daemon.Start(c.LogFile.Path, svcConfig) if err != nil { return err } @@ -78,6 +87,7 @@ var startCmd = &cobra.Command{ } func init() { + ServerCmd.AddCommand(runner.RunnerCmd) ServerCmd.AddCommand(configureCmd) ServerCmd.AddCommand(configCmd) ServerCmd.AddCommand(logs.LogsCmd) diff --git a/pkg/cmd/server/stop.go b/pkg/cmd/server/stop.go index 12d9ca72ac..da9871ef01 100644 --- a/pkg/cmd/server/stop.go +++ b/pkg/cmd/server/stop.go @@ -4,9 +4,12 @@ package server import ( + "errors" + "fmt" + "github.com/spf13/cobra" - "github.com/daytonaio/daytona/pkg/cmd/server/daemon" + "github.com/daytonaio/daytona/pkg/cmd/common/daemon" "github.com/daytonaio/daytona/pkg/views" ) @@ -15,6 +18,11 @@ var stopCmd = &cobra.Command{ Short: "Stops the Daytona Server daemon", RunE: func(cmd *cobra.Command, args []string) error { views.RenderInfoMessageBold("Stopping the Daytona Server daemon...") - return daemon.Stop() + err := daemon.Stop(svcConfig) + if errors.Is(err, daemon.ErrDaemonNotInstalled) { + return fmt.Errorf("%w. First run 'daytona server' to start the server daemon", err) + } + + return err }, } diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index 3ba6abe656..5a7441e511 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -65,14 +65,15 @@ var targetCreateCmd = &cobra.Command{ logs_view.SetupLongestPrefixLength([]string{createTargetDto.Name}) logs_view.DisplayLogEntry(logs.LogEntry{ - TargetName: &createTargetDto.Name, - Msg: views.GetPrettyLogLine("Request submitted"), + Label: createTargetDto.Name, + Msg: views.GetPrettyLogLine("Request submitted"), }, logs_view.STATIC_INDEX) - go apiclient_util.ReadTargetLogs(logsContext, apiclient_util.ReadLogParams{ + go cmd_common.ReadTargetLogs(logsContext, cmd_common.ReadLogParams{ Id: createTargetDto.Id, Label: &createTargetDto.Name, - ActiveProfile: activeProfile, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, Follow: util.Pointer(true), SkipPrefixLengthSetup: true, }) diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index 99a5f798ea..b34795342a 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -67,7 +67,7 @@ var deleteCmd = &cobra.Command{ } } else { for _, arg := range args { - target, _, err := apiclient_util.GetTarget(arg, false) + target, _, err := apiclient_util.GetTarget(arg) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue diff --git a/pkg/cmd/target/info.go b/pkg/cmd/target/info.go index ed1ed11c25..797dbc3813 100644 --- a/pkg/cmd/target/info.go +++ b/pkg/cmd/target/info.go @@ -31,7 +31,7 @@ var infoCmd = &cobra.Command{ var target *apiclient.TargetDTO if len(args) == 0 { - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Verbose(true).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).ShowOptions(showOptions).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -51,7 +51,7 @@ var infoCmd = &cobra.Command{ } } else { - target, _, err = apiclient_util.GetTarget(args[0], true) + target, _, err = apiclient_util.GetTarget(args[0]) if err != nil { return err } @@ -75,6 +75,9 @@ var infoCmd = &cobra.Command{ }, } +var showOptions bool + func init() { + infoCmd.Flags().BoolVarP(&showOptions, "show-options", "v", false, "Show target options") format.RegisterFormatFlag(infoCmd) } diff --git a/pkg/cmd/target/list.go b/pkg/cmd/target/list.go index f7108bf637..f6a6631658 100644 --- a/pkg/cmd/target/list.go +++ b/pkg/cmd/target/list.go @@ -13,8 +13,6 @@ import ( "github.com/spf13/cobra" ) -var verbose bool - var listCmd = &cobra.Command{ Use: "list", Short: "List targets", @@ -28,7 +26,7 @@ var listCmd = &cobra.Command{ return err } - targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Verbose(verbose).Execute() + targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).ShowOptions(showOptions).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) @@ -50,12 +48,12 @@ var listCmd = &cobra.Command{ return err } - list_view.ListTargets(targetList, verbose, activeProfile.Name) + list_view.ListTargets(targetList, activeProfile.Name, showOptions) return nil }, } func init() { - listCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show verbose output") + listCmd.Flags().BoolVarP(&showOptions, "show-options", "v", false, "Show target options") format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/target/logs.go b/pkg/cmd/target/logs.go index b9b7228b28..5b7e03a84c 100644 --- a/pkg/cmd/target/logs.go +++ b/pkg/cmd/target/logs.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" @@ -51,17 +52,18 @@ var logsCmd = &cobra.Command{ return nil } } else { - target, _, err = apiclient_util.GetTarget(args[0], false) + target, _, err = apiclient_util.GetTarget(args[0]) if err != nil { return err } } - apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ - Id: target.Id, - Label: &target.Name, - ActiveProfile: activeProfile, - Follow: &followFlag, + cmd_common.ReadTargetLogs(ctx, cmd_common.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Follow: &followFlag, }) return nil diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index 7502272586..b3d3920f33 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -45,7 +45,7 @@ var restartCmd = &cobra.Command{ return nil } } else { - target, _, err = apiclient_util.GetTarget(args[0], false) + target, _, err = apiclient_util.GetTarget(args[0]) if err != nil { return err } diff --git a/pkg/cmd/target/setdefault.go b/pkg/cmd/target/setdefault.go index c2ed5e780b..c0a7ac7b31 100644 --- a/pkg/cmd/target/setdefault.go +++ b/pkg/cmd/target/setdefault.go @@ -42,7 +42,7 @@ var setDefaultCmd = &cobra.Command{ target = selection.GetTargetFromPrompt(targetList, false, "Set As Default") } else { - target, _, err = apiclient_util.GetTarget(args[0], true) + target, _, err = apiclient_util.GetTarget(args[0]) if err != nil { return err } diff --git a/pkg/cmd/target/ssh.go b/pkg/cmd/target/ssh.go index 81d3433b94..f13ad49b55 100644 --- a/pkg/cmd/target/ssh.go +++ b/pkg/cmd/target/ssh.go @@ -58,12 +58,16 @@ var sshCmd = &cobra.Command{ return nil } } else { - tg, _, err = apiclient_util.GetTarget(args[0], true) + tg, _, err = apiclient_util.GetTarget(args[0]) if err != nil { return err } } + if tg.TargetConfig.ProviderInfo.AgentlessTarget != nil && *tg.TargetConfig.ProviderInfo.AgentlessTarget { + return agentlessTargetError(tg.TargetConfig.ProviderInfo.Name) + } + if tg.State.Name == apiclient.ResourceStateNameStopped { tgRunningStatus, err := autoStartTarget(*tg) if err != nil { diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 9821a188da..9ba3e8611e 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -62,7 +62,7 @@ var startCmd = &cobra.Command{ if len(selectedTargetsNames) == 1 { targetName := selectedTargetsNames[0] - target, _, err := apiclient_util.GetTarget(targetName, false) + target, _, err := apiclient_util.GetTarget(targetName) if err != nil { return err } @@ -75,7 +75,7 @@ var startCmd = &cobra.Command{ views.RenderInfoMessage(fmt.Sprintf("Target '%s' started successfully", targetName)) } else { for _, targetName := range selectedTargetsNames { - target, _, err := apiclient_util.GetTarget(targetName, false) + target, _, err := apiclient_util.GetTarget(targetName) if err != nil { return err } @@ -179,12 +179,13 @@ func StartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) err } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadTargetLogs(logsContext, apiclient_util.ReadLogParams{ - Id: target.Id, - Label: &target.Name, - ActiveProfile: activeProfile, - Follow: util.Pointer(true), - From: &from, + go cmd_common.ReadTargetLogs(logsContext, cmd_common.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Follow: util.Pointer(true), + From: &from, }) res, err := apiClient.TargetAPI.StartTarget(ctx, target.Id).Execute() @@ -203,5 +204,5 @@ func StartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) err } func agentlessTargetError(providerName string) error { - return fmt.Errorf("%s does not require target state management; you may continue without starting or stopping it", providerName) + return fmt.Errorf("%s does not use a target-level agent; you may continue without managing its state or trying to access it", providerName) } diff --git a/pkg/cmd/target/stop.go b/pkg/cmd/target/stop.go index c24a7ffb44..8500b6750f 100644 --- a/pkg/cmd/target/stop.go +++ b/pkg/cmd/target/stop.go @@ -77,10 +77,11 @@ var stopCmd = &cobra.Command{ return t.Name })) - apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ + cmd_common.ReadTargetLogs(ctx, cmd_common.ReadLogParams{ Id: target.Id, Label: &target.Name, - ActiveProfile: activeProfile, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, From: &from, SkipPrefixLengthSetup: true, }) @@ -89,7 +90,7 @@ var stopCmd = &cobra.Command{ } else { targetId := args[0] - target, _, err := apiclient_util.GetTarget(targetId, false) + target, _, err := apiclient_util.GetTarget(targetId) if err != nil { return err } @@ -99,11 +100,12 @@ var stopCmd = &cobra.Command{ return err } - apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ - Id: target.Id, - Label: &target.Name, - ActiveProfile: activeProfile, - From: &from, + cmd_common.ReadTargetLogs(ctx, cmd_common.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + From: &from, }) views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) @@ -142,10 +144,11 @@ func stopAllTargets(activeProfile config.Profile, from time.Time) error { return t.Name })) - apiclient_util.ReadTargetLogs(ctx, apiclient_util.ReadLogParams{ + cmd_common.ReadTargetLogs(ctx, cmd_common.ReadLogParams{ Id: target.Id, Label: &target.Name, - ActiveProfile: activeProfile, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, From: &from, SkipPrefixLengthSetup: true, }) diff --git a/pkg/cmd/targetconfig/add.go b/pkg/cmd/targetconfig/add.go index 0be3dc6d26..06e4f6ab16 100644 --- a/pkg/cmd/targetconfig/add.go +++ b/pkg/cmd/targetconfig/add.go @@ -14,18 +14,18 @@ import ( "sort" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" internal_util "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/internal/util/apiclient/conversion" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/provider" "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/views" provider_view "github.com/daytonaio/daytona/pkg/views/provider" "github.com/daytonaio/daytona/pkg/views/targetconfig" "github.com/spf13/cobra" - - log "github.com/sirupsen/logrus" ) var pipeFile string @@ -89,26 +89,24 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, apiclient_util.HandleErrorResponse(res, err) } - providersManifest, err := manager.GetProviderManager(&manager.ProviderManagerConfig{ - RegistryUrl: serverConfig.RegistryUrl, - }).GetProvidersManifest() + providersManifest, err := util.GetProvidersManifest(serverConfig.RegistryUrl) if err != nil { - log.Error(err) + return nil, err } - var latestProviders []apiclient.Provider + var latestProviders []apiclient.ProviderInfo if providersManifest != nil { providersManifestLatest := providersManifest.GetLatestVersions() if providersManifestLatest == nil { return nil, errors.New("could not get latest provider versions") } - latestProviders = provider.GetProviderListFromManifest(providersManifestLatest) + latestProviders = conversion.GetProviderListFromManifest(providersManifestLatest) } else { fmt.Println("Could not get provider manifest. Can't check for new providers to install") } - providerViewList, err := provider.GetProviderViewOptions(apiClient, latestProviders, ctx) + providerViewList, err := provider.GetProviderViewOptions(ctx, apiClient, latestProviders) if err != nil { return nil, err } @@ -126,24 +124,43 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, nil } + selectedTargetConfig := &targetconfig.TargetConfigView{ + Name: "", + Options: "{}", + ProviderInfo: targetconfig.ProviderInfo{ + Name: selectedProvider.Name, + RunnerId: selectedProvider.RunnerId, + RunnerName: selectedProvider.RunnerName, + Version: selectedProvider.Version, + Label: selectedProvider.Label, + }, + } + if selectedProvider.Installed != nil && !*selectedProvider.Installed { if providersManifest == nil { return nil, errors.New("could not get providers manifest") } - err = provider.InstallProvider(apiClient, *selectedProvider, providersManifest) + + selectedRunner, err := cmd_common.GetRunnerFlow(apiClient, "Manage Providers") + if err != nil { + if common.IsCtrlCAbort(err) { + return nil, nil + } else { + return nil, err + } + } + + if selectedRunner == nil { + return nil, nil + } + + err = provider.InstallProvider(apiClient, selectedRunner.Id, *selectedProvider, providersManifest) if err != nil { return nil, err } - } - selectedTargetConfig := &targetconfig.TargetConfigView{ - Name: "", - Options: "{}", - ProviderInfo: targetconfig.ProviderInfo{ - Name: selectedProvider.Name, - Version: selectedProvider.Version, - Label: selectedProvider.Label, - }, + selectedProvider.RunnerId = selectedRunner.Id + selectedProvider.RunnerName = selectedRunner.Name } targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() @@ -158,12 +175,7 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, err } - targetConfigManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(context.Background(), selectedProvider.Name).Execute() - if err != nil { - return nil, apiclient_util.HandleErrorResponse(res, err) - } - - err = targetconfig.SetTargetConfigForm(selectedTargetConfig, *targetConfigManifest) + err = targetconfig.SetTargetConfigForm(selectedTargetConfig, selectedProvider.TargetConfigManifest) if err != nil { return nil, err } @@ -171,10 +183,13 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien targetConfigData := apiclient.AddTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, - ProviderInfo: apiclient.TargetProviderInfo{ - Name: selectedProvider.Name, - Version: selectedProvider.Version, - Label: selectedProvider.Label, + ProviderInfo: apiclient.ProviderInfo{ + Name: selectedProvider.Name, + Version: selectedProvider.Version, + Label: selectedProvider.Label, + RunnerId: selectedProvider.RunnerId, + RunnerName: selectedProvider.RunnerName, + TargetConfigManifest: selectedProvider.TargetConfigManifest, }, } @@ -188,9 +203,11 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien Name: targetConfig.Name, Options: targetConfig.Options, ProviderInfo: targetconfig.ProviderInfo{ - Name: targetConfig.ProviderInfo.Name, - Version: targetConfig.ProviderInfo.Version, - Label: targetConfig.ProviderInfo.Label, + Name: targetConfig.ProviderInfo.Name, + RunnerId: targetConfig.ProviderInfo.RunnerId, + RunnerName: targetConfig.ProviderInfo.RunnerName, + Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, }, }, nil } @@ -214,23 +231,21 @@ func handleTargetConfigJSON(data []byte) error { if selectedTargetConfig.Options == "" { return errors.New("option fields are required to setup your target config") } - targetManifest, res, err := apiClient.ProviderAPI.GetTargetConfigManifest(ctx, selectedTargetConfig.ProviderInfo.Name).Execute() - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } - err = validateProperty(*targetManifest, selectedTargetConfig) + targetManifest := selectedTargetConfig.ProviderInfo.TargetConfigManifest + + err = validateProperty(targetManifest, selectedTargetConfig) if err != nil { return err } targetConfigData := apiclient.AddTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, - ProviderInfo: apiclient.TargetProviderInfo{ + ProviderInfo: apiclient.ProviderInfo{ Name: selectedTargetConfig.ProviderInfo.Name, Version: selectedTargetConfig.ProviderInfo.Version, }, } - _, res, err = apiClient.TargetConfigAPI.AddTargetConfig(ctx).TargetConfig(targetConfigData).Execute() + _, res, err := apiClient.TargetConfigAPI.AddTargetConfig(ctx).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/targetconfig/list.go b/pkg/cmd/targetconfig/list.go index 2ed76d0552..c0d32dce4b 100644 --- a/pkg/cmd/targetconfig/list.go +++ b/pkg/cmd/targetconfig/list.go @@ -25,7 +25,7 @@ var listCmd = &cobra.Command{ return err } - targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).Execute() + targetConfigs, res, err := apiClient.TargetConfigAPI.ListTargetConfigs(ctx).ShowOptions(showOptions).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -36,11 +36,14 @@ var listCmd = &cobra.Command{ return nil } - targetconfig.ListTargetConfigs(targetConfigs) + targetconfig.ListTargetConfigs(targetConfigs, showOptions) return nil }, } +var showOptions bool + func init() { + listCmd.Flags().BoolVarP(&showOptions, "show-options", "v", false, "Show target options") format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go index ff8a46ad4a..adb4430316 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/workspace/code.go @@ -69,7 +69,7 @@ var CodeCmd = &cobra.Command{ } } else { var statusCode int - ws, statusCode, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]), true) + ws, statusCode, err = apiclient_util.GetWorkspace(url.PathEscape(args[0])) if err != nil { if statusCode == http.StatusNotFound { log.Debug(err) @@ -92,7 +92,7 @@ var CodeCmd = &cobra.Command{ } } - providerMetadata := *ws.Info.ProviderMetadata + providerMetadata := *ws.ProviderMetadata gpgKey, err := common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId) if err != nil { diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index a09285a54e..7b07e6418b 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -16,6 +16,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/bootstrap" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" @@ -127,9 +128,9 @@ var CreateCmd = &cobra.Command{ } if target != nil { - requestLogEntry.TargetName = &target.Name + requestLogEntry.Label = target.Name } else if createTargetDto != nil { - requestLogEntry.TargetName = &createTargetDto.Name + requestLogEntry.Label = createTargetDto.Name } logs_view.DisplayLogEntry(requestLogEntry, logs_view.STATIC_INDEX) @@ -139,8 +140,8 @@ var CreateCmd = &cobra.Command{ continue } logs_view.DisplayLogEntry(logs.LogEntry{ - WorkspaceName: &createWorkspaceDtos[i].Name, - Msg: fmt.Sprintf("Using detected workspace template '%s'\n", workspaceTemplateName), + Label: createWorkspaceDtos[i].Name, + Msg: fmt.Sprintf("Using detected workspace template '%s'\n", workspaceTemplateName), }, i) } @@ -159,10 +160,11 @@ var CreateCmd = &cobra.Command{ defer stopLogs() if createTargetDto != nil { - go apiclient_util.ReadTargetLogs(logsContext, apiclient_util.ReadLogParams{ + go cmd_common.ReadTargetLogs(logsContext, cmd_common.ReadLogParams{ Id: targetId, Label: &createTargetDto.Name, - ActiveProfile: activeProfile, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, Follow: util.Pointer(true), SkipPrefixLengthSetup: true, }) @@ -200,10 +202,11 @@ var CreateCmd = &cobra.Command{ for i := range createWorkspaceDtos { createWorkspaceDtos[i].TargetId = targetId - go apiclient_util.ReadWorkspaceLogs(logsContext, apiclient_util.ReadLogParams{ + go cmd_common.ReadWorkspaceLogs(logsContext, cmd_common.ReadLogParams{ Id: createWorkspaceDtos[i].Id, Label: &createWorkspaceDtos[i].Name, - ActiveProfile: activeProfile, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, Index: util.Pointer(i), Follow: util.Pointer(true), SkipPrefixLengthSetup: true, @@ -256,7 +259,7 @@ var CreateCmd = &cobra.Command{ createdWorkspaces := []apiclient.WorkspaceDTO{} for _, createWorkspaceDto := range createWorkspaceDtos { - ws, _, err := apiclient_util.GetWorkspace(createWorkspaceDto.Id, true) + ws, _, err := apiclient_util.GetWorkspace(createWorkspaceDto.Id) if err != nil { return err } @@ -276,7 +279,7 @@ var CreateCmd = &cobra.Command{ views.RenderCreationInfoMessage(fmt.Sprintf("Opening the workspace in %s ...", chosenIde.Name)) - return cmd_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *createdWorkspaces[0].Info.ProviderMetadata, YesFlag, gpgKey) + return cmd_common.OpenIDE(chosenIdeId, activeProfile, createWorkspaceDtos[0].Name, *createdWorkspaces[0].ProviderMetadata, YesFlag, gpgKey) }, } @@ -377,5 +380,5 @@ func IsLocalDockerTarget(target *apiclient.TargetDTO) bool { return false } - return !strings.Contains(target.TargetConfig.Options, "Remote Hostname") + return !strings.Contains(target.TargetConfig.Options, "Remote Hostname") && target.TargetConfig.ProviderInfo.RunnerId == bootstrap.LOCAL_RUNNER_ID } diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index 0649176a27..ab77baab27 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -85,7 +85,7 @@ var DeleteCmd = &cobra.Command{ workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, selection.DeleteActionVerb) } else { for _, arg := range args { - workspace, _, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue diff --git a/pkg/cmd/workspace/info.go b/pkg/cmd/workspace/info.go index 51f98ed645..bcbee4d7d8 100644 --- a/pkg/cmd/workspace/info.go +++ b/pkg/cmd/workspace/info.go @@ -34,7 +34,7 @@ var InfoCmd = &cobra.Command{ var ws *apiclient.WorkspaceDTO if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute() + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -54,7 +54,7 @@ var InfoCmd = &cobra.Command{ } } else { - ws, _, err = apiclient_util.GetWorkspace(args[0], true) + ws, _, err = apiclient_util.GetWorkspace(args[0]) if err != nil { return err } diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 6ec34124d0..150f4c33c9 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -14,8 +14,6 @@ import ( "github.com/spf13/cobra" ) -var verbose bool - var ListCmd = &cobra.Command{ Use: "list", Short: "List workspaces", @@ -31,7 +29,7 @@ var ListCmd = &cobra.Command{ return err } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(verbose).Execute() + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } @@ -61,12 +59,11 @@ var ListCmd = &cobra.Command{ return err } - list.ListWorkspaces(workspaceList, specifyGitProviders, verbose, activeProfile.Name) + list.ListWorkspaces(workspaceList, specifyGitProviders, activeProfile.Name) return nil }, } func init() { - ListCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show verbose output") format.RegisterFormatFlag(ListCmd) } diff --git a/pkg/cmd/workspace/logs.go b/pkg/cmd/workspace/logs.go index 662c1db57d..d3c3c9e70a 100644 --- a/pkg/cmd/workspace/logs.go +++ b/pkg/cmd/workspace/logs.go @@ -11,6 +11,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -46,7 +47,7 @@ var LogsCmd = &cobra.Command{ var ws *apiclient.WorkspaceDTO if len(args) == 0 { - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute() + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -66,7 +67,7 @@ var LogsCmd = &cobra.Command{ } } else { - ws, _, err = apiclient_util.GetWorkspace(args[0], true) + ws, _, err = apiclient_util.GetWorkspace(args[0]) if err != nil { return err } @@ -76,12 +77,13 @@ var LogsCmd = &cobra.Command{ return nil } - apiclient_util.ReadWorkspaceLogs(ctx, apiclient_util.ReadLogParams{ - Id: ws.Id, - Label: &ws.Name, - ActiveProfile: activeProfile, - Index: util.Pointer(0), - Follow: &followFlag, + cmd_common.ReadWorkspaceLogs(ctx, cmd_common.ReadLogParams{ + Id: ws.Id, + Label: &ws.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Index: util.Pointer(0), + Follow: &followFlag, }) return nil }, diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/workspace/restart.go index 1b5d9f5461..0edb337569 100644 --- a/pkg/cmd/workspace/restart.go +++ b/pkg/cmd/workspace/restart.go @@ -50,7 +50,7 @@ var RestartCmd = &cobra.Command{ } } else { for _, arg := range args { - workspace, _, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index a3776236ad..2a146ced2b 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -20,6 +20,7 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/docker" + "github.com/daytonaio/daytona/pkg/models" "github.com/docker/docker/api/types/container" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" @@ -48,18 +49,18 @@ var SshProxyCmd = &cobra.Command{ var target *apiclient.TargetDTO - ws, statusCode, err := apiclient_util.GetWorkspace(resourceId, true) + ws, statusCode, err := apiclient_util.GetWorkspace(resourceId) if err != nil && statusCode != http.StatusNotFound { return err } if ws == nil { - target, _, err = apiclient_util.GetTarget(resourceId, true) + target, _, err = apiclient_util.GetTarget(resourceId) if err != nil { return err } } else { - target, _, err = apiclient_util.GetTarget(ws.TargetId, true) + target, _, err = apiclient_util.GetTarget(ws.TargetId) if err != nil { return err } @@ -77,7 +78,12 @@ var SshProxyCmd = &cobra.Command{ ApiClient: cli, }) - containerName := dockerClient.GetWorkspaceContainerName(conversion.ToWorkspace(ws)) + workspace, err := conversion.Convert[apiclient.WorkspaceDTO, models.Workspace](ws) + if err != nil { + return err + } + + containerName := dockerClient.GetWorkspaceContainerName(workspace) ctx := context.Background() diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index b884fc9ccf..a22b1fb888 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -70,7 +70,7 @@ var SshCmd = &cobra.Command{ return nil } } else { - ws, _, err = apiclient_util.GetWorkspace(args[0], true) + ws, _, err = apiclient_util.GetWorkspace(args[0]) if err != nil { return err } diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index 8f87d4c6d2..d82d38f9cf 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -14,6 +14,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" ide_views "github.com/daytonaio/daytona/pkg/views/ide" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -63,7 +64,7 @@ var StartCmd = &cobra.Command{ selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, selection.StartActionVerb) } else { for _, arg := range args { - workspace, _, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -90,12 +91,12 @@ var StartCmd = &cobra.Command{ ideList = config.GetIdeList() ideId = c.DefaultIdeId - ws, res, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, workspace.Id).Verbose(true).Execute() + ws, res, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, workspace.Id).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } if ideId != "ssh" { - workspaceProviderMetadata = *ws.Info.ProviderMetadata + workspaceProviderMetadata = *ws.ProviderMetadata } } @@ -183,13 +184,14 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspac } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadWorkspaceLogs(logsContext, apiclient_util.ReadLogParams{ - Id: workspace.Id, - Label: &workspace.Name, - ActiveProfile: activeProfile, - Index: util.Pointer(0), - Follow: util.Pointer(true), - From: &from, + go cmd_common.ReadWorkspaceLogs(logsContext, cmd_common.ReadLogParams{ + Id: workspace.Id, + Label: &workspace.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Index: util.Pointer(0), + Follow: util.Pointer(true), + From: &from, }) res, err := apiClient.WorkspaceAPI.StartWorkspace(ctx, workspace.Id).Execute() diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go index da868673d6..5e0fbfbbbb 100644 --- a/pkg/cmd/workspace/stop.go +++ b/pkg/cmd/workspace/stop.go @@ -13,6 +13,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -53,7 +54,7 @@ var StopCmd = &cobra.Command{ selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, selection.StopActionVerb) } else { for _, arg := range args { - workspace, _, err := apiclient_util.GetWorkspace(arg, false) + workspace, _, err := apiclient_util.GetWorkspace(arg) if err != nil { log.Error(fmt.Sprintf("[ %s ] : %v", arg, err)) continue @@ -136,13 +137,14 @@ func StopWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspace } logsContext, stopLogs := context.WithCancel(context.Background()) - go apiclient_util.ReadWorkspaceLogs(logsContext, apiclient_util.ReadLogParams{ - Id: workspace.Id, - Label: &workspace.Name, - ActiveProfile: activeProfile, - Index: util.Pointer(0), - Follow: util.Pointer(true), - From: &from, + go cmd_common.ReadWorkspaceLogs(logsContext, cmd_common.ReadLogParams{ + Id: workspace.Id, + Label: &workspace.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Index: util.Pointer(0), + Follow: util.Pointer(true), + From: &from, }) res, err := apiClient.WorkspaceAPI.StopWorkspace(ctx, workspace.Id).Execute() diff --git a/pkg/db/job_store.go b/pkg/db/job_store.go index 7a814ebfdf..af72d30df2 100644 --- a/pkg/db/job_store.go +++ b/pkg/db/job_store.go @@ -91,6 +91,9 @@ func processJobFilters(tx *gorm.DB, filter *stores.JobFilter) *gorm.DB { if filter.ResourceId != nil { tx = tx.Where("resource_id = ?", *filter.ResourceId) } + if filter.RunnerIdOrIsNil != nil { + tx = tx.Where("runner_id = ? OR runner_id IS NULL OR runner_id = ''", *filter.RunnerIdOrIsNil) + } if filter.States != nil && len(*filter.States) > 0 { placeholders := strings.Repeat("?,", len(*filter.States)) placeholders = placeholders[:len(placeholders)-1] diff --git a/pkg/db/runner_metadata_store.go b/pkg/db/runner_metadata_store.go new file mode 100644 index 0000000000..a0cc58b946 --- /dev/null +++ b/pkg/db/runner_metadata_store.go @@ -0,0 +1,76 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" +) + +type RunnerMetadataStore struct { + IStore +} + +func NewRunnerMetadataStore(store IStore) (stores.RunnerMetadataStore, error) { + err := store.AutoMigrate(&models.RunnerMetadata{}) + if err != nil { + return nil, err + } + + return &RunnerMetadataStore{store}, nil +} + +func (s *RunnerMetadataStore) List(ctx context.Context) ([]*models.RunnerMetadata, error) { + tx := s.GetTransaction(ctx) + + var runnerMetadata []*models.RunnerMetadata + tx = tx.Find(&runnerMetadata) + if tx.Error != nil { + return nil, tx.Error + } + + return runnerMetadata, nil +} + +func (s *RunnerMetadataStore) Find(ctx context.Context, runnerId string) (*models.RunnerMetadata, error) { + tx := s.GetTransaction(ctx) + + runnerMetadata := &models.RunnerMetadata{} + tx = tx.Where("runner_id = ?", runnerId).First(&runnerMetadata) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, stores.ErrRunnerMetadataNotFound + } + return nil, tx.Error + } + + return runnerMetadata, nil +} + +func (s *RunnerMetadataStore) Save(ctx context.Context, runnerMetadata *models.RunnerMetadata) error { + tx := s.GetTransaction(ctx) + + tx = tx.Save(runnerMetadata) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *RunnerMetadataStore) Delete(ctx context.Context, runnerMetadata *models.RunnerMetadata) error { + tx := s.GetTransaction(ctx) + + tx = tx.Delete(runnerMetadata) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrRunnerMetadataNotFound + } + + return nil +} diff --git a/pkg/db/runner_store.go b/pkg/db/runner_store.go new file mode 100644 index 0000000000..2eb14143f6 --- /dev/null +++ b/pkg/db/runner_store.go @@ -0,0 +1,82 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package db + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type RunnerStore struct { + IStore +} + +func NewRunnerStore(store IStore) (stores.RunnerStore, error) { + err := store.AutoMigrate(&models.Runner{}) + if err != nil { + return nil, err + } + + return &RunnerStore{store}, nil +} + +func (s *RunnerStore) List(ctx context.Context) ([]*models.Runner, error) { + tx := s.GetTransaction(ctx) + + runners := []*models.Runner{} + tx = preloadRunnerEntities(tx).Find(&runners) + if tx.Error != nil { + return nil, tx.Error + } + + return runners, nil +} + +func (s *RunnerStore) Find(ctx context.Context, idOrName string) (*models.Runner, error) { + tx := s.GetTransaction(ctx) + + runner := &models.Runner{} + tx = preloadRunnerEntities(tx).Where("id = ? OR name = ?", idOrName, idOrName).First(runner) + if tx.Error != nil { + if IsRecordNotFound(tx.Error) { + return nil, stores.ErrRunnerNotFound + } + return nil, tx.Error + } + + return runner, nil +} + +func (s *RunnerStore) Save(ctx context.Context, runner *models.Runner) error { + tx := s.GetTransaction(ctx) + + tx = tx.Save(runner) + if tx.Error != nil { + return tx.Error + } + + return nil +} + +func (s *RunnerStore) Delete(ctx context.Context, runner *models.Runner) error { + tx := s.GetTransaction(ctx) + + tx = tx.Delete(runner) + if tx.Error != nil { + return tx.Error + } + if tx.RowsAffected == 0 { + return stores.ErrRunnerNotFound + } + + return nil +} + +func preloadRunnerEntities(tx *gorm.DB) *gorm.DB { + return tx.Preload(clause.Associations) +} diff --git a/pkg/db/target_metadata_store.go b/pkg/db/target_metadata_store.go index 05c5e25fd8..2eb3c46351 100644 --- a/pkg/db/target_metadata_store.go +++ b/pkg/db/target_metadata_store.go @@ -6,8 +6,6 @@ package db import ( "context" - "gorm.io/gorm" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) @@ -25,11 +23,11 @@ func NewTargetMetadataStore(store IStore) (stores.TargetMetadataStore, error) { return &TargetMetadataStore{store}, nil } -func (s *TargetMetadataStore) Find(ctx context.Context, filter *stores.TargetMetadataFilter) (*models.TargetMetadata, error) { +func (s *TargetMetadataStore) Find(ctx context.Context, targetId string) (*models.TargetMetadata, error) { tx := s.GetTransaction(ctx) targetMetadata := &models.TargetMetadata{} - tx = processTargetMetadataFilters(tx, filter).First(&targetMetadata) + tx = tx.Where("target_id = ?", targetId).First(&targetMetadata) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrTargetMetadataNotFound @@ -64,15 +62,3 @@ func (s *TargetMetadataStore) Delete(ctx context.Context, targetMetadata *models return nil } - -func processTargetMetadataFilters(tx *gorm.DB, filter *stores.TargetMetadataFilter) *gorm.DB { - if filter != nil { - if filter.Id != nil { - tx = tx.Where("id = ?", *filter.Id) - } - if filter.TargetId != nil { - tx = tx.Where("target_id = ?", *filter.TargetId) - } - } - return tx -} diff --git a/pkg/db/workspace_metadata_store.go b/pkg/db/workspace_metadata_store.go index 4db4a100bf..4fa75102e6 100644 --- a/pkg/db/workspace_metadata_store.go +++ b/pkg/db/workspace_metadata_store.go @@ -6,8 +6,6 @@ package db import ( "context" - "gorm.io/gorm" - "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) @@ -25,11 +23,11 @@ func NewWorkspaceMetadataStore(store IStore) (stores.WorkspaceMetadataStore, err return &WorkspaceMetadataStore{store}, nil } -func (s *WorkspaceMetadataStore) Find(ctx context.Context, filter *stores.WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) { +func (s *WorkspaceMetadataStore) Find(ctx context.Context, workspaceId string) (*models.WorkspaceMetadata, error) { tx := s.GetTransaction(ctx) workspaceMetadata := &models.WorkspaceMetadata{} - tx = processWorkspaceMetadataFilters(tx, filter).First(&workspaceMetadata) + tx = tx.Where("workspace_id = ?", workspaceId).First(&workspaceMetadata) if tx.Error != nil { if IsRecordNotFound(tx.Error) { return nil, stores.ErrWorkspaceMetadataNotFound @@ -64,15 +62,3 @@ func (s *WorkspaceMetadataStore) Delete(ctx context.Context, workspaceMetadata * return nil } - -func processWorkspaceMetadataFilters(tx *gorm.DB, filter *stores.WorkspaceMetadataFilter) *gorm.DB { - if filter != nil { - if filter.Id != nil { - tx = tx.Where("id = ?", *filter.Id) - } - if filter.WorkspaceId != nil { - tx = tx.Where("workspace_id = ?", *filter.WorkspaceId) - } - } - return tx -} diff --git a/pkg/docker/client.go b/pkg/docker/client.go index cc8ec2d5ec..e2718d0a00 100644 --- a/pkg/docker/client.go +++ b/pkg/docker/client.go @@ -37,8 +37,8 @@ type IDockerClient interface { StartWorkspace(opts *CreateWorkspaceOptions, daytonaDownloadUrl string) error StopWorkspace(workspace *models.Workspace, logWriter io.Writer) error - GetWorkspaceInfo(workspace *models.Workspace) (*models.WorkspaceInfo, error) - GetTargetInfo(t *models.Target) (*models.TargetInfo, error) + GetWorkspaceProviderMetadata(workspace *models.Workspace) (string, error) + GetTargetProviderMetadata(t *models.Target) (string, error) GetWorkspaceContainerName(workspace *models.Workspace) string GetWorkspaceVolumeName(workspace *models.Workspace) string diff --git a/pkg/docker/info.go b/pkg/docker/info.go deleted file mode 100644 index a678175165..0000000000 --- a/pkg/docker/info.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package docker - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" -) - -const ContainerNotFoundMetadata = "{\"state\": \"container not found\"}" -const TargetMetadataFormat = "{\"networkId\": \"%s\"}" - -func (d *DockerClient) GetTargetInfo(t *models.Target) (*models.TargetInfo, error) { - targetInfo := &models.TargetInfo{ - Name: t.Name, - ProviderMetadata: fmt.Sprintf(TargetMetadataFormat, t.Id), - } - - return targetInfo, nil -} - -func (d *DockerClient) GetWorkspaceInfo(w *models.Workspace) (*models.WorkspaceInfo, error) { - isRunning := true - info, err := d.getContainerInfo(w) - if err != nil { - if client.IsErrNotFound(err) { - isRunning = false - } else { - return nil, err - } - } - - if info == nil || info.State == nil { - return &models.WorkspaceInfo{ - Name: w.Name, - IsRunning: isRunning, - Created: "", - ProviderMetadata: ContainerNotFoundMetadata, - }, nil - } - - workspaceInfo := &models.WorkspaceInfo{ - Name: w.Name, - IsRunning: isRunning, - Created: info.Created, - } - - if info.Config != nil && info.Config.Labels != nil { - metadata, err := json.Marshal(info.Config.Labels) - if err != nil { - return nil, err - } - workspaceInfo.ProviderMetadata = string(metadata) - } - - return workspaceInfo, nil -} - -func (d *DockerClient) getContainerInfo(w *models.Workspace) (*types.ContainerJSON, error) { - ctx := context.Background() - - info, err := d.apiClient.ContainerInspect(ctx, d.GetWorkspaceContainerName(w)) - if err != nil { - return nil, err - } - - return &info, nil -} diff --git a/pkg/docker/info_test.go b/pkg/docker/info_test.go deleted file mode 100644 index b163a02e3d..0000000000 --- a/pkg/docker/info_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package docker_test - -import ( - "fmt" - - "github.com/daytonaio/daytona/pkg/docker" - "github.com/daytonaio/daytona/pkg/models" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" -) - -func (s *DockerClientTestSuite) TestGetWorkspaceInfo() { - s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) - - containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) - - inspectResult := types.ContainerJSON{ - ContainerJSONBase: &types.ContainerJSONBase{ - State: &types.ContainerState{ - Running: true, - }, - Created: "test-created", - }, - Config: &container.Config{ - Labels: map[string]string{ - "test": "label", - }, - }, - } - metadata := `{"test":"label"}` - - s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(inspectResult, nil) - - workspaceInfo, err := s.dockerClient.GetWorkspaceInfo(workspace1) - require.Nil(s.T(), err) - require.Equal(s.T(), workspace1.Name, workspaceInfo.Name) - require.Equal(s.T(), workspaceInfo.IsRunning, inspectResult.State.Running) - require.Equal(s.T(), workspaceInfo.Created, inspectResult.Created) - require.Equal(s.T(), workspaceInfo.ProviderMetadata, metadata) -} - -func (s *DockerClientTestSuite) TestGetTargetInfo() { - var targetConfig = &models.TargetConfig{ - Name: "test", - ProviderInfo: models.ProviderInfo{ - Name: "test-provider", - Version: "test", - }, - Options: "test-options", - Deleted: false, - } - - targetWithoutWorkspaces := &models.Target{ - Id: "123", - Name: "test", - TargetConfigId: targetConfig.Id, - TargetConfig: *targetConfig, - } - - targetInfo, err := s.dockerClient.GetTargetInfo(targetWithoutWorkspaces) - require.Nil(s.T(), err) - require.Equal(s.T(), targetInfo.Name, targetWithoutWorkspaces.Name) - require.Equal(s.T(), targetInfo.ProviderMetadata, fmt.Sprintf(docker.TargetMetadataFormat, targetWithoutWorkspaces.Id)) -} diff --git a/pkg/docker/metadata.go b/pkg/docker/metadata.go new file mode 100644 index 0000000000..a7a81113ba --- /dev/null +++ b/pkg/docker/metadata.go @@ -0,0 +1,45 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package docker + +import ( + "context" + "encoding/json" + "errors" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/docker/docker/api/types" +) + +func (d *DockerClient) GetTargetProviderMetadata(t *models.Target) (string, error) { + return "", nil +} + +func (d *DockerClient) GetWorkspaceProviderMetadata(w *models.Workspace) (string, error) { + info, err := d.getContainerInfo(w) + if err != nil { + return "", err + } + + if info.Config == nil || info.Config.Labels == nil { + return "", errors.New("container labels not found") + } + + metadata, err := json.Marshal(info.Config.Labels) + if err != nil { + return "", err + } + return string(metadata), nil +} + +func (d *DockerClient) getContainerInfo(w *models.Workspace) (*types.ContainerJSON, error) { + ctx := context.Background() + + info, err := d.apiClient.ContainerInspect(ctx, d.GetWorkspaceContainerName(w)) + if err != nil { + return nil, err + } + + return &info, nil +} diff --git a/pkg/docker/metadata_test.go b/pkg/docker/metadata_test.go new file mode 100644 index 0000000000..30c570cce1 --- /dev/null +++ b/pkg/docker/metadata_test.go @@ -0,0 +1,38 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package docker_test + +import ( + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func (s *DockerClientTestSuite) TestGetWorkspaceProviderMetadata() { + s.mockClient.On("ContainerList", mock.Anything, mock.Anything).Return([]types.Container{}, nil) + + containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) + + inspectResult := types.ContainerJSON{ + ContainerJSONBase: &types.ContainerJSONBase{ + State: &types.ContainerState{ + Running: true, + }, + Created: "test-created", + }, + Config: &container.Config{ + Labels: map[string]string{ + "test": "label", + }, + }, + } + metadata := `{"test":"label"}` + + s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(inspectResult, nil) + + workspaceMetadata, err := s.dockerClient.GetWorkspaceProviderMetadata(workspace1) + require.Nil(s.T(), err) + require.Equal(s.T(), workspaceMetadata, metadata) +} diff --git a/pkg/jobs/build/build.go b/pkg/jobs/build/build.go index 1abff13387..26942db2b3 100644 --- a/pkg/jobs/build/build.go +++ b/pkg/jobs/build/build.go @@ -24,7 +24,7 @@ type BuildJob struct { deleteImage func(ctx context.Context, image string, force bool) error trackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error - loggerFactory logs.LoggerFactory + loggerFactory logs.ILoggerFactory builderFactory build.IBuilderFactory basePath string diff --git a/pkg/jobs/build/factory.go b/pkg/jobs/build/factory.go index d32b33f330..b57a3950d8 100644 --- a/pkg/jobs/build/factory.go +++ b/pkg/jobs/build/factory.go @@ -30,7 +30,7 @@ type BuildJobFactoryConfig struct { DeleteImage func(ctx context.Context, image string, force bool) error TrackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error - LoggerFactory logs.LoggerFactory + LoggerFactory logs.ILoggerFactory BuilderFactory build.IBuilderFactory BasePath string diff --git a/pkg/jobs/build/run.go b/pkg/jobs/build/run.go index 6e77244c7f..347cd22cdb 100644 --- a/pkg/jobs/build/run.go +++ b/pkg/jobs/build/run.go @@ -31,7 +31,10 @@ func (bj *BuildJob) run(ctx context.Context, j *models.Job) error { return fmt.Errorf("build config is not set") } - buildLogger := bj.loggerFactory.CreateBuildLogger(b.Id, logs.LogSourceBuilder) + buildLogger, err := bj.loggerFactory.CreateLogger(b.Id, b.Id, logs.LogSourceBuilder) + if err != nil { + return err + } defer buildLogger.Close() workspaceDir := filepath.Join(bj.basePath, b.Id, "workspace") diff --git a/pkg/jobs/runner/factory.go b/pkg/jobs/runner/factory.go new file mode 100644 index 0000000000..44fb62ec7b --- /dev/null +++ b/pkg/jobs/runner/factory.go @@ -0,0 +1,38 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runner/providermanager" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type IRunnerJobFactory interface { + Create(job models.Job) jobs.IJob +} + +type RunnerJobFactory struct { + config RunnerJobFactoryConfig +} + +type RunnerJobFactoryConfig struct { + TrackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + ProviderManager providermanager.IProviderManager +} + +func NewRunnerJobFactory(config RunnerJobFactoryConfig) IRunnerJobFactory { + return &RunnerJobFactory{ + config: config, + } +} + +func (f *RunnerJobFactory) Create(job models.Job) jobs.IJob { + return &RunnerJob{ + Job: job, + trackTelemetryEvent: f.config.TrackTelemetryEvent, + providerManager: f.config.ProviderManager, + } +} diff --git a/pkg/jobs/runner/install.go b/pkg/jobs/runner/install.go new file mode 100644 index 0000000000..7331b984b8 --- /dev/null +++ b/pkg/jobs/runner/install.go @@ -0,0 +1,28 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "encoding/json" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" +) + +func (rj *RunnerJob) installProvider(ctx context.Context, j *models.Job) error { + var installProviderDto services.InstallProviderDTO + + err := json.Unmarshal([]byte(*j.Metadata), &installProviderDto) + if err != nil { + return err + } + + downloadPath, err := rj.providerManager.DownloadProvider(ctx, installProviderDto.DownloadUrls, installProviderDto.Name) + if err != nil { + return err + } + + return rj.providerManager.RegisterProvider(downloadPath, false) +} diff --git a/pkg/jobs/runner/runner.go b/pkg/jobs/runner/runner.go new file mode 100644 index 0000000000..c0fc54196f --- /dev/null +++ b/pkg/jobs/runner/runner.go @@ -0,0 +1,32 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runner/providermanager" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type RunnerJob struct { + models.Job + + trackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + providerManager providermanager.IProviderManager +} + +func (pj *RunnerJob) Execute(ctx context.Context) error { + switch pj.Action { + case models.JobActionInstallProvider: + return pj.installProvider(ctx, &pj.Job) + case models.JobActionUpdateProvider: + return pj.updateProvider(ctx, &pj.Job) + case models.JobActionUninstallProvider: + return pj.uninstallProvider(ctx, &pj.Job) + } + return errors.New("invalid job action") +} diff --git a/pkg/jobs/runner/uninstall.go b/pkg/jobs/runner/uninstall.go new file mode 100644 index 0000000000..5016944430 --- /dev/null +++ b/pkg/jobs/runner/uninstall.go @@ -0,0 +1,19 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +func (rj *RunnerJob) uninstallProvider(ctx context.Context, j *models.Job) error { + if j.Metadata == nil { + return errors.New("metadata is required") + } + + return rj.providerManager.UninstallProvider(*j.Metadata) +} diff --git a/pkg/jobs/runner/update.go b/pkg/jobs/runner/update.go new file mode 100644 index 0000000000..488dc42603 --- /dev/null +++ b/pkg/jobs/runner/update.go @@ -0,0 +1,14 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" +) + +func (pj *RunnerJob) updateProvider(ctx context.Context, j *models.Job) error { + return pj.installProvider(ctx, j) +} diff --git a/pkg/jobs/target/create.go b/pkg/jobs/target/create.go index 541412e604..ac1852546c 100644 --- a/pkg/jobs/target/create.go +++ b/pkg/jobs/target/create.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/views" ) @@ -18,12 +19,22 @@ func (tj *TargetJob) create(ctx context.Context, j *models.Job) error { return err } - targetLogger := tj.loggerFactory.CreateTargetLogger(tg.Id, tg.Name, logs.LogSourceServer) + targetLogger, err := tj.loggerFactory.CreateLogger(tg.Id, tg.Name, logs.LogSourceServer) + if err != nil { + return err + } defer targetLogger.Close() targetLogger.Write([]byte(fmt.Sprintf("Creating target %s (%s)\n", tg.Name, tg.Id))) - err = tj.provisioner.CreateTarget(tg) + p, err := tj.providerManager.GetProvider(tg.TargetConfig.ProviderInfo.Name) + if err != nil { + return err + } + + _, err = (*p).CreateTarget(&provider.TargetRequest{ + Target: tg, + }) if err != nil { return err } diff --git a/pkg/jobs/target/delete.go b/pkg/jobs/target/delete.go index ad5c05494b..b9c67eb2a4 100644 --- a/pkg/jobs/target/delete.go +++ b/pkg/jobs/target/delete.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider" log "github.com/sirupsen/logrus" ) @@ -18,16 +19,32 @@ func (tj *TargetJob) delete(ctx context.Context, j *models.Job, force bool) erro return err } - targetLogger := tj.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) + targetLogger, err := tj.loggerFactory.CreateLogger(t.Id, t.Name, logs.LogSourceServer) + if err != nil { + return err + } + defer targetLogger.Close() targetLogger.Write([]byte(fmt.Sprintf("Destroying target %s", t.Name))) - err = tj.provisioner.DestroyTarget(t) + p, err := tj.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) if err != nil { - if !force { - return err + if force { + log.Error(err) + return nil } - log.Error(err) + return err + } + + _, err = (*p).DestroyTarget(&provider.TargetRequest{ + Target: t, + }) + if err != nil { + if force { + log.Error(err) + return nil + } + return err } targetLogger.Write([]byte(fmt.Sprintf("Target %s destroyed", t.Name))) diff --git a/pkg/jobs/target/factory.go b/pkg/jobs/target/factory.go index 912e288537..9f7c3176ba 100644 --- a/pkg/jobs/target/factory.go +++ b/pkg/jobs/target/factory.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/jobs" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -25,10 +25,11 @@ type TargetJobFactoryConfig struct { FindTarget func(ctx context.Context, targetId string) (*models.Target, error) HandleSuccessfulCreation func(ctx context.Context, targetId string) error - TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + UpdateTargetProviderMetadata func(ctx context.Context, targetId, metadata string) error - LoggerFactory logs.LoggerFactory - Provisioner provisioner.IProvisioner + LoggerFactory logs.ILoggerFactory + ProviderManager providermanager.IProviderManager } func NewTargetJobFactory(config TargetJobFactoryConfig) ITargetJobFactory { @@ -41,10 +42,11 @@ func (f *TargetJobFactory) Create(job models.Job) jobs.IJob { return &TargetJob{ Job: job, - findTarget: f.config.FindTarget, - handleSuccessfulCreation: f.config.HandleSuccessfulCreation, - trackTelemetryEvent: f.config.TrackTelemetryEvent, - loggerFactory: f.config.LoggerFactory, - provisioner: f.config.Provisioner, + findTarget: f.config.FindTarget, + handleSuccessfulCreation: f.config.HandleSuccessfulCreation, + trackTelemetryEvent: f.config.TrackTelemetryEvent, + updateTargetProviderMetadata: f.config.UpdateTargetProviderMetadata, + loggerFactory: f.config.LoggerFactory, + providerManager: f.config.ProviderManager, } } diff --git a/pkg/jobs/target/start.go b/pkg/jobs/target/start.go index 096cbab22d..06c8c7f604 100644 --- a/pkg/jobs/target/start.go +++ b/pkg/jobs/target/start.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/views" ) @@ -18,12 +19,34 @@ func (tj *TargetJob) start(ctx context.Context, j *models.Job) error { return err } - targetLogger := tj.loggerFactory.CreateTargetLogger(tg.Id, tg.Name, logs.LogSourceServer) + targetLogger, err := tj.loggerFactory.CreateLogger(tg.Id, tg.Name, logs.LogSourceServer) + if err != nil { + return err + } defer targetLogger.Close() targetLogger.Write([]byte("Starting target\n")) - err = tj.provisioner.StartTarget(tg) + p, err := tj.providerManager.GetProvider(tg.TargetConfig.ProviderInfo.Name) + if err != nil { + return err + } + + _, err = (*p).StartTarget(&provider.TargetRequest{ + Target: tg, + }) + if err != nil { + return err + } + + providerMetadata, err := (*p).GetTargetProviderMetadata(&provider.TargetRequest{ + Target: tg, + }) + if err != nil { + return err + } + + err = tj.updateTargetProviderMetadata(ctx, tg.Id, providerMetadata) if err != nil { return err } diff --git a/pkg/jobs/target/stop.go b/pkg/jobs/target/stop.go index 4f2e3df56a..6a8dc38271 100644 --- a/pkg/jobs/target/stop.go +++ b/pkg/jobs/target/stop.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/views" ) @@ -18,13 +19,22 @@ func (tj *TargetJob) stop(ctx context.Context, j *models.Job) error { return err } - targetLogger := tj.loggerFactory.CreateTargetLogger(t.Id, t.Name, logs.LogSourceServer) + targetLogger, err := tj.loggerFactory.CreateLogger(t.Id, t.Name, logs.LogSourceServer) + if err != nil { + return err + } defer targetLogger.Close() targetLogger.Write([]byte(fmt.Sprintf("Stopping target %s\n", t.Name))) - // todo: go routines - err = tj.provisioner.StopTarget(t) + p, err := tj.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) + if err != nil { + return err + } + + _, err = (*p).StopTarget(&provider.TargetRequest{ + Target: t, + }) if err != nil { return err } diff --git a/pkg/jobs/target/target.go b/pkg/jobs/target/target.go index b7461a0ce5..18a597fd7a 100644 --- a/pkg/jobs/target/target.go +++ b/pkg/jobs/target/target.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -19,10 +19,11 @@ type TargetJob struct { findTarget func(ctx context.Context, targetId string) (*models.Target, error) handleSuccessfulCreation func(ctx context.Context, targetId string) error - trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + updateTargetProviderMetadata func(ctx context.Context, targetId, metadata string) error - loggerFactory logs.LoggerFactory - provisioner provisioner.IProvisioner + loggerFactory logs.ILoggerFactory + providerManager providermanager.IProviderManager } func (tj *TargetJob) Execute(ctx context.Context) error { diff --git a/pkg/jobs/workspace/create.go b/pkg/jobs/workspace/create.go index 8945aa6cb2..03159633f9 100644 --- a/pkg/jobs/workspace/create.go +++ b/pkg/jobs/workspace/create.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/views" ) @@ -21,10 +21,13 @@ func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { return err } - workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + workspaceLogger, err := wj.loggerFactory.CreateLogger(w.Id, w.Name, logs.LogSourceServer) + if err != nil { + return err + } defer workspaceLogger.Close() - workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s\n", w.Name))) + workspaceLogger.Write([]byte(fmt.Sprintf("Creating workspace %s (%s)\n", w.Name, w.Id))) workspaceEnvVars, err := wj.getWorkspaceEnvironmentVariables(ctx, w) if err != nil { @@ -44,7 +47,12 @@ func (wj *WorkspaceJob) create(ctx context.Context, j *models.Job) error { w.EnvVars = extractedEnvVars - err = wj.provisioner.CreateWorkspace(provisioner.WorkspaceParams{ + p, err := wj.providerManager.GetProvider(w.Target.TargetConfig.ProviderInfo.Name) + if err != nil { + return err + } + + _, err = (*p).CreateWorkspace(&provider.WorkspaceRequest{ Workspace: w, ContainerRegistries: containerRegistries, GitProviderConfig: gc, diff --git a/pkg/jobs/workspace/delete.go b/pkg/jobs/workspace/delete.go index 2f9ac4b8ff..5c2b39e156 100644 --- a/pkg/jobs/workspace/delete.go +++ b/pkg/jobs/workspace/delete.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider" log "github.com/sirupsen/logrus" ) @@ -18,16 +19,31 @@ func (wj *WorkspaceJob) delete(ctx context.Context, j *models.Job, force bool) e return err } - workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + workspaceLogger, err := wj.loggerFactory.CreateLogger(w.Id, w.Name, logs.LogSourceServer) + if err != nil { + return err + } + defer workspaceLogger.Close() workspaceLogger.Write([]byte(fmt.Sprintf("Destroying workspace %s", w.Name))) - err = wj.provisioner.DestroyWorkspace(w) + p, err := wj.providerManager.GetProvider(w.Target.TargetConfig.ProviderInfo.Name) if err != nil { - if !force { - return err + if force { + log.Error(err) + return nil } - log.Error(err) + return err + } + + _, err = (*p).DestroyWorkspace(&provider.WorkspaceRequest{ + Workspace: w, + }) + if err != nil { + if force { + log.Error(err) + } + return nil } workspaceLogger.Write([]byte(fmt.Sprintf("Workspace %s destroyed", w.Name))) diff --git a/pkg/jobs/workspace/factory.go b/pkg/jobs/workspace/factory.go index f034ca4df2..15f4e0fbb9 100644 --- a/pkg/jobs/workspace/factory.go +++ b/pkg/jobs/workspace/factory.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/jobs" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -26,11 +26,12 @@ type WorkspaceJobFactoryConfig struct { FindTarget func(ctx context.Context, targetId string) (*models.Target, error) FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) + UpdateWorkspaceProviderMetadata func(ctx context.Context, workspaceId, metadata string) error TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error - LoggerFactory logs.LoggerFactory - Provisioner provisioner.IProvisioner - BuilderImage string + LoggerFactory logs.ILoggerFactory + ProviderManager providermanager.IProviderManager + BuilderImage string } func NewWorkspaceJobFactory(config WorkspaceJobFactoryConfig) IWorkspaceJobFactory { @@ -47,9 +48,10 @@ func (f *WorkspaceJobFactory) Create(job models.Job) jobs.IJob { findTarget: f.config.FindTarget, findGitProviderConfig: f.config.FindGitProviderConfig, getWorkspaceEnvironmentVariables: f.config.GetWorkspaceEnvironmentVariables, + updateWorkspaceProviderMetadata: f.config.UpdateWorkspaceProviderMetadata, trackTelemetryEvent: f.config.TrackTelemetryEvent, loggerFactory: f.config.LoggerFactory, - provisioner: f.config.Provisioner, + providerManager: f.config.ProviderManager, builderImage: f.config.BuilderImage, } } diff --git a/pkg/jobs/workspace/start.go b/pkg/jobs/workspace/start.go index 99deca07dc..81fc468c42 100644 --- a/pkg/jobs/workspace/start.go +++ b/pkg/jobs/workspace/start.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/views" ) @@ -21,7 +21,10 @@ func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { return err } - workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + workspaceLogger, err := wj.loggerFactory.CreateLogger(w.Id, w.Name, logs.LogSourceServer) + if err != nil { + return err + } defer workspaceLogger.Close() workspaceLogger.Write([]byte(fmt.Sprintf("Starting workspace %s\n", w.Name))) @@ -44,12 +47,29 @@ func (wj *WorkspaceJob) start(ctx context.Context, j *models.Job) error { w.EnvVars = extractedEnvVars - err = wj.provisioner.StartWorkspace(provisioner.WorkspaceParams{ + p, err := wj.providerManager.GetProvider(w.Target.TargetConfig.ProviderInfo.Name) + if err != nil { + return err + } + + req := &provider.WorkspaceRequest{ Workspace: w, ContainerRegistries: containerRegistries, GitProviderConfig: gc, BuilderImage: wj.builderImage, - }) + } + + _, err = (*p).StartWorkspace(req) + if err != nil { + return err + } + + providerMetadata, err := (*p).GetWorkspaceProviderMetadata(req) + if err != nil { + return err + } + + err = wj.updateWorkspaceProviderMetadata(ctx, w.Id, providerMetadata) if err != nil { return err } diff --git a/pkg/jobs/workspace/stop.go b/pkg/jobs/workspace/stop.go index 1de4f6d887..37c310b23d 100644 --- a/pkg/jobs/workspace/stop.go +++ b/pkg/jobs/workspace/stop.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/provider" "github.com/daytonaio/daytona/pkg/views" ) @@ -18,13 +19,22 @@ func (wj *WorkspaceJob) stop(ctx context.Context, j *models.Job) error { return err } - workspaceLogger := wj.loggerFactory.CreateWorkspaceLogger(w.Id, w.Name, logs.LogSourceServer) + workspaceLogger, err := wj.loggerFactory.CreateLogger(w.Id, w.Name, logs.LogSourceServer) + if err != nil { + return err + } defer workspaceLogger.Close() workspaceLogger.Write([]byte(fmt.Sprintf("Stopping workspace %s\n", w.Name))) - // todo: go routines - err = wj.provisioner.StopWorkspace(w) + p, err := wj.providerManager.GetProvider(w.Target.TargetConfig.ProviderInfo.Name) + if err != nil { + return err + } + + _, err = (*p).StopWorkspace(&provider.WorkspaceRequest{ + Workspace: w, + }) if err != nil { return err } diff --git a/pkg/jobs/workspace/workspace.go b/pkg/jobs/workspace/workspace.go index 70d85618a9..ca26b8553d 100644 --- a/pkg/jobs/workspace/workspace.go +++ b/pkg/jobs/workspace/workspace.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" + "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -18,14 +18,14 @@ type WorkspaceJob struct { findWorkspace func(ctx context.Context, workspaceId string) (*models.Workspace, error) findTarget func(ctx context.Context, targetId string) (*models.Target, error) - findContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) + updateWorkspaceProviderMetadata func(ctx context.Context, workspaceId, metadata string) error getWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error - loggerFactory logs.LoggerFactory - provisioner provisioner.IProvisioner - builderImage string + loggerFactory logs.ILoggerFactory + providerManager providermanager.IProviderManager + builderImage string } func (wj *WorkspaceJob) Execute(ctx context.Context) error { diff --git a/pkg/logs/build.go b/pkg/logs/build.go deleted file mode 100644 index 77ad0e3ec7..0000000000 --- a/pkg/logs/build.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package logs - -import ( - "encoding/json" - "io" - "os" - "path/filepath" - - "github.com/sirupsen/logrus" -) - -type buildLogger struct { - logsDir string - buildId string - logFile *os.File - logger *logrus.Logger - source LogSource -} - -func (bl *buildLogger) Write(p []byte) (n int, err error) { - if bl.logFile == nil { - filePath := filepath.Join(bl.logsDir, bl.buildId, "log") - err = os.MkdirAll(filepath.Dir(filePath), 0755) - if err != nil { - return len(p), err - } - - logFile, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return len(p), err - } - bl.logFile = logFile - bl.logger.SetOutput(bl.logFile) - } - - var entry LogEntry - entry.Msg = string(p) - entry.Source = string(bl.source) - entry.BuildId = &bl.buildId - - b, err := json.Marshal(entry) - if err != nil { - return len(p), err - } - - b = append(b, []byte(LogDelimiter)...) - - _, err = bl.logFile.Write(b) - if err != nil { - return len(p), err - } - - return len(p), nil -} - -func (bl *buildLogger) Close() error { - if bl.logFile != nil { - err := bl.logFile.Close() - bl.logFile = nil - return err - } - return nil -} - -func (bl *buildLogger) Cleanup() error { - buildLogsDir := filepath.Join(bl.logsDir, bl.buildId) - - _, err := os.Stat(buildLogsDir) - if os.IsNotExist(err) { - return nil - } else if err != nil { - return err - } - - return os.RemoveAll(buildLogsDir) -} - -func (l *loggerFactoryImpl) CreateBuildLogger(buildId string, source LogSource) Logger { - logger := logrus.New() - - return &buildLogger{ - logsDir: l.buildLogsDir, - buildId: buildId, - logger: logger, - source: source, - } -} - -func (l *loggerFactoryImpl) CreateBuildLogReader(buildId string) (io.Reader, error) { - filePath := filepath.Join(l.buildLogsDir, buildId, "log") - return os.Open(filePath) -} diff --git a/pkg/logs/factory.go b/pkg/logs/factory.go new file mode 100644 index 0000000000..5037a47f04 --- /dev/null +++ b/pkg/logs/factory.go @@ -0,0 +1,98 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package logs + +import ( + "fmt" + "io" + "os" + "path/filepath" +) + +var LogDelimiter = "!-#_^*|\n" + +type Logger interface { + io.WriteCloser + ConstructJsonLogEntry(p []byte) ([]byte, error) + Cleanup() error +} + +type LogSource string + +const ( + LogSourceServer LogSource = "server" + LogSourceProvider LogSource = "provider" + LogSourceBuilder LogSource = "builder" + LogSourceRunner LogSource = "runner" +) + +type LogEntry struct { + Source string `json:"source"` + Label string `json:"label"` + Msg string `json:"msg"` + Level string `json:"level"` + Time string `json:"time"` +} + +type ILoggerFactory interface { + CreateLogger(id, label string, source LogSource) (Logger, error) + CreateLogReader(id string) (io.Reader, error) + CreateLogWriter(id string) (io.WriteCloser, error) +} + +type loggerFactory struct { + logsDir string +} + +type LoggerFactoryConfig struct { + LogsDir string + ApiUrl *string + ApiKey *string + ApiBasePath *ApiBasePath +} + +func NewLoggerFactory(config LoggerFactoryConfig) ILoggerFactory { + if config.ApiUrl != nil && config.ApiKey != nil && config.ApiBasePath != nil { + return &remoteLoggerFactory{ + localLoggerFactory: &loggerFactory{ + logsDir: config.LogsDir, + }, + apiUrl: *config.ApiUrl, + apiKey: *config.ApiKey, + apiBasePath: *config.ApiBasePath, + } + } + + return &loggerFactory{ + logsDir: config.LogsDir, + } +} + +func (l *loggerFactory) CreateLogger(id, label string, source LogSource) (Logger, error) { + return &logger{ + id: id, + logsDir: l.logsDir, + label: label, + source: source, + }, nil +} + +func (l *loggerFactory) CreateLogReader(id string) (io.Reader, error) { + filePath := filepath.Join(l.logsDir, id, "log") + + dirPath := filepath.Dir(filePath) + if err := os.MkdirAll(dirPath, 0755); err != nil { + return nil, fmt.Errorf("failed to create directories for path %s: %v", dirPath, err) + } + + return os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644) +} + +func (l *loggerFactory) CreateLogWriter(id string) (io.WriteCloser, error) { + return &logger{ + id: id, + logsDir: l.logsDir, + skipEntryConstructor: true, + }, nil +} diff --git a/internal/util/log_reader.go b/pkg/logs/log_reader.go similarity index 88% rename from internal/util/log_reader.go rename to pkg/logs/log_reader.go index 1791f641dd..9a6ef38d4e 100644 --- a/internal/util/log_reader.go +++ b/pkg/logs/log_reader.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package util +package logs import ( "archive/zip" @@ -12,8 +12,6 @@ import ( "io" "strings" - "github.com/daytonaio/daytona/pkg/logs" - log "github.com/sirupsen/logrus" ) @@ -50,8 +48,8 @@ func ReadJSONLog(ctx context.Context, logReader io.Reader, follow bool, c chan i default: line, readErr := reader.ReadString('\n') if line != "" { - stripped := strings.TrimSuffix(line, logs.LogDelimiter) - var logEntry logs.LogEntry + stripped := strings.TrimSuffix(line, LogDelimiter) + var logEntry LogEntry err := json.Unmarshal([]byte(stripped), &logEntry) if err != nil { @@ -62,10 +60,10 @@ func ReadJSONLog(ctx context.Context, logReader io.Reader, follow bool, c chan i } if readErr != nil { if readErr != io.EOF { - c <- logs.LogEntry{} + c <- LogEntry{} errChan <- readErr } else if !follow { - c <- logs.LogEntry{} + c <- LogEntry{} errChan <- io.EOF return } diff --git a/pkg/logs/logger.go b/pkg/logs/logger.go index 21aa5334fb..0eb4215e4d 100644 --- a/pkg/logs/logger.go +++ b/pkg/logs/logger.go @@ -4,60 +4,86 @@ package logs import ( - "io" + "encoding/json" + "os" + "path/filepath" + "time" ) -var LogDelimiter = "!-#_^*|\n" - -type Logger interface { - io.WriteCloser - Cleanup() error +type logger struct { + logsDir string + id string + label string + logFile *os.File + source LogSource + skipEntryConstructor bool } -type LogSource string +func (w *logger) Write(p []byte) (n int, err error) { + if w.logFile == nil { + filePath := filepath.Join(w.logsDir, w.id, "log") + err = os.MkdirAll(filepath.Dir(filePath), 0755) + if err != nil { + return len(p), err + } -const ( - LogSourceServer LogSource = "server" - LogSourceProvider LogSource = "provider" - LogSourceBuilder LogSource = "builder" -) + logFile, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return len(p), err + } + w.logFile = logFile + } -type LogEntry struct { - Source string `json:"source"` - TargetName *string `json:"targetName,omitempty"` - WorkspaceName *string `json:"workspaceName,omitempty"` - BuildId *string `json:"buildId,omitempty"` - Msg string `json:"msg"` - Level string `json:"level"` - Time string `json:"time"` -} + b := p -type LoggerFactory interface { - CreateBuildLogger(buildId string, source LogSource) Logger - CreateBuildLogReader(buildId string) (io.Reader, error) + if !w.skipEntryConstructor { + b, err = w.ConstructJsonLogEntry(p) + if err != nil { + return len(p), err + } + } - CreateTargetLogger(targetId, targetName string, source LogSource) Logger - CreateTargetLogReader(targetId string) (io.Reader, error) + _, err = w.logFile.Write(b) + if err != nil { + return len(p), err + } - CreateWorkspaceLogger(workspaceId, workspaceName string, source LogSource) Logger - CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) + return len(p), nil } -type loggerFactoryImpl struct { - targetLogsDir string - buildLogsDir string -} +func (w *logger) ConstructJsonLogEntry(p []byte) ([]byte, error) { + var entry LogEntry + entry.Msg = string(p) + entry.Source = string(w.source) + entry.Label = w.label + entry.Time = time.Now().Format(time.RFC3339) + + b, err := json.Marshal(entry) + if err != nil { + return nil, err + } -func NewLoggerFactory(targetLogsDir *string, buildLogsDir *string) LoggerFactory { - loggerFactoryImpl := &loggerFactoryImpl{} + return append(b, []byte(LogDelimiter)...), nil +} - if targetLogsDir != nil { - loggerFactoryImpl.targetLogsDir = *targetLogsDir +func (w *logger) Close() error { + if w.logFile != nil { + err := w.logFile.Close() + w.logFile = nil + return err } + return nil +} + +func (w *logger) Cleanup() error { + workspaceLogsDir := filepath.Join(w.logsDir, w.id) - if buildLogsDir != nil { - loggerFactoryImpl.buildLogsDir = *buildLogsDir + _, err := os.Stat(workspaceLogsDir) + if os.IsNotExist(err) { + return nil + } else if err != nil { + return err } - return loggerFactoryImpl + return os.RemoveAll(workspaceLogsDir) } diff --git a/pkg/logs/remote_factory.go b/pkg/logs/remote_factory.go new file mode 100644 index 0000000000..99420029a9 --- /dev/null +++ b/pkg/logs/remote_factory.go @@ -0,0 +1,61 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package logs + +import ( + "context" + "errors" + "fmt" + "io" + + "github.com/daytonaio/daytona/internal/util" +) + +type remoteLoggerFactory struct { + localLoggerFactory ILoggerFactory + apiUrl string + apiKey string + apiBasePath ApiBasePath +} + +type RemoteLoggerFactoryConfig struct { + LogsDir string + ApiUrl string + ApiKey string + ApiBasePath ApiBasePath +} + +type ApiBasePath string + +var ( + ApiBasePathWorkspace ApiBasePath = "/log/workspace" + ApiBasePathBuild ApiBasePath = "/log/build" + ApiBasePathRunner ApiBasePath = "/log/runner" + ApiBasePathTarget ApiBasePath = "/log/target" +) + +func (r *remoteLoggerFactory) CreateLogger(id, label string, source LogSource) (Logger, error) { + conn, _, err := util.GetWebsocketConn(context.Background(), fmt.Sprintf("%s/%s/write", r.apiBasePath, id), r.apiUrl, r.apiKey, nil) + if err != nil { + return nil, err + } + + localLogger, err := r.localLoggerFactory.CreateLogger(id, label, source) + if err != nil { + return nil, err + } + + return &RemoteLogger{ + localLogger: localLogger, + conn: conn, + }, nil +} + +func (l *remoteLoggerFactory) CreateLogReader(id string) (io.Reader, error) { + return nil, errors.New("not implemented") +} + +func (l *remoteLoggerFactory) CreateLogWriter(id string) (io.WriteCloser, error) { + return nil, errors.New("not implemented") +} diff --git a/pkg/logs/remote_logger.go b/pkg/logs/remote_logger.go new file mode 100644 index 0000000000..faf615bc3a --- /dev/null +++ b/pkg/logs/remote_logger.go @@ -0,0 +1,57 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package logs + +import ( + "github.com/gorilla/websocket" +) + +type RemoteLogger struct { + localLogger Logger + conn *websocket.Conn +} + +func (r *RemoteLogger) Write(p []byte) (n int, err error) { + if r.conn != nil { + b, err := r.localLogger.ConstructJsonLogEntry(p) + if err != nil { + return len(p), err + } + + err = r.conn.WriteMessage(websocket.TextMessage, b) + if err != nil { + return len(p), err + } + } + + return r.localLogger.Write(p) +} + +func (r *RemoteLogger) Cleanup() error { + if r.conn != nil { + err := r.conn.Close() + r.conn = nil + if err != nil { + return err + } + } + + return r.localLogger.Cleanup() +} + +func (r *RemoteLogger) Close() error { + if r.conn != nil { + err := r.conn.Close() + r.conn = nil + if err != nil { + return err + } + } + + return r.localLogger.Close() +} + +func (r *RemoteLogger) ConstructJsonLogEntry(p []byte) ([]byte, error) { + return r.localLogger.ConstructJsonLogEntry(p) +} diff --git a/pkg/logs/target.go b/pkg/logs/target.go deleted file mode 100644 index a13517a7c9..0000000000 --- a/pkg/logs/target.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package logs - -import ( - "encoding/json" - "io" - "os" - "path/filepath" - "time" - - "github.com/sirupsen/logrus" -) - -type targetLogger struct { - logsDir string - targetId string - targetName string - logFile *os.File - logger *logrus.Logger - source LogSource -} - -func (w *targetLogger) Write(p []byte) (n int, err error) { - if w.logFile == nil { - filePath := filepath.Join(w.logsDir, w.targetId, "log") - err = os.MkdirAll(filepath.Dir(filePath), 0755) - if err != nil { - return len(p), err - } - logFile, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return len(p), err - } - w.logFile = logFile - w.logger.SetOutput(w.logFile) - } - - var entry LogEntry - entry.Msg = string(p) - entry.Source = string(w.source) - entry.TargetName = &w.targetName - entry.Time = time.Now().Format(time.RFC3339) - - b, err := json.Marshal(entry) - if err != nil { - return len(p), err - } - - b = append(b, []byte(LogDelimiter)...) - - _, err = w.logFile.Write(b) - if err != nil { - return len(p), err - } - - return len(p), nil -} - -func (w *targetLogger) Close() error { - if w.logFile != nil { - err := w.logFile.Close() - w.logFile = nil - return err - } - return nil -} - -func (w *targetLogger) Cleanup() error { - targetLogsDir := filepath.Join(w.logsDir, w.targetId) - - _, err := os.Stat(targetLogsDir) - if os.IsNotExist(err) { - return nil - } else if err != nil { - return err - } - - return os.RemoveAll(targetLogsDir) -} - -func (l *loggerFactoryImpl) CreateTargetLogger(targetId, targetName string, source LogSource) Logger { - logger := logrus.New() - - return &targetLogger{ - targetId: targetId, - targetName: targetName, - logsDir: l.targetLogsDir, - logger: logger, - source: source, - } -} - -func (l *loggerFactoryImpl) CreateTargetLogReader(targetId string) (io.Reader, error) { - filePath := filepath.Join(l.targetLogsDir, targetId, "log") - return os.Open(filePath) -} diff --git a/pkg/logs/types.go b/pkg/logs/types.go new file mode 100644 index 0000000000..466096f374 --- /dev/null +++ b/pkg/logs/types.go @@ -0,0 +1,92 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package logs + +import ( + "fmt" + "os" + "strconv" + + log "github.com/sirupsen/logrus" +) + +var defaultLogFileConfig = LogFileConfig{ + MaxSize: 100, // megabytes + MaxBackups: 7, + MaxAge: 15, // days + LocalTime: true, + Compress: true, +} + +type LogFileConfig struct { + Path string `json:"path" validate:"required"` + MaxSize int `json:"maxSize" validate:"required"` + MaxBackups int `json:"maxBackups" validate:"required"` + MaxAge int `json:"maxAge" validate:"required"` + LocalTime bool `json:"localTime" validate:"optional"` + Compress bool `json:"compress" validate:"optional"` +} // @name LogFileConfig + +func GetDefaultLogFileConfig(logFilePath string) *LogFileConfig { + logFileConfig := LogFileConfig{ + Path: logFilePath, + MaxSize: defaultLogFileConfig.MaxSize, + MaxBackups: defaultLogFileConfig.MaxBackups, + MaxAge: defaultLogFileConfig.MaxAge, + LocalTime: defaultLogFileConfig.LocalTime, + Compress: defaultLogFileConfig.Compress, + } + + logFileMaxSize := os.Getenv("DEFAULT_LOG_FILE_MAX_SIZE") + if logFileMaxSize != "" { + value, err := strconv.Atoi(logFileMaxSize) + if err != nil { + log.Error(fmt.Printf("%s. Using default log file max size.", err)) + } else { + logFileConfig.MaxSize = value + } + } + + logFileMaxBackups := os.Getenv("DEFAULT_LOG_FILE_MAX_BACKUPS") + if logFileMaxBackups != "" { + value, err := strconv.Atoi(logFileMaxBackups) + if err != nil { + log.Error(fmt.Printf("%s. Using default log file max backups.", err)) + } else { + logFileConfig.MaxBackups = value + } + } + + logFileMaxAge := os.Getenv("DEFAULT_LOG_FILE_MAX_AGE") + if logFileMaxAge != "" { + value, err := strconv.Atoi(logFileMaxAge) + if err != nil { + log.Error(fmt.Printf("%s. Using default log file max age.", err)) + } else { + logFileConfig.MaxAge = value + } + } + + logFileLocalTime := os.Getenv("DEFAULT_LOG_FILE_LOCAL_TIME") + if logFileLocalTime != "" { + value, err := strconv.ParseBool(logFileLocalTime) + if err != nil { + log.Error(fmt.Printf("%s. Using default log file local time.", err)) + } else { + logFileConfig.LocalTime = value + } + } + + logFileCompress := os.Getenv("DEFAULT_LOG_FILE_COMPRESS") + if logFileCompress != "" { + value, err := strconv.ParseBool(logFileCompress) + if err != nil { + log.Error(fmt.Printf("%s. Using default log file compress.", err)) + } else { + logFileConfig.Compress = value + } + } + + return &logFileConfig +} diff --git a/pkg/logs/workspace.go b/pkg/logs/workspace.go deleted file mode 100644 index 4c4257a689..0000000000 --- a/pkg/logs/workspace.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package logs - -import ( - "encoding/json" - "io" - "os" - "path/filepath" - "time" - - "github.com/sirupsen/logrus" -) - -type workspaceLogger struct { - logsDir string - workspaceId string - workspaceName string - logFile *os.File - logger *logrus.Logger - source LogSource -} - -func (pl *workspaceLogger) Write(p []byte) (n int, err error) { - if pl.logFile == nil { - filePath := filepath.Join(pl.logsDir, pl.workspaceId, "log") - err = os.MkdirAll(filepath.Dir(filePath), 0755) - if err != nil { - return len(p), err - } - - logFile, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return len(p), err - } - pl.logFile = logFile - pl.logger.SetOutput(pl.logFile) - } - - var entry LogEntry - entry.Msg = string(p) - entry.Source = string(pl.source) - entry.WorkspaceName = &pl.workspaceName - entry.Time = time.Now().Format(time.RFC3339) - - b, err := json.Marshal(entry) - if err != nil { - return len(p), err - } - - b = append(b, []byte(LogDelimiter)...) - - _, err = pl.logFile.Write(b) - if err != nil { - return len(p), err - } - - return len(p), nil -} - -func (pl *workspaceLogger) Close() error { - if pl.logFile != nil { - err := pl.logFile.Close() - pl.logFile = nil - return err - } - return nil -} - -func (pl *workspaceLogger) Cleanup() error { - workspaceLogsDir := filepath.Join(pl.logsDir, pl.workspaceId) - - _, err := os.Stat(workspaceLogsDir) - if os.IsNotExist(err) { - return nil - } else if err != nil { - return err - } - - return os.RemoveAll(workspaceLogsDir) -} - -func (l *loggerFactoryImpl) CreateWorkspaceLogger(workspaceId, workspaceName string, source LogSource) Logger { - logger := logrus.New() - - return &workspaceLogger{ - workspaceId: workspaceId, - logsDir: l.targetLogsDir, - workspaceName: workspaceName, - logger: logger, - source: source, - } -} - -func (l *loggerFactoryImpl) CreateWorkspaceLogReader(workspaceId string) (io.Reader, error) { - filePath := filepath.Join(l.targetLogsDir, workspaceId, "log") - return os.Open(filePath) -} diff --git a/pkg/models/api_key.go b/pkg/models/api_key.go index 19d8e5df77..b162772bf8 100644 --- a/pkg/models/api_key.go +++ b/pkg/models/api_key.go @@ -9,6 +9,7 @@ const ( ApiKeyTypeClient ApiKeyType = "client" ApiKeyTypeWorkspace ApiKeyType = "workspace" ApiKeyTypeTarget ApiKeyType = "target" + ApiKeyTypeRunner ApiKeyType = "runner" ) type ApiKey struct { diff --git a/pkg/models/job.go b/pkg/models/job.go index 0770821690..84abd3550b 100644 --- a/pkg/models/job.go +++ b/pkg/models/job.go @@ -10,12 +10,15 @@ import ( type Job struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` ResourceId string `json:"resourceId" validate:"required" gorm:"not null"` + RunnerId *string `json:"runnerId" validate:"optional"` ResourceType ResourceType `json:"resourceType" validate:"required" gorm:"not null"` State JobState `json:"state" validate:"required" gorm:"not null"` Action JobAction `json:"action" validate:"required" gorm:"not null"` - Error *string `json:"error" validate:"optional"` - CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` - UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` + // JSON encoded metadata + Metadata *string `json:"metadata" validate:"optional"` + Error *string `json:"error" validate:"optional"` + CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` + UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` } // @name Job type ResourceType string // @name ResourceType @@ -24,6 +27,7 @@ const ( ResourceTypeWorkspace ResourceType = "workspace" ResourceTypeTarget ResourceType = "target" ResourceTypeBuild ResourceType = "build" + ResourceTypeRunner ResourceType = "runner" ) type JobState string // @name JobState @@ -38,13 +42,16 @@ const ( type JobAction string const ( - JobActionCreate JobAction = "create" - JobActionStart JobAction = "start" - JobActionStop JobAction = "stop" - JobActionRestart JobAction = "restart" - JobActionDelete JobAction = "delete" - JobActionForceDelete JobAction = "force-delete" - JobActionRun JobAction = "run" + JobActionCreate JobAction = "create" + JobActionStart JobAction = "start" + JobActionStop JobAction = "stop" + JobActionRestart JobAction = "restart" + JobActionDelete JobAction = "delete" + JobActionForceDelete JobAction = "force-delete" + JobActionRun JobAction = "run" + JobActionInstallProvider JobAction = "install-provider" + JobActionUninstallProvider JobAction = "uninstall-provider" + JobActionUpdateProvider JobAction = "update-provider" ) func getResourceStateFromJob(job *Job) ResourceState { diff --git a/pkg/models/provider_info.go b/pkg/models/provider_info.go new file mode 100644 index 0000000000..78ad3cf390 --- /dev/null +++ b/pkg/models/provider_info.go @@ -0,0 +1,45 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +type ProviderInfo struct { + RunnerId string `json:"runnerId" validate:"required"` + RunnerName string `json:"runnerName" validate:"required"` + Name string `json:"name" validate:"required"` + Version string `json:"version" validate:"required"` + AgentlessTarget bool `json:"agentlessTarget" validate:"optional"` + Label *string `json:"label" validate:"optional"` + TargetConfigManifest TargetConfigManifest `json:"targetConfigManifest" validate:"required"` +} // @name ProviderInfo + +type TargetConfigManifest map[string]TargetConfigProperty // @name TargetConfigManifest + +type TargetConfigPropertyType string + +const ( + TargetConfigPropertyTypeString TargetConfigPropertyType = "string" + TargetConfigPropertyTypeOption TargetConfigPropertyType = "option" + TargetConfigPropertyTypeBoolean TargetConfigPropertyType = "boolean" + TargetConfigPropertyTypeInt TargetConfigPropertyType = "int" + TargetConfigPropertyTypeFloat TargetConfigPropertyType = "float" + TargetConfigPropertyTypeFilePath TargetConfigPropertyType = "file-path" +) + +type TargetConfigProperty struct { + Type TargetConfigPropertyType + InputMasked bool + // A regex string matched with the name of the target config to determine if the property should be disabled + // If the regex matches the target config name, the property will be disabled + // E.g. "^local$" will disable the property for the local target + DisabledPredicate string + // DefaultValue is converted into the appropriate type based on the Type + // If the property is a FilePath, the DefaultValue is a path to a directory + DefaultValue string + // Brief description of the property + Description string + // Options is only used if the Type is TargetConfigPropertyTypeOption + Options []string + // Suggestions is an optional list of auto-complete values to assist the user while filling the field + Suggestions []string +} // @name TargetConfigProperty diff --git a/pkg/models/runner.go b/pkg/models/runner.go new file mode 100644 index 0000000000..b0853f8e55 --- /dev/null +++ b/pkg/models/runner.go @@ -0,0 +1,44 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package models + +import ( + "time" + + "github.com/daytonaio/daytona/internal/util" +) + +type Runner struct { + Id string `json:"id" validate:"required" gorm:"primaryKey"` + Name string `json:"name" validate:"required" gorm:"uniqueIndex;not null"` + ApiKey string `json:"-" validate:"required" gorm:"not null"` + Metadata *RunnerMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:RunnerId;references:Id"` +} // @name Runner + +func (r *Runner) GetState() ResourceState { + var state ResourceState + state.Name = ResourceStateNameUnresponsive + state.UpdatedAt = time.Now() + state.Error = util.Pointer("Runner is unresponsive") + + if r.Metadata == nil { + return state + } + + if r.Metadata != nil && (time.Since(r.Metadata.UpdatedAt) > RESOURCE_UNRESPONSIVE_THRESHOLD || r.Metadata.Uptime == 0) { + state.UpdatedAt = r.Metadata.UpdatedAt + return state + } + + state.Name = ResourceStateNameStarted + return state +} + +type RunnerMetadata struct { + RunnerId string `json:"runnerId" validate:"required" gorm:"primaryKey"` + UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` + Uptime uint64 `json:"uptime" validate:"required" gorm:"not null"` + RunningJobs *uint64 `json:"runningJobs,omitempty" validate:"optional" gorm:"default:0"` + Providers []ProviderInfo `json:"providers" validate:"required" gorm:"serializer:json;not null"` +} // @name RunnerMetadata diff --git a/pkg/models/target.go b/pkg/models/target.go index c45e679756..178dd1e499 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -9,19 +9,20 @@ import ( "github.com/daytonaio/daytona/internal/util" ) -const AGENT_UNRESPONSIVE_THRESHOLD = 30 * time.Second +const RESOURCE_UNRESPONSIVE_THRESHOLD = 30 * time.Second type Target struct { - Id string `json:"id" validate:"required" gorm:"primaryKey"` - Name string `json:"name" validate:"required" gorm:"not null"` - TargetConfigId string `json:"targetConfigId" validate:"required" gorm:"not null"` - TargetConfig TargetConfig `json:"targetConfig" validate:"required" gorm:"foreignKey:TargetConfigId"` - ApiKey string `json:"-" validate:"required" gorm:"not null"` - EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` - IsDefault bool `json:"default" validate:"required" gorm:"not null"` - Workspaces []Workspace `json:"workspaces" validate:"required" gorm:"foreignKey:TargetId;references:Id"` - Metadata *TargetMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:TargetId;references:Id"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` + Id string `json:"id" validate:"required" gorm:"primaryKey"` + Name string `json:"name" validate:"required" gorm:"not null"` + TargetConfigId string `json:"targetConfigId" validate:"required" gorm:"not null"` + TargetConfig TargetConfig `json:"targetConfig" validate:"required" gorm:"foreignKey:TargetConfigId"` + ApiKey string `json:"-" validate:"required" gorm:"not null"` + EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + IsDefault bool `json:"default" validate:"required" gorm:"not null"` + Workspaces []Workspace `json:"workspaces" validate:"required" gorm:"foreignKey:TargetId;references:Id"` + Metadata *TargetMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:TargetId;references:Id"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` + ProviderMetadata *string `json:"providerMetadata,omitempty" validate:"optional"` } // @name Target type TargetMetadata struct { @@ -47,7 +48,7 @@ func (t *Target) GetState() ResourceState { // If the target should be running, check if it is unresponsive if state.Name == ResourceStateNameStarted { - if t.Metadata != nil && time.Since(t.Metadata.UpdatedAt) > AGENT_UNRESPONSIVE_THRESHOLD { + if t.Metadata != nil && time.Since(t.Metadata.UpdatedAt) > RESOURCE_UNRESPONSIVE_THRESHOLD { state.Name = ResourceStateNameUnresponsive state.Error = util.Pointer("Target is unresponsive") state.UpdatedAt = t.Metadata.UpdatedAt @@ -56,15 +57,3 @@ func (t *Target) GetState() ResourceState { return state } - -type TargetInfo struct { - Name string `json:"name" validate:"required"` - ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` -} // @name TargetInfo - -type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Version string `json:"version" validate:"required"` - AgentlessTarget bool `json:"agentlessTarget" validate:"optional"` - Label *string `json:"label" validate:"optional"` -} // @name TargetProviderInfo diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index 2a334668f2..c10dfa2337 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -20,10 +20,11 @@ type Workspace struct { EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` TargetId string `json:"targetId" validate:"required" gorm:"not null"` Target Target `json:"target" validate:"required" gorm:"foreignKey:TargetId"` - ApiKey string `json:"-" validate:"required" gorm:"not null"` + ApiKey string `json:"apiKey" validate:"required" gorm:"not null"` Metadata *WorkspaceMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:WorkspaceId;references:Id"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` + ProviderMetadata *string `json:"providerMetadata,omitempty" validate:"optional"` } // @name Workspace type WorkspaceMetadata struct { @@ -45,7 +46,7 @@ func (w *Workspace) GetState() ResourceState { // If the workspace should be running, check if it is unresponsive if state.Name == ResourceStateNameStarted { - if w.Metadata != nil && time.Since(w.Metadata.UpdatedAt) > AGENT_UNRESPONSIVE_THRESHOLD { + if w.Metadata != nil && time.Since(w.Metadata.UpdatedAt) > RESOURCE_UNRESPONSIVE_THRESHOLD { state.Name = ResourceStateNameUnresponsive state.Error = util.Pointer("Workspace is unresponsive") state.UpdatedAt = w.Metadata.UpdatedAt @@ -60,14 +61,6 @@ type CachedBuild struct { Image string `json:"image" validate:"required"` } // @name CachedBuild -type WorkspaceInfo struct { - Name string `json:"name" validate:"required"` - Created string `json:"created" validate:"required"` - IsRunning bool `json:"isRunning" validate:"required"` - ProviderMetadata string `json:"providerMetadata,omitempty" validate:"optional"` - TargetId string `json:"targetId" validate:"required"` -} // @name WorkspaceInfo - type GitStatus struct { CurrentBranch string `json:"currentBranch" validate:"required"` Files []*FileStatus `json:"fileStatus" validate:"required"` diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 4fb135a1f7..8c7cfaaf5f 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -13,23 +13,22 @@ import ( type Provider interface { Initialize(InitializeProviderRequest) (*util.Empty, error) - GetInfo() (ProviderInfo, error) + GetInfo() (models.ProviderInfo, error) CheckRequirements() (*[]RequirementStatus, error) - GetTargetConfigManifest() (*TargetConfigManifest, error) GetPresetTargetConfigs() (*[]TargetConfig, error) CreateTarget(*TargetRequest) (*util.Empty, error) StartTarget(*TargetRequest) (*util.Empty, error) StopTarget(*TargetRequest) (*util.Empty, error) DestroyTarget(*TargetRequest) (*util.Empty, error) - GetTargetInfo(*TargetRequest) (*models.TargetInfo, error) + GetTargetProviderMetadata(*TargetRequest) (string, error) CreateWorkspace(*WorkspaceRequest) (*util.Empty, error) StartWorkspace(*WorkspaceRequest) (*util.Empty, error) StopWorkspace(*WorkspaceRequest) (*util.Empty, error) DestroyWorkspace(*WorkspaceRequest) (*util.Empty, error) - GetWorkspaceInfo(*WorkspaceRequest) (*models.WorkspaceInfo, error) + GetWorkspaceProviderMetadata(*WorkspaceRequest) (string, error) } type ProviderPlugin struct { diff --git a/pkg/provider/rpc_client.go b/pkg/provider/rpc_client.go index 2cf0df32ab..604e1bddd4 100644 --- a/pkg/provider/rpc_client.go +++ b/pkg/provider/rpc_client.go @@ -19,8 +19,8 @@ func (m *ProviderRPCClient) Initialize(req InitializeProviderRequest) (*util.Emp return new(util.Empty), err } -func (m *ProviderRPCClient) GetInfo() (ProviderInfo, error) { - var resp ProviderInfo +func (m *ProviderRPCClient) GetInfo() (models.ProviderInfo, error) { + var resp models.ProviderInfo err := m.client.Call("Plugin.GetInfo", new(interface{}), &resp) return resp, err } @@ -31,13 +31,6 @@ func (m *ProviderRPCClient) CheckRequirements() (*[]RequirementStatus, error) { return &result, err } -func (m *ProviderRPCClient) GetTargetConfigManifest() (*TargetConfigManifest, error) { - var resp TargetConfigManifest - err := m.client.Call("Plugin.GetTargetConfigManifest", new(interface{}), &resp) - - return &resp, err -} - func (m *ProviderRPCClient) GetPresetTargetConfigs() (*[]TargetConfig, error) { var resp []TargetConfig err := m.client.Call("Plugin.GetPresetTargetConfigs", new(interface{}), &resp) @@ -64,10 +57,10 @@ func (m *ProviderRPCClient) DestroyTarget(targetReq *TargetRequest) (*util.Empty return new(util.Empty), err } -func (m *ProviderRPCClient) GetTargetInfo(targetReq *TargetRequest) (*models.TargetInfo, error) { - var response models.TargetInfo - err := m.client.Call("Plugin.GetTargetInfo", targetReq, &response) - return &response, err +func (m *ProviderRPCClient) GetTargetProviderMetadata(targetReq *TargetRequest) (string, error) { + var resp string + err := m.client.Call("Plugin.GetTargetProviderMetadata", targetReq, &resp) + return resp, err } func (m *ProviderRPCClient) CreateWorkspace(workspaceReq *WorkspaceRequest) (*util.Empty, error) { @@ -90,8 +83,8 @@ func (m *ProviderRPCClient) DestroyWorkspace(workspaceReq *WorkspaceRequest) (*u return new(util.Empty), err } -func (m *ProviderRPCClient) GetWorkspaceInfo(workspaceReq *WorkspaceRequest) (*models.WorkspaceInfo, error) { - var resp models.WorkspaceInfo - err := m.client.Call("Plugin.GetWorkspaceInfo", workspaceReq, &resp) - return &resp, err +func (m *ProviderRPCClient) GetWorkspaceProviderMetadata(workspaceReq *WorkspaceRequest) (string, error) { + var resp string + err := m.client.Call("Plugin.GetWorkspaceProviderMetadata", workspaceReq, &resp) + return resp, err } diff --git a/pkg/provider/rpc_server.go b/pkg/provider/rpc_server.go index f00a07a2d6..7855f7543d 100644 --- a/pkg/provider/rpc_server.go +++ b/pkg/provider/rpc_server.go @@ -17,7 +17,7 @@ func (m *ProviderRPCServer) Initialize(arg InitializeProviderRequest, resp *util return err } -func (m *ProviderRPCServer) GetInfo(arg interface{}, resp *ProviderInfo) error { +func (m *ProviderRPCServer) GetInfo(arg interface{}, resp *models.ProviderInfo) error { info, err := m.Impl.GetInfo() if err != nil { return err @@ -36,16 +36,6 @@ func (m *ProviderRPCServer) CheckRequirements(arg interface{}, resp *[]Requireme return nil } -func (m *ProviderRPCServer) GetTargetConfigManifest(arg interface{}, resp *TargetConfigManifest) error { - targetConfigManifest, err := m.Impl.GetTargetConfigManifest() - if err != nil { - return err - } - - *resp = *targetConfigManifest - return nil -} - func (m *ProviderRPCServer) GetPresetTargetConfigs(arg interface{}, resp *[]TargetConfig) error { targetConfigs, err := m.Impl.GetPresetTargetConfigs() if err != nil { @@ -76,13 +66,13 @@ func (m *ProviderRPCServer) DestroyTarget(arg *TargetRequest, resp *util.Empty) return err } -func (m *ProviderRPCServer) GetTargetInfo(arg *TargetRequest, resp *models.TargetInfo) error { - info, err := m.Impl.GetTargetInfo(arg) +func (m *ProviderRPCServer) GetTargetProviderMetadata(arg *TargetRequest, resp *string) error { + metadata, err := m.Impl.GetTargetProviderMetadata(arg) if err != nil { return err } - *resp = *info + *resp = metadata return nil } @@ -106,12 +96,12 @@ func (m *ProviderRPCServer) DestroyWorkspace(arg *WorkspaceRequest, resp *util.E return err } -func (m *ProviderRPCServer) GetWorkspaceInfo(arg *WorkspaceRequest, resp *models.WorkspaceInfo) error { - info, err := m.Impl.GetWorkspaceInfo(arg) +func (m *ProviderRPCServer) GetWorkspaceProviderMetadata(arg *WorkspaceRequest, resp *string) error { + metadata, err := m.Impl.GetWorkspaceProviderMetadata(arg) if err != nil { return err } - *resp = *info + *resp = metadata return nil } diff --git a/pkg/provider/types.go b/pkg/provider/types.go index d7fd476872..d35cefd1fb 100644 --- a/pkg/provider/types.go +++ b/pkg/provider/types.go @@ -12,11 +12,12 @@ type InitializeProviderRequest struct { BasePath string DaytonaDownloadUrl string DaytonaVersion string - LogsDir string - - NetworkKey string - ServerUrl string - ApiUrl string + TargetLogsDir string + WorkspaceLogsDir string + NetworkKey string + ServerUrl string + ApiUrl string + ApiKey *string // ServerPort is used if the target supports direct server access ServerPort uint32 // ApiPort is used if the target supports direct server access @@ -34,49 +35,11 @@ type WorkspaceRequest struct { GitProviderConfig *models.GitProviderConfig } -type ProviderInfo struct { - Name string `json:"name" validate:"required"` - Label *string `json:"label" validate:"optional"` - AgentlessTarget bool `json:"agentlessTarget" validate:"optional"` - Version string `json:"version" validate:"required"` -} - type TargetConfig struct { Name string `json:"name" validate:"required"` // JSON encoded map of options Options string `json:"options" validate:"required"` -} - -type TargetConfigManifest map[string]TargetConfigProperty // @name TargetConfigManifest - -type TargetConfigPropertyType string - -const ( - TargetConfigPropertyTypeString TargetConfigPropertyType = "string" - TargetConfigPropertyTypeOption TargetConfigPropertyType = "option" - TargetConfigPropertyTypeBoolean TargetConfigPropertyType = "boolean" - TargetConfigPropertyTypeInt TargetConfigPropertyType = "int" - TargetConfigPropertyTypeFloat TargetConfigPropertyType = "float" - TargetConfigPropertyTypeFilePath TargetConfigPropertyType = "file-path" -) - -type TargetConfigProperty struct { - Type TargetConfigPropertyType - InputMasked bool - // A regex string matched with the name of the target config to determine if the property should be disabled - // If the regex matches the target config name, the property will be disabled - // E.g. "^local$" will disable the property for the local target - DisabledPredicate string - // DefaultValue is converted into the appropriate type based on the Type - // If the property is a FilePath, the DefaultValue is a path to a directory - DefaultValue string - // Brief description of the property - Description string - // Options is only used if the Type is TargetConfigPropertyTypeOption - Options []string - // Suggestions is an optional list of auto-complete values to assist the user while filling the field - Suggestions []string -} // @name TargetConfigProperty +} // @name ProviderTargetConfig type RequirementStatus struct { Name string diff --git a/pkg/provisioner/create.go b/pkg/provisioner/create.go deleted file mode 100644 index 4ead351c49..0000000000 --- a/pkg/provisioner/create.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provisioner - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider" -) - -func (p *Provisioner) CreateTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).CreateTarget(&provider.TargetRequest{ - Target: t, - }) - - return err -} - -func (p *Provisioner) CreateWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).CreateWorkspace(&provider.WorkspaceRequest{ - Workspace: params.Workspace, - ContainerRegistries: params.ContainerRegistries, - GitProviderConfig: params.GitProviderConfig, - BuilderImage: params.BuilderImage, - }) - - return err -} diff --git a/pkg/provisioner/destroy.go b/pkg/provisioner/destroy.go deleted file mode 100644 index 2d774a3d3d..0000000000 --- a/pkg/provisioner/destroy.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provisioner - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider" -) - -func (p *Provisioner) DestroyTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).DestroyTarget(&provider.TargetRequest{ - Target: t, - }) - - return err -} - -func (p *Provisioner) DestroyWorkspace(ws *models.Workspace) error { - targetProvider, err := p.providerManager.GetProvider(ws.Target.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).DestroyWorkspace(&provider.WorkspaceRequest{ - Workspace: ws, - }) - - return err -} diff --git a/pkg/provisioner/info.go b/pkg/provisioner/info.go deleted file mode 100644 index feda44c526..0000000000 --- a/pkg/provisioner/info.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provisioner - -import ( - "context" - - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider" -) - -type TargetInfoResult struct { - Info *models.TargetInfo - Err error -} - -// Gets the target info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetTargetInfo(ctx context.Context, t *models.Target) (*models.TargetInfo, error) { - ch := make(chan TargetInfoResult, 1) - - go func() { - targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) - if err != nil { - ch <- TargetInfoResult{nil, err} - return - } - - info, err := (*targetProvider).GetTargetInfo(&provider.TargetRequest{ - Target: t, - }) - - ch <- TargetInfoResult{info, err} - }() - - select { - case <-ctx.Done(): - return nil, ctx.Err() - case data := <-ch: - return data.Info, data.Err - } -} - -type WorkspaceInfoResult struct { - Info *models.WorkspaceInfo - Err error -} - -// Gets the workspace info from the provider - the context is used to cancel the request if it takes too long -func (p *Provisioner) GetWorkspaceInfo(ctx context.Context, workspace *models.Workspace) (*models.WorkspaceInfo, error) { - ch := make(chan WorkspaceInfoResult, 1) - - go func() { - targetProvider, err := p.providerManager.GetProvider(workspace.Target.TargetConfig.ProviderInfo.Name) - if err != nil { - ch <- WorkspaceInfoResult{nil, err} - return - } - - info, err := (*targetProvider).GetWorkspaceInfo(&provider.WorkspaceRequest{ - Workspace: workspace, - }) - - ch <- WorkspaceInfoResult{info, err} - }() - - select { - case <-ctx.Done(): - return nil, ctx.Err() - case data := <-ch: - return data.Info, data.Err - } -} diff --git a/pkg/provisioner/provisioner.go b/pkg/provisioner/provisioner.go deleted file mode 100644 index 813cb29ac9..0000000000 --- a/pkg/provisioner/provisioner.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provisioner - -import ( - "context" - - "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider/manager" -) - -type WorkspaceParams struct { - Workspace *models.Workspace - Target *models.Target - ContainerRegistries common.ContainerRegistries - GitProviderConfig *models.GitProviderConfig - BuilderImage string -} - -type IProvisioner interface { - CreateTarget(target *models.Target) error - StartTarget(target *models.Target) error - StopTarget(target *models.Target) error - GetTargetInfo(ctx context.Context, target *models.Target) (*models.TargetInfo, error) - DestroyTarget(target *models.Target) error - - CreateWorkspace(params WorkspaceParams) error - DestroyWorkspace(workspace *models.Workspace) error - StartWorkspace(params WorkspaceParams) error - StopWorkspace(workspace *models.Workspace) error - GetWorkspaceInfo(ctx context.Context, workspace *models.Workspace) (*models.WorkspaceInfo, error) -} - -type ProvisionerConfig struct { - ProviderManager manager.IProviderManager -} - -func NewProvisioner(config ProvisionerConfig) IProvisioner { - return &Provisioner{ - providerManager: config.ProviderManager, - } -} - -type Provisioner struct { - providerManager manager.IProviderManager -} diff --git a/pkg/provisioner/start.go b/pkg/provisioner/start.go deleted file mode 100644 index c1fc6e56f8..0000000000 --- a/pkg/provisioner/start.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provisioner - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider" -) - -func (p *Provisioner) StartTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).StartTarget(&provider.TargetRequest{ - Target: t, - }) - - return err -} - -func (p *Provisioner) StartWorkspace(params WorkspaceParams) error { - targetProvider, err := p.providerManager.GetProvider(params.Workspace.Target.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).StartWorkspace(&provider.WorkspaceRequest{ - Workspace: params.Workspace, - ContainerRegistries: params.ContainerRegistries, - GitProviderConfig: params.GitProviderConfig, - BuilderImage: params.BuilderImage, - }) - - return err -} diff --git a/pkg/provisioner/stop.go b/pkg/provisioner/stop.go deleted file mode 100644 index e372f2403e..0000000000 --- a/pkg/provisioner/stop.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package provisioner - -import ( - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provider" -) - -func (p *Provisioner) StopTarget(t *models.Target) error { - targetProvider, err := p.providerManager.GetProvider(t.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).StopTarget(&provider.TargetRequest{ - Target: t, - }) - - return err -} - -func (p *Provisioner) StopWorkspace(ws *models.Workspace) error { - targetProvider, err := p.providerManager.GetProvider(ws.Target.TargetConfig.ProviderInfo.Name) - if err != nil { - return err - } - - _, err = (*targetProvider).StopWorkspace(&provider.WorkspaceRequest{ - Workspace: ws, - }) - - return err -} diff --git a/pkg/runner/config.go b/pkg/runner/config.go new file mode 100644 index 0000000000..a672390466 --- /dev/null +++ b/pkg/runner/config.go @@ -0,0 +1,194 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "encoding/json" + "errors" + "os" + "path/filepath" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/google/uuid" + + log "github.com/sirupsen/logrus" +) + +type Config struct { + Id string `json:"id"` + Name string `json:"name"` + ServerApiKey string `json:"serverApiKey"` + ServerApiUrl string `json:"serverApiUrl"` + ProvidersDir string `json:"providersDir"` + LogFile *logs.LogFileConfig `json:"logFile"` + ClientId string `envconfig:"DAYTONA_CLIENT_ID"` + TelemetryEnabled bool `json:"telemetryEnabled"` +} // @name RunnerConfig + +var ErrConfigNotFound = errors.New("run 'daytona runner configure' to configure the runner") + +func GetConfig() (*Config, error) { + configFilePath, err := configFilePath() + if err != nil { + return nil, err + } + + _, err = os.Stat(configFilePath) + if os.IsNotExist(err) { + return nil, ErrConfigNotFound + } + + if err != nil { + return nil, err + } + + var c Config + configContent, err := os.ReadFile(configFilePath) + if err != nil { + return nil, err + } + + err = json.Unmarshal(configContent, &c) + if err != nil { + return nil, err + } + + if c.Id == "" { + c.Id = uuid.NewString() + } + + if c.ProvidersDir == "" { + defaultProvidersDir, err := getDefaultProvidersDir() + if err != nil { + return nil, err + } + + c.ProvidersDir = defaultProvidersDir + } + + if c.LogFile == nil { + logFilePath, err := getDefaultLogFilePath() + if err != nil { + log.Error("failed to get default log file path") + } + + c.LogFile = logs.GetDefaultLogFileConfig(logFilePath) + } + + err = Save(c) + if err != nil { + return nil, err + } + + return &c, nil +} + +func GetConfigDir() (string, error) { + daytonaConfigDir := os.Getenv("DAYTONA_RUNNER_CONFIG_DIR") + if daytonaConfigDir != "" { + return daytonaConfigDir, nil + } + + userConfigDir, err := os.UserConfigDir() + if err != nil { + return "", err + } + + return filepath.Join(userConfigDir, "daytona-runner"), nil +} + +func Save(c Config) error { + if err := util.DirectoryValidator(&c.ProvidersDir); err != nil { + return err + } + + configFilePath, err := configFilePath() + if err != nil { + return err + } + + configContent, err := json.MarshalIndent(c, "", " ") + if err != nil { + return err + } + + err = os.MkdirAll(filepath.Dir(configFilePath), 0700) + if err != nil { + return err + } + + err = os.WriteFile(configFilePath, configContent, 0600) + if err != nil { + return err + } + + return nil +} + +func EnableTelemetry(c Config) error { + c.TelemetryEnabled = true + + return Save(c) +} + +func DisableTelemetry(c Config) error { + c.TelemetryEnabled = false + + return Save(c) +} + +func configFilePath() (string, error) { + configDir, err := GetConfigDir() + if err != nil { + return "", err + } + + return filepath.Join(configDir, "config.json"), nil +} + +func getDefaultLogFilePath() (string, error) { + configDir, err := GetConfigDir() + if err != nil { + return "", err + } + + return filepath.Join(configDir, "log"), nil +} + +func GetDefaultConfig() (*Config, error) { + providersDir, err := getDefaultProvidersDir() + if err != nil { + return nil, errors.New("failed to get default providers dir") + } + + logFilePath, err := getDefaultLogFilePath() + if err != nil { + log.Error("failed to get default log file path") + } + + c := Config{ + ProvidersDir: providersDir, + LogFile: logs.GetDefaultLogFileConfig(logFilePath), + } + + if os.Getenv("DEFAULT_PROVIDERS_DIR") != "" { + c.ProvidersDir = os.Getenv("DEFAULT_PROVIDERS_DIR") + } + + return &c, nil +} + +func getDefaultProvidersDir() (string, error) { + configDir, err := GetConfigDir() + if err != nil { + return "", err + } + + return filepath.Join(configDir, "providers"), nil +} + +func GetLogsDir(configDir string) string { + return filepath.Join(configDir, "logs") +} diff --git a/pkg/provider/manager/error.go b/pkg/runner/providermanager/error.go similarity index 95% rename from pkg/provider/manager/error.go rename to pkg/runner/providermanager/error.go index e8faa1f393..1da18a57e8 100644 --- a/pkg/provider/manager/error.go +++ b/pkg/runner/providermanager/error.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package manager +package providermanager import "fmt" diff --git a/pkg/provider/manager/installer.go b/pkg/runner/providermanager/installer.go similarity index 51% rename from pkg/provider/manager/installer.go rename to pkg/runner/providermanager/installer.go index 239928ee74..961e95a5ac 100644 --- a/pkg/provider/manager/installer.go +++ b/pkg/runner/providermanager/installer.go @@ -1,14 +1,10 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package manager +package providermanager import ( "context" - "encoding/json" - "fmt" - "io" - "net/http" goos "os" "path/filepath" "runtime" @@ -17,31 +13,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (m *ProviderManager) GetProvidersManifest() (*ProvidersManifest, error) { - manifestUrl := fmt.Sprintf("%s/providers/manifest.json", m.registryUrl) - - resp, err := http.Get(manifestUrl) - if err != nil { - return nil, err - } - - defer resp.Body.Close() - - manifestJson, err := io.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - var manifest ProvidersManifest - err = json.Unmarshal(manifestJson, &manifest) - if err != nil { - return nil, err - } - - return &manifest, nil -} - -func (m *ProviderManager) DownloadProvider(ctx context.Context, downloadUrls map[os.OperatingSystem]string, providerName string) (string, error) { +func (m *providerManagerImpl) DownloadProvider(ctx context.Context, downloadUrls map[os.OperatingSystem]string, providerName string) (string, error) { downloadPath := filepath.Join(m.baseDir, providerName, providerName) if runtime.GOOS == "windows" { downloadPath += ".exe" diff --git a/pkg/provider/manager/manager.go b/pkg/runner/providermanager/manager.go similarity index 73% rename from pkg/provider/manager/manager.go rename to pkg/runner/providermanager/manager.go index cfeeb69f7b..8cf7c759c6 100644 --- a/pkg/provider/manager/manager.go +++ b/pkg/runner/providermanager/manager.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package manager +package providermanager import ( "context" @@ -16,7 +16,7 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" os_util "github.com/daytonaio/daytona/pkg/os" - . "github.com/daytonaio/daytona/pkg/provider" + "github.com/daytonaio/daytona/pkg/provider" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-plugin" "github.com/shirou/gopsutil/process" @@ -39,9 +39,8 @@ var ProviderHandshakeConfig = plugin.HandshakeConfig{ type IProviderManager interface { DownloadProvider(ctx context.Context, downloadUrls map[os_util.OperatingSystem]string, providerName string) (string, error) - GetProvider(name string) (*Provider, error) - GetProviders() map[string]Provider - GetProvidersManifest() (*ProvidersManifest, error) + GetProvider(name string) (*provider.Provider, error) + GetProviders() map[string]provider.Provider RegisterProvider(pluginPath string, manualInstall bool) error TerminateProviderProcesses(providersBasePath string) error UninstallProvider(name string) error @@ -52,22 +51,25 @@ type ProviderManagerConfig struct { GetTargetConfigMap func(ctx context.Context) (map[string]*models.TargetConfig, error) CreateTargetConfig func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error CreateProviderNetworkKey func(ctx context.Context, providerName string) (string, error) + RunnerId string + RunnerName string DaytonaDownloadUrl string ServerUrl string - ServerVersion string ApiUrl string - LogsDir string - RegistryUrl string + ApiKey *string + WorkspaceLogsDir string + TargetLogsDir string BaseDir string ServerPort uint32 ApiPort uint32 + Logger *log.Logger } -var providerManager *ProviderManager +var providerManager *providerManagerImpl -func GetProviderManager(config *ProviderManagerConfig) *ProviderManager { +func GetProviderManager(config *ProviderManagerConfig) *providerManagerImpl { if config != nil && providerManager != nil { - log.Fatal("Provider manager already initialized") + config.Logger.Fatal("Provider manager already initialized") } if providerManager == nil { @@ -75,27 +77,32 @@ func GetProviderManager(config *ProviderManagerConfig) *ProviderManager { log.Fatal("Provider manager not initialized") } - providerManager = &ProviderManager{ + providerManager = &providerManagerImpl{ pluginRefs: make(map[string]*pluginRef), + runnerId: config.RunnerId, + runnerName: config.RunnerName, daytonaDownloadUrl: config.DaytonaDownloadUrl, serverUrl: config.ServerUrl, - serverVersion: config.ServerVersion, apiUrl: config.ApiUrl, - logsDir: config.LogsDir, + apiKey: config.ApiKey, + workspaceLogsDir: config.WorkspaceLogsDir, + targetLogsDir: config.TargetLogsDir, getTargetConfigMap: config.GetTargetConfigMap, createTargetConfig: config.CreateTargetConfig, - registryUrl: config.RegistryUrl, baseDir: config.BaseDir, createProviderNetworkKey: config.CreateProviderNetworkKey, serverPort: config.ServerPort, apiPort: config.ApiPort, + logger: config.Logger, } } return providerManager } -type ProviderManager struct { +type providerManagerImpl struct { + runnerId string + runnerName string pluginRefs map[string]*pluginRef getTargetConfigMap func(ctx context.Context) (map[string]*models.TargetConfig, error) createTargetConfig func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error @@ -104,14 +111,16 @@ type ProviderManager struct { serverUrl string serverVersion string apiUrl string + apiKey *string serverPort uint32 apiPort uint32 - logsDir string - registryUrl string + workspaceLogsDir string + targetLogsDir string baseDir string + logger *log.Logger } -func (m *ProviderManager) GetProvider(name string) (*Provider, error) { +func (m *providerManagerImpl) GetProvider(name string) (*provider.Provider, error) { pluginRef, ok := m.pluginRefs[name] if !ok { return nil, errors.New("provider not found") @@ -134,12 +143,12 @@ func (m *ProviderManager) GetProvider(name string) (*Provider, error) { return p, nil } -func (m *ProviderManager) GetProviders() map[string]Provider { - providers := make(map[string]Provider) +func (m *providerManagerImpl) GetProviders() map[string]provider.Provider { + providers := make(map[string]provider.Provider) for name := range m.pluginRefs { provider, err := m.GetProvider(name) if err != nil { - log.Printf("Error getting provider %s: %s", name, err) + m.logger.Printf("Error getting provider %s: %s", name, err) continue } @@ -149,7 +158,7 @@ func (m *ProviderManager) GetProviders() map[string]Provider { return providers } -func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool) error { +func (m *providerManagerImpl) RegisterProvider(pluginPath string, manualInstall bool) error { ctx := context.Background() pluginRef, err := m.initializeProvider(pluginPath) @@ -182,35 +191,32 @@ func (m *ProviderManager) RegisterProvider(pluginPath string, manualInstall bool return errors.New("failed to get preset target configs: " + err.Error()) } - log.Infof("Setting preset target configs for %s", pluginRef.name) + m.logger.Infof("Setting preset target configs for %s", pluginRef.name) for _, targetConfig := range *presetTargetConfigs { if _, ok := existingTargetConfigs[targetConfig.Name]; ok { - log.Infof("Target config %s already exists. Skipping...", targetConfig.Name) + m.logger.Infof("Target config %s already exists. Skipping...", targetConfig.Name) continue } - err = m.createTargetConfig(ctx, targetConfig.Name, targetConfig.Options, - models.ProviderInfo{ - Name: providerInfo.Name, - Version: providerInfo.Version, - Label: providerInfo.Label, - AgentlessTarget: providerInfo.AgentlessTarget, - }) + providerInfo.RunnerId = m.runnerId + providerInfo.RunnerName = m.runnerName + + err = m.createTargetConfig(ctx, targetConfig.Name, targetConfig.Options, providerInfo) if err != nil { - log.Errorf("Failed to set target config %s: %s", targetConfig.Name, err) + m.logger.Errorf("Failed to set target config %s: %s", targetConfig.Name, err) } else { - log.Infof("Target config %s set", targetConfig.Name) + m.logger.Infof("Target config %s set", targetConfig.Name) } } - log.Infof("Preset target configs set for %s", pluginRef.name) + m.logger.Infof("Preset target configs set for %s", pluginRef.name) } - log.Infof("Provider %s initialized", pluginRef.name) + m.logger.Infof("Provider %s initialized", pluginRef.name) return nil } -func (m *ProviderManager) UninstallProvider(name string) error { +func (m *providerManagerImpl) UninstallProvider(name string) error { pluginRef, ok := m.pluginRefs[name] if !ok { return errors.New("provider not found") @@ -251,9 +257,8 @@ func (m *ProviderManager) UninstallProvider(name string) error { return nil } -func (m *ProviderManager) TerminateProviderProcesses(providersBasePath string) error { +func (m *providerManagerImpl) TerminateProviderProcesses(providersBasePath string) error { process, err := process.Processes() - if err != nil { return err } @@ -262,7 +267,7 @@ func (m *ProviderManager) TerminateProviderProcesses(providersBasePath string) e if e, err := p.Exe(); err == nil && strings.HasPrefix(e, providersBasePath) { err := p.Kill() if err != nil { - log.Errorf("Failed to kill process %d: %s", p.Pid, err) + m.logger.Errorf("Failed to kill process %d: %s", p.Pid, err) } } } @@ -270,7 +275,7 @@ func (m *ProviderManager) TerminateProviderProcesses(providersBasePath string) e return nil } -func (m *ProviderManager) Purge() error { +func (m *providerManagerImpl) Purge() error { for name := range m.pluginRefs { err := m.UninstallProvider(name) if err != nil { @@ -283,7 +288,7 @@ func (m *ProviderManager) Purge() error { return os.RemoveAll(m.baseDir) } -func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, error) { +func (m *providerManagerImpl) initializeProvider(pluginPath string) (*pluginRef, error) { ctx := context.Background() pluginName := filepath.Base(pluginPath) @@ -305,7 +310,7 @@ func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, err }) pluginMap := map[string]plugin.Plugin{} - pluginMap[pluginName] = &ProviderPlugin{} + pluginMap[pluginName] = &provider.ProviderPlugin{} client := plugin.NewClient(&plugin.ClientConfig{ HandshakeConfig: ProviderHandshakeConfig, @@ -315,7 +320,7 @@ func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, err Managed: true, }) - log.Infof("Provider %s registered", pluginName) + m.logger.Infof("Provider %s registered", pluginName) p, err := m.dispenseProvider(client, pluginName) if err != nil { @@ -327,13 +332,15 @@ func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, err return nil, errors.New("failed to create network key: " + err.Error()) } - _, err = (*p).Initialize(InitializeProviderRequest{ + _, err = (*p).Initialize(provider.InitializeProviderRequest{ BasePath: pluginBasePath, DaytonaDownloadUrl: m.daytonaDownloadUrl, DaytonaVersion: m.serverVersion, ServerUrl: m.serverUrl, ApiUrl: m.apiUrl, - LogsDir: m.logsDir, + ApiKey: m.apiKey, + WorkspaceLogsDir: m.workspaceLogsDir, + TargetLogsDir: m.targetLogsDir, NetworkKey: networkKey, ServerPort: m.serverPort, ApiPort: m.apiPort, @@ -349,7 +356,7 @@ func (m *ProviderManager) initializeProvider(pluginPath string) (*pluginRef, err }, nil } -func (m *ProviderManager) dispenseProvider(client *plugin.Client, name string) (*Provider, error) { +func (m *providerManagerImpl) dispenseProvider(client *plugin.Client, name string) (*provider.Provider, error) { rpcClient, err := client.Client() if err != nil { return nil, err @@ -360,7 +367,7 @@ func (m *ProviderManager) dispenseProvider(client *plugin.Client, name string) ( return nil, err } - provider, ok := raw.(Provider) + provider, ok := raw.(provider.Provider) if !ok { return nil, errors.New("unexpected type from plugin") } diff --git a/pkg/runner/providers.go b/pkg/runner/providers.go new file mode 100644 index 0000000000..6c4041b21d --- /dev/null +++ b/pkg/runner/providers.go @@ -0,0 +1,142 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "errors" + "os" + "path/filepath" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/runner/providermanager" +) + +func (r *Runner) downloadDefaultProviders(registryUrl string) error { + manifest, err := util.GetProvidersManifest(registryUrl) + if err != nil { + return err + } + + defaultProviders := manifest.GetDefaultProviders() + + r.logger.Info("Downloading default providers") + for providerName, provider := range defaultProviders { + lockFilePath := filepath.Join(r.Config.ProvidersDir, providerName, providermanager.INITIAL_SETUP_LOCK_FILE_NAME) + + _, err := os.Stat(lockFilePath) + if err == nil { + continue + } + + _, err = r.providerManager.DownloadProvider(context.Background(), provider.DownloadUrls, providerName) + if err != nil { + if !providermanager.IsProviderAlreadyDownloaded(err, providerName) { + r.logger.Error(err) + } + continue + } + } + + r.logger.Info("Default providers downloaded") + + return nil +} + +func (r *Runner) registerProviders(registryUrl string) error { + r.logger.Info("Registering providers") + + manifest, err := util.GetProvidersManifest(registryUrl) + if err != nil { + return err + } + + directoryEntries, err := os.ReadDir(r.Config.ProvidersDir) + if err != nil { + if os.IsNotExist(err) { + r.logger.Info("No providers found") + return nil + } + return err + } + + for _, entry := range directoryEntries { + if entry.IsDir() { + providerDir := filepath.Join(r.Config.ProvidersDir, entry.Name()) + + pluginPath, err := r.getPluginPath(providerDir) + if err != nil { + if !providermanager.IsNoPluginFound(err, providerDir) { + r.logger.Error(err) + } + continue + } + + err = r.providerManager.RegisterProvider(pluginPath, false) + if err != nil { + r.logger.Error(err) + continue + } + + // Lock the initial setup + lockFilePath := filepath.Join(r.Config.ProvidersDir, entry.Name(), providermanager.INITIAL_SETUP_LOCK_FILE_NAME) + + _, err = os.Stat(lockFilePath) + if err != nil { + file, err := os.Create(lockFilePath) + if err != nil { + return err + } + defer file.Close() + } + + // Check for updates + provider, err := r.providerManager.GetProvider(entry.Name()) + if err != nil { + r.logger.Error(err) + continue + } + + info, err := (*provider).GetInfo() + if err != nil { + r.logger.Error(err) + continue + } + requirements, err := (*provider).CheckRequirements() + if err != nil { + return err + } + for _, req := range *requirements { + if req.Met { + r.logger.Infof("Provider requirement met: %s", req.Reason) + } else { + r.logger.Warnf("Provider requirement not met: %s", req.Reason) + } + } + + if manifest.HasUpdateAvailable(info.Name, info.Version) { + r.logger.Infof("Update available for %s. Update with `daytona provider update`.", info.Name) + } + } + } + + r.logger.Info("Providers registered") + + return nil +} + +func (r *Runner) getPluginPath(dir string) (string, error) { + files, err := os.ReadDir(dir) + if err != nil { + return "", err + } + + for _, file := range files { + if !file.IsDir() && file.Name() != providermanager.INITIAL_SETUP_LOCK_FILE_NAME { + return filepath.Join(dir, file.Name()), nil + } + } + + return "", errors.New("no plugin found in " + dir) +} diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go new file mode 100644 index 0000000000..c9c2d17bf9 --- /dev/null +++ b/pkg/runner/runner.go @@ -0,0 +1,259 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "context" + "errors" + "fmt" + "net/http" + "os" + "os/signal" + "time" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/jobs" + "github.com/daytonaio/daytona/pkg/jobs/build" + "github.com/daytonaio/daytona/pkg/jobs/runner" + "github.com/daytonaio/daytona/pkg/jobs/target" + "github.com/daytonaio/daytona/pkg/jobs/workspace" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/runner/providermanager" + "github.com/daytonaio/daytona/pkg/scheduler" + "github.com/hashicorp/go-plugin" + log "github.com/sirupsen/logrus" +) + +// TODO: add lock when running interval func +// 1 second interval +const DEFAULT_JOB_POLL_INTERVAL = "*/1 * * * * *" + +const RUNNER_METADATA_UPDATE_INTERVAL = 2 * time.Second + +type IRunner interface { + Start(ctx context.Context) error + CheckAndRunJobs(ctx context.Context) error +} + +type RunnerConfig struct { + models.Runner + Config *Config + Logger *log.Logger + + ProviderManager providermanager.IProviderManager + RegistryUrl string + + ListPendingJobs func(ctx context.Context) ([]*models.Job, int, error) + UpdateJobState func(ctx context.Context, jobId string, state models.JobState, err *error) error + SetRunnerMetadata func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error + + WorkspaceJobFactory workspace.IWorkspaceJobFactory + TargetJobFactory target.ITargetJobFactory + BuildJobFactory build.IBuildJobFactory + RunnerJobFactory runner.IRunnerJobFactory +} + +func NewRunner(config RunnerConfig) IRunner { + return &Runner{ + Runner: config.Runner, + Config: config.Config, + logger: config.Logger, + + providerManager: config.ProviderManager, + registryUrl: config.RegistryUrl, + + listPendingJobs: config.ListPendingJobs, + updateJobState: config.UpdateJobState, + setRunnerMetadata: config.SetRunnerMetadata, + + workspaceJobFactory: config.WorkspaceJobFactory, + targetJobFactory: config.TargetJobFactory, + buildJobFactory: config.BuildJobFactory, + runnerJobFactory: config.RunnerJobFactory, + } +} + +type Runner struct { + models.Runner + Config *Config + logger *log.Logger + startTime time.Time + + providerManager providermanager.IProviderManager + registryUrl string + + listPendingJobs func(ctx context.Context) ([]*models.Job, int, error) + updateJobState func(ctx context.Context, jobId string, state models.JobState, err *error) error + setRunnerMetadata func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error + + workspaceJobFactory workspace.IWorkspaceJobFactory + targetJobFactory target.ITargetJobFactory + buildJobFactory build.IBuildJobFactory + runnerJobFactory runner.IRunnerJobFactory +} + +func (r *Runner) Start(ctx context.Context) error { + r.logger.Info(fmt.Sprintf("Starting runner %s\n", r.Config.Id)) + + r.startTime = time.Now() + + go func() { + interruptChannel := make(chan os.Signal, 1) + signal.Notify(interruptChannel, os.Interrupt) + + for range interruptChannel { + plugin.CleanupClients() + } + }() + + // Terminate orphaned provider processes + err := r.providerManager.TerminateProviderProcesses(r.Config.ProvidersDir) + if err != nil { + r.logger.Errorf("Failed to terminate orphaned provider processes: %s", err) + } + + err = r.downloadDefaultProviders(r.registryUrl) + if err != nil { + return err + } + + err = r.registerProviders(r.registryUrl) + if err != nil { + return err + } + + scheduler := scheduler.NewCronScheduler() + + err = scheduler.AddFunc(DEFAULT_JOB_POLL_INTERVAL, func() { + err := r.CheckAndRunJobs(ctx) + if err != nil { + r.logger.Error(err) + } + }) + if err != nil { + return err + } + + scheduler.Start() + + r.logger.Info("Runner started") + + go func() { + for { + _ = r.UpdateRunnerMetadata(r.Config) + time.Sleep(RUNNER_METADATA_UPDATE_INTERVAL) + } + }() + + <-ctx.Done() + + r.logger.Info("Shutting down runner") + scheduler.Stop() + return nil +} + +func (r *Runner) CheckAndRunJobs(ctx context.Context) error { + jobs, statusCode, err := r.listPendingJobs(ctx) + if err != nil { + if statusCode == http.StatusNotFound { + return nil + } + return err + } + + // goroutines, sync group + for _, job := range jobs { + err = r.runJob(ctx, job) + if err != nil { + return err + } + } + + return nil +} + +func (r *Runner) runJob(ctx context.Context, j *models.Job) error { + var job jobs.IJob + + j.State = models.JobStateRunning + err := r.updateJobState(ctx, j.Id, models.JobStateRunning, nil) + if err != nil { + return err + } + + r.logJobStateUpdate(j) + + switch j.ResourceType { + case models.ResourceTypeWorkspace: + job = r.workspaceJobFactory.Create(*j) + case models.ResourceTypeTarget: + job = r.targetJobFactory.Create(*j) + case models.ResourceTypeBuild: + job = r.buildJobFactory.Create(*j) + case models.ResourceTypeRunner: + job = r.runnerJobFactory.Create(*j) + default: + return errors.New("invalid resource type for job") + } + + err = job.Execute(ctx) + if err != nil { + j.State = models.JobStateError + r.logJobStateUpdate(j) + return r.updateJobState(ctx, j.Id, models.JobStateError, &err) + } + + j.State = models.JobStateSuccess + r.logJobStateUpdate(j) + return r.updateJobState(ctx, j.Id, models.JobStateSuccess, nil) +} + +// Runner uptime in seconds +func (r *Runner) uptime() int32 { + return max(int32(time.Since(r.startTime).Seconds()), 1) +} + +func (r *Runner) UpdateRunnerMetadata(config *Config) error { + providers := r.providerManager.GetProviders() + uptime := r.uptime() + + providerInfos := []models.ProviderInfo{} + for _, provider := range providers { + info, err := provider.GetInfo() + if err != nil { + r.logger.Info(fmt.Errorf("failed to get provider: %w", err)) + continue + } + + info.RunnerId = r.Config.Id + info.RunnerName = r.Config.Name + providerInfos = append(providerInfos, info) + } + + return r.setRunnerMetadata(context.Background(), r.Config.Id, models.RunnerMetadata{ + Uptime: uint64(uptime), + Providers: providerInfos, + RunningJobs: util.Pointer(uint64(0)), + }) +} + +func (r *Runner) logJobStateUpdate(j *models.Job) { + if j == nil { + return + } + + message := "Invalid Job State" + switch j.State { + case models.JobStatePending: + message = "Job pending" + case models.JobStateSuccess: + message = "Job succeeded" + case models.JobStateError: + message = "Job failed" + case models.JobStateRunning: + message = "Running job" + } + + r.logger.Info(fmt.Sprintf("%-16s %-16s %-12s %-12s\n", message, j.Id, j.ResourceType, j.Action)) +} diff --git a/pkg/runners/runner.go b/pkg/runners/runner.go deleted file mode 100644 index bccfb75577..0000000000 --- a/pkg/runners/runner.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package runners - -import ( - "context" -) - -// TODO: add lock when running interval func -// 1 second interval -const DEFAULT_JOB_POLL_INTERVAL = "*/1 * * * * *" - -type IJobRunner interface { - StartRunner(ctx context.Context) error - CheckAndRunJobs(ctx context.Context) error -} diff --git a/pkg/runners/runner/runner.go b/pkg/runners/runner/runner.go deleted file mode 100644 index b647181ca1..0000000000 --- a/pkg/runners/runner/runner.go +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package runner - -import ( - "context" - - "github.com/daytonaio/daytona/pkg/jobs" - "github.com/daytonaio/daytona/pkg/jobs/build" - "github.com/daytonaio/daytona/pkg/jobs/target" - "github.com/daytonaio/daytona/pkg/jobs/workspace" - "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/runners" - "github.com/daytonaio/daytona/pkg/scheduler" - log "github.com/sirupsen/logrus" -) - -type JobRunnerConfig struct { - ListPendingJobs func(ctx context.Context) ([]*models.Job, error) - UpdateJobState func(ctx context.Context, job *models.Job, state models.JobState, err *error) error - - WorkspaceJobFactory workspace.IWorkspaceJobFactory - TargetJobFactory target.ITargetJobFactory - BuildJobFactory build.IBuildJobFactory -} - -func NewJobRunner(config JobRunnerConfig) runners.IJobRunner { - return &JobRunner{ - listPendingJobs: config.ListPendingJobs, - updateJobState: config.UpdateJobState, - - workspaceJobFactory: config.WorkspaceJobFactory, - targetJobFactory: config.TargetJobFactory, - buildJobFactory: config.BuildJobFactory, - } -} - -type JobRunner struct { - listPendingJobs func(ctx context.Context) ([]*models.Job, error) - updateJobState func(ctx context.Context, job *models.Job, state models.JobState, err *error) error - - workspaceJobFactory workspace.IWorkspaceJobFactory - targetJobFactory target.ITargetJobFactory - buildJobFactory build.IBuildJobFactory -} - -func (s *JobRunner) StartRunner(ctx context.Context) error { - scheduler := scheduler.NewCronScheduler() - - err := scheduler.AddFunc(runners.DEFAULT_JOB_POLL_INTERVAL, func() { - err := s.CheckAndRunJobs(ctx) - if err != nil { - log.Error(err) - } - }) - if err != nil { - return err - } - - scheduler.Start() - return nil -} - -func (s *JobRunner) CheckAndRunJobs(ctx context.Context) error { - jobs, err := s.listPendingJobs(ctx) - if err != nil { - return err - } - - // goroutines, sync group - for _, job := range jobs { - err = s.runJob(ctx, job) - if err != nil { - return err - } - } - - return nil -} - -func (s *JobRunner) runJob(ctx context.Context, j *models.Job) error { - var job jobs.IJob - - err := s.updateJobState(ctx, j, models.JobStateRunning, nil) - if err != nil { - return err - } - - switch j.ResourceType { - case models.ResourceTypeWorkspace: - job = s.workspaceJobFactory.Create(*j) - case models.ResourceTypeTarget: - job = s.targetJobFactory.Create(*j) - case models.ResourceTypeBuild: - job = s.buildJobFactory.Create(*j) - } - - err = job.Execute(ctx) - if err != nil { - return s.updateJobState(ctx, j, models.JobStateError, &err) - } - - return s.updateJobState(ctx, j, models.JobStateSuccess, nil) -} diff --git a/pkg/server/apikeys/validate.go b/pkg/server/apikeys/validate.go index abe4104816..71ce71472f 100644 --- a/pkg/server/apikeys/validate.go +++ b/pkg/server/apikeys/validate.go @@ -17,19 +17,15 @@ func (s *ApiKeyService) IsValidApiKey(ctx context.Context, apiKey string) bool { return err == nil } -func (s *ApiKeyService) IsWorkspaceApiKey(ctx context.Context, apiKey string) bool { +func (s *ApiKeyService) GetApiKeyType(ctx context.Context, apiKey string) (models.ApiKeyType, error) { keyHash := apikeys.HashKey(apiKey) key, err := s.apiKeyStore.Find(ctx, keyHash) if err != nil { - return false + return models.ApiKeyTypeClient, err } - if key.Type != models.ApiKeyTypeWorkspace { - return false - } - - return true + return key.Type, nil } func (s *ApiKeyService) IsTargetApiKey(ctx context.Context, apiKey string) bool { diff --git a/pkg/server/apikeys/validate_test.go b/pkg/server/apikeys/validate_test.go index 22c5b66fb5..481801e61b 100644 --- a/pkg/server/apikeys/validate_test.go +++ b/pkg/server/apikeys/validate_test.go @@ -30,7 +30,7 @@ func (s *ApiKeyServiceTestSuite) TestIsValidKey_False() { require.False(res) } -func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_True() { +func (s *ApiKeyServiceTestSuite) TestGetApiKeyType() { keyName := "workspaceKey" require := s.Require() @@ -38,42 +38,7 @@ func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_True() { apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) require.Nil(err) - res := s.apiKeyService.IsWorkspaceApiKey(context.TODO(), apiKey) - require.True(res) -} - -func (s *ApiKeyServiceTestSuite) TestIsWorkspaceApiKey_False() { - keyName := "clientKey" - - require := s.Require() - - apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) - require.Nil(err) - - res := s.apiKeyService.IsWorkspaceApiKey(context.TODO(), apiKey) - require.False(res) -} - -func (s *ApiKeyServiceTestSuite) TestIsIsTargetApiKey_True() { - keyName := "targetKey" - - require := s.Require() - - apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeTarget, keyName) - require.Nil(err) - - res := s.apiKeyService.IsTargetApiKey(context.TODO(), apiKey) - require.True(res) -} - -func (s *ApiKeyServiceTestSuite) TestIsTargetApiKey_False() { - keyName := "clientKey" - - require := s.Require() - - apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) + apiKeyType, err := s.apiKeyService.GetApiKeyType(context.TODO(), apiKey) require.Nil(err) - - res := s.apiKeyService.IsTargetApiKey(context.TODO(), apiKey) - require.False(res) + require.Equal(models.ApiKeyTypeWorkspace, apiKeyType) } diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index 107f0dbca8..cdaebd60f3 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -22,7 +22,7 @@ type BuildServiceConfig struct { FindWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) CreateJob func(ctx context.Context, workspaceId string, action models.JobAction) error - LoggerFactory logs.LoggerFactory + LoggerFactory logs.ILoggerFactory } type BuildService struct { @@ -30,7 +30,7 @@ type BuildService struct { findWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) createJob func(ctx context.Context, workspaceId string, action models.JobAction) error - loggerFactory logs.LoggerFactory + loggerFactory logs.ILoggerFactory } func NewBuildService(config BuildServiceConfig) services.IBuildService { @@ -194,5 +194,9 @@ func (s *BuildService) AwaitEmptyList(ctx context.Context, waitTime time.Duratio } func (s *BuildService) GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) { - return s.loggerFactory.CreateBuildLogReader(buildId) + return s.loggerFactory.CreateLogReader(buildId) +} + +func (s *BuildService) GetBuildLogWriter(ctx context.Context, buildId string) (io.WriteCloser, error) { + return s.loggerFactory.CreateLogWriter(buildId) } diff --git a/pkg/server/config.go b/pkg/server/config.go index b35e07af4f..aaaf7cbfe7 100644 --- a/pkg/server/config.go +++ b/pkg/server/config.go @@ -10,7 +10,10 @@ import ( "path/filepath" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/logs" "github.com/google/uuid" + log "github.com/sirupsen/logrus" ) func GetConfig() (*Config, error) { @@ -54,7 +57,12 @@ func GetConfig() (*Config, error) { } if c.LogFile == nil { - c.LogFile = getDefaultLogFileConfig() + logFilePath, err := getDefaultLogFilePath() + if err != nil { + log.Error("failed to get default log file path") + } + + c.LogFile = logs.GetDefaultLogFileConfig(logFilePath) } err = Save(c) @@ -75,10 +83,7 @@ func configFilePath() (string, error) { } func Save(c Config) error { - if err := directoryValidator(&c.BinariesPath); err != nil { - return err - } - if err := directoryValidator(&c.ProvidersDir); err != nil { + if err := util.DirectoryValidator(&c.BinariesPath); err != nil { return err } @@ -114,14 +119,18 @@ func GetConfigDir() (string, error) { return filepath.Join(configDir, "server"), nil } -func GetTargetLogsDir(configDir string) (string, error) { - return filepath.Join(configDir, "logs"), nil +func GetTargetLogsDir(configDir string) string { + return filepath.Join(configDir, "logs", "targets") } -func directoryValidator(path *string) error { - _, err := os.Stat(*path) - if os.IsNotExist(err) { - return os.MkdirAll(*path, 0700) - } - return err +func GetRunnerLogsDir(configDir string) string { + return filepath.Join(configDir, "logs", "runners") +} + +func GetWorkspaceLogsDir(configDir string) string { + return filepath.Join(configDir, "logs", "workspaces") +} + +func GetBuildLogsDir(configDir string) string { + return filepath.Join(configDir, "logs", "builds") } diff --git a/pkg/server/defaults.go b/pkg/server/defaults.go index a99d8839f0..4d6a76b15c 100644 --- a/pkg/server/defaults.go +++ b/pkg/server/defaults.go @@ -11,7 +11,8 @@ import ( "path/filepath" "strconv" - "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/logs" "github.com/google/uuid" log "github.com/sirupsen/logrus" @@ -31,14 +32,6 @@ const defaultLocalBuilderRegistryImage = "registry:2.8.3" const defaultBuilderRegistryServer = "local" const defaultBuildImageNamespace = "" -var defaultLogFileConfig = LogFileConfig{ - MaxSize: 100, // megabytes - MaxBackups: 7, - MaxAge: 15, // days - LocalTime: true, - Compress: true, -} - var us_defaultFrpsConfig = FRPSConfig{ Domain: "try-us.daytona.app", Port: 7000, @@ -94,100 +87,32 @@ func getDefaultFRPSConfig() *FRPSConfig { } } -func getDefaultLogFileConfig() *LogFileConfig { - logFilePath, err := getDefaultLogFilePath() - if err != nil { - log.Error("failed to get default log file path") - } - - logFileConfig := LogFileConfig{ - Path: logFilePath, - MaxSize: defaultLogFileConfig.MaxSize, - MaxBackups: defaultLogFileConfig.MaxBackups, - MaxAge: defaultLogFileConfig.MaxAge, - LocalTime: defaultLogFileConfig.LocalTime, - Compress: defaultLogFileConfig.Compress, - } - - logFileMaxSize := os.Getenv("DEFAULT_LOG_FILE_MAX_SIZE") - if logFileMaxSize != "" { - value, err := strconv.Atoi(logFileMaxSize) - if err != nil { - log.Error(fmt.Printf("%s. Using default log file max size.", err)) - } else { - logFileConfig.MaxSize = value - } - } - - logFileMaxBackups := os.Getenv("DEFAULT_LOG_FILE_MAX_BACKUPS") - if logFileMaxBackups != "" { - value, err := strconv.Atoi(logFileMaxBackups) - if err != nil { - log.Error(fmt.Printf("%s. Using default log file max backups.", err)) - } else { - logFileConfig.MaxBackups = value - } - } - - logFileMaxAge := os.Getenv("DEFAULT_LOG_FILE_MAX_AGE") - if logFileMaxAge != "" { - value, err := strconv.Atoi(logFileMaxAge) - if err != nil { - log.Error(fmt.Printf("%s. Using default log file max age.", err)) - } else { - logFileConfig.MaxAge = value - } - } - - logFileLocalTime := os.Getenv("DEFAULT_LOG_FILE_LOCAL_TIME") - if logFileLocalTime != "" { - value, err := strconv.ParseBool(logFileLocalTime) - if err != nil { - log.Error(fmt.Printf("%s. Using default log file local time.", err)) - } else { - logFileConfig.LocalTime = value - } - } - - logFileCompress := os.Getenv("DEFAULT_LOG_FILE_COMPRESS") - if logFileCompress != "" { - value, err := strconv.ParseBool(logFileCompress) - if err != nil { - log.Error(fmt.Printf("%s. Using default log file compress.", err)) - } else { - logFileConfig.Compress = value - } - } - - return &logFileConfig -} - func getDefaultConfig() (*Config, error) { - providersDir, err := getDefaultProvidersDir() + binariesPath, err := getDefaultBinariesPath() if err != nil { - return nil, errors.New("failed to get default providers dir") + return nil, errors.New("failed to get default binaries path") } - binariesPath, err := getDefaultBinariesPath() + logFilePath, err := getDefaultLogFilePath() if err != nil { - return nil, errors.New("failed to get default binaries path") + log.Error("failed to get default log file path") } c := Config{ Id: uuid.NewString(), RegistryUrl: defaultRegistryUrl, - ProvidersDir: providersDir, ServerDownloadUrl: defaultServerDownloadUrl, ApiPort: defaultApiPort, HeadscalePort: defaultHeadscalePort, BinariesPath: binariesPath, Frps: getDefaultFRPSConfig(), - LogFile: getDefaultLogFileConfig(), + LogFile: logs.GetDefaultLogFileConfig(logFilePath), DefaultWorkspaceImage: defaultWorkspaceImage, DefaultWorkspaceUser: defaultWorkspaceUser, BuilderImage: defaultBuilderImage, LocalBuilderRegistryPort: defaultLocalBuilderRegistryPort, LocalBuilderRegistryImage: defaultLocalBuilderRegistryImage, + LocalRunnerDisabled: util.Pointer(false), BuilderRegistryServer: defaultBuilderRegistryServer, BuildImageNamespace: defaultBuildImageNamespace, SamplesIndexUrl: defaultSamplesIndexUrl, @@ -199,9 +124,6 @@ func getDefaultConfig() (*Config, error) { if os.Getenv("DEFAULT_SERVER_DOWNLOAD_URL") != "" { c.ServerDownloadUrl = os.Getenv("DEFAULT_SERVER_DOWNLOAD_URL") } - if os.Getenv("DEFAULT_PROVIDERS_DIR") != "" { - c.ProvidersDir = os.Getenv("DEFAULT_PROVIDERS_DIR") - } if os.Getenv("DEFAULT_BINARIES_PATH") != "" { c.BinariesPath = os.Getenv("DEFAULT_BINARIES_PATH") } @@ -237,15 +159,6 @@ func parsePort(port string) (uint32, error) { return uint32(p), nil } -func getDefaultProvidersDir() (string, error) { - configDir, err := config.GetConfigDir() - if err != nil { - return "", err - } - - return filepath.Join(configDir, "providers"), nil -} - func getDefaultLogFilePath() (string, error) { configDir, err := GetConfigDir() if err != nil { diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index 097f68621a..b1bac4d8eb 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -67,7 +67,7 @@ func (s *JobService) Create(ctx context.Context, j *models.Job) error { return s.jobStore.Save(ctx, j) } -func (s *JobService) SetState(ctx context.Context, jobId string, state models.JobState, err *string) error { +func (s *JobService) SetState(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { job, findErr := s.Find(ctx, &stores.JobFilter{ Id: &jobId, }) @@ -75,12 +75,12 @@ func (s *JobService) SetState(ctx context.Context, jobId string, state models.Jo return findErr } - if job.State == state { + if job.State == updateJobStateDto.State { return errors.New("job is already in the specified state") } - job.State = state - job.Error = err + job.State = updateJobStateDto.State + job.Error = updateJobStateDto.ErrorMessage return s.jobStore.Save(ctx, job) } @@ -111,4 +111,9 @@ var validResourceActions = map[models.ResourceType][]models.JobAction{ models.JobActionDelete, models.JobActionForceDelete, }, + models.ResourceTypeRunner: { + models.JobActionInstallProvider, + models.JobActionUninstallProvider, + models.JobActionUpdateProvider, + }, } diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go index f4938d16c1..fed94eed96 100644 --- a/pkg/server/jobs/service_test.go +++ b/pkg/server/jobs/service_test.go @@ -114,7 +114,10 @@ func (s *JobServiceTestSuite) TestSetState() { job4Update := *job4 job4Update.State = models.JobStateSuccess - err = s.jobService.SetState(context.TODO(), job4Update.Id, models.JobStateSuccess, nil) + err = s.jobService.SetState(context.TODO(), job4Update.Id, services.UpdateJobStateDTO{ + State: models.JobStateSuccess, + ErrorMessage: nil, + }) require.Nil(err) updated, err := s.jobService.Find(context.TODO(), &stores.JobFilter{ diff --git a/pkg/server/log.go b/pkg/server/log.go index 7ca329ae99..d8b244eaf8 100644 --- a/pkg/server/log.go +++ b/pkg/server/log.go @@ -11,7 +11,7 @@ import ( "regexp" "github.com/daytonaio/daytona/internal/constants" - "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/logs" frp_log "github.com/fatedier/frp/pkg/util/log" log "github.com/sirupsen/logrus" "gopkg.in/natefinch/lumberjack.v2" @@ -86,7 +86,7 @@ func (s *Server) GetLogReader(logFileQuery string) (io.Reader, error) { var reader io.Reader if regexp.MustCompile(constants.ZIP_LOG_FILE_NAME_SUFFIX_PATTERN).MatchString(logFileQuery) { - reader, err = util.ReadCompressedFile(logFilePath) + reader, err = logs.ReadCompressedFile(logFilePath) } else { reader, err = os.Open(logFilePath) } diff --git a/pkg/server/providers.go b/pkg/server/providers.go deleted file mode 100644 index 7c55961b47..0000000000 --- a/pkg/server/providers.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package server - -import ( - "context" - "errors" - "os" - "path/filepath" - - "github.com/daytonaio/daytona/pkg/provider/manager" - log "github.com/sirupsen/logrus" -) - -func (s *Server) downloadDefaultProviders() error { - manifest, err := s.ProviderManager.GetProvidersManifest() - if err != nil { - return err - } - - defaultProviders := manifest.GetDefaultProviders() - - log.Info("Downloading default providers") - for providerName, provider := range defaultProviders { - lockFilePath := filepath.Join(s.config.ProvidersDir, providerName, manager.INITIAL_SETUP_LOCK_FILE_NAME) - - _, err := os.Stat(lockFilePath) - if err == nil { - continue - } - - _, err = s.ProviderManager.DownloadProvider(context.Background(), provider.DownloadUrls, providerName) - if err != nil { - if !manager.IsProviderAlreadyDownloaded(err, providerName) { - log.Error(err) - } - continue - } - } - - log.Info("Default providers downloaded") - - return nil -} - -func (s *Server) registerProviders() error { - log.Info("Registering providers") - - manifest, err := s.ProviderManager.GetProvidersManifest() - if err != nil { - return err - } - - directoryEntries, err := os.ReadDir(s.config.ProvidersDir) - if err != nil { - if os.IsNotExist(err) { - log.Info("No providers found") - return nil - } - return err - } - - for _, entry := range directoryEntries { - if entry.IsDir() { - providerDir := filepath.Join(s.config.ProvidersDir, entry.Name()) - - pluginPath, err := s.getPluginPath(providerDir) - if err != nil { - if !manager.IsNoPluginFound(err, providerDir) { - log.Error(err) - } - continue - } - - err = s.ProviderManager.RegisterProvider(pluginPath, false) - if err != nil { - log.Error(err) - continue - } - - // Lock the initial setup - lockFilePath := filepath.Join(s.config.ProvidersDir, entry.Name(), manager.INITIAL_SETUP_LOCK_FILE_NAME) - - _, err = os.Stat(lockFilePath) - if err != nil { - file, err := os.Create(lockFilePath) - if err != nil { - return err - } - defer file.Close() - } - - // Check for updates - provider, err := s.ProviderManager.GetProvider(entry.Name()) - if err != nil { - log.Error(err) - continue - } - - info, err := (*provider).GetInfo() - if err != nil { - log.Error(err) - continue - } - requirements, err := (*provider).CheckRequirements() - if err != nil { - return err - } - for _, req := range *requirements { - if req.Met { - log.Infof("Provider requirement met: %s", req.Reason) - } else { - log.Warnf("Provider requirement not met: %s", req.Reason) - } - } - - if manifest.HasUpdateAvailable(info.Name, info.Version) { - log.Infof("Update available for %s. Update with `daytona provider update`.", info.Name) - } - } - } - - log.Info("Providers registered") - - return nil -} - -func (s *Server) getPluginPath(dir string) (string, error) { - files, err := os.ReadDir(dir) - if err != nil { - return "", err - } - - for _, file := range files { - if !file.IsDir() && file.Name() != manager.INITIAL_SETUP_LOCK_FILE_NAME { - return filepath.Join(dir, file.Name()), nil - } - } - - return "", errors.New("no plugin found in " + dir) -} diff --git a/pkg/server/purge.go b/pkg/server/purge.go index b68b158af1..47a048c88a 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -31,12 +31,6 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { fmt.Println("Deleting all targets...") - err := server.Start() - if err != nil { - s.trackPurgeError(ctx, force, err) - return []error{err} - } - targets, err := s.TargetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) if err != nil { s.trackPurgeError(ctx, force, err) @@ -63,16 +57,17 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { fmt.Printf("Failed to list targets: %v\n", err) } - fmt.Println("Purging providers...") - err = s.ProviderManager.Purge() - if err != nil { - s.trackPurgeError(ctx, force, err) - if !force { - return []error{err} - } else { - fmt.Printf("Failed to purge providers: %v\n", err) - } - } + // FIXME: todo + // fmt.Println("Purging providers...") + // err = s.ProviderManager.Purge() + // if err != nil { + // s.trackPurgeError(ctx, force, err) + // if !force { + // return []error{err} + // } else { + // fmt.Printf("Failed to purge providers: %v\n", err) + // } + // } fmt.Println("Purging builds...") errs := s.BuildService.Delete(ctx, nil, force) diff --git a/pkg/server/runners/jobs.go b/pkg/server/runners/jobs.go new file mode 100644 index 0000000000..573090b1dd --- /dev/null +++ b/pkg/server/runners/jobs.go @@ -0,0 +1,19 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runners + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" +) + +func (s *RunnerService) ListRunnerJobs(ctx context.Context, runnerId string) ([]*models.Job, error) { + return s.listJobsForRunner(ctx, runnerId) +} + +func (s *RunnerService) UpdateJobState(ctx context.Context, jobId string, req services.UpdateJobStateDTO) error { + return s.updateJobState(ctx, jobId, req) +} diff --git a/pkg/server/runners/provider.go b/pkg/server/runners/provider.go new file mode 100644 index 0000000000..c473134301 --- /dev/null +++ b/pkg/server/runners/provider.go @@ -0,0 +1,62 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runners + +import ( + "context" + "encoding/json" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" +) + +func (s *RunnerService) ListProviders(ctx context.Context, runnerId *string) ([]models.ProviderInfo, error) { + var metadatas []*models.RunnerMetadata + + if runnerId == nil { + var err error + metadatas, err = s.runnerMetadataStore.List(ctx) + if err != nil { + return nil, err + } + } else { + metadata, err := s.runnerMetadataStore.Find(ctx, *runnerId) + if err != nil { + return nil, err + } + metadatas = []*models.RunnerMetadata{metadata} + } + + providers := []models.ProviderInfo{} + for _, metadata := range metadatas { + providers = append(providers, metadata.Providers...) + } + + return providers, nil +} + +func (s *RunnerService) InstallProvider(ctx context.Context, runnerId string, providerMetadata services.InstallProviderDTO) error { + metadata, err := json.Marshal(providerMetadata) + if err != nil { + return err + } + + return s.createJob(ctx, runnerId, models.JobActionInstallProvider, string(metadata)) +} + +func (s *RunnerService) UninstallProvider(ctx context.Context, runnerId string, providerName string) error { + return s.createJob(ctx, runnerId, models.JobActionUninstallProvider, providerName) +} + +func (s *RunnerService) UpdateProvider(ctx context.Context, runnerId string, providerName string, downloadUrls services.DownloadUrls) error { + metadata, err := json.Marshal(services.InstallProviderDTO{ + Name: providerName, + DownloadUrls: downloadUrls, + }) + if err != nil { + return err + } + + return s.createJob(ctx, runnerId, models.JobActionUpdateProvider, string(metadata)) +} diff --git a/pkg/server/runners/register.go b/pkg/server/runners/register.go new file mode 100644 index 0000000000..1ab29a758b --- /dev/null +++ b/pkg/server/runners/register.go @@ -0,0 +1,62 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runners + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" +) + +func (s *RunnerService) RegisterRunner(ctx context.Context, req services.RegisterRunnerDTO) (*services.RunnerDTO, error) { + var err error + ctx, err = s.runnerStore.BeginTransaction(ctx) + if err != nil { + return nil, s.runnerStore.RollbackTransaction(ctx, err) + } + + defer stores.RecoverAndRollback(ctx, s.runnerStore) + + _, err = s.runnerStore.Find(ctx, req.Name) + if err == nil { + return nil, s.runnerStore.RollbackTransaction(ctx, services.ErrRunnerAlreadyExists) + } + + apiKey, err := s.generateApiKey(ctx, req.Id) + if err != nil { + return nil, s.runnerStore.RollbackTransaction(ctx, err) + } + + runner := &models.Runner{ + Id: req.Id, + Name: req.Name, + ApiKey: apiKey, + Metadata: &models.RunnerMetadata{ + RunnerId: req.Id, + Uptime: 0, + }, + } + + err = s.runnerStore.Save(ctx, runner) + if err != nil { + return nil, s.runnerStore.RollbackTransaction(ctx, err) + } + + err = s.runnerMetadataStore.Save(ctx, runner.Metadata) + if err != nil { + return nil, s.runnerStore.RollbackTransaction(ctx, err) + } + + err = s.runnerStore.CommitTransaction(ctx) + if err != nil { + return nil, s.runnerStore.RollbackTransaction(ctx, err) + } + + return &services.RunnerDTO{ + Runner: *runner, + State: runner.GetState(), + }, nil +} diff --git a/pkg/server/runners/remove.go b/pkg/server/runners/remove.go new file mode 100644 index 0000000000..8dd6a30c92 --- /dev/null +++ b/pkg/server/runners/remove.go @@ -0,0 +1,53 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runners + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/stores" +) + +func (s *RunnerService) RemoveRunner(ctx context.Context, runnerId string) error { + var err error + ctx, err = s.runnerStore.BeginTransaction(ctx) + if err != nil { + return s.runnerStore.RollbackTransaction(ctx, err) + } + + defer stores.RecoverAndRollback(ctx, s.runnerStore) + + runner, err := s.runnerStore.Find(ctx, runnerId) + if err != nil { + return s.runnerStore.RollbackTransaction(ctx, err) + } + + err = s.runnerStore.Delete(ctx, runner) + if err != nil { + return s.runnerStore.RollbackTransaction(ctx, err) + } + + metadata, err := s.runnerMetadataStore.Find(ctx, runnerId) + if err != nil && !stores.IsRunnerMetadataNotFound(err) { + return s.runnerStore.RollbackTransaction(ctx, err) + } + if metadata != nil { + err = s.runnerMetadataStore.Delete(ctx, metadata) + if err != nil { + return s.runnerStore.RollbackTransaction(ctx, err) + } + } + + err = s.revokeApiKey(ctx, runner.Id) + if err != nil { + return s.runnerStore.RollbackTransaction(ctx, err) + } + + err = s.unsetDefaultTarget(ctx, runner.Id) + if err != nil { + return s.runnerStore.RollbackTransaction(ctx, err) + } + + return s.runnerStore.CommitTransaction(ctx) +} diff --git a/pkg/server/runners/service.go b/pkg/server/runners/service.go new file mode 100644 index 0000000000..8c3c2eb584 --- /dev/null +++ b/pkg/server/runners/service.go @@ -0,0 +1,110 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runners + +import ( + "context" + "io" + + "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/logs" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +type RunnerServiceConfig struct { + RunnerStore stores.RunnerStore + RunnerMetadataStore stores.RunnerMetadataStore + LoggerFactory logs.ILoggerFactory + + CreateJob func(ctx context.Context, runnerId string, action models.JobAction, metadata string) error + ListJobsForRunner func(ctx context.Context, runnerId string) ([]*models.Job, error) + UpdateJobState func(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error + GenerateApiKey func(ctx context.Context, name string) (string, error) + RevokeApiKey func(ctx context.Context, name string) error + UnsetDefaultTarget func(ctx context.Context, runnerId string) error + + TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error +} + +func NewRunnerService(config RunnerServiceConfig) services.IRunnerService { + return &RunnerService{ + runnerStore: config.RunnerStore, + runnerMetadataStore: config.RunnerMetadataStore, + loggerFactory: config.LoggerFactory, + + createJob: config.CreateJob, + listJobsForRunner: config.ListJobsForRunner, + updateJobState: config.UpdateJobState, + generateApiKey: config.GenerateApiKey, + revokeApiKey: config.RevokeApiKey, + unsetDefaultTarget: config.UnsetDefaultTarget, + + trackTelemetryEvent: config.TrackTelemetryEvent, + } +} + +type RunnerService struct { + runnerStore stores.RunnerStore + runnerMetadataStore stores.RunnerMetadataStore + loggerFactory logs.ILoggerFactory + + createJob func(ctx context.Context, runnerId string, action models.JobAction, metadata string) error + listJobsForRunner func(ctx context.Context, runnerId string) ([]*models.Job, error) + updateJobState func(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error + generateApiKey func(ctx context.Context, name string) (string, error) + revokeApiKey func(ctx context.Context, name string) error + unsetDefaultTarget func(ctx context.Context, runnerId string) error + + trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error +} + +func (s *RunnerService) GetRunner(ctx context.Context, runnerId string) (*services.RunnerDTO, error) { + runner, err := s.runnerStore.Find(ctx, runnerId) + if err != nil { + return nil, stores.ErrRunnerNotFound + } + + return &services.RunnerDTO{ + Runner: *runner, + State: runner.GetState(), + }, nil +} + +func (s *RunnerService) ListRunners(ctx context.Context) ([]*services.RunnerDTO, error) { + runners, err := s.runnerStore.List(ctx) + if err != nil { + return nil, err + } + + return util.ArrayMap(runners, func(runner *models.Runner) *services.RunnerDTO { + return &services.RunnerDTO{ + Runner: *runner, + State: runner.GetState(), + } + }), nil +} + +func (s *RunnerService) SetRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error { + m, err := s.runnerMetadataStore.Find(ctx, runnerId) + if err != nil { + return stores.ErrRunnerMetadataNotFound + } + + m.Uptime = metadata.Uptime + m.RunningJobs = metadata.RunningJobs + m.Providers = metadata.Providers + m.UpdatedAt = metadata.UpdatedAt + return s.runnerMetadataStore.Save(ctx, m) +} + +func (s *RunnerService) GetRunnerLogReader(ctx context.Context, runnerId string) (io.Reader, error) { + return s.loggerFactory.CreateLogReader(runnerId) +} + +func (s *RunnerService) GetRunnerLogWriter(ctx context.Context, runnerId string) (io.WriteCloser, error) { + return s.loggerFactory.CreateLogWriter(runnerId) +} diff --git a/pkg/server/server.go b/pkg/server/server.go index f00352e55a..d341bbc596 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -4,13 +4,8 @@ package server import ( - "os" - "os/signal" - - "github.com/daytonaio/daytona/pkg/provider/manager" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/telemetry" - "github.com/hashicorp/go-plugin" log "github.com/sirupsen/logrus" ) @@ -27,9 +22,9 @@ type ServerInstanceConfig struct { TargetService services.ITargetService ApiKeyService services.IApiKeyService GitProviderService services.IGitProviderService - ProviderManager manager.IProviderManager EnvironmentVariableService services.IEnvironmentVariableService JobService services.IJobService + RunnerService services.IRunnerService TelemetryService telemetry.TelemetryService } @@ -57,9 +52,9 @@ func GetInstance(serverConfig *ServerInstanceConfig) *Server { TargetService: serverConfig.TargetService, ApiKeyService: serverConfig.ApiKeyService, GitProviderService: serverConfig.GitProviderService, - ProviderManager: serverConfig.ProviderManager, EnvironmentVariableService: serverConfig.EnvironmentVariableService, JobService: serverConfig.JobService, + RunnerService: serverConfig.RunnerService, TelemetryService: serverConfig.TelemetryService, } } @@ -80,38 +75,12 @@ type Server struct { TargetService services.ITargetService ApiKeyService services.IApiKeyService GitProviderService services.IGitProviderService - ProviderManager manager.IProviderManager EnvironmentVariableService services.IEnvironmentVariableService JobService services.IJobService + RunnerService services.IRunnerService TelemetryService telemetry.TelemetryService } func (s *Server) Initialize() error { return s.initLogs() } - -func (s *Server) Start() error { - log.Info("Starting Daytona server") - - go func() { - interruptChannel := make(chan os.Signal, 1) - signal.Notify(interruptChannel, os.Interrupt) - - for range interruptChannel { - plugin.CleanupClients() - } - }() - - // Terminate orphaned provider processes - err := s.ProviderManager.TerminateProviderProcesses(s.config.ProvidersDir) - if err != nil { - log.Errorf("Failed to terminate orphaned provider processes: %s", err) - } - - err = s.downloadDefaultProviders() - if err != nil { - return err - } - - return s.registerProviders() -} diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index f67fdf804f..eb962cf979 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -75,7 +75,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTar return s.handleCreateError(ctx, tg, err) } - err = s.createJob(ctx, tg.Id, models.JobActionCreate) + err = s.createJob(ctx, tg.Id, tg.TargetConfig.ProviderInfo.RunnerId, models.JobActionCreate) if err != nil { return s.handleCreateError(ctx, tg, err) } diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 8b2785c3a5..2755d6ffeb 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -5,15 +5,10 @@ package targets import ( "context" - "errors" - "fmt" - "time" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" - log "github.com/sirupsen/logrus" ) func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { @@ -37,40 +32,8 @@ func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilt } tg.Workspaces = updatedWorkspaces - response := services.TargetDTO{ + return &services.TargetDTO{ Target: *tg, State: state, - } - - if !params.Verbose { - return &response, nil - } - - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - resultCh := make(chan provisioner.TargetInfoResult, 1) - - go func() { - targetInfo, err := s.provisioner.GetTargetInfo(ctx, tg) - resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} - }() - - select { - case res := <-resultCh: - if res.Err != nil { - log.Error(fmt.Errorf("failed to get target info for %s: %v", tg.Name, res.Err)) - return nil, res.Err - } - - response.Info = res.Info - case <-ctx.Done(): - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting target info for %s", tg.Name)) - } else { - log.Warn(fmt.Sprintf("cancelled getting target info for %s", tg.Name)) - } - } - - return &response, nil + }, nil } diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index 88d36333f3..a864cd7a35 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -5,16 +5,10 @@ package targets import ( "context" - "errors" - "fmt" - "sync" - "time" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" - log "github.com/sirupsen/logrus" ) func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]services.TargetDTO, error) { @@ -23,10 +17,9 @@ func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFi return nil, err } - var wg sync.WaitGroup response := []services.TargetDTO{} - for i, t := range targets { + for _, t := range targets { state := t.GetState() if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { @@ -46,43 +39,7 @@ func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFi Target: *t, State: state, }) - - if !params.Verbose { - continue - } - - wg.Add(1) - go func(i int) { - defer wg.Done() - - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - resultCh := make(chan provisioner.TargetInfoResult, 1) - - go func() { - targetInfo, err := s.provisioner.GetTargetInfo(ctx, t) - resultCh <- provisioner.TargetInfoResult{Info: targetInfo, Err: err} - }() - - select { - case res := <-resultCh: - if res.Err != nil { - log.Error(fmt.Errorf("failed to get target info for %s: %v", t.Name, res.Err)) - return - } - - response[i].Info = res.Info - case <-ctx.Done(): - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting target info for %s", t.Name)) - } else { - log.Warn(fmt.Sprintf("cancelled getting target info for %s", t.Name)) - } - } - }(i) } - wg.Wait() return response, nil } diff --git a/pkg/server/targets/metadata.go b/pkg/server/targets/metadata.go index c4850b99cc..b629e6fcbe 100644 --- a/pkg/server/targets/metadata.go +++ b/pkg/server/targets/metadata.go @@ -11,9 +11,7 @@ import ( ) func (s *TargetService) SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { - m, err := s.targetMetadataStore.Find(ctx, &stores.TargetMetadataFilter{ - TargetId: &targetId, - }) + m, err := s.targetMetadataStore.Find(ctx, targetId) if err != nil { return nil, stores.ErrTargetMetadataNotFound } diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 384369f6b4..2bb0e19684 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -34,7 +34,20 @@ func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error return s.handleRemoveError(ctx, t, err) } - err = s.createJob(ctx, t.Id, models.JobActionDelete) + err = s.revokeApiKey(ctx, targetId) + if err != nil { + return s.handleRemoveError(ctx, t, err) + } + + metadata, err := s.targetMetadataStore.Find(ctx, targetId) + if err == nil { + err = s.targetMetadataStore.Delete(ctx, metadata) + if err != nil { + return s.handleRemoveError(ctx, t, err) + } + } + + err = s.createJob(ctx, t.Id, t.TargetConfig.ProviderInfo.RunnerId, models.JobActionDelete) if err != nil { return s.handleRemoveError(ctx, t, err) } @@ -65,46 +78,20 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) return s.handleRemoveError(ctx, t, err) } - err = s.createJob(ctx, t.Id, models.JobActionForceDelete) - if err != nil { - return s.handleRemoveError(ctx, t, err) - } - - err = s.targetStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, t, err) -} - -func (s *TargetService) HandleSuccessfulRemoval(ctx context.Context, targetId string) error { - var err error - ctx, err = s.targetStore.BeginTransaction(ctx) - if err != nil { - return s.handleRemoveError(ctx, nil, err) - } - - defer stores.RecoverAndRollback(ctx, s.targetStore) - err = s.revokeApiKey(ctx, targetId) if err != nil { - // Should not fail the whole operation if the API key cannot be revoked log.Error(err) } - t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) - if err != nil { - return s.handleRemoveError(ctx, t, stores.ErrTargetNotFound) - } - - metadata, err := s.targetMetadataStore.Find(ctx, &stores.TargetMetadataFilter{TargetId: &targetId}) - if err != nil { - return s.handleRemoveError(ctx, t, err) - } - - err = s.targetMetadataStore.Delete(ctx, metadata) - if err != nil { - return s.handleRemoveError(ctx, t, err) + metadata, err := s.targetMetadataStore.Find(ctx, targetId) + if err == nil { + err = s.targetMetadataStore.Delete(ctx, metadata) + if err != nil { + log.Error(err) + } } - err = s.targetStore.Delete(ctx, t) + err = s.createJob(ctx, t.Id, t.TargetConfig.ProviderInfo.RunnerId, models.JobActionForceDelete) if err != nil { return s.handleRemoveError(ctx, t, err) } diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index fc707ae2e5..34de343a0f 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -9,7 +9,6 @@ import ( "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" @@ -22,13 +21,12 @@ type TargetServiceConfig struct { FindTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) GenerateApiKey func(ctx context.Context, name string) (string, error) RevokeApiKey func(ctx context.Context, name string) error - CreateJob func(ctx context.Context, targetId string, action models.JobAction) error + CreateJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error ServerApiUrl string ServerUrl string ServerVersion string - Provisioner provisioner.IProvisioner - LoggerFactory logs.LoggerFactory + LoggerFactory logs.ILoggerFactory TelemetryService telemetry.TelemetryService } @@ -45,7 +43,6 @@ func NewTargetService(config TargetServiceConfig) services.ITargetService { serverApiUrl: config.ServerApiUrl, serverUrl: config.ServerUrl, serverVersion: config.ServerVersion, - provisioner: config.Provisioner, loggerFactory: config.LoggerFactory, telemetryService: config.TelemetryService, } @@ -58,16 +55,36 @@ type TargetService struct { findTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) generateApiKey func(ctx context.Context, name string) (string, error) revokeApiKey func(ctx context.Context, name string) error - createJob func(ctx context.Context, targetId string, action models.JobAction) error + createJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error - provisioner provisioner.IProvisioner serverApiUrl string serverUrl string serverVersion string - loggerFactory logs.LoggerFactory + loggerFactory logs.ILoggerFactory telemetryService telemetry.TelemetryService } -func (s *TargetService) GetTargetLogReader(targetId string) (io.Reader, error) { - return s.loggerFactory.CreateTargetLogReader(targetId) +func (s *TargetService) GetTargetLogReader(ctx context.Context, targetId string) (io.Reader, error) { + return s.loggerFactory.CreateLogReader(targetId) +} + +func (s *TargetService) GetTargetLogWriter(ctx context.Context, targetId string) (io.WriteCloser, error) { + return s.loggerFactory.CreateLogWriter(targetId) +} + +// TODO: revise - "remove default" is enough for now +func (s *TargetService) SaveTarget(ctx context.Context, target *models.Target) error { + return s.targetStore.Save(ctx, target) +} + +func (s *TargetService) UpdateTargetProviderMetadata(ctx context.Context, targetId, metadata string) error { + tg, err := s.targetStore.Find(ctx, &stores.TargetFilter{ + IdOrName: &targetId, + }) + if err != nil { + return err + } + + tg.ProviderMetadata = &metadata + return s.targetStore.Save(ctx, tg) } diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 4f412123ee..d7a0ac8c0e 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -48,11 +48,6 @@ var createTargetDTO = services.CreateTargetDTO{ TargetConfigName: "test", } -var targetInfo = models.TargetInfo{ - Name: createTargetDTO.Name, - ProviderMetadata: "provider-metadata-test", -} - func TestTargetService(t *testing.T) { tg.EnvVars = targets.GetTargetEnvVars(tg, targets.TargetEnvVarParams{ ApiUrl: serverApiUrl, @@ -71,10 +66,8 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) apiKeyService := mocks.NewMockApiKeyService() - mockProvisioner := mocks.NewMockProvisioner() tgLogsDir := t.TempDir() - buildLogsDir := t.TempDir() service := targets.NewTargetService(targets.TargetServiceConfig{ TargetStore: targetStore, @@ -90,14 +83,10 @@ func TestTargetService(t *testing.T) { }, ServerApiUrl: serverApiUrl, ServerUrl: serverUrl, - Provisioner: mockProvisioner, - LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: tgLogsDir}), }) t.Run("CreateTarget", func(t *testing.T) { - mockProvisioner.On("CreateTarget", tg).Return(nil) - mockProvisioner.On("StartTarget", tg).Return(nil) - apiKeyService.On("Generate", models.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) target, err := service.CreateTarget(ctx, createTargetDTO) @@ -121,45 +110,29 @@ func TestTargetService(t *testing.T) { }) t.Run("GetTarget", func(t *testing.T) { - mockProvisioner.On("GetTargetInfo", mock.Anything, tg).Return(&targetInfo, nil) - - target, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{Verbose: true}) + target, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Nil(t, err) require.NotNil(t, target) - targetDtoEquals(t, createTargetDTO, *target, targetInfo, true) + targetDtoEquals(t, createTargetDTO, *target) }) t.Run("GetTarget fails when target not found", func(t *testing.T) { - _, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{Verbose: true}) + _, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{}) require.NotNil(t, err) require.Equal(t, stores.ErrTargetNotFound, err) }) t.Run("ListTargets", func(t *testing.T) { - verbose := false - targets, err := service.ListTargets(ctx, nil, services.TargetRetrievalParams{Verbose: verbose}) + targets, err := service.ListTargets(ctx, nil, services.TargetRetrievalParams{}) require.Nil(t, err) require.Len(t, targets, 1) target := targets[0] - targetDtoEquals(t, createTargetDTO, target, targetInfo, verbose) - }) - - t.Run("ListTargets - verbose", func(t *testing.T) { - verbose := true - - targets, err := service.ListTargets(ctx, nil, services.TargetRetrievalParams{Verbose: verbose}) - - require.Nil(t, err) - require.Len(t, targets, 1) - - target := targets[0] - - targetDtoEquals(t, createTargetDTO, target, targetInfo, verbose) + targetDtoEquals(t, createTargetDTO, target) }) t.Run("StartTarget", func(t *testing.T) { @@ -177,22 +150,19 @@ func TestTargetService(t *testing.T) { }) t.Run("StopTarget", func(t *testing.T) { - mockProvisioner.On("StopTarget", tg).Return(nil) - err := service.StopTarget(ctx, createTargetDTO.Id) require.Nil(t, err) }) t.Run("RemoveTarget", func(t *testing.T) { - mockProvisioner.On("DestroyTarget", tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{Verbose: true}) + _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Equal(t, stores.ErrTargetNotFound, err) }) @@ -200,14 +170,13 @@ func TestTargetService(t *testing.T) { err := targetStore.Save(ctx, tg) require.Nil(t, err) - mockProvisioner.On("DestroyTarget", tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{Verbose: true}) + _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Equal(t, stores.ErrTargetNotFound, err) }) @@ -232,7 +201,6 @@ func TestTargetService(t *testing.T) { t.Cleanup(func() { apiKeyService.AssertExpectations(t) - mockProvisioner.AssertExpectations(t) }) } @@ -246,18 +214,11 @@ func targetEquals(t *testing.T, t1, t2 *models.Target) { require.Equal(t, t1.IsDefault, t2.IsDefault) } -func targetDtoEquals(t *testing.T, req services.CreateTargetDTO, target services.TargetDTO, targetInfo models.TargetInfo, verbose bool) { +func targetDtoEquals(t *testing.T, req services.CreateTargetDTO, target services.TargetDTO) { t.Helper() require.Equal(t, req.Id, target.Id) require.Equal(t, req.Name, target.Name) require.Equal(t, tc.ProviderInfo, target.TargetConfig.ProviderInfo) require.Equal(t, tc.Options, target.TargetConfig.Options) - - if verbose { - require.Equal(t, target.Info.Name, targetInfo.Name) - require.Equal(t, target.Info.ProviderMetadata, targetInfo.ProviderMetadata) - } else { - require.Nil(t, target.Info) - } } diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index 4d14f24bb0..29696e7219 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -23,7 +23,7 @@ func (s *TargetService) StartTarget(ctx context.Context, targetId string) error return s.handleStartError(ctx, target, services.ErrAgentlessTarget) } - err = s.createJob(ctx, target.Id, models.JobActionStart) + err = s.createJob(ctx, target.Id, target.TargetConfig.ProviderInfo.RunnerId, models.JobActionStart) return s.handleStartError(ctx, target, err) } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index b0f045cd9f..5812f4f2e9 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -23,7 +23,7 @@ func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { return s.handleStartError(ctx, target, services.ErrAgentlessTarget) } - err = s.createJob(ctx, target.Id, models.JobActionStop) + err = s.createJob(ctx, target.Id, target.TargetConfig.ProviderInfo.RunnerId, models.JobActionStop) return s.handleStopError(ctx, target, err) } diff --git a/pkg/server/types.go b/pkg/server/types.go index fe4dd06b65..9159f04fdb 100644 --- a/pkg/server/types.go +++ b/pkg/server/types.go @@ -7,6 +7,8 @@ import ( "context" "net" "net/http" + + "github.com/daytonaio/daytona/pkg/logs" ) type TailscaleServer interface { @@ -37,30 +39,21 @@ type NetworkKey struct { } // @name NetworkKey type Config struct { - ProvidersDir string `json:"providersDir" validate:"required"` - RegistryUrl string `json:"registryUrl" validate:"required"` - Id string `json:"id" validate:"required"` - ServerDownloadUrl string `json:"serverDownloadUrl" validate:"required"` - Frps *FRPSConfig `json:"frps,omitempty" validate:"optional"` - ApiPort uint32 `json:"apiPort" validate:"required"` - HeadscalePort uint32 `json:"headscalePort" validate:"required"` - BinariesPath string `json:"binariesPath" validate:"required"` - LogFile *LogFileConfig `json:"logFile" validate:"required"` - BuilderImage string `json:"builderImage" validate:"required"` - DefaultWorkspaceImage string `json:"defaultWorkspaceImage" validate:"required"` - DefaultWorkspaceUser string `json:"defaultWorkspaceUser" validate:"required"` - LocalBuilderRegistryPort uint32 `json:"localBuilderRegistryPort" validate:"required"` - LocalBuilderRegistryImage string `json:"localBuilderRegistryImage" validate:"required"` - BuilderRegistryServer string `json:"builderRegistryServer" validate:"required"` - BuildImageNamespace string `json:"buildImageNamespace" validate:"optional"` - SamplesIndexUrl string `json:"samplesIndexUrl" validate:"optional"` + RegistryUrl string `json:"registryUrl" validate:"required"` + Id string `json:"id" validate:"required"` + ServerDownloadUrl string `json:"serverDownloadUrl" validate:"required"` + Frps *FRPSConfig `json:"frps,omitempty" validate:"optional"` + ApiPort uint32 `json:"apiPort" validate:"required"` + HeadscalePort uint32 `json:"headscalePort" validate:"required"` + BinariesPath string `json:"binariesPath" validate:"required"` + LogFile *logs.LogFileConfig `json:"logFile" validate:"required"` + BuilderImage string `json:"builderImage" validate:"required"` + DefaultWorkspaceImage string `json:"defaultWorkspaceImage" validate:"required"` + DefaultWorkspaceUser string `json:"defaultWorkspaceUser" validate:"required"` + LocalBuilderRegistryPort uint32 `json:"localBuilderRegistryPort" validate:"required"` + LocalBuilderRegistryImage string `json:"localBuilderRegistryImage" validate:"required"` + BuilderRegistryServer string `json:"builderRegistryServer" validate:"required"` + BuildImageNamespace string `json:"buildImageNamespace" validate:"optional"` + LocalRunnerDisabled *bool `json:"localRunnerDisabled" validate:"optional"` + SamplesIndexUrl string `json:"samplesIndexUrl" validate:"optional"` } // @name ServerConfig - -type LogFileConfig struct { - Path string `json:"path" validate:"required"` - MaxSize int `json:"maxSize" validate:"required"` - MaxBackups int `json:"maxBackups" validate:"required"` - MaxAge int `json:"maxAge" validate:"required"` - LocalTime bool `json:"localTime" validate:"optional"` - Compress bool `json:"compress" validate:"optional"` -} // @name LogFileConfig diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 8add269a46..54cf0b0481 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -45,6 +45,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre } w.Repository.Url = util.CleanUpRepositoryUrl(w.Repository.Url) + if w.GitProviderConfigId == nil || *w.GitProviderConfigId == "" { configs, err := s.listGitProviderConfigs(ctx, w.Repository.Url) if err != nil { @@ -60,6 +61,10 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre } } + if w.GitProviderConfigId != nil && *w.GitProviderConfigId == "" { + w.GitProviderConfigId = nil + } + if w.Repository.Sha == "" { sha, err := s.getLastCommitSha(ctx, w.Repository) if err != nil { @@ -113,7 +118,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre return s.handleCreateError(ctx, w, err) } - err = s.createJob(ctx, w.Id, models.JobActionCreate) + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionCreate) if err != nil { return s.handleCreateError(ctx, w, err) } diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/get.go index 4b7766dce4..c8f6c7f7c0 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/get.go @@ -5,63 +5,26 @@ package workspaces import ( "context" - "errors" - "fmt" - "time" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" - log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { - ws, err := s.workspaceStore.Find(ctx, workspaceId) + w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceNotFound } - state := ws.GetState() + state := w.GetState() if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { return nil, services.ErrWorkspaceDeleted } - response := &services.WorkspaceDTO{ - Workspace: *ws, + return &services.WorkspaceDTO{ + Workspace: *w, State: state, - } - - if !params.Verbose { - return response, nil - } - - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - resultCh := make(chan provisioner.WorkspaceInfoResult, 1) - - go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws) - resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} - }() - - select { - case res := <-resultCh: - if res.Err != nil { - log.Error(fmt.Errorf("failed to get workspace info for %s: %v", ws.Name, res.Err)) - return nil, res.Err - } - - response.Info = res.Info - case <-ctx.Done(): - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting workspace info for %s", ws.Name)) - } else { - log.Warn(fmt.Sprintf("cancelled getting workspace info for %s", ws.Name)) - } - } - - return response, nil + }, nil } diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index 754552aed3..b7de45577e 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -5,15 +5,9 @@ package workspaces import ( "context" - "errors" - "fmt" - "sync" - "time" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" - log "github.com/sirupsen/logrus" ) func (s *WorkspaceService) ListWorkspaces(ctx context.Context, params services.WorkspaceRetrievalParams) ([]services.WorkspaceDTO, error) { @@ -22,10 +16,9 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, params services.W return nil, err } - var wg sync.WaitGroup response := []services.WorkspaceDTO{} - for i, ws := range workspaces { + for _, ws := range workspaces { state := ws.GetState() if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { @@ -36,43 +29,7 @@ func (s *WorkspaceService) ListWorkspaces(ctx context.Context, params services.W Workspace: *ws, State: state, }) - - if !params.Verbose { - continue - } - - wg.Add(1) - go func(i int) { - defer wg.Done() - - ctx, cancel := context.WithTimeout(ctx, 5*time.Second) - defer cancel() - - resultCh := make(chan provisioner.WorkspaceInfoResult, 1) - - go func() { - workspaceInfo, err := s.provisioner.GetWorkspaceInfo(ctx, ws) - resultCh <- provisioner.WorkspaceInfoResult{Info: workspaceInfo, Err: err} - }() - - select { - case res := <-resultCh: - if res.Err != nil { - log.Error(fmt.Errorf("failed to get workspace info for %s: %v", ws.Name, res.Err)) - return - } - - response[i].Info = res.Info - case <-ctx.Done(): - if errors.Is(ctx.Err(), context.DeadlineExceeded) { - log.Warn(fmt.Sprintf("timeout getting workspace info for %s", ws.Name)) - } else { - log.Warn(fmt.Sprintf("cancelled getting workspace info for %s", ws.Name)) - } - } - }(i) } - wg.Wait() return response, nil } diff --git a/pkg/server/workspaces/metadata.go b/pkg/server/workspaces/metadata.go index 5d4294c717..0ef6c1389b 100644 --- a/pkg/server/workspaces/metadata.go +++ b/pkg/server/workspaces/metadata.go @@ -11,9 +11,7 @@ import ( ) func (s *WorkspaceService) SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { - m, err := s.workspaceMetadataStore.Find(ctx, &stores.WorkspaceMetadataFilter{ - WorkspaceId: &workspaceId, - }) + m, err := s.workspaceMetadataStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceMetadataNotFound } diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index 7934d53863..f5c4f96bf1 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -5,7 +5,6 @@ package workspaces import ( "context" - "fmt" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" @@ -23,59 +22,42 @@ func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId stri defer stores.RecoverAndRollback(ctx, s.workspaceStore) - ws, err := s.workspaceStore.Find(ctx, workspaceId) + w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) + return s.handleRemoveError(ctx, w, stores.ErrWorkspaceNotFound) } - ws.Name = util.AddDeletedToName(ws.Name) + w.Name = util.AddDeletedToName(w.Name) - err = s.workspaceStore.Save(ctx, ws) + err = s.workspaceStore.Save(ctx, w) if err != nil { - return s.handleRemoveError(ctx, ws, err) + return s.handleRemoveError(ctx, w, err) } - err = s.createJob(ctx, ws.Id, models.JobActionDelete) + err = s.revokeApiKey(ctx, workspaceId) if err != nil { - return s.handleRemoveError(ctx, ws, err) + return s.handleRemoveError(ctx, w, err) } - err = s.workspaceStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, ws, err) -} - -// ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. -func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { - var err error - ctx, err = s.workspaceStore.BeginTransaction(ctx) - if err != nil { - return s.handleRemoveError(ctx, nil, err) - } - - defer stores.RecoverAndRollback(ctx, s.workspaceStore) - - ws, err := s.workspaceStore.Find(ctx, workspaceId) - if err != nil { - return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) - } - - ws.Name = util.AddDeletedToName(ws.Name) - - err = s.workspaceStore.Save(ctx, ws) - if err != nil { - return s.handleRemoveError(ctx, ws, err) + metadata, err := s.workspaceMetadataStore.Find(ctx, workspaceId) + if err == nil { + err = s.workspaceMetadataStore.Delete(ctx, metadata) + if err != nil { + return s.handleRemoveError(ctx, w, err) + } } - err = s.createJob(ctx, ws.Id, models.JobActionForceDelete) + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionDelete) if err != nil { - return s.handleRemoveError(ctx, ws, err) + return s.handleRemoveError(ctx, w, err) } err = s.workspaceStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, ws, err) + return s.handleRemoveError(ctx, w, err) } -func (s *WorkspaceService) HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error { +// ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. +func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { @@ -84,34 +66,38 @@ func (s *WorkspaceService) HandleSuccessfulRemoval(ctx context.Context, workspac defer stores.RecoverAndRollback(ctx, s.workspaceStore) - err = s.revokeApiKey(ctx, fmt.Sprintf("ws-%s", workspaceId)) + w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - // Should not fail the whole operation if the API key cannot be revoked - log.Error(err) + return s.handleRemoveError(ctx, w, stores.ErrWorkspaceNotFound) } - ws, err := s.workspaceStore.Find(ctx, workspaceId) + w.Name = util.AddDeletedToName(w.Name) + + err = s.workspaceStore.Save(ctx, w) if err != nil { - return s.handleRemoveError(ctx, ws, stores.ErrWorkspaceNotFound) + return s.handleRemoveError(ctx, w, err) } - metadata, err := s.workspaceMetadataStore.Find(ctx, &stores.WorkspaceMetadataFilter{WorkspaceId: &workspaceId}) + err = s.revokeApiKey(ctx, workspaceId) if err != nil { - return s.handleRemoveError(ctx, ws, err) + log.Error(err) } - err = s.workspaceMetadataStore.Delete(ctx, metadata) - if err != nil { - return s.handleRemoveError(ctx, ws, err) + metadata, err := s.workspaceMetadataStore.Find(ctx, workspaceId) + if err == nil { + err = s.workspaceMetadataStore.Delete(ctx, metadata) + if err != nil { + log.Error(err) + } } - err = s.workspaceStore.Delete(ctx, ws) + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionForceDelete) if err != nil { - return s.handleRemoveError(ctx, ws, err) + return s.handleRemoveError(ctx, w, err) } err = s.workspaceStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, ws, err) + return s.handleRemoveError(ctx, w, err) } func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Workspace, err error) error { diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index 82f3acd1a3..724d3fd5bb 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -10,7 +10,6 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" @@ -28,14 +27,13 @@ type WorkspaceServiceConfig struct { ListGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) - CreateJob func(ctx context.Context, workspaceId string, action models.JobAction) error + CreateJob func(ctx context.Context, workspaceId string, runnerId string, action models.JobAction) error TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error - LoggerFactory logs.LoggerFactory + LoggerFactory logs.ILoggerFactory ServerApiUrl string ServerUrl string ServerVersion string - Provisioner provisioner.IProvisioner DefaultWorkspaceImage string DefaultWorkspaceUser string } @@ -61,7 +59,6 @@ func NewWorkspaceService(config WorkspaceServiceConfig) services.IWorkspaceServi serverVersion: config.ServerVersion, defaultWorkspaceImage: config.DefaultWorkspaceImage, defaultWorkspaceUser: config.DefaultWorkspaceUser, - provisioner: config.Provisioner, loggerFactory: config.LoggerFactory, } } @@ -78,18 +75,31 @@ type WorkspaceService struct { listGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) getLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) - createJob func(ctx context.Context, workspaceId string, action models.JobAction) error + createJob func(ctx context.Context, workspaceId string, runnerId string, action models.JobAction) error trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error - provisioner provisioner.IProvisioner serverApiUrl string serverUrl string serverVersion string defaultWorkspaceImage string defaultWorkspaceUser string - loggerFactory logs.LoggerFactory + loggerFactory logs.ILoggerFactory } func (s *WorkspaceService) GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) { - return s.loggerFactory.CreateWorkspaceLogReader(workspaceId) + return s.loggerFactory.CreateLogReader(workspaceId) +} + +func (s *WorkspaceService) GetWorkspaceLogWriter(ctx context.Context, workspaceId string) (io.WriteCloser, error) { + return s.loggerFactory.CreateLogWriter(workspaceId) +} + +func (s *WorkspaceService) UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId, metadata string) error { + w, err := s.workspaceStore.Find(ctx, workspaceId) + if err != nil { + return err + } + + w.ProviderMetadata = &metadata + return s.workspaceStore.Save(ctx, w) } diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index c2fcb8b4b5..8dfda721c1 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -12,11 +12,9 @@ import ( "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" "github.com/daytonaio/daytona/internal/util" - "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/provisioner" "github.com/daytonaio/daytona/pkg/server/workspaces" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -79,14 +77,6 @@ var createWorkspaceDTO = services.CreateWorkspaceDTO{ TargetId: tg.Id, } -var workspaceInfo = models.WorkspaceInfo{ - Name: createWorkspaceDTO.Name, - Created: "1 min ago", - IsRunning: true, - ProviderMetadata: "provider-metadata-test", - TargetId: "123", -} - var ws = &models.Workspace{ Id: "123", Name: "workspace1", @@ -122,10 +112,8 @@ func TestTargetService(t *testing.T) { apiKeyService := mocks.NewMockApiKeyService() gitProviderService := mocks.NewMockGitProviderService() - mockProvisioner := mocks.NewMockProvisioner() tgLogsDir := t.TempDir() - buildLogsDir := t.TempDir() service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { @@ -164,8 +152,7 @@ func TestTargetService(t *testing.T) { ServerUrl: serverUrl, DefaultWorkspaceImage: defaultWorkspaceImage, DefaultWorkspaceUser: defaultWorkspaceUser, - Provisioner: mockProvisioner, - LoggerFactory: logs.NewLoggerFactory(&tgLogsDir, &buildLogsDir), + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: tgLogsDir}), }) t.Run("CreateWorkspace", func(t *testing.T) { @@ -191,29 +178,6 @@ func TestTargetService(t *testing.T) { ClientId: "test", }) - containerRegistries := common.ContainerRegistries{ - "test": &models.ContainerRegistry{ - Server: "test", - Username: "test", - Password: "test", - }, - } - - mockProvisioner.On("CreateWorkspace", provisioner.WorkspaceParams{ - Workspace: ws, - Target: tg, - ContainerRegistries: containerRegistries, - GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultWorkspaceImage, - }).Return(nil) - mockProvisioner.On("StartWorkspace", provisioner.WorkspaceParams{ - Workspace: ws, - Target: tg, - ContainerRegistries: containerRegistries, - GitProviderConfig: &gitProviderConfig, - BuilderImage: defaultWorkspaceImage, - }).Return(nil) - gitProviderService.On("GetConfig", "github").Return(&gitProviderConfig, nil) workspace, err := service.CreateWorkspace(ctx, createWorkspaceDTO) @@ -242,72 +206,49 @@ func TestTargetService(t *testing.T) { }) t.Run("GetWorkspace", func(t *testing.T) { - mockProvisioner.On("GetWorkspaceInfo", ws, tg).Return(&workspaceInfo, nil) - - w, err := service.GetWorkspace(ctx, ws.Id, services.WorkspaceRetrievalParams{Verbose: true}) + w, err := service.GetWorkspace(ctx, ws.Id, services.WorkspaceRetrievalParams{}) require.Nil(t, err) require.NotNil(t, w) - workspaceDtoEquals(t, createWorkspaceDTO, *w, workspaceInfo, defaultWorkspaceImage, true) + workspaceDtoEquals(t, createWorkspaceDTO, *w, defaultWorkspaceImage) }) t.Run("GetWorkspace fails when workspace not found", func(t *testing.T) { - _, err := service.GetWorkspace(ctx, "invalid-id", services.WorkspaceRetrievalParams{Verbose: true}) + _, err := service.GetWorkspace(ctx, "invalid-id", services.WorkspaceRetrievalParams{}) require.NotNil(t, err) require.Equal(t, stores.ErrWorkspaceNotFound, err) }) t.Run("ListWorkspaces", func(t *testing.T) { - verbose := false - - workspaces, err := service.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{Verbose: verbose}) - - require.Nil(t, err) - require.Len(t, workspaces, 1) - - workspaceDtoEquals(t, createWorkspaceDTO, workspaces[0], workspaceInfo, defaultWorkspaceImage, verbose) - }) - - t.Run("ListWorkspaces - verbose", func(t *testing.T) { - t.Skip("Need to figure out how to test the ListWorkspaces goroutine") - - verbose := true - mockProvisioner.On("GetWorkspaceInfo", ws, tg).Return(&workspaceInfo, nil) - - workspaces, err := service.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{Verbose: verbose}) + workspaces, err := service.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{}) require.Nil(t, err) require.Len(t, workspaces, 1) - workspaceDtoEquals(t, createWorkspaceDTO, workspaces[0], workspaceInfo, defaultWorkspaceImage, verbose) + workspaceDtoEquals(t, createWorkspaceDTO, workspaces[0], defaultWorkspaceImage) }) t.Run("StartWorkspace", func(t *testing.T) { - mockProvisioner.On("StartWorkspace", mock.Anything, tg).Return(nil) - err := service.StartWorkspace(ctx, createWorkspaceDTO.Id) require.Nil(t, err) }) t.Run("StopWorkspace", func(t *testing.T) { - mockProvisioner.On("StopWorkspace", mock.Anything, tg).Return(nil) - err := service.StopWorkspace(ctx, createWorkspaceDTO.Id) require.Nil(t, err) }) t.Run("RemoveWorkspace", func(t *testing.T) { - mockProvisioner.On("DestroyWorkspace", mock.Anything, tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err := service.RemoveWorkspace(ctx, createWorkspaceDTO.Id) require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{Verbose: true}) + _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) require.Equal(t, stores.ErrWorkspaceNotFound, err) }) @@ -315,14 +256,13 @@ func TestTargetService(t *testing.T) { err := workspaceStore.Save(ctx, ws) require.Nil(t, err) - mockProvisioner.On("DestroyWorkspace", mock.Anything, tg).Return(nil) apiKeyService.On("Revoke", mock.Anything).Return(nil) err = service.ForceRemoveWorkspace(ctx, createWorkspaceDTO.Id) require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{Verbose: true}) + _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) require.Equal(t, stores.ErrWorkspaceNotFound, err) }) @@ -344,7 +284,6 @@ func TestTargetService(t *testing.T) { t.Cleanup(func() { apiKeyService.AssertExpectations(t) - mockProvisioner.AssertExpectations(t) }) } @@ -362,30 +301,16 @@ func workspaceEquals(t *testing.T, ws1, ws2 *services.WorkspaceDTO) { require.Equal(t, ws1.Repository.Name, ws2.Repository.Name) } -func workspaceDtoEquals(t *testing.T, req services.CreateWorkspaceDTO, workspace services.WorkspaceDTO, workspaceInfo models.WorkspaceInfo, workspaceImage string, verbose bool) { +func workspaceDtoEquals(t *testing.T, req services.CreateWorkspaceDTO, workspace services.WorkspaceDTO, workspaceImage string) { t.Helper() require.Equal(t, req.Id, workspace.Id) require.Equal(t, req.Name, workspace.Name) - if verbose { - require.Equal(t, workspace.Info.Name, workspaceInfo.Name) - require.Equal(t, workspace.Info.ProviderMetadata, workspaceInfo.ProviderMetadata) - } else { - require.Nil(t, workspace.Info) - } - require.Equal(t, req.Name, workspace.Name) require.Equal(t, req.Source.Repository.Id, workspace.Repository.Id) require.Equal(t, req.Source.Repository.Url, workspace.Repository.Url) require.Equal(t, req.Source.Repository.Name, workspace.Repository.Name) require.Equal(t, workspace.ApiKey, workspace.Name) require.Equal(t, workspace.Image, workspaceImage) - - if verbose { - require.Equal(t, workspace.Info.Name, workspaceInfo.Name) - require.Equal(t, workspace.Info.Created, workspaceInfo.Created) - require.Equal(t, workspace.Info.IsRunning, workspaceInfo.IsRunning) - require.Equal(t, workspace.Info.ProviderMetadata, workspaceInfo.ProviderMetadata) - } } diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index e0ba40f17e..adc56bbb99 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -13,17 +13,17 @@ import ( ) func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { - ws, err := s.workspaceStore.Find(ctx, workspaceId) + w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - return s.handleStartError(ctx, ws, stores.ErrWorkspaceNotFound) + return s.handleStartError(ctx, w, stores.ErrWorkspaceNotFound) } - err = s.createJob(ctx, ws.Id, models.JobActionStart) + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionStart) if err != nil { - return s.handleStartError(ctx, ws, err) + return s.handleStartError(ctx, w, err) } - return s.handleStartError(ctx, ws, err) + return s.handleStartError(ctx, w, err) } func (s *WorkspaceService) handleStartError(ctx context.Context, w *models.Workspace, err error) error { diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 0af8fb1fd0..5e6fbc59c8 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -13,17 +13,17 @@ import ( ) func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { - ws, err := s.workspaceStore.Find(ctx, workspaceId) + w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - return s.handleStopError(ctx, ws, stores.ErrWorkspaceNotFound) + return s.handleStopError(ctx, w, stores.ErrWorkspaceNotFound) } - err = s.createJob(ctx, ws.Id, models.JobActionStop) + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionStop) if err != nil { - return s.handleStopError(ctx, ws, err) + return s.handleStopError(ctx, w, err) } - return s.handleStopError(ctx, ws, err) + return s.handleStopError(ctx, w, err) } func (s *WorkspaceService) handleStopError(ctx context.Context, w *models.Workspace, err error) error { diff --git a/pkg/server/workspacetemplates/prebuild.go b/pkg/server/workspacetemplates/prebuild.go index 89e221aa9e..2b569e3e69 100644 --- a/pkg/server/workspacetemplates/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" - "github.com/daytonaio/daytona/pkg/runners" + "github.com/daytonaio/daytona/pkg/runner" "github.com/daytonaio/daytona/pkg/scheduler" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" @@ -329,7 +329,7 @@ func (s *WorkspaceTemplateService) EnforceRetentionPolicy(ctx context.Context) e func (s *WorkspaceTemplateService) StartRetentionPoller(ctx context.Context) error { scheduler := scheduler.NewCronScheduler() - err := scheduler.AddFunc(runners.DEFAULT_JOB_POLL_INTERVAL, func() { + err := scheduler.AddFunc(runner.DEFAULT_JOB_POLL_INTERVAL, func() { err := s.EnforceRetentionPolicy(ctx) if err != nil { log.Error(err) diff --git a/pkg/services/api_key.go b/pkg/services/api_key.go index 263645d699..efda69dabd 100644 --- a/pkg/services/api_key.go +++ b/pkg/services/api_key.go @@ -11,8 +11,7 @@ import ( type IApiKeyService interface { Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) - IsWorkspaceApiKey(ctx context.Context, apiKey string) bool - IsTargetApiKey(ctx context.Context, apiKey string) bool + GetApiKeyType(ctx context.Context, apiKey string) (models.ApiKeyType, error) IsValidApiKey(ctx context.Context, apiKey string) bool ListClientKeys(ctx context.Context) ([]*models.ApiKey, error) Revoke(ctx context.Context, name string) error diff --git a/pkg/services/build.go b/pkg/services/build.go index 3be5bebf6e..a0090d855f 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -20,7 +20,9 @@ type IBuildService interface { Delete(ctx context.Context, filter *BuildFilter, force bool) []error HandleSuccessfulRemoval(ctx context.Context, id string) error AwaitEmptyList(ctx context.Context, waitTime time.Duration) error + GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) + GetBuildLogWriter(ctx context.Context, buildId string) (io.WriteCloser, error) } type BuildDTO struct { diff --git a/pkg/services/job.go b/pkg/services/job.go index 2658c85f44..fe68d4709f 100644 --- a/pkg/services/job.go +++ b/pkg/services/job.go @@ -13,7 +13,7 @@ import ( type IJobService interface { Create(ctx context.Context, job *models.Job) error - SetState(ctx context.Context, jobId string, state models.JobState, error *string) error + SetState(ctx context.Context, jobId string, updateJobStateDto UpdateJobStateDTO) error Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) Delete(ctx context.Context, job *models.Job) error diff --git a/pkg/services/runner.go b/pkg/services/runner.go new file mode 100644 index 0000000000..d08c4ee472 --- /dev/null +++ b/pkg/services/runner.go @@ -0,0 +1,62 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package services + +import ( + "context" + "errors" + "io" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/os" +) + +type IRunnerService interface { + RegisterRunner(ctx context.Context, req RegisterRunnerDTO) (*RunnerDTO, error) + GetRunner(ctx context.Context, runnerId string) (*RunnerDTO, error) + ListRunners(ctx context.Context) ([]*RunnerDTO, error) + ListRunnerJobs(ctx context.Context, runnerId string) ([]*models.Job, error) + UpdateJobState(ctx context.Context, jobId string, req UpdateJobStateDTO) error + SetRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error + RemoveRunner(ctx context.Context, runnerId string) error + + ListProviders(ctx context.Context, runnerId *string) ([]models.ProviderInfo, error) + InstallProvider(ctx context.Context, runnerId string, providerMetadata InstallProviderDTO) error + UninstallProvider(ctx context.Context, runnerId string, providerName string) error + UpdateProvider(ctx context.Context, runnerId string, providerName string, downloadUrls DownloadUrls) error + + GetRunnerLogReader(ctx context.Context, runnerId string) (io.Reader, error) + GetRunnerLogWriter(ctx context.Context, runnerId string) (io.WriteCloser, error) +} + +type RunnerDTO struct { + models.Runner + State models.ResourceState `json:"state" validate:"required"` +} // @name RunnerDTO + +type RegisterRunnerDTO struct { + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` +} // @name RegisterRunnerDTO + +type RegisterRunnerResultDTO struct { + models.Runner + ApiKey string `json:"apiKey" validate:"required"` +} // @name RegisterRunnerResultDTO + +type UpdateJobStateDTO struct { + State models.JobState `json:"state" validate:"required"` + ErrorMessage *string `json:"errorMessage,omitempty" validate:"optional"` +} // @name UpdateJobState + +type InstallProviderDTO struct { + Name string `json:"name" validate:"required"` + DownloadUrls DownloadUrls `json:"downloadUrls" validate:"required"` +} // @name InstallProviderDTO + +type DownloadUrls map[os.OperatingSystem]string // @name DownloadUrls + +var ( + ErrRunnerAlreadyExists = errors.New("runner already exists") +) diff --git a/pkg/services/target.go b/pkg/services/target.go index 27130706d0..e25c43010e 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -15,23 +15,24 @@ import ( type ITargetService interface { CreateTarget(ctx context.Context, req CreateTargetDTO) (*models.Target, error) GetTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*TargetDTO, error) - GetTargetLogReader(targetId string) (io.Reader, error) + SaveTarget(ctx context.Context, target *models.Target) error ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]TargetDTO, error) StartTarget(ctx context.Context, targetId string) error StopTarget(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error + UpdateTargetProviderMetadata(ctx context.Context, targetId, metadata string) error RemoveTarget(ctx context.Context, targetId string) error ForceRemoveTarget(ctx context.Context, targetId string) error HandleSuccessfulCreation(ctx context.Context, targetId string) error - HandleSuccessfulRemoval(ctx context.Context, targetId string) error + GetTargetLogReader(ctx context.Context, targetId string) (io.Reader, error) + GetTargetLogWriter(ctx context.Context, targetId string) (io.WriteCloser, error) SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) } type TargetDTO struct { models.Target State models.ResourceState `json:"state" validate:"required"` - Info *models.TargetInfo `json:"info" validate:"optional"` } // @name TargetDTO type CreateTargetDTO struct { @@ -40,8 +41,11 @@ type CreateTargetDTO struct { TargetConfigName string `json:"targetConfigName" validate:"required"` } // @name CreateTargetDTO +type UpdateTargetProviderMetadataDTO struct { + Metadata string `json:"metadata" validate:"required"` +} // @name UpdateTargetProviderMetadataDTO + type TargetRetrievalParams struct { - Verbose bool ShowDeleted bool } diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 90d68d52cc..85963c8f4f 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -20,23 +20,18 @@ type IWorkspaceService interface { StopWorkspace(ctx context.Context, workspaceId string) error RemoveWorkspace(ctx context.Context, workspaceId string) error ForceRemoveWorkspace(ctx context.Context, workspaceId string) error - HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error + UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId, metadata string) error GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) + GetWorkspaceLogWriter(ctx context.Context, workspaceId string) (io.WriteCloser, error) SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) } type WorkspaceDTO struct { models.Workspace - State models.ResourceState `json:"state" validate:"required"` - Info *models.WorkspaceInfo `json:"info" validate:"optional"` + State models.ResourceState `json:"state" validate:"required"` } // @name WorkspaceDTO -type WorkspaceRetrievalParams struct { - Verbose bool - ShowDeleted bool -} - type CreateWorkspaceDTO struct { Id string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` @@ -46,7 +41,7 @@ type CreateWorkspaceDTO struct { Source CreateWorkspaceSourceDTO `json:"source" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` TargetId string `json:"targetId" validate:"required"` - GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` + GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` } // @name CreateWorkspaceDTO func (c *CreateWorkspaceDTO) ToWorkspace() *models.Workspace { @@ -75,6 +70,10 @@ type CreateWorkspaceSourceDTO struct { Repository *gitprovider.GitRepository `json:"repository" validate:"required"` } // @name CreateWorkspaceSourceDTO +type WorkspaceRetrievalParams struct { + ShowDeleted bool +} + var ( ErrWorkspaceAlreadyExists = errors.New("workspace already exists") ErrWorkspaceDeleted = errors.New("workspace is deleted") diff --git a/pkg/stores/job_store.go b/pkg/stores/job_store.go index 7da198a1fb..ce3994ceec 100644 --- a/pkg/stores/job_store.go +++ b/pkg/stores/job_store.go @@ -19,11 +19,12 @@ type JobStore interface { } type JobFilter struct { - Id *string - ResourceId *string - ResourceType *models.ResourceType - States *[]models.JobState - Actions *[]models.JobAction + Id *string + ResourceId *string + RunnerIdOrIsNil *string + ResourceType *models.ResourceType + States *[]models.JobState + Actions *[]models.JobAction } func (f *JobFilter) StatesToInterface() []interface{} { diff --git a/pkg/stores/runner.go b/pkg/stores/runner.go new file mode 100644 index 0000000000..bdcd3f7b07 --- /dev/null +++ b/pkg/stores/runner.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type RunnerStore interface { + IStore + List(ctx context.Context) ([]*models.Runner, error) + Find(ctx context.Context, idOrName string) (*models.Runner, error) + Save(ctx context.Context, runner *models.Runner) error + Delete(ctx context.Context, runner *models.Runner) error +} + +var ( + ErrRunnerNotFound = errors.New("runner not found") +) + +func IsRunnerNotFound(err error) bool { + return err.Error() == ErrRunnerNotFound.Error() +} diff --git a/pkg/stores/runner_metadata.go b/pkg/stores/runner_metadata.go new file mode 100644 index 0000000000..d2ab2943d0 --- /dev/null +++ b/pkg/stores/runner_metadata.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package stores + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/models" +) + +type RunnerMetadataStore interface { + IStore + List(ctx context.Context) ([]*models.RunnerMetadata, error) + Find(ctx context.Context, runnerId string) (*models.RunnerMetadata, error) + Save(ctx context.Context, metadata *models.RunnerMetadata) error + Delete(ctx context.Context, metadata *models.RunnerMetadata) error +} + +var ( + ErrRunnerMetadataNotFound = errors.New("runner metadata not found") +) + +func IsRunnerMetadataNotFound(err error) bool { + return err.Error() == ErrRunnerMetadataNotFound.Error() +} diff --git a/pkg/stores/target_metadata.go b/pkg/stores/target_metadata.go index cc795695ed..52196d3ea5 100644 --- a/pkg/stores/target_metadata.go +++ b/pkg/stores/target_metadata.go @@ -10,14 +10,9 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -type TargetMetadataFilter struct { - Id *string - TargetId *string -} - type TargetMetadataStore interface { IStore - Find(ctx context.Context, filter *TargetMetadataFilter) (*models.TargetMetadata, error) + Find(ctx context.Context, targetId string) (*models.TargetMetadata, error) Save(ctx context.Context, metadata *models.TargetMetadata) error Delete(ctx context.Context, metadata *models.TargetMetadata) error } diff --git a/pkg/stores/workspace_metadata.go b/pkg/stores/workspace_metadata.go index cdd69c93b8..a5f4474309 100644 --- a/pkg/stores/workspace_metadata.go +++ b/pkg/stores/workspace_metadata.go @@ -10,14 +10,9 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -type WorkspaceMetadataFilter struct { - Id *string - WorkspaceId *string -} - type WorkspaceMetadataStore interface { IStore - Find(ctx context.Context, filter *WorkspaceMetadataFilter) (*models.WorkspaceMetadata, error) + Find(ctx context.Context, workspaceId string) (*models.WorkspaceMetadata, error) Save(ctx context.Context, metadata *models.WorkspaceMetadata) error Delete(ctx context.Context, metadata *models.WorkspaceMetadata) error } diff --git a/pkg/telemetry/constants.go b/pkg/telemetry/constants.go index 3c4ff1287f..07114b28ec 100644 --- a/pkg/telemetry/constants.go +++ b/pkg/telemetry/constants.go @@ -23,4 +23,5 @@ var ( CLI_SOURCE TelemetrySource = "cli" CLI_WORKSPACE_SOURCE TelemetrySource = "cli-workspace" AGENT_SOURCE TelemetrySource = "agent" + RUNNER_SOURCE TelemetrySource = "runner" ) diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index 171cc9cb5a..fe96781298 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -16,6 +16,7 @@ type TelemetryService interface { io.Closer TrackCliEvent(event CliEvent, clientId string, properties map[string]interface{}) error TrackServerEvent(event ServerEvent, clientId string, properties map[string]interface{}) error + TrackRunnerEvent(event BuildRunnerEvent, clientId string, properties map[string]interface{}) error TrackBuildRunnerEvent(event BuildRunnerEvent, clientId string, properties map[string]interface{}) error SetCommonProps(properties map[string]interface{}) } diff --git a/pkg/views/logs/display.go b/pkg/views/logs/display.go index a6c713e765..894d0fea27 100644 --- a/pkg/views/logs/display.go +++ b/pkg/views/logs/display.go @@ -5,6 +5,7 @@ package logs import ( "fmt" + "io" "slices" "strings" @@ -15,15 +16,24 @@ import ( const FIRST_WORKSPACE_INDEX = 0 const STATIC_INDEX = -1 -const TARGET_PREFIX = "TARGET" -const PROVIDER_PREFIX = "PROVIDER" -var longestPrefixLength = len(TARGET_PREFIX) +var minimumLongestPrefixLength = 4 const maxPrefixLength = 20 const prefixDelimiter = " | " const prefixPadding = " " +func DisplayLogsFromReader(reader io.Reader) { + for { + buf := make([]byte, 1024) + n, err := reader.Read(buf) + if err != nil { + break + } + fmt.Print(string(buf[:n])) + } +} + func DisplayLogs(logEntriesChan <-chan logs.LogEntry, index int) { for logEntry := range logEntriesChan { DisplayLogEntry(logEntry, index) @@ -34,22 +44,10 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { line := logEntry.Msg prefixColor := getPrefixColor(index, logEntry.Source) - var prefixText string - - if logEntry.WorkspaceName != nil { - prefixText = *logEntry.WorkspaceName - } else if logEntry.BuildId != nil { - prefixText = *logEntry.BuildId - } else if logEntry.TargetName != nil { - prefixText = *logEntry.TargetName - } + prefixText := logEntry.Label - if index == STATIC_INDEX && prefixText == "" { - if logEntry.Source == string(logs.LogSourceProvider) { - prefixText = PROVIDER_PREFIX - } else { - prefixText = TARGET_PREFIX - } + if prefixText == "" { + prefixText = strings.ToUpper(logEntry.Source) } prefix := lipgloss.NewStyle().Foreground(prefixColor).Bold(true).Render(formatPrefixText(prefixText)) @@ -60,7 +58,7 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { } // Ensure the cursor moving never overwrites the prefix - cursorOffset := longestPrefixLength + len(prefixDelimiter) + 2*len(prefixPadding) + cursorOffset := minimumLongestPrefixLength + len(prefixDelimiter) + 2*len(prefixPadding) line = strings.ReplaceAll(line, "\r", fmt.Sprintf("\u001b[%dG", cursorOffset)) line = strings.ReplaceAll(line, "\u001b[0G", fmt.Sprintf("\u001b[%dG", cursorOffset)) @@ -86,16 +84,16 @@ func DisplayLogEntry(logEntry logs.LogEntry, index int) { } func SetupLongestPrefixLength(workspaceNames []string) { - longestPrefixLength = len(slices.MaxFunc(workspaceNames, func(a, b string) int { + minimumLongestPrefixLength = len(slices.MaxFunc(workspaceNames, func(a, b string) int { return len(a) - len(b) })) } func formatPrefixText(input string) string { - prefixLength := longestPrefixLength + prefixLength := minimumLongestPrefixLength if prefixLength > maxPrefixLength { prefixLength = maxPrefixLength - longestPrefixLength = maxPrefixLength + minimumLongestPrefixLength = maxPrefixLength } // Trim input if longer than maxPrefixLength diff --git a/pkg/views/provider/list.go b/pkg/views/provider/list.go index 25de7e09d6..1e6d6d1fc9 100644 --- a/pkg/views/provider/list.go +++ b/pkg/views/provider/list.go @@ -13,12 +13,13 @@ import ( ) type rowData struct { - Label string - Name string - Version string + Label string + RunnerName string + Name string + Version string } -func List(providerList []apiclient.Provider) { +func List(providerList []apiclient.ProviderInfo) { if len(providerList) == 0 { views_util.NotifyEmptyProviderList(true) return @@ -31,7 +32,7 @@ func List(providerList []apiclient.Provider) { } table := util.GetTableView(data, []string{ - "Provider", "Name", "Version", + "Provider", "Runner", "Name", "Version", }, nil, func() { renderUnstyledList(providerList) }) @@ -39,7 +40,7 @@ func List(providerList []apiclient.Provider) { fmt.Println(table) } -func getRowFromData(provider *apiclient.Provider) []string { +func getRowFromData(provider *apiclient.ProviderInfo) []string { var data rowData if provider.Label != nil { @@ -47,23 +48,26 @@ func getRowFromData(provider *apiclient.Provider) []string { } else { data.Label = provider.Name } + data.RunnerName = provider.RunnerName data.Name = provider.Name data.Version = provider.Version return []string{ views.NameStyle.Render(data.Label), + views.DefaultRowDataStyle.Render(data.RunnerName), views.DefaultRowDataStyle.Render(data.Name), views.DefaultRowDataStyle.Render(data.Version), } } -func renderUnstyledList(providerList []apiclient.Provider) { +func renderUnstyledList(providerList []apiclient.ProviderInfo) { output := "\n" for _, provider := range providerList { if provider.Label != nil { output += fmt.Sprintf("%s %s", views.GetPropertyKey("Provider: "), *provider.Label) + "\n\n" } + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Runner: "), provider.RunnerName) + "\n\n" output += fmt.Sprintf("%s %s", views.GetPropertyKey("Name: "), provider.Name) + "\n\n" output += fmt.Sprintf("%s %s", views.GetPropertyKey("Version: "), provider.Version) + "\n" diff --git a/pkg/views/provider/select.go b/pkg/views/provider/select.go index c1d2cb054f..809d14e30b 100644 --- a/pkg/views/provider/select.go +++ b/pkg/views/provider/select.go @@ -14,10 +14,13 @@ import ( ) type ProviderView struct { - Name string - Label *string - Version string - Installed *bool + Name string + Label *string + Version string + Installed *bool + RunnerName string + RunnerId string + TargetConfigManifest map[string]apiclient.TargetConfigProperty } var NewProviderId = "+ New Provider" @@ -58,15 +61,18 @@ func GetProviderFromPrompt(providers []ProviderView, title string, withNewProvid return nil, common.ErrCtrlCAbort } -func ProviderListToView(providers []apiclient.Provider) []ProviderView { +func ProviderListToView(providers []apiclient.ProviderInfo) []ProviderView { var providerViews []ProviderView for _, p := range providers { providerViews = append(providerViews, ProviderView{ - Name: p.Name, - Label: p.Label, - Version: p.Version, - Installed: nil, + Name: p.Name, + Label: p.Label, + Version: p.Version, + Installed: nil, + RunnerId: p.RunnerId, + RunnerName: p.RunnerName, + TargetConfigManifest: p.TargetConfigManifest, }) } diff --git a/pkg/views/provider/view.go b/pkg/views/provider/view.go index ab7342ce82..2e0f7211dc 100644 --- a/pkg/views/provider/view.go +++ b/pkg/views/provider/view.go @@ -4,6 +4,7 @@ package provider import ( + "fmt" "os" "github.com/charmbracelet/bubbles/list" @@ -17,12 +18,18 @@ type item struct { } func (i item) Title() string { + title := i.provider.Name if i.provider.Label != nil { - return *i.provider.Label - } else { - return i.provider.Name + title = *i.provider.Label } + + if i.provider.RunnerName != "" { + title = fmt.Sprintf("%s (Runner %s)", title, i.provider.RunnerName) + } + + return title } + func (i item) Description() string { desc := i.provider.Version if i.provider.Installed != nil { diff --git a/pkg/views/runner/config.go b/pkg/views/runner/config.go new file mode 100644 index 0000000000..c509b6222e --- /dev/null +++ b/pkg/views/runner/config.go @@ -0,0 +1,48 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "fmt" + + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/views" +) + +func RenderConfig(config *runner.Config, showKey bool) { + output := views.GetStyledMainTitle("Daytona Runner Config") + "\n\n" + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Runner ID: "), config.Id) + "\n\n" + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Runner Name: "), config.Name) + "\n\n" + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("API URL: "), config.ServerApiUrl) + "\n\n" + + if showKey { + output += fmt.Sprintf("%s %s", views.GetPropertyKey("API Key: "), config.ServerApiKey) + "\n\n" + } + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Providers Dir: "), config.ProvidersDir) + "\n\n" + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Log File Path: "), config.LogFile.Path) + "\n\n" + + output += fmt.Sprintf("%s %d", views.GetPropertyKey("Log File Max Size: "), config.LogFile.MaxSize) + "\n\n" + + output += fmt.Sprintf("%s %d", views.GetPropertyKey("Log File Max Backups: "), config.LogFile.MaxBackups) + "\n\n" + + output += fmt.Sprintf("%s %d", views.GetPropertyKey("Log File Max Age: "), config.LogFile.MaxAge) + "\n\n" + + output += fmt.Sprintf("%s %t", views.GetPropertyKey("Log File Local Time: "), config.LogFile.LocalTime) + "\n\n" + + output += fmt.Sprintf("%s %t", views.GetPropertyKey("Log File Compress: "), config.LogFile.Compress) + "\n\n" + + output += views.SeparatorString + "\n\n" + + output += fmt.Sprintf("To edit these values run: %s", lipgloss.NewStyle().Foreground(views.Green).Render("daytona runner configure")) + "\n\n" + + output += views.SeparatorString + + views.RenderContainerLayout(views.GetInfoMessage(output)) +} diff --git a/pkg/views/runner/configure.go b/pkg/views/runner/configure.go new file mode 100644 index 0000000000..1a4edb505a --- /dev/null +++ b/pkg/views/runner/configure.go @@ -0,0 +1,200 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "errors" + "os" + "path/filepath" + "strconv" + + "github.com/charmbracelet/bubbles/help" + "github.com/charmbracelet/bubbles/key" + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/views" +) + +type Model struct { + form *huh.Form + quitting bool + config *runner.Config + keymap keymap + help help.Model +} + +type keymap struct { + submit key.Binding +} + +func NewModel(config *runner.Config) Model { + m := Model{ + config: config, + help: help.New(), + keymap: keymap{ + submit: key.NewBinding(key.WithKeys("ctrl+s"), key.WithHelp("ctrl+s", "submit")), + }, + } + + m.form = m.createForm() + return m +} +func (m *Model) createForm() *huh.Form { + logFileMaxSize := strconv.Itoa(int(m.config.LogFile.MaxSize)) + logFileMaxBackups := strconv.Itoa(int(m.config.LogFile.MaxBackups)) + logFileMaxAge := strconv.Itoa(int(m.config.LogFile.MaxAge)) + + return huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("ID"). + Description("Unique ID generated by the Daytona Server"). + Value(&m.config.Id), + huh.NewInput(). + Title("Name"). + Description("Unique name set on the Daytona Server"). + Value(&m.config.Name), + huh.NewInput(). + Title("Server API URL"). + Value(&m.config.ServerApiUrl), + huh.NewInput(). + Title("Server API Key"). + EchoMode(huh.EchoModePassword). + Value(&m.config.ServerApiKey), + huh.NewInput(). + Title("Providers Directory"). + Description("Directory will be created if it does not exist"). + Value(&m.config.ProvidersDir), + ), + huh.NewGroup( + huh.NewInput(). + Title("Log File Path"). + Description("File will be created if it does not exist"). + Value(&m.config.LogFile.Path). + Validate(func(s string) error { + _, err := os.Stat(s) + if os.IsNotExist(err) { + err = os.MkdirAll(filepath.Dir(s), 0755) + if err != nil { + return err + } + _, err = os.Create(s) + } + return err + }), + huh.NewInput(). + Title("Log File Max Size"). + Description("In megabytes"). + Value(&logFileMaxSize). + Validate(createIntValidator(&logFileMaxSize, &m.config.LogFile.MaxSize)), + huh.NewInput(). + Title("Log File Max Backups"). + Value(&logFileMaxBackups). + Validate(createIntValidator(&logFileMaxBackups, &m.config.LogFile.MaxBackups)), + huh.NewInput(). + Title("Log File Max Age"). + Description("In days"). + Value(&logFileMaxAge). + Validate(createIntValidator(&logFileMaxAge, &m.config.LogFile.MaxAge)), + huh.NewConfirm(). + Title("Log File Local Time"). + Description("Used for timestamping files. Default is UTC time."). + Value(&m.config.LogFile.LocalTime), + huh.NewConfirm(). + Title("Log File Compress"). + Value(&m.config.LogFile.Compress), + ), + ).WithTheme(views.GetCustomTheme()).WithHeight(20) +} + +func (m Model) Init() tea.Cmd { + return m.form.Init() +} + +func (m Model) ValidateField() { + // Validate the current field before submitting the form. + m.form.NextField() + m.form.PrevField() +} + +func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.String() { + case "ctrl+s": + m.ValidateField() + if len(m.form.Errors()) > 0 { + return m, nil + } + m.quitting = true + return m, tea.Quit + case "ctrl+c": + m.config = nil + return m, tea.Quit + } + } + + var cmds []tea.Cmd + form, cmd := m.form.Update(msg) + if f, ok := form.(*huh.Form); ok { + m.form = f + cmds = append(cmds, cmd) + } + + if m.form.State == huh.StateCompleted { + m.quitting = true + return m, tea.Quit + } + + return m, tea.Batch(cmds...) +} + +func (m Model) View() string { + if m.quitting { + return "" + } + helpView := "" + if len(m.form.Errors()) == 0 { + helpView = views.DefaultRowDataStyle.Render(" • " + m.help.ShortHelpView([]key.Binding{m.keymap.submit})) + } + + // TODO: once huh is updated to properly focus fields, add alt screen titles + // return views.GetAltScreenTitle("SERVER CONFIGURATION") + m.form.View() + helpView + return m.form.View() + helpView +} + +func ConfigurationForm(config *runner.Config) (*runner.Config, error) { + m := NewModel(config) + + p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() + + if err != nil { + return nil, err + } + + if m, ok := p.(Model); ok && m.config != nil { + return m.config, nil + } + + return nil, errors.New("no changes were made") +} + +func createIntValidator(viewValue *string, value *int) func(string) error { + return func(string) error { + validateInt, err := strconv.Atoi(*viewValue) + if err != nil { + return errors.New("failed to parse int") + } + + if validateInt <= 0 { + return errors.New("int out of range") + } + + *value = int(validateInt) + + return nil + } +} diff --git a/pkg/views/server/config.go b/pkg/views/server/config.go index f86c7b7623..51b23ee4bc 100644 --- a/pkg/views/server/config.go +++ b/pkg/views/server/config.go @@ -61,7 +61,9 @@ func RenderConfig(config *server.Config) { output += fmt.Sprintf("%s %s", views.GetPropertyKey("Build Image Namespace: "), config.BuildImageNamespace) + "\n\n" - output += fmt.Sprintf("%s %s", views.GetPropertyKey("Providers Dir: "), config.ProvidersDir) + "\n\n" + if config.LocalRunnerDisabled != nil && *config.LocalRunnerDisabled { + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Local Runner Disabled: "), "Yes") + "\n\n" + } output += fmt.Sprintf("%s %s", views.GetPropertyKey("Registry URL: "), config.RegistryUrl) + "\n\n" diff --git a/pkg/views/server/configure.go b/pkg/views/server/configure.go index d522f52803..58dbc5b2b8 100644 --- a/pkg/views/server/configure.go +++ b/pkg/views/server/configure.go @@ -52,10 +52,6 @@ func (m *Model) createForm() *huh.Form { return huh.NewForm( huh.NewGroup( - huh.NewInput(). - Title("Providers Directory"). - Description("Directory will be created if it does not exist"). - Value(&m.config.ProvidersDir), huh.NewInput(). Title("Registry URL"). Value(&m.config.RegistryUrl), @@ -97,6 +93,10 @@ func (m *Model) createForm() *huh.Form { huh.NewInput(). Title("Local Builder Registry Image"). Value(&m.config.LocalBuilderRegistryImage), + huh.NewConfirm(). + Title("Local Runner Disabled"). + Description("Disables the local runner"). + Value(m.config.LocalRunnerDisabled), ).WithHideFunc(func() bool { return m.config.BuilderRegistryServer != "local" }), diff --git a/pkg/views/server/runner/info/view.go b/pkg/views/server/runner/info/view.go new file mode 100644 index 0000000000..58d83e6a85 --- /dev/null +++ b/pkg/views/server/runner/info/view.go @@ -0,0 +1,70 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package info + +import ( + "fmt" + "os" + + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +const propertyNameWidth = 20 + +var propertyNameStyle = lipgloss.NewStyle(). + Foreground(views.LightGray) + +var propertyValueStyle = lipgloss.NewStyle(). + Foreground(views.Light). + Bold(true) + +func Render(runner *apiclient.RunnerDTO, forceUnstyled bool) { + var output string + output += "\n\n" + + output += views.GetStyledMainTitle("Runner Info") + "\n\n" + + output += getInfoLine("Name", runner.Name) + "\n" + + output += getInfoLine("ID", runner.Id) + "\n" + + output += getInfoLine("State", views.GetStateLabel(runner.State.Name)) + "\n" + + if runner.State.Error != nil { + output += getInfoLine("Error", *runner.State.Error) + "\n" + } + + terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + fmt.Println(output) + return + } + if terminalWidth < views.TUITableMinimumWidth || forceUnstyled { + renderUnstyledInfo(output) + return + } + + renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth)) +} + +func renderUnstyledInfo(output string) { + fmt.Println(output) +} + +func renderTUIView(output string, width int) { + output = lipgloss.NewStyle().PaddingLeft(3).Render(output) + + content := lipgloss. + NewStyle().Width(width). + Render(output) + + fmt.Println(content) +} + +func getInfoLine(key, value string) string { + return propertyNameStyle.Render(fmt.Sprintf("%-*s", propertyNameWidth, key)) + propertyValueStyle.Render(value) + "\n" +} diff --git a/pkg/views/server/runner/list/view.go b/pkg/views/server/runner/list/view.go new file mode 100644 index 0000000000..ba1b39a65e --- /dev/null +++ b/pkg/views/server/runner/list/view.go @@ -0,0 +1,65 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package list + +import ( + "fmt" + + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/server/runner/info" + "github.com/daytonaio/daytona/pkg/views/util" + views_util "github.com/daytonaio/daytona/pkg/views/util" +) + +type rowData struct { + Name string + Id string + State string +} + +func ListRunners(runnerList []apiclient.RunnerDTO) { + if len(runnerList) == 0 { + views_util.NotifyEmptyRunnerList(true) + return + } + + data := [][]string{} + + for _, p := range runnerList { + data = append(data, getRowFromData(p)) + } + + table := util.GetTableView(data, []string{ + "Name", "ID", "State", + }, nil, func() { + renderUnstyledList(runnerList) + }) + + fmt.Println(table) +} + +func renderUnstyledList(runnerList []apiclient.RunnerDTO) { + for _, p := range runnerList { + info.Render(&p, true) + + if p.Id != runnerList[len(runnerList)-1].Id { + fmt.Printf("\n%s\n\n", views.SeparatorString) + } + } +} + +func getRowFromData(runner apiclient.RunnerDTO) []string { + var data rowData + + data.Name = runner.Name + views_util.AdditionalPropertyPadding + data.Id = runner.Id + data.State = views.GetStateLabel(runner.State.Name) + + return []string{ + views.NameStyle.Render(data.Name), + views.DefaultRowDataStyle.Render(data.Id), + data.State, + } +} diff --git a/pkg/views/server/runner/notify.go b/pkg/views/server/runner/notify.go new file mode 100644 index 0000000000..cfc5e4eb3d --- /dev/null +++ b/pkg/views/server/runner/notify.go @@ -0,0 +1,32 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + + "github.com/atotto/clipboard" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/views" +) + +func Notify(runner *apiclient.RegisterRunnerResultDTO, apiUrl string) { + var output string + + output += fmt.Sprintf("You can connect the Runner %s to the Daytona Server by running this command on the Runner's machine:", runner.Name) + + views.RenderContainerLayout(views.GetInfoMessage(output)) + + command := fmt.Sprintf("daytona runner configure --api-url %s --api-key %s --id %s --name %s", apiUrl, runner.ApiKey, runner.Id, runner.Name) + fmt.Println(lipgloss.NewStyle().Padding(0).Foreground(views.Green).Render(command)) + + if err := clipboard.WriteAll(command); err == nil { + output = "The command has been copied to your clipboard." + } else { + output = "Make sure to copy it as you will not be able to see it again." + } + + views.RenderContainerLayout(views.GetInfoMessage(output)) +} diff --git a/pkg/views/server/runner/register.go b/pkg/views/server/runner/register.go new file mode 100644 index 0000000000..44ef96e615 --- /dev/null +++ b/pkg/views/server/runner/register.go @@ -0,0 +1,33 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "errors" + + "github.com/daytonaio/daytona/pkg/views" + + "github.com/charmbracelet/huh" +) + +func RunnerRegistrationView(name *string, existingNames []string) error { + return huh.NewForm( + huh.NewGroup( + huh.NewInput(). + Title("Runner Name"). + Value(name). + Validate(func(str string) error { + if str == "" { + return errors.New("name can not be blank") + } + for _, a := range existingNames { + if a == str { + return errors.New("name already in use") + } + } + return nil + }), + ), + ).WithHeight(5).WithTheme(views.GetCustomTheme()).Run() +} diff --git a/pkg/views/server/runner/selection/select.go b/pkg/views/server/runner/selection/select.go new file mode 100644 index 0000000000..d2b367b901 --- /dev/null +++ b/pkg/views/server/runner/selection/select.go @@ -0,0 +1,48 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/views" +) + +const NewTargetConfigName = "+ New Target Config" + +type RunnerView struct { + Id string + Name string +} + +func GetRunnerFromPrompt(runners []apiclient.RunnerDTO, activeProfileName string, actionVerb string) (*RunnerView, error) { + items := []list.Item{} + + for _, r := range runners { + items = append(items, item{ + runner: RunnerView{ + Id: r.Id, + Name: r.Name, + }, + }) + } + + l := views.GetStyledSelectList(items) + m := model{list: l} + m.list.Title = views.GetStyledMainTitle("Choose a Runner To " + actionVerb) + m.footer = views.GetListFooter(activeProfileName, views.DefaultListFooterPadding) + + p, err := tea.NewProgram(m, tea.WithAltScreen()).Run() + if err != nil { + return nil, err + } + + if m, ok := p.(model); ok && m.choice != nil { + return m.choice, nil + } + + return nil, common.ErrCtrlCAbort +} diff --git a/pkg/views/server/runner/selection/view.go b/pkg/views/server/runner/selection/view.go new file mode 100644 index 0000000000..3af5aec750 --- /dev/null +++ b/pkg/views/server/runner/selection/view.go @@ -0,0 +1,66 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package runner + +import ( + "fmt" + "os" + + "github.com/charmbracelet/bubbles/list" + tea "github.com/charmbracelet/bubbletea" + "github.com/daytonaio/daytona/pkg/views" + "golang.org/x/term" +) + +type item struct { + runner RunnerView +} + +func (i item) Title() string { return i.runner.Name } + +func (i item) Description() string { return i.runner.Id } +func (i item) FilterValue() string { return fmt.Sprintf("%s%s", i.runner.Id, i.runner.Name) } + +type model struct { + list list.Model + choice *RunnerView + footer string +} + +func (m model) Init() tea.Cmd { + return nil +} + +func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch keypress := msg.String(); keypress { + case "ctrl+c": + return m, tea.Quit + + case "enter": + i, ok := m.list.SelectedItem().(item) + if ok { + m.choice = &i.runner + } + return m, tea.Quit + } + case tea.WindowSizeMsg: + h, v := views.DocStyle.GetFrameSize() + m.list.SetSize(msg.Width-h, msg.Height-v) + } + + var cmd tea.Cmd + m.list, cmd = m.list.Update(msg) + return m, cmd +} + +func (m model) View() string { + terminalWidth, terminalHeight, err := term.GetSize(int(os.Stdout.Fd())) + if err != nil { + return "" + } + + return views.DocStyle.Width(terminalWidth - 4).Height(terminalHeight - 4).Render(m.list.View() + m.footer) +} diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index 71bda0a328..b558f87f8b 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -39,6 +39,8 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("Provider", providerLabel) + "\n" + output += getInfoLine("Runner", target.TargetConfig.ProviderInfo.RunnerName) + "\n" + if target.Default { output += getInfoLine("Default", "Yes") + "\n" } @@ -52,8 +54,8 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("Options", target.TargetConfig.Options) + "\n" - if target.Info != nil { - output += getInfoLine("Metadata", *target.Info.ProviderMetadata) + "\n" + if target.ProviderMetadata != nil { + output += getInfoLine("Metadata", *target.ProviderMetadata) + "\n" } terminalWidth, _, err := term.GetSize(int(os.Stdout.Fd())) diff --git a/pkg/views/target/list/view.go b/pkg/views/target/list/view.go index d91efc3390..682f21696f 100644 --- a/pkg/views/target/list/view.go +++ b/pkg/views/target/list/view.go @@ -16,16 +16,16 @@ import ( ) type RowData struct { - Name string - Provider string - WorkspaceCount string - Default bool - Status string - Options string - Uptime string + Name string + Provider string + WorkspaceCount string + Default bool + Status string + TargetConfigProperty string + Uptime string } -func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileName string) { +func ListTargets(targetList []apiclient.TargetDTO, activeProfileName string, showOptions bool) { if len(targetList) == 0 { views_util.NotifyEmptyTargetList(true) return @@ -33,7 +33,13 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa SortTargets(&targetList) - headers := []string{"Target", "Options", "# Workspaces", "Default", "Status"} + targetConfigPropertyHeader := "Config Name" + + if showOptions { + targetConfigPropertyHeader = "Options" + } + + headers := []string{"Target", targetConfigPropertyHeader, "# Workspaces", "Default", "Status"} data := util.ArrayMap(targetList, func(target apiclient.TargetDTO) []string { provider := target.TargetConfig.ProviderInfo.Name @@ -42,12 +48,16 @@ func ListTargets(targetList []apiclient.TargetDTO, verbose bool, activeProfileNa } rowData := RowData{ - Name: target.Name, - Provider: provider, - Options: target.TargetConfig.Options, - WorkspaceCount: fmt.Sprint(len(target.Workspaces)), - Default: target.Default, - Status: views.GetStateLabel(target.State.Name), + Name: target.Name, + Provider: provider, + TargetConfigProperty: target.TargetConfig.Name, + WorkspaceCount: fmt.Sprint(len(target.Workspaces)), + Default: target.Default, + Status: views.GetStateLabel(target.State.Name), + } + + if showOptions { + rowData.TargetConfigProperty = target.TargetConfig.Options } if target.Metadata != nil { @@ -107,7 +117,7 @@ func getRowFromRowData(rowData RowData) []string { return []string{ fmt.Sprintf("%s %s", views.NameStyle.Render(rowData.Name), views.DefaultRowDataStyle.Render(fmt.Sprintf("(%s)", rowData.Provider))), - views.DefaultRowDataStyle.Render(rowData.Options), + views.DefaultRowDataStyle.Render(rowData.TargetConfigProperty), views.DefaultRowDataStyle.Render(rowData.WorkspaceCount), isDefault, rowData.Status, diff --git a/pkg/views/target/selection/view.go b/pkg/views/target/selection/view.go index e9d364a6f0..4edb39eb3f 100644 --- a/pkg/views/target/selection/view.go +++ b/pkg/views/target/selection/view.go @@ -53,8 +53,14 @@ func (i item[T]) Title() string { return title } -func (i item[T]) Id() string { return i.id } -func (i item[T]) Description() string { return i.desc } +func (i item[T]) Id() string { return i.id } +func (i item[T]) Description() string { + desc := i.desc + if i.target.TargetConfig.ProviderInfo.RunnerName != "" { + desc = fmt.Sprintf("%s (%s)", desc, i.target.TargetConfig.ProviderInfo.RunnerName) + } + return desc +} func (i item[T]) State() string { return i.state } func (i item[T]) FilterValue() string { return i.title } diff --git a/pkg/views/targetconfig/list.go b/pkg/views/targetconfig/list.go index 70b52d5352..d4e8df5224 100644 --- a/pkg/views/targetconfig/list.go +++ b/pkg/views/targetconfig/list.go @@ -15,10 +15,11 @@ import ( type rowData struct { ConfigName string Provider string + RunnerName string Options string } -func ListTargetConfigs(targetConfigs []apiclient.TargetConfig) { +func ListTargetConfigs(targetConfigs []apiclient.TargetConfig, showOptions bool) { if len(targetConfigs) == 0 { util.NotifyEmptyTargetConfigList(true) return @@ -26,15 +27,23 @@ func ListTargetConfigs(targetConfigs []apiclient.TargetConfig) { sortTargetConfigs(&targetConfigs) + headers := []string{ + "Name", "Provider", "Runner", "Options", + } data := [][]string{} for _, targetConfig := range targetConfigs { data = append(data, getRowFromRowData(&targetConfig)) } - table := util.GetTableView(data, []string{ - "Name", "Provider", "Options", - }, nil, func() { + if !showOptions { + headers = headers[:len(headers)-1] + for value := range data { + data[value] = data[value][:len(data[value])-1] + } + } + + table := util.GetTableView(data, headers, nil, func() { renderUnstyledList(targetConfigs) }) @@ -46,6 +55,7 @@ func getRowFromRowData(targetConfig *apiclient.TargetConfig) []string { data.ConfigName = targetConfig.Name data.Provider = targetConfig.ProviderInfo.Name + data.RunnerName = targetConfig.ProviderInfo.RunnerName if targetConfig.ProviderInfo.Label != nil { data.Provider = *targetConfig.ProviderInfo.Label } @@ -54,6 +64,7 @@ func getRowFromRowData(targetConfig *apiclient.TargetConfig) []string { row := []string{ views.NameStyle.Render(data.ConfigName), views.DefaultRowDataStyle.Render(data.Provider), + views.DefaultRowDataStyle.Render(data.RunnerName), views.DefaultRowDataStyle.Render(data.Options), } @@ -76,6 +87,8 @@ func renderUnstyledList(targetConfigs []apiclient.TargetConfig) { output += fmt.Sprintf("%s %s", views.GetPropertyKey("Provider: "), targetConfig.ProviderInfo.Name) + "\n\n" + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Runner: "), targetConfig.ProviderInfo.RunnerName) + "\n\n" + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Options: "), targetConfig.Options) + "\n\n" if targetConfig.Name != targetConfigs[len(targetConfigs)-1].Name { diff --git a/pkg/views/targetconfig/select.go b/pkg/views/targetconfig/select.go index d65e2be33e..eea2b8fd18 100644 --- a/pkg/views/targetconfig/select.go +++ b/pkg/views/targetconfig/select.go @@ -20,15 +20,19 @@ const NewTargetConfigName = "+ New Target Config" type TargetConfigView struct { Id string Name string + RunnerName string Options string ProviderInfo ProviderInfo } type ProviderInfo struct { - Name string - Version string - Label *string - Installed *bool + Name string + RunnerId string + RunnerName string + Version string + Label *string + Installed *bool + TargetConfigManifest map[string]apiclient.TargetConfigProperty } func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activeProfileName string, providerViewList *[]provider.ProviderView, withNewTargetConfig bool, actionVerb string) (*TargetConfigView, error) { @@ -67,10 +71,13 @@ func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activePro Name: fmt.Sprintf("Add a %s Target Config", label), Options: "{}", ProviderInfo: ProviderInfo{ - Name: providerView.Name, - Version: providerView.Version, - Label: providerView.Label, - Installed: providerView.Installed, + Name: providerView.Name, + RunnerId: providerView.RunnerId, + RunnerName: providerView.RunnerName, + Version: providerView.Version, + Label: providerView.Label, + Installed: providerView.Installed, + TargetConfigManifest: providerView.TargetConfigManifest, }, }, }) @@ -96,12 +103,16 @@ func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activePro func ToTargetConfigView(targetConfig apiclient.TargetConfig) TargetConfigView { return TargetConfigView{ - Name: targetConfig.Name, - Options: targetConfig.Options, + Id: targetConfig.Id, + Name: targetConfig.Name, + RunnerName: targetConfig.ProviderInfo.RunnerName, + Options: targetConfig.Options, ProviderInfo: ProviderInfo{ - Name: targetConfig.ProviderInfo.Name, - Version: targetConfig.ProviderInfo.Version, - Label: targetConfig.ProviderInfo.Label, + Name: targetConfig.ProviderInfo.Name, + RunnerId: targetConfig.ProviderInfo.RunnerId, + RunnerName: targetConfig.ProviderInfo.RunnerName, + Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, }, } } diff --git a/pkg/views/targetconfig/set.go b/pkg/views/targetconfig/set.go index efaf6f98e2..e26b2839cc 100644 --- a/pkg/views/targetconfig/set.go +++ b/pkg/views/targetconfig/set.go @@ -68,6 +68,10 @@ func SetTargetConfigForm(targetConfig *TargetConfigView, targetConfigManifest ma } } + if property.Type == nil { + continue + } + switch *property.Type { case apiclient.TargetConfigPropertyTypeFloat, apiclient.TargetConfigPropertyTypeInt: var initialValue *string @@ -134,6 +138,11 @@ func SetTargetConfigForm(targetConfig *TargetConfigView, targetConfigManifest ma continue } } + + if property.Type == nil { + continue + } + switch *property.Type { case apiclient.TargetConfigPropertyTypeInt: options[name], err = strconv.Atoi(*options[name].(*string)) @@ -173,6 +182,10 @@ func getInput(name string, property apiclient.TargetConfigProperty, initialValue Description(*property.Description). Value(value). Validate(func(s string) error { + if property.Type == nil { + return errors.New("property type is not defined") + } + switch *property.Type { case apiclient.TargetConfigPropertyTypeInt: _, err := strconv.Atoi(s) diff --git a/pkg/views/targetconfig/view.go b/pkg/views/targetconfig/view.go index ef5dfa54ae..874a3fc467 100644 --- a/pkg/views/targetconfig/view.go +++ b/pkg/views/targetconfig/view.go @@ -4,6 +4,7 @@ package targetconfig import ( + "fmt" "os" "github.com/charmbracelet/bubbles/list" @@ -25,6 +26,10 @@ func (i item) Description() string { desc = *i.targetConfig.ProviderInfo.Label } + if i.targetConfig.ProviderInfo.RunnerName != "" { + desc = fmt.Sprintf("%s (Runner %s)", desc, i.targetConfig.ProviderInfo.RunnerName) + } + if i.targetConfig.ProviderInfo.Installed != nil { if !*i.targetConfig.ProviderInfo.Installed { desc += " (needs installing)" diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index d9836c7829..b9eda9e115 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -29,7 +29,7 @@ func NotifyEmptyTargetConfigList(tip bool) { func NotifyEmptyWorkspaceTemplateList(tip bool) { views.RenderInfoMessageBold("No workspace templates found") if tip { - views.RenderTip("Use 'daytona workspace-template add' to add a workspace template") + views.RenderTip("Use 'daytona template add' to add a workspace template") } } @@ -95,3 +95,10 @@ func NotifyEmptyServerLogList(tip bool) { views.RenderTip("Use 'daytona serve' in order to create server log files") } } + +func NotifyEmptyRunnerList(tip bool) { + views.RenderInfoMessageBold("No runners found") + if tip { + views.RenderTip("Use 'daytona runner register' to register a runner") + } +} diff --git a/pkg/views/workspace/info/multi.go b/pkg/views/workspace/info/multi.go index c0845ebf64..c66886b50a 100644 --- a/pkg/views/workspace/info/multi.go +++ b/pkg/views/workspace/info/multi.go @@ -35,7 +35,7 @@ func RenderMulti(workspaces []apiclient.WorkspaceDTO, ide string, forceUnstyled output += fmt.Sprintf("%s\n\n", views.SeparatorString) for index, workspace := range workspaces { output += getInfoLine(fmt.Sprintf("Workspace #%d", index+1), fmt.Sprintf("%s (%s)", workspace.Name, workspace.Id)) + "\n" - output += getSingleWorkspaceOutput(&workspace, true) + output += getWorkspaceDataOutput(&workspace, true) if index < len(workspaces)-1 { output += fmt.Sprintf("\n%s\n\n", views.SeparatorString) } diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go index 57d79fab3f..dab8568326 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/workspace/info/view.go @@ -56,7 +56,7 @@ func Render(workspace *apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { return } - output += getSingleWorkspaceOutput(workspace, isCreationView) + output += getWorkspaceDataOutput(workspace, isCreationView) if !isCreationView { output = views.GetStyledMainTitle("Workspace Info") + "\n" + output @@ -83,8 +83,7 @@ func renderTUIView(output string, width int, isCreationView bool) { fmt.Println(content) } -// TODO: migrate to the target info view -func getSingleWorkspaceOutput(workspace *apiclient.WorkspaceDTO, isCreationView bool) string { +func getWorkspaceDataOutput(workspace *apiclient.WorkspaceDTO, isCreationView bool) string { var output string var repositoryUrl string diff --git a/pkg/views/workspace/list/view.go b/pkg/views/workspace/list/view.go index 93a3bcf7d1..e12d0c1956 100644 --- a/pkg/views/workspace/list/view.go +++ b/pkg/views/workspace/list/view.go @@ -20,20 +20,19 @@ type RowData struct { Repository string TargetName string Status string - Created string Branch string Uptime string } -func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, verbose bool, activeProfileName string) { +func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders bool, activeProfileName string) { if len(workspaceList) == 0 { views_util.NotifyEmptyWorkspaceList(true) return } - SortWorkspaces(&workspaceList, verbose) + SortWorkspaces(&workspaceList) - headers := []string{"Workspace", "Repository", "Target", "Status", "Created", "Branch"} + headers := []string{"Workspace", "Repository", "Target", "Status", "Branch"} data := [][]string{} @@ -46,13 +45,6 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders data = append(data, row) } - if !verbose { - headers = headers[:len(headers)-2] - for value := range data { - data[value] = data[value][:len(data[value])-2] - } - } - footer := lipgloss.NewStyle().Foreground(views.LightGray).Render(views.GetListFooter(activeProfileName, &views.Padding{})) table := views_util.GetTableView(data, headers, &footer, func() { @@ -62,7 +54,7 @@ func ListWorkspaces(workspaceList []apiclient.WorkspaceDTO, specifyGitProviders fmt.Println(table) } -func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { +func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO) { sort.Slice(*workspaceList, func(i, j int) bool { pi, pj := views_util.GetStateSortPriorities((*workspaceList)[i].State.Name, (*workspaceList)[j].State.Name) if pi != pj { @@ -75,7 +67,7 @@ func SortWorkspaces(workspaceList *[]apiclient.WorkspaceDTO, verbose bool) { } func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) *RowData { - rowData := RowData{"", "", "", "", "", "", ""} + rowData := RowData{"", "", "", "", "", ""} rowData.Name = workspace.Name + views_util.AdditionalPropertyPadding rowData.Repository = util.GetRepositorySlugFromUrl(workspace.Repository.Url, specifyGitProviders) rowData.Branch = workspace.Repository.Branch @@ -83,10 +75,6 @@ func getTableRowData(workspace apiclient.WorkspaceDTO, specifyGitProviders bool) rowData.TargetName = workspace.Target.Name + views_util.AdditionalPropertyPadding - if workspace.Info != nil { - rowData.Created = util.FormatTimestamp(workspace.Info.Created) - } - if workspace.Metadata != nil { views_util.CheckAndAppendTimeLabel(&rowData.Status, workspace.State, workspace.Metadata.Uptime) } @@ -115,7 +103,6 @@ func getRowFromRowData(rowData RowData, isMultiWorkspaceAccordion bool) []string views.DefaultRowDataStyle.Render(rowData.Repository), views.DefaultRowDataStyle.Render(rowData.TargetName), rowData.Status, - views.DefaultRowDataStyle.Render(rowData.Created), views.DefaultRowDataStyle.Render(views.GetBranchNameLabel(rowData.Branch)), } diff --git a/pkg/views/workspace/selection/workspace.go b/pkg/views/workspace/selection/workspace.go index 4236e1c885..998b496501 100644 --- a/pkg/views/workspace/selection/workspace.go +++ b/pkg/views/workspace/selection/workspace.go @@ -10,7 +10,6 @@ import ( "github.com/charmbracelet/bubbles/list" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" - "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -39,13 +38,6 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect workspaceName = "Unnamed Workspace" } - // Get the time if available - createdTime := "" - - if workspace.Info != nil { - createdTime = util.FormatTimestamp(workspace.Info.Created) - } - stateLabel := views.GetStateLabel(workspace.State.Name) isDisabled := false @@ -70,7 +62,6 @@ func generateWorkspaceList(workspaces []apiclient.WorkspaceDTO, isMultipleSelect desc: "", targetName: workspace.Target.Name, repository: workspace.Repository.Url, - createdTime: createdTime, state: stateLabel, workspace: &workspace, choiceProperty: workspace, @@ -126,7 +117,7 @@ func getWorkspaceProgramEssentials(modelTitle string, actionVerb ActionVerb, wor } func selectWorkspacePrompt(workspaces []apiclient.WorkspaceDTO, actionVerb ActionVerb, choiceChan chan<- *apiclient.WorkspaceDTO) { - list_view.SortWorkspaces(&workspaces, true) + list_view.SortWorkspaces(&workspaces) p := getWorkspaceProgramEssentials("Select a Workspace To ", actionVerb, workspaces, "", false) if m, ok := p.(model[apiclient.WorkspaceDTO]); ok && m.choice != nil { @@ -145,7 +136,7 @@ func GetWorkspaceFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb Acti } func selectWorkspacesFromPrompt(workspaces []apiclient.WorkspaceDTO, actionVerb ActionVerb, choiceChan chan<- []*apiclient.WorkspaceDTO) { - list_view.SortWorkspaces(&workspaces, true) + list_view.SortWorkspaces(&workspaces) footerText := lipgloss.NewStyle().Bold(true).PaddingLeft(2).Render(fmt.Sprintf("\n\nPress 'x' to mark a workspace.\nPress 'enter' to %s the current/marked workspaces.", actionVerb)) p := getWorkspaceProgramEssentials("Select Workspaces To ", actionVerb, workspaces, footerText, true) From 62adfcb416c75b21e9db1ee7d2023a1647764862 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Wed, 8 Jan 2025 15:58:05 +0100 Subject: [PATCH 35/76] fix: target config deletion and agentless prop (#1693) Signed-off-by: Ivan Dagelic --- pkg/api/server.go | 2 +- pkg/cmd/provider/list.go | 1 + pkg/cmd/targetconfig/add.go | 23 +++++++++++++---------- pkg/db/target_config_store.go | 16 ++++++---------- pkg/views/provider/select.go | 2 ++ pkg/views/targetconfig/select.go | 13 ++++++++----- 6 files changed, 31 insertions(+), 26 deletions(-) diff --git a/pkg/api/server.go b/pkg/api/server.go index c92b4fbe9d..c46e6cd459 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -271,7 +271,7 @@ func (a *ApiServer) Start() error { { targetConfigController.GET("", targetconfig.ListTargetConfigs) targetConfigController.PUT("", targetconfig.AddTargetConfig) - targetConfigController.DELETE("/:configName", targetconfig.RemoveTargetConfig) + targetConfigController.DELETE("/:configId", targetconfig.RemoveTargetConfig) } logController := protected.Group("/log") diff --git a/pkg/cmd/provider/list.go b/pkg/cmd/provider/list.go index 90fddbd935..53097e96a9 100644 --- a/pkg/cmd/provider/list.go +++ b/pkg/cmd/provider/list.go @@ -56,6 +56,7 @@ func GetProviderViewOptions(ctx context.Context, apiClient *apiclient.APIClient, for _, installedProvider := range installedProviders { providerMap[installedProvider.Name] = provider.ProviderView{ Name: installedProvider.Name, + AgentlessTarget: installedProvider.AgentlessTarget, Label: installedProvider.Label, Version: installedProvider.Version, Installed: util.Pointer(true), diff --git a/pkg/cmd/targetconfig/add.go b/pkg/cmd/targetconfig/add.go index 06e4f6ab16..72b0db9fbe 100644 --- a/pkg/cmd/targetconfig/add.go +++ b/pkg/cmd/targetconfig/add.go @@ -128,11 +128,12 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien Name: "", Options: "{}", ProviderInfo: targetconfig.ProviderInfo{ - Name: selectedProvider.Name, - RunnerId: selectedProvider.RunnerId, - RunnerName: selectedProvider.RunnerName, - Version: selectedProvider.Version, - Label: selectedProvider.Label, + Name: selectedProvider.Name, + AgentlessTarget: selectedProvider.AgentlessTarget, + RunnerId: selectedProvider.RunnerId, + RunnerName: selectedProvider.RunnerName, + Version: selectedProvider.Version, + Label: selectedProvider.Label, }, } @@ -184,6 +185,7 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, ProviderInfo: apiclient.ProviderInfo{ + AgentlessTarget: selectedProvider.AgentlessTarget, Name: selectedProvider.Name, Version: selectedProvider.Version, Label: selectedProvider.Label, @@ -203,11 +205,12 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien Name: targetConfig.Name, Options: targetConfig.Options, ProviderInfo: targetconfig.ProviderInfo{ - Name: targetConfig.ProviderInfo.Name, - RunnerId: targetConfig.ProviderInfo.RunnerId, - RunnerName: targetConfig.ProviderInfo.RunnerName, - Version: targetConfig.ProviderInfo.Version, - Label: targetConfig.ProviderInfo.Label, + Name: targetConfig.ProviderInfo.Name, + AgentlessTarget: targetConfig.ProviderInfo.AgentlessTarget, + RunnerId: targetConfig.ProviderInfo.RunnerId, + RunnerName: targetConfig.ProviderInfo.RunnerName, + Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, }, }, nil } diff --git a/pkg/db/target_config_store.go b/pkg/db/target_config_store.go index e79e532555..2f379a5f48 100644 --- a/pkg/db/target_config_store.go +++ b/pkg/db/target_config_store.go @@ -29,7 +29,7 @@ func (s *TargetConfigStore) List(ctx context.Context, allowDeleted bool) ([]*mod tx := s.GetTransaction(ctx) targetConfigs := []*models.TargetConfig{} - tx = processTargetConfigFilters(tx, "", allowDeleted).Find(&targetConfigs) + tx = processTargetConfigFilters(tx, nil, allowDeleted).Find(&targetConfigs) if tx.Error != nil { return nil, tx.Error @@ -42,7 +42,7 @@ func (s *TargetConfigStore) Find(ctx context.Context, idOrName string, allowDele tx := s.GetTransaction(ctx) targetConfig := &models.TargetConfig{} - tx = processTargetConfigFilters(tx, idOrName, allowDeleted).First(targetConfig) + tx = processTargetConfigFilters(tx, &idOrName, allowDeleted).First(targetConfig) if tx.Error != nil { if IsRecordNotFound(tx.Error) { @@ -58,16 +58,12 @@ func (s *TargetConfigStore) Save(ctx context.Context, targetConfig *models.Targe tx := s.GetTransaction(ctx) tx = tx.Save(targetConfig) - if tx.Error != nil { - return tx.Error - } - - return nil + return tx.Error } -func processTargetConfigFilters(tx *gorm.DB, idOrName string, allowDeleted bool) *gorm.DB { - if idOrName != "" { - tx = tx.Where("id = ? OR name = ?", idOrName, idOrName) +func processTargetConfigFilters(tx *gorm.DB, idOrName *string, allowDeleted bool) *gorm.DB { + if idOrName != nil { + tx = tx.Where("id = ? OR name = ?", *idOrName, *idOrName) } if !allowDeleted { diff --git a/pkg/views/provider/select.go b/pkg/views/provider/select.go index 809d14e30b..72c0b8d21b 100644 --- a/pkg/views/provider/select.go +++ b/pkg/views/provider/select.go @@ -15,6 +15,7 @@ import ( type ProviderView struct { Name string + AgentlessTarget *bool Label *string Version string Installed *bool @@ -67,6 +68,7 @@ func ProviderListToView(providers []apiclient.ProviderInfo) []ProviderView { for _, p := range providers { providerViews = append(providerViews, ProviderView{ Name: p.Name, + AgentlessTarget: p.AgentlessTarget, Label: p.Label, Version: p.Version, Installed: nil, diff --git a/pkg/views/targetconfig/select.go b/pkg/views/targetconfig/select.go index eea2b8fd18..ae086a7fc2 100644 --- a/pkg/views/targetconfig/select.go +++ b/pkg/views/targetconfig/select.go @@ -27,6 +27,7 @@ type TargetConfigView struct { type ProviderInfo struct { Name string + AgentlessTarget *bool RunnerId string RunnerName string Version string @@ -78,6 +79,7 @@ func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activePro Label: providerView.Label, Installed: providerView.Installed, TargetConfigManifest: providerView.TargetConfigManifest, + AgentlessTarget: providerView.AgentlessTarget, }, }, }) @@ -108,11 +110,12 @@ func ToTargetConfigView(targetConfig apiclient.TargetConfig) TargetConfigView { RunnerName: targetConfig.ProviderInfo.RunnerName, Options: targetConfig.Options, ProviderInfo: ProviderInfo{ - Name: targetConfig.ProviderInfo.Name, - RunnerId: targetConfig.ProviderInfo.RunnerId, - RunnerName: targetConfig.ProviderInfo.RunnerName, - Version: targetConfig.ProviderInfo.Version, - Label: targetConfig.ProviderInfo.Label, + Name: targetConfig.ProviderInfo.Name, + AgentlessTarget: targetConfig.ProviderInfo.AgentlessTarget, + RunnerId: targetConfig.ProviderInfo.RunnerId, + RunnerName: targetConfig.ProviderInfo.RunnerName, + Version: targetConfig.ProviderInfo.Version, + Label: targetConfig.ProviderInfo.Label, }, } } From 12fa401e7b9db3ca1b1fce9247e1e80eba299c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Fri, 10 Jan 2025 11:15:42 +0100 Subject: [PATCH 36/76] fix: agentmode (#1500) Signed-off-by: Luka Brecic --- docs/agent_mode/daytona.md | 7 +-- docs/agent_mode/daytona_info.md | 2 +- docs/agent_mode/daytona_logs.md | 2 +- docs/agent_mode/daytona_restart.md | 18 ------ docs/agent_mode/daytona_start.md | 18 ------ docs/agent_mode/daytona_stop.md | 18 ------ hack/docs/agent_mode/daytona.yaml | 7 +-- hack/docs/agent_mode/daytona_info.yaml | 2 +- hack/docs/agent_mode/daytona_logs.yaml | 2 +- hack/docs/agent_mode/daytona_restart.yaml | 9 --- hack/docs/agent_mode/daytona_start.yaml | 9 --- hack/docs/agent_mode/daytona_stop.yaml | 9 --- pkg/cmd/agentmode/agent_mode.go | 7 ++- pkg/cmd/agentmode/info.go | 68 ++++++++++++++++------- pkg/cmd/agentmode/logs.go | 61 +++++++++++++++++++- pkg/cmd/agentmode/restart.go | 39 ------------- pkg/cmd/agentmode/start.go | 35 ------------ pkg/cmd/agentmode/stop.go | 39 ------------- 18 files changed, 118 insertions(+), 234 deletions(-) delete mode 100644 docs/agent_mode/daytona_restart.md delete mode 100644 docs/agent_mode/daytona_start.md delete mode 100644 docs/agent_mode/daytona_stop.md delete mode 100644 hack/docs/agent_mode/daytona_restart.yaml delete mode 100644 hack/docs/agent_mode/daytona_start.yaml delete mode 100644 hack/docs/agent_mode/daytona_stop.yaml delete mode 100644 pkg/cmd/agentmode/restart.go delete mode 100644 pkg/cmd/agentmode/start.go delete mode 100644 pkg/cmd/agentmode/stop.go diff --git a/docs/agent_mode/daytona.md b/docs/agent_mode/daytona.md index 0238291882..820f97fc28 100644 --- a/docs/agent_mode/daytona.md +++ b/docs/agent_mode/daytona.md @@ -24,11 +24,8 @@ daytona [flags] * [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. * [daytona expose](daytona_expose.md) - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace * [daytona forward](daytona_forward.md) - Forward a port publicly via an URL -* [daytona info](daytona_info.md) - Show workspace info +* [daytona info](daytona_info.md) - Show resource info * [daytona list](daytona_list.md) - List workspaces -* [daytona logs](daytona_logs.md) - View logs for the workspace -* [daytona restart](daytona_restart.md) - Restart the workspace -* [daytona start](daytona_start.md) - Start the workspace -* [daytona stop](daytona_stop.md) - Stop the workspace +* [daytona logs](daytona_logs.md) - View resource logs * [daytona version](daytona_version.md) - Print the version number diff --git a/docs/agent_mode/daytona_info.md b/docs/agent_mode/daytona_info.md index 6b2340360f..84fa076ba7 100644 --- a/docs/agent_mode/daytona_info.md +++ b/docs/agent_mode/daytona_info.md @@ -1,6 +1,6 @@ ## daytona info -Show workspace info +Show resource info ``` daytona info [flags] diff --git a/docs/agent_mode/daytona_logs.md b/docs/agent_mode/daytona_logs.md index 01523f908f..6f21f58ec6 100644 --- a/docs/agent_mode/daytona_logs.md +++ b/docs/agent_mode/daytona_logs.md @@ -1,6 +1,6 @@ ## daytona logs -View logs for the workspace +View resource logs ``` daytona logs [flags] diff --git a/docs/agent_mode/daytona_restart.md b/docs/agent_mode/daytona_restart.md deleted file mode 100644 index 4953c7e673..0000000000 --- a/docs/agent_mode/daytona_restart.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona restart - -Restart the workspace - -``` -daytona restart [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_start.md b/docs/agent_mode/daytona_start.md deleted file mode 100644 index 3baa6d8938..0000000000 --- a/docs/agent_mode/daytona_start.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona start - -Start the workspace - -``` -daytona start [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/docs/agent_mode/daytona_stop.md b/docs/agent_mode/daytona_stop.md deleted file mode 100644 index 7631814021..0000000000 --- a/docs/agent_mode/daytona_stop.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona stop - -Stop the workspace - -``` -daytona stop [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager - diff --git a/hack/docs/agent_mode/daytona.yaml b/hack/docs/agent_mode/daytona.yaml index dd4e6664e7..c44de9924c 100644 --- a/hack/docs/agent_mode/daytona.yaml +++ b/hack/docs/agent_mode/daytona.yaml @@ -16,10 +16,7 @@ see_also: - daytona docs - Opens the Daytona documentation in your default browser. - daytona expose - Expose a local port over stdout - Used by the Daytona CLI to make direct connections to the workspace - daytona forward - Forward a port publicly via an URL - - daytona info - Show workspace info + - daytona info - Show resource info - daytona list - List workspaces - - daytona logs - View logs for the workspace - - daytona restart - Restart the workspace - - daytona start - Start the workspace - - daytona stop - Stop the workspace + - daytona logs - View resource logs - daytona version - Print the version number diff --git a/hack/docs/agent_mode/daytona_info.yaml b/hack/docs/agent_mode/daytona_info.yaml index 6d9a8ef626..8717176e9d 100644 --- a/hack/docs/agent_mode/daytona_info.yaml +++ b/hack/docs/agent_mode/daytona_info.yaml @@ -1,5 +1,5 @@ name: daytona info -synopsis: Show workspace info +synopsis: Show resource info usage: daytona info [flags] options: - name: format diff --git a/hack/docs/agent_mode/daytona_logs.yaml b/hack/docs/agent_mode/daytona_logs.yaml index 70a97d203c..b7eeb419a8 100644 --- a/hack/docs/agent_mode/daytona_logs.yaml +++ b/hack/docs/agent_mode/daytona_logs.yaml @@ -1,5 +1,5 @@ name: daytona logs -synopsis: View logs for the workspace +synopsis: View resource logs usage: daytona logs [flags] inherited_options: - name: help diff --git a/hack/docs/agent_mode/daytona_restart.yaml b/hack/docs/agent_mode/daytona_restart.yaml deleted file mode 100644 index e26f0ebb3b..0000000000 --- a/hack/docs/agent_mode/daytona_restart.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona restart -synopsis: Restart the workspace -usage: daytona restart [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_start.yaml b/hack/docs/agent_mode/daytona_start.yaml deleted file mode 100644 index 8751a52ba3..0000000000 --- a/hack/docs/agent_mode/daytona_start.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona start -synopsis: Start the workspace -usage: daytona start [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/hack/docs/agent_mode/daytona_stop.yaml b/hack/docs/agent_mode/daytona_stop.yaml deleted file mode 100644 index 7bfbfe3d24..0000000000 --- a/hack/docs/agent_mode/daytona_stop.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona stop -synopsis: Stop the workspace -usage: daytona stop [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go index f1402c7d2d..b70428bc91 100644 --- a/pkg/cmd/agentmode/agent_mode.go +++ b/pkg/cmd/agentmode/agent_mode.go @@ -36,9 +36,6 @@ func Execute() error { agentModeRootCmd.AddCommand(gitCredCmd) agentModeRootCmd.AddCommand(dockerCredCmd) agentModeRootCmd.AddCommand(AgentCmd) - agentModeRootCmd.AddCommand(startCmd) - agentModeRootCmd.AddCommand(stopCmd) - agentModeRootCmd.AddCommand(restartCmd) agentModeRootCmd.AddCommand(infoCmd) agentModeRootCmd.AddCommand(portForwardCmd) agentModeRootCmd.AddCommand(exposeCmd) @@ -71,3 +68,7 @@ func init() { workspaceId = workspaceIdEnv } } + +func isWorkspaceAgentMode() bool { + return workspaceId != "" +} diff --git a/pkg/cmd/agentmode/info.go b/pkg/cmd/agentmode/info.go index bfa94a9b2f..a4e8d008cb 100644 --- a/pkg/cmd/agentmode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -6,41 +6,69 @@ package agentmode import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/format" - "github.com/daytonaio/daytona/pkg/views/target/info" + target_views "github.com/daytonaio/daytona/pkg/views/target/info" + workspaces_views "github.com/daytonaio/daytona/pkg/views/workspace/info" "github.com/spf13/cobra" ) var infoCmd = &cobra.Command{ Use: "info", - Short: "Show workspace info", + Short: "Show resource info", Aliases: []string{"view", "inspect"}, Args: cobra.ExactArgs(0), GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { - var target *apiclient.TargetDTO - - target, _, err := apiclient_util.GetTarget(targetId) - if err != nil { - return err - } - - if target == nil { - return nil + if isWorkspaceAgentMode() { + return runWorkspaceInfo() } - if format.FormatFlag != "" { - formattedData := format.NewFormatter(target) - formattedData.Print() - return nil - } - - info.Render(target, false) - return nil + return runTargetInfo() }, } func init() { format.RegisterFormatFlag(infoCmd) } + +func runWorkspaceInfo() error { + workspace, _, err := apiclient_util.GetWorkspace(workspaceId) + if err != nil { + return err + } + + if workspace == nil { + return nil + } + + if format.FormatFlag != "" { + formattedData := format.NewFormatter(workspace) + formattedData.Print() + return nil + } + + workspaces_views.Render(workspace, "", false) + + return nil +} + +func runTargetInfo() error { + target, _, err := apiclient_util.GetTarget(targetId) + if err != nil { + return err + } + + if target == nil { + return nil + } + + if format.FormatFlag != "" { + formattedData := format.NewFormatter(target) + formattedData.Print() + return nil + } + + target_views.Render(target, false) + + return nil +} diff --git a/pkg/cmd/agentmode/logs.go b/pkg/cmd/agentmode/logs.go index 0f41b852d7..7dbd1df771 100644 --- a/pkg/cmd/agentmode/logs.go +++ b/pkg/cmd/agentmode/logs.go @@ -4,19 +4,74 @@ package agentmode import ( - "errors" + "context" "github.com/daytonaio/daytona/internal/util" + apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/agent/config" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/spf13/cobra" ) var logsCmd = &cobra.Command{ Use: "logs", - Short: "View logs for the workspace", + Short: "View resource logs", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, Aliases: []string{"lg", "log"}, RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") + ctx := context.Background() + + mode := config.ModeTarget + if isWorkspaceAgentMode() { + mode = config.ModeWorkspace + } + + cfg, err := config.GetConfig(mode) + if err != nil { + return err + } + + if isWorkspaceAgentMode() { + return runWorkspaceLogs(ctx, cfg.Server.ApiUrl, cfg.Server.ApiKey) + } + + return runTargetLogs(ctx, cfg.Server.ApiUrl, cfg.Server.ApiKey) }, } + +func runWorkspaceLogs(ctx context.Context, serverUrl, serverApiKey string) error { + workspace, _, err := apiclient_util.GetWorkspace(workspaceId) + if err != nil { + return err + } + + cmd_common.ReadWorkspaceLogs(ctx, cmd_common.ReadLogParams{ + Id: workspace.Id, + Label: &workspace.Name, + ServerUrl: serverUrl, + ApiKey: serverApiKey, + Index: util.Pointer(0), + Follow: util.Pointer(false), + }) + + return nil +} + +func runTargetLogs(ctx context.Context, serverUrl, serverApiKey string) error { + target, _, err := apiclient_util.GetTarget(targetId) + if err != nil { + return err + } + + cmd_common.ReadTargetLogs(ctx, cmd_common.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ServerUrl: serverUrl, + ApiKey: serverApiKey, + Index: util.Pointer(0), + Follow: util.Pointer(false), + }) + + return nil +} diff --git a/pkg/cmd/agentmode/restart.go b/pkg/cmd/agentmode/restart.go deleted file mode 100644 index 8758214f2d..0000000000 --- a/pkg/cmd/agentmode/restart.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package agentmode - -import ( - "errors" - - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var restartCmd = &cobra.Command{ - Use: "restart", - Short: "Restart the workspace", - Args: cobra.NoArgs, - GroupID: util.TARGET_GROUP, - RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") - }, - // RunE: func(cmd *cobra.Command, args []string) error { - // apiClient, err := apiclient.GetApiClient(nil) - // if err != nil { - // return err - // } - - // err = target_cmd.RestartTarget(apiClient, targetId, workspaceId) - // if err != nil { - // return err - // } - - // if workspaceId != "" { - // views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully restarted", workspaceId, targetId)) - // } else { - // views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully restarted", targetId)) - // } - // return nil - // }, -} diff --git a/pkg/cmd/agentmode/start.go b/pkg/cmd/agentmode/start.go deleted file mode 100644 index 1f64cabc4b..0000000000 --- a/pkg/cmd/agentmode/start.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package agentmode - -import ( - "errors" - - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var startCmd = &cobra.Command{ - Use: "start", - Short: "Start the workspace", - Args: cobra.NoArgs, - GroupID: util.TARGET_GROUP, - RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") - }, - // RunE: func(cmd *cobra.Command, args []string) error { - // apiClient, err := apiclient.GetApiClient(nil) - // if err != nil { - // return err - // } - - // err = target_cmd.StartTarget(apiClient, targetId, workspaceId) - // if err != nil { - // return err - // } - - // views.RenderInfoMessage("Workspace successfully started") - // return nil - // }, -} diff --git a/pkg/cmd/agentmode/stop.go b/pkg/cmd/agentmode/stop.go deleted file mode 100644 index b452b4b6d9..0000000000 --- a/pkg/cmd/agentmode/stop.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package agentmode - -import ( - "errors" - - "github.com/daytonaio/daytona/internal/util" - "github.com/spf13/cobra" -) - -var stopCmd = &cobra.Command{ - Use: "stop", - Short: "Stop the workspace", - Args: cobra.NoArgs, - GroupID: util.TARGET_GROUP, - RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") - }, - // RunE: func(cmd *cobra.Command, args []string) error { - // apiClient, err := apiclient.GetApiClient(nil) - // if err != nil { - // return err - // } - - // err = target_cmd.StopTarget(apiClient, targetId, workspaceId) - // if err != nil { - // return err - // } - - // if workspaceId != "" { - // views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' from target '%s' successfully stopped", workspaceId, targetId)) - // } else { - // views.RenderInfoMessage(fmt.Sprintf("Target '%s' successfully stopped", targetId)) - // } - // return nil - // }, -} From 10e52e10dc19de893f671c0bc4b5902ebb31537f Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 10 Jan 2025 10:21:36 +0000 Subject: [PATCH 37/76] refactor: move agent_mode util to common Signed-off-by: Toma Puljak --- cmd/daytona/main.go | 4 ++-- internal/util/apiclient/api_client.go | 3 ++- pkg/cmd/cmd.go | 2 +- {internal => pkg/common}/agent_mode.go | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) rename {internal => pkg/common}/agent_mode.go (94%) diff --git a/cmd/daytona/main.go b/cmd/daytona/main.go index a768a4bda3..c42be7a680 100644 --- a/cmd/daytona/main.go +++ b/cmd/daytona/main.go @@ -9,17 +9,17 @@ import ( golog "log" - "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/cmd" "github.com/daytonaio/daytona/pkg/cmd/agentmode" + "github.com/daytonaio/daytona/pkg/common" "github.com/rs/zerolog" zlog "github.com/rs/zerolog/log" log "github.com/sirupsen/logrus" ) func main() { - if internal.AgentMode() { + if common.AgentMode() { err := agentmode.Execute() if err != nil { log.Fatal(err) diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index 730338ff60..d412f201ef 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -13,6 +13,7 @@ import ( "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/telemetry" ) @@ -60,7 +61,7 @@ func GetApiClient(profile *config.Profile) (*apiclient.APIClient, error) { clientConfig.AddDefaultHeader(telemetry.ENABLED_HEADER, "true") clientConfig.AddDefaultHeader(telemetry.SESSION_ID_HEADER, internal.SESSION_ID) clientConfig.AddDefaultHeader(telemetry.CLIENT_ID_HEADER, config.GetClientId()) - if internal.AgentMode() { + if common.AgentMode() { clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_WORKSPACE_SOURCE)) } else { clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_SOURCE)) diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 46ac580968..1a6036b1e3 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -215,7 +215,7 @@ func GetCmdTelemetryData(cmd *cobra.Command, flags []string) map[string]interfac } source := telemetry.CLI_SOURCE - if internal.AgentMode() { + if common.AgentMode() { source = telemetry.CLI_WORKSPACE_SOURCE } diff --git a/internal/agent_mode.go b/pkg/common/agent_mode.go similarity index 94% rename from internal/agent_mode.go rename to pkg/common/agent_mode.go index 8faf824ba2..11a5fc4bfe 100644 --- a/internal/agent_mode.go +++ b/pkg/common/agent_mode.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package internal +package common import "os" From 435ec3ab49cd6c693836137f2af4eb91b8d01c51 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Fri, 10 Jan 2025 11:43:55 +0100 Subject: [PATCH 38/76] fix: create target dto param (#1694) Signed-off-by: Ivan Dagelic --- pkg/api/docs/docs.go | 4 +-- pkg/api/docs/swagger.json | 4 +-- pkg/api/docs/swagger.yaml | 4 +-- pkg/apiclient/api/openapi.yaml | 6 ++--- pkg/apiclient/docs/CreateTargetDTO.md | 22 ++++++++-------- pkg/apiclient/docs/TargetAPI.md | 2 +- pkg/apiclient/model_create_target_dto.go | 32 ++++++++++++------------ pkg/cmd/target/create.go | 6 ++--- pkg/cmd/workspace/create/cmd.go | 6 +---- pkg/models/target.go | 9 ++++++- pkg/server/targets/create.go | 2 +- pkg/server/targets/service_test.go | 6 ++--- pkg/services/target.go | 6 ++--- 13 files changed, 56 insertions(+), 53 deletions(-) diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 00d02a04d6..c33b03fc1e 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -4032,7 +4032,7 @@ const docTemplate = `{ "required": [ "id", "name", - "targetConfigName" + "targetConfigId" ], "properties": { "id": { @@ -4041,7 +4041,7 @@ const docTemplate = `{ "name": { "type": "string" }, - "targetConfigName": { + "targetConfigId": { "type": "string" } } diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 7bda2d048a..7624b620db 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -4029,7 +4029,7 @@ "required": [ "id", "name", - "targetConfigName" + "targetConfigId" ], "properties": { "id": { @@ -4038,7 +4038,7 @@ "name": { "type": "string" }, - "targetConfigName": { + "targetConfigId": { "type": "string" } } diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index de5951bc7b..cc2d2d6bcf 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -211,12 +211,12 @@ definitions: type: string name: type: string - targetConfigName: + targetConfigId: type: string required: - id - name - - targetConfigName + - targetConfigId type: object CreateWorkspaceDTO: properties: diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 9fb76a2112..ef67d9eecc 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -3064,20 +3064,20 @@ components: type: object CreateTargetDTO: example: - targetConfigName: targetConfigName name: name + targetConfigId: targetConfigId id: id properties: id: type: string name: type: string - targetConfigName: + targetConfigId: type: string required: - id - name - - targetConfigName + - targetConfigId type: object CreateWorkspaceDTO: example: diff --git a/pkg/apiclient/docs/CreateTargetDTO.md b/pkg/apiclient/docs/CreateTargetDTO.md index e1b5229371..f9d7f3a668 100644 --- a/pkg/apiclient/docs/CreateTargetDTO.md +++ b/pkg/apiclient/docs/CreateTargetDTO.md @@ -6,13 +6,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **Id** | **string** | | **Name** | **string** | | -**TargetConfigName** | **string** | | +**TargetConfigId** | **string** | | ## Methods ### NewCreateTargetDTO -`func NewCreateTargetDTO(id string, name string, targetConfigName string, ) *CreateTargetDTO` +`func NewCreateTargetDTO(id string, name string, targetConfigId string, ) *CreateTargetDTO` NewCreateTargetDTO instantiates a new CreateTargetDTO object This constructor will assign default values to properties that have it defined, @@ -67,24 +67,24 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. -### GetTargetConfigName +### GetTargetConfigId -`func (o *CreateTargetDTO) GetTargetConfigName() string` +`func (o *CreateTargetDTO) GetTargetConfigId() string` -GetTargetConfigName returns the TargetConfigName field if non-nil, zero value otherwise. +GetTargetConfigId returns the TargetConfigId field if non-nil, zero value otherwise. -### GetTargetConfigNameOk +### GetTargetConfigIdOk -`func (o *CreateTargetDTO) GetTargetConfigNameOk() (*string, bool)` +`func (o *CreateTargetDTO) GetTargetConfigIdOk() (*string, bool)` -GetTargetConfigNameOk returns a tuple with the TargetConfigName field if it's non-nil, zero value otherwise +GetTargetConfigIdOk returns a tuple with the TargetConfigId field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetTargetConfigName +### SetTargetConfigId -`func (o *CreateTargetDTO) SetTargetConfigName(v string)` +`func (o *CreateTargetDTO) SetTargetConfigId(v string)` -SetTargetConfigName sets TargetConfigName field to given value. +SetTargetConfigId sets TargetConfigId field to given value. diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index 2d4f24451d..a9420bcec7 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -38,7 +38,7 @@ import ( ) func main() { - target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfigName_example") // CreateTargetDTO | Create target + target := *openapiclient.NewCreateTargetDTO("Id_example", "Name_example", "TargetConfigId_example") // CreateTargetDTO | Create target configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) diff --git a/pkg/apiclient/model_create_target_dto.go b/pkg/apiclient/model_create_target_dto.go index c38a711e60..6730a0e8cd 100644 --- a/pkg/apiclient/model_create_target_dto.go +++ b/pkg/apiclient/model_create_target_dto.go @@ -21,9 +21,9 @@ var _ MappedNullable = &CreateTargetDTO{} // CreateTargetDTO struct for CreateTargetDTO type CreateTargetDTO struct { - Id string `json:"id"` - Name string `json:"name"` - TargetConfigName string `json:"targetConfigName"` + Id string `json:"id"` + Name string `json:"name"` + TargetConfigId string `json:"targetConfigId"` } type _CreateTargetDTO CreateTargetDTO @@ -32,11 +32,11 @@ type _CreateTargetDTO CreateTargetDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateTargetDTO(id string, name string, targetConfigName string) *CreateTargetDTO { +func NewCreateTargetDTO(id string, name string, targetConfigId string) *CreateTargetDTO { this := CreateTargetDTO{} this.Id = id this.Name = name - this.TargetConfigName = targetConfigName + this.TargetConfigId = targetConfigId return &this } @@ -96,28 +96,28 @@ func (o *CreateTargetDTO) SetName(v string) { o.Name = v } -// GetTargetConfigName returns the TargetConfigName field value -func (o *CreateTargetDTO) GetTargetConfigName() string { +// GetTargetConfigId returns the TargetConfigId field value +func (o *CreateTargetDTO) GetTargetConfigId() string { if o == nil { var ret string return ret } - return o.TargetConfigName + return o.TargetConfigId } -// GetTargetConfigNameOk returns a tuple with the TargetConfigName field value +// GetTargetConfigIdOk returns a tuple with the TargetConfigId field value // and a boolean to check if the value has been set. -func (o *CreateTargetDTO) GetTargetConfigNameOk() (*string, bool) { +func (o *CreateTargetDTO) GetTargetConfigIdOk() (*string, bool) { if o == nil { return nil, false } - return &o.TargetConfigName, true + return &o.TargetConfigId, true } -// SetTargetConfigName sets field value -func (o *CreateTargetDTO) SetTargetConfigName(v string) { - o.TargetConfigName = v +// SetTargetConfigId sets field value +func (o *CreateTargetDTO) SetTargetConfigId(v string) { + o.TargetConfigId = v } func (o CreateTargetDTO) MarshalJSON() ([]byte, error) { @@ -132,7 +132,7 @@ func (o CreateTargetDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name - toSerialize["targetConfigName"] = o.TargetConfigName + toSerialize["targetConfigId"] = o.TargetConfigId return toSerialize, nil } @@ -143,7 +143,7 @@ func (o *CreateTargetDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "id", "name", - "targetConfigName", + "targetConfigId", } allProperties := make(map[string]interface{}) diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index 5a7441e511..1d658c9171 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -162,8 +162,8 @@ func CreateTargetDtoFlow(ctx context.Context, params TargetCreationParams) (*api id = stringid.TruncateID(id) return &apiclient.CreateTargetDTO{ - Id: id, - Name: targetName, - TargetConfigName: targetConfigView.Name, + Id: id, + Name: targetName, + TargetConfigId: targetConfigView.Id, }, nil } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 7b07e6418b..1415c11d72 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -169,11 +169,7 @@ var CreateCmd = &cobra.Command{ SkipPrefixLengthSetup: true, }) - t, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(apiclient.CreateTargetDTO{ - Id: createTargetDto.Id, - Name: createTargetDto.Name, - TargetConfigName: createTargetDto.TargetConfigName, - }).Execute() + t, res, err := apiClient.TargetAPI.CreateTarget(ctx).Target(*createTargetDto).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/models/target.go b/pkg/models/target.go index 178dd1e499..97c7ed9d7e 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -31,12 +31,19 @@ type TargetMetadata struct { Uptime uint64 `json:"uptime" validate:"required" gorm:"not null"` } // @name TargetMetadata +var allowedAgentlessTargetStates = map[ResourceStateName]bool{ + ResourceStateNamePendingCreate: true, + ResourceStateNameCreating: true, + ResourceStateNameError: true, + ResourceStateNameDeleted: true, +} + func (t *Target) GetState() ResourceState { state := getResourceStateFromJob(t.LastJob) // Some providers do not utilize agents in target mode if t.TargetConfig.ProviderInfo.AgentlessTarget { - if state.Name == ResourceStateNameDeleted || state.Name == ResourceStateNamePendingCreate || state.Name == ResourceStateNameCreating { + if allowedAgentlessTargetStates[state.Name] { return state } diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index eb962cf979..850a76d732 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -30,7 +30,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTar return nil, services.ErrTargetAlreadyExists } - tc, err := s.findTargetConfig(ctx, req.TargetConfigName) + tc, err := s.findTargetConfig(ctx, req.TargetConfigId) if err != nil { return s.handleCreateError(ctx, nil, err) } diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index d7a0ac8c0e..4cc88bb171 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -43,9 +43,9 @@ var tg = &models.Target{ } var createTargetDTO = services.CreateTargetDTO{ - Name: "test", - Id: "test", - TargetConfigName: "test", + Name: "test", + Id: "test", + TargetConfigId: "test", } func TestTargetService(t *testing.T) { diff --git a/pkg/services/target.go b/pkg/services/target.go index e25c43010e..c5573bc4dc 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -36,9 +36,9 @@ type TargetDTO struct { } // @name TargetDTO type CreateTargetDTO struct { - Id string `json:"id" validate:"required"` - Name string `json:"name" validate:"required"` - TargetConfigName string `json:"targetConfigName" validate:"required"` + Id string `json:"id" validate:"required"` + Name string `json:"name" validate:"required"` + TargetConfigId string `json:"targetConfigId" validate:"required"` } // @name CreateTargetDTO type UpdateTargetProviderMetadataDTO struct { From 3d40f5b70ee6e5325cf7f9304ca8e9fa6b2cc388 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 10 Jan 2025 13:18:06 +0000 Subject: [PATCH 39/76] refactor: abstract api key generation methods (#1701) Signed-off-by: Toma Puljak --- pkg/cmd/bootstrap/get_server_instance.go | 7 +++++++ pkg/server/apikeys/apikeys.go | 5 ++--- pkg/server/apikeys/service.go | 12 +++++++++--- pkg/server/apikeys/service_test.go | 8 ++++++++ pkg/server/apikeys/validate.go | 7 +++---- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/pkg/cmd/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go index ea07d3f0e1..519710f9ab 100644 --- a/pkg/cmd/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -11,6 +11,7 @@ import ( "path/filepath" "github.com/daytonaio/daytona/cmd/daytona/config" + apikey_util "github.com/daytonaio/daytona/internal/apikeys" "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/db" @@ -278,6 +279,12 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe apiKeyService := apikeys.NewApiKeyService(apikeys.ApiKeyServiceConfig{ ApiKeyStore: apiKeyStore, + GenerateRandomKey: func(name string) string { + return apikey_util.GenerateRandomKey() + }, + GetKeyHash: func(key string) string { + return apikey_util.HashKey(key) + }, }) headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) diff --git a/pkg/server/apikeys/apikeys.go b/pkg/server/apikeys/apikeys.go index 27c303a96f..7987d12d64 100644 --- a/pkg/server/apikeys/apikeys.go +++ b/pkg/server/apikeys/apikeys.go @@ -6,7 +6,6 @@ package apikeys import ( "context" - "github.com/daytonaio/daytona/internal/apikeys" "github.com/daytonaio/daytona/pkg/models" ) @@ -37,10 +36,10 @@ func (s *ApiKeyService) Revoke(ctx context.Context, name string) error { } func (s *ApiKeyService) Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) { - key := apikeys.GenerateRandomKey() + key := s.generateRandomKey(name) apiKey := &models.ApiKey{ - KeyHash: apikeys.HashKey(key), + KeyHash: s.getKeyHash(key), Type: keyType, Name: name, } diff --git a/pkg/server/apikeys/service.go b/pkg/server/apikeys/service.go index 31917a20a6..69855617a3 100644 --- a/pkg/server/apikeys/service.go +++ b/pkg/server/apikeys/service.go @@ -9,15 +9,21 @@ import ( ) type ApiKeyServiceConfig struct { - ApiKeyStore stores.ApiKeyStore + ApiKeyStore stores.ApiKeyStore + GenerateRandomKey func(name string) string + GetKeyHash func(key string) string } func NewApiKeyService(config ApiKeyServiceConfig) services.IApiKeyService { return &ApiKeyService{ - apiKeyStore: config.ApiKeyStore, + apiKeyStore: config.ApiKeyStore, + generateRandomKey: config.GenerateRandomKey, + getKeyHash: config.GetKeyHash, } } type ApiKeyService struct { - apiKeyStore stores.ApiKeyStore + apiKeyStore stores.ApiKeyStore + generateRandomKey func(name string) string + getKeyHash func(key string) string } diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index 8d36e10773..9615bf5982 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -7,7 +7,9 @@ import ( "context" "testing" + apikeys_util "github.com/daytonaio/daytona/internal/apikeys" t_apikeys "github.com/daytonaio/daytona/internal/testing/server/apikeys" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/services" @@ -32,6 +34,12 @@ func (s *ApiKeyServiceTestSuite) SetupTest() { s.apiKeyStore = t_apikeys.NewInMemoryApiKeyStore() s.apiKeyService = apikeys.NewApiKeyService(apikeys.ApiKeyServiceConfig{ ApiKeyStore: s.apiKeyStore, + GenerateRandomKey: func(name string) string { + return apikeys_util.GenerateRandomKey() + }, + GetKeyHash: func(key string) string { + return apikeys_util.HashKey(key) + }, }) for _, keyName := range clientKeyNames { diff --git a/pkg/server/apikeys/validate.go b/pkg/server/apikeys/validate.go index 71ce71472f..2936fbb4a8 100644 --- a/pkg/server/apikeys/validate.go +++ b/pkg/server/apikeys/validate.go @@ -6,19 +6,18 @@ package apikeys import ( "context" - "github.com/daytonaio/daytona/internal/apikeys" "github.com/daytonaio/daytona/pkg/models" ) func (s *ApiKeyService) IsValidApiKey(ctx context.Context, apiKey string) bool { - keyHash := apikeys.HashKey(apiKey) + keyHash := s.getKeyHash(apiKey) _, err := s.apiKeyStore.Find(ctx, keyHash) return err == nil } func (s *ApiKeyService) GetApiKeyType(ctx context.Context, apiKey string) (models.ApiKeyType, error) { - keyHash := apikeys.HashKey(apiKey) + keyHash := s.getKeyHash(apiKey) key, err := s.apiKeyStore.Find(ctx, keyHash) if err != nil { @@ -29,7 +28,7 @@ func (s *ApiKeyService) GetApiKeyType(ctx context.Context, apiKey string) (model } func (s *ApiKeyService) IsTargetApiKey(ctx context.Context, apiKey string) bool { - keyHash := apikeys.HashKey(apiKey) + keyHash := s.getKeyHash(apiKey) key, err := s.apiKeyStore.Find(ctx, keyHash) if err != nil { From d8d9ff9067415f4059ba8f5ec98363cbd0a5f5ac Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Fri, 10 Jan 2025 14:18:25 +0000 Subject: [PATCH 40/76] feat: auto-create docker default target Signed-off-by: Toma Puljak --- pkg/cmd/bootstrap/get_local_runner.go | 45 ++++++++++++++------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/pkg/cmd/bootstrap/get_local_runner.go b/pkg/cmd/bootstrap/get_local_runner.go index 6e5304a652..e7ced8c21d 100644 --- a/pkg/cmd/bootstrap/get_local_runner.go +++ b/pkg/cmd/bootstrap/get_local_runner.go @@ -15,7 +15,6 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/build" "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/db" "github.com/daytonaio/daytona/pkg/docker" jobs_build "github.com/daytonaio/daytona/pkg/jobs/build" jobs_runner "github.com/daytonaio/daytona/pkg/jobs/runner" @@ -27,11 +26,11 @@ import ( "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/server/headscale" - "github.com/daytonaio/daytona/pkg/server/targetconfigs" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/docker/docker/client" + "github.com/docker/docker/pkg/stringid" log "github.com/sirupsen/logrus" ) @@ -325,23 +324,8 @@ func getProviderManager(params LocalRunnerParams, logger *log.Logger) (providerm headscaleUrl := util.GetFrpcHeadscaleUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain) binaryUrl, _ := url.JoinPath(util.GetFrpcApiUrl(params.ServerConfig.Frps.Protocol, params.ServerConfig.Id, params.ServerConfig.Frps.Domain), "binary", "script") - dbPath, err := getDbPath() - if err != nil { - return nil, err - } - - dbConnection := db.GetSQLiteConnection(dbPath) - - store := db.NewStore(dbConnection) - - targetConfigStore, err := db.NewTargetConfigStore(store) - if err != nil { - return nil, err - } - - targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ - TargetConfigStore: targetConfigStore, - }) + targetConfigService := server.GetInstance(nil).TargetConfigService + targetService := server.GetInstance(nil).TargetService return providermanager.GetProviderManager(&providermanager.ProviderManagerConfig{ TargetLogsDir: server.GetTargetLogsDir(params.ConfigDir), @@ -362,12 +346,31 @@ func getProviderManager(params LocalRunnerParams, logger *log.Logger) (providerm return targetConfigService.Map(ctx) }, CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { - _, err := targetConfigService.Add(ctx, services.AddTargetConfigDTO{ + tc, err := targetConfigService.Add(ctx, services.AddTargetConfigDTO{ Name: name, Options: options, ProviderInfo: providerInfo, }) - return err + + if err != nil { + return err + } + + if providerInfo.Name == "docker-provider" { + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + + _, err := targetService.CreateTarget(ctx, services.CreateTargetDTO{ + TargetConfigId: tc.Id, + Name: name, + Id: id, + }) + if err != nil { + log.Error(err) + } + } + + return nil }, }), nil } From 4913c34623c1da2a31f4c6b785c38fb264f64068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Mon, 13 Jan 2025 13:19:22 +0100 Subject: [PATCH 41/76] fix: purge (#1456) Signed-off-by: Luka Brecic --- cmd/daytona/config/config.go | 7 +- docs/daytona_purge.md | 2 +- docs/daytona_runner.md | 2 +- docs/daytona_runner_purge.md | 8 +- hack/docs/daytona_purge.yaml | 2 +- hack/docs/daytona_runner.yaml | 2 +- hack/docs/daytona_runner_purge.yaml | 7 +- .../server/targets/mocks/build_service.go | 6 - pkg/cmd/purge.go | 133 ++++++++++-------- pkg/cmd/runner/purge.go | 99 ++++++++++++- pkg/cmd/server/serve.go | 6 +- pkg/logs/types.go | 12 +- pkg/runner/config.go | 11 ++ pkg/runner/runner.go | 43 +++++- pkg/server/builds/service.go | 27 ---- pkg/server/headscale/server.go | 5 - pkg/server/log.go | 6 +- pkg/server/purge.go | 117 --------------- pkg/server/registry/service.go | 5 - pkg/services/build.go | 2 - pkg/views/purge/purge_resources.go | 52 +++++++ pkg/views/runner/config.go | 6 +- pkg/views/runner/configure.go | 30 ++-- pkg/views/server/configure.go | 51 ++----- pkg/views/util/validators.go | 62 ++++++++ 25 files changed, 389 insertions(+), 314 deletions(-) delete mode 100644 pkg/server/purge.go create mode 100644 pkg/views/purge/purge_resources.go create mode 100644 pkg/views/util/validators.go diff --git a/cmd/daytona/config/config.go b/cmd/daytona/config/config.go index 9989751578..794af7592a 100644 --- a/cmd/daytona/config/config.go +++ b/cmd/daytona/config/config.go @@ -215,12 +215,7 @@ func DeleteConfigDir() error { return err } - err = os.RemoveAll(configDir) - if err != nil { - return err - } - - return nil + return os.RemoveAll(configDir) } func TelemetryEnabled() bool { diff --git a/docs/daytona_purge.md b/docs/daytona_purge.md index b34cf5c858..ca5f4af20d 100644 --- a/docs/daytona_purge.md +++ b/docs/daytona_purge.md @@ -4,7 +4,7 @@ Purges all Daytona data from the current device ### Synopsis -Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. +Purges all Daytona data from the current device - including all local runner providers, configuration files and SSH files. This command is irreversible. ``` daytona purge [flags] diff --git a/docs/daytona_runner.md b/docs/daytona_runner.md index b3249e5b74..a4f0b6fb5a 100644 --- a/docs/daytona_runner.md +++ b/docs/daytona_runner.md @@ -14,7 +14,7 @@ Manage the runner * [daytona runner config](daytona_runner_config.md) - Outputs Daytona Runner config * [daytona runner configure](daytona_runner_configure.md) - Configure Daytona Runner * [daytona runner logs](daytona_runner_logs.md) - View runner logs -* [daytona runner purge](daytona_runner_purge.md) - Purges the runner +* [daytona runner purge](daytona_runner_purge.md) - Purges the Daytona Runner * [daytona runner restart](daytona_runner_restart.md) - Restarts the runner * [daytona runner serve](daytona_runner_serve.md) - Starts the runner in the foreground * [daytona runner start](daytona_runner_start.md) - Starts the runner diff --git a/docs/daytona_runner_purge.md b/docs/daytona_runner_purge.md index 8a3d980009..9f8a3437ef 100644 --- a/docs/daytona_runner_purge.md +++ b/docs/daytona_runner_purge.md @@ -1,11 +1,17 @@ ## daytona runner purge -Purges the runner +Purges the Daytona Runner ``` daytona runner purge [flags] ``` +### Options + +``` + -y, --yes Execute Daytona Runner purge without prompt +``` + ### Options inherited from parent commands ``` diff --git a/hack/docs/daytona_purge.yaml b/hack/docs/daytona_purge.yaml index 7d28219871..f68628140e 100644 --- a/hack/docs/daytona_purge.yaml +++ b/hack/docs/daytona_purge.yaml @@ -1,7 +1,7 @@ name: daytona purge synopsis: Purges all Daytona data from the current device description: | - Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible. + Purges all Daytona data from the current device - including all local runner providers, configuration files and SSH files. This command is irreversible. usage: daytona purge [flags] options: - name: force diff --git a/hack/docs/daytona_runner.yaml b/hack/docs/daytona_runner.yaml index c4b9db1b6c..eeeda1e074 100644 --- a/hack/docs/daytona_runner.yaml +++ b/hack/docs/daytona_runner.yaml @@ -9,7 +9,7 @@ see_also: - daytona runner config - Outputs Daytona Runner config - daytona runner configure - Configure Daytona Runner - daytona runner logs - View runner logs - - daytona runner purge - Purges the runner + - daytona runner purge - Purges the Daytona Runner - daytona runner restart - Restarts the runner - daytona runner serve - Starts the runner in the foreground - daytona runner start - Starts the runner diff --git a/hack/docs/daytona_runner_purge.yaml b/hack/docs/daytona_runner_purge.yaml index 67596d919d..7c62f4d303 100644 --- a/hack/docs/daytona_runner_purge.yaml +++ b/hack/docs/daytona_runner_purge.yaml @@ -1,6 +1,11 @@ name: daytona runner purge -synopsis: Purges the runner +synopsis: Purges the Daytona Runner usage: daytona runner purge [flags] +options: + - name: "yes" + shorthand: "y" + default_value: "false" + usage: Execute Daytona Runner purge without prompt inherited_options: - name: help default_value: "false" diff --git a/internal/testing/server/targets/mocks/build_service.go b/internal/testing/server/targets/mocks/build_service.go index 4f24295acc..13162b1846 100644 --- a/internal/testing/server/targets/mocks/build_service.go +++ b/internal/testing/server/targets/mocks/build_service.go @@ -7,7 +7,6 @@ package mocks import ( "io" - "time" "github.com/daytonaio/daytona/pkg/services" "github.com/stretchr/testify/mock" @@ -46,11 +45,6 @@ func (m *MockBuildService) HandleSuccessfulRemoval(id string) error { return args.Get(0).(error) } -func (m *MockBuildService) AwaitEmptyList(waitTime time.Duration) error { - args := m.Called(waitTime) - return args.Error(0) -} - func (m *MockBuildService) GetBuildLogReader(buildId string) (io.Reader, error) { args := m.Called(buildId) return args.Get(0).(io.Reader), args.Error(1) diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 0bb001231b..f65fbc45a7 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -5,22 +5,23 @@ package cmd import ( "context" - "errors" "fmt" "os" + "path/filepath" + "strings" "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/cmd/bootstrap" + server_cmd "github.com/daytonaio/daytona/pkg/cmd/server" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/server" - "github.com/daytonaio/daytona/pkg/server/headscale" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" view "github.com/daytonaio/daytona/pkg/views/purge" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -29,7 +30,7 @@ var forceFlag bool var purgeCmd = &cobra.Command{ Use: "purge", Short: "Purges all Daytona data from the current device", - Long: "Purges all Daytona data from the current device - including all targets, configuration files, and SSH files. This command is irreversible.", + Long: "Purges all Daytona data from the current device - including all local runner providers, configuration files and SSH files. This command is irreversible.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { var confirmCheck bool @@ -46,12 +47,6 @@ var purgeCmd = &cobra.Command{ return err } - // FIXME: TODO - // runnerConfig, err := runner.GetConfig() - // if err != nil { - // return err - // } - serverConfigDir, err := server.GetConfigDir() if err != nil { return err @@ -107,7 +102,6 @@ var purgeCmd = &cobra.Command{ defer telemetryService.Close() - fmt.Println("Purging the server") server, err := bootstrap.GetInstance(serverConfig, serverConfigDir, internal.Version, telemetryService) if err != nil { return err @@ -117,63 +111,52 @@ var purgeCmd = &cobra.Command{ ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, config.GetClientId()) ctx = context.WithValue(ctx, telemetry.ENABLED_CONTEXT_KEY, c.TelemetryEnabled) - errCh := make(chan error) - - go func() { - err := <-errCh - if err != nil { - if !forceFlag { - log.Fatal(err) - } - } - }() - - headscaleServerStartedChan := make(chan struct{}) - headscaleServerErrChan := make(chan error) - - go func() { - err := server.TailscaleServer.Start(headscaleServerErrChan) - if err != nil { - headscaleServerErrChan <- err - return + // Get all targets, workspaces and builds to prompt user for resource purge + targets, err := server.TargetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) + if err != nil { + if !forceFlag { + return err + } else { + fmt.Printf("Failed to get targets: %v\n", err) } - headscaleServerStartedChan <- struct{}{} - }() - - localContainerRegistryErrChan := make(chan error) + } - go func() { - if server.LocalContainerRegistry != nil { - localContainerRegistryErrChan <- server.LocalContainerRegistry.Start() + workspaces, err := server.WorkspaceService.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{}) + if err != nil { + if !forceFlag { + return err } else { - localContainerRegistryErrChan <- nil + fmt.Printf("Failed to get workspaces: %v\n", err) } - }() - - select { - case <-headscaleServerStartedChan: - go func() { - headscaleServerErrChan <- server.TailscaleServer.Connect(headscale.HEADSCALE_USERNAME) - }() - case err := <-headscaleServerErrChan: - return err } - err = <-localContainerRegistryErrChan + builds, err := server.BuildService.List(ctx, nil) if err != nil { - return err + if !forceFlag { + return err + } else { + fmt.Printf("Failed to get builds: %v\n", err) + } } - errs := server.Purge(ctx, forceFlag) - if len(errs) > 0 { - errMessage := "" - for _, err := range errs { - errMessage += fmt.Sprintf("Failed to purge: %v\n", err) + if len(targets) != 0 || len(workspaces) != 0 || len(builds) != 0 { + var continuePurge bool + commands := view.PurgeResourcesPrompt(&continuePurge, len(targets), len(workspaces), len(builds)) + if err != nil { + if !forceFlag { + return err + } else { + fmt.Printf("Failed to prompt for resource purge: %v\n", err) + } + } + if !continuePurge { + fmt.Printf("\nOperation cancelled.\nManually delete leftover resources for a complete purge by starting the server and running the following commands:\n\n%s\n", strings.Join(commands, "\n")) + return nil } - - return errors.New(errMessage) } + fmt.Println("Purging the server") + if server.LocalContainerRegistry != nil { fmt.Println("Purging local container registry...") err := server.LocalContainerRegistry.Purge() @@ -196,6 +179,15 @@ var purgeCmd = &cobra.Command{ } } + err = purgeLocalRunnerProviders(ctx, serverConfig, serverConfigDir, telemetryService) + if err != nil { + if !forceFlag { + return err + } else { + fmt.Printf("Failed to purge local runner providers: %v\n", err) + } + } + fmt.Println("Server purged.") fmt.Println("\nDeleting the SSH configuration file") @@ -228,6 +220,33 @@ var purgeCmd = &cobra.Command{ } func init() { - purgeCmd.Flags().BoolVarP(&create.YesFlag, "yes", "y", false, "Execute purge without prompt") + purgeCmd.Flags().BoolVarP(&create.YesFlag, "yes", "y", false, "Execute purge without a prompt") purgeCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete all targets by force") } + +func purgeLocalRunnerProviders(ctx context.Context, serverConfig *server.Config, serverConfigDir string, telemetryService telemetry.TelemetryService) error { + localRunnerConfig := server_cmd.GetLocalRunnerConfig(filepath.Join(serverConfigDir, "local-runner")) + + params := bootstrap.LocalRunnerParams{ + ServerConfig: serverConfig, + RunnerConfig: localRunnerConfig, + ConfigDir: serverConfigDir, + TelemetryService: telemetryService, + } + + localRunner, err := bootstrap.GetLocalRunner(params) + if err != nil { + return err + } + + if localRunner != nil { + fmt.Println("Purging providers...") + err = localRunner.Purge(ctx) + if err != nil { + return err + } + fmt.Println("Providers purged.") + } + + return nil +} diff --git a/pkg/cmd/runner/purge.go b/pkg/cmd/runner/purge.go index daeb504ae7..c71aebbcbb 100644 --- a/pkg/cmd/runner/purge.go +++ b/pkg/cmd/runner/purge.go @@ -4,14 +4,109 @@ package runner import ( + "fmt" + "net" + + "github.com/charmbracelet/huh" + "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/views" "github.com/spf13/cobra" ) +var yesFlag bool + var purgeCmd = &cobra.Command{ Use: "purge", - Short: "Purges the runner", + Short: "Purges the Daytona Runner", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { - return nil + if !yesFlag { + var confirmCheck bool + + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Purging will remove the entire Daytona Runner configuration from the system, are you sure you want to continue?"). + Description("This action is irreversible."). + Value(&confirmCheck), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + + if !confirmCheck { + fmt.Println("Operation cancelled.") + return nil + } + } + + cfg, err := runner.GetConfig() + if err != nil { + return err + } + + err = healthCheck(cfg.ApiPort) + if err == nil { + return runStopRunnerForm(cfg.ApiPort) + } + + return purgeRunner() }, } + +func healthCheck(apiPort int32) error { + _, err := net.Dial("tcp", fmt.Sprintf(":%d", apiPort)) + + return err +} + +func runStopRunnerForm(apiPort int32) error { + var runnerStoppedCheck bool + + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title("Please stop the Daytona Runner before continuing by executing daytona runner stop command."). + Description("Purging all data requires the Daytona Runner to be stopped."). + Affirmative("Continue"). + Negative("Abort"). + Value(&runnerStoppedCheck), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + return err + } + + if runnerStoppedCheck { + err = healthCheck(apiPort) + if err == nil { + views.RenderInfoMessage("The Daytona Runner is still running. Please stop it before continuing.") + return nil + } + } else { + fmt.Println("Operation cancelled.") + return nil + } + + return purgeRunner() +} + +func purgeRunner() error { + err := runner.DeleteConfigDir() + if err != nil { + return err + } + + views.RenderInfoMessageBold("The Daytona Runner has been purged from this device.") + + return nil +} + +func init() { + purgeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Execute Daytona Runner purge without a prompt") +} diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index baf4da6f43..6bd2cc4baa 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -137,11 +137,9 @@ var ServeCmd = &cobra.Command{ return } - localRunnerConfig := getLocalRunnerConfig(filepath.Join(configDir, "local-runner")) - localRunnerErrChan <- startLocalRunner(bootstrap.LocalRunnerParams{ ServerConfig: c, - RunnerConfig: localRunnerConfig, + RunnerConfig: GetLocalRunnerConfig(filepath.Join(configDir, "local-runner")), ConfigDir: configDir, TelemetryService: telemetryService, }) @@ -265,7 +263,7 @@ func startLocalRunner(params bootstrap.LocalRunnerParams) error { return runner.Start(context.Background()) } -func getLocalRunnerConfig(configDir string) *runner.Config { +func GetLocalRunnerConfig(configDir string) *runner.Config { providersDir := filepath.Join(configDir, "providers") logFilePath := filepath.Join(configDir, "runner.log") diff --git a/pkg/logs/types.go b/pkg/logs/types.go index 466096f374..380d9340c7 100644 --- a/pkg/logs/types.go +++ b/pkg/logs/types.go @@ -21,9 +21,9 @@ var defaultLogFileConfig = LogFileConfig{ type LogFileConfig struct { Path string `json:"path" validate:"required"` - MaxSize int `json:"maxSize" validate:"required"` - MaxBackups int `json:"maxBackups" validate:"required"` - MaxAge int `json:"maxAge" validate:"required"` + MaxSize int32 `json:"maxSize" validate:"required"` + MaxBackups int32 `json:"maxBackups" validate:"required"` + MaxAge int32 `json:"maxAge" validate:"required"` LocalTime bool `json:"localTime" validate:"optional"` Compress bool `json:"compress" validate:"optional"` } // @name LogFileConfig @@ -44,7 +44,7 @@ func GetDefaultLogFileConfig(logFilePath string) *LogFileConfig { if err != nil { log.Error(fmt.Printf("%s. Using default log file max size.", err)) } else { - logFileConfig.MaxSize = value + logFileConfig.MaxSize = int32(value) } } @@ -54,7 +54,7 @@ func GetDefaultLogFileConfig(logFilePath string) *LogFileConfig { if err != nil { log.Error(fmt.Printf("%s. Using default log file max backups.", err)) } else { - logFileConfig.MaxBackups = value + logFileConfig.MaxBackups = int32(value) } } @@ -64,7 +64,7 @@ func GetDefaultLogFileConfig(logFilePath string) *LogFileConfig { if err != nil { log.Error(fmt.Printf("%s. Using default log file max age.", err)) } else { - logFileConfig.MaxAge = value + logFileConfig.MaxAge = int32(value) } } diff --git a/pkg/runner/config.go b/pkg/runner/config.go index a672390466..19115f8c15 100644 --- a/pkg/runner/config.go +++ b/pkg/runner/config.go @@ -19,6 +19,7 @@ import ( type Config struct { Id string `json:"id"` Name string `json:"name"` + ApiPort int32 `json:"apiPort"` ServerApiKey string `json:"serverApiKey"` ServerApiUrl string `json:"serverApiUrl"` ProvidersDir string `json:"providersDir"` @@ -99,6 +100,15 @@ func GetConfigDir() (string, error) { return filepath.Join(userConfigDir, "daytona-runner"), nil } +func DeleteConfigDir() error { + configDir, err := GetConfigDir() + if err != nil { + return err + } + + return os.RemoveAll(configDir) +} + func Save(c Config) error { if err := util.DirectoryValidator(&c.ProvidersDir); err != nil { return err @@ -171,6 +181,7 @@ func GetDefaultConfig() (*Config, error) { c := Config{ ProvidersDir: providersDir, LogFile: logs.GetDefaultLogFileConfig(logFilePath), + ApiPort: 3983, } if os.Getenv("DEFAULT_PROVIDERS_DIR") != "" { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index c9c2d17bf9..045187e99f 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -7,12 +7,15 @@ import ( "context" "errors" "fmt" + "net" "net/http" "os" "os/signal" "time" + "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/api/controllers/health" "github.com/daytonaio/daytona/pkg/jobs" "github.com/daytonaio/daytona/pkg/jobs/build" "github.com/daytonaio/daytona/pkg/jobs/runner" @@ -21,6 +24,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/scheduler" + "github.com/gin-gonic/gin" "github.com/hashicorp/go-plugin" log "github.com/sirupsen/logrus" ) @@ -34,6 +38,7 @@ const RUNNER_METADATA_UPDATE_INTERVAL = 2 * time.Second type IRunner interface { Start(ctx context.Context) error CheckAndRunJobs(ctx context.Context) error + Purge(ctx context.Context) error } type RunnerConfig struct { @@ -98,6 +103,12 @@ func (r *Runner) Start(ctx context.Context) error { r.startTime = time.Now() + // Check if the API port is already in use for the runner API server + _, err := net.Dial("tcp", fmt.Sprintf(":%d", r.Config.ApiPort)) + if err == nil { + return fmt.Errorf("cannot start runner API server, port %d is already in use", r.Config.ApiPort) + } + go func() { interruptChannel := make(chan os.Signal, 1) signal.Notify(interruptChannel, os.Interrupt) @@ -107,8 +118,25 @@ func (r *Runner) Start(ctx context.Context) error { } }() + router := gin.New() + router.Use(gin.Recovery()) + + gin.SetMode(gin.ReleaseMode) + + public := router.Group("/") + + healthController := public.Group(constants.HEALTH_CHECK_ROUTE) + { + healthController.GET("", health.HealthCheck) + } + + routerErrChan := make(chan error) + go func() { + routerErrChan <- router.Run(fmt.Sprintf(":%d", r.Config.ApiPort)) + }() + // Terminate orphaned provider processes - err := r.providerManager.TerminateProviderProcesses(r.Config.ProvidersDir) + err = r.providerManager.TerminateProviderProcesses(r.Config.ProvidersDir) if err != nil { r.logger.Errorf("Failed to terminate orphaned provider processes: %s", err) } @@ -146,11 +174,16 @@ func (r *Runner) Start(ctx context.Context) error { } }() - <-ctx.Done() + select { + case err = <-routerErrChan: + case <-ctx.Done(): + err = nil + } r.logger.Info("Shutting down runner") scheduler.Stop() - return nil + + return err } func (r *Runner) CheckAndRunJobs(ctx context.Context) error { @@ -173,6 +206,10 @@ func (r *Runner) CheckAndRunJobs(ctx context.Context) error { return nil } +func (r *Runner) Purge(ctx context.Context) error { + return r.providerManager.Purge() +} + func (r *Runner) runJob(ctx context.Context, j *models.Job) error { var job jobs.IJob diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index cdaebd60f3..c8ba99cef8 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -5,9 +5,7 @@ package builds import ( "context" - "errors" "io" - "time" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" @@ -168,31 +166,6 @@ func (s *BuildService) Delete(ctx context.Context, filter *services.BuildFilter, return errors } -func (s *BuildService) AwaitEmptyList(ctx context.Context, waitTime time.Duration) error { - timeout := time.NewTimer(waitTime) - defer timeout.Stop() - - for { - select { - case <-timeout.C: - return errors.New("awaiting empty build list timed out") - default: - builds, err := s.List(ctx, &services.BuildFilter{ - ShowDeleted: true, - }) - if err != nil { - return err - } - - if len(builds) == 0 { - return nil - } - - time.Sleep(time.Second) - } - } -} - func (s *BuildService) GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) { return s.loggerFactory.CreateLogReader(buildId) } diff --git a/pkg/server/headscale/server.go b/pkg/server/headscale/server.go index 19836d7f23..a959199f4a 100644 --- a/pkg/server/headscale/server.go +++ b/pkg/server/headscale/server.go @@ -126,10 +126,5 @@ func (s *HeadscaleServer) Stop() error { } func (s *HeadscaleServer) Purge() error { - err := s.Stop() - if err != nil { - return err - } - return os.RemoveAll(s.configDir) } diff --git a/pkg/server/log.go b/pkg/server/log.go index d8b244eaf8..aed0a48990 100644 --- a/pkg/server/log.go +++ b/pkg/server/log.go @@ -42,9 +42,9 @@ func (f *logFormatter) Format(entry *log.Entry) ([]byte, error) { func (s *Server) initLogs() error { rotatedLogFile := &lumberjack.Logger{ Filename: s.config.LogFile.Path, - MaxSize: s.config.LogFile.MaxSize, // megabytes - MaxBackups: s.config.LogFile.MaxBackups, - MaxAge: s.config.LogFile.MaxAge, // days + MaxSize: int(s.config.LogFile.MaxSize), // megabytes + MaxBackups: int(s.config.LogFile.MaxBackups), + MaxAge: int(s.config.LogFile.MaxAge), // days LocalTime: s.config.LogFile.LocalTime, Compress: s.config.LogFile.Compress, } diff --git a/pkg/server/purge.go b/pkg/server/purge.go deleted file mode 100644 index 47a048c88a..0000000000 --- a/pkg/server/purge.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package server - -import ( - "context" - "fmt" - "time" - - "github.com/daytonaio/daytona/pkg/services" - "github.com/daytonaio/daytona/pkg/telemetry" - log "github.com/sirupsen/logrus" -) - -func (s *Server) Purge(ctx context.Context, force bool) []error { - log.SetLevel(log.PanicLevel) - - telemetryEnabled := telemetry.TelemetryEnabled(ctx) - telemetryProps := map[string]interface{}{ - "force": force, - "server_id": s.Id, - } - - if telemetryEnabled { - err := s.TelemetryService.TrackServerEvent(telemetry.ServerEventPurgeStarted, telemetry.ClientId(ctx), telemetryProps) - if err != nil { - log.Trace(err) - } - } - - fmt.Println("Deleting all targets...") - - targets, err := s.TargetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) - if err != nil { - s.trackPurgeError(ctx, force, err) - if !force { - return []error{err} - } - } - - if err == nil { - for _, target := range targets { - err := s.TargetService.RemoveTarget(ctx, target.Id) - if err != nil { - s.trackPurgeError(ctx, force, err) - if !force { - return []error{err} - } else { - fmt.Printf("Failed to delete %s: %v\n", target.Name, err) - } - } else { - fmt.Printf("Target %s deleted\n", target.Name) - } - } - } else { - fmt.Printf("Failed to list targets: %v\n", err) - } - - // FIXME: todo - // fmt.Println("Purging providers...") - // err = s.ProviderManager.Purge() - // if err != nil { - // s.trackPurgeError(ctx, force, err) - // if !force { - // return []error{err} - // } else { - // fmt.Printf("Failed to purge providers: %v\n", err) - // } - // } - - fmt.Println("Purging builds...") - errs := s.BuildService.Delete(ctx, nil, force) - if len(errs) > 0 { - s.trackPurgeError(ctx, force, errs[0]) - if !force { - return errs - } else { - fmt.Printf("Failed to mark builds for deletion: %v\n", errs[0]) - } - } - - err = s.BuildService.AwaitEmptyList(ctx, time.Minute) - if err != nil { - s.trackPurgeError(ctx, force, err) - if !force { - return []error{err} - } else { - fmt.Printf("Failed to await empty build list: %v\n", err) - } - } - - if telemetryEnabled { - err := s.TelemetryService.TrackServerEvent(telemetry.ServerEventPurgeCompleted, telemetry.ClientId(ctx), telemetryProps) - if err != nil { - log.Trace(err) - } - } - - return nil -} - -func (s *Server) trackPurgeError(ctx context.Context, force bool, err error) { - telemetryEnabled := telemetry.TelemetryEnabled(ctx) - telemetryProps := map[string]interface{}{ - "server_id": s.Id, - "force": force, - "error": err.Error(), - } - - if telemetryEnabled { - err := s.TelemetryService.TrackServerEvent(telemetry.ServerEventPurgeError, telemetry.ClientId(ctx), telemetryProps) - if err != nil { - log.Trace(err) - } - } -} diff --git a/pkg/server/registry/service.go b/pkg/server/registry/service.go index b797c3efa0..5c02aaa548 100644 --- a/pkg/server/registry/service.go +++ b/pkg/server/registry/service.go @@ -174,11 +174,6 @@ func (s *LocalContainerRegistry) Stop() error { } func (s *LocalContainerRegistry) Purge() error { - err := s.Stop() - if err != nil { - return err - } - return os.RemoveAll(s.dataPath) } diff --git a/pkg/services/build.go b/pkg/services/build.go index a0090d855f..d92c4cf6a7 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -7,7 +7,6 @@ import ( "context" "errors" "io" - "time" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" @@ -19,7 +18,6 @@ type IBuildService interface { List(ctx context.Context, filter *BuildFilter) ([]*BuildDTO, error) Delete(ctx context.Context, filter *BuildFilter, force bool) []error HandleSuccessfulRemoval(ctx context.Context, id string) error - AwaitEmptyList(ctx context.Context, waitTime time.Duration) error GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) GetBuildLogWriter(ctx context.Context, buildId string) (io.WriteCloser, error) diff --git a/pkg/views/purge/purge_resources.go b/pkg/views/purge/purge_resources.go new file mode 100644 index 0000000000..aab59c9444 --- /dev/null +++ b/pkg/views/purge/purge_resources.go @@ -0,0 +1,52 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package purge + +import ( + "fmt" + "log" + "strings" + + "github.com/charmbracelet/huh" + "github.com/charmbracelet/lipgloss" + "github.com/daytonaio/daytona/pkg/views" +) + +func PurgeResourcesPrompt(continuePurge *bool, numOfTargets, numOfWorkspaces, numOfBuilds int) []string { + commands := []string{} + resources := []string{} + + if numOfBuilds > 0 { + resources = append(resources, fmt.Sprintf("builds: %d", numOfBuilds)) + commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona build remove -af")) + } + + if numOfWorkspaces > 0 { + resources = append(resources, fmt.Sprintf("workspaces: %d", numOfWorkspaces)) + commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona remove -afy")) + } + + if numOfTargets > 0 { + resources = append(resources, fmt.Sprintf("targets: %d", numOfTargets)) + commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona target remove -afy")) + } + + form := huh.NewForm( + huh.NewGroup( + huh.NewConfirm(). + Title(fmt.Sprintf("Leftover resources found: [%s]\nWould you like to continue with purge?", strings.Join(resources, ", "))). + Description("This action is irreversible."). + Affirmative("Continue"). + Negative("Abort"). + Value(continuePurge), + ), + ).WithTheme(views.GetCustomTheme()) + + err := form.Run() + if err != nil { + log.Fatal(err) + } + + return commands +} diff --git a/pkg/views/runner/config.go b/pkg/views/runner/config.go index c509b6222e..92c059f037 100644 --- a/pkg/views/runner/config.go +++ b/pkg/views/runner/config.go @@ -18,10 +18,12 @@ func RenderConfig(config *runner.Config, showKey bool) { output += fmt.Sprintf("%s %s", views.GetPropertyKey("Runner Name: "), config.Name) + "\n\n" - output += fmt.Sprintf("%s %s", views.GetPropertyKey("API URL: "), config.ServerApiUrl) + "\n\n" + output += fmt.Sprintf("%s %d", views.GetPropertyKey("Runner API Port: "), config.ApiPort) + "\n\n" + + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Server API URL: "), config.ServerApiUrl) + "\n\n" if showKey { - output += fmt.Sprintf("%s %s", views.GetPropertyKey("API Key: "), config.ServerApiKey) + "\n\n" + output += fmt.Sprintf("%s %s", views.GetPropertyKey("Server API Key: "), config.ServerApiKey) + "\n\n" } output += fmt.Sprintf("%s %s", views.GetPropertyKey("Providers Dir: "), config.ProvidersDir) + "\n\n" diff --git a/pkg/views/runner/configure.go b/pkg/views/runner/configure.go index 1a4edb505a..ab70444a32 100644 --- a/pkg/views/runner/configure.go +++ b/pkg/views/runner/configure.go @@ -15,6 +15,7 @@ import ( "github.com/charmbracelet/huh" "github.com/daytonaio/daytona/pkg/runner" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/util" ) type Model struct { @@ -45,6 +46,7 @@ func (m *Model) createForm() *huh.Form { logFileMaxSize := strconv.Itoa(int(m.config.LogFile.MaxSize)) logFileMaxBackups := strconv.Itoa(int(m.config.LogFile.MaxBackups)) logFileMaxAge := strconv.Itoa(int(m.config.LogFile.MaxAge)) + apiPort := strconv.Itoa(int(m.config.ApiPort)) return huh.NewForm( huh.NewGroup( @@ -56,6 +58,11 @@ func (m *Model) createForm() *huh.Form { Title("Name"). Description("Unique name set on the Daytona Server"). Value(&m.config.Name), + huh.NewInput(). + Title("Runner API Port"). + Description("Port used for exposing runner health-check endpoint"). + Value(&apiPort). + Validate(util.CreatePortValidator(&apiPort, &m.config.ApiPort)), huh.NewInput(). Title("Server API URL"). Value(&m.config.ServerApiUrl), @@ -88,16 +95,16 @@ func (m *Model) createForm() *huh.Form { Title("Log File Max Size"). Description("In megabytes"). Value(&logFileMaxSize). - Validate(createIntValidator(&logFileMaxSize, &m.config.LogFile.MaxSize)), + Validate(util.CreateIntValidator(&logFileMaxSize, &m.config.LogFile.MaxSize)), huh.NewInput(). Title("Log File Max Backups"). Value(&logFileMaxBackups). - Validate(createIntValidator(&logFileMaxBackups, &m.config.LogFile.MaxBackups)), + Validate(util.CreateIntValidator(&logFileMaxBackups, &m.config.LogFile.MaxBackups)), huh.NewInput(). Title("Log File Max Age"). Description("In days"). Value(&logFileMaxAge). - Validate(createIntValidator(&logFileMaxAge, &m.config.LogFile.MaxAge)), + Validate(util.CreateIntValidator(&logFileMaxAge, &m.config.LogFile.MaxAge)), huh.NewConfirm(). Title("Log File Local Time"). Description("Used for timestamping files. Default is UTC time."). @@ -181,20 +188,3 @@ func ConfigurationForm(config *runner.Config) (*runner.Config, error) { return nil, errors.New("no changes were made") } - -func createIntValidator(viewValue *string, value *int) func(string) error { - return func(string) error { - validateInt, err := strconv.Atoi(*viewValue) - if err != nil { - return errors.New("failed to parse int") - } - - if validateInt <= 0 { - return errors.New("int out of range") - } - - *value = int(validateInt) - - return nil - } -} diff --git a/pkg/views/server/configure.go b/pkg/views/server/configure.go index 58dbc5b2b8..7d03f2ed71 100644 --- a/pkg/views/server/configure.go +++ b/pkg/views/server/configure.go @@ -14,6 +14,7 @@ import ( "github.com/charmbracelet/huh" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views" + "github.com/daytonaio/daytona/pkg/views/util" ) type Model struct { @@ -89,7 +90,7 @@ func (m *Model) createForm() *huh.Form { huh.NewInput(). Title("Local Builder Registry Port"). Value(&localBuilderRegistryPort). - Validate(createPortValidator(m.config, &localBuilderRegistryPort, &m.config.LocalBuilderRegistryPort)), + Validate(util.CreateServerPortValidator(m.config, &localBuilderRegistryPort, &m.config.LocalBuilderRegistryPort)), huh.NewInput(). Title("Local Builder Registry Image"). Value(&m.config.LocalBuilderRegistryImage), @@ -104,11 +105,11 @@ func (m *Model) createForm() *huh.Form { huh.NewInput(). Title("API Port"). Value(&apiPortView). - Validate(createPortValidator(m.config, &apiPortView, &m.config.ApiPort)), + Validate(util.CreateServerPortValidator(m.config, &apiPortView, &m.config.ApiPort)), huh.NewInput(). Title("Headscale Port"). Value(&headscalePortView). - Validate(createPortValidator(m.config, &headscalePortView, &m.config.HeadscalePort)), + Validate(util.CreateServerPortValidator(m.config, &headscalePortView, &m.config.HeadscalePort)), huh.NewInput(). Title("Binaries Path"). Description("Directory will be created if it does not exist"). @@ -131,16 +132,16 @@ func (m *Model) createForm() *huh.Form { Title("Log File Max Size"). Description("In megabytes"). Value(&logFileMaxSize). - Validate(createIntValidator(&logFileMaxSize, &m.config.LogFile.MaxSize)), + Validate(util.CreateIntValidator(&logFileMaxSize, &m.config.LogFile.MaxSize)), huh.NewInput(). Title("Log File Max Backups"). Value(&logFileMaxBackups). - Validate(createIntValidator(&logFileMaxBackups, &m.config.LogFile.MaxBackups)), + Validate(util.CreateIntValidator(&logFileMaxBackups, &m.config.LogFile.MaxBackups)), huh.NewInput(). Title("Log File Max Age"). Description("In days"). Value(&logFileMaxAge). - Validate(createIntValidator(&logFileMaxAge, &m.config.LogFile.MaxAge)), + Validate(util.CreateIntValidator(&logFileMaxAge, &m.config.LogFile.MaxAge)), huh.NewConfirm(). Title("Log File Local Time"). Description("Used for timestamping files. Default is UTC time."). @@ -156,7 +157,7 @@ func (m *Model) createForm() *huh.Form { huh.NewInput(). Title("Frps Port"). Value(&frpsPortView). - Validate(createPortValidator(m.config, &frpsPortView, &m.config.Frps.Port)), + Validate(util.CreateServerPortValidator(m.config, &frpsPortView, &m.config.Frps.Port)), huh.NewInput(). Title("Frps Protocol"). Value(&m.config.Frps.Protocol), @@ -236,39 +237,3 @@ func ConfigurationForm(config *apiclient.ServerConfig) (*apiclient.ServerConfig, return nil, errors.New("no changes were made") } - -func createPortValidator(config *apiclient.ServerConfig, portView *string, port *int32) func(string) error { - return func(string) error { - validatePort, err := strconv.Atoi(*portView) - if err != nil { - return errors.New("failed to parse port") - } - if validatePort < 0 || validatePort > 65535 { - return errors.New("port out of range") - } - *port = int32(validatePort) - - if config.ApiPort == config.HeadscalePort { - return errors.New("port conflict") - } - - return nil - } -} - -func createIntValidator(viewValue *string, value *int32) func(string) error { - return func(string) error { - validateInt, err := strconv.Atoi(*viewValue) - if err != nil { - return errors.New("failed to parse int") - } - - if validateInt <= 0 { - return errors.New("int out of range") - } - - *value = int32(validateInt) - - return nil - } -} diff --git a/pkg/views/util/validators.go b/pkg/views/util/validators.go new file mode 100644 index 0000000000..b2a7e20e79 --- /dev/null +++ b/pkg/views/util/validators.go @@ -0,0 +1,62 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "errors" + "strconv" + + "github.com/daytonaio/daytona/pkg/apiclient" +) + +func CreateServerPortValidator(config *apiclient.ServerConfig, portView *string, port *int32) func(string) error { + return func(string) error { + validatePort, err := strconv.Atoi(*portView) + if err != nil { + return errors.New("failed to parse port") + } + if validatePort < 0 || validatePort > 65535 { + return errors.New("port out of range") + } + *port = int32(validatePort) + + if config.ApiPort == config.HeadscalePort { + return errors.New("port conflict") + } + + return nil + } +} + +func CreatePortValidator(portView *string, port *int32) func(string) error { + return func(string) error { + validatePort, err := strconv.Atoi(*portView) + if err != nil { + return errors.New("failed to parse port") + } + if validatePort < 0 || validatePort > 65535 { + return errors.New("port out of range") + } + *port = int32(validatePort) + + return nil + } +} + +func CreateIntValidator(viewValue *string, value *int32) func(string) error { + return func(string) error { + validateInt, err := strconv.Atoi(*viewValue) + if err != nil { + return errors.New("failed to parse int") + } + + if validateInt <= 0 { + return errors.New("int out of range") + } + + *value = int32(validateInt) + + return nil + } +} From e9d447170eeaa33956d5624f5df4dfeab9f4495c Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 13 Jan 2025 12:32:08 +0000 Subject: [PATCH 42/76] telemetry: refactor and add more events (#1691) - removed tracking API calls - added events for all resources Signed-off-by: Toma Puljak --- docs/daytona_runner_configure.md | 10 +- hack/docs/daytona_runner_configure.yaml | 5 + internal/util/apiclient/api_client.go | 3 +- pkg/api/controllers/runner/provider/update.go | 12 +- .../workspacetemplate/prebuild/prebuild.go | 2 +- pkg/api/docs/docs.go | 27 ++- pkg/api/docs/swagger.json | 27 ++- pkg/api/docs/swagger.yaml | 19 +- pkg/api/middlewares/telemetry.go | 79 -------- pkg/apiclient/README.md | 1 + pkg/apiclient/api/openapi.yaml | 26 ++- pkg/apiclient/api_provider.go | 22 +-- pkg/apiclient/docs/InstallProviderDTO.md | 23 ++- pkg/apiclient/docs/ProviderAPI.md | 10 +- pkg/apiclient/docs/UpdateProviderDTO.md | 72 +++++++ pkg/apiclient/model_install_provider_dto.go | 30 ++- pkg/apiclient/model_update_provider_dto.go | 184 ++++++++++++++++++ pkg/cmd/agentmode/agent_mode.go | 4 +- pkg/cmd/bootstrap/get_local_runner.go | 29 +-- pkg/cmd/bootstrap/get_remote_runner.go | 23 ++- pkg/cmd/bootstrap/get_server_instance.go | 38 +++- pkg/cmd/build/build.go | 1 + pkg/cmd/cmd.go | 107 +++++----- pkg/cmd/common/open_ide.go | 46 +++-- pkg/cmd/common/telemetry.go | 50 +++++ pkg/cmd/env/env.go | 1 + pkg/cmd/generatedocs.go | 1 + pkg/cmd/gitprovider/gitprovider.go | 1 + pkg/cmd/ide.go | 7 +- pkg/cmd/prebuild/prebuild.go | 1 + pkg/cmd/profile/profile.go | 1 + pkg/cmd/provider/install.go | 1 + pkg/cmd/provider/provider.go | 1 + pkg/cmd/provider/update.go | 9 +- pkg/cmd/purge.go | 52 +++-- pkg/cmd/runner/configure.go | 9 +- pkg/cmd/runner/runner.go | 1 + pkg/cmd/runner/serve.go | 2 + pkg/cmd/server/runner/register.go | 11 +- pkg/cmd/server/runner/unregister.go | 3 +- pkg/cmd/server/serve.go | 34 ++-- pkg/cmd/target/target.go | 1 + pkg/cmd/targetconfig/target_config.go | 1 + pkg/cmd/workspace/create/cmd.go | 16 +- pkg/cmd/workspace/list.go | 2 +- pkg/cmd/workspace/ssh-proxy.go | 3 +- .../workspacetemplate/workspacetemplate.go | 1 + pkg/common/local_docker_target_config.go | 16 ++ pkg/common/local_runner.go | 6 + pkg/jobs/build/build.go | 2 +- pkg/jobs/build/factory.go | 2 +- pkg/jobs/build/run.go | 4 - pkg/jobs/runner/factory.go | 2 +- pkg/jobs/runner/runner.go | 2 +- pkg/jobs/target/factory.go | 2 +- pkg/jobs/target/target.go | 2 +- pkg/jobs/workspace/factory.go | 2 +- pkg/jobs/workspace/workspace.go | 2 +- pkg/posthogservice/service.go | 41 ++-- pkg/runner/config.go | 11 +- pkg/runner/runner.go | 82 ++++++-- pkg/server/apikeys/apikeys.go | 30 ++- pkg/server/apikeys/service.go | 22 ++- pkg/server/apikeys/service_test.go | 4 + pkg/server/builds/create.go | 88 +++++++++ pkg/server/builds/service.go | 81 ++++---- pkg/server/builds/service_test.go | 4 + pkg/server/gitproviders/config.go | 33 +++- pkg/server/gitproviders/remove.go | 34 +++- pkg/server/gitproviders/service.go | 4 + pkg/server/jobs/service.go | 45 ++++- pkg/server/jobs/service_test.go | 4 + pkg/server/runners/provider.go | 101 ++++++++-- pkg/server/runners/register.go | 42 +++- pkg/server/runners/remove.go | 45 ++++- pkg/server/runners/service.go | 4 +- pkg/server/targetconfigs/service.go | 66 ++++++- pkg/server/targets/create.go | 11 +- pkg/server/targets/remove.go | 46 +++-- pkg/server/targets/service.go | 48 ++--- pkg/server/targets/start.go | 9 +- pkg/server/targets/stop.go | 10 +- pkg/server/workspaces/create.go | 12 +- pkg/server/workspaces/remove.go | 47 +++-- pkg/server/workspaces/service.go | 4 +- pkg/server/workspaces/service_test.go | 2 +- pkg/server/workspaces/start.go | 12 +- pkg/server/workspaces/stop.go | 12 +- pkg/server/workspacetemplates/prebuild.go | 152 --------------- .../workspacetemplates/prebuild_delete.go | 104 ++++++++++ .../workspacetemplates/prebuild_save.go | 119 +++++++++++ .../workspacetemplates/prebuild_test.go | 2 +- pkg/server/workspacetemplates/service.go | 46 ++++- pkg/services/runner.go | 10 +- pkg/services/workspace_template.go | 2 +- pkg/telemetry/api_key.go | 40 ++++ pkg/telemetry/build.go | 55 ++++++ pkg/telemetry/build_runner_events.go | 36 ---- pkg/telemetry/cli.go | 67 +++++++ pkg/telemetry/cli_events.go | 14 -- pkg/telemetry/constants.go | 9 +- pkg/telemetry/event.go | 32 +++ pkg/telemetry/git_provider_config.go | 49 +++++ pkg/telemetry/job.go | 54 +++++ pkg/telemetry/runner.go | 53 +++++ pkg/telemetry/server_events.go | 109 ----------- pkg/telemetry/target.go | 60 ++++++ pkg/telemetry/target_config.go | 51 +++++ pkg/telemetry/telemetry.go | 37 ++-- pkg/telemetry/workspace.go | 75 +++++++ pkg/telemetry/workspace_template.go | 60 ++++++ pkg/views/runner/configure.go | 3 + pkg/views/server/runner/notify.go | 7 +- 113 files changed, 2368 insertions(+), 883 deletions(-) create mode 100644 pkg/apiclient/docs/UpdateProviderDTO.md create mode 100644 pkg/apiclient/model_update_provider_dto.go create mode 100644 pkg/cmd/common/telemetry.go create mode 100644 pkg/common/local_docker_target_config.go create mode 100644 pkg/common/local_runner.go create mode 100644 pkg/server/builds/create.go create mode 100644 pkg/server/workspacetemplates/prebuild_delete.go create mode 100644 pkg/server/workspacetemplates/prebuild_save.go create mode 100644 pkg/telemetry/api_key.go create mode 100644 pkg/telemetry/build.go delete mode 100644 pkg/telemetry/build_runner_events.go create mode 100644 pkg/telemetry/cli.go delete mode 100644 pkg/telemetry/cli_events.go create mode 100644 pkg/telemetry/event.go create mode 100644 pkg/telemetry/git_provider_config.go create mode 100644 pkg/telemetry/job.go create mode 100644 pkg/telemetry/runner.go delete mode 100644 pkg/telemetry/server_events.go create mode 100644 pkg/telemetry/target.go create mode 100644 pkg/telemetry/target_config.go create mode 100644 pkg/telemetry/workspace.go create mode 100644 pkg/telemetry/workspace_template.go diff --git a/docs/daytona_runner_configure.md b/docs/daytona_runner_configure.md index e32c5f592e..f9743af8bc 100644 --- a/docs/daytona_runner_configure.md +++ b/docs/daytona_runner_configure.md @@ -9,10 +9,12 @@ daytona runner configure [flags] ### Options ``` - --api-key string Runner API Key - --api-url string Daytona Server API URL - --id string Runner ID - --name string Runner Name + --api-key string Runner API Key + --api-url string Daytona Server API URL + --client-id string Client ID + --disable-telemetry Disable telemetry + --id string Runner ID + --name string Runner Name ``` ### Options inherited from parent commands diff --git a/hack/docs/daytona_runner_configure.yaml b/hack/docs/daytona_runner_configure.yaml index 4e09afb182..d2bbdaedb6 100644 --- a/hack/docs/daytona_runner_configure.yaml +++ b/hack/docs/daytona_runner_configure.yaml @@ -6,6 +6,11 @@ options: usage: Runner API Key - name: api-url usage: Daytona Server API URL + - name: client-id + usage: Client ID + - name: disable-telemetry + default_value: "false" + usage: Disable telemetry - name: id usage: Runner ID - name: name diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index d412f201ef..496e999905 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -61,8 +61,9 @@ func GetApiClient(profile *config.Profile) (*apiclient.APIClient, error) { clientConfig.AddDefaultHeader(telemetry.ENABLED_HEADER, "true") clientConfig.AddDefaultHeader(telemetry.SESSION_ID_HEADER, internal.SESSION_ID) clientConfig.AddDefaultHeader(telemetry.CLIENT_ID_HEADER, config.GetClientId()) + if common.AgentMode() { - clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_WORKSPACE_SOURCE)) + clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_AGENT_MODE_SOURCE)) } else { clientConfig.AddDefaultHeader(telemetry.SOURCE_HEADER, string(telemetry.CLI_SOURCE)) } diff --git a/pkg/api/controllers/runner/provider/update.go b/pkg/api/controllers/runner/provider/update.go index 9f81fc3b49..b612bdaef1 100644 --- a/pkg/api/controllers/runner/provider/update.go +++ b/pkg/api/controllers/runner/provider/update.go @@ -18,9 +18,9 @@ import ( // @Tags provider // @Summary Update provider // @Description Update provider -// @Param downloadUrls body DownloadUrls true "Provider download URLs" -// @Param runnerId path string true "Runner ID" -// @Param providerName path string true "Provider name" +// @Param updateProviderDto body UpdateProviderDTO true "Update provider" +// @Param runnerId path string true "Runner ID" +// @Param providerName path string true "Provider name" // @Success 200 // @Router /runner/{runnerId}/provider/{providerName}/update [post] // @@ -29,8 +29,8 @@ func UpdateProvider(ctx *gin.Context) { runnerId := ctx.Param("runnerId") providerName := ctx.Param("providerName") - var downloadUrls services.DownloadUrls - err := ctx.BindJSON(&downloadUrls) + var updateProviderMetadataDto services.UpdateProviderDTO + err := ctx.BindJSON(&updateProviderMetadataDto) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) return @@ -38,7 +38,7 @@ func UpdateProvider(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.RunnerService.UpdateProvider(ctx.Request.Context(), runnerId, providerName, downloadUrls) + err = server.RunnerService.UpdateProvider(ctx.Request.Context(), runnerId, providerName, updateProviderMetadataDto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update provider: %w", err)) return diff --git a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go index 2d9bff556d..8e029442aa 100644 --- a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go @@ -72,7 +72,7 @@ func SetPrebuild(ctx *gin.Context) { } server := server.GetInstance(nil) - prebuild, err := server.WorkspaceTemplateService.SetPrebuild(ctx.Request.Context(), templateName, dto) + prebuild, err := server.WorkspaceTemplateService.SavePrebuild(ctx.Request.Context(), templateName, dto) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set prebuild: %s", err.Error())) return diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index c33b03fc1e..f3626c40c6 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1276,12 +1276,12 @@ const docTemplate = `{ "operationId": "UpdateProvider", "parameters": [ { - "description": "Provider download URLs", - "name": "downloadUrls", + "description": "Update provider", + "name": "updateProviderDto", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/DownloadUrls" + "$ref": "#/definitions/UpdateProviderDTO" } }, { @@ -4649,7 +4649,8 @@ const docTemplate = `{ "type": "object", "required": [ "downloadUrls", - "name" + "name", + "version" ], "properties": { "downloadUrls": { @@ -4657,6 +4658,9 @@ const docTemplate = `{ }, "name": { "type": "string" + }, + "version": { + "type": "string" } } }, @@ -5619,6 +5623,21 @@ const docTemplate = `{ } } }, + "UpdateProviderDTO": { + "type": "object", + "required": [ + "downloadUrls", + "version" + ], + "properties": { + "downloadUrls": { + "$ref": "#/definitions/DownloadUrls" + }, + "version": { + "type": "string" + } + } + }, "UpdateRunnerMetadataDTO": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 7624b620db..fe1383980d 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1273,12 +1273,12 @@ "operationId": "UpdateProvider", "parameters": [ { - "description": "Provider download URLs", - "name": "downloadUrls", + "description": "Update provider", + "name": "updateProviderDto", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/DownloadUrls" + "$ref": "#/definitions/UpdateProviderDTO" } }, { @@ -4646,7 +4646,8 @@ "type": "object", "required": [ "downloadUrls", - "name" + "name", + "version" ], "properties": { "downloadUrls": { @@ -4654,6 +4655,9 @@ }, "name": { "type": "string" + }, + "version": { + "type": "string" } } }, @@ -5616,6 +5620,21 @@ } } }, + "UpdateProviderDTO": { + "type": "object", + "required": [ + "downloadUrls", + "version" + ], + "properties": { + "downloadUrls": { + "$ref": "#/definitions/DownloadUrls" + }, + "version": { + "type": "string" + } + } + }, "UpdateRunnerMetadataDTO": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index cc2d2d6bcf..e8905c6448 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -633,9 +633,12 @@ definitions: $ref: '#/definitions/DownloadUrls' name: type: string + version: + type: string required: - downloadUrls - name + - version type: object Job: properties: @@ -1308,6 +1311,16 @@ definitions: required: - state type: object + UpdateProviderDTO: + properties: + downloadUrls: + $ref: '#/definitions/DownloadUrls' + version: + type: string + required: + - downloadUrls + - version + type: object UpdateRunnerMetadataDTO: properties: providers: @@ -2393,12 +2406,12 @@ paths: description: Update provider operationId: UpdateProvider parameters: - - description: Provider download URLs + - description: Update provider in: body - name: downloadUrls + name: updateProviderDto required: true schema: - $ref: '#/definitions/DownloadUrls' + $ref: '#/definitions/UpdateProviderDTO' - description: Runner ID in: path name: runnerId diff --git a/pkg/api/middlewares/telemetry.go b/pkg/api/middlewares/telemetry.go index e503d0fd61..19aa21d052 100644 --- a/pkg/api/middlewares/telemetry.go +++ b/pkg/api/middlewares/telemetry.go @@ -5,31 +5,14 @@ package middlewares import ( "context" - "strings" - "time" "github.com/daytonaio/daytona/internal" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/gin-gonic/gin" "github.com/google/uuid" - log "github.com/sirupsen/logrus" ) -var ignoreTelemetryPaths = map[string]bool{ - "/health": true, - "/target/:targetId/metadata": true, - "/target/:targetId": true, - "/workspace/:workspaceId/metadata": true, - "/workspace/:workspaceId": true, - "/runner/:runnerId/metadata": true, - "/runner/:runnerId": true, - "/server/network-key": true, - "/job/": true, - "/runner/:runnerId/jobs": true, - "/runner/:runnerId/jobs/:jobId/state": true, -} - func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.HandlerFunc { return func(ctx *gin.Context) { if telemetryService == nil { @@ -37,17 +20,6 @@ func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.Handle return } - if ctx.GetHeader(telemetry.ENABLED_HEADER) != "true" { - ctx.Next() - return - } - - reqUri := ctx.FullPath() - if ignoreTelemetryPaths[reqUri] { - ctx.Next() - return - } - clientId := ctx.GetHeader(telemetry.CLIENT_ID_HEADER) if clientId == "" { clientId = uuid.NewString() @@ -67,57 +39,6 @@ func TelemetryMiddleware(telemetryService telemetry.TelemetryService) gin.Handle ctx.Request = ctx.Request.WithContext(telemetryCtx) - source := ctx.GetHeader(telemetry.SOURCE_HEADER) - - reqMethod := ctx.Request.Method - - query := ctx.Request.URL.RawQuery - - remoteProfile := false - if source == string(telemetry.CLI_SOURCE) && !strings.Contains(ctx.Request.Host, "localhost") { - remoteProfile = true - } - - err := telemetryService.TrackServerEvent(telemetry.ServerEventApiRequestStarted, clientId, map[string]interface{}{ - "method": reqMethod, - "URI": reqUri, - "query": query, - "source": source, - "server_id": server.Id, - "session_id": sessionId, - "remote_profile": remoteProfile, - }) - if err != nil { - log.Trace(err) - } - - startTime := time.Now() - ctx.Next() - endTime := time.Now() - execTime := endTime.Sub(startTime) - statusCode := ctx.Writer.Status() - - properties := map[string]interface{}{ - "method": reqMethod, - "URI": reqUri, - "query": query, - "status": statusCode, - "source": source, - "exec time (µs)": execTime.Microseconds(), - "server_id": server.Id, - "session_id": sessionId, - "remote_profile": remoteProfile, - } - - if len(ctx.Errors) > 0 { - properties["error"] = ctx.Errors.String() - } - - err = telemetryService.TrackServerEvent(telemetry.ServerEventApiResponseSent, clientId, properties) - if err != nil { - log.Trace(err) - } - ctx.Next() } } diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index a3f6d088c0..fd067d530a 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -280,6 +280,7 @@ Class | Method | HTTP request | Description - [TargetDTO](docs/TargetDTO.md) - [TargetMetadata](docs/TargetMetadata.md) - [UpdateJobState](docs/UpdateJobState.md) + - [UpdateProviderDTO](docs/UpdateProviderDTO.md) - [UpdateRunnerMetadataDTO](docs/UpdateRunnerMetadataDTO.md) - [UpdateTargetMetadataDTO](docs/UpdateTargetMetadataDTO.md) - [UpdateTargetProviderMetadataDTO](docs/UpdateTargetProviderMetadataDTO.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index ef67d9eecc..e3950d9f25 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -934,8 +934,8 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/DownloadUrls' - description: Provider download URLs + $ref: '#/components/schemas/UpdateProviderDTO' + description: Update provider required: true responses: "200": @@ -944,7 +944,7 @@ paths: summary: Update provider tags: - provider - x-codegen-request-body-name: downloadUrls + x-codegen-request-body-name: updateProviderDto /sample: get: description: List samples @@ -3670,6 +3670,7 @@ components: downloadUrls: key: downloadUrls name: name + version: version properties: downloadUrls: additionalProperties: @@ -3677,9 +3678,12 @@ components: type: object name: type: string + version: + type: string required: - downloadUrls - name + - version type: object Job: example: @@ -5054,6 +5058,22 @@ components: required: - state type: object + UpdateProviderDTO: + example: + downloadUrls: + key: downloadUrls + version: version + properties: + downloadUrls: + additionalProperties: + type: string + type: object + version: + type: string + required: + - downloadUrls + - version + type: object UpdateRunnerMetadataDTO: example: runningJobs: 0 diff --git a/pkg/apiclient/api_provider.go b/pkg/apiclient/api_provider.go index df01d66586..b6870b6295 100644 --- a/pkg/apiclient/api_provider.go +++ b/pkg/apiclient/api_provider.go @@ -375,16 +375,16 @@ func (a *ProviderAPIService) UninstallProviderExecute(r ApiUninstallProviderRequ } type ApiUpdateProviderRequest struct { - ctx context.Context - ApiService *ProviderAPIService - runnerId string - providerName string - downloadUrls *map[string]string + ctx context.Context + ApiService *ProviderAPIService + runnerId string + providerName string + updateProviderDto *UpdateProviderDTO } -// Provider download URLs -func (r ApiUpdateProviderRequest) DownloadUrls(downloadUrls map[string]string) ApiUpdateProviderRequest { - r.downloadUrls = &downloadUrls +// Update provider +func (r ApiUpdateProviderRequest) UpdateProviderDto(updateProviderDto UpdateProviderDTO) ApiUpdateProviderRequest { + r.updateProviderDto = &updateProviderDto return r } @@ -431,8 +431,8 @@ func (a *ProviderAPIService) UpdateProviderExecute(r ApiUpdateProviderRequest) ( localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.downloadUrls == nil { - return nil, reportError("downloadUrls is required and must be specified") + if r.updateProviderDto == nil { + return nil, reportError("updateProviderDto is required and must be specified") } // to determine the Content-Type header @@ -453,7 +453,7 @@ func (a *ProviderAPIService) UpdateProviderExecute(r ApiUpdateProviderRequest) ( localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.downloadUrls + localVarPostBody = r.updateProviderDto if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/docs/InstallProviderDTO.md b/pkg/apiclient/docs/InstallProviderDTO.md index 0c62eab37b..d1dc4f7d84 100644 --- a/pkg/apiclient/docs/InstallProviderDTO.md +++ b/pkg/apiclient/docs/InstallProviderDTO.md @@ -6,12 +6,13 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **DownloadUrls** | **map[string]string** | | **Name** | **string** | | +**Version** | **string** | | ## Methods ### NewInstallProviderDTO -`func NewInstallProviderDTO(downloadUrls map[string]string, name string, ) *InstallProviderDTO` +`func NewInstallProviderDTO(downloadUrls map[string]string, name string, version string, ) *InstallProviderDTO` NewInstallProviderDTO instantiates a new InstallProviderDTO object This constructor will assign default values to properties that have it defined, @@ -66,6 +67,26 @@ and a boolean to check if the value has been set. SetName sets Name field to given value. +### GetVersion + +`func (o *InstallProviderDTO) GetVersion() string` + +GetVersion returns the Version field if non-nil, zero value otherwise. + +### GetVersionOk + +`func (o *InstallProviderDTO) GetVersionOk() (*string, bool)` + +GetVersionOk returns a tuple with the Version field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetVersion + +`func (o *InstallProviderDTO) SetVersion(v string)` + +SetVersion sets Version field to given value. + + [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/pkg/apiclient/docs/ProviderAPI.md b/pkg/apiclient/docs/ProviderAPI.md index 13db2ba603..dff9ad3631 100644 --- a/pkg/apiclient/docs/ProviderAPI.md +++ b/pkg/apiclient/docs/ProviderAPI.md @@ -33,7 +33,7 @@ import ( func main() { runnerId := "runnerId_example" // string | Runner ID - installProviderDto := *openapiclient.NewInstallProviderDTO(map[string]string{"key": "Inner_example"}, "Name_example") // InstallProviderDTO | Install provider + installProviderDto := *openapiclient.NewInstallProviderDTO(map[string]string{"key": "Inner_example"}, "Name_example", "Version_example") // InstallProviderDTO | Install provider configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) @@ -220,7 +220,7 @@ Name | Type | Description | Notes ## UpdateProvider -> UpdateProvider(ctx, runnerId, providerName).DownloadUrls(downloadUrls).Execute() +> UpdateProvider(ctx, runnerId, providerName).UpdateProviderDto(updateProviderDto).Execute() Update provider @@ -241,11 +241,11 @@ import ( func main() { runnerId := "runnerId_example" // string | Runner ID providerName := "providerName_example" // string | Provider name - downloadUrls := map[string]string{"key": "Inner_example"} // map[string]string | Provider download URLs + updateProviderDto := *openapiclient.NewUpdateProviderDTO(map[string]string{"key": "Inner_example"}, "Version_example") // UpdateProviderDTO | Update provider configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ProviderAPI.UpdateProvider(context.Background(), runnerId, providerName).DownloadUrls(downloadUrls).Execute() + r, err := apiClient.ProviderAPI.UpdateProvider(context.Background(), runnerId, providerName).UpdateProviderDto(updateProviderDto).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `ProviderAPI.UpdateProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -271,7 +271,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **downloadUrls** | **map[string]string** | Provider download URLs | + **updateProviderDto** | [**UpdateProviderDTO**](UpdateProviderDTO.md) | Update provider | ### Return type diff --git a/pkg/apiclient/docs/UpdateProviderDTO.md b/pkg/apiclient/docs/UpdateProviderDTO.md new file mode 100644 index 0000000000..ba6164725c --- /dev/null +++ b/pkg/apiclient/docs/UpdateProviderDTO.md @@ -0,0 +1,72 @@ +# UpdateProviderDTO + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**DownloadUrls** | **map[string]string** | | +**Version** | **string** | | + +## Methods + +### NewUpdateProviderDTO + +`func NewUpdateProviderDTO(downloadUrls map[string]string, version string, ) *UpdateProviderDTO` + +NewUpdateProviderDTO instantiates a new UpdateProviderDTO object +This constructor will assign default values to properties that have it defined, +and makes sure properties required by API are set, but the set of arguments +will change when the set of required properties is changed + +### NewUpdateProviderDTOWithDefaults + +`func NewUpdateProviderDTOWithDefaults() *UpdateProviderDTO` + +NewUpdateProviderDTOWithDefaults instantiates a new UpdateProviderDTO object +This constructor will only assign default values to properties that have it defined, +but it doesn't guarantee that properties required by API are set + +### GetDownloadUrls + +`func (o *UpdateProviderDTO) GetDownloadUrls() map[string]string` + +GetDownloadUrls returns the DownloadUrls field if non-nil, zero value otherwise. + +### GetDownloadUrlsOk + +`func (o *UpdateProviderDTO) GetDownloadUrlsOk() (*map[string]string, bool)` + +GetDownloadUrlsOk returns a tuple with the DownloadUrls field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetDownloadUrls + +`func (o *UpdateProviderDTO) SetDownloadUrls(v map[string]string)` + +SetDownloadUrls sets DownloadUrls field to given value. + + +### GetVersion + +`func (o *UpdateProviderDTO) GetVersion() string` + +GetVersion returns the Version field if non-nil, zero value otherwise. + +### GetVersionOk + +`func (o *UpdateProviderDTO) GetVersionOk() (*string, bool)` + +GetVersionOk returns a tuple with the Version field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetVersion + +`func (o *UpdateProviderDTO) SetVersion(v string)` + +SetVersion sets Version field to given value. + + + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/pkg/apiclient/model_install_provider_dto.go b/pkg/apiclient/model_install_provider_dto.go index bf9863e53f..f449c902c1 100644 --- a/pkg/apiclient/model_install_provider_dto.go +++ b/pkg/apiclient/model_install_provider_dto.go @@ -23,6 +23,7 @@ var _ MappedNullable = &InstallProviderDTO{} type InstallProviderDTO struct { DownloadUrls map[string]string `json:"downloadUrls"` Name string `json:"name"` + Version string `json:"version"` } type _InstallProviderDTO InstallProviderDTO @@ -31,10 +32,11 @@ type _InstallProviderDTO InstallProviderDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewInstallProviderDTO(downloadUrls map[string]string, name string) *InstallProviderDTO { +func NewInstallProviderDTO(downloadUrls map[string]string, name string, version string) *InstallProviderDTO { this := InstallProviderDTO{} this.DownloadUrls = downloadUrls this.Name = name + this.Version = version return &this } @@ -94,6 +96,30 @@ func (o *InstallProviderDTO) SetName(v string) { o.Name = v } +// GetVersion returns the Version field value +func (o *InstallProviderDTO) GetVersion() string { + if o == nil { + var ret string + return ret + } + + return o.Version +} + +// GetVersionOk returns a tuple with the Version field value +// and a boolean to check if the value has been set. +func (o *InstallProviderDTO) GetVersionOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Version, true +} + +// SetVersion sets field value +func (o *InstallProviderDTO) SetVersion(v string) { + o.Version = v +} + func (o InstallProviderDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -106,6 +132,7 @@ func (o InstallProviderDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["downloadUrls"] = o.DownloadUrls toSerialize["name"] = o.Name + toSerialize["version"] = o.Version return toSerialize, nil } @@ -116,6 +143,7 @@ func (o *InstallProviderDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "downloadUrls", "name", + "version", } allProperties := make(map[string]interface{}) diff --git a/pkg/apiclient/model_update_provider_dto.go b/pkg/apiclient/model_update_provider_dto.go new file mode 100644 index 0000000000..7dd135aaa7 --- /dev/null +++ b/pkg/apiclient/model_update_provider_dto.go @@ -0,0 +1,184 @@ +/* +Daytona Server API + +Daytona Server API + +API version: v0.0.0-dev +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package apiclient + +import ( + "bytes" + "encoding/json" + "fmt" +) + +// checks if the UpdateProviderDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &UpdateProviderDTO{} + +// UpdateProviderDTO struct for UpdateProviderDTO +type UpdateProviderDTO struct { + DownloadUrls map[string]string `json:"downloadUrls"` + Version string `json:"version"` +} + +type _UpdateProviderDTO UpdateProviderDTO + +// NewUpdateProviderDTO instantiates a new UpdateProviderDTO object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewUpdateProviderDTO(downloadUrls map[string]string, version string) *UpdateProviderDTO { + this := UpdateProviderDTO{} + this.DownloadUrls = downloadUrls + this.Version = version + return &this +} + +// NewUpdateProviderDTOWithDefaults instantiates a new UpdateProviderDTO object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewUpdateProviderDTOWithDefaults() *UpdateProviderDTO { + this := UpdateProviderDTO{} + return &this +} + +// GetDownloadUrls returns the DownloadUrls field value +func (o *UpdateProviderDTO) GetDownloadUrls() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.DownloadUrls +} + +// GetDownloadUrlsOk returns a tuple with the DownloadUrls field value +// and a boolean to check if the value has been set. +func (o *UpdateProviderDTO) GetDownloadUrlsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.DownloadUrls, true +} + +// SetDownloadUrls sets field value +func (o *UpdateProviderDTO) SetDownloadUrls(v map[string]string) { + o.DownloadUrls = v +} + +// GetVersion returns the Version field value +func (o *UpdateProviderDTO) GetVersion() string { + if o == nil { + var ret string + return ret + } + + return o.Version +} + +// GetVersionOk returns a tuple with the Version field value +// and a boolean to check if the value has been set. +func (o *UpdateProviderDTO) GetVersionOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Version, true +} + +// SetVersion sets field value +func (o *UpdateProviderDTO) SetVersion(v string) { + o.Version = v +} + +func (o UpdateProviderDTO) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o UpdateProviderDTO) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["downloadUrls"] = o.DownloadUrls + toSerialize["version"] = o.Version + return toSerialize, nil +} + +func (o *UpdateProviderDTO) UnmarshalJSON(data []byte) (err error) { + // This validates that all required properties are included in the JSON object + // by unmarshalling the object into a generic map with string keys and checking + // that every required field exists as a key in the generic map. + requiredProperties := []string{ + "downloadUrls", + "version", + } + + allProperties := make(map[string]interface{}) + + err = json.Unmarshal(data, &allProperties) + + if err != nil { + return err + } + + for _, requiredProperty := range requiredProperties { + if _, exists := allProperties[requiredProperty]; !exists { + return fmt.Errorf("no value given for required property %v", requiredProperty) + } + } + + varUpdateProviderDTO := _UpdateProviderDTO{} + + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&varUpdateProviderDTO) + + if err != nil { + return err + } + + *o = UpdateProviderDTO(varUpdateProviderDTO) + + return err +} + +type NullableUpdateProviderDTO struct { + value *UpdateProviderDTO + isSet bool +} + +func (v NullableUpdateProviderDTO) Get() *UpdateProviderDTO { + return v.value +} + +func (v *NullableUpdateProviderDTO) Set(val *UpdateProviderDTO) { + v.value = val + v.isSet = true +} + +func (v NullableUpdateProviderDTO) IsSet() bool { + return v.isSet +} + +func (v *NullableUpdateProviderDTO) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableUpdateProviderDTO(val *UpdateProviderDTO) *NullableUpdateProviderDTO { + return &NullableUpdateProviderDTO{value: val, isSet: true} +} + +func (v NullableUpdateProviderDTO) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableUpdateProviderDTO) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/cmd/agentmode/agent_mode.go b/pkg/cmd/agentmode/agent_mode.go index b70428bc91..187d9c3dee 100644 --- a/pkg/cmd/agentmode/agent_mode.go +++ b/pkg/cmd/agentmode/agent_mode.go @@ -45,7 +45,7 @@ func Execute() error { telemetryEnabled := config.TelemetryEnabled() startTime := time.Now() - telemetryService, command, flags, isComplete, err := cmd.PreRun(agentModeRootCmd, os.Args[1:], telemetryEnabled, clientId, startTime) + command, flags, isComplete, err := cmd.PreRun(agentModeRootCmd, os.Args[1:], telemetryEnabled, clientId, startTime) if err != nil { return err } @@ -54,7 +54,7 @@ func Execute() error { endTime := time.Now() if !isComplete { - cmd.PostRun(command, err, telemetryService, clientId, startTime, endTime, flags) + cmd.PostRun(command, err, clientId, startTime, endTime, flags) } return err diff --git a/pkg/cmd/bootstrap/get_local_runner.go b/pkg/cmd/bootstrap/get_local_runner.go index e7ced8c21d..52212178cb 100644 --- a/pkg/cmd/bootstrap/get_local_runner.go +++ b/pkg/cmd/bootstrap/get_local_runner.go @@ -34,8 +34,6 @@ import ( log "github.com/sirupsen/logrus" ) -const LOCAL_RUNNER_ID = "local" - type LocalRunnerParams struct { ServerConfig *server.Config RunnerConfig *runner.Config @@ -53,7 +51,7 @@ type LocalJobFactoryParams struct { func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { loggerFactory := logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetRunnerLogsDir(params.ConfigDir)}) - runnerLogger, err := loggerFactory.CreateLogger(LOCAL_RUNNER_ID, LOCAL_RUNNER_ID, logs.LogSourceRunner) + runnerLogger, err := loggerFactory.CreateLogger(common.LOCAL_RUNNER_ID, common.LOCAL_RUNNER_ID, logs.LogSourceRunner) if err != nil { return nil, err } @@ -99,8 +97,8 @@ func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { } runnerJobFactory := jobs_runner.NewRunnerJobFactory(jobs_runner.RunnerJobFactoryConfig{ - TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackBuildRunnerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, ProviderManager: providerManager, }) @@ -112,21 +110,24 @@ func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { RegistryUrl: params.ServerConfig.RegistryUrl, ListPendingJobs: func(ctx context.Context) ([]*models.Job, int, error) { jobs, err := jobService.List(ctx, &stores.JobFilter{ - RunnerIdOrIsNil: util.Pointer(LOCAL_RUNNER_ID), + RunnerIdOrIsNil: util.Pointer(common.LOCAL_RUNNER_ID), States: &[]models.JobState{models.JobStatePending}, }) return jobs, 0, err }, - UpdateJobState: func(ctx context.Context, jobId string, state models.JobState, err *error) error { + UpdateJobState: func(ctx context.Context, jobId string, state models.JobState, err error) error { var jobErr *string if err != nil { - jobErr = util.Pointer((*err).Error()) + jobErr = util.Pointer(err.Error()) } return jobService.SetState(ctx, jobId, services.UpdateJobStateDTO{ State: state, ErrorMessage: jobErr, }) }, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) + }, SetRunnerMetadata: func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error { return runnerService.SetRunnerMetadata(context.Background(), runnerId, &models.RunnerMetadata{ Uptime: uint64(metadata.Uptime), @@ -179,8 +180,8 @@ func getLocalWorkspaceJobFactory(params LocalJobFactoryParams) (workspace.IWorks return util.MergeEnvVars(serverEnvVars, w.EnvVars), nil }, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackServerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, LoggerFactory: workspaceLogsFactory, ProviderManager: params.ProviderManager, @@ -205,8 +206,8 @@ func getLocalTargetJobFactory(params LocalJobFactoryParams) (target.ITargetJobFa return targetService.HandleSuccessfulCreation(ctx, targetId) }, UpdateTargetProviderMetadata: targetService.UpdateTargetProviderMetadata, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackServerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, LoggerFactory: loggerFactory, ProviderManager: params.ProviderManager, @@ -289,8 +290,8 @@ func getLocalBuildJobFactory(params LocalJobFactoryParams) (jobs_build.IBuildJob DeleteImage: func(ctx context.Context, image string, force bool) error { return dockerClient.DeleteImage(image, force, nil) }, - TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackBuildRunnerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, LoggerFactory: buildLogsFactory, BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ diff --git a/pkg/cmd/bootstrap/get_remote_runner.go b/pkg/cmd/bootstrap/get_remote_runner.go index c4e6beb4d7..f6e2506ea4 100644 --- a/pkg/cmd/bootstrap/get_remote_runner.go +++ b/pkg/cmd/bootstrap/get_remote_runner.go @@ -102,8 +102,8 @@ func GetRemoteRunner(params RemoteRunnerParams) (runner.IRunner, error) { } runnerJobFactory := jobs_runner.NewRunnerJobFactory(jobs_runner.RunnerJobFactoryConfig{ - TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackRunnerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, ProviderManager: providerManager, }) @@ -141,10 +141,13 @@ func GetRemoteRunner(params RemoteRunnerParams) (runner.IRunner, error) { } return response, res.StatusCode, nil }, - UpdateJobState: func(ctx context.Context, jobId string, state models.JobState, jobError *error) error { + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) + }, + UpdateJobState: func(ctx context.Context, jobId string, state models.JobState, jobError error) error { var jobErr *string if jobError != nil { - jobErr = util.Pointer((*jobError).Error()) + jobErr = util.Pointer(jobError.Error()) } _, err := params.ApiClient.RunnerAPI.UpdateJobState(ctx, params.RunnerConfig.Id, jobId).UpdateJobState(apiclient.UpdateJobState{ State: apiclient.JobState(state), @@ -306,8 +309,8 @@ func getRemoteWorkspaceJobFactory(params RemoteJobFactoryParams) (workspace.IWor return util.MergeEnvVars(envVarsMap, w.EnvVars), nil }, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackServerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, LoggerFactory: loggerFactory, ProviderManager: params.ProviderManager, @@ -342,8 +345,8 @@ func getRemoteTargetJobFactory(params RemoteJobFactoryParams) (target.ITargetJob }).Execute() return err }, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackServerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, LoggerFactory: loggerFactory, ProviderManager: params.ProviderManager, @@ -458,8 +461,8 @@ func getRemoteBuildJobFactory(params RemoteJobFactoryParams) (jobs_build.IBuildJ DeleteImage: func(ctx context.Context, image string, force bool) error { return dockerClient.DeleteImage(image, force, nil) }, - TrackTelemetryEvent: func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error { - return params.TelemetryService.TrackBuildRunnerEvent(event, clientId, props) + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return params.TelemetryService.Track(event, clientId) }, LoggerFactory: loggerFactory, BuilderFactory: build.NewBuilderFactory(build.BuilderFactoryConfig{ diff --git a/pkg/cmd/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go index 519710f9ab..80ebcb17dd 100644 --- a/pkg/cmd/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -135,10 +135,16 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return nil }, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) jobService := jobs.NewJobService(jobs.JobServiceConfig{ JobStore: jobStore, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) buildService := builds.NewBuildService(builds.BuildServiceConfig{ @@ -169,6 +175,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }) }, LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetBuildLogsDir(configDir)}), + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) prebuildWebhookEndpoint := fmt.Sprintf("%s%s", util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), constants.WEBHOOK_EVENT_ROUTE) @@ -242,6 +251,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return gitProvider.GetCommitsRange(repo, initialSha, currentSha) }, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) err = workspaceTemplateService.StartRetentionPoller(context.Background()) @@ -275,6 +287,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe targetConfigService := targetconfigs.NewTargetConfigService(targetconfigs.TargetConfigServiceConfig{ TargetConfigStore: targetConfigStore, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) apiKeyService := apikeys.NewApiKeyService(apikeys.ApiKeyServiceConfig{ @@ -285,6 +300,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe GetKeyHash: func(key string) string { return apikey_util.HashKey(key) }, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) headscaleUrl := util.GetFrpcHeadscaleUrl(c.Frps.Protocol, c.Id, c.Frps.Domain) @@ -310,11 +328,13 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe State: models.JobStatePending, }) }, - ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), - ServerVersion: version, - ServerUrl: headscaleUrl, - LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetTargetLogsDir(configDir)}), - TelemetryService: telemetryService, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, + ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), + ServerVersion: version, + ServerUrl: headscaleUrl, + LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: server.GetTargetLogsDir(configDir)}), }) workspaceService := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ @@ -382,7 +402,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe State: models.JobStatePending, }) }, - TrackTelemetryEvent: telemetryService.TrackServerEvent, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, ServerApiUrl: util.GetFrpcApiUrl(c.Frps.Protocol, c.Id, c.Frps.Domain), ServerVersion: version, ServerUrl: headscaleUrl, @@ -440,7 +462,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe } return nil }, - TrackTelemetryEvent: telemetryService.TrackServerEvent, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return telemetryService.Track(event, clientId) + }, }) s := server.GetInstance(&server.ServerInstanceConfig{ diff --git a/pkg/cmd/build/build.go b/pkg/cmd/build/build.go index d8b128b0eb..e4c7d7bf01 100644 --- a/pkg/cmd/build/build.go +++ b/pkg/cmd/build/build.go @@ -12,6 +12,7 @@ var BuildCmd = &cobra.Command{ Use: "build", Aliases: []string{"builds"}, Short: "Manage builds", + Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, } diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index 1a6036b1e3..c961eec1c8 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -12,11 +12,11 @@ import ( "time" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal" . "github.com/daytonaio/daytona/internal/util" . "github.com/daytonaio/daytona/pkg/cmd/apikey" . "github.com/daytonaio/daytona/pkg/cmd/autocomplete" . "github.com/daytonaio/daytona/pkg/cmd/build" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" . "github.com/daytonaio/daytona/pkg/cmd/env" . "github.com/daytonaio/daytona/pkg/cmd/gitprovider" . "github.com/daytonaio/daytona/pkg/cmd/ports" @@ -32,7 +32,6 @@ import ( . "github.com/daytonaio/daytona/pkg/cmd/workspace/create" . "github.com/daytonaio/daytona/pkg/cmd/workspacetemplate" "github.com/daytonaio/daytona/pkg/common" - "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/telemetry" view "github.com/daytonaio/daytona/pkg/views/initial" log "github.com/sirupsen/logrus" @@ -95,7 +94,7 @@ func Execute() error { clientId := config.GetClientId() telemetryEnabled := config.TelemetryEnabled() - telemetryService, cmd, flags, isCompletion, err := PreRun(rootCmd, os.Args[1:], telemetryEnabled, clientId, startTime) + cmd, flags, isCompletion, err := PreRun(rootCmd, os.Args[1:], telemetryEnabled, clientId, startTime) if err != nil { fmt.Printf("Error: %v\n\n", err) return cmd.Help() @@ -106,7 +105,7 @@ func Execute() error { endTime := time.Now() if !isCompletion { - PostRun(cmd, err, telemetryService, clientId, startTime, endTime, flags) + PostRun(cmd, err, clientId, startTime, endTime, flags) } return err @@ -205,58 +204,27 @@ func RunInitialScreenFlow(cmd *cobra.Command, args []string) error { return nil } -func GetCmdTelemetryData(cmd *cobra.Command, flags []string) map[string]interface{} { - path := cmd.CommandPath() - - // Trim daytona from the path if a non-root command was invoked - // This prevents a `daytona` pileup in the telemetry data - if path != "daytona" { - path = strings.TrimPrefix(path, "daytona ") - } - - source := telemetry.CLI_SOURCE - if common.AgentMode() { - source = telemetry.CLI_WORKSPACE_SOURCE - } - - calledAs := cmd.CalledAs() - - data := telemetry.AdditionalData - data["command"] = path - data["called_as"] = calledAs - data["source"] = source - data["flags"] = flags - - return data -} - -func PreRun(rootCmd *cobra.Command, args []string, telemetryEnabled bool, clientId string, startTime time.Time) (telemetry.TelemetryService, *cobra.Command, []string, bool, error) { - var telemetryService telemetry.TelemetryService - - if telemetryEnabled { - telemetryService = posthogservice.NewTelemetryService(posthogservice.PosthogServiceConfig{ - ApiKey: internal.PosthogApiKey, - Endpoint: internal.PosthogEndpoint, - Version: internal.Version, - }) - } - +func PreRun(rootCmd *cobra.Command, args []string, telemetryEnabled bool, clientId string, startTime time.Time) (*cobra.Command, []string, bool, error) { cmd, flags, isCompletion, err := validateCommands(rootCmd, os.Args[1:]) if err != nil && !isCompletion { - if telemetryEnabled && !strings.HasSuffix(cmd.CommandPath(), "daemon-serve") { - props := GetCmdTelemetryData(cmd, flags) - err := telemetryService.TrackCliEvent(telemetry.CliEventInvalidCmd, clientId, props) + if !shouldIgnoreCommand(cmd.CommandPath()) { + event := telemetry.NewCliEvent(telemetry.CliEventCommandInvalid, cmd, flags, err, nil) + err := cmd_common.TrackTelemetryEvent(event, clientId) + if err != nil { + log.Trace(err) + } + err = cmd_common.CloseTelemetryService() if err != nil { log.Trace(err) } - telemetryService.Close() } - return telemetryService, cmd, flags, isCompletion, err + return cmd, flags, isCompletion, err } - if telemetryEnabled && !strings.HasSuffix(cmd.CommandPath(), "daemon-serve") && !isCompletion { - err := telemetryService.TrackCliEvent(telemetry.CliEventCmdStart, clientId, GetCmdTelemetryData(cmd, flags)) + if !shouldIgnoreCommand(cmd.CommandPath()) && !isCompletion { + event := telemetry.NewCliEvent(telemetry.CliEventCommandStarted, cmd, flags, nil, nil) + err := cmd_common.TrackTelemetryEvent(event, clientId) if err != nil { log.Trace(err) } @@ -268,36 +236,55 @@ func PreRun(rootCmd *cobra.Command, args []string, telemetryEnabled bool, client for range interruptChannel { endTime := time.Now() execTime := endTime.Sub(startTime) - props := GetCmdTelemetryData(cmd, flags) - props["exec time (µs)"] = execTime.Microseconds() - props["error"] = "interrupted" + extras := map[string]interface{}{"exec_time_µs": execTime.Microseconds()} + event := telemetry.NewCliEvent(telemetry.CliEventCommandInterrupted, cmd, flags, nil, extras) + err := cmd_common.TrackTelemetryEvent(event, clientId) + if err != nil { + log.Trace(err) + } - err := telemetryService.TrackCliEvent(telemetry.CliEventCmdEnd, clientId, props) + err = cmd_common.CloseTelemetryService() if err != nil { log.Trace(err) } - telemetryService.Close() os.Exit(0) } }() } - return telemetryService, cmd, flags, isCompletion, nil + return cmd, flags, isCompletion, nil } -func PostRun(cmd *cobra.Command, cmdErr error, telemetryService telemetry.TelemetryService, clientId string, startTime time.Time, endTime time.Time, flags []string) { - if telemetryService != nil && !strings.HasSuffix(cmd.CommandPath(), "daemon-serve") { +func PostRun(cmd *cobra.Command, cmdErr error, clientId string, startTime time.Time, endTime time.Time, flags []string) { + if !shouldIgnoreCommand(cmd.CommandPath()) { execTime := endTime.Sub(startTime) - props := GetCmdTelemetryData(cmd, flags) - props["exec time (µs)"] = execTime.Microseconds() + extras := map[string]interface{}{"exec_time_µs": execTime.Microseconds()} + eventName := telemetry.CliEventCommandCompleted if cmdErr != nil { - props["error"] = cmdErr.Error() + eventName = telemetry.CliEventCommandFailed + } + event := telemetry.NewCliEvent(eventName, cmd, flags, cmdErr, extras) + + err := cmd_common.TrackTelemetryEvent(event, clientId) + if err != nil { + log.Trace(err) } - err := telemetryService.TrackCliEvent(telemetry.CliEventCmdEnd, clientId, props) + err = cmd_common.CloseTelemetryService() if err != nil { log.Trace(err) } - telemetryService.Close() } } + +func shouldIgnoreCommand(commandPath string) bool { + ignoredPaths := []string{"daemon-serve", "ssh-proxy"} + + for _, ignoredPath := range ignoredPaths { + if strings.HasSuffix(commandPath, ignoredPath) { + return true + } + } + + return false +} diff --git a/pkg/cmd/common/open_ide.go b/pkg/cmd/common/open_ide.go index cb600b9ba3..e74bee2cb9 100644 --- a/pkg/cmd/common/open_ide.go +++ b/pkg/cmd/common/open_ide.go @@ -10,42 +10,56 @@ import ( "github.com/daytonaio/daytona/internal/jetbrains" "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/telemetry" + + log "github.com/sirupsen/logrus" ) func OpenIDE(ideId string, activeProfile config.Profile, workspaceId string, workspaceProviderMetadata string, yesFlag bool, gpgKey *string) error { - telemetry.AdditionalData["ide"] = ideId - + var err error switch ideId { case "vscode": - return ide.OpenVSCode(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenVSCode(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "code-insiders": - return ide.OpenVSCodeInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenVSCodeInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "ssh": - return ide.OpenTerminalSsh(activeProfile, workspaceId, gpgKey, nil) + err = ide.OpenTerminalSsh(activeProfile, workspaceId, gpgKey, nil) case "browser": - return ide.OpenBrowserIDE(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenBrowserIDE(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "codium": - return ide.OpenVScodium(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenVScodium(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "codium-insiders": - return ide.OpenVScodiumInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenVScodiumInsiders(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "cursor": - return ide.OpenCursor(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenCursor(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "jupyter": - return ide.OpenJupyterIDE(activeProfile, workspaceId, workspaceProviderMetadata, yesFlag, gpgKey) + err = ide.OpenJupyterIDE(activeProfile, workspaceId, workspaceProviderMetadata, yesFlag, gpgKey) case "fleet": - return ide.OpenFleet(activeProfile, workspaceId, gpgKey) + err = ide.OpenFleet(activeProfile, workspaceId, gpgKey) case "positron": - return ide.OpenPositron(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenPositron(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) case "zed": - return ide.OpenZed(activeProfile, workspaceId, gpgKey) + err = ide.OpenZed(activeProfile, workspaceId, gpgKey) case "windsurf": - return ide.OpenWindsurf(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) + err = ide.OpenWindsurf(activeProfile, workspaceId, workspaceProviderMetadata, gpgKey) default: _, ok := jetbrains.GetIdes()[jetbrains.Id(ideId)] if ok { - return ide.OpenJetbrainsIDE(activeProfile, ideId, workspaceId, gpgKey) + err = ide.OpenJetbrainsIDE(activeProfile, ideId, workspaceId, gpgKey) + } else { + return errors.New("invalid IDE. Please choose one by running `daytona ide`") } } - return errors.New("invalid IDE. Please choose one by running `daytona ide`") + eventName := telemetry.CliEventWorkspaceOpened + if err != nil { + eventName = telemetry.CliEventWorkspaceOpenFailed + } + + event := telemetry.NewCliEvent(eventName, nil, []string{}, err, map[string]interface{}{"ide": ideId}) + telemetryErr := TrackTelemetryEvent(event, config.GetClientId()) + if telemetryErr != nil { + log.Trace(telemetryErr) + } + + return err } diff --git a/pkg/cmd/common/telemetry.go b/pkg/cmd/common/telemetry.go new file mode 100644 index 0000000000..f6a92a7ffc --- /dev/null +++ b/pkg/cmd/common/telemetry.go @@ -0,0 +1,50 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/internal" + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/posthogservice" + "github.com/daytonaio/daytona/pkg/telemetry" +) + +var telemetryService telemetry.TelemetryService + +func TrackTelemetryEvent(event telemetry.Event, clientId string) error { + if telemetryService == nil { + return nil + } + + return telemetryService.Track(event, clientId) +} + +func CloseTelemetryService() error { + if telemetryService == nil { + return nil + } + + return telemetryService.Close() +} + +func init() { + telemetryEnabled := config.TelemetryEnabled() + + if !telemetryEnabled { + return + } + + source := telemetry.CLI_SOURCE + if common.AgentMode() { + source = telemetry.CLI_AGENT_MODE_SOURCE + } + + telemetryService = posthogservice.NewTelemetryService(posthogservice.PosthogServiceConfig{ + ApiKey: internal.PosthogApiKey, + Endpoint: internal.PosthogEndpoint, + Version: internal.Version, + Source: source, + }) +} diff --git a/pkg/cmd/env/env.go b/pkg/cmd/env/env.go index 00d98fa445..2056ab35e4 100644 --- a/pkg/cmd/env/env.go +++ b/pkg/cmd/env/env.go @@ -11,6 +11,7 @@ import ( var EnvCmd = &cobra.Command{ Use: "env", Short: "Manage server environment variables that are added to all targets and workspaces", + Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, } diff --git a/pkg/cmd/generatedocs.go b/pkg/cmd/generatedocs.go index 2cbb4dca28..6ca84ab2a5 100644 --- a/pkg/cmd/generatedocs.go +++ b/pkg/cmd/generatedocs.go @@ -18,6 +18,7 @@ var defaultDirectory = "docs" var generateDocsCmd = &cobra.Command{ Use: "generate-docs", Short: "Generate documentation for the Daytona CLI", + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { directory, err := cmd.Flags().GetString("directory") if err != nil { diff --git a/pkg/cmd/gitprovider/gitprovider.go b/pkg/cmd/gitprovider/gitprovider.go index e65c51a81c..7cbd308d86 100644 --- a/pkg/cmd/gitprovider/gitprovider.go +++ b/pkg/cmd/gitprovider/gitprovider.go @@ -12,6 +12,7 @@ var GitProviderCmd = &cobra.Command{ Use: "git-providers", Aliases: []string{"git-provider", "gp"}, Short: "Manage Git providers", + Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, } diff --git a/pkg/cmd/ide.go b/pkg/cmd/ide.go index 788415f1fb..884e02a278 100644 --- a/pkg/cmd/ide.go +++ b/pkg/cmd/ide.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/jetbrains" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/cmd/common" ide_util "github.com/daytonaio/daytona/pkg/ide" "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" @@ -96,7 +97,11 @@ var ideCmd = &cobra.Command{ c.DefaultIdeId = chosenIde.Id - telemetry.AdditionalData["ide"] = chosenIde.Id + event := telemetry.NewCliEvent(telemetry.CliEventDefaultIdeSet, nil, []string{}, nil, map[string]interface{}{"ide": chosenIde.Id}) + telemetryErr := common.TrackTelemetryEvent(event, config.GetClientId()) + if telemetryErr != nil { + log.Trace(telemetryErr) + } err = c.Save() if err != nil { diff --git a/pkg/cmd/prebuild/prebuild.go b/pkg/cmd/prebuild/prebuild.go index 1cf24600bb..a5978ecaf6 100644 --- a/pkg/cmd/prebuild/prebuild.go +++ b/pkg/cmd/prebuild/prebuild.go @@ -12,6 +12,7 @@ var PrebuildCmd = &cobra.Command{ Use: "prebuild", Aliases: []string{"pb", "prebuilds"}, Short: "Manage prebuilds", + Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, } diff --git a/pkg/cmd/profile/profile.go b/pkg/cmd/profile/profile.go index 85fe58a491..6292f1a3ac 100644 --- a/pkg/cmd/profile/profile.go +++ b/pkg/cmd/profile/profile.go @@ -11,6 +11,7 @@ import ( var ProfileCmd = &cobra.Command{ Use: "profile", Short: "Manage profiles", + Args: cobra.NoArgs, GroupID: util.PROFILE_GROUP, } diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index 4153d544a2..c7e64068fa 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -126,6 +126,7 @@ func InstallProvider(apiClient *apiclient.APIClient, runnerId string, providerTo res, err := apiClient.ProviderAPI.InstallProvider(context.Background(), runnerId).InstallProviderDto(apiclient.InstallProviderDTO{ Name: providerToInstall.Name, DownloadUrls: downloadUrls, + Version: providerToInstall.Version, }).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/cmd/provider/provider.go b/pkg/cmd/provider/provider.go index 5c38d5a66d..1489af2ab0 100644 --- a/pkg/cmd/provider/provider.go +++ b/pkg/cmd/provider/provider.go @@ -11,6 +11,7 @@ import ( var ProviderCmd = &cobra.Command{ Use: "provider", Short: "Manage providers", + Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, } diff --git a/pkg/cmd/provider/update.go b/pkg/cmd/provider/update.go index 2f53dfd4cd..a996857db9 100644 --- a/pkg/cmd/provider/update.go +++ b/pkg/cmd/provider/update.go @@ -117,14 +117,19 @@ func updateProvider(runnerId string, providerName string, providersManifest *uti } version, ok := providerManifest.Versions["latest"] + versionName := "latest" if !ok { - _, latest := providerManifest.FindLatestVersion() + name, latest := providerManifest.FindLatestVersion() + versionName = name version = *latest } downloadUrls := convertOSToStringMap(version.DownloadUrls) - res, err := apiClient.ProviderAPI.UpdateProvider(context.Background(), runnerId, providerName).DownloadUrls(downloadUrls).Execute() + res, err := apiClient.ProviderAPI.UpdateProvider(context.Background(), runnerId, providerName).UpdateProviderDto(apiclient.UpdateProviderDTO{ + DownloadUrls: downloadUrls, + Version: versionName, + }).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index f65fbc45a7..c269afcb71 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -98,6 +98,7 @@ var purgeCmd = &cobra.Command{ ApiKey: internal.PosthogApiKey, Endpoint: internal.PosthogEndpoint, Version: internal.Version, + Source: telemetry.CLI_SOURCE, }) defer telemetryService.Close() @@ -179,12 +180,31 @@ var purgeCmd = &cobra.Command{ } } - err = purgeLocalRunnerProviders(ctx, serverConfig, serverConfigDir, telemetryService) + localRunnerConfig := server_cmd.GetLocalRunnerConfig(filepath.Join(serverConfigDir, "local-runner"), c.TelemetryEnabled, c.Id) + + params := bootstrap.LocalRunnerParams{ + ServerConfig: serverConfig, + RunnerConfig: localRunnerConfig, + ConfigDir: serverConfigDir, + TelemetryService: telemetryService, + } + + localRunner, err := bootstrap.GetLocalRunner(params) if err != nil { - if !forceFlag { - return err + return err + } + + if localRunner != nil { + fmt.Println("Purging providers...") + err = localRunner.Purge(ctx) + if err != nil { + if !forceFlag { + return err + } else { + fmt.Printf("Failed to purge local runner providers: %v\n", err) + } } else { - fmt.Printf("Failed to purge local runner providers: %v\n", err) + fmt.Println("Providers purged.") } } @@ -224,29 +244,7 @@ func init() { purgeCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete all targets by force") } -func purgeLocalRunnerProviders(ctx context.Context, serverConfig *server.Config, serverConfigDir string, telemetryService telemetry.TelemetryService) error { - localRunnerConfig := server_cmd.GetLocalRunnerConfig(filepath.Join(serverConfigDir, "local-runner")) - - params := bootstrap.LocalRunnerParams{ - ServerConfig: serverConfig, - RunnerConfig: localRunnerConfig, - ConfigDir: serverConfigDir, - TelemetryService: telemetryService, - } - - localRunner, err := bootstrap.GetLocalRunner(params) - if err != nil { - return err - } - - if localRunner != nil { - fmt.Println("Purging providers...") - err = localRunner.Purge(ctx) - if err != nil { - return err - } - fmt.Println("Providers purged.") - } +func purgeLocalRunnerProviders(ctx context.Context, serverConfig *server.Config, serverConfigDir string, cliConfig *config.Config, telemetryService telemetry.TelemetryService) error { return nil } diff --git a/pkg/cmd/runner/configure.go b/pkg/cmd/runner/configure.go index 0d0a3b7529..13fdaa7202 100644 --- a/pkg/cmd/runner/configure.go +++ b/pkg/cmd/runner/configure.go @@ -36,6 +36,7 @@ var configureCmd = &cobra.Command{ config.Name = nameFlag config.ServerApiUrl = apiUrlFlag config.ServerApiKey = apiKeyFlag + config.TelemetryEnabled = !telemetryDisabled } else { config, err = runner_view.ConfigurationForm(config) if err != nil { @@ -43,7 +44,9 @@ var configureCmd = &cobra.Command{ } } - config.ClientId = idFlag + if clientId != "" { + config.ClientId = clientId + } err = runner.Save(*config) if err != nil { @@ -67,10 +70,14 @@ var idFlag string var nameFlag string var apiUrlFlag string var apiKeyFlag string +var clientId string +var telemetryDisabled bool func init() { configureCmd.Flags().StringVar(&idFlag, "id", "", "Runner ID") configureCmd.Flags().StringVar(&nameFlag, "name", "", "Runner Name") configureCmd.Flags().StringVar(&apiUrlFlag, "api-url", "", "Daytona Server API URL") configureCmd.Flags().StringVar(&apiKeyFlag, "api-key", "", "Runner API Key") + configureCmd.Flags().StringVar(&clientId, "client-id", "", "Client ID") + configureCmd.Flags().BoolVar(&telemetryDisabled, "disable-telemetry", false, "Disable telemetry") } diff --git a/pkg/cmd/runner/runner.go b/pkg/cmd/runner/runner.go index dafb361c75..0372a2c188 100644 --- a/pkg/cmd/runner/runner.go +++ b/pkg/cmd/runner/runner.go @@ -11,6 +11,7 @@ import ( var RunnerCmd = &cobra.Command{ Use: "runner", Short: "Manage the runner", + Args: cobra.NoArgs, GroupID: util.RUNNER_GROUP, } diff --git a/pkg/cmd/runner/serve.go b/pkg/cmd/runner/serve.go index 2c5b6050a1..178e534cd9 100644 --- a/pkg/cmd/runner/serve.go +++ b/pkg/cmd/runner/serve.go @@ -13,6 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/cmd/bootstrap" "github.com/daytonaio/daytona/pkg/posthogservice" "github.com/daytonaio/daytona/pkg/runner" + "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -50,6 +51,7 @@ var serveCmd = &cobra.Command{ ApiKey: internal.PosthogApiKey, Endpoint: internal.PosthogEndpoint, Version: internal.Version, + Source: telemetry.RUNNER_SOURCE, }) apiClient, err := apiclient_util.GetRunnerApiClient(runnerConfig.ServerApiUrl, runnerConfig.ServerApiKey, runnerConfig.ClientId, runnerConfig.TelemetryEnabled) diff --git a/pkg/cmd/server/runner/register.go b/pkg/cmd/server/runner/register.go index 6cf9aa992d..971f46f8f9 100644 --- a/pkg/cmd/server/runner/register.go +++ b/pkg/cmd/server/runner/register.go @@ -6,11 +6,11 @@ package runner import ( "context" + "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/views/server/runner" - runner_view "github.com/daytonaio/daytona/pkg/views/server/runner" "github.com/docker/docker/pkg/stringid" "github.com/spf13/cobra" @@ -23,6 +23,11 @@ var registerCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() + c, err := config.GetConfig() + if err != nil { + return err + } + apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err @@ -49,7 +54,7 @@ var registerCmd = &cobra.Command{ id := stringid.GenerateRandomID() id = stringid.TruncateID(id) - runner, res, err := apiClient.RunnerAPI.RegisterRunner(ctx).Runner(apiclient.RegisterRunnerDTO{ + runnerDto, res, err := apiClient.RunnerAPI.RegisterRunner(ctx).Runner(apiclient.RegisterRunnerDTO{ Id: id, Name: name, }).Execute() @@ -63,7 +68,7 @@ var registerCmd = &cobra.Command{ } apiUrl := util.GetFrpcApiUrl(apiServerConfig.Frps.Protocol, apiServerConfig.Id, apiServerConfig.Frps.Domain) - runner_view.Notify(runner, apiUrl) + runner.Notify(runnerDto, apiUrl, c.Id, !c.TelemetryEnabled) return nil }, diff --git a/pkg/cmd/server/runner/unregister.go b/pkg/cmd/server/runner/unregister.go index 759179e75d..9af5591e46 100644 --- a/pkg/cmd/server/runner/unregister.go +++ b/pkg/cmd/server/runner/unregister.go @@ -11,7 +11,6 @@ import ( "github.com/charmbracelet/huh" "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/bootstrap" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" runner "github.com/daytonaio/daytona/pkg/views/server/runner/selection" @@ -69,7 +68,7 @@ var unregisterCmd = &cobra.Command{ selectedRunnerId = args[0] } - if selectedRunnerId == bootstrap.LOCAL_RUNNER_ID { + if selectedRunnerId == common.LOCAL_RUNNER_ID { return errors.New("to disable the local runner, use the 'daytona server configure' form") } diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 6bd2cc4baa..29b8bbb4cd 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -17,6 +17,7 @@ import ( "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/api" "github.com/daytonaio/daytona/pkg/cmd/bootstrap" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/posthogservice" @@ -26,6 +27,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/registry" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/daytonaio/daytona/pkg/views" started_view "github.com/daytonaio/daytona/pkg/views/server/started" @@ -66,10 +68,16 @@ var ServeCmd = &cobra.Command{ return err } + cliConfig, err := config.GetConfig() + if err != nil { + return err + } + telemetryService := posthogservice.NewTelemetryService(posthogservice.PosthogServiceConfig{ ApiKey: internal.PosthogApiKey, Endpoint: internal.PosthogEndpoint, Version: internal.Version, + Source: telemetry.SERVER_SOURCE, }) apiServer := api.NewApiServer(api.ApiServerConfig{ @@ -139,7 +147,7 @@ var ServeCmd = &cobra.Command{ localRunnerErrChan <- startLocalRunner(bootstrap.LocalRunnerParams{ ServerConfig: c, - RunnerConfig: GetLocalRunnerConfig(filepath.Join(configDir, "local-runner")), + RunnerConfig: GetLocalRunnerConfig(filepath.Join(configDir, "local-runner"), cliConfig.TelemetryEnabled, cliConfig.Id), ConfigDir: configDir, TelemetryService: telemetryService, }) @@ -240,12 +248,12 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { func startLocalRunner(params bootstrap.LocalRunnerParams) error { runnerService := server.GetInstance(nil).RunnerService - _, err := runnerService.GetRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + _, err := runnerService.GetRunner(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { if stores.IsRunnerNotFound(err) { _, err := runnerService.RegisterRunner(context.Background(), services.RegisterRunnerDTO{ - Id: bootstrap.LOCAL_RUNNER_ID, - Name: bootstrap.LOCAL_RUNNER_ID, + Id: common.LOCAL_RUNNER_ID, + Name: common.LOCAL_RUNNER_ID, }) if err != nil { return err @@ -263,15 +271,17 @@ func startLocalRunner(params bootstrap.LocalRunnerParams) error { return runner.Start(context.Background()) } -func GetLocalRunnerConfig(configDir string) *runner.Config { +func GetLocalRunnerConfig(configDir string, telemetryEnabled bool, clientId string) *runner.Config { providersDir := filepath.Join(configDir, "providers") logFilePath := filepath.Join(configDir, "runner.log") return &runner.Config{ - Id: bootstrap.LOCAL_RUNNER_ID, - Name: bootstrap.LOCAL_RUNNER_ID, - ProvidersDir: providersDir, - LogFile: logs.GetDefaultLogFileConfig(logFilePath), + Id: common.LOCAL_RUNNER_ID, + Name: common.LOCAL_RUNNER_ID, + ProvidersDir: providersDir, + LogFile: logs.GetDefaultLogFileConfig(logFilePath), + TelemetryEnabled: telemetryEnabled, + ClientId: clientId, } } @@ -280,7 +290,7 @@ func awaitLocalRunnerStarted() error { startTime := time.Now() for { - r, err := server.RunnerService.GetRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + r, err := server.RunnerService.GetRunner(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { return err } @@ -303,12 +313,12 @@ func awaitLocalRunnerStarted() error { func handleDisabledLocalRunner() error { runnerService := server.GetInstance(nil).RunnerService - _, err := runnerService.GetRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + _, err := runnerService.GetRunner(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { if stores.IsRunnerNotFound(err) { return nil } } - return runnerService.RemoveRunner(context.Background(), bootstrap.LOCAL_RUNNER_ID) + return runnerService.RemoveRunner(context.Background(), common.LOCAL_RUNNER_ID) } diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go index 131c11c9e5..61e01de385 100644 --- a/pkg/cmd/target/target.go +++ b/pkg/cmd/target/target.go @@ -11,6 +11,7 @@ import ( var TargetCmd = &cobra.Command{ Use: "target", Aliases: []string{"targets", "tg"}, + Args: cobra.NoArgs, Short: "Manage targets", GroupID: util.TARGET_GROUP, } diff --git a/pkg/cmd/targetconfig/target_config.go b/pkg/cmd/targetconfig/target_config.go index 71f08b1f9b..d5682f8c88 100644 --- a/pkg/cmd/targetconfig/target_config.go +++ b/pkg/cmd/targetconfig/target_config.go @@ -12,6 +12,7 @@ var TargetConfigCmd = &cobra.Command{ Use: "target-config", Aliases: []string{"tc"}, Short: "Manage target configs", + Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index 1415c11d72..fd0c5367e8 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -16,7 +16,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/bootstrap" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/logs" @@ -189,7 +188,7 @@ var CreateCmd = &cobra.Command{ } var tsConn *tsnet.Server - if !IsLocalDockerTarget(target) || activeProfile.Id != "default" { + if !common.IsLocalDockerTarget(target.TargetConfig.ProviderInfo.Name, target.TargetConfig.Options, target.TargetConfig.ProviderInfo.RunnerId) || activeProfile.Id != "default" { tsConn, err = tailscale.GetConnection(&activeProfile) if err != nil { return err @@ -219,9 +218,6 @@ var CreateCmd = &cobra.Command{ } } - if err != nil { - return apiclient_util.HandleErrorResponse(res, err) - } gpgKey, err := cmd_common.GetGitProviderGpgKey(apiClient, ctx, createWorkspaceDtos[0].GitProviderConfigId) if err != nil { log.Warn(err) @@ -317,7 +313,7 @@ func init() { } func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile *config.Profile, tsConn *tsnet.Server, gpgKey *string) error { - if IsLocalDockerTarget(target) && (activeProfile != nil && activeProfile.Id == "default") { + if common.IsLocalDockerTarget(target.TargetConfig.ProviderInfo.Name, target.TargetConfig.Options, target.TargetConfig.ProviderInfo.RunnerId) && (activeProfile != nil && activeProfile.Id == "default") { err := config.EnsureSshConfigEntryAdded(activeProfile.Id, workspaceId, gpgKey) if err != nil { return err @@ -370,11 +366,3 @@ func waitForDial(target *apiclient.TargetDTO, workspaceId string, activeProfile return err } } - -func IsLocalDockerTarget(target *apiclient.TargetDTO) bool { - if target.TargetConfig.ProviderInfo.Name != "docker-provider" { - return false - } - - return !strings.Contains(target.TargetConfig.Options, "Remote Hostname") && target.TargetConfig.ProviderInfo.RunnerId == bootstrap.LOCAL_RUNNER_ID -} diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 150f4c33c9..42e9390fcd 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -17,7 +17,7 @@ import ( var ListCmd = &cobra.Command{ Use: "list", Short: "List workspaces", - Args: cobra.ExactArgs(0), + Args: cobra.NoArgs, Aliases: []string{"ls"}, GroupID: util.TARGET_GROUP, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/pkg/cmd/workspace/ssh-proxy.go b/pkg/cmd/workspace/ssh-proxy.go index 2a146ced2b..0fa5385c29 100644 --- a/pkg/cmd/workspace/ssh-proxy.go +++ b/pkg/cmd/workspace/ssh-proxy.go @@ -17,7 +17,6 @@ import ( "github.com/daytonaio/daytona/internal/util/apiclient/conversion" ssh_config "github.com/daytonaio/daytona/pkg/agent/ssh/config" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/docker" "github.com/daytonaio/daytona/pkg/models" @@ -66,7 +65,7 @@ var SshProxyCmd = &cobra.Command{ } } - if ws != nil && create.IsLocalDockerTarget(target) && profile.Id == "default" { + if ws != nil && common.IsLocalDockerTarget(target.TargetConfig.ProviderInfo.Name, target.TargetConfig.Options, target.TargetConfig.ProviderInfo.RunnerId) && profile.Id == "default" { // If the target is local, we directly access the ssh port through the container cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) diff --git a/pkg/cmd/workspacetemplate/workspacetemplate.go b/pkg/cmd/workspacetemplate/workspacetemplate.go index 1fe22b7c67..eb1e01be34 100644 --- a/pkg/cmd/workspacetemplate/workspacetemplate.go +++ b/pkg/cmd/workspacetemplate/workspacetemplate.go @@ -11,6 +11,7 @@ import ( var WorkspaceTemplateCmd = &cobra.Command{ Use: "template", Short: "Manage workspace templates", + Args: cobra.NoArgs, Aliases: []string{"templates", "workspace-template", "workspace-templates", "wt"}, GroupID: util.TARGET_GROUP, } diff --git a/pkg/common/local_docker_target_config.go b/pkg/common/local_docker_target_config.go new file mode 100644 index 0000000000..3f03e24708 --- /dev/null +++ b/pkg/common/local_docker_target_config.go @@ -0,0 +1,16 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +import ( + "strings" +) + +func IsLocalDockerTarget(providerName, options, runnerId string) bool { + if providerName != "docker-provider" { + return false + } + + return !strings.Contains(options, "Remote Hostname") && runnerId == LOCAL_RUNNER_ID +} diff --git a/pkg/common/local_runner.go b/pkg/common/local_runner.go new file mode 100644 index 0000000000..5acd6e3d60 --- /dev/null +++ b/pkg/common/local_runner.go @@ -0,0 +1,6 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +const LOCAL_RUNNER_ID = "local" diff --git a/pkg/jobs/build/build.go b/pkg/jobs/build/build.go index 26942db2b3..dee3e892ea 100644 --- a/pkg/jobs/build/build.go +++ b/pkg/jobs/build/build.go @@ -23,7 +23,7 @@ type BuildJob struct { checkImageExists func(ctx context.Context, image string) bool deleteImage func(ctx context.Context, image string, force bool) error - trackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error loggerFactory logs.ILoggerFactory builderFactory build.IBuilderFactory diff --git a/pkg/jobs/build/factory.go b/pkg/jobs/build/factory.go index b57a3950d8..e4d0a16c42 100644 --- a/pkg/jobs/build/factory.go +++ b/pkg/jobs/build/factory.go @@ -29,7 +29,7 @@ type BuildJobFactoryConfig struct { CheckImageExists func(ctx context.Context, image string) bool DeleteImage func(ctx context.Context, image string, force bool) error - TrackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error LoggerFactory logs.ILoggerFactory BuilderFactory build.IBuilderFactory diff --git a/pkg/jobs/build/run.go b/pkg/jobs/build/run.go index 347cd22cdb..49a279a9d9 100644 --- a/pkg/jobs/build/run.go +++ b/pkg/jobs/build/run.go @@ -50,10 +50,6 @@ func (bj *BuildJob) run(ctx context.Context, j *models.Job) error { } exists := bj.checkImageExists(ctx, imageName) - if err != nil { - return bj.handleBuildResult(b.Build, builder, buildLogger, err) - } - if exists { return bj.handleBuildResult(b.Build, builder, buildLogger, nil) } diff --git a/pkg/jobs/runner/factory.go b/pkg/jobs/runner/factory.go index 44fb62ec7b..742b575221 100644 --- a/pkg/jobs/runner/factory.go +++ b/pkg/jobs/runner/factory.go @@ -19,7 +19,7 @@ type RunnerJobFactory struct { } type RunnerJobFactoryConfig struct { - TrackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error ProviderManager providermanager.IProviderManager } diff --git a/pkg/jobs/runner/runner.go b/pkg/jobs/runner/runner.go index c0fc54196f..4a40b913c6 100644 --- a/pkg/jobs/runner/runner.go +++ b/pkg/jobs/runner/runner.go @@ -15,7 +15,7 @@ import ( type RunnerJob struct { models.Job - trackTelemetryEvent func(event telemetry.BuildRunnerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error providerManager providermanager.IProviderManager } diff --git a/pkg/jobs/target/factory.go b/pkg/jobs/target/factory.go index 9f7c3176ba..52209c6aeb 100644 --- a/pkg/jobs/target/factory.go +++ b/pkg/jobs/target/factory.go @@ -25,7 +25,7 @@ type TargetJobFactoryConfig struct { FindTarget func(ctx context.Context, targetId string) (*models.Target, error) HandleSuccessfulCreation func(ctx context.Context, targetId string) error - TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error UpdateTargetProviderMetadata func(ctx context.Context, targetId, metadata string) error LoggerFactory logs.ILoggerFactory diff --git a/pkg/jobs/target/target.go b/pkg/jobs/target/target.go index 18a597fd7a..bb6d7d8447 100644 --- a/pkg/jobs/target/target.go +++ b/pkg/jobs/target/target.go @@ -19,7 +19,7 @@ type TargetJob struct { findTarget func(ctx context.Context, targetId string) (*models.Target, error) handleSuccessfulCreation func(ctx context.Context, targetId string) error - trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error updateTargetProviderMetadata func(ctx context.Context, targetId, metadata string) error loggerFactory logs.ILoggerFactory diff --git a/pkg/jobs/workspace/factory.go b/pkg/jobs/workspace/factory.go index 15f4e0fbb9..d08ee90758 100644 --- a/pkg/jobs/workspace/factory.go +++ b/pkg/jobs/workspace/factory.go @@ -27,7 +27,7 @@ type WorkspaceJobFactoryConfig struct { FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) UpdateWorkspaceProviderMetadata func(ctx context.Context, workspaceId, metadata string) error - TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error LoggerFactory logs.ILoggerFactory ProviderManager providermanager.IProviderManager diff --git a/pkg/jobs/workspace/workspace.go b/pkg/jobs/workspace/workspace.go index ca26b8553d..10e71da506 100644 --- a/pkg/jobs/workspace/workspace.go +++ b/pkg/jobs/workspace/workspace.go @@ -21,7 +21,7 @@ type WorkspaceJob struct { findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) updateWorkspaceProviderMetadata func(ctx context.Context, workspaceId, metadata string) error getWorkspaceEnvironmentVariables func(ctx context.Context, w *models.Workspace) (map[string]string, error) - trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error loggerFactory logs.ILoggerFactory providerManager providermanager.IProviderManager diff --git a/pkg/posthogservice/service.go b/pkg/posthogservice/service.go index 26fd119de1..d565705724 100644 --- a/pkg/posthogservice/service.go +++ b/pkg/posthogservice/service.go @@ -4,7 +4,6 @@ package posthogservice import ( - "fmt" "log" "github.com/daytonaio/daytona/pkg/telemetry" @@ -16,6 +15,7 @@ type PosthogServiceConfig struct { ApiKey string Endpoint string Version string + Source telemetry.TelemetrySource } func NewTelemetryService(config PosthogServiceConfig) telemetry.TelemetryService { @@ -25,48 +25,31 @@ func NewTelemetryService(config PosthogServiceConfig) telemetry.TelemetryService Verbose: true, }) posthogService := &posthogService{ - client: client, - AbstractTelemetryService: telemetry.NewAbstractTelemetryService(config.Version), + client: client, + version: config.Version, + source: config.Source, } - posthogService.AbstractTelemetryService.TelemetryService = posthogService - return posthogService } type posthogService struct { - *telemetry.AbstractTelemetryService - - client posthog.Client + client posthog.Client + version string + source telemetry.TelemetrySource } func (p *posthogService) Close() error { return p.client.Close() } -func (p *posthogService) TrackCliEvent(event telemetry.CliEvent, clientId string, properties map[string]interface{}) error { - p.AbstractTelemetryService.SetCommonProps(properties) - return p.client.Enqueue(posthog.Capture{ - DistinctId: clientId, - Event: string(event), - Properties: properties, - }) -} +func (p *posthogService) Track(event telemetry.Event, clientId string) error { + props := event.Props() -func (p *posthogService) TrackServerEvent(event telemetry.ServerEvent, clientId string, properties map[string]interface{}) error { - p.AbstractTelemetryService.SetCommonProps(properties) + telemetry.SetCommonProps(p.version, p.source, props) return p.client.Enqueue(posthog.Capture{ DistinctId: clientId, - Event: string(event), - Properties: properties, - }) -} - -func (p *posthogService) TrackBuildRunnerEvent(event telemetry.BuildRunnerEvent, buildRunnerId string, properties map[string]interface{}) error { - p.AbstractTelemetryService.SetCommonProps(properties) - return p.client.Enqueue(posthog.Capture{ - DistinctId: fmt.Sprintf("build-runner-%s", buildRunnerId), - Event: string(event), - Properties: properties, + Event: event.Name(), + Properties: props, }) } diff --git a/pkg/runner/config.go b/pkg/runner/config.go index 19115f8c15..8f281da3f7 100644 --- a/pkg/runner/config.go +++ b/pkg/runner/config.go @@ -110,6 +110,10 @@ func DeleteConfigDir() error { } func Save(c Config) error { + if c.ClientId == "" { + c.ClientId = uuid.NewString() + } + if err := util.DirectoryValidator(&c.ProvidersDir); err != nil { return err } @@ -179,9 +183,10 @@ func GetDefaultConfig() (*Config, error) { } c := Config{ - ProvidersDir: providersDir, - LogFile: logs.GetDefaultLogFileConfig(logFilePath), - ApiPort: 3983, + ProvidersDir: providersDir, + LogFile: logs.GetDefaultLogFileConfig(logFilePath), + TelemetryEnabled: true, + ApiPort: 3983, } if os.Getenv("DEFAULT_PROVIDERS_DIR") != "" { diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 045187e99f..a01a1db954 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -24,6 +24,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/runner/providermanager" "github.com/daytonaio/daytona/pkg/scheduler" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/gin-gonic/gin" "github.com/hashicorp/go-plugin" log "github.com/sirupsen/logrus" @@ -49,9 +50,10 @@ type RunnerConfig struct { ProviderManager providermanager.IProviderManager RegistryUrl string - ListPendingJobs func(ctx context.Context) ([]*models.Job, int, error) - UpdateJobState func(ctx context.Context, jobId string, state models.JobState, err *error) error - SetRunnerMetadata func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error + ListPendingJobs func(ctx context.Context) ([]*models.Job, int, error) + UpdateJobState func(ctx context.Context, jobId string, state models.JobState, err error) error + SetRunnerMetadata func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error WorkspaceJobFactory workspace.IWorkspaceJobFactory TargetJobFactory target.ITargetJobFactory @@ -68,9 +70,10 @@ func NewRunner(config RunnerConfig) IRunner { providerManager: config.ProviderManager, registryUrl: config.RegistryUrl, - listPendingJobs: config.ListPendingJobs, - updateJobState: config.UpdateJobState, - setRunnerMetadata: config.SetRunnerMetadata, + listPendingJobs: config.ListPendingJobs, + updateJobState: config.UpdateJobState, + setRunnerMetadata: config.SetRunnerMetadata, + trackTelemetryEvent: config.TrackTelemetryEvent, workspaceJobFactory: config.WorkspaceJobFactory, targetJobFactory: config.TargetJobFactory, @@ -88,9 +91,10 @@ type Runner struct { providerManager providermanager.IProviderManager registryUrl string - listPendingJobs func(ctx context.Context) ([]*models.Job, int, error) - updateJobState func(ctx context.Context, jobId string, state models.JobState, err *error) error - setRunnerMetadata func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error + listPendingJobs func(ctx context.Context) ([]*models.Job, int, error) + updateJobState func(ctx context.Context, jobId string, state models.JobState, err error) error + setRunnerMetadata func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error workspaceJobFactory workspace.IWorkspaceJobFactory targetJobFactory target.ITargetJobFactory @@ -211,15 +215,24 @@ func (r *Runner) Purge(ctx context.Context) error { } func (r *Runner) runJob(ctx context.Context, j *models.Job) error { + startTime := time.Now() + if r.Config.TelemetryEnabled { + event := telemetry.NewJobEvent(telemetry.JobEventRunStarted, j, nil, nil) + err := r.trackTelemetryEvent(event, r.Config.ClientId) + if err != nil { + r.logger.Trace(err) + } + } + var job jobs.IJob j.State = models.JobStateRunning err := r.updateJobState(ctx, j.Id, models.JobStateRunning, nil) if err != nil { - return err + return r.handleRunFailed(j, err, startTime) } - r.logJobStateUpdate(j) + r.logJobStateUpdate(j, nil) switch j.ResourceType { case models.ResourceTypeWorkspace: @@ -236,14 +249,26 @@ func (r *Runner) runJob(ctx context.Context, j *models.Job) error { err = job.Execute(ctx) if err != nil { - j.State = models.JobStateError - r.logJobStateUpdate(j) - return r.updateJobState(ctx, j.Id, models.JobStateError, &err) + return r.handleRunFailed(j, err, startTime) } j.State = models.JobStateSuccess - r.logJobStateUpdate(j) - return r.updateJobState(ctx, j.Id, models.JobStateSuccess, nil) + r.logJobStateUpdate(j, nil) + err = r.updateJobState(ctx, j.Id, models.JobStateSuccess, nil) + if err != nil { + return r.handleRunFailed(j, err, startTime) + } + + if r.Config.TelemetryEnabled { + execTime := time.Since(startTime) + event := telemetry.NewJobEvent(telemetry.JobEventRunCompleted, j, nil, map[string]interface{}{"exec_time_ms": execTime.Milliseconds()}) + err = r.trackTelemetryEvent(event, r.Config.ClientId) + if err != nil { + r.logger.Trace(err) + } + } + + return nil } // Runner uptime in seconds @@ -275,7 +300,7 @@ func (r *Runner) UpdateRunnerMetadata(config *Config) error { }) } -func (r *Runner) logJobStateUpdate(j *models.Job) { +func (r *Runner) logJobStateUpdate(j *models.Job, err error) { if j == nil { return } @@ -292,5 +317,26 @@ func (r *Runner) logJobStateUpdate(j *models.Job) { message = "Running job" } - r.logger.Info(fmt.Sprintf("%-16s %-16s %-12s %-12s\n", message, j.Id, j.ResourceType, j.Action)) + message = fmt.Sprintf("%-16s %-16s %-12s %-12s\n", message, j.Id, j.ResourceType, j.Action) + if err != nil { + message += fmt.Sprintf(" Error: %s\n", err) + } + + r.logger.Info(message) +} + +func (r *Runner) handleRunFailed(j *models.Job, err error, startTime time.Time) error { + j.State = models.JobStateError + r.logJobStateUpdate(j, err) + + if r.Config.TelemetryEnabled { + execTime := time.Since(startTime) + event := telemetry.NewJobEvent(telemetry.JobEventRunFailed, j, err, map[string]interface{}{"exec_time_ms": execTime.Milliseconds()}) + err = r.trackTelemetryEvent(event, r.Config.ClientId) + if err != nil { + r.logger.Trace(err) + } + } + + return r.updateJobState(context.Background(), j.Id, models.JobStateError, err) } diff --git a/pkg/server/apikeys/apikeys.go b/pkg/server/apikeys/apikeys.go index 7987d12d64..5b75e7d522 100644 --- a/pkg/server/apikeys/apikeys.go +++ b/pkg/server/apikeys/apikeys.go @@ -7,6 +7,8 @@ import ( "context" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" ) func (s *ApiKeyService) ListClientKeys(ctx context.Context) ([]*models.ApiKey, error) { @@ -46,8 +48,32 @@ func (s *ApiKeyService) Generate(ctx context.Context, keyType models.ApiKeyType, err := s.apiKeyStore.Save(ctx, apiKey) if err != nil { - return "", err + return "", s.handleGenerateApiKeyError(ctx, apiKey, err) } - return key, nil + return key, s.handleGenerateApiKeyError(ctx, apiKey, nil) +} + +func (s *ApiKeyService) handleGenerateApiKeyError(ctx context.Context, key *models.ApiKey, err error) error { + if key.Type != models.ApiKeyTypeClient { + return err + } + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + eventName := telemetry.ApiKeyEventLifecycleCreated + if err != nil { + eventName = telemetry.ApiKeyEventLifecycleCreationFailed + } + + event := telemetry.NewApiKeyEvent(eventName, key, err, nil) + + telemetryErr := s.trackTelemetryEvent(event, telemetry.ClientId(ctx)) + if telemetryErr != nil { + log.Trace(telemetryErr) + } + + return err } diff --git a/pkg/server/apikeys/service.go b/pkg/server/apikeys/service.go index 69855617a3..270ab134ff 100644 --- a/pkg/server/apikeys/service.go +++ b/pkg/server/apikeys/service.go @@ -6,24 +6,28 @@ package apikeys import ( "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" ) type ApiKeyServiceConfig struct { - ApiKeyStore stores.ApiKeyStore - GenerateRandomKey func(name string) string - GetKeyHash func(key string) string + ApiKeyStore stores.ApiKeyStore + GenerateRandomKey func(name string) string + GetKeyHash func(key string) string + TrackTelemetryEvent func(event telemetry.Event, clientId string) error } func NewApiKeyService(config ApiKeyServiceConfig) services.IApiKeyService { return &ApiKeyService{ - apiKeyStore: config.ApiKeyStore, - generateRandomKey: config.GenerateRandomKey, - getKeyHash: config.GetKeyHash, + apiKeyStore: config.ApiKeyStore, + generateRandomKey: config.GenerateRandomKey, + getKeyHash: config.GetKeyHash, + trackTelemetryEvent: config.TrackTelemetryEvent, } } type ApiKeyService struct { - apiKeyStore stores.ApiKeyStore - generateRandomKey func(name string) string - getKeyHash func(key string) string + apiKeyStore stores.ApiKeyStore + generateRandomKey func(name string) string + getKeyHash func(key string) string + trackTelemetryEvent func(event telemetry.Event, clientId string) error } diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index 9615bf5982..04c4553857 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -14,6 +14,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/apikeys" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/suite" ) @@ -40,6 +41,9 @@ func (s *ApiKeyServiceTestSuite) SetupTest() { GetKeyHash: func(key string) string { return apikeys_util.HashKey(key) }, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return nil + }, }) for _, keyName := range clientKeyNames { diff --git a/pkg/server/builds/create.go b/pkg/server/builds/create.go new file mode 100644 index 0000000000..389394dd9b --- /dev/null +++ b/pkg/server/builds/create.go @@ -0,0 +1,88 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package builds + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/telemetry" + "github.com/docker/docker/pkg/stringid" + + log "github.com/sirupsen/logrus" +) + +func (s *BuildService) Create(ctx context.Context, b services.CreateBuildDTO) (string, error) { + ctx, err := s.buildStore.BeginTransaction(ctx) + if err != nil { + return "", s.handleCreateError(ctx, nil, err) + } + + id := stringid.GenerateRandomID() + id = stringid.TruncateID(id) + + workspaceTemplate, err := s.findWorkspaceTemplate(ctx, b.WorkspaceTemplateName) + if err != nil { + return "", s.handleCreateError(ctx, nil, err) + } + + repo, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl, b.Branch) + if err != nil { + return "", s.handleCreateError(ctx, nil, err) + } + + newBuild := models.Build{ + Id: id, + ContainerConfig: models.ContainerConfig{ + Image: workspaceTemplate.Image, + User: workspaceTemplate.User, + }, + BuildConfig: workspaceTemplate.BuildConfig, + Repository: repo, + EnvVars: b.EnvVars, + } + + if b.PrebuildId != nil { + newBuild.PrebuildId = *b.PrebuildId + } + + err = s.buildStore.Save(ctx, &newBuild) + if err != nil { + return "", s.handleCreateError(ctx, nil, err) + } + + err = s.createJob(ctx, id, models.JobActionRun) + if err != nil { + return "", s.handleCreateError(ctx, &newBuild, err) + } + + err = s.buildStore.CommitTransaction(ctx) + return id, s.handleCreateError(ctx, &newBuild, err) +} + +func (s *BuildService) handleCreateError(ctx context.Context, b *models.Build, err error) error { + if err != nil { + err = s.buildStore.RollbackTransaction(ctx, err) + } + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.BuildEventLifecycleCreated + if err != nil { + eventName = telemetry.BuildEventLifecycleCreationFailed + } + event := telemetry.NewBuildEvent(eventName, b, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index c8ba99cef8..cdf64f0fbe 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -12,7 +12,9 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" - "github.com/docker/docker/pkg/stringid" + "github.com/daytonaio/daytona/pkg/telemetry" + + log "github.com/sirupsen/logrus" ) type BuildServiceConfig struct { @@ -20,6 +22,7 @@ type BuildServiceConfig struct { FindWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) CreateJob func(ctx context.Context, workspaceId string, action models.JobAction) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error LoggerFactory logs.ILoggerFactory } @@ -28,6 +31,7 @@ type BuildService struct { findWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) createJob func(ctx context.Context, workspaceId string, action models.JobAction) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error loggerFactory logs.ILoggerFactory } @@ -38,51 +42,10 @@ func NewBuildService(config BuildServiceConfig) services.IBuildService { getRepositoryContext: config.GetRepositoryContext, loggerFactory: config.LoggerFactory, createJob: config.CreateJob, + trackTelemetryEvent: config.TrackTelemetryEvent, } } -func (s *BuildService) Create(ctx context.Context, b services.CreateBuildDTO) (string, error) { - id := stringid.GenerateRandomID() - id = stringid.TruncateID(id) - - workspaceTemplate, err := s.findWorkspaceTemplate(ctx, b.WorkspaceTemplateName) - if err != nil { - return "", err - } - - repo, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl, b.Branch) - if err != nil { - return "", err - } - - newBuild := models.Build{ - Id: id, - ContainerConfig: models.ContainerConfig{ - Image: workspaceTemplate.Image, - User: workspaceTemplate.User, - }, - BuildConfig: workspaceTemplate.BuildConfig, - Repository: repo, - EnvVars: b.EnvVars, - } - - if b.PrebuildId != nil { - newBuild.PrebuildId = *b.PrebuildId - } - - err = s.buildStore.Save(ctx, &newBuild) - if err != nil { - return "", err - } - - err = s.createJob(ctx, id, models.JobActionRun) - if err != nil { - return "", err - } - - return id, nil -} - func (s *BuildService) Find(ctx context.Context, filter *services.BuildFilter) (*services.BuildDTO, error) { var storeFilter *stores.BuildFilter @@ -146,17 +109,19 @@ func (s *BuildService) Delete(ctx context.Context, filter *services.BuildFilter, builds, err := s.List(ctx, filter) if err != nil { - return []error{err} + return []error{s.handleDeleteError(ctx, nil, err, force)} } for _, b := range builds { if force { err = s.createJob(ctx, b.Id, models.JobActionForceDelete) + err = s.handleDeleteError(ctx, &b.Build, err, force) if err != nil { errors = append(errors, err) } } else { err = s.createJob(ctx, b.Id, models.JobActionDelete) + err = s.handleDeleteError(ctx, &b.Build, err, force) if err != nil { errors = append(errors, err) } @@ -166,6 +131,34 @@ func (s *BuildService) Delete(ctx context.Context, filter *services.BuildFilter, return errors } +func (s *BuildService) handleDeleteError(ctx context.Context, b *models.Build, err error, force bool) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.BuildEventLifecycleDeleted + if force { + eventName = telemetry.BuildEventLifecycleForceDeleted + } + if err != nil { + eventName = telemetry.BuildEventLifecycleDeletionFailed + if force { + eventName = telemetry.BuildEventLifecycleForceDeletionFailed + } + } + + event := telemetry.NewBuildEvent(eventName, b, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} + func (s *BuildService) GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) { return s.loggerFactory.CreateLogReader(buildId) } diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 152b22de4d..238252bd60 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -13,6 +13,7 @@ import ( "github.com/daytonaio/daytona/pkg/server/builds" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/suite" ) @@ -106,6 +107,9 @@ func (s *BuildServiceTestSuite) SetupTest() { s.buildStore = build_internal.NewInMemoryBuildStore() s.buildService = builds.NewBuildService(builds.BuildServiceConfig{ BuildStore: s.buildStore, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return nil + }, }) for _, b := range expectedBuilds { diff --git a/pkg/server/gitproviders/config.go b/pkg/server/gitproviders/config.go index e3a8534968..95fef25729 100644 --- a/pkg/server/gitproviders/config.go +++ b/pkg/server/gitproviders/config.go @@ -10,7 +10,10 @@ import ( "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/docker/docker/pkg/stringid" + + log "github.com/sirupsen/logrus" ) func (s *GitProviderService) GetConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) { @@ -55,12 +58,12 @@ func (s *GitProviderService) ListConfigsForUrl(ctx context.Context, repoUrl stri func (s *GitProviderService) SetGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error { gitProvider, err := s.newGitProvider(providerConfig) if err != nil { - return err + return s.handleSetGitProviderConfigError(ctx, providerConfig, err) } userData, err := gitProvider.GetUser() if err != nil { - return err + return s.handleSetGitProviderConfigError(ctx, providerConfig, err) } providerConfig.Username = userData.Username if providerConfig.Id == "" { @@ -72,7 +75,7 @@ func (s *GitProviderService) SetGitProviderConfig(ctx context.Context, providerC if providerConfig.Alias == "" { gitProviderConfigs, err := s.ListConfigs(ctx) if err != nil { - return err + return s.handleSetGitProviderConfigError(ctx, providerConfig, err) } uniqueAlias := userData.Username @@ -91,5 +94,27 @@ func (s *GitProviderService) SetGitProviderConfig(ctx context.Context, providerC providerConfig.Alias = uniqueAlias } - return s.configStore.Save(ctx, providerConfig) + err = s.configStore.Save(ctx, providerConfig) + return s.handleSetGitProviderConfigError(ctx, providerConfig, err) +} + +func (s *GitProviderService) handleSetGitProviderConfigError(ctx context.Context, gpc *models.GitProviderConfig, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.GitProviderConfigEventLifecycleSaved + if err != nil { + eventName = telemetry.GitProviderConfigEventLifecycleSaveFailed + } + event := telemetry.NewGitProviderConfigEvent(eventName, gpc, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err } diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/remove.go index 54b47fd880..bdc431ad78 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/remove.go @@ -3,18 +3,46 @@ package gitproviders -import "context" +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" +) func (s *GitProviderService) RemoveGitProvider(ctx context.Context, gitProviderId string) error { gitProvider, err := s.configStore.Find(ctx, gitProviderId) if err != nil { - return err + return s.handleRemoveGitProviderConfigError(ctx, nil, err) } err = s.detachWorkspaceTemplates(ctx, gitProvider.Id) if err != nil { + return s.handleRemoveGitProviderConfigError(ctx, gitProvider, err) + } + + err = s.configStore.Delete(ctx, gitProvider) + return s.handleRemoveGitProviderConfigError(ctx, gitProvider, err) +} + +func (s *GitProviderService) handleRemoveGitProviderConfigError(ctx context.Context, gpc *models.GitProviderConfig, err error) error { + if !telemetry.TelemetryEnabled(ctx) { return err } - return s.configStore.Delete(ctx, gitProvider) + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.GitProviderConfigEventLifecycleDeleted + if err != nil { + eventName = telemetry.GitProviderConfigEventLifecycleDeletionFailed + } + event := telemetry.NewGitProviderConfigEvent(eventName, gpc, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err } diff --git a/pkg/server/gitproviders/service.go b/pkg/server/gitproviders/service.go index 592770a127..2abba7a6e0 100644 --- a/pkg/server/gitproviders/service.go +++ b/pkg/server/gitproviders/service.go @@ -13,23 +13,27 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" ) type GitProviderServiceConfig struct { ConfigStore stores.GitProviderConfigStore DetachWorkspaceTemplates func(ctx context.Context, gitProviderConfigId string) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error } type GitProviderService struct { configStore stores.GitProviderConfigStore detachWorkspaceTemplates func(ctx context.Context, gitProviderConfigId string) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error } func NewGitProviderService(config GitProviderServiceConfig) services.IGitProviderService { return &GitProviderService{ configStore: config.ConfigStore, detachWorkspaceTemplates: config.DetachWorkspaceTemplates, + trackTelemetryEvent: config.TrackTelemetryEvent, } } diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index b1bac4d8eb..11db91c70a 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -11,20 +11,26 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/docker/docker/pkg/stringid" + + log "github.com/sirupsen/logrus" ) type JobServiceConfig struct { - JobStore stores.JobStore + JobStore stores.JobStore + TrackTelemetryEvent func(event telemetry.Event, clientId string) error } type JobService struct { - jobStore stores.JobStore + jobStore stores.JobStore + trackTelemetryEvent func(event telemetry.Event, clientId string) error } func NewJobService(config JobServiceConfig) services.IJobService { return &JobService{ - jobStore: config.JobStore, + jobStore: config.JobStore, + trackTelemetryEvent: config.TrackTelemetryEvent, } } @@ -39,11 +45,11 @@ func (s *JobService) Find(ctx context.Context, filter *stores.JobFilter) (*model func (s *JobService) Create(ctx context.Context, j *models.Job) error { validAction, ok := validResourceActions[j.ResourceType] if !ok { - return services.ErrInvalidResourceJobAction + return s.handleCreateError(ctx, j, services.ErrInvalidResourceJobAction) } if !slices.Contains(validAction, j.Action) { - return services.ErrInvalidResourceJobAction + return s.handleCreateError(ctx, j, services.ErrInvalidResourceJobAction) } pendingJobs, err := s.List(ctx, &stores.JobFilter{ @@ -52,11 +58,11 @@ func (s *JobService) Create(ctx context.Context, j *models.Job) error { States: &[]models.JobState{models.JobStatePending, models.JobStateRunning}, }) if err != nil { - return err + return s.handleCreateError(ctx, j, err) } if len(pendingJobs) > 0 { - return stores.ErrJobInProgress + return s.handleCreateError(ctx, j, stores.ErrJobInProgress) } if j.Id == "" { @@ -64,7 +70,9 @@ func (s *JobService) Create(ctx context.Context, j *models.Job) error { id = stringid.TruncateID(id) j.Id = id } - return s.jobStore.Save(ctx, j) + + err = s.jobStore.Save(ctx, j) + return s.handleCreateError(ctx, j, err) } func (s *JobService) SetState(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { @@ -89,6 +97,27 @@ func (s *JobService) Delete(ctx context.Context, j *models.Job) error { return s.jobStore.Delete(ctx, j) } +func (s *JobService) handleCreateError(ctx context.Context, j *models.Job, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.JobEventLifecycleCreated + if err != nil { + eventName = telemetry.JobEventLifecycleCreationFailed + } + event := telemetry.NewJobEvent(eventName, j, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} + var validResourceActions = map[models.ResourceType][]models.JobAction{ models.ResourceTypeWorkspace: { models.JobActionCreate, diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go index fed94eed96..9e84a5f601 100644 --- a/pkg/server/jobs/service_test.go +++ b/pkg/server/jobs/service_test.go @@ -12,6 +12,7 @@ import ( jobs "github.com/daytonaio/daytona/pkg/server/jobs" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/stretchr/testify/suite" ) @@ -63,6 +64,9 @@ func (s *JobServiceTestSuite) SetupTest() { s.jobStore = job_internal.NewInMemoryJobStore() s.jobService = jobs.NewJobService(jobs.JobServiceConfig{ JobStore: s.jobStore, + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return nil + }, }) for _, j := range expectedJobs { diff --git a/pkg/server/runners/provider.go b/pkg/server/runners/provider.go index c473134301..8f3704fb23 100644 --- a/pkg/server/runners/provider.go +++ b/pkg/server/runners/provider.go @@ -9,6 +9,8 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" ) func (s *RunnerService) ListProviders(ctx context.Context, runnerId *string) ([]models.ProviderInfo, error) { @@ -36,27 +38,104 @@ func (s *RunnerService) ListProviders(ctx context.Context, runnerId *string) ([] return providers, nil } -func (s *RunnerService) InstallProvider(ctx context.Context, runnerId string, providerMetadata services.InstallProviderDTO) error { - metadata, err := json.Marshal(providerMetadata) +func (s *RunnerService) InstallProvider(ctx context.Context, runnerId string, providerDto services.InstallProviderDTO) error { + params := providerActionParams{ + providerName: providerDto.Name, + providerVersion: &providerDto.Version, + eventName: telemetry.RunnerEventProviderInstalled, + errEventName: telemetry.RunnerEventProviderInstallationFailed, + } + + runner, err := s.runnerStore.Find(ctx, runnerId) if err != nil { - return err + return s.handleProviderActionError(ctx, params, err) } - return s.createJob(ctx, runnerId, models.JobActionInstallProvider, string(metadata)) + params.runner = runner + + metadata, err := json.Marshal(providerDto) + if err != nil { + return s.handleProviderActionError(ctx, params, err) + } + + err = s.createJob(ctx, runnerId, models.JobActionInstallProvider, string(metadata)) + return s.handleProviderActionError(ctx, params, err) } func (s *RunnerService) UninstallProvider(ctx context.Context, runnerId string, providerName string) error { - return s.createJob(ctx, runnerId, models.JobActionUninstallProvider, providerName) + params := providerActionParams{ + providerName: providerName, + eventName: telemetry.RunnerEventProviderUninstalled, + errEventName: telemetry.RunnerEventProviderUninstallationFailed, + } + + runner, err := s.runnerStore.Find(ctx, runnerId) + if err != nil { + return s.handleProviderActionError(ctx, params, err) + } + + params.runner = runner + + err = s.createJob(ctx, runnerId, models.JobActionUninstallProvider, providerName) + return s.handleProviderActionError(ctx, params, err) } -func (s *RunnerService) UpdateProvider(ctx context.Context, runnerId string, providerName string, downloadUrls services.DownloadUrls) error { - metadata, err := json.Marshal(services.InstallProviderDTO{ - Name: providerName, - DownloadUrls: downloadUrls, - }) +func (s *RunnerService) UpdateProvider(ctx context.Context, runnerId string, providerName string, providerDto services.UpdateProviderDTO) error { + params := providerActionParams{ + providerName: providerName, + providerVersion: &providerDto.Version, + eventName: telemetry.RunnerEventProviderUpdated, + errEventName: telemetry.RunnerEventProviderUpdateFailed, + } + + runner, err := s.runnerStore.Find(ctx, runnerId) + if err != nil { + return s.handleProviderActionError(ctx, params, err) + } + + params.runner = runner + + metadata, err := json.Marshal(providerDto) if err != nil { + return s.handleProviderActionError(ctx, params, err) + } + + err = s.createJob(ctx, runnerId, models.JobActionUpdateProvider, string(metadata)) + return s.handleProviderActionError(ctx, params, err) +} + +type providerActionParams struct { + runner *models.Runner + eventName telemetry.RunnerEventName + errEventName telemetry.RunnerEventName + providerName string + providerVersion *string +} + +func (s *RunnerService) handleProviderActionError(ctx context.Context, params providerActionParams, err error) error { + if !telemetry.TelemetryEnabled(ctx) { return err } - return s.createJob(ctx, runnerId, models.JobActionUpdateProvider, string(metadata)) + eventName := params.eventName + if err != nil { + eventName = params.errEventName + } + + clientId := telemetry.ClientId(ctx) + + extras := map[string]interface{}{ + "provider_name": params.providerName, + } + if params.providerVersion != nil { + extras["provider_version"] = *params.providerVersion + } + + event := telemetry.NewRunnerEvent(eventName, params.runner, err, extras) + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err } diff --git a/pkg/server/runners/register.go b/pkg/server/runners/register.go index 1ab29a758b..4c495a83ec 100644 --- a/pkg/server/runners/register.go +++ b/pkg/server/runners/register.go @@ -9,25 +9,28 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + + log "github.com/sirupsen/logrus" ) func (s *RunnerService) RegisterRunner(ctx context.Context, req services.RegisterRunnerDTO) (*services.RunnerDTO, error) { var err error ctx, err = s.runnerStore.BeginTransaction(ctx) if err != nil { - return nil, s.runnerStore.RollbackTransaction(ctx, err) + return nil, s.handleRegisterError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.runnerStore) _, err = s.runnerStore.Find(ctx, req.Name) if err == nil { - return nil, s.runnerStore.RollbackTransaction(ctx, services.ErrRunnerAlreadyExists) + return nil, s.handleRegisterError(ctx, nil, services.ErrRunnerAlreadyExists) } apiKey, err := s.generateApiKey(ctx, req.Id) if err != nil { - return nil, s.runnerStore.RollbackTransaction(ctx, err) + return nil, s.handleRegisterError(ctx, nil, err) } runner := &models.Runner{ @@ -42,21 +45,46 @@ func (s *RunnerService) RegisterRunner(ctx context.Context, req services.Registe err = s.runnerStore.Save(ctx, runner) if err != nil { - return nil, s.runnerStore.RollbackTransaction(ctx, err) + return nil, s.handleRegisterError(ctx, runner, err) } err = s.runnerMetadataStore.Save(ctx, runner.Metadata) if err != nil { - return nil, s.runnerStore.RollbackTransaction(ctx, err) + return nil, s.handleRegisterError(ctx, runner, err) } err = s.runnerStore.CommitTransaction(ctx) if err != nil { - return nil, s.runnerStore.RollbackTransaction(ctx, err) + return nil, s.handleRegisterError(ctx, runner, err) } return &services.RunnerDTO{ Runner: *runner, State: runner.GetState(), - }, nil + }, s.handleRegisterError(ctx, runner, nil) +} + +func (s *RunnerService) handleRegisterError(ctx context.Context, r *models.Runner, err error) error { + if err != nil { + err = s.runnerStore.RollbackTransaction(ctx, err) + } + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.RunnerEventLifecycleRegistered + if err != nil { + eventName = telemetry.RunnerEventLifecycleRegistrationFailed + } + event := telemetry.NewRunnerEvent(eventName, r, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err } diff --git a/pkg/server/runners/remove.go b/pkg/server/runners/remove.go index 8dd6a30c92..c9c6478924 100644 --- a/pkg/server/runners/remove.go +++ b/pkg/server/runners/remove.go @@ -6,48 +6,77 @@ package runners import ( "context" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" ) func (s *RunnerService) RemoveRunner(ctx context.Context, runnerId string) error { var err error ctx, err = s.runnerStore.BeginTransaction(ctx) if err != nil { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.runnerStore) runner, err := s.runnerStore.Find(ctx, runnerId) if err != nil { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, nil, err) } err = s.runnerStore.Delete(ctx, runner) if err != nil { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, runner, err) } metadata, err := s.runnerMetadataStore.Find(ctx, runnerId) if err != nil && !stores.IsRunnerMetadataNotFound(err) { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, runner, err) } if metadata != nil { err = s.runnerMetadataStore.Delete(ctx, metadata) if err != nil { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, runner, err) } } err = s.revokeApiKey(ctx, runner.Id) if err != nil { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, runner, err) } err = s.unsetDefaultTarget(ctx, runner.Id) if err != nil { - return s.runnerStore.RollbackTransaction(ctx, err) + return s.handleRemoveError(ctx, runner, err) } - return s.runnerStore.CommitTransaction(ctx) + err = s.runnerStore.CommitTransaction(ctx) + return s.handleRemoveError(ctx, runner, err) +} + +func (s *RunnerService) handleRemoveError(ctx context.Context, r *models.Runner, err error) error { + if err != nil { + err = s.runnerStore.RollbackTransaction(ctx, err) + } + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.RunnerEventLifecycleDeleted + if err != nil { + eventName = telemetry.RunnerEventLifecycleDeletionFailed + } + event := telemetry.NewRunnerEvent(eventName, r, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err } diff --git a/pkg/server/runners/service.go b/pkg/server/runners/service.go index 8c3c2eb584..44180fbcf2 100644 --- a/pkg/server/runners/service.go +++ b/pkg/server/runners/service.go @@ -27,7 +27,7 @@ type RunnerServiceConfig struct { RevokeApiKey func(ctx context.Context, name string) error UnsetDefaultTarget func(ctx context.Context, runnerId string) error - TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error } func NewRunnerService(config RunnerServiceConfig) services.IRunnerService { @@ -59,7 +59,7 @@ type RunnerService struct { revokeApiKey func(ctx context.Context, name string) error unsetDefaultTarget func(ctx context.Context, runnerId string) error - trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error } func (s *RunnerService) GetRunner(ctx context.Context, runnerId string) (*services.RunnerDTO, error) { diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index a4d712c4d5..a8836083b8 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -9,20 +9,26 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" "github.com/docker/docker/pkg/stringid" + + log "github.com/sirupsen/logrus" ) type TargetConfigServiceConfig struct { - TargetConfigStore stores.TargetConfigStore + TargetConfigStore stores.TargetConfigStore + TrackTelemetryEvent func(event telemetry.Event, clientId string) error } type TargetConfigService struct { - targetConfigStore stores.TargetConfigStore + targetConfigStore stores.TargetConfigStore + trackTelemetryEvent func(event telemetry.Event, clientId string) error } func NewTargetConfigService(config TargetConfigServiceConfig) services.ITargetConfigService { return &TargetConfigService{ - targetConfigStore: config.TargetConfigStore, + targetConfigStore: config.TargetConfigStore, + trackTelemetryEvent: config.TrackTelemetryEvent, } } @@ -51,10 +57,10 @@ func (s *TargetConfigService) Find(ctx context.Context, idOrName string) (*model func (s *TargetConfigService) Add(ctx context.Context, addTargetConfig services.AddTargetConfigDTO) (*models.TargetConfig, error) { persistedTargetConfig, err := s.targetConfigStore.Find(ctx, addTargetConfig.Name, false) if err != nil && !stores.IsTargetConfigNotFound(err) { - return nil, err + return nil, s.handleCreateError(ctx, nil, err) } if persistedTargetConfig != nil && !persistedTargetConfig.Deleted { - return nil, stores.ErrTargetConfigAlreadyExists + return nil, s.handleCreateError(ctx, nil, stores.ErrTargetConfigAlreadyExists) } targetConfig := &models.TargetConfig{ @@ -65,15 +71,59 @@ func (s *TargetConfigService) Add(ctx context.Context, addTargetConfig services. Deleted: false, } - return targetConfig, s.targetConfigStore.Save(ctx, targetConfig) + err = s.targetConfigStore.Save(ctx, targetConfig) + return targetConfig, s.handleCreateError(ctx, targetConfig, err) } func (s *TargetConfigService) Delete(ctx context.Context, targetConfigId string) error { targetConfig, err := s.targetConfigStore.Find(ctx, targetConfigId, false) if err != nil { - return err + return s.handleDeleteError(ctx, nil, err) } targetConfig.Deleted = true - return s.targetConfigStore.Save(ctx, targetConfig) + err = s.targetConfigStore.Save(ctx, targetConfig) + return s.handleDeleteError(ctx, targetConfig, err) +} + +func (s *TargetConfigService) handleCreateError(ctx context.Context, tc *models.TargetConfig, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.TargetConfigEventLifecycleCreated + if err != nil { + eventName = telemetry.TargetConfigEventLifecycleCreationFailed + } + event := telemetry.NewTargetConfigEvent(eventName, tc, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} + +func (s *TargetConfigService) handleDeleteError(ctx context.Context, tc *models.TargetConfig, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.TargetConfigEventLifecycleDeleted + if err != nil { + eventName = telemetry.TargetConfigEventLifecycleDeletionFailed + } + event := telemetry.NewTargetConfigEvent(eventName, tc, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err } diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index 850a76d732..6d49b7716d 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -99,15 +99,14 @@ func (s *TargetService) handleCreateError(ctx context.Context, target *models.Ta clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target) - event := telemetry.ServerEventTargetCreated + eventName := telemetry.TargetEventLifecycleCreated if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetCreateError + eventName = telemetry.TargetEventLifecycleCreationFailed } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + event := telemetry.NewTargetEvent(eventName, target, err, nil) + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { - log.Trace(err) + log.Trace(telemetryError) } return target, err diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/remove.go index 2bb0e19684..a1e06422ca 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/remove.go @@ -61,21 +61,21 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) var err error ctx, err = s.targetStore.BeginTransaction(ctx) if err != nil { - return s.handleRemoveError(ctx, nil, err) + return s.handleForceRemoveError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.targetStore) t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleRemoveError(ctx, nil, stores.ErrTargetNotFound) + return s.handleForceRemoveError(ctx, nil, stores.ErrTargetNotFound) } t.Name = util.AddDeletedToName(t.Name) err = s.targetStore.Save(ctx, t) if err != nil { - return s.handleRemoveError(ctx, t, err) + return s.handleForceRemoveError(ctx, t, err) } err = s.revokeApiKey(ctx, targetId) @@ -93,11 +93,11 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) err = s.createJob(ctx, t.Id, t.TargetConfig.ProviderInfo.RunnerId, models.JobActionForceDelete) if err != nil { - return s.handleRemoveError(ctx, t, err) + return s.handleForceRemoveError(ctx, t, err) } err = s.targetStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, t, err) + return s.handleForceRemoveError(ctx, t, err) } func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Target, err error) error { @@ -111,15 +111,39 @@ func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Ta clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target) - event := telemetry.ServerEventTargetDestroyed + eventName := telemetry.TargetEventLifecycleDeleted if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetDestroyError + eventName = telemetry.TargetEventLifecycleDeletionFailed + } + event := telemetry.NewTargetEvent(eventName, target, err, nil) + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + + return err +} + +func (s *TargetService) handleForceRemoveError(ctx context.Context, target *models.Target, err error) error { + if err != nil { + err = s.targetStore.RollbackTransaction(ctx, err) + } + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.TargetEventLifecycleForceDeleted + if err != nil { + eventName = telemetry.TargetEventLifecycleForceDeletionFailed + } + event := telemetry.NewTargetEvent(eventName, target, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { - log.Trace(err) + log.Trace(telemetryError) } return err diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 34de343a0f..61dde8a94b 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -18,16 +18,16 @@ type TargetServiceConfig struct { TargetStore stores.TargetStore TargetMetadataStore stores.TargetMetadataStore - FindTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) - GenerateApiKey func(ctx context.Context, name string) (string, error) - RevokeApiKey func(ctx context.Context, name string) error - CreateJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error - - ServerApiUrl string - ServerUrl string - ServerVersion string - LoggerFactory logs.ILoggerFactory - TelemetryService telemetry.TelemetryService + FindTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) + GenerateApiKey func(ctx context.Context, name string) (string, error) + RevokeApiKey func(ctx context.Context, name string) error + CreateJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error + + ServerApiUrl string + ServerUrl string + ServerVersion string + LoggerFactory logs.ILoggerFactory } func NewTargetService(config TargetServiceConfig) services.ITargetService { @@ -40,11 +40,11 @@ func NewTargetService(config TargetServiceConfig) services.ITargetService { revokeApiKey: config.RevokeApiKey, createJob: config.CreateJob, - serverApiUrl: config.ServerApiUrl, - serverUrl: config.ServerUrl, - serverVersion: config.ServerVersion, - loggerFactory: config.LoggerFactory, - telemetryService: config.TelemetryService, + serverApiUrl: config.ServerApiUrl, + serverUrl: config.ServerUrl, + serverVersion: config.ServerVersion, + loggerFactory: config.LoggerFactory, + trackTelemetryEvent: config.TrackTelemetryEvent, } } @@ -52,16 +52,16 @@ type TargetService struct { targetStore stores.TargetStore targetMetadataStore stores.TargetMetadataStore - findTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) - generateApiKey func(ctx context.Context, name string) (string, error) - revokeApiKey func(ctx context.Context, name string) error - createJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error + findTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) + generateApiKey func(ctx context.Context, name string) (string, error) + revokeApiKey func(ctx context.Context, name string) error + createJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error - serverApiUrl string - serverUrl string - serverVersion string - loggerFactory logs.ILoggerFactory - telemetryService telemetry.TelemetryService + serverApiUrl string + serverUrl string + serverVersion string + loggerFactory logs.ILoggerFactory } func (s *TargetService) GetTargetLogReader(ctx context.Context, targetId string) (io.Reader, error) { diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index 29696e7219..80dedee2f9 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -34,13 +34,12 @@ func (s *TargetService) handleStartError(ctx context.Context, target *models.Tar clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target) - event := telemetry.ServerEventTargetStarted + eventName := telemetry.TargetEventLifecycleStarted if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetStartError + eventName = telemetry.TargetEventLifecycleStartFailed } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + event := telemetry.NewTargetEvent(eventName, target, err, nil) + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { log.Trace(telemetryError) } diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index 5812f4f2e9..cc1e753708 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -34,13 +34,13 @@ func (s *TargetService) handleStopError(ctx context.Context, target *models.Targ clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewTargetEventProps(ctx, target) - event := telemetry.ServerEventTargetStopped + eventName := telemetry.TargetEventLifecycleStopped if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventTargetStopError + eventName = telemetry.TargetEventLifecycleStopFailed } - telemetryError := s.telemetryService.TrackServerEvent(event, clientId, telemetryProps) + event := telemetry.NewTargetEvent(eventName, target, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { log.Trace(telemetryError) } diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 54cf0b0481..79523bb6c2 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -144,15 +144,15 @@ func (s *WorkspaceService) handleCreateError(ctx context.Context, w *models.Work clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) - event := telemetry.ServerEventWorkspaceCreated + eventName := telemetry.WorkspaceEventLifecycleCreated if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceCreateError + eventName = telemetry.WorkspaceEventLifecycleCreationFailed } - telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { - log.Trace(err) + log.Trace(telemetryError) } if w == nil { diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/remove.go index f5c4f96bf1..37c93abc26 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/remove.go @@ -61,21 +61,21 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { - return s.handleRemoveError(ctx, nil, err) + return s.handleForceRemoveError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.workspaceStore) w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - return s.handleRemoveError(ctx, w, stores.ErrWorkspaceNotFound) + return s.handleForceRemoveError(ctx, w, stores.ErrWorkspaceNotFound) } w.Name = util.AddDeletedToName(w.Name) err = s.workspaceStore.Save(ctx, w) if err != nil { - return s.handleRemoveError(ctx, w, err) + return s.handleForceRemoveError(ctx, w, err) } err = s.revokeApiKey(ctx, workspaceId) @@ -93,11 +93,11 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionForceDelete) if err != nil { - return s.handleRemoveError(ctx, w, err) + return s.handleForceRemoveError(ctx, w, err) } err = s.workspaceStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, w, err) + return s.handleForceRemoveError(ctx, w, err) } func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Workspace, err error) error { @@ -111,15 +111,40 @@ func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Work clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) - event := telemetry.ServerEventWorkspaceDestroyed + eventName := telemetry.WorkspaceEventLifecycleDeleted if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceDestroyError + eventName = telemetry.WorkspaceEventLifecycleDeletionFailed } - telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} + +func (s *WorkspaceService) handleForceRemoveError(ctx context.Context, w *models.Workspace, err error) error { + if err != nil { + err = s.workspaceStore.RollbackTransaction(ctx, err) + } + + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.WorkspaceEventLifecycleForceDeleted + if err != nil { + eventName = telemetry.WorkspaceEventLifecycleForceDeletionFailed + } + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { - log.Trace(err) + log.Trace(telemetryError) } return err diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index 724d3fd5bb..8fcfc82c99 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -28,7 +28,7 @@ type WorkspaceServiceConfig struct { FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) CreateJob func(ctx context.Context, workspaceId string, runnerId string, action models.JobAction) error - TrackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + TrackTelemetryEvent func(event telemetry.Event, clientId string) error LoggerFactory logs.ILoggerFactory ServerApiUrl string @@ -76,7 +76,7 @@ type WorkspaceService struct { findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) getLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) createJob func(ctx context.Context, workspaceId string, runnerId string, action models.JobAction) error - trackTelemetryEvent func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error + trackTelemetryEvent func(event telemetry.Event, clientId string) error serverApiUrl string serverUrl string diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 8dfda721c1..f577deafdd 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -144,7 +144,7 @@ func TestTargetService(t *testing.T) { GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { return gitProviderService.GetLastCommitSha(repo) }, - TrackTelemetryEvent: func(event telemetry.ServerEvent, clientId string, props map[string]interface{}) error { + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { return nil }, WorkspaceStore: workspaceStore, diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index adc56bbb99..d0a158047d 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -33,15 +33,15 @@ func (s *WorkspaceService) handleStartError(ctx context.Context, w *models.Works clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) - event := telemetry.ServerEventWorkspaceStarted + eventName := telemetry.WorkspaceEventLifecycleStarted if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceStartError + eventName = telemetry.WorkspaceEventLifecycleStartFailed } - telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { - log.Trace(err) + log.Trace(telemetryError) } return err diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 5e6fbc59c8..2c41f15e53 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -33,15 +33,15 @@ func (s *WorkspaceService) handleStopError(ctx context.Context, w *models.Worksp clientId := telemetry.ClientId(ctx) - telemetryProps := telemetry.NewWorkspaceEventProps(ctx, w) - event := telemetry.ServerEventWorkspaceStopped + eventName := telemetry.WorkspaceEventLifecycleStopped if err != nil { - telemetryProps["error"] = err.Error() - event = telemetry.ServerEventWorkspaceStopError + eventName = telemetry.WorkspaceEventLifecycleStopFailed } - telemetryError := s.trackTelemetryEvent(event, clientId, telemetryProps) + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) if telemetryError != nil { - log.Trace(err) + log.Trace(telemetryError) } return err diff --git a/pkg/server/workspacetemplates/prebuild.go b/pkg/server/workspacetemplates/prebuild.go index 2b569e3e69..e0cd7cca52 100644 --- a/pkg/server/workspacetemplates/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -5,7 +5,6 @@ package workspacetemplates import ( "context" - "errors" "fmt" "sort" @@ -18,89 +17,6 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceTemplateService) SetPrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto services.CreatePrebuildDTO) (*services.PrebuildDTO, error) { - workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ - Name: &workspaceTemplateName, - }) - if err != nil { - return nil, err - } - - existingPrebuild, _ := workspaceTemplate.FindPrebuild(&models.MatchParams{ - Branch: &createPrebuildDto.Branch, - }) - - if existingPrebuild != nil && createPrebuildDto.Id == nil { - return nil, errors.New("prebuild for the specified workspace template and branch already exists") - } - - if createPrebuildDto.CommitInterval == nil && len(createPrebuildDto.TriggerFiles) == 0 { - return nil, errors.New("either the commit interval or trigger files must be specified") - } - - repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl) - if err != nil { - return nil, err - } - - prebuild := &models.PrebuildConfig{ - Branch: createPrebuildDto.Branch, - CommitInterval: createPrebuildDto.CommitInterval, - TriggerFiles: createPrebuildDto.TriggerFiles, - Retention: createPrebuildDto.Retention, - } - - if createPrebuildDto.Id != nil { - prebuild.Id = *createPrebuildDto.Id - } else { - err = prebuild.GenerateId() - if err != nil { - return nil, err - } - } - - err = workspaceTemplate.SetPrebuild(prebuild) - if err != nil { - return nil, err - } - - // Remember the new webhook ID in case config saving fails - newWebhookId := "" - - existingWebhookId, err := s.findPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) - if err != nil { - return nil, err - } - - if existingWebhookId == nil { - newWebhookId, err = s.registerPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) - if err != nil { - return nil, err - } - } - - err = s.templateStore.Save(ctx, workspaceTemplate) - if err != nil { - if newWebhookId != "" { - err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, newWebhookId) - if err != nil { - log.Error(err) - } - } - - return nil, err - } - - return &services.PrebuildDTO{ - Id: prebuild.Id, - WorkspaceTemplateName: workspaceTemplate.Name, - Branch: prebuild.Branch, - CommitInterval: prebuild.CommitInterval, - TriggerFiles: prebuild.TriggerFiles, - Retention: prebuild.Retention, - }, nil -} - func (s *WorkspaceTemplateService) FindPrebuild(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*services.PrebuildDTO, error) { wt, err := s.templateStore.Find(ctx, workspaceTemplateFilter) if err != nil { @@ -151,74 +67,6 @@ func (s *WorkspaceTemplateService) ListPrebuilds(ctx context.Context, workspaceT return result, nil } -func (s *WorkspaceTemplateService) DeletePrebuild(ctx context.Context, workspaceTemplateName string, id string, force bool) []error { - workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ - Name: &workspaceTemplateName, - }) - if err != nil { - return []error{err} - } - - // Get all prebuilds for this workspace template's repository URL and - // if this is the last prebuild, unregister the Git provider webhook - prebuilds, err := s.ListPrebuilds(ctx, &stores.WorkspaceTemplateFilter{ - Url: &workspaceTemplate.RepositoryUrl, - }, nil) - if err != nil { - return []error{err} - } - - if len(prebuilds) == 1 { - repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl) - if err != nil { - return []error{err} - } - - existingWebhookId, err := s.findPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) - if err != nil { - if force { - log.Error(err) - } else { - return []error{err} - } - } - - if existingWebhookId != nil { - err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, *existingWebhookId) - if err != nil { - if force { - log.Error(err) - } else { - return []error{err} - } - } - } - } - - errs := s.deleteBuilds(ctx, &id, nil, force) - if len(errs) > 0 { - if force { - for _, err := range errs { - log.Error(err) - } - } else { - return errs - } - } - - err = workspaceTemplate.RemovePrebuild(id) - if err != nil { - return []error{err} - } - - err = s.templateStore.Save(ctx, workspaceTemplate) - if err != nil { - return []error{err} - } - - return nil -} - // TODO: revise build trigger strategy // We should discuss if the function should throw if the build can not be created or move on to the next one func (s *WorkspaceTemplateService) ProcessGitEvent(ctx context.Context, data gitprovider.GitEventData) error { diff --git a/pkg/server/workspacetemplates/prebuild_delete.go b/pkg/server/workspacetemplates/prebuild_delete.go new file mode 100644 index 0000000000..94a9e480a2 --- /dev/null +++ b/pkg/server/workspacetemplates/prebuild_delete.go @@ -0,0 +1,104 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspacetemplates + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceTemplateService) DeletePrebuild(ctx context.Context, workspaceTemplateName string, id string, force bool) []error { + workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplateName, + }) + if err != nil { + return []error{s.handleDeletePrebuildError(ctx, nil, err)} + } + + // Get all prebuilds for this workspace template's repository URL and + // if this is the last prebuild, unregister the Git provider webhook + prebuilds, err := s.ListPrebuilds(ctx, &stores.WorkspaceTemplateFilter{ + Url: &workspaceTemplate.RepositoryUrl, + }, nil) + if err != nil { + return []error{s.handleDeletePrebuildError(ctx, workspaceTemplate, err)} + } + + if len(prebuilds) == 1 { + repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl) + if err != nil { + return []error{s.handleDeletePrebuildError(ctx, workspaceTemplate, err)} + } + + existingWebhookId, err := s.findPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) + if err != nil { + if force { + log.Error(s.handleDeletePrebuildError(ctx, workspaceTemplate, err)) + } else { + return []error{s.handleDeletePrebuildError(ctx, workspaceTemplate, err)} + } + } + + if existingWebhookId != nil { + err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, *existingWebhookId) + if err != nil { + if force { + log.Error(s.handleDeletePrebuildError(ctx, workspaceTemplate, err)) + } else { + return []error{s.handleDeletePrebuildError(ctx, workspaceTemplate, err)} + } + } + } + } + + errs := s.deleteBuilds(ctx, &id, nil, force) + if len(errs) > 0 { + for _, err := range errs { + err = s.handleDeletePrebuildError(ctx, workspaceTemplate, err) + if force { + log.Error(err) + } + } + if !force { + return errs + } + } + + err = workspaceTemplate.RemovePrebuild(id) + if err != nil { + return []error{s.handleDeletePrebuildError(ctx, workspaceTemplate, err)} + } + + err = s.templateStore.Save(ctx, workspaceTemplate) + err = s.handleDeletePrebuildError(ctx, workspaceTemplate, err) + if err != nil { + return []error{err} + } + + return nil +} + +func (s *WorkspaceTemplateService) handleDeletePrebuildError(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + eventName := telemetry.WorkspaceTemplateEventPrebuildDeleted + if err != nil { + eventName = telemetry.WorkspaceTemplateEventPrebuildDeletionFailed + } + + event := telemetry.NewWorkspaceTemplateEvent(eventName, workspaceTemplate, err, nil) + telemetryError := s.trackTelemetryEvent(event, telemetry.ClientId(ctx)) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/server/workspacetemplates/prebuild_save.go b/pkg/server/workspacetemplates/prebuild_save.go new file mode 100644 index 0000000000..ddd4b2040d --- /dev/null +++ b/pkg/server/workspacetemplates/prebuild_save.go @@ -0,0 +1,119 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspacetemplates + +import ( + "context" + "errors" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceTemplateService) SavePrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto services.CreatePrebuildDTO) (*services.PrebuildDTO, error) { + workspaceTemplate, err := s.Find(ctx, &stores.WorkspaceTemplateFilter{ + Name: &workspaceTemplateName, + }) + if err != nil { + return nil, s.handleSavePrebuildError(ctx, nil, err) + } + + existingPrebuild, _ := workspaceTemplate.FindPrebuild(&models.MatchParams{ + Branch: &createPrebuildDto.Branch, + }) + + if existingPrebuild != nil && createPrebuildDto.Id == nil { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, errors.New("prebuild for the specified workspace template and branch already exists")) + } + + if createPrebuildDto.CommitInterval == nil && len(createPrebuildDto.TriggerFiles) == 0 { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, errors.New("either the commit interval or trigger files must be specified")) + } + + repository, gitProviderId, err := s.getRepositoryContext(ctx, workspaceTemplate.RepositoryUrl) + if err != nil { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, err) + } + + prebuild := &models.PrebuildConfig{ + Branch: createPrebuildDto.Branch, + CommitInterval: createPrebuildDto.CommitInterval, + TriggerFiles: createPrebuildDto.TriggerFiles, + Retention: createPrebuildDto.Retention, + } + + if createPrebuildDto.Id != nil { + prebuild.Id = *createPrebuildDto.Id + } else { + err = prebuild.GenerateId() + if err != nil { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, err) + } + } + + err = workspaceTemplate.SetPrebuild(prebuild) + if err != nil { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, err) + } + + // Remember the new webhook ID in case config saving fails + newWebhookId := "" + + existingWebhookId, err := s.findPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) + if err != nil { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, err) + } + + if existingWebhookId == nil { + newWebhookId, err = s.registerPrebuildWebhook(ctx, gitProviderId, repository, s.prebuildWebhookEndpoint) + if err != nil { + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, err) + } + } + + err = s.templateStore.Save(ctx, workspaceTemplate) + if err != nil { + if newWebhookId != "" { + err = s.unregisterPrebuildWebhook(ctx, gitProviderId, repository, newWebhookId) + if err != nil { + log.Error(err) + } + } + + return nil, s.handleSavePrebuildError(ctx, workspaceTemplate, err) + } + + return &services.PrebuildDTO{ + Id: prebuild.Id, + WorkspaceTemplateName: workspaceTemplate.Name, + Branch: prebuild.Branch, + CommitInterval: prebuild.CommitInterval, + TriggerFiles: prebuild.TriggerFiles, + Retention: prebuild.Retention, + }, s.handleSavePrebuildError(ctx, workspaceTemplate, err) +} + +func (s *WorkspaceTemplateService) handleSavePrebuildError(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.WorkspaceTemplateEventPrebuildSaved + if err != nil { + eventName = telemetry.WorkspaceTemplateEventPrebuildSaveFailed + } + event := telemetry.NewWorkspaceTemplateEvent(eventName, workspaceTemplate, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/server/workspacetemplates/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go index 37de0b37ff..b4d886c3f0 100644 --- a/pkg/server/workspacetemplates/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -68,7 +68,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestSetPrebuild() { }).Return(repository1, nil) s.gitProviderService.On("GetPrebuildWebhook", "github", repository1, "").Return(util.Pointer("webhook-id"), nil) - newPrebuildDto, err := s.workspaceTemplateService.SetPrebuild(context.TODO(), workspaceTemplate1.Name, services.CreatePrebuildDTO{ + newPrebuildDto, err := s.workspaceTemplateService.SavePrebuild(context.TODO(), workspaceTemplate1.Name, services.CreatePrebuildDTO{ Id: &prebuild3.Id, Branch: prebuild3.Branch, CommitInterval: prebuild3.CommitInterval, diff --git a/pkg/server/workspacetemplates/service.go b/pkg/server/workspacetemplates/service.go index ac7f2c99ce..895d357892 100644 --- a/pkg/server/workspacetemplates/service.go +++ b/pkg/server/workspacetemplates/service.go @@ -12,6 +12,9 @@ import ( "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + + log "github.com/sirupsen/logrus" ) type WorkspaceTemplateServiceConfig struct { @@ -27,6 +30,7 @@ type WorkspaceTemplateServiceConfig struct { UnregisterPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error RegisterPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) GetCommitsRange func(ctx context.Context, repo *gitprovider.GitRepository, initialSha string, currentSha string) (int, error) + TrackTelemetryEvent func(event telemetry.Event, clientId string) error } type WorkspaceTemplateService struct { @@ -42,6 +46,7 @@ type WorkspaceTemplateService struct { findPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) unregisterPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error registerPrebuildWebhook func(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) + trackTelemetryEvent func(event telemetry.Event, clientId string) error } func NewWorkspaceTemplateService(config WorkspaceTemplateServiceConfig) services.IWorkspaceTemplateService { @@ -57,6 +62,7 @@ func NewWorkspaceTemplateService(config WorkspaceTemplateServiceConfig) services unregisterPrebuildWebhook: config.UnregisterPrebuildWebhook, registerPrebuildWebhook: config.RegisterPrebuildWebhook, getCommitsRange: config.GetCommitsRange, + trackTelemetryEvent: config.TrackTelemetryEvent, } } @@ -119,7 +125,23 @@ func (s *WorkspaceTemplateService) Find(ctx context.Context, filter *stores.Work func (s *WorkspaceTemplateService) Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error { workspaceTemplate.RepositoryUrl = util.CleanUpRepositoryUrl(workspaceTemplate.RepositoryUrl) + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.WorkspaceTemplateEventLifecycleSaved + err := s.templateStore.Save(ctx, workspaceTemplate) + if err != nil { + eventName = telemetry.WorkspaceTemplateEventLifecycleSaveFailed + } + + if telemetry.TelemetryEnabled(ctx) { + event := telemetry.NewWorkspaceTemplateEvent(eventName, workspaceTemplate, err, nil) + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + } + if err != nil { return err } @@ -132,7 +154,7 @@ func (s *WorkspaceTemplateService) Delete(ctx context.Context, workspaceTemplate Name: &workspaceTemplateName, }) if err != nil { - return []error{err} + return []error{s.handleDeleteError(ctx, nil, err)} } // DeletePrebuild handles deleting the builds and removing the webhook @@ -144,9 +166,31 @@ func (s *WorkspaceTemplateService) Delete(ctx context.Context, workspaceTemplate } err = s.templateStore.Delete(ctx, wt) + err = s.handleDeleteError(ctx, wt, err) if err != nil { return []error{err} } return nil } + +func (s *WorkspaceTemplateService) handleDeleteError(ctx context.Context, wt *models.WorkspaceTemplate, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.WorkspaceTemplateEventLifecycleDeleted + if err != nil { + eventName = telemetry.WorkspaceTemplateEventLifecycleDeletionFailed + } + event := telemetry.NewWorkspaceTemplateEvent(eventName, wt, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/services/runner.go b/pkg/services/runner.go index d08c4ee472..b1e6c53ef5 100644 --- a/pkg/services/runner.go +++ b/pkg/services/runner.go @@ -22,9 +22,9 @@ type IRunnerService interface { RemoveRunner(ctx context.Context, runnerId string) error ListProviders(ctx context.Context, runnerId *string) ([]models.ProviderInfo, error) - InstallProvider(ctx context.Context, runnerId string, providerMetadata InstallProviderDTO) error + InstallProvider(ctx context.Context, runnerId string, providerDto InstallProviderDTO) error UninstallProvider(ctx context.Context, runnerId string, providerName string) error - UpdateProvider(ctx context.Context, runnerId string, providerName string, downloadUrls DownloadUrls) error + UpdateProvider(ctx context.Context, runnerId string, providerName string, providerDto UpdateProviderDTO) error GetRunnerLogReader(ctx context.Context, runnerId string) (io.Reader, error) GetRunnerLogWriter(ctx context.Context, runnerId string) (io.WriteCloser, error) @@ -53,8 +53,14 @@ type UpdateJobStateDTO struct { type InstallProviderDTO struct { Name string `json:"name" validate:"required"` DownloadUrls DownloadUrls `json:"downloadUrls" validate:"required"` + Version string `json:"version" validate:"required"` } // @name InstallProviderDTO +type UpdateProviderDTO struct { + DownloadUrls DownloadUrls `json:"downloadUrls" validate:"required"` + Version string `json:"version" validate:"required"` +} // @name UpdateProviderDTO + type DownloadUrls map[os.OperatingSystem]string // @name DownloadUrls var ( diff --git a/pkg/services/workspace_template.go b/pkg/services/workspace_template.go index b5181839ed..ccd63db841 100644 --- a/pkg/services/workspace_template.go +++ b/pkg/services/workspace_template.go @@ -18,7 +18,7 @@ type IWorkspaceTemplateService interface { SetDefault(ctx context.Context, workspaceTemplateName string) error Delete(ctx context.Context, workspaceTemplateName string, force bool) []error - SetPrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) + SavePrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) FindPrebuild(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*PrebuildDTO, error) ListPrebuilds(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*PrebuildDTO, error) DeletePrebuild(ctx context.Context, workspaceTemplateName string, id string, force bool) []error diff --git a/pkg/telemetry/api_key.go b/pkg/telemetry/api_key.go new file mode 100644 index 0000000000..a0f24929d0 --- /dev/null +++ b/pkg/telemetry/api_key.go @@ -0,0 +1,40 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import "github.com/daytonaio/daytona/pkg/models" + +type ApiKeyEventName string + +const ( + ApiKeyEventLifecycleCreated ApiKeyEventName = "api_key_lifecycle_created" + ApiKeyEventLifecycleCreationFailed ApiKeyEventName = "api_key_lifecycle_creation_failed" +) + +type ApiKeyEvent struct { + key *models.ApiKey + AbstractEvent +} + +func NewApiKeyEvent(name ApiKeyEventName, key *models.ApiKey, err error, extras map[string]interface{}) Event { + return ApiKeyEvent{ + key: key, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e ApiKeyEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.key == nil { + return props + } + + props["type"] = e.key.Type + return props +} diff --git a/pkg/telemetry/build.go b/pkg/telemetry/build.go new file mode 100644 index 0000000000..a2fc9cc3a1 --- /dev/null +++ b/pkg/telemetry/build.go @@ -0,0 +1,55 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import "github.com/daytonaio/daytona/pkg/models" + +type BuildEventName string + +const ( + BuildEventLifecycleCreated BuildEventName = "build_lifecycle_created" + BuildEventLifecycleCreationFailed BuildEventName = "build_lifecycle_creation_failed" + BuildEventLifecycleDeleted BuildEventName = "build_lifecycle_deleted" + BuildEventLifecycleDeletionFailed BuildEventName = "build_lifecycle_deletion_failed" + BuildEventLifecycleForceDeleted BuildEventName = "build_lifecycle_force_deleted" + BuildEventLifecycleForceDeletionFailed BuildEventName = "build_lifecycle_force_deletion_failed" +) + +type buildEvent struct { + build *models.Build + AbstractEvent +} + +func NewBuildEvent(name BuildEventName, b *models.Build, err error, extras map[string]interface{}) Event { + return buildEvent{ + build: b, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e buildEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.build == nil { + return props + } + + props["build_id"] = e.build.Id + props["from_prebuild"] = e.build.PrebuildId != "" + if isImagePublic(e.build.ContainerConfig.Image) { + props["image"] = e.build.Image + } + + if e.build.Repository != nil && isPublic(e.build.Repository.Url) { + props["repository_url"] = e.build.Repository.Url + } + + props["builder"] = getBuilder(e.build.BuildConfig) + + return props +} diff --git a/pkg/telemetry/build_runner_events.go b/pkg/telemetry/build_runner_events.go deleted file mode 100644 index cc5dad8e52..0000000000 --- a/pkg/telemetry/build_runner_events.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package telemetry - -import ( - "context" -) - -type BuildRunnerEvent string - -const ( - // Purge events - BuildRunnerEventPurgeStarted BuildRunnerEvent = "build_runner_purge_started" - BuildRunnerEventPurgeCompleted BuildRunnerEvent = "build_runner_purge_completed" - BuildRunnerEventPurgeError BuildRunnerEvent = "build_runner_purge_error" - - // Build events - BuildRunnerEventRunBuild BuildRunnerEvent = "build_runner_run_build" - BuildRunnerEventRunBuildError BuildRunnerEvent = "build_runner_run_build_error" -) - -func NewBuildRunnerEventProps(ctx context.Context, buildId, buildState string) map[string]interface{} { - props := map[string]interface{}{} - - sessionId := SessionId(ctx) - serverId := ServerId(ctx) - - props["session_id"] = sessionId - props["server_id"] = serverId - - props["build_id"] = buildId - props["build_state"] = buildState - - return props -} diff --git a/pkg/telemetry/cli.go b/pkg/telemetry/cli.go new file mode 100644 index 0000000000..1588a77810 --- /dev/null +++ b/pkg/telemetry/cli.go @@ -0,0 +1,67 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "strings" + + "github.com/spf13/cobra" +) + +type CliEventName string + +const ( + CliEventCommandStarted CliEventName = "cli_command_started" + CliEventCommandCompleted CliEventName = "cli_command_completed" + CliEventCommandFailed CliEventName = "cli_command_failed" + CliEventCommandInvalid CliEventName = "cli_command_invalid" + CliEventCommandInterrupted CliEventName = "cli_command_interrupted" + CliEventTargetOpened CliEventName = "cli_target_opened" + CliEventTargetOpenFailed CliEventName = "cli_target_open_failed" + CliEventWorkspaceOpened CliEventName = "cli_workspace_opened" + CliEventWorkspaceOpenFailed CliEventName = "cli_workspace_open_failed" + CliEventDefaultIdeSet CliEventName = "cli_default_ide_set" +) + +type cliEvent struct { + AbstractEvent + cmd *cobra.Command + flags []string +} + +func NewCliEvent(name CliEventName, cmd *cobra.Command, flags []string, err error, extras map[string]interface{}) Event { + return cliEvent{ + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + cmd: cmd, + flags: flags, + } +} + +func (e cliEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.cmd == nil { + return props + } + + path := e.cmd.CommandPath() + + // Trim daytona from the path if a non-root command was invoked + // This prevents a `daytona` pileup in the telemetry data + if path != "daytona" { + path = strings.TrimPrefix(path, "daytona ") + } + + calledAs := e.cmd.CalledAs() + + props["command"] = path + props["called_as"] = calledAs + props["flags"] = e.flags + + return props +} diff --git a/pkg/telemetry/cli_events.go b/pkg/telemetry/cli_events.go deleted file mode 100644 index 175e9b9225..0000000000 --- a/pkg/telemetry/cli_events.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package telemetry - -type CliEvent string - -const ( - CliEventCmdStart CliEvent = "cli_cmd_start" - CliEventCmdEnd CliEvent = "cli_cmd_end" - CliEventInvalidCmd CliEvent = "cli_invalid_cmd" -) - -var AdditionalData map[string]interface{} = map[string]interface{}{} diff --git a/pkg/telemetry/constants.go b/pkg/telemetry/constants.go index 07114b28ec..57d3b3e0f8 100644 --- a/pkg/telemetry/constants.go +++ b/pkg/telemetry/constants.go @@ -20,8 +20,9 @@ var ( type TelemetrySource string var ( - CLI_SOURCE TelemetrySource = "cli" - CLI_WORKSPACE_SOURCE TelemetrySource = "cli-workspace" - AGENT_SOURCE TelemetrySource = "agent" - RUNNER_SOURCE TelemetrySource = "runner" + CLI_SOURCE TelemetrySource = "cli" + CLI_AGENT_MODE_SOURCE TelemetrySource = "cli_agent_mode" + AGENT_SOURCE TelemetrySource = "agent" + RUNNER_SOURCE TelemetrySource = "runner" + SERVER_SOURCE TelemetrySource = "server" ) diff --git a/pkg/telemetry/event.go b/pkg/telemetry/event.go new file mode 100644 index 0000000000..d7e48080f0 --- /dev/null +++ b/pkg/telemetry/event.go @@ -0,0 +1,32 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +type Event interface { + Name() string + Props() map[string]interface{} +} + +type AbstractEvent struct { + name string + extras map[string]interface{} + err error +} + +func (e AbstractEvent) Name() string { + return e.name +} + +func (e AbstractEvent) Props() map[string]interface{} { + props := map[string]interface{}{} + if e.err != nil { + props["error"] = e.err.Error() + } + + for k, v := range e.extras { + props[k] = v + } + + return props +} diff --git a/pkg/telemetry/git_provider_config.go b/pkg/telemetry/git_provider_config.go new file mode 100644 index 0000000000..b90a1bd9fc --- /dev/null +++ b/pkg/telemetry/git_provider_config.go @@ -0,0 +1,49 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import "github.com/daytonaio/daytona/pkg/models" + +type GitProviderConfigEventName string + +const ( + GitProviderConfigEventLifecycleSaved GitProviderConfigEventName = "git_provider_config_lifecycle_saved" + GitProviderConfigEventLifecycleSaveFailed GitProviderConfigEventName = "git_provider_config_lifecycle_save_failed" + GitProviderConfigEventLifecycleDeleted GitProviderConfigEventName = "git_provider_config_lifecycle_deleted" + GitProviderConfigEventLifecycleDeletionFailed GitProviderConfigEventName = "git_provider_config_lifecycle_deletion_failed" + GitProviderConfigEventLifecycleForceDeleted GitProviderConfigEventName = "git_provider_config_lifecycle_force_deleted" + GitProviderConfigEventLifecycleForceDeletionFailed GitProviderConfigEventName = "git_provider_config_lifecycle_force_deletion_failed" +) + +type GitProviderConfigEvent struct { + gitProviderConfig *models.GitProviderConfig + AbstractEvent +} + +func NewGitProviderConfigEvent(name GitProviderConfigEventName, b *models.GitProviderConfig, err error, extras map[string]interface{}) Event { + return GitProviderConfigEvent{ + gitProviderConfig: b, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e GitProviderConfigEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.gitProviderConfig == nil { + return props + } + + props["provider_id"] = e.gitProviderConfig.ProviderId + props["is_self_hosted"] = e.gitProviderConfig.BaseApiUrl != nil && *e.gitProviderConfig.BaseApiUrl != "" + if e.gitProviderConfig.SigningMethod != nil { + props["signing_method"] = *e.gitProviderConfig.SigningMethod + } + + return props +} diff --git a/pkg/telemetry/job.go b/pkg/telemetry/job.go new file mode 100644 index 0000000000..2a369c1c32 --- /dev/null +++ b/pkg/telemetry/job.go @@ -0,0 +1,54 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/models" +) + +type JobEventName string + +const ( + JobEventLifecycleCreated JobEventName = "job_lifecycle_created" + JobEventLifecycleCreationFailed JobEventName = "job_lifecycle_creation_failed" + JobEventRunStarted JobEventName = "job_run_started" + JobEventRunCompleted JobEventName = "job_run_completed" + JobEventRunFailed JobEventName = "job_run_failed" +) + +type jobEvent struct { + AbstractEvent + job *models.Job +} + +func NewJobEvent(name JobEventName, j *models.Job, err error, extras map[string]interface{}) Event { + return jobEvent{ + job: j, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e jobEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.job == nil { + return props + } + + props["job_id"] = e.job.Id + props["is_local_runner"] = e.job.RunnerId != nil && *e.job.RunnerId == common.LOCAL_RUNNER_ID + props["resource_type"] = e.job.ResourceType + props["job_action"] = e.job.Action + + if e.job.Error != nil { + props["job_error"] = *e.job.Error + } + + return props +} diff --git a/pkg/telemetry/runner.go b/pkg/telemetry/runner.go new file mode 100644 index 0000000000..9238a8e622 --- /dev/null +++ b/pkg/telemetry/runner.go @@ -0,0 +1,53 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/models" +) + +type RunnerEventName string + +const ( + RunnerEventLifecycleRegistered RunnerEventName = "runner_lifecycle_registered" + RunnerEventLifecycleRegistrationFailed RunnerEventName = "runner_lifecycle_registration_failed" + RunnerEventLifecycleDeleted RunnerEventName = "runner_lifecycle_deleted" + RunnerEventLifecycleDeletionFailed RunnerEventName = "runner_lifecycle_deletion_failed" + RunnerEventProviderInstalled RunnerEventName = "runner_provider_installed" + RunnerEventProviderInstallationFailed RunnerEventName = "runner_provider_installation_failed" + RunnerEventProviderUninstalled RunnerEventName = "runner_provider_uninstalled" + RunnerEventProviderUninstallationFailed RunnerEventName = "runer_provider_uninstallation_failed" + RunnerEventProviderUpdated RunnerEventName = "runner_provider_updated" + RunnerEventProviderUpdateFailed RunnerEventName = "runner_provider_update_failed" +) + +type runnerEvent struct { + AbstractEvent + runner *models.Runner +} + +func NewRunnerEvent(name RunnerEventName, r *models.Runner, err error, extras map[string]interface{}) Event { + return runnerEvent{ + runner: r, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e runnerEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.runner == nil { + return props + } + + props["runner_id"] = e.runner.Id + props["is_local_runner"] = e.runner.Id == common.LOCAL_RUNNER_ID + + return props +} diff --git a/pkg/telemetry/server_events.go b/pkg/telemetry/server_events.go deleted file mode 100644 index 344763f2e1..0000000000 --- a/pkg/telemetry/server_events.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2024 Daytona Platforms Inc. -// SPDX-License-Identifier: Apache-2.0 - -package telemetry - -import ( - "context" - "net/http" - "strings" - "time" - - "github.com/daytonaio/daytona/pkg/models" -) - -type ServerEvent string - -const ( - ServerEventApiRequestStarted ServerEvent = "server_api_request_started" - ServerEventApiResponseSent ServerEvent = "server_api_response_sent" - ServerEventPurgeStarted ServerEvent = "server_purge_started" - ServerEventPurgeCompleted ServerEvent = "server_purge_completed" - ServerEventPurgeError ServerEvent = "server_purge_error" - - // Target events - ServerEventTargetCreated ServerEvent = "server_target_created" - ServerEventTargetDestroyed ServerEvent = "server_target_destroyed" - ServerEventTargetStarted ServerEvent = "server_target_started" - ServerEventTargetStopped ServerEvent = "server_target_stopped" - ServerEventTargetCreateError ServerEvent = "server_target_created_error" - ServerEventTargetDestroyError ServerEvent = "server_target_destroyed_error" - ServerEventTargetStartError ServerEvent = "server_target_started_error" - ServerEventTargetStopError ServerEvent = "server_target_stopped_error" - - // Workspace events - ServerEventWorkspaceCreated ServerEvent = "server_workspace_created" - ServerEventWorkspaceDestroyed ServerEvent = "server_workspace_destroyed" - ServerEventWorkspaceStarted ServerEvent = "server_workspace_started" - ServerEventWorkspaceStopped ServerEvent = "server_workspace_stopped" - ServerEventWorkspaceCreateError ServerEvent = "server_workspace_created_error" - ServerEventWorkspaceDestroyError ServerEvent = "server_workspace_destroyed_error" - ServerEventWorkspaceStartError ServerEvent = "server_workspace_started_error" - ServerEventWorkspaceStopError ServerEvent = "server_workspace_stopped_error" -) - -func NewTargetEventProps(ctx context.Context, target *models.Target) map[string]interface{} { - props := map[string]interface{}{} - - sessionId := SessionId(ctx) - serverId := ServerId(ctx) - - props["session_id"] = sessionId - props["server_id"] = serverId - - if target != nil { - props["target_id"] = target.Id - props["target_name"] = target.Name - props["target_provider"] = target.TargetConfig.ProviderInfo.Name - props["target_provider_version"] = target.TargetConfig.ProviderInfo.Version - } - - return props -} - -func NewWorkspaceEventProps(ctx context.Context, workspace *models.Workspace) map[string]interface{} { - props := map[string]interface{}{} - - if workspace == nil { - return props - } - - props["workspace_provider"] = workspace.Target.TargetConfig.ProviderInfo.Name - props["workspace_provider_version"] = workspace.Target.TargetConfig.ProviderInfo.Version - - if isImagePublic(workspace.Image) { - props["workspace_image"] = workspace.Image - } - if workspace.Repository != nil && isPublic(workspace.Repository.Url) { - props["workspace_repository"] = workspace.Repository.Url - } - - if workspace.BuildConfig == nil { - props["workspace_builder"] = "none" - } else if workspace.BuildConfig.Devcontainer != nil { - props["workspace_builder"] = "devcontainer" - } else { - props["workspace_builder"] = "automatic" - } - - return props -} - -func isImagePublic(imageName string) bool { - if strings.Count(imageName, "/") < 2 { - if strings.Count(imageName, "/") == 0 { - return isPublic("https://hub.docker.com/_/" + imageName) - } - - return isPublic("https://hub.docker.com/r/" + imageName) - } - - return isPublic(imageName) -} - -func isPublic(url string) bool { - ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) - _, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) - cancel() - return err == nil -} diff --git a/pkg/telemetry/target.go b/pkg/telemetry/target.go new file mode 100644 index 0000000000..18edcd2d02 --- /dev/null +++ b/pkg/telemetry/target.go @@ -0,0 +1,60 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/models" +) + +type TargetEventName string + +const ( + TargetEventLifecycleCreated TargetEventName = "target_lifecycle_created" + TargetEventLifecycleCreationFailed TargetEventName = "target_lifecycle_creation_failed" + TargetEventLifecycleStarted TargetEventName = "target_lifecycle_started" + TargetEventLifecycleStartFailed TargetEventName = "target_lifecycle_start_failed" + TargetEventLifecycleRestarted TargetEventName = "target_lifecycle_restarted" + TargetEventLifecycleRestartFailed TargetEventName = "target_lifecycle_restart_failed" + TargetEventLifecycleStopped TargetEventName = "target_lifecycle_stopped" + TargetEventLifecycleStopFailed TargetEventName = "target_lifecycle_stop_failed" + TargetEventLifecycleDeleted TargetEventName = "target_lifecycle_deleted" + TargetEventLifecycleDeletionFailed TargetEventName = "target_lifecycle_deletion_failed" + TargetEventLifecycleForceDeleted TargetEventName = "target_lifecycle_force_deleted" + TargetEventLifecycleForceDeletionFailed TargetEventName = "target_lifecycle_force_deletion_failed" +) + +type targetEvent struct { + AbstractEvent + target *models.Target +} + +func NewTargetEvent(name TargetEventName, t *models.Target, err error, extras map[string]interface{}) Event { + return targetEvent{ + target: t, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e targetEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.target == nil { + return props + } + + props["target_id"] = e.target.Id + props["is_local_docker_target_config"] = common.IsLocalDockerTarget(e.target.TargetConfig.ProviderInfo.Name, e.target.TargetConfig.Options, e.target.TargetConfig.ProviderInfo.RunnerId) + props["provider_name"] = e.target.TargetConfig.ProviderInfo.Name + props["provider_version"] = e.target.TargetConfig.ProviderInfo.Version + props["target_config_deleted"] = e.target.TargetConfig.Deleted + props["agentless_target"] = e.target.TargetConfig.ProviderInfo.AgentlessTarget + props["is_local_runner"] = e.target.TargetConfig.ProviderInfo.RunnerId == common.LOCAL_RUNNER_ID + + return props +} diff --git a/pkg/telemetry/target_config.go b/pkg/telemetry/target_config.go new file mode 100644 index 0000000000..9674eaa2ac --- /dev/null +++ b/pkg/telemetry/target_config.go @@ -0,0 +1,51 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/models" +) + +type TargetConfigEventName string + +const ( + TargetConfigEventLifecycleCreated TargetConfigEventName = "target_config_lifecycle_created" + TargetConfigEventLifecycleCreationFailed TargetConfigEventName = "target_config_lifecycle_creation_failed" + TargetConfigEventLifecycleDeleted TargetConfigEventName = "target_config_lifecycle_deleted" + TargetConfigEventLifecycleDeletionFailed TargetConfigEventName = "target_config_lifecycle_deletion_failed" +) + +type targetConfigEvent struct { + AbstractEvent + targetConfig *models.TargetConfig +} + +func NewTargetConfigEvent(name TargetConfigEventName, tc *models.TargetConfig, err error, extras map[string]interface{}) Event { + return targetConfigEvent{ + targetConfig: tc, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e targetConfigEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.targetConfig == nil { + return props + } + + props["target_config_id"] = e.targetConfig.Id + props["provider_name"] = e.targetConfig.ProviderInfo.Name + props["provider_version"] = e.targetConfig.ProviderInfo.Version + props["deleted"] = e.targetConfig.Deleted + props["is_local_docker_target_config"] = common.IsLocalDockerTarget(e.targetConfig.ProviderInfo.Name, e.targetConfig.Options, e.targetConfig.ProviderInfo.RunnerId) + props["is_local_runner"] = e.targetConfig.ProviderInfo.RunnerId == common.LOCAL_RUNNER_ID + + return props +} diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index fe96781298..6fa07779ae 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -7,6 +7,10 @@ import ( "context" "fmt" "io" + "net/http" + "runtime" + "strings" + "time" "github.com/daytonaio/daytona/internal" "github.com/google/uuid" @@ -14,11 +18,7 @@ import ( type TelemetryService interface { io.Closer - TrackCliEvent(event CliEvent, clientId string, properties map[string]interface{}) error - TrackServerEvent(event ServerEvent, clientId string, properties map[string]interface{}) error - TrackRunnerEvent(event BuildRunnerEvent, clientId string, properties map[string]interface{}) error - TrackBuildRunnerEvent(event BuildRunnerEvent, clientId string, properties map[string]interface{}) error - SetCommonProps(properties map[string]interface{}) + Track(event Event, clientId string) error } func TelemetryEnabled(ctx context.Context) bool { @@ -59,17 +59,28 @@ func ServerId(ctx context.Context) string { return id } -type AbstractTelemetryService struct { - daytonaVersion string - TelemetryService +func SetCommonProps(version string, source TelemetrySource, properties map[string]interface{}) { + properties["daytona_version"] = version + properties["source"] = source + properties["os"] = runtime.GOOS + properties["arch"] = runtime.GOARCH } -func NewAbstractTelemetryService(version string) *AbstractTelemetryService { - return &AbstractTelemetryService{ - daytonaVersion: version, +func isImagePublic(imageName string) bool { + if strings.Count(imageName, "/") < 2 { + if strings.Count(imageName, "/") == 0 { + return isPublic("https://hub.docker.com/_/" + imageName) + } + + return isPublic("https://hub.docker.com/r/" + imageName) } + + return isPublic(imageName) } -func (t *AbstractTelemetryService) SetCommonProps(properties map[string]interface{}) { - properties["daytona_version"] = t.daytonaVersion +func isPublic(url string) bool { + ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) + _, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) + cancel() + return err == nil } diff --git a/pkg/telemetry/workspace.go b/pkg/telemetry/workspace.go new file mode 100644 index 0000000000..e6cb7e9c53 --- /dev/null +++ b/pkg/telemetry/workspace.go @@ -0,0 +1,75 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "github.com/daytonaio/daytona/pkg/common" + "github.com/daytonaio/daytona/pkg/models" +) + +type WorkspaceEventName string + +const ( + WorkspaceEventLifecycleCreated WorkspaceEventName = "workspace_lifecycle_created" + WorkspaceEventLifecycleCreationFailed WorkspaceEventName = "workspace_lifecycle_creation_failed" + WorkspaceEventLifecycleStarted WorkspaceEventName = "workspace_lifecycle_started" + WorkspaceEventLifecycleStartFailed WorkspaceEventName = "workspace_lifecycle_start_failed" + WorkspaceEventLifecycleRestarted WorkspaceEventName = "workspace_lifecycle_restarted" + WorkspaceEventLifecycleRestartFailed WorkspaceEventName = "workspace_lifecycle_restart_failed" + WorkspaceEventLifecycleStopped WorkspaceEventName = "workspace_lifecycle_stopped" + WorkspaceEventLifecycleStopFailed WorkspaceEventName = "workspace_lifecycle_stop_failed" + WorkspaceEventLifecycleDeleted WorkspaceEventName = "workspace_lifecycle_deleted" + WorkspaceEventLifecycleDeletionFailed WorkspaceEventName = "workspace_lifecycle_deletion_failed" + WorkspaceEventLifecycleForceDeleted WorkspaceEventName = "workspace_lifecycle_force_deleted" + WorkspaceEventLifecycleForceDeletionFailed WorkspaceEventName = "workspace_lifecycle_force_deletion_failed" +) + +type workspaceEvent struct { + AbstractEvent + workspace *models.Workspace +} + +func NewWorkspaceEvent(name WorkspaceEventName, w *models.Workspace, err error, extras map[string]interface{}) Event { + return workspaceEvent{ + workspace: w, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e workspaceEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.workspace == nil { + return props + } + + props["workspace_id"] = e.workspace.Id + props["is_local_docker_target_config"] = common.IsLocalDockerTarget(e.workspace.Target.TargetConfig.ProviderInfo.Name, e.workspace.Target.TargetConfig.Options, e.workspace.Target.TargetConfig.ProviderInfo.RunnerId) + props["provider_name"] = e.workspace.Target.TargetConfig.ProviderInfo.Name + props["provider_version"] = e.workspace.Target.TargetConfig.ProviderInfo.Version + if isImagePublic(e.workspace.Image) { + props["image"] = e.workspace.Image + } + if e.workspace.Repository != nil && isPublic(e.workspace.Repository.Url) { + props["repository_url"] = e.workspace.Repository.Url + } + props["builder"] = getBuilder(e.workspace.BuildConfig) + props["is_local_runner"] = e.workspace.Target.TargetConfig.ProviderInfo.RunnerId == common.LOCAL_RUNNER_ID + + return props +} + +func getBuilder(bc *models.BuildConfig) string { + if bc == nil { + return "none" + } else if bc.Devcontainer != nil { + return "devcontainer" + } else { + return "automatic" + } +} diff --git a/pkg/telemetry/workspace_template.go b/pkg/telemetry/workspace_template.go new file mode 100644 index 0000000000..033e9171b5 --- /dev/null +++ b/pkg/telemetry/workspace_template.go @@ -0,0 +1,60 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package telemetry + +import ( + "github.com/daytonaio/daytona/pkg/models" +) + +type WorkspaceTemplateEventName string + +var ( + WorkspaceTemplateEventLifecycleSaved WorkspaceTemplateEventName = "workspace_template_lifecycle_saved" + WorkspaceTemplateEventLifecycleSaveFailed WorkspaceTemplateEventName = "workspace_template_lifecycle_save_failed" + WorkspaceTemplateEventLifecycleDeleted WorkspaceTemplateEventName = "workspace_template_lifecycle_deleted" + WorkspaceTemplateEventLifecycleDeletionFailed WorkspaceTemplateEventName = "workspace_template_lifecycle_deletion_failed" + WorkspaceTemplateEventPrebuildSaved WorkspaceTemplateEventName = "workspace_template_prebuild_saved" + WorkspaceTemplateEventPrebuildSaveFailed WorkspaceTemplateEventName = "workspace_template_prebuild_save_failed" + WorkspaceTemplateEventPrebuildDeleted WorkspaceTemplateEventName = "workspace_template_prebuild_deleted" + WorkspaceTemplateEventPrebuildDeletionFailed WorkspaceTemplateEventName = "workspace_template_prebuild_deletion_failed" +) + +type workspaceTemplateEvent struct { + AbstractEvent + workspaceTemplate *models.WorkspaceTemplate +} + +func NewWorkspaceTemplateEvent(name WorkspaceTemplateEventName, wt *models.WorkspaceTemplate, err error, extras map[string]interface{}) Event { + return workspaceTemplateEvent{ + workspaceTemplate: wt, + AbstractEvent: AbstractEvent{ + name: string(name), + extras: extras, + err: err, + }, + } +} + +func (e workspaceTemplateEvent) Props() map[string]interface{} { + props := e.AbstractEvent.Props() + + if e.workspaceTemplate == nil { + return props + } + + props["workspace_template_name"] = e.workspaceTemplate.Name + props["prebuilds"] = e.workspaceTemplate.Prebuilds + + if isImagePublic(e.workspaceTemplate.Image) { + props["image"] = e.workspaceTemplate.Image + } + + if isPublic(e.workspaceTemplate.RepositoryUrl) { + props["repository_url"] = e.workspaceTemplate.RepositoryUrl + } + + props["builder"] = getBuilder(e.workspaceTemplate.BuildConfig) + + return props +} diff --git a/pkg/views/runner/configure.go b/pkg/views/runner/configure.go index ab70444a32..6fdf33be51 100644 --- a/pkg/views/runner/configure.go +++ b/pkg/views/runner/configure.go @@ -74,6 +74,9 @@ func (m *Model) createForm() *huh.Form { Title("Providers Directory"). Description("Directory will be created if it does not exist"). Value(&m.config.ProvidersDir), + huh.NewConfirm(). + Title("Telemetry Enabled"). + Value(&m.config.TelemetryEnabled), ), huh.NewGroup( huh.NewInput(). diff --git a/pkg/views/server/runner/notify.go b/pkg/views/server/runner/notify.go index cfc5e4eb3d..cf738cc97f 100644 --- a/pkg/views/server/runner/notify.go +++ b/pkg/views/server/runner/notify.go @@ -12,14 +12,17 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func Notify(runner *apiclient.RegisterRunnerResultDTO, apiUrl string) { +func Notify(runner *apiclient.RegisterRunnerResultDTO, apiUrl, clientId string, telemetryDisabled bool) { var output string output += fmt.Sprintf("You can connect the Runner %s to the Daytona Server by running this command on the Runner's machine:", runner.Name) views.RenderContainerLayout(views.GetInfoMessage(output)) - command := fmt.Sprintf("daytona runner configure --api-url %s --api-key %s --id %s --name %s", apiUrl, runner.ApiKey, runner.Id, runner.Name) + command := fmt.Sprintf("daytona runner configure --api-url %s --api-key %s --id %s --name %s --client-id %s", apiUrl, runner.ApiKey, runner.Id, runner.Name, clientId) + if telemetryDisabled { + command += " --disable-telemetry" + } fmt.Println(lipgloss.NewStyle().Padding(0).Foreground(views.Green).Render(command)) if err := clipboard.WriteAll(command); err == nil { From 73265f3a9dd90818260f11fec8f37ce1120ab0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Mon, 13 Jan 2025 16:22:25 +0100 Subject: [PATCH 43/76] fix: remove key hash when listing api-keys (#1703) Signed-off-by: Luka Brecic --- docs/daytona_purge.md | 2 +- docs/daytona_runner_purge.md | 2 +- hack/docs/daytona_purge.yaml | 2 +- hack/docs/daytona_runner_purge.yaml | 2 +- internal/apikeys/functions.go | 19 ---- pkg/api/controllers/apikey/apikey.go | 27 ++++- pkg/api/controllers/apikey/dto/apikey.go | 12 +++ pkg/api/docs/docs.go | 11 +-- pkg/api/docs/swagger.json | 11 +-- pkg/api/docs/swagger.yaml | 11 +-- pkg/api/middlewares/auth.go | 18 +--- pkg/api/middlewares/runner.go | 9 +- pkg/api/middlewares/workspace.go | 9 +- pkg/api/util/token.go | 23 +++++ pkg/apiclient/README.md | 2 +- pkg/apiclient/api/openapi.yaml | 13 ++- pkg/apiclient/api_api_key.go | 8 +- pkg/apiclient/docs/ApiKeyAPI.md | 6 +- .../docs/{ApiKey.md => ApiKeyViewDTO.md} | 48 ++++----- ...l_api_key.go => model_api_key_view_dto.go} | 99 +++++++++---------- pkg/cmd/apikey/api_key.go | 2 +- pkg/cmd/apikey/generate.go | 5 +- pkg/cmd/apikey/revoke.go | 31 ++---- pkg/server/apikeys/apikeys.go | 19 +++- pkg/services/api_key.go | 8 +- pkg/views/apikey/create.go | 2 +- pkg/views/apikey/list.go | 6 +- pkg/views/apikey/select.go | 4 +- pkg/views/apikey/view.go | 4 +- 29 files changed, 213 insertions(+), 202 deletions(-) create mode 100644 pkg/api/controllers/apikey/dto/apikey.go create mode 100644 pkg/api/util/token.go rename pkg/apiclient/docs/{ApiKey.md => ApiKeyViewDTO.md} (56%) rename pkg/apiclient/{model_api_key.go => model_api_key_view_dto.go} (54%) diff --git a/docs/daytona_purge.md b/docs/daytona_purge.md index ca5f4af20d..0b9b699151 100644 --- a/docs/daytona_purge.md +++ b/docs/daytona_purge.md @@ -14,7 +14,7 @@ daytona purge [flags] ``` -f, --force Delete all targets by force - -y, --yes Execute purge without prompt + -y, --yes Execute purge without a prompt ``` ### Options inherited from parent commands diff --git a/docs/daytona_runner_purge.md b/docs/daytona_runner_purge.md index 9f8a3437ef..19ea313d08 100644 --- a/docs/daytona_runner_purge.md +++ b/docs/daytona_runner_purge.md @@ -9,7 +9,7 @@ daytona runner purge [flags] ### Options ``` - -y, --yes Execute Daytona Runner purge without prompt + -y, --yes Execute Daytona Runner purge without a prompt ``` ### Options inherited from parent commands diff --git a/hack/docs/daytona_purge.yaml b/hack/docs/daytona_purge.yaml index f68628140e..73d34c8aa5 100644 --- a/hack/docs/daytona_purge.yaml +++ b/hack/docs/daytona_purge.yaml @@ -11,7 +11,7 @@ options: - name: "yes" shorthand: "y" default_value: "false" - usage: Execute purge without prompt + usage: Execute purge without a prompt inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_runner_purge.yaml b/hack/docs/daytona_runner_purge.yaml index 7c62f4d303..d5c53af30e 100644 --- a/hack/docs/daytona_runner_purge.yaml +++ b/hack/docs/daytona_runner_purge.yaml @@ -5,7 +5,7 @@ options: - name: "yes" shorthand: "y" default_value: "false" - usage: Execute Daytona Runner purge without prompt + usage: Execute Daytona Runner purge without a prompt inherited_options: - name: help default_value: "false" diff --git a/internal/apikeys/functions.go b/internal/apikeys/functions.go index acd4d6c21d..d5d4939f7a 100644 --- a/internal/apikeys/functions.go +++ b/internal/apikeys/functions.go @@ -5,7 +5,6 @@ package apikeys import ( "encoding/base64" - "encoding/json" "github.com/daytonaio/daytona/internal/util" "github.com/google/uuid" @@ -20,21 +19,3 @@ func GenerateRandomKey() string { uuid := uuid.NewString() return base64.RawStdEncoding.EncodeToString([]byte(uuid)) } - -// Helper function that compares a key with a hash gotten from the API -func EqualsKeyHashFromApi(key string, keyHashFromApi string) bool { - var keyHash string - // We need to marshal then unmarshal the key to mimic the behavior of the API - // Without this, the hash will be different on a byte level - jsonString, err := json.Marshal(HashKey(key)) - if err != nil { - return false - } - - err = json.Unmarshal(jsonString, &keyHash) - if err != nil { - return false - } - - return keyHash == keyHashFromApi -} diff --git a/pkg/api/controllers/apikey/apikey.go b/pkg/api/controllers/apikey/apikey.go index 576fd0b643..b87c9119ff 100644 --- a/pkg/api/controllers/apikey/apikey.go +++ b/pkg/api/controllers/apikey/apikey.go @@ -7,7 +7,11 @@ import ( "fmt" "net/http" + internal_util "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/api/controllers/apikey/dto" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" + "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" ) @@ -17,20 +21,26 @@ import ( // @Summary List API keys // @Description List API keys // @Produce json -// @Success 200 {array} ApiKey +// @Success 200 {array} ApiKeyViewDTO // @Router /apikey [get] // // @id ListClientApiKeys func ListClientApiKeys(ctx *gin.Context) { server := server.GetInstance(nil) + currentApiKeyName, _ := server.ApiKeyService.GetApiKeyName(ctx.Request.Context(), util.ExtractToken(ctx)) + response, err := server.ApiKeyService.ListClientKeys(ctx.Request.Context()) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get client API keys: %w", err)) return } - ctx.JSON(200, response) + result := internal_util.ArrayMap(response, func(key *services.ApiKeyDTO) dto.ApiKeyViewDTO { + return dto.ApiKeyViewDTO{Name: key.Name, Type: key.Type, Current: key.Name == currentApiKeyName} + }) + + ctx.JSON(200, result) } // RevokeApiKey godoc @@ -48,7 +58,18 @@ func RevokeApiKey(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.ApiKeyService.Revoke(ctx.Request.Context(), apiKeyName) + currentApiKeyName, err := server.ApiKeyService.GetApiKeyName(ctx.Request.Context(), util.ExtractToken(ctx)) + if err != nil { + ctx.AbortWithError(http.StatusNotFound, fmt.Errorf("failed to get current api key name: %w", err)) + return + } + + if currentApiKeyName == apiKeyName { + ctx.AbortWithError(http.StatusForbidden, fmt.Errorf("cannot revoke current api key")) + return + } + + err = server.ApiKeyService.Revoke(ctx.Request.Context(), apiKeyName) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to revoke api key: %w", err)) return diff --git a/pkg/api/controllers/apikey/dto/apikey.go b/pkg/api/controllers/apikey/dto/apikey.go new file mode 100644 index 0000000000..27aeb6ffbe --- /dev/null +++ b/pkg/api/controllers/apikey/dto/apikey.go @@ -0,0 +1,12 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package dto + +import "github.com/daytonaio/daytona/pkg/models" + +type ApiKeyViewDTO struct { + Type models.ApiKeyType `json:"type" validate:"required"` + Name string `json:"name" validate:"required"` + Current bool `json:"current" validate:"required"` +} // @name ApiKeyViewDTO diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index f3626c40c6..4335973976 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -32,7 +32,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/ApiKey" + "$ref": "#/definitions/ApiKeyViewDTO" } } } @@ -3743,19 +3743,18 @@ const docTemplate = `{ } } }, - "ApiKey": { + "ApiKeyViewDTO": { "type": "object", "required": [ - "keyHash", + "current", "name", "type" ], "properties": { - "keyHash": { - "type": "string" + "current": { + "type": "boolean" }, "name": { - "description": "Workspace or client name", "type": "string" }, "type": { diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index fe1383980d..766a777026 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -29,7 +29,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/ApiKey" + "$ref": "#/definitions/ApiKeyViewDTO" } } } @@ -3740,19 +3740,18 @@ } } }, - "ApiKey": { + "ApiKeyViewDTO": { "type": "object", "required": [ - "keyHash", + "current", "name", "type" ], "properties": { - "keyHash": { - "type": "string" + "current": { + "type": "boolean" }, "name": { - "description": "Workspace or client name", "type": "string" }, "type": { diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index e8905c6448..f5d7254cd5 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -13,17 +13,16 @@ definitions: - options - providerInfo type: object - ApiKey: + ApiKeyViewDTO: properties: - keyHash: - type: string + current: + type: boolean name: - description: Workspace or client name type: string type: $ref: '#/definitions/models.ApiKeyType' required: - - keyHash + - current - name - type type: object @@ -1618,7 +1617,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/ApiKey' + $ref: '#/definitions/ApiKeyViewDTO' type: array summary: List API keys tags: diff --git a/pkg/api/middlewares/auth.go b/pkg/api/middlewares/auth.go index 3f7f5ee4d6..5135d80024 100644 --- a/pkg/api/middlewares/auth.go +++ b/pkg/api/middlewares/auth.go @@ -5,21 +5,15 @@ package middlewares import ( "errors" - "strings" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" ) func AuthMiddleware() gin.HandlerFunc { return func(ctx *gin.Context) { - bearerToken := ctx.GetHeader("Authorization") - if bearerToken == "" { - ctx.AbortWithError(401, errors.New("unauthorized")) - return - } - - token := ExtractToken(bearerToken) + token := util.ExtractToken(ctx) if token == "" { ctx.AbortWithError(401, errors.New("unauthorized")) return @@ -42,11 +36,3 @@ func AuthMiddleware() gin.HandlerFunc { ctx.Next() } } - -func ExtractToken(bearerToken string) string { - if !strings.HasPrefix(bearerToken, "Bearer ") { - return "" - } - - return strings.TrimPrefix(bearerToken, "Bearer ") -} diff --git a/pkg/api/middlewares/runner.go b/pkg/api/middlewares/runner.go index 07d500823b..a3e4f098f0 100644 --- a/pkg/api/middlewares/runner.go +++ b/pkg/api/middlewares/runner.go @@ -6,6 +6,7 @@ package middlewares import ( "errors" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" @@ -13,13 +14,7 @@ import ( func RunnerAuthMiddleware() gin.HandlerFunc { return func(ctx *gin.Context) { - bearerToken := ctx.GetHeader("Authorization") - if bearerToken == "" { - ctx.AbortWithError(401, errors.New("unauthorized")) - return - } - - token := ExtractToken(bearerToken) + token := util.ExtractToken(ctx) if token == "" { ctx.AbortWithError(401, errors.New("unauthorized")) return diff --git a/pkg/api/middlewares/workspace.go b/pkg/api/middlewares/workspace.go index 7f512559c9..dd4b63c3bc 100644 --- a/pkg/api/middlewares/workspace.go +++ b/pkg/api/middlewares/workspace.go @@ -6,6 +6,7 @@ package middlewares import ( "errors" + "github.com/daytonaio/daytona/pkg/api/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/gin-gonic/gin" @@ -13,13 +14,7 @@ import ( func WorkspaceAuthMiddleware() gin.HandlerFunc { return func(ctx *gin.Context) { - bearerToken := ctx.GetHeader("Authorization") - if bearerToken == "" { - ctx.AbortWithError(401, errors.New("unauthorized")) - return - } - - token := ExtractToken(bearerToken) + token := util.ExtractToken(ctx) if token == "" { ctx.AbortWithError(401, errors.New("unauthorized")) return diff --git a/pkg/api/util/token.go b/pkg/api/util/token.go new file mode 100644 index 0000000000..2e192fd2cb --- /dev/null +++ b/pkg/api/util/token.go @@ -0,0 +1,23 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "strings" + + "github.com/gin-gonic/gin" +) + +func ExtractToken(ctx *gin.Context) string { + bearerToken := ctx.GetHeader("Authorization") + if bearerToken == "" { + return "" + } + + if !strings.HasPrefix(bearerToken, "Bearer ") { + return "" + } + + return strings.TrimPrefix(bearerToken, "Bearer ") +} diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index fd067d530a..2b8cb63398 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -194,7 +194,7 @@ Class | Method | HTTP request | Description ## Documentation For Models - [AddTargetConfigDTO](docs/AddTargetConfigDTO.md) - - [ApiKey](docs/ApiKey.md) + - [ApiKeyViewDTO](docs/ApiKeyViewDTO.md) - [BuildConfig](docs/BuildConfig.md) - [BuildDTO](docs/BuildDTO.md) - [CachedBuild](docs/CachedBuild.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index e3950d9f25..f1fd84bb4a 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -19,7 +19,7 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/ApiKey' + $ref: '#/components/schemas/ApiKeyViewDTO' type: array description: OK summary: List API keys @@ -2757,21 +2757,20 @@ components: - options - providerInfo type: object - ApiKey: + ApiKeyViewDTO: example: - keyHash: keyHash + current: true name: name type: null properties: - keyHash: - type: string + current: + type: boolean name: - description: Workspace or client name type: string type: $ref: '#/components/schemas/models.ApiKeyType' required: - - keyHash + - current - name - type type: object diff --git a/pkg/apiclient/api_api_key.go b/pkg/apiclient/api_api_key.go index 412ac79c2c..535d8219c5 100644 --- a/pkg/apiclient/api_api_key.go +++ b/pkg/apiclient/api_api_key.go @@ -145,7 +145,7 @@ type ApiListClientApiKeysRequest struct { ApiService *ApiKeyAPIService } -func (r ApiListClientApiKeysRequest) Execute() ([]ApiKey, *http.Response, error) { +func (r ApiListClientApiKeysRequest) Execute() ([]ApiKeyViewDTO, *http.Response, error) { return r.ApiService.ListClientApiKeysExecute(r) } @@ -166,13 +166,13 @@ func (a *ApiKeyAPIService) ListClientApiKeys(ctx context.Context) ApiListClientA // Execute executes the request // -// @return []ApiKey -func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysRequest) ([]ApiKey, *http.Response, error) { +// @return []ApiKeyViewDTO +func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysRequest) ([]ApiKeyViewDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []ApiKey + localVarReturnValue []ApiKeyViewDTO ) localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.ListClientApiKeys") diff --git a/pkg/apiclient/docs/ApiKeyAPI.md b/pkg/apiclient/docs/ApiKeyAPI.md index 99e12717b5..3739ec7a67 100644 --- a/pkg/apiclient/docs/ApiKeyAPI.md +++ b/pkg/apiclient/docs/ApiKeyAPI.md @@ -82,7 +82,7 @@ Name | Type | Description | Notes ## ListClientApiKeys -> []ApiKey ListClientApiKeys(ctx).Execute() +> []ApiKeyViewDTO ListClientApiKeys(ctx).Execute() List API keys @@ -109,7 +109,7 @@ func main() { fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.ListClientApiKeys``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListClientApiKeys`: []ApiKey + // response from `ListClientApiKeys`: []ApiKeyViewDTO fmt.Fprintf(os.Stdout, "Response from `ApiKeyAPI.ListClientApiKeys`: %v\n", resp) } ``` @@ -125,7 +125,7 @@ Other parameters are passed through a pointer to a apiListClientApiKeysRequest s ### Return type -[**[]ApiKey**](ApiKey.md) +[**[]ApiKeyViewDTO**](ApiKeyViewDTO.md) ### Authorization diff --git a/pkg/apiclient/docs/ApiKey.md b/pkg/apiclient/docs/ApiKeyViewDTO.md similarity index 56% rename from pkg/apiclient/docs/ApiKey.md rename to pkg/apiclient/docs/ApiKeyViewDTO.md index 15ad2efb40..c15444aefc 100644 --- a/pkg/apiclient/docs/ApiKey.md +++ b/pkg/apiclient/docs/ApiKeyViewDTO.md @@ -1,88 +1,88 @@ -# ApiKey +# ApiKeyViewDTO ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**KeyHash** | **string** | | -**Name** | **string** | Workspace or client name | +**Current** | **bool** | | +**Name** | **string** | | **Type** | [**ModelsApiKeyType**](ModelsApiKeyType.md) | | ## Methods -### NewApiKey +### NewApiKeyViewDTO -`func NewApiKey(keyHash string, name string, type_ ModelsApiKeyType, ) *ApiKey` +`func NewApiKeyViewDTO(current bool, name string, type_ ModelsApiKeyType, ) *ApiKeyViewDTO` -NewApiKey instantiates a new ApiKey object +NewApiKeyViewDTO instantiates a new ApiKeyViewDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewApiKeyWithDefaults +### NewApiKeyViewDTOWithDefaults -`func NewApiKeyWithDefaults() *ApiKey` +`func NewApiKeyViewDTOWithDefaults() *ApiKeyViewDTO` -NewApiKeyWithDefaults instantiates a new ApiKey object +NewApiKeyViewDTOWithDefaults instantiates a new ApiKeyViewDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set -### GetKeyHash +### GetCurrent -`func (o *ApiKey) GetKeyHash() string` +`func (o *ApiKeyViewDTO) GetCurrent() bool` -GetKeyHash returns the KeyHash field if non-nil, zero value otherwise. +GetCurrent returns the Current field if non-nil, zero value otherwise. -### GetKeyHashOk +### GetCurrentOk -`func (o *ApiKey) GetKeyHashOk() (*string, bool)` +`func (o *ApiKeyViewDTO) GetCurrentOk() (*bool, bool)` -GetKeyHashOk returns a tuple with the KeyHash field if it's non-nil, zero value otherwise +GetCurrentOk returns a tuple with the Current field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. -### SetKeyHash +### SetCurrent -`func (o *ApiKey) SetKeyHash(v string)` +`func (o *ApiKeyViewDTO) SetCurrent(v bool)` -SetKeyHash sets KeyHash field to given value. +SetCurrent sets Current field to given value. ### GetName -`func (o *ApiKey) GetName() string` +`func (o *ApiKeyViewDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *ApiKey) GetNameOk() (*string, bool)` +`func (o *ApiKeyViewDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *ApiKey) SetName(v string)` +`func (o *ApiKeyViewDTO) SetName(v string)` SetName sets Name field to given value. ### GetType -`func (o *ApiKey) GetType() ModelsApiKeyType` +`func (o *ApiKeyViewDTO) GetType() ModelsApiKeyType` GetType returns the Type field if non-nil, zero value otherwise. ### GetTypeOk -`func (o *ApiKey) GetTypeOk() (*ModelsApiKeyType, bool)` +`func (o *ApiKeyViewDTO) GetTypeOk() (*ModelsApiKeyType, bool)` GetTypeOk returns a tuple with the Type field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetType -`func (o *ApiKey) SetType(v ModelsApiKeyType)` +`func (o *ApiKeyViewDTO) SetType(v ModelsApiKeyType)` SetType sets Type field to given value. diff --git a/pkg/apiclient/model_api_key.go b/pkg/apiclient/model_api_key_view_dto.go similarity index 54% rename from pkg/apiclient/model_api_key.go rename to pkg/apiclient/model_api_key_view_dto.go index 226adc61c2..3838c77456 100644 --- a/pkg/apiclient/model_api_key.go +++ b/pkg/apiclient/model_api_key_view_dto.go @@ -16,65 +16,64 @@ import ( "fmt" ) -// checks if the ApiKey type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &ApiKey{} +// checks if the ApiKeyViewDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ApiKeyViewDTO{} -// ApiKey struct for ApiKey -type ApiKey struct { - KeyHash string `json:"keyHash"` - // Workspace or client name - Name string `json:"name"` - Type ModelsApiKeyType `json:"type"` +// ApiKeyViewDTO struct for ApiKeyViewDTO +type ApiKeyViewDTO struct { + Current bool `json:"current"` + Name string `json:"name"` + Type ModelsApiKeyType `json:"type"` } -type _ApiKey ApiKey +type _ApiKeyViewDTO ApiKeyViewDTO -// NewApiKey instantiates a new ApiKey object +// NewApiKeyViewDTO instantiates a new ApiKeyViewDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewApiKey(keyHash string, name string, type_ ModelsApiKeyType) *ApiKey { - this := ApiKey{} - this.KeyHash = keyHash +func NewApiKeyViewDTO(current bool, name string, type_ ModelsApiKeyType) *ApiKeyViewDTO { + this := ApiKeyViewDTO{} + this.Current = current this.Name = name this.Type = type_ return &this } -// NewApiKeyWithDefaults instantiates a new ApiKey object +// NewApiKeyViewDTOWithDefaults instantiates a new ApiKeyViewDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewApiKeyWithDefaults() *ApiKey { - this := ApiKey{} +func NewApiKeyViewDTOWithDefaults() *ApiKeyViewDTO { + this := ApiKeyViewDTO{} return &this } -// GetKeyHash returns the KeyHash field value -func (o *ApiKey) GetKeyHash() string { +// GetCurrent returns the Current field value +func (o *ApiKeyViewDTO) GetCurrent() bool { if o == nil { - var ret string + var ret bool return ret } - return o.KeyHash + return o.Current } -// GetKeyHashOk returns a tuple with the KeyHash field value +// GetCurrentOk returns a tuple with the Current field value // and a boolean to check if the value has been set. -func (o *ApiKey) GetKeyHashOk() (*string, bool) { +func (o *ApiKeyViewDTO) GetCurrentOk() (*bool, bool) { if o == nil { return nil, false } - return &o.KeyHash, true + return &o.Current, true } -// SetKeyHash sets field value -func (o *ApiKey) SetKeyHash(v string) { - o.KeyHash = v +// SetCurrent sets field value +func (o *ApiKeyViewDTO) SetCurrent(v bool) { + o.Current = v } // GetName returns the Name field value -func (o *ApiKey) GetName() string { +func (o *ApiKeyViewDTO) GetName() string { if o == nil { var ret string return ret @@ -85,7 +84,7 @@ func (o *ApiKey) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *ApiKey) GetNameOk() (*string, bool) { +func (o *ApiKeyViewDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -93,12 +92,12 @@ func (o *ApiKey) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *ApiKey) SetName(v string) { +func (o *ApiKeyViewDTO) SetName(v string) { o.Name = v } // GetType returns the Type field value -func (o *ApiKey) GetType() ModelsApiKeyType { +func (o *ApiKeyViewDTO) GetType() ModelsApiKeyType { if o == nil { var ret ModelsApiKeyType return ret @@ -109,7 +108,7 @@ func (o *ApiKey) GetType() ModelsApiKeyType { // GetTypeOk returns a tuple with the Type field value // and a boolean to check if the value has been set. -func (o *ApiKey) GetTypeOk() (*ModelsApiKeyType, bool) { +func (o *ApiKeyViewDTO) GetTypeOk() (*ModelsApiKeyType, bool) { if o == nil { return nil, false } @@ -117,11 +116,11 @@ func (o *ApiKey) GetTypeOk() (*ModelsApiKeyType, bool) { } // SetType sets field value -func (o *ApiKey) SetType(v ModelsApiKeyType) { +func (o *ApiKeyViewDTO) SetType(v ModelsApiKeyType) { o.Type = v } -func (o ApiKey) MarshalJSON() ([]byte, error) { +func (o ApiKeyViewDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -129,20 +128,20 @@ func (o ApiKey) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o ApiKey) ToMap() (map[string]interface{}, error) { +func (o ApiKeyViewDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} - toSerialize["keyHash"] = o.KeyHash + toSerialize["current"] = o.Current toSerialize["name"] = o.Name toSerialize["type"] = o.Type return toSerialize, nil } -func (o *ApiKey) UnmarshalJSON(data []byte) (err error) { +func (o *ApiKeyViewDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. requiredProperties := []string{ - "keyHash", + "current", "name", "type", } @@ -161,53 +160,53 @@ func (o *ApiKey) UnmarshalJSON(data []byte) (err error) { } } - varApiKey := _ApiKey{} + varApiKeyViewDTO := _ApiKeyViewDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varApiKey) + err = decoder.Decode(&varApiKeyViewDTO) if err != nil { return err } - *o = ApiKey(varApiKey) + *o = ApiKeyViewDTO(varApiKeyViewDTO) return err } -type NullableApiKey struct { - value *ApiKey +type NullableApiKeyViewDTO struct { + value *ApiKeyViewDTO isSet bool } -func (v NullableApiKey) Get() *ApiKey { +func (v NullableApiKeyViewDTO) Get() *ApiKeyViewDTO { return v.value } -func (v *NullableApiKey) Set(val *ApiKey) { +func (v *NullableApiKeyViewDTO) Set(val *ApiKeyViewDTO) { v.value = val v.isSet = true } -func (v NullableApiKey) IsSet() bool { +func (v NullableApiKeyViewDTO) IsSet() bool { return v.isSet } -func (v *NullableApiKey) Unset() { +func (v *NullableApiKeyViewDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableApiKey(val *ApiKey) *NullableApiKey { - return &NullableApiKey{value: val, isSet: true} +func NewNullableApiKeyViewDTO(val *ApiKeyViewDTO) *NullableApiKeyViewDTO { + return &NullableApiKeyViewDTO{value: val, isSet: true} } -func (v NullableApiKey) MarshalJSON() ([]byte, error) { +func (v NullableApiKeyViewDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableApiKey) UnmarshalJSON(src []byte) error { +func (v *NullableApiKeyViewDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/cmd/apikey/api_key.go b/pkg/cmd/apikey/api_key.go index 703541bd96..378aa38d09 100644 --- a/pkg/cmd/apikey/api_key.go +++ b/pkg/cmd/apikey/api_key.go @@ -16,7 +16,7 @@ var ApiKeyCmd = &cobra.Command{ } func init() { - ApiKeyCmd.AddCommand(GenerateCmd) + ApiKeyCmd.AddCommand(generateCmd) ApiKeyCmd.AddCommand(revokeCmd) ApiKeyCmd.AddCommand(listCmd) } diff --git a/pkg/cmd/apikey/generate.go b/pkg/cmd/apikey/generate.go index 52ada83072..264cd05a64 100644 --- a/pkg/cmd/apikey/generate.go +++ b/pkg/cmd/apikey/generate.go @@ -12,11 +12,10 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" - "github.com/daytonaio/daytona/pkg/views/apikey" view "github.com/daytonaio/daytona/pkg/views/apikey" ) -var GenerateCmd = &cobra.Command{ +var generateCmd = &cobra.Command{ Use: "generate [NAME]", Short: "Generate a new API key", Aliases: []string{"g", "new"}, @@ -38,7 +37,7 @@ var GenerateCmd = &cobra.Command{ if len(args) == 1 { keyName = args[0] } else { - apikey.ApiKeyCreationView(&keyName, apiKeyList) + view.ApiKeyCreationView(&keyName, apiKeyList) } for _, key := range apiKeyList { diff --git a/pkg/cmd/apikey/revoke.go b/pkg/cmd/apikey/revoke.go index 8194d3c87b..439d3eb352 100644 --- a/pkg/cmd/apikey/revoke.go +++ b/pkg/cmd/apikey/revoke.go @@ -11,8 +11,6 @@ import ( "github.com/charmbracelet/huh" "github.com/spf13/cobra" - "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/apikeys" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/common" @@ -30,22 +28,12 @@ var revokeCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { return err } - var selectedApiKey *apiclient.ApiKey + var selectedApiKey *apiclient.ApiKeyViewDTO apiKeyList, _, err := apiClient.ApiKeyAPI.ListClientApiKeys(ctx).Execute() if err != nil { @@ -71,22 +59,15 @@ var revokeCmd = &cobra.Command{ } if selectedApiKey == nil { - return errors.New("No API key selected") + return errors.New("no API key selected") } if !yesFlag { - title := fmt.Sprintf("Revoke API Key '%s'?", selectedApiKey.Name) - description := fmt.Sprintf("Are you sure you want to revoke '%s'?", selectedApiKey.Name) - if apikeys.EqualsKeyHashFromApi(activeProfile.Api.Key, selectedApiKey.KeyHash) { - title = fmt.Sprintf("Warning! API Key '%s' is attached to your active profile", selectedApiKey.Name) - description = fmt.Sprintf("Revoking '%s' will lock out your active profile from accessing the server.", selectedApiKey.Name) - } - form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title(title). - Description(description). + Title(fmt.Sprintf("Revoke API Key '%s'?", selectedApiKey.Name)). + Description(fmt.Sprintf("Are you sure you want to revoke '%s'?", selectedApiKey.Name)). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -97,6 +78,10 @@ var revokeCmd = &cobra.Command{ } } + if selectedApiKey.Current { + return errors.New("cannot revoke current API key") + } + if yesFlag { res, err := apiClient.ApiKeyAPI.RevokeApiKey(ctx, selectedApiKey.Name).Execute() if err != nil { diff --git a/pkg/server/apikeys/apikeys.go b/pkg/server/apikeys/apikeys.go index 5b75e7d522..9ff82f148e 100644 --- a/pkg/server/apikeys/apikeys.go +++ b/pkg/server/apikeys/apikeys.go @@ -7,21 +7,25 @@ import ( "context" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" "github.com/daytonaio/daytona/pkg/telemetry" log "github.com/sirupsen/logrus" ) -func (s *ApiKeyService) ListClientKeys(ctx context.Context) ([]*models.ApiKey, error) { +func (s *ApiKeyService) ListClientKeys(ctx context.Context) ([]*services.ApiKeyDTO, error) { keys, err := s.apiKeyStore.List(ctx) if err != nil { return nil, err } - clientKeys := []*models.ApiKey{} + clientKeys := []*services.ApiKeyDTO{} for _, key := range keys { if key.Type == models.ApiKeyTypeClient { - clientKeys = append(clientKeys, key) + clientKeys = append(clientKeys, &services.ApiKeyDTO{ + Type: key.Type, + Name: key.Name, + }) } } @@ -54,6 +58,15 @@ func (s *ApiKeyService) Generate(ctx context.Context, keyType models.ApiKeyType, return key, s.handleGenerateApiKeyError(ctx, apiKey, nil) } +func (s *ApiKeyService) GetApiKeyName(ctx context.Context, apiKey string) (string, error) { + key, err := s.apiKeyStore.Find(ctx, s.getKeyHash(apiKey)) + if err != nil { + return "", err + } + + return key.Name, nil +} + func (s *ApiKeyService) handleGenerateApiKeyError(ctx context.Context, key *models.ApiKey, err error) error { if key.Type != models.ApiKeyTypeClient { return err diff --git a/pkg/services/api_key.go b/pkg/services/api_key.go index efda69dabd..c112e34051 100644 --- a/pkg/services/api_key.go +++ b/pkg/services/api_key.go @@ -13,6 +13,12 @@ type IApiKeyService interface { Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) GetApiKeyType(ctx context.Context, apiKey string) (models.ApiKeyType, error) IsValidApiKey(ctx context.Context, apiKey string) bool - ListClientKeys(ctx context.Context) ([]*models.ApiKey, error) + ListClientKeys(ctx context.Context) ([]*ApiKeyDTO, error) Revoke(ctx context.Context, name string) error + GetApiKeyName(ctx context.Context, apiKey string) (string, error) } + +type ApiKeyDTO struct { + Type models.ApiKeyType `json:"type" validate:"required"` + Name string `json:"name" validate:"required"` +} // @name ApiKeyDTO diff --git a/pkg/views/apikey/create.go b/pkg/views/apikey/create.go index 9e8e5d4520..6108d76850 100644 --- a/pkg/views/apikey/create.go +++ b/pkg/views/apikey/create.go @@ -13,7 +13,7 @@ import ( "github.com/charmbracelet/huh" ) -func ApiKeyCreationView(name *string, clientKeys []apiclient.ApiKey) { +func ApiKeyCreationView(name *string, clientKeys []apiclient.ApiKeyViewDTO) { form := huh.NewForm( huh.NewGroup( huh.NewInput(). diff --git a/pkg/views/apikey/list.go b/pkg/views/apikey/list.go index 002d20cfbc..e589b3834b 100644 --- a/pkg/views/apikey/list.go +++ b/pkg/views/apikey/list.go @@ -16,7 +16,7 @@ type RowData struct { Type string } -func ListApiKeys(apiKeyList []apiclient.ApiKey) { +func ListApiKeys(apiKeyList []apiclient.ApiKeyViewDTO) { data := [][]string{} for _, apiKey := range apiKeyList { @@ -32,7 +32,7 @@ func ListApiKeys(apiKeyList []apiclient.ApiKey) { fmt.Println(table) } -func getRowFromRowData(apiKey apiclient.ApiKey) []string { +func getRowFromRowData(apiKey apiclient.ApiKeyViewDTO) []string { rowData := RowData{"", ""} rowData.Name = apiKey.Name @@ -46,7 +46,7 @@ func getRowFromRowData(apiKey apiclient.ApiKey) []string { return row } -func renderUnstyledList(apiKeyList []apiclient.ApiKey) { +func renderUnstyledList(apiKeyList []apiclient.ApiKeyViewDTO) { output := "\n" for _, apiKey := range apiKeyList { diff --git a/pkg/views/apikey/select.go b/pkg/views/apikey/select.go index 393a01afe9..6bf3363559 100644 --- a/pkg/views/apikey/select.go +++ b/pkg/views/apikey/select.go @@ -13,7 +13,7 @@ import ( var NewApiKeyName = "+ New API Key" -func GetApiKeyFromPrompt(apiKeys []apiclient.ApiKey, title string, withNewApiKey bool) (*apiclient.ApiKey, error) { +func GetApiKeyFromPrompt(apiKeys []apiclient.ApiKeyViewDTO, title string, withNewApiKey bool) (*apiclient.ApiKeyViewDTO, error) { var items []list.Item for _, p := range apiKeys { @@ -25,7 +25,7 @@ func GetApiKeyFromPrompt(apiKeys []apiclient.ApiKey, title string, withNewApiKey if withNewApiKey { name := NewApiKeyName items = append(items, item{ - apiKey: apiclient.ApiKey{ + apiKey: apiclient.ApiKeyViewDTO{ Name: name, }, }) diff --git a/pkg/views/apikey/view.go b/pkg/views/apikey/view.go index 229c57441b..4178686149 100644 --- a/pkg/views/apikey/view.go +++ b/pkg/views/apikey/view.go @@ -14,7 +14,7 @@ import ( ) type item struct { - apiKey apiclient.ApiKey + apiKey apiclient.ApiKeyViewDTO } func (i item) Title() string { return i.apiKey.Name } @@ -25,7 +25,7 @@ func (i item) FilterValue() string { return i.apiKey.Name } type model struct { list list.Model - choice *apiclient.ApiKey + choice *apiclient.ApiKeyViewDTO } func (m model) Init() tea.Cmd { From 2bcc3907b1315fff39efe57fbe039e67eeb37f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Mon, 13 Jan 2025 16:25:47 +0100 Subject: [PATCH 44/76] fix: make prebuild ID optional for build (#1706) Signed-off-by: Luka Brecic --- internal/testing/build/store.go | 2 +- pkg/api/docs/docs.go | 1 - pkg/api/docs/swagger.json | 1 - pkg/api/docs/swagger.yaml | 1 - pkg/apiclient/api/openapi.yaml | 1 - pkg/apiclient/docs/BuildDTO.md | 9 +++-- pkg/apiclient/model_build_dto.go | 36 +++++++++++-------- pkg/models/build.go | 2 +- pkg/server/builds/create.go | 2 +- pkg/server/builds/service_test.go | 2 +- pkg/server/workspacetemplates/prebuild.go | 4 ++- .../workspacetemplates/prebuild_test.go | 10 +++--- pkg/telemetry/build.go | 2 +- pkg/views/build/info/view.go | 4 ++- pkg/views/build/list/view.go | 7 ++-- 15 files changed, 50 insertions(+), 34 deletions(-) diff --git a/internal/testing/build/store.go b/internal/testing/build/store.go index e65cf2b5a7..2edeb1629e 100644 --- a/internal/testing/build/store.go +++ b/internal/testing/build/store.go @@ -76,7 +76,7 @@ func (s *InMemoryBuildStore) processFilters(filter *stores.BuildFilter) ([]*mode for _, b := range filteredBuilds { check := false for _, prebuildId := range *filter.PrebuildIds { - if b.PrebuildId == prebuildId { + if b.PrebuildId != nil && *b.PrebuildId == prebuildId { check = true break } diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 4335973976..570c9908e6 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -3780,7 +3780,6 @@ const docTemplate = `{ "createdAt", "envVars", "id", - "prebuildId", "repository", "state", "updatedAt" diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 766a777026..3b75c7bdb0 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -3777,7 +3777,6 @@ "createdAt", "envVars", "id", - "prebuildId", "repository", "state", "updatedAt" diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index f5d7254cd5..d1b5d4b79d 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -66,7 +66,6 @@ definitions: - createdAt - envVars - id - - prebuildId - repository - state - updatedAt diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index f1fd84bb4a..93b2b1aad4 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -2864,7 +2864,6 @@ components: - createdAt - envVars - id - - prebuildId - repository - state - updatedAt diff --git a/pkg/apiclient/docs/BuildDTO.md b/pkg/apiclient/docs/BuildDTO.md index 7f2aa45f84..3bb5b605cd 100644 --- a/pkg/apiclient/docs/BuildDTO.md +++ b/pkg/apiclient/docs/BuildDTO.md @@ -11,7 +11,7 @@ Name | Type | Description | Notes **Id** | **string** | | **Image** | Pointer to **string** | | [optional] **LastJob** | Pointer to [**Job**](Job.md) | | [optional] -**PrebuildId** | **string** | | +**PrebuildId** | Pointer to **string** | | [optional] **Repository** | [**GitRepository**](GitRepository.md) | | **State** | [**ResourceState**](ResourceState.md) | | **UpdatedAt** | **string** | | @@ -21,7 +21,7 @@ Name | Type | Description | Notes ### NewBuildDTO -`func NewBuildDTO(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ResourceState, updatedAt string, ) *BuildDTO` +`func NewBuildDTO(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, repository GitRepository, state ResourceState, updatedAt string, ) *BuildDTO` NewBuildDTO instantiates a new BuildDTO object This constructor will assign default values to properties that have it defined, @@ -210,6 +210,11 @@ and a boolean to check if the value has been set. SetPrebuildId sets PrebuildId field to given value. +### HasPrebuildId + +`func (o *BuildDTO) HasPrebuildId() bool` + +HasPrebuildId returns a boolean if a field has been set. ### GetRepository diff --git a/pkg/apiclient/model_build_dto.go b/pkg/apiclient/model_build_dto.go index 7d4760f9af..f9c1eb0e71 100644 --- a/pkg/apiclient/model_build_dto.go +++ b/pkg/apiclient/model_build_dto.go @@ -28,7 +28,7 @@ type BuildDTO struct { Id string `json:"id"` Image *string `json:"image,omitempty"` LastJob *Job `json:"lastJob,omitempty"` - PrebuildId string `json:"prebuildId"` + PrebuildId *string `json:"prebuildId,omitempty"` Repository GitRepository `json:"repository"` State ResourceState `json:"state"` UpdatedAt string `json:"updatedAt"` @@ -41,13 +41,12 @@ type _BuildDTO BuildDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewBuildDTO(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, prebuildId string, repository GitRepository, state ResourceState, updatedAt string) *BuildDTO { +func NewBuildDTO(containerConfig ContainerConfig, createdAt string, envVars map[string]string, id string, repository GitRepository, state ResourceState, updatedAt string) *BuildDTO { this := BuildDTO{} this.ContainerConfig = containerConfig this.CreatedAt = createdAt this.EnvVars = envVars this.Id = id - this.PrebuildId = prebuildId this.Repository = repository this.State = state this.UpdatedAt = updatedAt @@ -254,28 +253,36 @@ func (o *BuildDTO) SetLastJob(v Job) { o.LastJob = &v } -// GetPrebuildId returns the PrebuildId field value +// GetPrebuildId returns the PrebuildId field value if set, zero value otherwise. func (o *BuildDTO) GetPrebuildId() string { - if o == nil { + if o == nil || IsNil(o.PrebuildId) { var ret string return ret } - - return o.PrebuildId + return *o.PrebuildId } -// GetPrebuildIdOk returns a tuple with the PrebuildId field value +// GetPrebuildIdOk returns a tuple with the PrebuildId field value if set, nil otherwise // and a boolean to check if the value has been set. func (o *BuildDTO) GetPrebuildIdOk() (*string, bool) { - if o == nil { + if o == nil || IsNil(o.PrebuildId) { return nil, false } - return &o.PrebuildId, true + return o.PrebuildId, true +} + +// HasPrebuildId returns a boolean if a field has been set. +func (o *BuildDTO) HasPrebuildId() bool { + if o != nil && !IsNil(o.PrebuildId) { + return true + } + + return false } -// SetPrebuildId sets field value +// SetPrebuildId gets a reference to the given string and assigns it to the PrebuildId field. func (o *BuildDTO) SetPrebuildId(v string) { - o.PrebuildId = v + o.PrebuildId = &v } // GetRepository returns the Repository field value @@ -405,7 +412,9 @@ func (o BuildDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } - toSerialize["prebuildId"] = o.PrebuildId + if !IsNil(o.PrebuildId) { + toSerialize["prebuildId"] = o.PrebuildId + } toSerialize["repository"] = o.Repository toSerialize["state"] = o.State toSerialize["updatedAt"] = o.UpdatedAt @@ -424,7 +433,6 @@ func (o *BuildDTO) UnmarshalJSON(data []byte) (err error) { "createdAt", "envVars", "id", - "prebuildId", "repository", "state", "updatedAt", diff --git a/pkg/models/build.go b/pkg/models/build.go index 1f7f2328c3..dbce8c20bb 100644 --- a/pkg/models/build.go +++ b/pkg/models/build.go @@ -20,7 +20,7 @@ type Build struct { Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json;not null"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` - PrebuildId string `json:"prebuildId" validate:"required" gorm:"not null"` + PrebuildId *string `json:"prebuildId" validate:"optional"` CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` } // @name Build diff --git a/pkg/server/builds/create.go b/pkg/server/builds/create.go index 389394dd9b..9b4986a6a0 100644 --- a/pkg/server/builds/create.go +++ b/pkg/server/builds/create.go @@ -45,7 +45,7 @@ func (s *BuildService) Create(ctx context.Context, b services.CreateBuildDTO) (s } if b.PrebuildId != nil { - newBuild.PrebuildId = *b.PrebuildId + newBuild.PrebuildId = b.PrebuildId } err = s.buildStore.Save(ctx, &newBuild) diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index 238252bd60..d44fb0b2eb 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -150,7 +150,7 @@ func (s *BuildServiceTestSuite) TestSave() { createBuildDto := services.CreateBuildDTO{ WorkspaceTemplateName: "workspaceTemplateName", Branch: "branch", - PrebuildId: &build4.PrebuildId, + PrebuildId: build4.PrebuildId, EnvVars: build4.EnvVars, } diff --git a/pkg/server/workspacetemplates/prebuild.go b/pkg/server/workspacetemplates/prebuild.go index e0cd7cca52..d51bdaf341 100644 --- a/pkg/server/workspacetemplates/prebuild.go +++ b/pkg/server/workspacetemplates/prebuild.go @@ -143,7 +143,9 @@ func (s *WorkspaceTemplateService) EnforceRetentionPolicy(ctx context.Context) e // Group builds by their prebuildId for _, b := range existingBuilds { - buildMap[b.PrebuildId] = append(buildMap[b.PrebuildId], b.Build) + if b.PrebuildId != nil && *b.PrebuildId != "" { + buildMap[*b.PrebuildId] = append(buildMap[*b.PrebuildId], b.Build) + } } for _, prebuild := range prebuilds { diff --git a/pkg/server/workspacetemplates/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go index b4d886c3f0..e9b4dd85d9 100644 --- a/pkg/server/workspacetemplates/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -147,7 +147,7 @@ func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventCommitInterval() GetNewest: util.Pointer(true), }).Return(&models.Build{ Id: "1", - PrebuildId: prebuild1.Id, + PrebuildId: &prebuild1.Id, Repository: repository1, }, nil) @@ -202,22 +202,22 @@ func (s *WorkspaceTemplateServiceTestSuite) TestEnforceRetentionPolicy() { }).Return([]*models.Build{ { Id: "1", - PrebuildId: "1", + PrebuildId: util.Pointer("1"), CreatedAt: time.Now().Add(time.Hour * -4), }, { Id: "2", - PrebuildId: "1", + PrebuildId: util.Pointer("1"), CreatedAt: time.Now().Add(time.Hour * -3), }, { Id: "3", - PrebuildId: "1", + PrebuildId: util.Pointer("1"), CreatedAt: time.Now().Add(time.Hour * -2), }, { Id: "4", - PrebuildId: "1", + PrebuildId: util.Pointer("1"), CreatedAt: time.Now().Add(time.Hour * -1), }, }, nil) diff --git a/pkg/telemetry/build.go b/pkg/telemetry/build.go index a2fc9cc3a1..021261cd83 100644 --- a/pkg/telemetry/build.go +++ b/pkg/telemetry/build.go @@ -40,7 +40,7 @@ func (e buildEvent) Props() map[string]interface{} { } props["build_id"] = e.build.Id - props["from_prebuild"] = e.build.PrebuildId != "" + props["from_prebuild"] = e.build.PrebuildId != nil && *e.build.PrebuildId != "" if isImagePublic(e.build.ContainerConfig.Image) { props["image"] = e.build.Image } diff --git a/pkg/views/build/info/view.go b/pkg/views/build/info/view.go index 6f080cda3c..e5a6adf396 100644 --- a/pkg/views/build/info/view.go +++ b/pkg/views/build/info/view.go @@ -61,7 +61,9 @@ func Render(b *apiclient.BuildDTO, apiServerConfig *apiclient.ServerConfig, forc output += getInfoLine("Devcontainer path", b.BuildConfig.Devcontainer.FilePath) + "\n" } - output += getInfoLine("Prebuild ID", b.PrebuildId) + "\n" + if b.PrebuildId != nil { + output += getInfoLine("Prebuild ID", *b.PrebuildId) + "\n" + } output += getInfoLine("Created", util.FormatTimestamp(b.CreatedAt)) + "\n" diff --git a/pkg/views/build/list/view.go b/pkg/views/build/list/view.go index 75e1c7fc1d..ff667f3e33 100644 --- a/pkg/views/build/list/view.go +++ b/pkg/views/build/list/view.go @@ -72,10 +72,13 @@ func getRowFromRowData(build apiclient.BuildDTO) []string { data.Id = build.Id + views_util.AdditionalPropertyPadding data.Status = views.GetStateLabel(build.State.Name) - data.PrebuildId = build.PrebuildId - if data.PrebuildId == "" { + + if build.PrebuildId != nil && *build.PrebuildId != "" { + data.PrebuildId = *build.PrebuildId + } else { data.PrebuildId = "/" } + data.CreatedAt = util.FormatTimestamp(build.CreatedAt) data.UpdatedAt = util.FormatTimestamp(build.UpdatedAt) From 5ca2e81347d5a7dc02c859f89fe0c0f7b53a5b43 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 13 Jan 2025 16:31:58 +0000 Subject: [PATCH 45/76] fix: tests and minor issues (#1707) Signed-off-by: Toma Puljak --- .../testing/agent/mocks/docker_cred_helper.go | 24 +++++++ internal/testing/build/store.go | 33 +++++++++- internal/testing/server/targets/store.go | 42 +++++++++--- internal/testing/server/workspaces/store.go | 34 +++++++++- pkg/agent/agent_test.go | 15 +++-- pkg/cmd/bootstrap/get_server_instance.go | 4 +- pkg/cmd/purge.go | 5 -- pkg/server/apikeys/apikeys_test.go | 8 ++- pkg/server/builds/service.go | 4 +- pkg/server/builds/service_test.go | 42 +++++++++--- pkg/server/env/service_test.go | 18 ++---- pkg/server/jobs/service_test.go | 45 +++++++------ pkg/server/targets/get.go | 2 +- pkg/server/targets/service_test.go | 47 +++++++++----- pkg/server/workspaces/service_test.go | 59 +++++++++++------ .../workspacetemplates/prebuild_delete.go | 2 +- .../workspacetemplates/prebuild_test.go | 64 ++++++++++++------- 17 files changed, 316 insertions(+), 132 deletions(-) create mode 100644 internal/testing/agent/mocks/docker_cred_helper.go diff --git a/internal/testing/agent/mocks/docker_cred_helper.go b/internal/testing/agent/mocks/docker_cred_helper.go new file mode 100644 index 0000000000..046d136df8 --- /dev/null +++ b/internal/testing/agent/mocks/docker_cred_helper.go @@ -0,0 +1,24 @@ +//go:build testing + +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package mocks + +import "github.com/stretchr/testify/mock" + +type mockDockerCredHelper struct { + mock.Mock +} + +func (m *mockDockerCredHelper) SetDockerConfig() error { + args := m.Called() + return args.Error(0) +} + +func NewMockDockerCredHelper() *mockDockerCredHelper { + mockCredHelper := new(mockDockerCredHelper) + mockCredHelper.On("SetDockerConfig").Return(nil) + + return mockCredHelper +} diff --git a/internal/testing/build/store.go b/internal/testing/build/store.go index 2edeb1629e..9f1e4fee44 100644 --- a/internal/testing/build/store.go +++ b/internal/testing/build/store.go @@ -10,18 +10,21 @@ import ( "fmt" "github.com/daytonaio/daytona/internal/testing/common" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryBuildStore struct { common.InMemoryStore - builds map[string]*models.Build + builds map[string]*models.Build + jobStore stores.JobStore } -func NewInMemoryBuildStore() stores.BuildStore { +func NewInMemoryBuildStore(jobStore stores.JobStore) stores.BuildStore { return &InMemoryBuildStore{ - builds: make(map[string]*models.Build), + builds: make(map[string]*models.Build), + jobStore: jobStore, } } @@ -63,10 +66,16 @@ func (s *InMemoryBuildStore) processFilters(filter *stores.BuildFilter) ([]*mode filteredBuilds[k] = v } + jobs, err := s.jobMap(context.Background()) + if err != nil { + return nil, err + } + if filter != nil { if filter.Id != nil { b, ok := s.builds[*filter.Id] if ok { + b.LastJob = jobs[b.Id] return []*models.Build{b}, nil } else { return []*models.Build{}, fmt.Errorf("build with id %s not found", *filter.Id) @@ -98,6 +107,7 @@ func (s *InMemoryBuildStore) processFilters(filter *stores.BuildFilter) ([]*mode } } if newestBuild != nil { + newestBuild.LastJob = jobs[newestBuild.Id] return []*models.Build{newestBuild}, nil } } @@ -139,8 +149,25 @@ func (s *InMemoryBuildStore) processFilters(filter *stores.BuildFilter) ([]*mode } for _, b := range filteredBuilds { + b.LastJob = jobs[b.Id] result = append(result, b) } return result, nil } + +func (s *InMemoryBuildStore) jobMap(ctx context.Context) (map[string]*models.Job, error) { + jobs, err := s.jobStore.List(ctx, &stores.JobFilter{ + ResourceType: util.Pointer(models.ResourceTypeWorkspace), + }) + if err != nil { + return nil, err + } + + jobMap := make(map[string]*models.Job) + for _, j := range jobs { + jobMap[j.ResourceId] = j + } + + return jobMap, nil +} diff --git a/internal/testing/server/targets/store.go b/internal/testing/server/targets/store.go index 8d876ab1bf..d8e2c36d72 100644 --- a/internal/testing/server/targets/store.go +++ b/internal/testing/server/targets/store.go @@ -10,18 +10,21 @@ import ( "fmt" "github.com/daytonaio/daytona/internal/testing/common" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryTargetStore struct { common.InMemoryStore - targets map[string]*models.Target + targets map[string]*models.Target + jobStore stores.JobStore } -func NewInMemoryTargetStore() stores.TargetStore { +func NewInMemoryTargetStore(jobStore stores.JobStore) stores.TargetStore { return &InMemoryTargetStore{ - targets: make(map[string]*models.Target), + targets: make(map[string]*models.Target), + jobStore: jobStore, } } @@ -63,27 +66,50 @@ func (s *InMemoryTargetStore) processFilters(filter *stores.TargetFilter) ([]*mo filteredTargets[k] = v } + jobs, err := s.jobMap(context.Background()) + if err != nil { + return nil, err + } + if filter != nil { if filter.IdOrName != nil { t, ok := s.targets[*filter.IdOrName] if ok { + t.LastJob = jobs[t.Id] return []*models.Target{t}, nil } else { return []*models.Target{}, fmt.Errorf("target with id or name %s not found", *filter.IdOrName) } } if filter.Default != nil { - for _, targetConfig := range filteredTargets { - if targetConfig.IsDefault != *filter.Default { - delete(filteredTargets, targetConfig.Name) + for _, t := range filteredTargets { + if t.IsDefault != *filter.Default { + delete(filteredTargets, t.Name) } } } } - for _, targetConfig := range filteredTargets { - result = append(result, targetConfig) + for _, t := range filteredTargets { + t.LastJob = jobs[t.Id] + result = append(result, t) } return result, nil } + +func (s *InMemoryTargetStore) jobMap(ctx context.Context) (map[string]*models.Job, error) { + jobs, err := s.jobStore.List(ctx, &stores.JobFilter{ + ResourceType: util.Pointer(models.ResourceTypeTarget), + }) + if err != nil { + return nil, err + } + + jobMap := make(map[string]*models.Job) + for _, j := range jobs { + jobMap[j.ResourceId] = j + } + + return jobMap, nil +} diff --git a/internal/testing/server/workspaces/store.go b/internal/testing/server/workspaces/store.go index 6baf5f784e..5cb67652b6 100644 --- a/internal/testing/server/workspaces/store.go +++ b/internal/testing/server/workspaces/store.go @@ -9,24 +9,33 @@ import ( "context" "github.com/daytonaio/daytona/internal/testing/common" + "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" ) type InMemoryWorkspaceStore struct { common.InMemoryStore + jobStore stores.JobStore workspaces map[string]*models.Workspace } -func NewInMemoryWorkspaceStore() stores.WorkspaceStore { +func NewInMemoryWorkspaceStore(jobStore stores.JobStore) stores.WorkspaceStore { return &InMemoryWorkspaceStore{ workspaces: make(map[string]*models.Workspace), + jobStore: jobStore, } } func (s *InMemoryWorkspaceStore) List(ctx context.Context) ([]*models.Workspace, error) { workspaces := []*models.Workspace{} + jobs, err := s.jobMap(ctx) + if err != nil { + return nil, err + } + for _, w := range s.workspaces { + w.LastJob = jobs[w.Id] workspaces = append(workspaces, w) } @@ -34,15 +43,22 @@ func (s *InMemoryWorkspaceStore) List(ctx context.Context) ([]*models.Workspace, } func (s *InMemoryWorkspaceStore) Find(ctx context.Context, idOrName string) (*models.Workspace, error) { + jobs, err := s.jobMap(ctx) + if err != nil { + return nil, err + } + w, ok := s.workspaces[idOrName] if !ok { for _, w := range s.workspaces { if w.Name == idOrName { + w.LastJob = jobs[w.Id] return w, nil } } return nil, stores.ErrWorkspaceNotFound } + w.LastJob = jobs[w.Id] return w, nil } @@ -56,3 +72,19 @@ func (s *InMemoryWorkspaceStore) Delete(ctx context.Context, workspace *models.W delete(s.workspaces, workspace.Id) return nil } + +func (s *InMemoryWorkspaceStore) jobMap(ctx context.Context) (map[string]*models.Job, error) { + jobs, err := s.jobStore.List(ctx, &stores.JobFilter{ + ResourceType: util.Pointer(models.ResourceTypeWorkspace), + }) + if err != nil { + return nil, err + } + + jobMap := make(map[string]*models.Job) + for _, j := range jobs { + jobMap[j.ResourceId] = j + } + + return jobMap, nil +} diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index b0fed0e520..7fdf7f6e65 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -87,17 +87,19 @@ func TestAgent(t *testing.T) { mockSshServer := mocks.NewMockSshServer() mockTailscaleServer := mocks.NewMockTailscaleServer() mockToolboxServer := mocks.NewMockToolboxServer() + mockDockerCredHelper := mocks.NewMockDockerCredHelper() mockConfig.WorkspaceDir = t.TempDir() // Create a new Agent instance a := &agent.Agent{ - Config: mockConfig, - Git: mockGitService, - Ssh: mockSshServer, - Tailscale: mockTailscaleServer, - Toolbox: mockToolboxServer, - Workspace: workspace1, + Config: mockConfig, + Git: mockGitService, + Ssh: mockSshServer, + Tailscale: mockTailscaleServer, + Toolbox: mockToolboxServer, + Workspace: workspace1, + DockerCredHelper: mockDockerCredHelper, } t.Run("Start agent", func(t *testing.T) { @@ -111,6 +113,7 @@ func TestAgent(t *testing.T) { mockSshServer.AssertExpectations(t) mockTailscaleServer.AssertExpectations(t) mockToolboxServer.AssertExpectations(t) + mockDockerCredHelper.AssertExpectations(t) }) } diff --git a/pkg/cmd/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go index 80ebcb17dd..bb02c5bfb5 100644 --- a/pkg/cmd/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -166,9 +166,9 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe return repo, err }, - CreateJob: func(ctx context.Context, workspaceId string, action models.JobAction) error { + CreateJob: func(ctx context.Context, buildId string, action models.JobAction) error { return jobService.Create(ctx, &models.Job{ - ResourceId: workspaceId, + ResourceId: buildId, ResourceType: models.ResourceTypeBuild, Action: action, State: models.JobStatePending, diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index c269afcb71..f56708e479 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -243,8 +243,3 @@ func init() { purgeCmd.Flags().BoolVarP(&create.YesFlag, "yes", "y", false, "Execute purge without a prompt") purgeCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Delete all targets by force") } - -func purgeLocalRunnerProviders(ctx context.Context, serverConfig *server.Config, serverConfigDir string, cliConfig *config.Config, telemetryService telemetry.TelemetryService) error { - - return nil -} diff --git a/pkg/server/apikeys/apikeys_test.go b/pkg/server/apikeys/apikeys_test.go index bbf21ba0e8..0071bce28d 100644 --- a/pkg/server/apikeys/apikeys_test.go +++ b/pkg/server/apikeys/apikeys_test.go @@ -7,16 +7,20 @@ import ( "context" "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" ) func (s *ApiKeyServiceTestSuite) TestListClientKeys() { - expectedKeys := []*models.ApiKey{} + expectedKeys := []*services.ApiKeyDTO{} keyNames := []string{} keyNames = append(keyNames, clientKeyNames...) for _, keyName := range keyNames { apiKey, _ := s.apiKeyStore.FindByName(context.TODO(), keyName) - expectedKeys = append(expectedKeys, apiKey) + expectedKeys = append(expectedKeys, &services.ApiKeyDTO{ + Type: apiKey.Type, + Name: apiKey.Name, + }) } require := s.Require() diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index cdf64f0fbe..5e9a4a2d9f 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -21,7 +21,7 @@ type BuildServiceConfig struct { BuildStore stores.BuildStore FindWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) GetRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) - CreateJob func(ctx context.Context, workspaceId string, action models.JobAction) error + CreateJob func(ctx context.Context, buildId string, action models.JobAction) error TrackTelemetryEvent func(event telemetry.Event, clientId string) error LoggerFactory logs.ILoggerFactory } @@ -30,7 +30,7 @@ type BuildService struct { buildStore stores.BuildStore findWorkspaceTemplate func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) getRepositoryContext func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) - createJob func(ctx context.Context, workspaceId string, action models.JobAction) error + createJob func(ctx context.Context, buildId string, action models.JobAction) error trackTelemetryEvent func(event telemetry.Event, clientId string) error loggerFactory logs.ILoggerFactory } diff --git a/pkg/server/builds/service_test.go b/pkg/server/builds/service_test.go index d44fb0b2eb..2e88819a7c 100644 --- a/pkg/server/builds/service_test.go +++ b/pkg/server/builds/service_test.go @@ -8,6 +8,7 @@ import ( "testing" build_internal "github.com/daytonaio/daytona/internal/testing/build" + "github.com/daytonaio/daytona/internal/testing/job" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server/builds" @@ -68,6 +69,14 @@ var build4 *models.Build = &models.Build{ }, } +var workspaceTemplate = &models.WorkspaceTemplate{ + Name: "workspaceTemplateName", + RepositoryUrl: "repositoryUrl", + Image: "image", + User: "user", + BuildConfig: &models.BuildConfig{}, +} + var expectedBuilds []*models.Build var expectedFilteredBuilds []*models.Build @@ -104,12 +113,32 @@ func (s *BuildServiceTestSuite) SetupTest() { build2.Id: build2, } - s.buildStore = build_internal.NewInMemoryBuildStore() + jobStore := job.NewInMemoryJobStore() + + s.buildStore = build_internal.NewInMemoryBuildStore(jobStore) s.buildService = builds.NewBuildService(builds.BuildServiceConfig{ BuildStore: s.buildStore, TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { return nil }, + FindWorkspaceTemplate: func(ctx context.Context, name string) (*models.WorkspaceTemplate, error) { + return workspaceTemplate, nil + }, + GetRepositoryContext: func(ctx context.Context, url, branch string) (*gitprovider.GitRepository, error) { + return &gitprovider.GitRepository{ + Url: url, + Branch: branch, + }, nil + }, + CreateJob: func(ctx context.Context, buildId string, action models.JobAction) error { + return jobStore.Save(ctx, &models.Job{ + Id: buildId, + ResourceId: buildId, + ResourceType: models.ResourceTypeRunner, + Action: action, + State: models.JobStateSuccess, + }) + }, }) for _, b := range expectedBuilds { @@ -126,7 +155,7 @@ func (s *BuildServiceTestSuite) TestList() { builds, err := s.buildService.List(context.TODO(), nil) require.Nil(err) - require.ElementsMatch(expectedBuilds, builds) + require.Len(builds, len(expectedBuilds)) } func (s *BuildServiceTestSuite) TestFind() { @@ -138,7 +167,7 @@ func (s *BuildServiceTestSuite) TestFind() { }, }) require.Nil(err) - require.Equal(build1, build) + require.Equal(build1.Id, build.Id) } func (s *BuildServiceTestSuite) TestSave() { @@ -146,9 +175,8 @@ func (s *BuildServiceTestSuite) TestSave() { require := s.Require() - // FIXME: fix me createBuildDto := services.CreateBuildDTO{ - WorkspaceTemplateName: "workspaceTemplateName", + WorkspaceTemplateName: workspaceTemplate.Name, Branch: "branch", PrebuildId: build4.PrebuildId, EnvVars: build4.EnvVars, @@ -176,8 +204,6 @@ func (s *BuildServiceTestSuite) TestDelete() { } func (s *BuildServiceTestSuite) TestHandleSuccessfulRemoval() { - expectedBuilds = expectedBuilds[:2] - require := s.Require() err := s.buildService.HandleSuccessfulRemoval(context.TODO(), build3.Id) @@ -185,5 +211,5 @@ func (s *BuildServiceTestSuite) TestHandleSuccessfulRemoval() { builds, err := s.buildService.List(context.TODO(), nil) require.Nil(err) - require.ElementsMatch(expectedBuilds, builds) + require.NotContains(builds, build3) } diff --git a/pkg/server/env/service_test.go b/pkg/server/env/service_test.go index 18b7526051..d6d2f2bca8 100644 --- a/pkg/server/env/service_test.go +++ b/pkg/server/env/service_test.go @@ -36,12 +36,6 @@ func TestEnvironmentVariableService(t *testing.T) { suite.Run(t, NewEnvironmentVariableTestSuite()) } -func (s *EnvironmentVariableServiceTestSuite) TestReturnsEnvironmentVariableNotFound() { - envVar, err := s.environmentVariableService.List(context.TODO()) - s.Require().Nil(envVar) - s.Require().True(stores.IsEnvironmentVariableNotFound(err)) -} - func (s *EnvironmentVariableServiceTestSuite) TestSaveEnvironmentVariable() { envVar := &models.EnvironmentVariable{ Key: "key1", @@ -51,10 +45,10 @@ func (s *EnvironmentVariableServiceTestSuite) TestSaveEnvironmentVariable() { err := s.environmentVariableService.Save(context.TODO(), envVar) s.Require().Nil(err) - envVarsFromStore, err := s.environmentVariableStore.List(context.TODO()) + envVars, err := s.environmentVariableStore.List(context.TODO()) s.Require().Nil(err) - s.Require().NotNil(envVarsFromStore) - s.Require().Equal(envVar, envVarsFromStore) + s.Require().NotNil(envVars) + s.Require().Contains(envVars, envVar) } func (s *EnvironmentVariableServiceTestSuite) TestDeleteEnvironmentVariable() { @@ -69,7 +63,7 @@ func (s *EnvironmentVariableServiceTestSuite) TestDeleteEnvironmentVariable() { err = s.environmentVariableService.Delete(context.TODO(), envVar.Key) s.Require().Nil(err) - EnvVarsFromStore, err := s.environmentVariableStore.List(context.TODO()) - s.Require().Nil(EnvVarsFromStore) - s.Require().True(stores.IsEnvironmentVariableNotFound(err)) + envVars, err := s.environmentVariableStore.List(context.TODO()) + s.Require().Nil(err) + s.Require().NotContains(envVars, envVar) } diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go index 9e84a5f601..f0a95d0f6b 100644 --- a/pkg/server/jobs/service_test.go +++ b/pkg/server/jobs/service_test.go @@ -19,31 +19,35 @@ import ( var expectedJobs []*models.Job var job1 = &models.Job{ - Id: "1", - ResourceId: "1", - Action: models.JobActionStart, - State: models.JobStatePending, + Id: "1", + ResourceId: "1", + ResourceType: models.ResourceTypeWorkspace, + Action: models.JobActionStart, + State: models.JobStatePending, } var job2 = &models.Job{ - Id: "2", - ResourceId: "2", - Action: models.JobActionStart, - State: models.JobStatePending, + Id: "2", + ResourceId: "2", + ResourceType: models.ResourceTypeWorkspace, + Action: models.JobActionStart, + State: models.JobStatePending, } var job3 = &models.Job{ - Id: "3", - ResourceId: "3", - Action: models.JobActionStart, - State: models.JobStatePending, + Id: "3", + ResourceId: "3", + ResourceType: models.ResourceTypeWorkspace, + Action: models.JobActionStart, + State: models.JobStatePending, } var job4 = &models.Job{ - Id: "4", - ResourceId: "4", - Action: models.JobActionStart, - State: models.JobStatePending, + Id: "4", + ResourceId: "4", + ResourceType: models.ResourceTypeWorkspace, + Action: models.JobActionStart, + State: models.JobStatePending, } type JobServiceTestSuite struct { @@ -138,10 +142,11 @@ func (s *JobServiceTestSuite) TestCreateWithAnotherJobInProgress() { require.Nil(err) var job5 = &models.Job{ - Id: "5", - ResourceId: "4", - Action: models.JobActionStart, - State: models.JobStatePending, + Id: "5", + ResourceId: "4", + ResourceType: models.ResourceTypeWorkspace, + Action: models.JobActionStart, + State: models.JobStatePending, } err = s.jobService.Create(context.TODO(), job5) diff --git a/pkg/server/targets/get.go b/pkg/server/targets/get.go index 2755d6ffeb..e685531fcc 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/get.go @@ -20,7 +20,7 @@ func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilt state := tg.GetState() if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { - return nil, stores.ErrTargetNotFound + return nil, services.ErrTargetDeleted } var updatedWorkspaces []models.Workspace diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 4cc88bb171..0d79b68ca2 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -7,6 +7,7 @@ import ( "context" "testing" + "github.com/daytonaio/daytona/internal/testing/job" t_targetconfigs "github.com/daytonaio/daytona/internal/testing/server/targetconfigs" t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" @@ -25,6 +26,7 @@ const serverApiUrl = "http://localhost:3986" const serverUrl = "http://localhost:3987" var tc = models.TargetConfig{ + Id: "test", Name: "test", ProviderInfo: models.ProviderInfo{ Name: "test-provider", @@ -58,7 +60,9 @@ func TestTargetService(t *testing.T) { ctx := context.Background() ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") - targetStore := t_targets.NewInMemoryTargetStore() + jobStore := job.NewInMemoryJobStore() + + targetStore := t_targets.NewInMemoryTargetStore(jobStore) targetMetadataStore := t_targets.NewInMemoryTargetMetadataStore() targetConfigStore := t_targetconfigs.NewInMemoryTargetConfigStore() @@ -84,6 +88,19 @@ func TestTargetService(t *testing.T) { ServerApiUrl: serverApiUrl, ServerUrl: serverUrl, LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: tgLogsDir}), + TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { + return nil + }, + CreateJob: func(ctx context.Context, targetId, runnerId string, action models.JobAction) error { + return jobStore.Save(ctx, &models.Job{ + Id: targetId, + ResourceId: targetId, + RunnerId: util.Pointer(runnerId), + ResourceType: models.ResourceTypeTarget, + Action: action, + State: models.JobStateSuccess, + }) + }, }) t.Run("CreateTarget", func(t *testing.T) { @@ -94,9 +111,6 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) require.NotNil(t, target) - // Must be true after creation - tg.IsDefault = true - targetEquals(t, tg, target) tg.EnvVars = nil @@ -155,6 +169,16 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) }) + t.Run("SetTargetMetadata", func(t *testing.T) { + err := targetStore.Save(ctx, tg) + require.Nil(t, err) + + _, err = service.SetTargetMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ + Uptime: 10, + }) + require.Nil(t, err) + }) + t.Run("RemoveTarget", func(t *testing.T) { apiKeyService.On("Revoke", mock.Anything).Return(nil) @@ -163,7 +187,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) - require.Equal(t, stores.ErrTargetNotFound, err) + require.Equal(t, services.ErrTargetDeleted, err) }) t.Run("ForceRemoveTarget", func(t *testing.T) { @@ -177,11 +201,12 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) - require.Equal(t, stores.ErrTargetNotFound, err) + require.Equal(t, services.ErrTargetDeleted, err) }) t.Run("CreateTarget fails name validation", func(t *testing.T) { invalidTargetRequest := createTargetDTO + invalidTargetRequest.Id = "some-id" invalidTargetRequest.Name = "invalid name" _, err := service.CreateTarget(ctx, invalidTargetRequest) @@ -189,16 +214,6 @@ func TestTargetService(t *testing.T) { require.Equal(t, services.ErrInvalidTargetName, err) }) - t.Run("SetTargetMetadata", func(t *testing.T) { - err := targetStore.Save(ctx, tg) - require.Nil(t, err) - - _, err = service.SetTargetMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ - Uptime: 10, - }) - require.Nil(t, err) - }) - t.Cleanup(func() { apiKeyService.AssertExpectations(t) }) diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index f577deafdd..5f9ad77954 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -8,6 +8,7 @@ import ( "fmt" "testing" + "github.com/daytonaio/daytona/internal/testing/job" t_targets "github.com/daytonaio/daytona/internal/testing/server/targets" "github.com/daytonaio/daytona/internal/testing/server/targets/mocks" t_workspaces "github.com/daytonaio/daytona/internal/testing/server/workspaces" @@ -94,7 +95,7 @@ var ws = &models.Workspace{ TargetId: tg.Id, } -func TestTargetService(t *testing.T) { +func TestWorkspaceService(t *testing.T) { ws.EnvVars = workspaces.GetWorkspaceEnvVars(ws, workspaces.WorkspaceEnvVarParams{ ApiUrl: serverApiUrl, ServerUrl: serverUrl, @@ -104,11 +105,14 @@ func TestTargetService(t *testing.T) { ctx := context.Background() ctx = context.WithValue(ctx, telemetry.CLIENT_ID_CONTEXT_KEY, "test-client-id") - targetStore := t_targets.NewInMemoryTargetStore() + jobStore := job.NewInMemoryJobStore() + + targetStore := t_targets.NewInMemoryTargetStore(jobStore) err := targetStore.Save(ctx, tg) require.Nil(t, err) - workspaceStore := t_workspaces.NewInMemoryWorkspaceStore() + workspaceStore := t_workspaces.NewInMemoryWorkspaceStore(jobStore) + metadataStore := t_workspaces.NewInMemoryWorkspaceMetadataStore() apiKeyService := mocks.NewMockApiKeyService() gitProviderService := mocks.NewMockGitProviderService() @@ -116,6 +120,7 @@ func TestTargetService(t *testing.T) { tgLogsDir := t.TempDir() service := workspaces.NewWorkspaceService(workspaces.WorkspaceServiceConfig{ + WorkspaceMetadataStore: metadataStore, FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { t, err := targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { @@ -153,6 +158,16 @@ func TestTargetService(t *testing.T) { DefaultWorkspaceImage: defaultWorkspaceImage, DefaultWorkspaceUser: defaultWorkspaceUser, LoggerFactory: logs.NewLoggerFactory(logs.LoggerFactoryConfig{LogsDir: tgLogsDir}), + CreateJob: func(ctx context.Context, workspaceId, runnerId string, action models.JobAction) error { + return jobStore.Save(ctx, &models.Job{ + Id: workspaceId, + ResourceId: workspaceId, + RunnerId: util.Pointer(runnerId), + ResourceType: models.ResourceTypeWorkspace, + Action: action, + State: models.JobStateSuccess, + }) + }, }) t.Run("CreateWorkspace", func(t *testing.T) { @@ -161,6 +176,7 @@ func TestTargetService(t *testing.T) { apiKeyService.On("Generate", models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) ws := &models.Workspace{ + Id: createWorkspaceDTO.Id, Name: createWorkspaceDTO.Name, Image: *createWorkspaceDTO.Image, User: *createWorkspaceDTO.User, @@ -187,6 +203,10 @@ func TestTargetService(t *testing.T) { workspaceEquals(t, &services.WorkspaceDTO{Workspace: *ws}, workspace) + job, err := jobStore.Find(ctx, &stores.JobFilter{ResourceId: &ws.Id}) + require.Nil(t, err) + require.Equal(t, job.ResourceType, models.ResourceTypeWorkspace) + ws.EnvVars = nil }) @@ -241,6 +261,19 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) }) + t.Run("SetWorkspaceMetadata", func(t *testing.T) { + res, err := service.SetWorkspaceMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ + Uptime: 10, + GitStatus: &models.GitStatus{ + CurrentBranch: "main", + }, + }) + require.Nil(t, err) + + require.Nil(t, err) + require.Equal(t, "main", res.GitStatus.CurrentBranch) + }) + t.Run("RemoveWorkspace", func(t *testing.T) { apiKeyService.On("Revoke", mock.Anything).Return(nil) @@ -249,7 +282,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) - require.Equal(t, stores.ErrWorkspaceNotFound, err) + require.Equal(t, services.ErrWorkspaceDeleted, err) }) t.Run("ForceRemoveWorkspace", func(t *testing.T) { @@ -263,23 +296,7 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) - require.Equal(t, stores.ErrWorkspaceNotFound, err) - }) - - t.Run("SetWorkspaceMetadata", func(t *testing.T) { - err := workspaceStore.Save(ctx, ws) - require.Nil(t, err) - - res, err := service.SetWorkspaceMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ - Uptime: 10, - GitStatus: &models.GitStatus{ - CurrentBranch: "main", - }, - }) - require.Nil(t, err) - - require.Nil(t, err) - require.Equal(t, "main", res.GitStatus.CurrentBranch) + require.Equal(t, services.ErrWorkspaceDeleted, err) }) t.Cleanup(func() { diff --git a/pkg/server/workspacetemplates/prebuild_delete.go b/pkg/server/workspacetemplates/prebuild_delete.go index 94a9e480a2..b1df85210c 100644 --- a/pkg/server/workspacetemplates/prebuild_delete.go +++ b/pkg/server/workspacetemplates/prebuild_delete.go @@ -57,7 +57,7 @@ func (s *WorkspaceTemplateService) DeletePrebuild(ctx context.Context, workspace } } - errs := s.deleteBuilds(ctx, &id, nil, force) + errs := s.deleteBuilds(ctx, nil, &id, force) if len(errs) > 0 { for _, err := range errs { err = s.handleDeletePrebuildError(ctx, workspaceTemplate, err) diff --git a/pkg/server/workspacetemplates/prebuild_test.go b/pkg/server/workspacetemplates/prebuild_test.go index e9b4dd85d9..875cad39f2 100644 --- a/pkg/server/workspacetemplates/prebuild_test.go +++ b/pkg/server/workspacetemplates/prebuild_test.go @@ -111,8 +111,10 @@ func (s *WorkspaceTemplateServiceTestSuite) TestDeletePrebuild() { require := s.Require() - s.buildService.On("MarkForDeletion", &stores.BuildFilter{ - PrebuildIds: &[]string{prebuild2.Id}, + s.buildService.On("Delete", &services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + PrebuildIds: &[]string{prebuild2.Id}, + }, }, false).Return([]error{}) err := s.workspaceTemplateService.DeletePrebuild(context.TODO(), workspaceTemplate1.Name, prebuild2.Id, false) @@ -142,13 +144,17 @@ func (s *WorkspaceTemplateServiceTestSuite) TestProcessGitEventCommitInterval() EnvVars: workspaceTemplate1.EnvVars, }).Return("", nil) - s.buildService.On("Find", &stores.BuildFilter{ - PrebuildIds: &[]string{prebuild1.Id}, - GetNewest: util.Pointer(true), - }).Return(&models.Build{ - Id: "1", - PrebuildId: &prebuild1.Id, - Repository: repository1, + s.buildService.On("Find", &services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + PrebuildIds: &[]string{prebuild1.Id}, + GetNewest: util.Pointer(true), + }, + }).Return(&services.BuildDTO{ + Build: models.Build{ + Id: "1", + PrebuildId: &prebuild1.Id, + Repository: repository1, + }, }, nil) data := gitprovider.GitEventData{ @@ -199,31 +205,41 @@ func (s *WorkspaceTemplateServiceTestSuite) TestEnforceRetentionPolicy() { s.buildService.On("List", &services.BuildFilter{ StateNames: &[]models.ResourceStateName{models.ResourceStateNameRunSuccessful}, - }).Return([]*models.Build{ + }).Return([]*services.BuildDTO{ { - Id: "1", - PrebuildId: util.Pointer("1"), - CreatedAt: time.Now().Add(time.Hour * -4), + Build: models.Build{ + Id: "1", + PrebuildId: util.Pointer("1"), + CreatedAt: time.Now().Add(time.Hour * -4), + }, }, { - Id: "2", - PrebuildId: util.Pointer("1"), - CreatedAt: time.Now().Add(time.Hour * -3), + Build: models.Build{ + Id: "2", + PrebuildId: util.Pointer("1"), + CreatedAt: time.Now().Add(time.Hour * -3), + }, }, { - Id: "3", - PrebuildId: util.Pointer("1"), - CreatedAt: time.Now().Add(time.Hour * -2), + Build: models.Build{ + Id: "3", + PrebuildId: util.Pointer("1"), + CreatedAt: time.Now().Add(time.Hour * -2), + }, }, { - Id: "4", - PrebuildId: util.Pointer("1"), - CreatedAt: time.Now().Add(time.Hour * -1), + Build: models.Build{ + Id: "4", + PrebuildId: util.Pointer("1"), + CreatedAt: time.Now().Add(time.Hour * -1), + }, }, }, nil) - s.buildService.On("MarkForDeletion", &stores.BuildFilter{ - Id: util.Pointer("1"), + s.buildService.On("Delete", &services.BuildFilter{ + StoreFilter: stores.BuildFilter{ + Id: util.Pointer("1"), + }, }, false).Return([]error{}) err := s.workspaceTemplateService.EnforceRetentionPolicy(context.TODO()) From b41b70b2e1868d2a0e3451801def480acc9ccd39 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Mon, 13 Jan 2025 14:29:46 +0000 Subject: [PATCH 46/76] fix: global verb consistency, cli aliases Signed-off-by: Ivan Dagelic Signed-off-by: Toma Puljak --- cmd/daytona/config/config.go | 2 +- docs/daytona.md | 2 +- docs/daytona_api-key.md | 4 +- ..._generate.md => daytona_api-key_create.md} | 6 +- ...ey_revoke.md => daytona_api-key_delete.md} | 6 +- docs/daytona_env.md | 2 +- ...na_env_remove.md => daytona_env_delete.md} | 6 +- docs/daytona_git-provider.md | 18 + docs/daytona_git-provider_create.md | 18 + docs/daytona_git-provider_delete.md | 25 ++ ...s_list.md => daytona_git-provider_list.md} | 8 +- docs/daytona_git-provider_update.md | 18 + docs/daytona_git-providers.md | 18 - docs/daytona_git-providers_add.md | 18 - docs/daytona_git-providers_delete.md | 25 -- docs/daytona_git-providers_update.md | 18 - docs/daytona_prebuild.md | 2 +- ...uild_add.md => daytona_prebuild_create.md} | 6 +- docs/daytona_profile.md | 6 +- ...ofile_add.md => daytona_profile_create.md} | 6 +- docs/daytona_profile_delete.md | 4 +- ...file_edit.md => daytona_profile_update.md} | 6 +- docs/daytona_server_runner.md | 4 +- ...ter.md => daytona_server_runner_create.md} | 6 +- ...ter.md => daytona_server_runner_delete.md} | 6 +- docs/daytona_target-config.md | 4 +- ...add.md => daytona_target-config_create.md} | 6 +- ...ove.md => daytona_target-config_delete.md} | 6 +- docs/daytona_template.md | 2 +- ...late_add.md => daytona_template_create.md} | 6 +- hack/docs/daytona.yaml | 2 +- hack/docs/daytona_api-key.yaml | 4 +- ...erate.yaml => daytona_api-key_create.yaml} | 6 +- ...evoke.yaml => daytona_api-key_delete.yaml} | 6 +- hack/docs/daytona_env.yaml | 2 +- ...nv_remove.yaml => daytona_env_delete.yaml} | 6 +- hack/docs/daytona_git-provider.yaml | 12 + hack/docs/daytona_git-provider_create.yaml | 9 + ....yaml => daytona_git-provider_delete.yaml} | 10 +- ...st.yaml => daytona_git-provider_list.yaml} | 8 +- ....yaml => daytona_git-provider_update.yaml} | 6 +- hack/docs/daytona_git-providers.yaml | 12 - hack/docs/daytona_git-providers_add.yaml | 9 - hack/docs/daytona_prebuild.yaml | 2 +- ..._add.yaml => daytona_prebuild_create.yaml} | 6 +- hack/docs/daytona_profile.yaml | 6 +- ...e_add.yaml => daytona_profile_create.yaml} | 6 +- hack/docs/daytona_profile_delete.yaml | 4 +- ..._edit.yaml => daytona_profile_update.yaml} | 6 +- hack/docs/daytona_server_runner.yaml | 4 +- ...yaml => daytona_server_runner_create.yaml} | 6 +- ...yaml => daytona_server_runner_delete.yaml} | 6 +- hack/docs/daytona_target-config.yaml | 4 +- ...yaml => daytona_target-config_create.yaml} | 6 +- ...yaml => daytona_target-config_delete.yaml} | 6 +- hack/docs/daytona_template.yaml | 2 +- ..._add.yaml => daytona_template_create.yaml} | 6 +- internal/cmd/tailscale/connection.go | 2 +- .../server/targets/mocks/api_key_service.go | 4 +- .../targets/mocks/git_provider_service.go | 6 +- internal/util/apiclient/api_client.go | 4 +- pkg/agent/agent.go | 4 +- pkg/agent/tailscale/server.go | 2 +- pkg/api/controllers/apikey/apikey.go | 16 +- .../apikey/{generate.go => create.go} | 12 +- pkg/api/controllers/build/{get.go => find.go} | 10 +- .../containerregistry/{get.go => find.go} | 12 +- pkg/api/controllers/env/env.go | 12 +- .../controllers/gitprovider/gitprovider.go | 46 +- .../runner/{register.go => create.go} | 24 +- .../runner/{remove.go => delete.go} | 14 +- .../controllers/runner/{get.go => find.go} | 12 +- pkg/api/controllers/runner/metadata.go | 12 +- pkg/api/controllers/server/server.go | 26 +- .../target/{remove.go => delete.go} | 16 +- pkg/api/controllers/target/metadata.go | 12 +- pkg/api/controllers/target/target.go | 12 +- .../targetconfig/{add.go => create.go} | 20 +- .../targetconfig/{remove.go => delete.go} | 12 +- .../workspace/{remove.go => delete.go} | 16 +- pkg/api/controllers/workspace/metadata.go | 12 +- .../controllers/workspace/toolbox/toolbox.go | 2 +- pkg/api/controllers/workspace/workspace.go | 12 +- .../workspacetemplate/prebuild/prebuild.go | 20 +- .../workspacetemplate/workspace_template.go | 24 +- pkg/api/docs/docs.go | 292 ++++++------- pkg/api/docs/swagger.json | 292 ++++++------- pkg/api/docs/swagger.yaml | 256 +++++------ pkg/api/server.go | 62 +-- pkg/apiclient/README.md | 64 +-- pkg/apiclient/api/openapi.yaml | 404 +++++++++--------- pkg/apiclient/api_api_key.go | 136 +++--- pkg/apiclient/api_build.go | 20 +- pkg/apiclient/api_container_registry.go | 22 +- pkg/apiclient/api_env_var.go | 22 +- pkg/apiclient/api_git_provider.go | 372 ++++++++-------- pkg/apiclient/api_prebuild.go | 42 +- pkg/apiclient/api_runner.go | 310 +++++++------- pkg/apiclient/api_server.go | 48 +-- pkg/apiclient/api_target.go | 360 ++++++++-------- pkg/apiclient/api_target_config.go | 172 ++++---- pkg/apiclient/api_workspace.go | 282 ++++++------ pkg/apiclient/api_workspace_template.go | 180 ++++---- pkg/apiclient/docs/ApiKeyAPI.md | 78 ++-- pkg/apiclient/docs/BuildAPI.md | 18 +- pkg/apiclient/docs/ContainerRegistryAPI.md | 18 +- ...egisterRunnerDTO.md => CreateRunnerDTO.md} | 26 +- ...rResultDTO.md => CreateRunnerResultDTO.md} | 40 +- ...tConfigDTO.md => CreateTargetConfigDTO.md} | 32 +- pkg/apiclient/docs/EnvVarAPI.md | 14 +- pkg/apiclient/docs/GitProviderAPI.md | 212 ++++----- pkg/apiclient/docs/PrebuildAPI.md | 36 +- pkg/apiclient/docs/RunnerAPI.md | 174 ++++---- pkg/apiclient/docs/ServerAPI.md | 40 +- pkg/apiclient/docs/TargetAPI.md | 158 +++---- pkg/apiclient/docs/TargetConfigAPI.md | 76 ++-- pkg/apiclient/docs/WorkspaceAPI.md | 138 +++--- pkg/apiclient/docs/WorkspaceTemplateAPI.md | 94 ++-- ...nner_dto.go => model_create_runner_dto.go} | 66 +-- ...o.go => model_create_runner_result_dto.go} | 80 ++-- ...o.go => model_create_target_config_dto.go} | 72 ++-- pkg/cmd/agent/agent.go | 2 +- pkg/cmd/agent/logs.go | 6 +- pkg/cmd/agentmode/docker_cred.go | 2 +- pkg/cmd/agentmode/forward.go | 2 + pkg/cmd/agentmode/git_cred.go | 4 +- pkg/cmd/agentmode/info.go | 3 +- pkg/cmd/agentmode/logs.go | 3 +- pkg/cmd/apikey/api_key.go | 5 +- pkg/cmd/apikey/{generate.go => create.go} | 11 +- pkg/cmd/apikey/{revoke.go => delete.go} | 13 +- pkg/cmd/apikey/list.go | 3 +- pkg/cmd/bootstrap/get_local_runner.go | 14 +- pkg/cmd/bootstrap/get_remote_runner.go | 16 +- pkg/cmd/bootstrap/get_server_instance.go | 28 +- pkg/cmd/build/build.go | 2 +- pkg/cmd/build/delete.go | 3 +- pkg/cmd/build/info.go | 5 +- pkg/cmd/build/list.go | 3 +- pkg/cmd/build/logs.go | 5 +- pkg/cmd/build/run.go | 3 +- pkg/cmd/cmd.go | 6 +- pkg/cmd/common/aliases.go | 27 ++ pkg/cmd/common/await_state.go | 2 +- pkg/cmd/common/delete_workspace.go | 2 +- pkg/cmd/common/get_gpg_key.go | 2 +- pkg/cmd/config.go | 3 +- pkg/cmd/env/delete.go | 9 +- pkg/cmd/env/list.go | 3 +- pkg/cmd/env/set.go | 7 +- pkg/cmd/gitprovider/{add.go => create.go} | 10 +- pkg/cmd/gitprovider/delete.go | 29 +- pkg/cmd/gitprovider/gitprovider.go | 6 +- pkg/cmd/gitprovider/list.go | 5 +- pkg/cmd/gitprovider/update.go | 8 +- pkg/cmd/ports/forward.go | 4 +- pkg/cmd/prebuild/{add.go => create.go} | 23 +- pkg/cmd/prebuild/delete.go | 3 +- pkg/cmd/prebuild/info.go | 10 +- pkg/cmd/prebuild/list.go | 3 +- pkg/cmd/prebuild/prebuild.go | 2 +- pkg/cmd/prebuild/update.go | 22 +- pkg/cmd/profile/{add.go => create.go} | 7 +- pkg/cmd/profile/delete.go | 7 +- pkg/cmd/profile/list.go | 3 +- pkg/cmd/profile/profile.go | 3 +- pkg/cmd/profile/{edit.go => update.go} | 16 +- pkg/cmd/profile/use.go | 4 +- pkg/cmd/provider/install.go | 2 +- pkg/cmd/provider/list.go | 3 +- pkg/cmd/provider/provider.go | 1 + pkg/cmd/provider/uninstall.go | 2 +- pkg/cmd/provider/update.go | 2 +- pkg/cmd/runner/config.go | 3 +- pkg/cmd/runner/logs.go | 8 +- pkg/cmd/runner/runner.go | 1 + pkg/cmd/server/config.go | 6 +- pkg/cmd/server/configure.go | 2 +- pkg/cmd/server/logs/list.go | 3 +- pkg/cmd/server/logs/logs.go | 6 +- .../server/runner/{register.go => create.go} | 16 +- .../runner/{unregister.go => delete.go} | 14 +- pkg/cmd/server/runner/list.go | 3 +- pkg/cmd/server/runner/logs.go | 4 +- pkg/cmd/server/runner/runner.go | 4 +- pkg/cmd/server/serve.go | 14 +- pkg/cmd/target/create.go | 7 +- pkg/cmd/target/delete.go | 4 +- pkg/cmd/target/info.go | 3 +- pkg/cmd/target/list.go | 3 +- pkg/cmd/target/logs.go | 3 +- pkg/cmd/target/setdefault.go | 8 +- pkg/cmd/target/target.go | 2 +- pkg/cmd/targetconfig/{add.go => create.go} | 20 +- pkg/cmd/targetconfig/{remove.go => delete.go} | 15 +- pkg/cmd/targetconfig/list.go | 3 +- pkg/cmd/targetconfig/target_config.go | 6 +- pkg/cmd/workspace/create/cmd.go | 1 + pkg/cmd/workspace/create/creation_data.go | 9 +- .../workspace/create/process_cmd_arguments.go | 2 +- pkg/cmd/workspace/delete.go | 2 +- pkg/cmd/workspace/info.go | 2 +- pkg/cmd/workspace/list.go | 3 +- pkg/cmd/workspace/logs.go | 2 +- pkg/cmd/workspace/start.go | 2 +- .../workspacetemplate/{add.go => create.go} | 20 +- pkg/cmd/workspacetemplate/delete.go | 3 +- pkg/cmd/workspacetemplate/export.go | 2 +- pkg/cmd/workspacetemplate/import.go | 6 +- pkg/cmd/workspacetemplate/info.go | 5 +- pkg/cmd/workspacetemplate/list.go | 3 +- pkg/cmd/workspacetemplate/setdefault.go | 8 +- pkg/cmd/workspacetemplate/update.go | 12 +- .../workspacetemplate/workspacetemplate.go | 4 +- pkg/models/workspace_template.go | 2 +- pkg/server/apikeys/apikeys.go | 10 +- pkg/server/apikeys/apikeys_test.go | 4 +- pkg/server/apikeys/service_test.go | 4 +- pkg/server/apikeys/validate_test.go | 4 +- pkg/server/gitproviders/config.go | 4 +- .../gitproviders/{remove.go => delete.go} | 10 +- pkg/server/jobs/service.go | 8 +- pkg/server/jobs/service_test.go | 2 +- pkg/server/registry/service.go | 6 +- pkg/server/runners/{register.go => create.go} | 4 +- pkg/server/runners/{remove.go => delete.go} | 22 +- pkg/server/runners/service.go | 16 +- pkg/server/targetconfigs/service.go | 2 +- pkg/server/targetconfigs/service_test.go | 4 +- pkg/server/targets/create.go | 2 +- pkg/server/targets/{remove.go => delete.go} | 38 +- pkg/server/targets/{get.go => find.go} | 2 +- pkg/server/targets/metadata.go | 2 +- pkg/server/targets/service.go | 12 +- pkg/server/targets/service_test.go | 38 +- pkg/server/targets/set-default.go | 4 +- pkg/server/workspaces/create.go | 3 +- .../workspaces/{remove.go => delete.go} | 38 +- pkg/server/workspaces/{get.go => find.go} | 2 +- pkg/server/workspaces/metadata.go | 2 +- pkg/server/workspaces/service.go | 12 +- pkg/server/workspaces/service_test.go | 43 +- .../workspacetemplates/prebuild_delete.go | 2 +- pkg/services/api_key.go | 9 +- pkg/services/build.go | 6 +- pkg/services/git_provider.go | 10 +- pkg/services/job.go | 6 +- pkg/services/runner.go | 16 +- pkg/services/target.go | 12 +- pkg/services/target_config.go | 8 +- pkg/services/workspace.go | 12 +- pkg/services/workspace_template.go | 8 +- pkg/stores/build.go | 2 +- pkg/views/apikey/notify.go | 2 +- pkg/views/env/delete.go | 4 +- pkg/views/initial/view.go | 2 +- .../prebuild/{add/add.go => create/create.go} | 2 +- pkg/views/profile/create.go | 2 +- pkg/views/purge/purge_resources.go | 6 +- pkg/views/server/config.go | 4 +- .../server/runner/{register.go => create.go} | 2 +- pkg/views/server/runner/notify.go | 2 +- pkg/views/targetconfig/{set.go => create.go} | 2 +- pkg/views/targetconfig/select.go | 2 +- pkg/views/util/empty_list.go | 23 +- pkg/views/util/help.go | 8 +- 266 files changed, 3338 insertions(+), 3237 deletions(-) rename docs/{daytona_api-key_generate.md => daytona_api-key_create.md} (65%) rename docs/{daytona_api-key_revoke.md => daytona_api-key_delete.md} (73%) rename docs/{daytona_env_remove.md => daytona_env_delete.md} (70%) create mode 100644 docs/daytona_git-provider.md create mode 100644 docs/daytona_git-provider_create.md create mode 100644 docs/daytona_git-provider_delete.md rename docs/{daytona_git-providers_list.md => daytona_git-provider_list.md} (51%) create mode 100644 docs/daytona_git-provider_update.md delete mode 100644 docs/daytona_git-providers.md delete mode 100644 docs/daytona_git-providers_add.md delete mode 100644 docs/daytona_git-providers_delete.md delete mode 100644 docs/daytona_git-providers_update.md rename docs/{daytona_prebuild_add.md => daytona_prebuild_create.md} (84%) rename docs/{daytona_profile_add.md => daytona_profile_create.md} (80%) rename docs/{daytona_profile_edit.md => daytona_profile_update.md} (77%) rename docs/{daytona_server_runner_register.md => daytona_server_runner_create.md} (72%) rename docs/{daytona_server_runner_unregister.md => daytona_server_runner_delete.md} (70%) rename docs/{daytona_target-config_add.md => daytona_target-config_create.md} (67%) rename docs/{daytona_target-config_remove.md => daytona_target-config_delete.md} (71%) rename docs/{daytona_template_add.md => daytona_template_create.md} (92%) rename hack/docs/{daytona_api-key_generate.yaml => daytona_api-key_create.yaml} (56%) rename hack/docs/{daytona_api-key_revoke.yaml => daytona_api-key_delete.yaml} (71%) rename hack/docs/{daytona_env_remove.yaml => daytona_env_delete.yaml} (64%) create mode 100644 hack/docs/daytona_git-provider.yaml create mode 100644 hack/docs/daytona_git-provider_create.yaml rename hack/docs/{daytona_git-providers_delete.yaml => daytona_git-provider_delete.yaml} (57%) rename hack/docs/{daytona_git-providers_list.yaml => daytona_git-provider_list.yaml} (53%) rename hack/docs/{daytona_git-providers_update.yaml => daytona_git-provider_update.yaml} (50%) delete mode 100644 hack/docs/daytona_git-providers.yaml delete mode 100644 hack/docs/daytona_git-providers_add.yaml rename hack/docs/{daytona_prebuild_add.yaml => daytona_prebuild_create.yaml} (85%) rename hack/docs/{daytona_profile_add.yaml => daytona_profile_create.yaml} (78%) rename hack/docs/{daytona_profile_edit.yaml => daytona_profile_update.yaml} (75%) rename hack/docs/{daytona_server_runner_register.yaml => daytona_server_runner_create.yaml} (67%) rename hack/docs/{daytona_server_runner_unregister.yaml => daytona_server_runner_delete.yaml} (68%) rename hack/docs/{daytona_target-config_add.yaml => daytona_target-config_create.yaml} (58%) rename hack/docs/{daytona_target-config_remove.yaml => daytona_target-config_delete.yaml} (69%) rename hack/docs/{daytona_template_add.yaml => daytona_template_create.yaml} (91%) rename pkg/api/controllers/apikey/{generate.go => create.go} (70%) rename pkg/api/controllers/build/{get.go => find.go} (87%) rename pkg/api/controllers/containerregistry/{get.go => find.go} (84%) rename pkg/api/controllers/runner/{register.go => create.go} (53%) rename pkg/api/controllers/runner/{remove.go => delete.go} (68%) rename pkg/api/controllers/runner/{get.go => find.go} (77%) rename pkg/api/controllers/target/{remove.go => delete.go} (74%) rename pkg/api/controllers/targetconfig/{add.go => create.go} (64%) rename pkg/api/controllers/targetconfig/{remove.go => delete.go} (73%) rename pkg/api/controllers/workspace/{remove.go => delete.go} (74%) rename pkg/apiclient/docs/{RegisterRunnerDTO.md => CreateRunnerDTO.md} (65%) rename pkg/apiclient/docs/{RegisterRunnerResultDTO.md => CreateRunnerResultDTO.md} (63%) rename pkg/apiclient/docs/{AddTargetConfigDTO.md => CreateTargetConfigDTO.md} (63%) rename pkg/apiclient/{model_register_runner_dto.go => model_create_runner_dto.go} (58%) rename pkg/apiclient/{model_register_runner_result_dto.go => model_create_runner_result_dto.go} (60%) rename pkg/apiclient/{model_add_target_config_dto.go => model_create_target_config_dto.go} (58%) rename pkg/cmd/apikey/{generate.go => create.go} (84%) rename pkg/cmd/apikey/{revoke.go => delete.go} (86%) create mode 100644 pkg/cmd/common/aliases.go rename pkg/cmd/gitprovider/{add.go => create.go} (94%) rename pkg/cmd/prebuild/{add.go => create.go} (86%) rename pkg/cmd/profile/{add.go => create.go} (94%) rename pkg/cmd/profile/{edit.go => update.go} (83%) rename pkg/cmd/server/runner/{register.go => create.go} (79%) rename pkg/cmd/server/runner/{unregister.go => delete.go} (85%) rename pkg/cmd/targetconfig/{add.go => create.go} (93%) rename pkg/cmd/targetconfig/{remove.go => delete.go} (81%) rename pkg/cmd/workspacetemplate/{add.go => create.go} (91%) rename pkg/server/gitproviders/{remove.go => delete.go} (73%) rename pkg/server/runners/{register.go => create.go} (92%) rename pkg/server/runners/{remove.go => delete.go} (73%) rename pkg/server/targets/{remove.go => delete.go} (74%) rename pkg/server/targets/{get.go => find.go} (84%) rename pkg/server/workspaces/{remove.go => delete.go} (75%) rename pkg/server/workspaces/{get.go => find.go} (79%) rename pkg/views/prebuild/{add/add.go => create/create.go} (99%) rename pkg/views/server/runner/{register.go => create.go} (89%) rename pkg/views/targetconfig/{set.go => create.go} (98%) diff --git a/cmd/daytona/config/config.go b/cmd/daytona/config/config.go index 794af7592a..2e555ac8bd 100644 --- a/cmd/daytona/config/config.go +++ b/cmd/daytona/config/config.go @@ -89,7 +89,7 @@ func GetConfig() (*Config, error) { return &c, nil } -var ErrNoProfilesFound = errors.New("no profiles found. Run `daytona serve` to create a default profile or `daytona profile add` to connect to a remote server") +var ErrNoProfilesFound = errors.New("no profiles found. Run `daytona serve` to create a default profile or `daytona profile create` to connect to a remote server") func (c *Config) GetActiveProfile() (Profile, error) { if len(c.Profiles) == 0 { diff --git a/docs/daytona.md b/docs/daytona.md index 69ca60b99d..462a56ac4d 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -29,7 +29,7 @@ daytona [flags] * [daytona docs](daytona_docs.md) - Opens the Daytona documentation in your default browser. * [daytona env](daytona_env.md) - Manage server environment variables that are added to all targets and workspaces * [daytona forward](daytona_forward.md) - Forward a port from a workspace to your local machine -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers +* [daytona git-provider](daytona_git-provider.md) - Manage Git provider configs * [daytona ide](daytona_ide.md) - Choose the default IDE * [daytona info](daytona_info.md) - Show workspace info * [daytona list](daytona_list.md) - List workspaces diff --git a/docs/daytona_api-key.md b/docs/daytona_api-key.md index 11ac2ece14..9d965b3200 100644 --- a/docs/daytona_api-key.md +++ b/docs/daytona_api-key.md @@ -11,7 +11,7 @@ Api Key commands ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona api-key generate](daytona_api-key_generate.md) - Generate a new API key +* [daytona api-key create](daytona_api-key_create.md) - Create a new API key +* [daytona api-key delete](daytona_api-key_delete.md) - Delete an API key * [daytona api-key list](daytona_api-key_list.md) - List API keys -* [daytona api-key revoke](daytona_api-key_revoke.md) - Revoke an API key diff --git a/docs/daytona_api-key_generate.md b/docs/daytona_api-key_create.md similarity index 65% rename from docs/daytona_api-key_generate.md rename to docs/daytona_api-key_create.md index 66d7b563d4..3d673cab22 100644 --- a/docs/daytona_api-key_generate.md +++ b/docs/daytona_api-key_create.md @@ -1,9 +1,9 @@ -## daytona api-key generate +## daytona api-key create -Generate a new API key +Create a new API key ``` -daytona api-key generate [NAME] [flags] +daytona api-key create [NAME] [flags] ``` ### Options inherited from parent commands diff --git a/docs/daytona_api-key_revoke.md b/docs/daytona_api-key_delete.md similarity index 73% rename from docs/daytona_api-key_revoke.md rename to docs/daytona_api-key_delete.md index 90366c5c1b..b7b63e694d 100644 --- a/docs/daytona_api-key_revoke.md +++ b/docs/daytona_api-key_delete.md @@ -1,9 +1,9 @@ -## daytona api-key revoke +## daytona api-key delete -Revoke an API key +Delete an API key ``` -daytona api-key revoke [NAME] [flags] +daytona api-key delete [NAME] [flags] ``` ### Options diff --git a/docs/daytona_env.md b/docs/daytona_env.md index 3f73927e40..b2af6593f9 100644 --- a/docs/daytona_env.md +++ b/docs/daytona_env.md @@ -11,7 +11,7 @@ Manage server environment variables that are added to all targets and workspaces ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona env delete](daytona_env_delete.md) - Delete server environment variables * [daytona env list](daytona_env_list.md) - List server environment variables -* [daytona env remove](daytona_env_remove.md) - Remove server environment variables * [daytona env set](daytona_env_set.md) - Set server environment variables diff --git a/docs/daytona_env_remove.md b/docs/daytona_env_delete.md similarity index 70% rename from docs/daytona_env_remove.md rename to docs/daytona_env_delete.md index 05348f409d..dcb57fc792 100644 --- a/docs/daytona_env_remove.md +++ b/docs/daytona_env_delete.md @@ -1,9 +1,9 @@ -## daytona env remove +## daytona env delete -Remove server environment variables +Delete server environment variables ``` -daytona env remove [KEY]... [flags] +daytona env delete [KEY]... [flags] ``` ### Options inherited from parent commands diff --git a/docs/daytona_git-provider.md b/docs/daytona_git-provider.md new file mode 100644 index 0000000000..f6e994aa80 --- /dev/null +++ b/docs/daytona_git-provider.md @@ -0,0 +1,18 @@ +## daytona git-provider + +Manage Git provider configs + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona](daytona.md) - Daytona is a Dev Environment Manager +* [daytona git-provider create](daytona_git-provider_create.md) - Create a Git provider config +* [daytona git-provider delete](daytona_git-provider_delete.md) - Delete a Git provider config +* [daytona git-provider list](daytona_git-provider_list.md) - Lists your registered Git provider configs +* [daytona git-provider update](daytona_git-provider_update.md) - Update a Git provider + diff --git a/docs/daytona_git-provider_create.md b/docs/daytona_git-provider_create.md new file mode 100644 index 0000000000..22ef3fc907 --- /dev/null +++ b/docs/daytona_git-provider_create.md @@ -0,0 +1,18 @@ +## daytona git-provider create + +Create a Git provider config + +``` +daytona git-provider create [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-provider](daytona_git-provider.md) - Manage Git provider configs + diff --git a/docs/daytona_git-provider_delete.md b/docs/daytona_git-provider_delete.md new file mode 100644 index 0000000000..05b1c52a49 --- /dev/null +++ b/docs/daytona_git-provider_delete.md @@ -0,0 +1,25 @@ +## daytona git-provider delete + +Delete a Git provider config + +``` +daytona git-provider delete [flags] +``` + +### Options + +``` + -a, --all Delete all Git providers + -y, --yes Confirm deletion without prompt +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-provider](daytona_git-provider.md) - Manage Git provider configs + diff --git a/docs/daytona_git-providers_list.md b/docs/daytona_git-provider_list.md similarity index 51% rename from docs/daytona_git-providers_list.md rename to docs/daytona_git-provider_list.md index a99673badb..b1ab54dadb 100644 --- a/docs/daytona_git-providers_list.md +++ b/docs/daytona_git-provider_list.md @@ -1,9 +1,9 @@ -## daytona git-providers list +## daytona git-provider list -Lists your registered Git providers +Lists your registered Git provider configs ``` -daytona git-providers list [flags] +daytona git-provider list [flags] ``` ### Options @@ -20,5 +20,5 @@ daytona git-providers list [flags] ### SEE ALSO -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers +* [daytona git-provider](daytona_git-provider.md) - Manage Git provider configs diff --git a/docs/daytona_git-provider_update.md b/docs/daytona_git-provider_update.md new file mode 100644 index 0000000000..b768a04ddb --- /dev/null +++ b/docs/daytona_git-provider_update.md @@ -0,0 +1,18 @@ +## daytona git-provider update + +Update a Git provider + +``` +daytona git-provider update [flags] +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona git-provider](daytona_git-provider.md) - Manage Git provider configs + diff --git a/docs/daytona_git-providers.md b/docs/daytona_git-providers.md deleted file mode 100644 index 702fdac3a3..0000000000 --- a/docs/daytona_git-providers.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona git-providers - -Manage Git providers - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona git-providers add](daytona_git-providers_add.md) - Register a Git provider -* [daytona git-providers delete](daytona_git-providers_delete.md) - Unregister a Git provider -* [daytona git-providers list](daytona_git-providers_list.md) - Lists your registered Git providers -* [daytona git-providers update](daytona_git-providers_update.md) - Update a Git provider - diff --git a/docs/daytona_git-providers_add.md b/docs/daytona_git-providers_add.md deleted file mode 100644 index d7b20b69cb..0000000000 --- a/docs/daytona_git-providers_add.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona git-providers add - -Register a Git provider - -``` -daytona git-providers add [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_git-providers_delete.md b/docs/daytona_git-providers_delete.md deleted file mode 100644 index ab7a22aa23..0000000000 --- a/docs/daytona_git-providers_delete.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona git-providers delete - -Unregister a Git provider - -``` -daytona git-providers delete [flags] -``` - -### Options - -``` - -a, --all Remove all Git providers - -y, --yes Confirm deletion without prompt -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_git-providers_update.md b/docs/daytona_git-providers_update.md deleted file mode 100644 index 164f00de24..0000000000 --- a/docs/daytona_git-providers_update.md +++ /dev/null @@ -1,18 +0,0 @@ -## daytona git-providers update - -Update a Git provider - -``` -daytona git-providers update [flags] -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona git-providers](daytona_git-providers.md) - Manage Git providers - diff --git a/docs/daytona_prebuild.md b/docs/daytona_prebuild.md index 8fbe49c684..ed17fef4a9 100644 --- a/docs/daytona_prebuild.md +++ b/docs/daytona_prebuild.md @@ -11,7 +11,7 @@ Manage prebuilds ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona prebuild add](daytona_prebuild_add.md) - Add a prebuild configuration +* [daytona prebuild create](daytona_prebuild_create.md) - Create a prebuild configuration * [daytona prebuild delete](daytona_prebuild_delete.md) - Delete a prebuild configuration * [daytona prebuild info](daytona_prebuild_info.md) - Show prebuild configuration info * [daytona prebuild list](daytona_prebuild_list.md) - List prebuild configurations diff --git a/docs/daytona_prebuild_add.md b/docs/daytona_prebuild_create.md similarity index 84% rename from docs/daytona_prebuild_add.md rename to docs/daytona_prebuild_create.md index 736d45f192..1ae54acafe 100644 --- a/docs/daytona_prebuild_add.md +++ b/docs/daytona_prebuild_create.md @@ -1,9 +1,9 @@ -## daytona prebuild add +## daytona prebuild create -Add a prebuild configuration +Create a prebuild configuration ``` -daytona prebuild add [WORKSPACE_CONFIG] [flags] +daytona prebuild create [WORKSPACE_CONFIG] [flags] ``` ### Options diff --git a/docs/daytona_profile.md b/docs/daytona_profile.md index 2226adeae0..819d91d7b2 100644 --- a/docs/daytona_profile.md +++ b/docs/daytona_profile.md @@ -11,9 +11,9 @@ Manage profiles ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona profile add](daytona_profile_add.md) - Add profile -* [daytona profile delete](daytona_profile_delete.md) - Delete profile [PROFILE_NAME] -* [daytona profile edit](daytona_profile_edit.md) - Edit profile [PROFILE_NAME] +* [daytona profile create](daytona_profile_create.md) - Create a profile +* [daytona profile delete](daytona_profile_delete.md) - Delete a profile * [daytona profile list](daytona_profile_list.md) - List profiles +* [daytona profile update](daytona_profile_update.md) - Update profile [PROFILE_NAME] * [daytona profile use](daytona_profile_use.md) - Use profile [PROFILE_NAME] diff --git a/docs/daytona_profile_add.md b/docs/daytona_profile_create.md similarity index 80% rename from docs/daytona_profile_add.md rename to docs/daytona_profile_create.md index 12ea0fa96d..c831592df7 100644 --- a/docs/daytona_profile_add.md +++ b/docs/daytona_profile_create.md @@ -1,9 +1,9 @@ -## daytona profile add +## daytona profile create -Add profile +Create a profile ``` -daytona profile add [flags] +daytona profile create [flags] ``` ### Options diff --git a/docs/daytona_profile_delete.md b/docs/daytona_profile_delete.md index d8ed86d359..1118f7559a 100644 --- a/docs/daytona_profile_delete.md +++ b/docs/daytona_profile_delete.md @@ -1,9 +1,9 @@ ## daytona profile delete -Delete profile [PROFILE_NAME] +Delete a profile ``` -daytona profile delete [flags] +daytona profile delete [PROFILE_NAME] [flags] ``` ### Options inherited from parent commands diff --git a/docs/daytona_profile_edit.md b/docs/daytona_profile_update.md similarity index 77% rename from docs/daytona_profile_edit.md rename to docs/daytona_profile_update.md index 79be7454f4..ba44c251cc 100644 --- a/docs/daytona_profile_edit.md +++ b/docs/daytona_profile_update.md @@ -1,9 +1,9 @@ -## daytona profile edit +## daytona profile update -Edit profile [PROFILE_NAME] +Update profile [PROFILE_NAME] ``` -daytona profile edit [flags] +daytona profile update [flags] ``` ### Options diff --git a/docs/daytona_server_runner.md b/docs/daytona_server_runner.md index 61c965e02d..3080769590 100644 --- a/docs/daytona_server_runner.md +++ b/docs/daytona_server_runner.md @@ -11,8 +11,8 @@ Manage runners ### SEE ALSO * [daytona server](daytona_server.md) - Start the server process in daemon mode +* [daytona server runner create](daytona_server_runner_create.md) - Create a runner +* [daytona server runner delete](daytona_server_runner_delete.md) - Delete a runner * [daytona server runner list](daytona_server_runner_list.md) - List runners * [daytona server runner logs](daytona_server_runner_logs.md) - View runner logs -* [daytona server runner register](daytona_server_runner_register.md) - Register runner -* [daytona server runner unregister](daytona_server_runner_unregister.md) - Unregister runner diff --git a/docs/daytona_server_runner_register.md b/docs/daytona_server_runner_create.md similarity index 72% rename from docs/daytona_server_runner_register.md rename to docs/daytona_server_runner_create.md index ab1ec737b7..efaedb9ea2 100644 --- a/docs/daytona_server_runner_register.md +++ b/docs/daytona_server_runner_create.md @@ -1,9 +1,9 @@ -## daytona server runner register +## daytona server runner create -Register runner +Create a runner ``` -daytona server runner register [flags] +daytona server runner create [flags] ``` ### Options diff --git a/docs/daytona_server_runner_unregister.md b/docs/daytona_server_runner_delete.md similarity index 70% rename from docs/daytona_server_runner_unregister.md rename to docs/daytona_server_runner_delete.md index 66f10cce53..48434a37e8 100644 --- a/docs/daytona_server_runner_unregister.md +++ b/docs/daytona_server_runner_delete.md @@ -1,9 +1,9 @@ -## daytona server runner unregister +## daytona server runner delete -Unregister runner +Delete a runner ``` -daytona server runner unregister [RUNNER] [flags] +daytona server runner delete [RUNNER] [flags] ``` ### Options diff --git a/docs/daytona_target-config.md b/docs/daytona_target-config.md index e5a6b3b900..1903037058 100644 --- a/docs/daytona_target-config.md +++ b/docs/daytona_target-config.md @@ -11,7 +11,7 @@ Manage target configs ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona target-config add](daytona_target-config_add.md) - Add target config +* [daytona target-config create](daytona_target-config_create.md) - Create target config +* [daytona target-config delete](daytona_target-config_delete.md) - Deletes a target config * [daytona target-config list](daytona_target-config_list.md) - List target configs -* [daytona target-config remove](daytona_target-config_remove.md) - Remove target config diff --git a/docs/daytona_target-config_add.md b/docs/daytona_target-config_create.md similarity index 67% rename from docs/daytona_target-config_add.md rename to docs/daytona_target-config_create.md index 9d30d21acb..5923b56944 100644 --- a/docs/daytona_target-config_add.md +++ b/docs/daytona_target-config_create.md @@ -1,9 +1,9 @@ -## daytona target-config add +## daytona target-config create -Add target config +Create target config ``` -daytona target-config add [flags] +daytona target-config create [flags] ``` ### Options inherited from parent commands diff --git a/docs/daytona_target-config_remove.md b/docs/daytona_target-config_delete.md similarity index 71% rename from docs/daytona_target-config_remove.md rename to docs/daytona_target-config_delete.md index d21ed4565f..2c0c89f2e3 100644 --- a/docs/daytona_target-config_remove.md +++ b/docs/daytona_target-config_delete.md @@ -1,9 +1,9 @@ -## daytona target-config remove +## daytona target-config delete -Remove target config +Deletes a target config ``` -daytona target-config remove [TARGET_CONFIG] [flags] +daytona target-config delete [TARGET_CONFIG] [flags] ``` ### Options diff --git a/docs/daytona_template.md b/docs/daytona_template.md index 8986a48c58..3d5dfc02b7 100644 --- a/docs/daytona_template.md +++ b/docs/daytona_template.md @@ -11,7 +11,7 @@ Manage workspace templates ### SEE ALSO * [daytona](daytona.md) - Daytona is a Dev Environment Manager -* [daytona template add](daytona_template_add.md) - Add a workspace template +* [daytona template create](daytona_template_create.md) - Create a workspace template * [daytona template delete](daytona_template_delete.md) - Delete a workspace template * [daytona template info](daytona_template_info.md) - Show workspace template info * [daytona template list](daytona_template_list.md) - Lists workspace templates diff --git a/docs/daytona_template_add.md b/docs/daytona_template_create.md similarity index 92% rename from docs/daytona_template_add.md rename to docs/daytona_template_create.md index a74b5ae4c5..3902e725ee 100644 --- a/docs/daytona_template_add.md +++ b/docs/daytona_template_create.md @@ -1,9 +1,9 @@ -## daytona template add +## daytona template create -Add a workspace template +Create a workspace template ``` -daytona template add [flags] +daytona template create [flags] ``` ### Options diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 8829e81c59..09b085da63 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -21,7 +21,7 @@ see_also: - daytona docs - Opens the Daytona documentation in your default browser. - daytona env - Manage server environment variables that are added to all targets and workspaces - daytona forward - Forward a port from a workspace to your local machine - - daytona git-providers - Manage Git providers + - daytona git-provider - Manage Git provider configs - daytona ide - Choose the default IDE - daytona info - Show workspace info - daytona list - List workspaces diff --git a/hack/docs/daytona_api-key.yaml b/hack/docs/daytona_api-key.yaml index a886de682c..828f053221 100644 --- a/hack/docs/daytona_api-key.yaml +++ b/hack/docs/daytona_api-key.yaml @@ -6,6 +6,6 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager - - daytona api-key generate - Generate a new API key + - daytona api-key create - Create a new API key + - daytona api-key delete - Delete an API key - daytona api-key list - List API keys - - daytona api-key revoke - Revoke an API key diff --git a/hack/docs/daytona_api-key_generate.yaml b/hack/docs/daytona_api-key_create.yaml similarity index 56% rename from hack/docs/daytona_api-key_generate.yaml rename to hack/docs/daytona_api-key_create.yaml index 988087f62b..8851a68a79 100644 --- a/hack/docs/daytona_api-key_generate.yaml +++ b/hack/docs/daytona_api-key_create.yaml @@ -1,6 +1,6 @@ -name: daytona api-key generate -synopsis: Generate a new API key -usage: daytona api-key generate [NAME] [flags] +name: daytona api-key create +synopsis: Create a new API key +usage: daytona api-key create [NAME] [flags] inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_api-key_revoke.yaml b/hack/docs/daytona_api-key_delete.yaml similarity index 71% rename from hack/docs/daytona_api-key_revoke.yaml rename to hack/docs/daytona_api-key_delete.yaml index 2009ac9ee1..97c332363d 100644 --- a/hack/docs/daytona_api-key_revoke.yaml +++ b/hack/docs/daytona_api-key_delete.yaml @@ -1,6 +1,6 @@ -name: daytona api-key revoke -synopsis: Revoke an API key -usage: daytona api-key revoke [NAME] [flags] +name: daytona api-key delete +synopsis: Delete an API key +usage: daytona api-key delete [NAME] [flags] options: - name: "yes" shorthand: "y" diff --git a/hack/docs/daytona_env.yaml b/hack/docs/daytona_env.yaml index 9108319e9d..60e8d4172c 100644 --- a/hack/docs/daytona_env.yaml +++ b/hack/docs/daytona_env.yaml @@ -7,6 +7,6 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager + - daytona env delete - Delete server environment variables - daytona env list - List server environment variables - - daytona env remove - Remove server environment variables - daytona env set - Set server environment variables diff --git a/hack/docs/daytona_env_remove.yaml b/hack/docs/daytona_env_delete.yaml similarity index 64% rename from hack/docs/daytona_env_remove.yaml rename to hack/docs/daytona_env_delete.yaml index 5798051dea..b5f703bc42 100644 --- a/hack/docs/daytona_env_remove.yaml +++ b/hack/docs/daytona_env_delete.yaml @@ -1,6 +1,6 @@ -name: daytona env remove -synopsis: Remove server environment variables -usage: daytona env remove [KEY]... [flags] +name: daytona env delete +synopsis: Delete server environment variables +usage: daytona env delete [KEY]... [flags] inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_git-provider.yaml b/hack/docs/daytona_git-provider.yaml new file mode 100644 index 0000000000..4e56d440ee --- /dev/null +++ b/hack/docs/daytona_git-provider.yaml @@ -0,0 +1,12 @@ +name: daytona git-provider +synopsis: Manage Git provider configs +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona - Daytona is a Dev Environment Manager + - daytona git-provider create - Create a Git provider config + - daytona git-provider delete - Delete a Git provider config + - daytona git-provider list - Lists your registered Git provider configs + - daytona git-provider update - Update a Git provider diff --git a/hack/docs/daytona_git-provider_create.yaml b/hack/docs/daytona_git-provider_create.yaml new file mode 100644 index 0000000000..c0d498d41f --- /dev/null +++ b/hack/docs/daytona_git-provider_create.yaml @@ -0,0 +1,9 @@ +name: daytona git-provider create +synopsis: Create a Git provider config +usage: daytona git-provider create [flags] +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona git-provider - Manage Git provider configs diff --git a/hack/docs/daytona_git-providers_delete.yaml b/hack/docs/daytona_git-provider_delete.yaml similarity index 57% rename from hack/docs/daytona_git-providers_delete.yaml rename to hack/docs/daytona_git-provider_delete.yaml index 95d0109933..c02f62b381 100644 --- a/hack/docs/daytona_git-providers_delete.yaml +++ b/hack/docs/daytona_git-provider_delete.yaml @@ -1,11 +1,11 @@ -name: daytona git-providers delete -synopsis: Unregister a Git provider -usage: daytona git-providers delete [flags] +name: daytona git-provider delete +synopsis: Delete a Git provider config +usage: daytona git-provider delete [flags] options: - name: all shorthand: a default_value: "false" - usage: Remove all Git providers + usage: Delete all Git providers - name: "yes" shorthand: "y" default_value: "false" @@ -15,4 +15,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona git-providers - Manage Git providers + - daytona git-provider - Manage Git provider configs diff --git a/hack/docs/daytona_git-providers_list.yaml b/hack/docs/daytona_git-provider_list.yaml similarity index 53% rename from hack/docs/daytona_git-providers_list.yaml rename to hack/docs/daytona_git-provider_list.yaml index 002423af47..1d28e5028c 100644 --- a/hack/docs/daytona_git-providers_list.yaml +++ b/hack/docs/daytona_git-provider_list.yaml @@ -1,6 +1,6 @@ -name: daytona git-providers list -synopsis: Lists your registered Git providers -usage: daytona git-providers list [flags] +name: daytona git-provider list +synopsis: Lists your registered Git provider configs +usage: daytona git-provider list [flags] options: - name: format shorthand: f @@ -10,4 +10,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona git-providers - Manage Git providers + - daytona git-provider - Manage Git provider configs diff --git a/hack/docs/daytona_git-providers_update.yaml b/hack/docs/daytona_git-provider_update.yaml similarity index 50% rename from hack/docs/daytona_git-providers_update.yaml rename to hack/docs/daytona_git-provider_update.yaml index 3782e8afda..afb8879df3 100644 --- a/hack/docs/daytona_git-providers_update.yaml +++ b/hack/docs/daytona_git-provider_update.yaml @@ -1,9 +1,9 @@ -name: daytona git-providers update +name: daytona git-provider update synopsis: Update a Git provider -usage: daytona git-providers update [flags] +usage: daytona git-provider update [flags] inherited_options: - name: help default_value: "false" usage: help for daytona see_also: - - daytona git-providers - Manage Git providers + - daytona git-provider - Manage Git provider configs diff --git a/hack/docs/daytona_git-providers.yaml b/hack/docs/daytona_git-providers.yaml deleted file mode 100644 index 0d80b38486..0000000000 --- a/hack/docs/daytona_git-providers.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: daytona git-providers -synopsis: Manage Git providers -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona - Daytona is a Dev Environment Manager - - daytona git-providers add - Register a Git provider - - daytona git-providers delete - Unregister a Git provider - - daytona git-providers list - Lists your registered Git providers - - daytona git-providers update - Update a Git provider diff --git a/hack/docs/daytona_git-providers_add.yaml b/hack/docs/daytona_git-providers_add.yaml deleted file mode 100644 index 5eca9c0e79..0000000000 --- a/hack/docs/daytona_git-providers_add.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: daytona git-providers add -synopsis: Register a Git provider -usage: daytona git-providers add [flags] -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona git-providers - Manage Git providers diff --git a/hack/docs/daytona_prebuild.yaml b/hack/docs/daytona_prebuild.yaml index d667986aa0..815be39a0c 100644 --- a/hack/docs/daytona_prebuild.yaml +++ b/hack/docs/daytona_prebuild.yaml @@ -6,7 +6,7 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager - - daytona prebuild add - Add a prebuild configuration + - daytona prebuild create - Create a prebuild configuration - daytona prebuild delete - Delete a prebuild configuration - daytona prebuild info - Show prebuild configuration info - daytona prebuild list - List prebuild configurations diff --git a/hack/docs/daytona_prebuild_add.yaml b/hack/docs/daytona_prebuild_create.yaml similarity index 85% rename from hack/docs/daytona_prebuild_add.yaml rename to hack/docs/daytona_prebuild_create.yaml index 8e6624cb21..0e985f0a62 100644 --- a/hack/docs/daytona_prebuild_add.yaml +++ b/hack/docs/daytona_prebuild_create.yaml @@ -1,6 +1,6 @@ -name: daytona prebuild add -synopsis: Add a prebuild configuration -usage: daytona prebuild add [WORKSPACE_CONFIG] [flags] +name: daytona prebuild create +synopsis: Create a prebuild configuration +usage: daytona prebuild create [WORKSPACE_CONFIG] [flags] options: - name: branch shorthand: b diff --git a/hack/docs/daytona_profile.yaml b/hack/docs/daytona_profile.yaml index a9cc38d245..1a8c47f964 100644 --- a/hack/docs/daytona_profile.yaml +++ b/hack/docs/daytona_profile.yaml @@ -6,8 +6,8 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager - - daytona profile add - Add profile - - daytona profile delete - Delete profile [PROFILE_NAME] - - daytona profile edit - Edit profile [PROFILE_NAME] + - daytona profile create - Create a profile + - daytona profile delete - Delete a profile - daytona profile list - List profiles + - daytona profile update - Update profile [PROFILE_NAME] - daytona use - Use profile [PROFILE_NAME] diff --git a/hack/docs/daytona_profile_add.yaml b/hack/docs/daytona_profile_create.yaml similarity index 78% rename from hack/docs/daytona_profile_add.yaml rename to hack/docs/daytona_profile_create.yaml index c2c08730a2..e803f67969 100644 --- a/hack/docs/daytona_profile_add.yaml +++ b/hack/docs/daytona_profile_create.yaml @@ -1,6 +1,6 @@ -name: daytona profile add -synopsis: Add profile -usage: daytona profile add [flags] +name: daytona profile create +synopsis: Create a profile +usage: daytona profile create [flags] options: - name: api-key shorthand: k diff --git a/hack/docs/daytona_profile_delete.yaml b/hack/docs/daytona_profile_delete.yaml index 95628ac7c8..4041504d23 100644 --- a/hack/docs/daytona_profile_delete.yaml +++ b/hack/docs/daytona_profile_delete.yaml @@ -1,6 +1,6 @@ name: daytona profile delete -synopsis: Delete profile [PROFILE_NAME] -usage: daytona profile delete [flags] +synopsis: Delete a profile +usage: daytona profile delete [PROFILE_NAME] [flags] inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_profile_edit.yaml b/hack/docs/daytona_profile_update.yaml similarity index 75% rename from hack/docs/daytona_profile_edit.yaml rename to hack/docs/daytona_profile_update.yaml index a2c71353d6..d299da83aa 100644 --- a/hack/docs/daytona_profile_edit.yaml +++ b/hack/docs/daytona_profile_update.yaml @@ -1,6 +1,6 @@ -name: daytona profile edit -synopsis: Edit profile [PROFILE_NAME] -usage: daytona profile edit [flags] +name: daytona profile update +synopsis: Update profile [PROFILE_NAME] +usage: daytona profile update [flags] options: - name: api-key shorthand: k diff --git a/hack/docs/daytona_server_runner.yaml b/hack/docs/daytona_server_runner.yaml index 5bd530e25d..60e87707f7 100644 --- a/hack/docs/daytona_server_runner.yaml +++ b/hack/docs/daytona_server_runner.yaml @@ -6,7 +6,7 @@ inherited_options: usage: help for daytona see_also: - daytona server - Start the server process in daemon mode + - daytona server runner create - Create a runner + - daytona server runner delete - Delete a runner - daytona server runner list - List runners - daytona server runner logs - View runner logs - - daytona server runner register - Register runner - - daytona server runner unregister - Unregister runner diff --git a/hack/docs/daytona_server_runner_register.yaml b/hack/docs/daytona_server_runner_create.yaml similarity index 67% rename from hack/docs/daytona_server_runner_register.yaml rename to hack/docs/daytona_server_runner_create.yaml index 34888f1c7e..5cb76176a2 100644 --- a/hack/docs/daytona_server_runner_register.yaml +++ b/hack/docs/daytona_server_runner_create.yaml @@ -1,6 +1,6 @@ -name: daytona server runner register -synopsis: Register runner -usage: daytona server runner register [flags] +name: daytona server runner create +synopsis: Create a runner +usage: daytona server runner create [flags] options: - name: name shorthand: "n" diff --git a/hack/docs/daytona_server_runner_unregister.yaml b/hack/docs/daytona_server_runner_delete.yaml similarity index 68% rename from hack/docs/daytona_server_runner_unregister.yaml rename to hack/docs/daytona_server_runner_delete.yaml index 196903503c..39a5ccb875 100644 --- a/hack/docs/daytona_server_runner_unregister.yaml +++ b/hack/docs/daytona_server_runner_delete.yaml @@ -1,6 +1,6 @@ -name: daytona server runner unregister -synopsis: Unregister runner -usage: daytona server runner unregister [RUNNER] [flags] +name: daytona server runner delete +synopsis: Delete a runner +usage: daytona server runner delete [RUNNER] [flags] options: - name: "yes" shorthand: "y" diff --git a/hack/docs/daytona_target-config.yaml b/hack/docs/daytona_target-config.yaml index e62d7f6e63..92a38a5fe9 100644 --- a/hack/docs/daytona_target-config.yaml +++ b/hack/docs/daytona_target-config.yaml @@ -6,6 +6,6 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager - - daytona target-config add - Add target config + - daytona target-config create - Create target config + - daytona target-config delete - Deletes a target config - daytona target-config list - List target configs - - daytona target-config remove - Remove target config diff --git a/hack/docs/daytona_target-config_add.yaml b/hack/docs/daytona_target-config_create.yaml similarity index 58% rename from hack/docs/daytona_target-config_add.yaml rename to hack/docs/daytona_target-config_create.yaml index 6a7dee27aa..2f1f93e86a 100644 --- a/hack/docs/daytona_target-config_add.yaml +++ b/hack/docs/daytona_target-config_create.yaml @@ -1,6 +1,6 @@ -name: daytona target-config add -synopsis: Add target config -usage: daytona target-config add [flags] +name: daytona target-config create +synopsis: Create target config +usage: daytona target-config create [flags] inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_target-config_remove.yaml b/hack/docs/daytona_target-config_delete.yaml similarity index 69% rename from hack/docs/daytona_target-config_remove.yaml rename to hack/docs/daytona_target-config_delete.yaml index 99df880375..922967bd75 100644 --- a/hack/docs/daytona_target-config_remove.yaml +++ b/hack/docs/daytona_target-config_delete.yaml @@ -1,6 +1,6 @@ -name: daytona target-config remove -synopsis: Remove target config -usage: daytona target-config remove [TARGET_CONFIG] [flags] +name: daytona target-config delete +synopsis: Deletes a target config +usage: daytona target-config delete [TARGET_CONFIG] [flags] options: - name: "yes" shorthand: "y" diff --git a/hack/docs/daytona_template.yaml b/hack/docs/daytona_template.yaml index 96a55556d8..dc05f766f8 100644 --- a/hack/docs/daytona_template.yaml +++ b/hack/docs/daytona_template.yaml @@ -6,7 +6,7 @@ inherited_options: usage: help for daytona see_also: - daytona - Daytona is a Dev Environment Manager - - daytona template add - Add a workspace template + - daytona template create - Create a workspace template - daytona template delete - Delete a workspace template - daytona template info - Show workspace template info - daytona template list - Lists workspace templates diff --git a/hack/docs/daytona_template_add.yaml b/hack/docs/daytona_template_create.yaml similarity index 91% rename from hack/docs/daytona_template_add.yaml rename to hack/docs/daytona_template_create.yaml index 283a3d606c..d1b7179a22 100644 --- a/hack/docs/daytona_template_add.yaml +++ b/hack/docs/daytona_template_create.yaml @@ -1,6 +1,6 @@ -name: daytona template add -synopsis: Add a workspace template -usage: daytona template add [flags] +name: daytona template create +synopsis: Create a workspace template +usage: daytona template create [flags] options: - name: builder usage: Specify the builder (currently auto/devcontainer/none) diff --git a/internal/cmd/tailscale/connection.go b/internal/cmd/tailscale/connection.go index 43fef15419..a801240da1 100644 --- a/internal/cmd/tailscale/connection.go +++ b/internal/cmd/tailscale/connection.go @@ -36,7 +36,7 @@ func GetConnection(profile *config.Profile) (*tsnet.Server, error) { return nil, apiclient_util.HandleErrorResponse(res, err) } - networkKey, res, err := apiClient.ServerAPI.GenerateNetworkKeyExecute(apiclient.ApiGenerateNetworkKeyRequest{}) + networkKey, res, err := apiClient.ServerAPI.CreateNetworkKeyExecute(apiclient.ApiCreateNetworkKeyRequest{}) if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } diff --git a/internal/testing/server/targets/mocks/api_key_service.go b/internal/testing/server/targets/mocks/api_key_service.go index 716719a280..12ca222b18 100644 --- a/internal/testing/server/targets/mocks/api_key_service.go +++ b/internal/testing/server/targets/mocks/api_key_service.go @@ -18,7 +18,7 @@ func NewMockApiKeyService() *mockApiKeyService { return &mockApiKeyService{} } -func (s *mockApiKeyService) Generate(keyType models.ApiKeyType, name string) (string, error) { +func (s *mockApiKeyService) Create(keyType models.ApiKeyType, name string) (string, error) { args := s.Called(keyType, name) return args.String(0), args.Error(1) } @@ -43,7 +43,7 @@ func (s *mockApiKeyService) ListClientKeys() ([]*models.ApiKey, error) { return args.Get(0).([]*models.ApiKey), args.Error(1) } -func (s *mockApiKeyService) Revoke(name string) error { +func (s *mockApiKeyService) Delete(name string) error { args := s.Called(name) return args.Error(0) } diff --git a/internal/testing/server/targets/mocks/git_provider_service.go b/internal/testing/server/targets/mocks/git_provider_service.go index d8cedef6bf..fda6641879 100644 --- a/internal/testing/server/targets/mocks/git_provider_service.go +++ b/internal/testing/server/targets/mocks/git_provider_service.go @@ -21,7 +21,7 @@ func NewMockGitProviderService() *MockGitProviderService { return &MockGitProviderService{} } -func (m *MockGitProviderService) GetConfig(id string) (*models.GitProviderConfig, error) { +func (m *MockGitProviderService) FindConfig(id string) (*models.GitProviderConfig, error) { args := m.Called(id) return args.Get(0).(*models.GitProviderConfig), args.Error(1) } @@ -76,12 +76,12 @@ func (m *MockGitProviderService) ListConfigs() ([]*models.GitProviderConfig, err return args.Get(0).([]*models.GitProviderConfig), args.Error(1) } -func (m *MockGitProviderService) RemoveGitProvider(gitProviderId string) error { +func (m *MockGitProviderService) DeleteGitProvider(gitProviderId string) error { args := m.Called(gitProviderId) return args.Error(0) } -func (m *MockGitProviderService) SetGitProviderConfig(providerConfig *models.GitProviderConfig) error { +func (m *MockGitProviderService) SaveGitProviderConfig(providerConfig *models.GitProviderConfig) error { args := m.Called(providerConfig) return args.Error(0) } diff --git a/internal/util/apiclient/api_client.go b/internal/util/apiclient/api_client.go index 496e999905..7426b327b5 100644 --- a/internal/util/apiclient/api_client.go +++ b/internal/util/apiclient/api_client.go @@ -151,7 +151,7 @@ func GetTarget(targetNameOrId string) (*apiclient.TargetDTO, int, error) { return nil, -1, err } - target, res, err := apiClient.TargetAPI.GetTarget(ctx, targetNameOrId).Execute() + target, res, err := apiClient.TargetAPI.FindTarget(ctx, targetNameOrId).Execute() if err != nil { return nil, res.StatusCode, HandleErrorResponse(res, err) } @@ -167,7 +167,7 @@ func GetWorkspace(workspaceNameOrId string) (*apiclient.WorkspaceDTO, int, error return nil, -1, err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceNameOrId).Execute() + workspace, res, err := apiClient.WorkspaceAPI.FindWorkspace(ctx, workspaceNameOrId).Execute() if err != nil { return nil, res.StatusCode, HandleErrorResponse(res, err) } diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index b1bdcf3e90..038d0b1097 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -271,7 +271,7 @@ func (a *Agent) updateWorkspaceMetadata() error { return err } - res, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), a.Config.WorkspaceId).WorkspaceMetadata(apiclient.UpdateWorkspaceMetadataDTO{ + res, err := apiClient.WorkspaceAPI.UpdateWorkspaceMetadata(context.Background(), a.Config.WorkspaceId).WorkspaceMetadata(apiclient.UpdateWorkspaceMetadataDTO{ Uptime: uptime, GitStatus: gitStatusDto, }).Execute() @@ -289,7 +289,7 @@ func (a *Agent) updateTargetMetadata() error { } uptime := a.uptime() - res, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), a.Config.TargetId).TargetMetadata(apiclient.UpdateTargetMetadataDTO{ + res, err := apiClient.TargetAPI.UpdateTargetMetadata(context.Background(), a.Config.TargetId).TargetMetadata(apiclient.UpdateTargetMetadataDTO{ Uptime: uptime, }).Execute() if err != nil { diff --git a/pkg/agent/tailscale/server.go b/pkg/agent/tailscale/server.go index 7081010e81..0ab2fc9271 100644 --- a/pkg/agent/tailscale/server.go +++ b/pkg/agent/tailscale/server.go @@ -87,7 +87,7 @@ func (s *Server) getNetworkKey() (string, error) { return "", err } - networkKey, _, err := apiClient.ServerAPI.GenerateNetworkKeyExecute(apiclient.ApiGenerateNetworkKeyRequest{}) + networkKey, _, err := apiClient.ServerAPI.CreateNetworkKeyExecute(apiclient.ApiCreateNetworkKeyRequest{}) // Retry indefinitely. Used to reconnect to the Daytona Server if err != nil { log.Tracef("Failed to get network key: %v", err) diff --git a/pkg/api/controllers/apikey/apikey.go b/pkg/api/controllers/apikey/apikey.go index b87c9119ff..5bd9aaabee 100644 --- a/pkg/api/controllers/apikey/apikey.go +++ b/pkg/api/controllers/apikey/apikey.go @@ -43,17 +43,17 @@ func ListClientApiKeys(ctx *gin.Context) { ctx.JSON(200, result) } -// RevokeApiKey godoc +// DeleteApiKey godoc // // @Tags apiKey -// @Summary Revoke API key -// @Description Revoke API key +// @Summary Delete API key +// @Description Delete API key // @Param apiKeyName path string true "API key name" // @Success 200 // @Router /apikey/{apiKeyName} [delete] // -// @id RevokeApiKey -func RevokeApiKey(ctx *gin.Context) { +// @id DeleteApiKey +func DeleteApiKey(ctx *gin.Context) { apiKeyName := ctx.Param("apiKeyName") server := server.GetInstance(nil) @@ -65,13 +65,13 @@ func RevokeApiKey(ctx *gin.Context) { } if currentApiKeyName == apiKeyName { - ctx.AbortWithError(http.StatusForbidden, fmt.Errorf("cannot revoke current api key")) + ctx.AbortWithError(http.StatusForbidden, fmt.Errorf("cannot delete current api key")) return } - err = server.ApiKeyService.Revoke(ctx.Request.Context(), apiKeyName) + err = server.ApiKeyService.Delete(ctx.Request.Context(), apiKeyName) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to revoke api key: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete api key: %w", err)) return } diff --git a/pkg/api/controllers/apikey/generate.go b/pkg/api/controllers/apikey/create.go similarity index 70% rename from pkg/api/controllers/apikey/generate.go rename to pkg/api/controllers/apikey/create.go index c195bc2ee2..e656343ae5 100644 --- a/pkg/api/controllers/apikey/generate.go +++ b/pkg/api/controllers/apikey/create.go @@ -12,23 +12,23 @@ import ( "github.com/gin-gonic/gin" ) -// GenerateApiKey godoc +// CreateApiKey godoc // // @Tags apiKey -// @Summary Generate an API key -// @Description Generate an API key +// @Summary Create an API key +// @Description Create an API key // @Produce plain // @Param apiKeyName path string true "API key name" // @Success 200 {string} apiKey // @Router /apikey/{apiKeyName} [post] // -// @id GenerateApiKey -func GenerateApiKey(ctx *gin.Context) { +// @id CreateApiKey +func CreateApiKey(ctx *gin.Context) { apiKeyName := ctx.Param("apiKeyName") server := server.GetInstance(nil) - response, err := server.ApiKeyService.Generate(ctx.Request.Context(), models.ApiKeyTypeClient, apiKeyName) + response, err := server.ApiKeyService.Create(ctx.Request.Context(), models.ApiKeyTypeClient, apiKeyName) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to get API keys: %w", err)) return diff --git a/pkg/api/controllers/build/get.go b/pkg/api/controllers/build/find.go similarity index 87% rename from pkg/api/controllers/build/get.go rename to pkg/api/controllers/build/find.go index be74ee9a4c..bd0c9cd5cb 100644 --- a/pkg/api/controllers/build/get.go +++ b/pkg/api/controllers/build/find.go @@ -13,18 +13,18 @@ import ( "github.com/gin-gonic/gin" ) -// GetBuild godoc +// FindBuild godoc // // @Tags build -// @Summary Get build data -// @Description Get build data +// @Summary Find build +// @Description Find build // @Accept json // @Param buildId path string true "Build ID" // @Success 200 {object} BuildDTO // @Router /build/{buildId} [get] // -// @id GetBuild -func GetBuild(ctx *gin.Context) { +// @id FindBuild +func FindBuild(ctx *gin.Context) { buildId := ctx.Param("buildId") server := server.GetInstance(nil) diff --git a/pkg/api/controllers/containerregistry/get.go b/pkg/api/controllers/containerregistry/find.go similarity index 84% rename from pkg/api/controllers/containerregistry/get.go rename to pkg/api/controllers/containerregistry/find.go index 9e9691595a..6b4a40109f 100644 --- a/pkg/api/controllers/containerregistry/get.go +++ b/pkg/api/controllers/containerregistry/find.go @@ -14,19 +14,19 @@ import ( "github.com/gin-gonic/gin" ) -// GetContainerRegistry godoc +// FindContainerRegistry godoc // // @Tags container registry -// @Summary Get container registry -// @Description Get container registry +// @Summary Find container registry +// @Description Find container registry // @Produce json // @Param server path string true "Container registry server" // @Param workspaceId query string false "Workspace ID or Name" // @Success 200 {object} ContainerRegistry // @Router /container-registry/{server} [get] // -// @id GetContainerRegistry -func GetContainerRegistry(ctx *gin.Context) { +// @id FindContainerRegistry +func FindContainerRegistry(ctx *gin.Context) { serverName := ctx.Param("server") workspaceId := ctx.Query("workspaceId") @@ -44,7 +44,7 @@ func GetContainerRegistry(ctx *gin.Context) { envVars = serverEnvVars if workspaceId != "" { - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + w, err := server.WorkspaceService.FindWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { diff --git a/pkg/api/controllers/env/env.go b/pkg/api/controllers/env/env.go index 6ed12fd388..ebbabd4f70 100644 --- a/pkg/api/controllers/env/env.go +++ b/pkg/api/controllers/env/env.go @@ -38,18 +38,18 @@ func ListEnvironmentVariables(ctx *gin.Context) { ctx.JSON(200, envVars) } -// SetEnvironmentVariable godoc +// SaveEnvironmentVariable godoc // // @Tags envVar -// @Summary Set environment variable -// @Description Set environment variable +// @Summary Save environment variable +// @Description Save environment variable // @Accept json // @Param environmentVariable body models.EnvironmentVariable true "Environment Variable" // @Success 201 // @Router /env [put] // -// @id SetEnvironmentVariable -func SetEnvironmentVariable(ctx *gin.Context) { +// @id SaveEnvironmentVariable +func SaveEnvironmentVariable(ctx *gin.Context) { var req models.EnvironmentVariable err := ctx.BindJSON(&req) if err != nil { @@ -88,7 +88,7 @@ func DeleteEnvironmentVariable(ctx *gin.Context) { ctx.Status(204) return } - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove environment variable: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete environment variable: %w", err)) return } diff --git a/pkg/api/controllers/gitprovider/gitprovider.go b/pkg/api/controllers/gitprovider/gitprovider.go index 5b91fbcdf5..3337f7439e 100644 --- a/pkg/api/controllers/gitprovider/gitprovider.go +++ b/pkg/api/controllers/gitprovider/gitprovider.go @@ -86,23 +86,23 @@ func ListGitProvidersForUrl(ctx *gin.Context) { ctx.JSON(200, gitProviders) } -// GetGitProvider godoc +// FindGitProvider godoc // // @Tags gitProvider -// @Summary Get Git provider -// @Description Get Git provider +// @Summary Find Git provider +// @Description Find Git provider // @Produce plain // @Param gitProviderId path string true "ID" // @Success 200 {object} models.GitProviderConfig // @Router /gitprovider/{gitProviderId} [get] // -// @id GetGitProvider -func GetGitProvider(ctx *gin.Context) { +// @id FindGitProvider +func FindGitProvider(ctx *gin.Context) { id := ctx.Param("gitProviderId") server := server.GetInstance(nil) - gitProvider, err := server.GitProviderService.GetConfig(ctx.Request.Context(), id) + gitProvider, err := server.GitProviderService.FindConfig(ctx.Request.Context(), id) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -120,18 +120,18 @@ func GetGitProvider(ctx *gin.Context) { ctx.JSON(200, gitProvider) } -// GetGitProviderIdForUrl godoc +// FindGitProviderIdForUrl godoc // // @Tags gitProvider -// @Summary Get Git provider ID -// @Description Get Git provider ID +// @Summary Find Git provider ID +// @Description Find Git provider ID // @Produce plain // @Param url path string true "Url" // @Success 200 {string} providerId // @Router /gitprovider/id-for-url/{url} [get] // -// @id GetGitProviderIdForUrl -func GetGitProviderIdForUrl(ctx *gin.Context) { +// @id FindGitProviderIdForUrl +func FindGitProviderIdForUrl(ctx *gin.Context) { urlParam := ctx.Param("url") decodedUrl, err := url.QueryUnescape(urlParam) @@ -155,18 +155,18 @@ func GetGitProviderIdForUrl(ctx *gin.Context) { ctx.String(200, providerId) } -// SetGitProvider godoc +// SaveGitProvider godoc // // @Tags gitProvider -// @Summary Set Git provider -// @Description Set Git provider +// @Summary Save Git provider +// @Description Save Git provider // @Param gitProviderConfig body SetGitProviderConfig true "Git provider" // @Produce json // @Success 200 // @Router /gitprovider [put] // -// @id SetGitProvider -func SetGitProvider(ctx *gin.Context) { +// @id SaveGitProvider +func SaveGitProvider(ctx *gin.Context) { var setConfigDto dto.SetGitProviderConfig err := ctx.BindJSON(&setConfigDto) @@ -194,7 +194,7 @@ func SetGitProvider(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.GitProviderService.SetGitProviderConfig(ctx.Request.Context(), &gitProviderConfig) + err = server.GitProviderService.SaveGitProviderConfig(ctx.Request.Context(), &gitProviderConfig) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -207,23 +207,23 @@ func SetGitProvider(ctx *gin.Context) { ctx.JSON(200, nil) } -// RemoveGitProvider godoc +// DeleteGitProvider godoc // // @Tags gitProvider -// @Summary Remove Git provider -// @Description Remove Git provider +// @Summary Delete Git provider +// @Description Delete Git provider // @Param gitProviderId path string true "Git provider" // @Produce json // @Success 200 // @Router /gitprovider/{gitProviderId} [delete] // -// @id RemoveGitProvider -func RemoveGitProvider(ctx *gin.Context) { +// @id DeleteGitProvider +func DeleteGitProvider(ctx *gin.Context) { gitProviderId := ctx.Param("gitProviderId") server := server.GetInstance(nil) - err := server.GitProviderService.RemoveGitProvider(ctx.Request.Context(), gitProviderId) + err := server.GitProviderService.DeleteGitProviderConfig(ctx.Request.Context(), gitProviderId) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/runner/register.go b/pkg/api/controllers/runner/create.go similarity index 53% rename from pkg/api/controllers/runner/register.go rename to pkg/api/controllers/runner/create.go index eed21c7bf0..0d102565c5 100644 --- a/pkg/api/controllers/runner/register.go +++ b/pkg/api/controllers/runner/create.go @@ -12,20 +12,20 @@ import ( "github.com/gin-gonic/gin" ) -// RegisterRunner godoc +// CreateRunner godoc // // @Tags runner -// @Summary Register a runner -// @Description Register a runner -// @Param runner body RegisterRunnerDTO true "Register runner" +// @Summary Create a runner +// @Description Create a runner +// @Param runner body CreateRunnerDTO true "Runner" // @Produce json -// @Success 200 {object} RegisterRunnerResultDTO +// @Success 200 {object} CreateRunnerResultDTO // @Router /runner [post] // -// @id RegisterRunner -func RegisterRunner(ctx *gin.Context) { - var registerRunnerReq services.RegisterRunnerDTO - err := ctx.BindJSON(®isterRunnerReq) +// @id CreateRunner +func CreateRunner(ctx *gin.Context) { + var createRunnerReq services.CreateRunnerDTO + err := ctx.BindJSON(&createRunnerReq) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) return @@ -33,13 +33,13 @@ func RegisterRunner(ctx *gin.Context) { server := server.GetInstance(nil) - r, err := server.RunnerService.RegisterRunner(ctx.Request.Context(), registerRunnerReq) + r, err := server.RunnerService.CreateRunner(ctx.Request.Context(), createRunnerReq) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to register runner: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create runner: %w", err)) return } - ctx.JSON(200, services.RegisterRunnerResultDTO{ + ctx.JSON(200, services.CreateRunnerResultDTO{ Runner: r.Runner, ApiKey: r.ApiKey, }) diff --git a/pkg/api/controllers/runner/remove.go b/pkg/api/controllers/runner/delete.go similarity index 68% rename from pkg/api/controllers/runner/remove.go rename to pkg/api/controllers/runner/delete.go index 4741ccbfa7..0347090247 100644 --- a/pkg/api/controllers/runner/remove.go +++ b/pkg/api/controllers/runner/delete.go @@ -11,24 +11,24 @@ import ( "github.com/gin-gonic/gin" ) -// RemoveRunner godoc +// DeleteRunner godoc // // @Tags runner -// @Summary Remove runner -// @Description Remove runner +// @Summary Delete runner +// @Description Delete runner // @Param runnerId path string true "Runner ID" // @Success 200 // @Router /runner/{runnerId} [delete] // -// @id RemoveRunner -func RemoveRunner(ctx *gin.Context) { +// @id DeleteRunner +func DeleteRunner(ctx *gin.Context) { runnerId := ctx.Param("runnerId") server := server.GetInstance(nil) - err := server.RunnerService.RemoveRunner(ctx.Request.Context(), runnerId) + err := server.RunnerService.DeleteRunner(ctx.Request.Context(), runnerId) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove runner: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete runner: %w", err)) return } diff --git a/pkg/api/controllers/runner/get.go b/pkg/api/controllers/runner/find.go similarity index 77% rename from pkg/api/controllers/runner/get.go rename to pkg/api/controllers/runner/find.go index d0c9b99117..4dbc49c83c 100644 --- a/pkg/api/controllers/runner/get.go +++ b/pkg/api/controllers/runner/find.go @@ -12,23 +12,23 @@ import ( "github.com/gin-gonic/gin" ) -// GetRunner godoc +// FindRunner godoc // // @Tags runner -// @Summary Get a runner -// @Description Get a runner +// @Summary Find a runner +// @Description Find a runner // @Param runnerId path string true "Runner ID" // @Produce json // @Success 200 {object} RunnerDTO // @Router /runner/{runnerId} [get] // -// @id GetRunner -func GetRunner(ctx *gin.Context) { +// @id FindRunner +func FindRunner(ctx *gin.Context) { runnerId := ctx.Param("runnerId") server := server.GetInstance(nil) - r, err := server.RunnerService.GetRunner(ctx.Request.Context(), runnerId) + r, err := server.RunnerService.FindRunner(ctx.Request.Context(), runnerId) if err != nil { statusCode := http.StatusInternalServerError if stores.IsRunnerNotFound(err) { diff --git a/pkg/api/controllers/runner/metadata.go b/pkg/api/controllers/runner/metadata.go index 4866f01c97..61785965a5 100644 --- a/pkg/api/controllers/runner/metadata.go +++ b/pkg/api/controllers/runner/metadata.go @@ -13,18 +13,18 @@ import ( "github.com/gin-gonic/gin" ) -// SetRunnerMetadata godoc +// UpdateRunnerMetadata godoc // // @Tags runner -// @Summary Set runner metadata -// @Description Set runner metadata +// @Summary Update runner metadata +// @Description Update runner metadata // @Param runnerId path string true "Runner ID" // @Param runnerMetadata body UpdateRunnerMetadataDTO true "Runner Metadata" // @Success 200 // @Router /runner/{runnerId}/metadata [post] // -// @id SetRunnerMetadata -func SetRunnerMetadata(ctx *gin.Context) { +// @id UpdateRunnerMetadata +func UpdateRunnerMetadata(ctx *gin.Context) { runnerId := ctx.Param("runnerId") var runnerMetadata dto.UpdateRunnerMetadataDTO @@ -36,7 +36,7 @@ func SetRunnerMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.RunnerService.SetRunnerMetadata(ctx.Request.Context(), runnerId, &models.RunnerMetadata{ + err = server.RunnerService.UpdateRunnerMetadata(ctx.Request.Context(), runnerId, &models.RunnerMetadata{ RunnerId: runnerId, Uptime: runnerMetadata.Uptime, Providers: runnerMetadata.Providers, diff --git a/pkg/api/controllers/server/server.go b/pkg/api/controllers/server/server.go index 4da10e9cc7..a81b894c5a 100644 --- a/pkg/api/controllers/server/server.go +++ b/pkg/api/controllers/server/server.go @@ -32,19 +32,19 @@ func GetConfig(ctx *gin.Context) { ctx.JSON(200, config) } -// SetConfig godoc +// SaveConfig godoc // // @Tags server -// @Summary Set the server configuration -// @Description Set the server configuration +// @Summary Save the server configuration +// @Description Save the server configuration // @Accept json // @Produce json // @Param config body ServerConfig true "Server configuration" // @Success 200 {object} ServerConfig -// @Router /server/config [post] +// @Router /server/config [put] // -// @id SetConfig -func SetConfig(ctx *gin.Context) { +// @id SaveConfig +func SaveConfig(ctx *gin.Context) { var c server.Config err := ctx.BindJSON(&c) if err != nil { @@ -61,17 +61,17 @@ func SetConfig(ctx *gin.Context) { ctx.JSON(200, c) } -// GenerateNetworkKey godoc +// CreateNetworkKey godoc // // @Tags server -// @Summary Generate a new authentication key -// @Description Generate a new authentication key +// @Summary Create a new authentication key +// @Description Create a new authentication key // @Produce json // @Success 200 {object} NetworkKey // @Router /server/network-key [post] // -// @id GenerateNetworkKey -func GenerateNetworkKey(ctx *gin.Context) { +// @id CreateNetworkKey +func CreateNetworkKey(ctx *gin.Context) { s := server.GetInstance(nil) authKey, err := s.TailscaleServer.CreateAuthKey(headscale.HEADSCALE_USERNAME) @@ -86,8 +86,8 @@ func GenerateNetworkKey(ctx *gin.Context) { // GetServerLogFiles godoc // // @Tags server -// @Summary List server log files -// @Description List server log files +// @Summary Get server log files +// @Description Get server log files // @Produce json // @Success 200 {array} string // @Router /server/logs [get] diff --git a/pkg/api/controllers/target/remove.go b/pkg/api/controllers/target/delete.go similarity index 74% rename from pkg/api/controllers/target/remove.go rename to pkg/api/controllers/target/delete.go index 632ed4cc22..fb23b66ddc 100644 --- a/pkg/api/controllers/target/remove.go +++ b/pkg/api/controllers/target/delete.go @@ -13,18 +13,18 @@ import ( "github.com/gin-gonic/gin" ) -// RemoveTarget godoc +// DeleteTarget godoc // // @Tags target -// @Summary Remove target -// @Description Remove target +// @Summary Delete target +// @Description Delete target // @Param targetId path string true "Target ID" // @Param force query bool false "Force" // @Success 200 // @Router /target/{targetId} [delete] // -// @id RemoveTarget -func RemoveTarget(ctx *gin.Context) { +// @id DeleteTarget +func DeleteTarget(ctx *gin.Context) { targetId := ctx.Param("targetId") forceQuery := ctx.Query("force") var err error @@ -41,13 +41,13 @@ func RemoveTarget(ctx *gin.Context) { server := server.GetInstance(nil) if force { - err = server.TargetService.ForceRemoveTarget(ctx.Request.Context(), targetId) + err = server.TargetService.ForceDeleteTarget(ctx.Request.Context(), targetId) } else { - err = server.TargetService.RemoveTarget(ctx.Request.Context(), targetId) + err = server.TargetService.DeleteTarget(ctx.Request.Context(), targetId) } if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete target: %w", err)) return } diff --git a/pkg/api/controllers/target/metadata.go b/pkg/api/controllers/target/metadata.go index aeac798c1e..b7e57baceb 100644 --- a/pkg/api/controllers/target/metadata.go +++ b/pkg/api/controllers/target/metadata.go @@ -13,18 +13,18 @@ import ( "github.com/gin-gonic/gin" ) -// SetTargetMetadata godoc +// UpdateTargetMetadata godoc // // @Tags target -// @Summary Set target metadata -// @Description Set target metadata +// @Summary Update target metadata +// @Description Update target metadata // @Param targetId path string true "Target ID" // @Param targetMetadata body UpdateTargetMetadataDTO true "Target Metadata" // @Success 200 // @Router /target/{targetId}/metadata [post] // -// @id SetTargetMetadata -func SetTargetMetadata(ctx *gin.Context) { +// @id UpdateTargetMetadata +func UpdateTargetMetadata(ctx *gin.Context) { targetId := ctx.Param("targetId") var updateDTO dto.UpdateTargetMetadataDTO @@ -36,7 +36,7 @@ func SetTargetMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.TargetService.SetTargetMetadata(ctx.Request.Context(), targetId, &models.TargetMetadata{ + _, err = server.TargetService.UpdateTargetMetadata(ctx.Request.Context(), targetId, &models.TargetMetadata{ Uptime: updateDTO.Uptime, }) if err != nil { diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index 33b2c63225..13e8d15f66 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -15,19 +15,19 @@ import ( "github.com/gin-gonic/gin" ) -// GetTarget godoc +// FindTarget godoc // // @Tags target -// @Summary Get target info -// @Description Get target info +// @Summary Find target +// @Description Find target // @Produce json // @Param targetId path string true "Target ID or Name" // @Param showOptions query bool false "Show target config options" // @Success 200 {object} TargetDTO // @Router /target/{targetId} [get] // -// @id GetTarget -func GetTarget(ctx *gin.Context) { +// @id FindTarget +func FindTarget(ctx *gin.Context) { targetId := ctx.Param("targetId") showTargetConfigOptionsQuery := ctx.Query("showOptions") var showTargetConfigOptions bool @@ -37,7 +37,7 @@ func GetTarget(ctx *gin.Context) { server := server.GetInstance(nil) - t, err := server.TargetService.GetTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + t, err := server.TargetService.FindTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsTargetNotFound(err) || services.IsTargetDeleted(err) { diff --git a/pkg/api/controllers/targetconfig/add.go b/pkg/api/controllers/targetconfig/create.go similarity index 64% rename from pkg/api/controllers/targetconfig/add.go rename to pkg/api/controllers/targetconfig/create.go index 85babd5673..850572afb9 100644 --- a/pkg/api/controllers/targetconfig/add.go +++ b/pkg/api/controllers/targetconfig/create.go @@ -12,25 +12,25 @@ import ( "github.com/gin-gonic/gin" ) -// AddTargetConfig godoc +// CreateTargetConfig godoc // // @Tags target-config -// @Summary Add a target config -// @Description Add a target config -// @Param targetConfig body AddTargetConfigDTO true "Target config to add" -// @Param showOptions query bool false "Show target config options" +// @Summary Create a target config +// @Description Create a target config +// @Param targetConfig body CreateTargetConfigDTO true "Target config to create" +// @Param showOptions query bool false "Show target config options" // @Success 200 {object} TargetConfig -// @Router /target-config [put] +// @Router /target-config [post] // -// @id AddTargetConfig -func AddTargetConfig(ctx *gin.Context) { +// @id CreateTargetConfig +func CreateTargetConfig(ctx *gin.Context) { showTargetConfigOptionsQuery := ctx.Query("showOptions") var showTargetConfigOptions bool if showTargetConfigOptionsQuery == "true" { showTargetConfigOptions = true } - var req services.AddTargetConfigDTO + var req services.CreateTargetConfigDTO err := ctx.BindJSON(&req) if err != nil { ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %w", err)) @@ -39,7 +39,7 @@ func AddTargetConfig(ctx *gin.Context) { server := server.GetInstance(nil) - targetConfig, err := server.TargetConfigService.Add(ctx.Request.Context(), req) + targetConfig, err := server.TargetConfigService.Create(ctx.Request.Context(), req) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to set target config: %w", err)) return diff --git a/pkg/api/controllers/targetconfig/remove.go b/pkg/api/controllers/targetconfig/delete.go similarity index 73% rename from pkg/api/controllers/targetconfig/remove.go rename to pkg/api/controllers/targetconfig/delete.go index e69d6bad2b..ad2efee045 100644 --- a/pkg/api/controllers/targetconfig/remove.go +++ b/pkg/api/controllers/targetconfig/delete.go @@ -11,24 +11,24 @@ import ( "github.com/gin-gonic/gin" ) -// RemoveTargetConfig godoc +// DeleteTargetConfig godoc // // @Tags target-config -// @Summary Remove a target config -// @Description Remove a target config +// @Summary Delete a target config +// @Description Delete a target config // @Param configId path string true "Target Config Id" // @Success 204 // @Router /target-config/{configId} [delete] // -// @id RemoveTargetConfig -func RemoveTargetConfig(ctx *gin.Context) { +// @id DeleteTargetConfig +func DeleteTargetConfig(ctx *gin.Context) { configId := ctx.Param("configId") server := server.GetInstance(nil) err := server.TargetConfigService.Delete(ctx.Request.Context(), configId) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove target config: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete target config: %w", err)) return } diff --git a/pkg/api/controllers/workspace/remove.go b/pkg/api/controllers/workspace/delete.go similarity index 74% rename from pkg/api/controllers/workspace/remove.go rename to pkg/api/controllers/workspace/delete.go index 0c33d6804a..5fb1c9960c 100644 --- a/pkg/api/controllers/workspace/remove.go +++ b/pkg/api/controllers/workspace/delete.go @@ -13,18 +13,18 @@ import ( "github.com/gin-gonic/gin" ) -// RemoveWorkspace godoc +// DeleteWorkspace godoc // // @Tags workspace -// @Summary Remove workspace -// @Description Remove workspace +// @Summary Delete workspace +// @Description Delete workspace // @Param workspaceId path string true "Workspace ID" // @Param force query bool false "Force" // @Success 200 // @Router /workspace/{workspaceId} [delete] // -// @id RemoveWorkspace -func RemoveWorkspace(ctx *gin.Context) { +// @id DeleteWorkspace +func DeleteWorkspace(ctx *gin.Context) { workspaceId := ctx.Param("workspaceId") forceQuery := ctx.Query("force") var err error @@ -41,13 +41,13 @@ func RemoveWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) if force { - err = server.WorkspaceService.ForceRemoveWorkspace(ctx.Request.Context(), workspaceId) + err = server.WorkspaceService.ForceDeleteWorkspace(ctx.Request.Context(), workspaceId) } else { - err = server.WorkspaceService.RemoveWorkspace(ctx.Request.Context(), workspaceId) + err = server.WorkspaceService.DeleteWorkspace(ctx.Request.Context(), workspaceId) } if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to remove workspace: %w", err)) + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete workspace: %w", err)) return } diff --git a/pkg/api/controllers/workspace/metadata.go b/pkg/api/controllers/workspace/metadata.go index 8a375cee97..de2cca895b 100644 --- a/pkg/api/controllers/workspace/metadata.go +++ b/pkg/api/controllers/workspace/metadata.go @@ -13,18 +13,18 @@ import ( "github.com/gin-gonic/gin" ) -// SetWorkspaceMetadata godoc +// UpdateWorkspaceMetadata godoc // // @Tags workspace -// @Summary Set workspace metadata -// @Description Set workspace metadata +// @Summary Update workspace metadata +// @Description Update workspace metadata // @Param workspaceId path string true "Workspace ID" // @Param workspaceMetadata body UpdateWorkspaceMetadataDTO true "Workspace Metadata" // @Success 200 // @Router /workspace/{workspaceId}/metadata [post] // -// @id SetWorkspaceMetadata -func SetWorkspaceMetadata(ctx *gin.Context) { +// @id UpdateWorkspaceMetadata +func UpdateWorkspaceMetadata(ctx *gin.Context) { workspaceId := ctx.Param("workspaceId") var updateDTO dto.UpdateWorkspaceMetadataDTO @@ -36,7 +36,7 @@ func SetWorkspaceMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.WorkspaceService.SetWorkspaceMetadata(ctx.Request.Context(), workspaceId, &models.WorkspaceMetadata{ + _, err = server.WorkspaceService.UpdateWorkspaceMetadata(ctx.Request.Context(), workspaceId, &models.WorkspaceMetadata{ Uptime: updateDTO.Uptime, GitStatus: updateDTO.GitStatus, }) diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index fa07f821dc..321240fe7e 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -48,7 +48,7 @@ func forwardRequestToToolbox(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + w, err := server.WorkspaceService.FindWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { if stores.IsWorkspaceNotFound(err) { ctx.AbortWithError(http.StatusNotFound, err) diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go index 62cb401d7c..c9066f2ba3 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/workspace/workspace.go @@ -15,22 +15,22 @@ import ( "github.com/gin-gonic/gin" ) -// GetWorkspace godoc +// FindWorkspace godoc // // @Tags workspace -// @Summary Get workspace info -// @Description Get workspace info +// @Summary Find workspace +// @Description Find workspace // @Produce json // @Param workspaceId path string true "Workspace ID or Name" // @Success 200 {object} WorkspaceDTO // @Router /workspace/{workspaceId} [get] // -// @id GetWorkspace -func GetWorkspace(ctx *gin.Context) { +// @id FindWorkspace +func FindWorkspace(ctx *gin.Context) { workspaceId := ctx.Param("workspaceId") server := server.GetInstance(nil) - w, err := server.WorkspaceService.GetWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + w, err := server.WorkspaceService.FindWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { diff --git a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go index 8e029442aa..0d52fae5df 100644 --- a/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go +++ b/pkg/api/controllers/workspacetemplate/prebuild/prebuild.go @@ -15,19 +15,19 @@ import ( "github.com/gin-gonic/gin" ) -// GetPrebuild godoc +// FindPrebuild godoc // // @Tags prebuild -// @Summary Get prebuild -// @Description Get prebuild +// @Summary Find prebuild +// @Description Find prebuild // @Accept json // @Param templateName path string true "Workspace template name" // @Param prebuildId path string true "Prebuild ID" // @Success 200 {object} PrebuildDTO // @Router /workspace-template/{templateName}/prebuild/{prebuildId} [get] // -// @id GetPrebuild -func GetPrebuild(ctx *gin.Context) { +// @id FindPrebuild +func FindPrebuild(ctx *gin.Context) { templateName := ctx.Param("templateName") prebuildId := ctx.Param("prebuildId") @@ -49,19 +49,19 @@ func GetPrebuild(ctx *gin.Context) { ctx.JSON(200, res) } -// SetPrebuild godoc +// SavePrebuild godoc // @Tags prebuild -// @Summary Set prebuild -// @Description Set prebuild +// @Summary Save prebuild +// @Description Save prebuild // @Accept json // @Param templateName path string true "Template name" // @Param prebuild body CreatePrebuildDTO true "Prebuild" // @Success 201 {string} prebuildId // @Router /workspace-template/{templateName}/prebuild [put] // -// @id SetPrebuild -func SetPrebuild(ctx *gin.Context) { +// @id SavePrebuild +func SavePrebuild(ctx *gin.Context) { templateName := ctx.Param("templateName") var dto services.CreatePrebuildDTO diff --git a/pkg/api/controllers/workspacetemplate/workspace_template.go b/pkg/api/controllers/workspacetemplate/workspace_template.go index 650846c6ac..4b9997048a 100644 --- a/pkg/api/controllers/workspacetemplate/workspace_template.go +++ b/pkg/api/controllers/workspacetemplate/workspace_template.go @@ -19,18 +19,18 @@ import ( log "github.com/sirupsen/logrus" ) -// GetWorkspaceTemplate godoc +// FindWorkspaceTemplate godoc // // @Tags workspace-template -// @Summary Get workspace template data -// @Description Get workspace template data +// @Summary Find a workspace template +// @Description Find a workspace template // @Accept json // @Param templateName path string true "Template name" // @Success 200 {object} WorkspaceTemplate // @Router /workspace-template/{templateName} [get] // -// @id GetWorkspaceTemplate -func GetWorkspaceTemplate(ctx *gin.Context) { +// @id FindWorkspaceTemplate +func FindWorkspaceTemplate(ctx *gin.Context) { templateName := ctx.Param("templateName") server := server.GetInstance(nil) @@ -49,8 +49,8 @@ func GetWorkspaceTemplate(ctx *gin.Context) { // GetDefaultWorkspaceTemplate godoc // // @Tags workspace-template -// @Summary Get workspace templates by git url -// @Description Get workspace templates by git url +// @Summary Get default workspace templates by git url +// @Description Get default workspace templates by git url // @Produce json // @Param gitUrl path string true "Git URL" // @Success 200 {object} WorkspaceTemplate @@ -68,7 +68,7 @@ func GetDefaultWorkspaceTemplate(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceTemplates, err := server.WorkspaceTemplateService.Find(ctx.Request.Context(), &stores.WorkspaceTemplateFilter{ + workspaceTemplate, err := server.WorkspaceTemplateService.Find(ctx.Request.Context(), &stores.WorkspaceTemplateFilter{ Url: &decodedURLParam, Default: util.Pointer(true), }) @@ -84,7 +84,7 @@ func GetDefaultWorkspaceTemplate(ctx *gin.Context) { return } - ctx.JSON(200, workspaceTemplates) + ctx.JSON(200, workspaceTemplate) } // ListWorkspaceTemplates godoc @@ -109,7 +109,7 @@ func ListWorkspaceTemplates(ctx *gin.Context) { ctx.JSON(200, workspaceTemplates) } -// SetWorkspaceTemplate godoc +// SaveWorkspaceTemplate godoc // // @Tags workspace-template // @Summary Set workspace template data @@ -119,8 +119,8 @@ func ListWorkspaceTemplates(ctx *gin.Context) { // @Success 201 // @Router /workspace-template [put] // -// @id SetWorkspaceTemplate -func SetWorkspaceTemplate(ctx *gin.Context) { +// @id SaveWorkspaceTemplate +func SaveWorkspaceTemplate(ctx *gin.Context) { var req services.CreateWorkspaceTemplateDTO err := ctx.BindJSON(&req) if err != nil { diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 570c9908e6..0d47f51b76 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -41,15 +41,15 @@ const docTemplate = `{ }, "/apikey/{apiKeyName}": { "post": { - "description": "Generate an API key", + "description": "Create an API key", "produces": [ "text/plain" ], "tags": [ "apiKey" ], - "summary": "Generate an API key", - "operationId": "GenerateApiKey", + "summary": "Create an API key", + "operationId": "CreateApiKey", "parameters": [ { "type": "string", @@ -69,12 +69,12 @@ const docTemplate = `{ } }, "delete": { - "description": "Revoke API key", + "description": "Delete API key", "tags": [ "apiKey" ], - "summary": "Revoke API key", - "operationId": "RevokeApiKey", + "summary": "Delete API key", + "operationId": "DeleteApiKey", "parameters": [ { "type": "string", @@ -231,15 +231,15 @@ const docTemplate = `{ }, "/build/{buildId}": { "get": { - "description": "Get build data", + "description": "Find build", "consumes": [ "application/json" ], "tags": [ "build" ], - "summary": "Get build data", - "operationId": "GetBuild", + "summary": "Find build", + "operationId": "FindBuild", "parameters": [ { "type": "string", @@ -289,15 +289,15 @@ const docTemplate = `{ }, "/container-registry/{server}": { "get": { - "description": "Get container registry", + "description": "Find container registry", "produces": [ "application/json" ], "tags": [ "container registry" ], - "summary": "Get container registry", - "operationId": "GetContainerRegistry", + "summary": "Find container registry", + "operationId": "FindContainerRegistry", "parameters": [ { "type": "string", @@ -347,15 +347,15 @@ const docTemplate = `{ } }, "put": { - "description": "Set environment variable", + "description": "Save environment variable", "consumes": [ "application/json" ], "tags": [ "envVar" ], - "summary": "Set environment variable", - "operationId": "SetEnvironmentVariable", + "summary": "Save environment variable", + "operationId": "SaveEnvironmentVariable", "parameters": [ { "description": "Environment Variable", @@ -422,15 +422,15 @@ const docTemplate = `{ } }, "put": { - "description": "Set Git provider", + "description": "Save Git provider", "produces": [ "application/json" ], "tags": [ "gitProvider" ], - "summary": "Set Git provider", - "operationId": "SetGitProvider", + "summary": "Save Git provider", + "operationId": "SaveGitProvider", "parameters": [ { "description": "Git provider", @@ -548,15 +548,15 @@ const docTemplate = `{ }, "/gitprovider/id-for-url/{url}": { "get": { - "description": "Get Git provider ID", + "description": "Find Git provider ID", "produces": [ "text/plain" ], "tags": [ "gitProvider" ], - "summary": "Get Git provider ID", - "operationId": "GetGitProviderIdForUrl", + "summary": "Find Git provider ID", + "operationId": "FindGitProviderIdForUrl", "parameters": [ { "type": "string", @@ -578,15 +578,15 @@ const docTemplate = `{ }, "/gitprovider/{gitProviderId}": { "get": { - "description": "Get Git provider", + "description": "Find Git provider", "produces": [ "text/plain" ], "tags": [ "gitProvider" ], - "summary": "Get Git provider", - "operationId": "GetGitProvider", + "summary": "Find Git provider", + "operationId": "FindGitProvider", "parameters": [ { "type": "string", @@ -606,15 +606,15 @@ const docTemplate = `{ } }, "delete": { - "description": "Remove Git provider", + "description": "Delete Git provider", "produces": [ "application/json" ], "tags": [ "gitProvider" ], - "summary": "Remove Git provider", - "operationId": "RemoveGitProvider", + "summary": "Delete Git provider", + "operationId": "DeleteGitProvider", "parameters": [ { "type": "string", @@ -979,23 +979,23 @@ const docTemplate = `{ } }, "post": { - "description": "Register a runner", + "description": "Create a runner", "produces": [ "application/json" ], "tags": [ "runner" ], - "summary": "Register a runner", - "operationId": "RegisterRunner", + "summary": "Create a runner", + "operationId": "CreateRunner", "parameters": [ { - "description": "Register runner", + "description": "Runner", "name": "runner", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/RegisterRunnerDTO" + "$ref": "#/definitions/CreateRunnerDTO" } } ], @@ -1003,7 +1003,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/RegisterRunnerResultDTO" + "$ref": "#/definitions/CreateRunnerResultDTO" } } } @@ -1043,15 +1043,15 @@ const docTemplate = `{ }, "/runner/{runnerId}": { "get": { - "description": "Get a runner", + "description": "Find a runner", "produces": [ "application/json" ], "tags": [ "runner" ], - "summary": "Get a runner", - "operationId": "GetRunner", + "summary": "Find a runner", + "operationId": "FindRunner", "parameters": [ { "type": "string", @@ -1071,12 +1071,12 @@ const docTemplate = `{ } }, "delete": { - "description": "Remove runner", + "description": "Delete runner", "tags": [ "runner" ], - "summary": "Remove runner", - "operationId": "RemoveRunner", + "summary": "Delete runner", + "operationId": "DeleteRunner", "parameters": [ { "type": "string", @@ -1171,12 +1171,12 @@ const docTemplate = `{ }, "/runner/{runnerId}/metadata": { "post": { - "description": "Set runner metadata", + "description": "Update runner metadata", "tags": [ "runner" ], - "summary": "Set runner metadata", - "operationId": "SetRunnerMetadata", + "summary": "Update runner metadata", + "operationId": "UpdateRunnerMetadata", "parameters": [ { "type": "string", @@ -1350,8 +1350,8 @@ const docTemplate = `{ } } }, - "post": { - "description": "Set the server configuration", + "put": { + "description": "Save the server configuration", "consumes": [ "application/json" ], @@ -1361,8 +1361,8 @@ const docTemplate = `{ "tags": [ "server" ], - "summary": "Set the server configuration", - "operationId": "SetConfig", + "summary": "Save the server configuration", + "operationId": "SaveConfig", "parameters": [ { "description": "Server configuration", @@ -1386,14 +1386,14 @@ const docTemplate = `{ }, "/server/logs": { "get": { - "description": "List server log files", + "description": "Get server log files", "produces": [ "application/json" ], "tags": [ "server" ], - "summary": "List server log files", + "summary": "Get server log files", "operationId": "GetServerLogFiles", "responses": { "200": { @@ -1410,15 +1410,15 @@ const docTemplate = `{ }, "/server/network-key": { "post": { - "description": "Generate a new authentication key", + "description": "Create a new authentication key", "produces": [ "application/json" ], "tags": [ "server" ], - "summary": "Generate a new authentication key", - "operationId": "GenerateNetworkKey", + "summary": "Create a new authentication key", + "operationId": "CreateNetworkKey", "responses": { "200": { "description": "OK", @@ -1522,21 +1522,21 @@ const docTemplate = `{ } } }, - "put": { - "description": "Add a target config", + "post": { + "description": "Create a target config", "tags": [ "target-config" ], - "summary": "Add a target config", - "operationId": "AddTargetConfig", + "summary": "Create a target config", + "operationId": "CreateTargetConfig", "parameters": [ { - "description": "Target config to add", + "description": "Target config to create", "name": "targetConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/AddTargetConfigDTO" + "$ref": "#/definitions/CreateTargetConfigDTO" } }, { @@ -1558,12 +1558,12 @@ const docTemplate = `{ }, "/target-config/{configId}": { "delete": { - "description": "Remove a target config", + "description": "Delete a target config", "tags": [ "target-config" ], - "summary": "Remove a target config", - "operationId": "RemoveTargetConfig", + "summary": "Delete a target config", + "operationId": "DeleteTargetConfig", "parameters": [ { "type": "string", @@ -1582,15 +1582,15 @@ const docTemplate = `{ }, "/target/{targetId}": { "get": { - "description": "Get target info", + "description": "Find target", "produces": [ "application/json" ], "tags": [ "target" ], - "summary": "Get target info", - "operationId": "GetTarget", + "summary": "Find target", + "operationId": "FindTarget", "parameters": [ { "type": "string", @@ -1616,12 +1616,12 @@ const docTemplate = `{ } }, "delete": { - "description": "Remove target", + "description": "Delete target", "tags": [ "target" ], - "summary": "Remove target", - "operationId": "RemoveTarget", + "summary": "Delete target", + "operationId": "DeleteTarget", "parameters": [ { "type": "string", @@ -1670,12 +1670,12 @@ const docTemplate = `{ }, "/target/{targetId}/metadata": { "post": { - "description": "Set target metadata", + "description": "Update target metadata", "tags": [ "target" ], - "summary": "Set target metadata", - "operationId": "SetTargetMetadata", + "summary": "Update target metadata", + "operationId": "UpdateTargetMetadata", "parameters": [ { "type": "string", @@ -1892,7 +1892,7 @@ const docTemplate = `{ "workspace-template" ], "summary": "Set workspace template data", - "operationId": "SetWorkspaceTemplate", + "operationId": "SaveWorkspaceTemplate", "parameters": [ { "description": "Workspace template", @@ -1913,14 +1913,14 @@ const docTemplate = `{ }, "/workspace-template/default/{gitUrl}": { "get": { - "description": "Get workspace templates by git url", + "description": "Get default workspace templates by git url", "produces": [ "application/json" ], "tags": [ "workspace-template" ], - "summary": "Get workspace templates by git url", + "summary": "Get default workspace templates by git url", "operationId": "GetDefaultWorkspaceTemplate", "parameters": [ { @@ -1993,15 +1993,15 @@ const docTemplate = `{ }, "/workspace-template/{templateName}": { "get": { - "description": "Get workspace template data", + "description": "Find a workspace template", "consumes": [ "application/json" ], "tags": [ "workspace-template" ], - "summary": "Get workspace template data", - "operationId": "GetWorkspaceTemplate", + "summary": "Find a workspace template", + "operationId": "FindWorkspaceTemplate", "parameters": [ { "type": "string", @@ -2082,15 +2082,15 @@ const docTemplate = `{ } }, "put": { - "description": "Set prebuild", + "description": "Save prebuild", "consumes": [ "application/json" ], "tags": [ "prebuild" ], - "summary": "Set prebuild", - "operationId": "SetPrebuild", + "summary": "Save prebuild", + "operationId": "SavePrebuild", "parameters": [ { "type": "string", @@ -2121,15 +2121,15 @@ const docTemplate = `{ }, "/workspace-template/{templateName}/prebuild/{prebuildId}": { "get": { - "description": "Get prebuild", + "description": "Find prebuild", "consumes": [ "application/json" ], "tags": [ "prebuild" ], - "summary": "Get prebuild", - "operationId": "GetPrebuild", + "summary": "Find prebuild", + "operationId": "FindPrebuild", "parameters": [ { "type": "string", @@ -2220,15 +2220,15 @@ const docTemplate = `{ }, "/workspace/{workspaceId}": { "get": { - "description": "Get workspace info", + "description": "Find workspace", "produces": [ "application/json" ], "tags": [ "workspace" ], - "summary": "Get workspace info", - "operationId": "GetWorkspace", + "summary": "Find workspace", + "operationId": "FindWorkspace", "parameters": [ { "type": "string", @@ -2248,12 +2248,12 @@ const docTemplate = `{ } }, "delete": { - "description": "Remove workspace", + "description": "Delete workspace", "tags": [ "workspace" ], - "summary": "Remove workspace", - "operationId": "RemoveWorkspace", + "summary": "Delete workspace", + "operationId": "DeleteWorkspace", "parameters": [ { "type": "string", @@ -2278,12 +2278,12 @@ const docTemplate = `{ }, "/workspace/{workspaceId}/metadata": { "post": { - "description": "Set workspace metadata", + "description": "Update workspace metadata", "tags": [ "workspace" ], - "summary": "Set workspace metadata", - "operationId": "SetWorkspaceMetadata", + "summary": "Update workspace metadata", + "operationId": "UpdateWorkspaceMetadata", "parameters": [ { "type": "string", @@ -3724,25 +3724,6 @@ const docTemplate = `{ } }, "definitions": { - "AddTargetConfigDTO": { - "type": "object", - "required": [ - "name", - "options", - "providerInfo" - ], - "properties": { - "name": { - "type": "string" - }, - "options": { - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/ProviderInfo" - } - } - }, "ApiKeyViewDTO": { "type": "object", "required": [ @@ -4014,6 +3995,43 @@ const docTemplate = `{ } } }, + "CreateRunnerDTO": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "CreateRunnerResultDTO": { + "type": "object", + "required": [ + "apiKey", + "id", + "name" + ], + "properties": { + "apiKey": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/RunnerMetadata" + }, + "name": { + "type": "string" + } + } + }, "CreateSessionRequest": { "type": "object", "required": [ @@ -4025,6 +4043,25 @@ const docTemplate = `{ } } }, + "CreateTargetConfigDTO": { + "type": "object", + "required": [ + "name", + "options", + "providerInfo" + ], + "properties": { + "name": { + "type": "string" + }, + "options": { + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/ProviderInfo" + } + } + }, "CreateTargetDTO": { "type": "object", "required": [ @@ -5028,43 +5065,6 @@ const docTemplate = `{ } } }, - "RegisterRunnerDTO": { - "type": "object", - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "RegisterRunnerResultDTO": { - "type": "object", - "required": [ - "apiKey", - "id", - "name" - ], - "properties": { - "apiKey": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/RunnerMetadata" - }, - "name": { - "type": "string" - } - } - }, "ReplaceRequest": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 3b75c7bdb0..5167742edb 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -38,15 +38,15 @@ }, "/apikey/{apiKeyName}": { "post": { - "description": "Generate an API key", + "description": "Create an API key", "produces": [ "text/plain" ], "tags": [ "apiKey" ], - "summary": "Generate an API key", - "operationId": "GenerateApiKey", + "summary": "Create an API key", + "operationId": "CreateApiKey", "parameters": [ { "type": "string", @@ -66,12 +66,12 @@ } }, "delete": { - "description": "Revoke API key", + "description": "Delete API key", "tags": [ "apiKey" ], - "summary": "Revoke API key", - "operationId": "RevokeApiKey", + "summary": "Delete API key", + "operationId": "DeleteApiKey", "parameters": [ { "type": "string", @@ -228,15 +228,15 @@ }, "/build/{buildId}": { "get": { - "description": "Get build data", + "description": "Find build", "consumes": [ "application/json" ], "tags": [ "build" ], - "summary": "Get build data", - "operationId": "GetBuild", + "summary": "Find build", + "operationId": "FindBuild", "parameters": [ { "type": "string", @@ -286,15 +286,15 @@ }, "/container-registry/{server}": { "get": { - "description": "Get container registry", + "description": "Find container registry", "produces": [ "application/json" ], "tags": [ "container registry" ], - "summary": "Get container registry", - "operationId": "GetContainerRegistry", + "summary": "Find container registry", + "operationId": "FindContainerRegistry", "parameters": [ { "type": "string", @@ -344,15 +344,15 @@ } }, "put": { - "description": "Set environment variable", + "description": "Save environment variable", "consumes": [ "application/json" ], "tags": [ "envVar" ], - "summary": "Set environment variable", - "operationId": "SetEnvironmentVariable", + "summary": "Save environment variable", + "operationId": "SaveEnvironmentVariable", "parameters": [ { "description": "Environment Variable", @@ -419,15 +419,15 @@ } }, "put": { - "description": "Set Git provider", + "description": "Save Git provider", "produces": [ "application/json" ], "tags": [ "gitProvider" ], - "summary": "Set Git provider", - "operationId": "SetGitProvider", + "summary": "Save Git provider", + "operationId": "SaveGitProvider", "parameters": [ { "description": "Git provider", @@ -545,15 +545,15 @@ }, "/gitprovider/id-for-url/{url}": { "get": { - "description": "Get Git provider ID", + "description": "Find Git provider ID", "produces": [ "text/plain" ], "tags": [ "gitProvider" ], - "summary": "Get Git provider ID", - "operationId": "GetGitProviderIdForUrl", + "summary": "Find Git provider ID", + "operationId": "FindGitProviderIdForUrl", "parameters": [ { "type": "string", @@ -575,15 +575,15 @@ }, "/gitprovider/{gitProviderId}": { "get": { - "description": "Get Git provider", + "description": "Find Git provider", "produces": [ "text/plain" ], "tags": [ "gitProvider" ], - "summary": "Get Git provider", - "operationId": "GetGitProvider", + "summary": "Find Git provider", + "operationId": "FindGitProvider", "parameters": [ { "type": "string", @@ -603,15 +603,15 @@ } }, "delete": { - "description": "Remove Git provider", + "description": "Delete Git provider", "produces": [ "application/json" ], "tags": [ "gitProvider" ], - "summary": "Remove Git provider", - "operationId": "RemoveGitProvider", + "summary": "Delete Git provider", + "operationId": "DeleteGitProvider", "parameters": [ { "type": "string", @@ -976,23 +976,23 @@ } }, "post": { - "description": "Register a runner", + "description": "Create a runner", "produces": [ "application/json" ], "tags": [ "runner" ], - "summary": "Register a runner", - "operationId": "RegisterRunner", + "summary": "Create a runner", + "operationId": "CreateRunner", "parameters": [ { - "description": "Register runner", + "description": "Runner", "name": "runner", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/RegisterRunnerDTO" + "$ref": "#/definitions/CreateRunnerDTO" } } ], @@ -1000,7 +1000,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/RegisterRunnerResultDTO" + "$ref": "#/definitions/CreateRunnerResultDTO" } } } @@ -1040,15 +1040,15 @@ }, "/runner/{runnerId}": { "get": { - "description": "Get a runner", + "description": "Find a runner", "produces": [ "application/json" ], "tags": [ "runner" ], - "summary": "Get a runner", - "operationId": "GetRunner", + "summary": "Find a runner", + "operationId": "FindRunner", "parameters": [ { "type": "string", @@ -1068,12 +1068,12 @@ } }, "delete": { - "description": "Remove runner", + "description": "Delete runner", "tags": [ "runner" ], - "summary": "Remove runner", - "operationId": "RemoveRunner", + "summary": "Delete runner", + "operationId": "DeleteRunner", "parameters": [ { "type": "string", @@ -1168,12 +1168,12 @@ }, "/runner/{runnerId}/metadata": { "post": { - "description": "Set runner metadata", + "description": "Update runner metadata", "tags": [ "runner" ], - "summary": "Set runner metadata", - "operationId": "SetRunnerMetadata", + "summary": "Update runner metadata", + "operationId": "UpdateRunnerMetadata", "parameters": [ { "type": "string", @@ -1347,8 +1347,8 @@ } } }, - "post": { - "description": "Set the server configuration", + "put": { + "description": "Save the server configuration", "consumes": [ "application/json" ], @@ -1358,8 +1358,8 @@ "tags": [ "server" ], - "summary": "Set the server configuration", - "operationId": "SetConfig", + "summary": "Save the server configuration", + "operationId": "SaveConfig", "parameters": [ { "description": "Server configuration", @@ -1383,14 +1383,14 @@ }, "/server/logs": { "get": { - "description": "List server log files", + "description": "Get server log files", "produces": [ "application/json" ], "tags": [ "server" ], - "summary": "List server log files", + "summary": "Get server log files", "operationId": "GetServerLogFiles", "responses": { "200": { @@ -1407,15 +1407,15 @@ }, "/server/network-key": { "post": { - "description": "Generate a new authentication key", + "description": "Create a new authentication key", "produces": [ "application/json" ], "tags": [ "server" ], - "summary": "Generate a new authentication key", - "operationId": "GenerateNetworkKey", + "summary": "Create a new authentication key", + "operationId": "CreateNetworkKey", "responses": { "200": { "description": "OK", @@ -1519,21 +1519,21 @@ } } }, - "put": { - "description": "Add a target config", + "post": { + "description": "Create a target config", "tags": [ "target-config" ], - "summary": "Add a target config", - "operationId": "AddTargetConfig", + "summary": "Create a target config", + "operationId": "CreateTargetConfig", "parameters": [ { - "description": "Target config to add", + "description": "Target config to create", "name": "targetConfig", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/AddTargetConfigDTO" + "$ref": "#/definitions/CreateTargetConfigDTO" } }, { @@ -1555,12 +1555,12 @@ }, "/target-config/{configId}": { "delete": { - "description": "Remove a target config", + "description": "Delete a target config", "tags": [ "target-config" ], - "summary": "Remove a target config", - "operationId": "RemoveTargetConfig", + "summary": "Delete a target config", + "operationId": "DeleteTargetConfig", "parameters": [ { "type": "string", @@ -1579,15 +1579,15 @@ }, "/target/{targetId}": { "get": { - "description": "Get target info", + "description": "Find target", "produces": [ "application/json" ], "tags": [ "target" ], - "summary": "Get target info", - "operationId": "GetTarget", + "summary": "Find target", + "operationId": "FindTarget", "parameters": [ { "type": "string", @@ -1613,12 +1613,12 @@ } }, "delete": { - "description": "Remove target", + "description": "Delete target", "tags": [ "target" ], - "summary": "Remove target", - "operationId": "RemoveTarget", + "summary": "Delete target", + "operationId": "DeleteTarget", "parameters": [ { "type": "string", @@ -1667,12 +1667,12 @@ }, "/target/{targetId}/metadata": { "post": { - "description": "Set target metadata", + "description": "Update target metadata", "tags": [ "target" ], - "summary": "Set target metadata", - "operationId": "SetTargetMetadata", + "summary": "Update target metadata", + "operationId": "UpdateTargetMetadata", "parameters": [ { "type": "string", @@ -1889,7 +1889,7 @@ "workspace-template" ], "summary": "Set workspace template data", - "operationId": "SetWorkspaceTemplate", + "operationId": "SaveWorkspaceTemplate", "parameters": [ { "description": "Workspace template", @@ -1910,14 +1910,14 @@ }, "/workspace-template/default/{gitUrl}": { "get": { - "description": "Get workspace templates by git url", + "description": "Get default workspace templates by git url", "produces": [ "application/json" ], "tags": [ "workspace-template" ], - "summary": "Get workspace templates by git url", + "summary": "Get default workspace templates by git url", "operationId": "GetDefaultWorkspaceTemplate", "parameters": [ { @@ -1990,15 +1990,15 @@ }, "/workspace-template/{templateName}": { "get": { - "description": "Get workspace template data", + "description": "Find a workspace template", "consumes": [ "application/json" ], "tags": [ "workspace-template" ], - "summary": "Get workspace template data", - "operationId": "GetWorkspaceTemplate", + "summary": "Find a workspace template", + "operationId": "FindWorkspaceTemplate", "parameters": [ { "type": "string", @@ -2079,15 +2079,15 @@ } }, "put": { - "description": "Set prebuild", + "description": "Save prebuild", "consumes": [ "application/json" ], "tags": [ "prebuild" ], - "summary": "Set prebuild", - "operationId": "SetPrebuild", + "summary": "Save prebuild", + "operationId": "SavePrebuild", "parameters": [ { "type": "string", @@ -2118,15 +2118,15 @@ }, "/workspace-template/{templateName}/prebuild/{prebuildId}": { "get": { - "description": "Get prebuild", + "description": "Find prebuild", "consumes": [ "application/json" ], "tags": [ "prebuild" ], - "summary": "Get prebuild", - "operationId": "GetPrebuild", + "summary": "Find prebuild", + "operationId": "FindPrebuild", "parameters": [ { "type": "string", @@ -2217,15 +2217,15 @@ }, "/workspace/{workspaceId}": { "get": { - "description": "Get workspace info", + "description": "Find workspace", "produces": [ "application/json" ], "tags": [ "workspace" ], - "summary": "Get workspace info", - "operationId": "GetWorkspace", + "summary": "Find workspace", + "operationId": "FindWorkspace", "parameters": [ { "type": "string", @@ -2245,12 +2245,12 @@ } }, "delete": { - "description": "Remove workspace", + "description": "Delete workspace", "tags": [ "workspace" ], - "summary": "Remove workspace", - "operationId": "RemoveWorkspace", + "summary": "Delete workspace", + "operationId": "DeleteWorkspace", "parameters": [ { "type": "string", @@ -2275,12 +2275,12 @@ }, "/workspace/{workspaceId}/metadata": { "post": { - "description": "Set workspace metadata", + "description": "Update workspace metadata", "tags": [ "workspace" ], - "summary": "Set workspace metadata", - "operationId": "SetWorkspaceMetadata", + "summary": "Update workspace metadata", + "operationId": "UpdateWorkspaceMetadata", "parameters": [ { "type": "string", @@ -3721,25 +3721,6 @@ } }, "definitions": { - "AddTargetConfigDTO": { - "type": "object", - "required": [ - "name", - "options", - "providerInfo" - ], - "properties": { - "name": { - "type": "string" - }, - "options": { - "type": "string" - }, - "providerInfo": { - "$ref": "#/definitions/ProviderInfo" - } - } - }, "ApiKeyViewDTO": { "type": "object", "required": [ @@ -4011,6 +3992,43 @@ } } }, + "CreateRunnerDTO": { + "type": "object", + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "CreateRunnerResultDTO": { + "type": "object", + "required": [ + "apiKey", + "id", + "name" + ], + "properties": { + "apiKey": { + "type": "string" + }, + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/RunnerMetadata" + }, + "name": { + "type": "string" + } + } + }, "CreateSessionRequest": { "type": "object", "required": [ @@ -4022,6 +4040,25 @@ } } }, + "CreateTargetConfigDTO": { + "type": "object", + "required": [ + "name", + "options", + "providerInfo" + ], + "properties": { + "name": { + "type": "string" + }, + "options": { + "type": "string" + }, + "providerInfo": { + "$ref": "#/definitions/ProviderInfo" + } + } + }, "CreateTargetDTO": { "type": "object", "required": [ @@ -5025,43 +5062,6 @@ } } }, - "RegisterRunnerDTO": { - "type": "object", - "required": [ - "id", - "name" - ], - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "RegisterRunnerResultDTO": { - "type": "object", - "required": [ - "apiKey", - "id", - "name" - ], - "properties": { - "apiKey": { - "type": "string" - }, - "id": { - "type": "string" - }, - "metadata": { - "$ref": "#/definitions/RunnerMetadata" - }, - "name": { - "type": "string" - } - } - }, "ReplaceRequest": { "type": "object", "required": [ diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index d1b5d4b79d..8926a08f4c 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -1,18 +1,5 @@ basePath: / definitions: - AddTargetConfigDTO: - properties: - name: - type: string - options: - type: string - providerInfo: - $ref: '#/definitions/ProviderInfo' - required: - - name - - options - - providerInfo - type: object ApiKeyViewDTO: properties: current: @@ -196,6 +183,31 @@ definitions: required: - retention type: object + CreateRunnerDTO: + properties: + id: + type: string + name: + type: string + required: + - id + - name + type: object + CreateRunnerResultDTO: + properties: + apiKey: + type: string + id: + type: string + metadata: + $ref: '#/definitions/RunnerMetadata' + name: + type: string + required: + - apiKey + - id + - name + type: object CreateSessionRequest: properties: sessionId: @@ -203,6 +215,19 @@ definitions: required: - sessionId type: object + CreateTargetConfigDTO: + properties: + name: + type: string + options: + type: string + providerInfo: + $ref: '#/definitions/ProviderInfo' + required: + - name + - options + - providerInfo + type: object CreateTargetDTO: properties: id: @@ -890,31 +915,6 @@ definitions: - targetConfigManifest - version type: object - RegisterRunnerDTO: - properties: - id: - type: string - name: - type: string - required: - - id - - name - type: object - RegisterRunnerResultDTO: - properties: - apiKey: - type: string - id: - type: string - metadata: - $ref: '#/definitions/RunnerMetadata' - name: - type: string - required: - - apiKey - - id - - name - type: object ReplaceRequest: properties: files: @@ -1623,8 +1623,8 @@ paths: - apiKey /apikey/{apiKeyName}: delete: - description: Revoke API key - operationId: RevokeApiKey + description: Delete API key + operationId: DeleteApiKey parameters: - description: API key name in: path @@ -1634,12 +1634,12 @@ paths: responses: "200": description: OK - summary: Revoke API key + summary: Delete API key tags: - apiKey post: - description: Generate an API key - operationId: GenerateApiKey + description: Create an API key + operationId: CreateApiKey parameters: - description: API key name in: path @@ -1653,7 +1653,7 @@ paths: description: OK schema: type: string - summary: Generate an API key + summary: Create an API key tags: - apiKey /build: @@ -1729,8 +1729,8 @@ paths: get: consumes: - application/json - description: Get build data - operationId: GetBuild + description: Find build + operationId: FindBuild parameters: - description: Build ID in: path @@ -1742,7 +1742,7 @@ paths: description: OK schema: $ref: '#/definitions/BuildDTO' - summary: Get build data + summary: Find build tags: - build /build/prebuild/{prebuildId}: @@ -1789,8 +1789,8 @@ paths: - build /container-registry/{server}: get: - description: Get container registry - operationId: GetContainerRegistry + description: Find container registry + operationId: FindContainerRegistry parameters: - description: Container registry server in: path @@ -1808,7 +1808,7 @@ paths: description: OK schema: $ref: '#/definitions/ContainerRegistry' - summary: Get container registry + summary: Find container registry tags: - container registry /env: @@ -1830,8 +1830,8 @@ paths: put: consumes: - application/json - description: Set environment variable - operationId: SetEnvironmentVariable + description: Save environment variable + operationId: SaveEnvironmentVariable parameters: - description: Environment Variable in: body @@ -1842,7 +1842,7 @@ paths: responses: "201": description: Created - summary: Set environment variable + summary: Save environment variable tags: - envVar /env/{key}: @@ -1878,8 +1878,8 @@ paths: tags: - gitProvider put: - description: Set Git provider - operationId: SetGitProvider + description: Save Git provider + operationId: SaveGitProvider parameters: - description: Git provider in: body @@ -1892,13 +1892,13 @@ paths: responses: "200": description: OK - summary: Set Git provider + summary: Save Git provider tags: - gitProvider /gitprovider/{gitProviderId}: delete: - description: Remove Git provider - operationId: RemoveGitProvider + description: Delete Git provider + operationId: DeleteGitProvider parameters: - description: Git provider in: path @@ -1910,12 +1910,12 @@ paths: responses: "200": description: OK - summary: Remove Git provider + summary: Delete Git provider tags: - gitProvider get: - description: Get Git provider - operationId: GetGitProvider + description: Find Git provider + operationId: FindGitProvider parameters: - description: ID in: path @@ -1929,7 +1929,7 @@ paths: description: OK schema: $ref: '#/definitions/GitProvider' - summary: Get Git provider + summary: Find Git provider tags: - gitProvider /gitprovider/{gitProviderId}/{namespaceId}/{repositoryId}/branches: @@ -2163,8 +2163,8 @@ paths: - gitProvider /gitprovider/id-for-url/{url}: get: - description: Get Git provider ID - operationId: GetGitProviderIdForUrl + description: Find Git provider ID + operationId: FindGitProviderIdForUrl parameters: - description: Url in: path @@ -2178,7 +2178,7 @@ paths: description: OK schema: type: string - summary: Get Git provider ID + summary: Find Git provider ID tags: - gitProvider /health: @@ -2251,29 +2251,29 @@ paths: tags: - runner post: - description: Register a runner - operationId: RegisterRunner + description: Create a runner + operationId: CreateRunner parameters: - - description: Register runner + - description: Runner in: body name: runner required: true schema: - $ref: '#/definitions/RegisterRunnerDTO' + $ref: '#/definitions/CreateRunnerDTO' produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/RegisterRunnerResultDTO' - summary: Register a runner + $ref: '#/definitions/CreateRunnerResultDTO' + summary: Create a runner tags: - runner /runner/{runnerId}: delete: - description: Remove runner - operationId: RemoveRunner + description: Delete runner + operationId: DeleteRunner parameters: - description: Runner ID in: path @@ -2283,12 +2283,12 @@ paths: responses: "200": description: OK - summary: Remove runner + summary: Delete runner tags: - runner get: - description: Get a runner - operationId: GetRunner + description: Find a runner + operationId: FindRunner parameters: - description: Runner ID in: path @@ -2302,7 +2302,7 @@ paths: description: OK schema: $ref: '#/definitions/RunnerDTO' - summary: Get a runner + summary: Find a runner tags: - runner /runner/{runnerId}/jobs: @@ -2358,8 +2358,8 @@ paths: - runner /runner/{runnerId}/metadata: post: - description: Set runner metadata - operationId: SetRunnerMetadata + description: Update runner metadata + operationId: UpdateRunnerMetadata parameters: - description: Runner ID in: path @@ -2375,7 +2375,7 @@ paths: responses: "200": description: OK - summary: Set runner metadata + summary: Update runner metadata tags: - runner /runner/{runnerId}/provider/{providerName}/uninstall: @@ -2499,11 +2499,11 @@ paths: summary: Get the server configuration tags: - server - post: + put: consumes: - application/json - description: Set the server configuration - operationId: SetConfig + description: Save the server configuration + operationId: SaveConfig parameters: - description: Server configuration in: body @@ -2518,12 +2518,12 @@ paths: description: OK schema: $ref: '#/definitions/ServerConfig' - summary: Set the server configuration + summary: Save the server configuration tags: - server /server/logs: get: - description: List server log files + description: Get server log files operationId: GetServerLogFiles produces: - application/json @@ -2534,13 +2534,13 @@ paths: items: type: string type: array - summary: List server log files + summary: Get server log files tags: - server /server/network-key: post: - description: Generate a new authentication key - operationId: GenerateNetworkKey + description: Create a new authentication key + operationId: CreateNetworkKey produces: - application/json responses: @@ -2548,7 +2548,7 @@ paths: description: OK schema: $ref: '#/definitions/NetworkKey' - summary: Generate a new authentication key + summary: Create a new authentication key tags: - server /target: @@ -2613,16 +2613,16 @@ paths: summary: List target configs tags: - target-config - put: - description: Add a target config - operationId: AddTargetConfig + post: + description: Create a target config + operationId: CreateTargetConfig parameters: - - description: Target config to add + - description: Target config to create in: body name: targetConfig required: true schema: - $ref: '#/definitions/AddTargetConfigDTO' + $ref: '#/definitions/CreateTargetConfigDTO' - description: Show target config options in: query name: showOptions @@ -2632,13 +2632,13 @@ paths: description: OK schema: $ref: '#/definitions/TargetConfig' - summary: Add a target config + summary: Create a target config tags: - target-config /target-config/{configId}: delete: - description: Remove a target config - operationId: RemoveTargetConfig + description: Delete a target config + operationId: DeleteTargetConfig parameters: - description: Target Config Id in: path @@ -2648,13 +2648,13 @@ paths: responses: "204": description: No Content - summary: Remove a target config + summary: Delete a target config tags: - target-config /target/{targetId}: delete: - description: Remove target - operationId: RemoveTarget + description: Delete target + operationId: DeleteTarget parameters: - description: Target ID in: path @@ -2668,12 +2668,12 @@ paths: responses: "200": description: OK - summary: Remove target + summary: Delete target tags: - target get: - description: Get target info - operationId: GetTarget + description: Find target + operationId: FindTarget parameters: - description: Target ID or Name in: path @@ -2691,7 +2691,7 @@ paths: description: OK schema: $ref: '#/definitions/TargetDTO' - summary: Get target info + summary: Find target tags: - target /target/{targetId}/handle-successful-creation: @@ -2712,8 +2712,8 @@ paths: - target /target/{targetId}/metadata: post: - description: Set target metadata - operationId: SetTargetMetadata + description: Update target metadata + operationId: UpdateTargetMetadata parameters: - description: Target ID in: path @@ -2729,7 +2729,7 @@ paths: responses: "200": description: OK - summary: Set target metadata + summary: Update target metadata tags: - target /target/{targetId}/provider-metadata: @@ -2858,7 +2858,7 @@ paths: consumes: - application/json description: Set workspace template data - operationId: SetWorkspaceTemplate + operationId: SaveWorkspaceTemplate parameters: - description: Workspace template in: body @@ -2895,8 +2895,8 @@ paths: get: consumes: - application/json - description: Get workspace template data - operationId: GetWorkspaceTemplate + description: Find a workspace template + operationId: FindWorkspaceTemplate parameters: - description: Template name in: path @@ -2908,7 +2908,7 @@ paths: description: OK schema: $ref: '#/definitions/WorkspaceTemplate' - summary: Get workspace template data + summary: Find a workspace template tags: - workspace-template /workspace-template/{templateName}/prebuild: @@ -2936,8 +2936,8 @@ paths: put: consumes: - application/json - description: Set prebuild - operationId: SetPrebuild + description: Save prebuild + operationId: SavePrebuild parameters: - description: Template name in: path @@ -2955,7 +2955,7 @@ paths: description: Created schema: type: string - summary: Set prebuild + summary: Save prebuild tags: - prebuild /workspace-template/{templateName}/prebuild/{prebuildId}: @@ -2988,8 +2988,8 @@ paths: get: consumes: - application/json - description: Get prebuild - operationId: GetPrebuild + description: Find prebuild + operationId: FindPrebuild parameters: - description: Workspace template name in: path @@ -3006,7 +3006,7 @@ paths: description: OK schema: $ref: '#/definitions/PrebuildDTO' - summary: Get prebuild + summary: Find prebuild tags: - prebuild /workspace-template/{templateName}/set-default: @@ -3027,7 +3027,7 @@ paths: - workspace-template /workspace-template/default/{gitUrl}: get: - description: Get workspace templates by git url + description: Get default workspace templates by git url operationId: GetDefaultWorkspaceTemplate parameters: - description: Git URL @@ -3042,7 +3042,7 @@ paths: description: OK schema: $ref: '#/definitions/WorkspaceTemplate' - summary: Get workspace templates by git url + summary: Get default workspace templates by git url tags: - workspace-template /workspace-template/prebuild: @@ -3080,8 +3080,8 @@ paths: - prebuild /workspace/{workspaceId}: delete: - description: Remove workspace - operationId: RemoveWorkspace + description: Delete workspace + operationId: DeleteWorkspace parameters: - description: Workspace ID in: path @@ -3095,12 +3095,12 @@ paths: responses: "200": description: OK - summary: Remove workspace + summary: Delete workspace tags: - workspace get: - description: Get workspace info - operationId: GetWorkspace + description: Find workspace + operationId: FindWorkspace parameters: - description: Workspace ID or Name in: path @@ -3114,13 +3114,13 @@ paths: description: OK schema: $ref: '#/definitions/WorkspaceDTO' - summary: Get workspace info + summary: Find workspace tags: - workspace /workspace/{workspaceId}/metadata: post: - description: Set workspace metadata - operationId: SetWorkspaceMetadata + description: Update workspace metadata + operationId: UpdateWorkspaceMetadata parameters: - description: Workspace ID in: path @@ -3136,7 +3136,7 @@ paths: responses: "200": description: OK - summary: Set workspace metadata + summary: Update workspace metadata tags: - workspace /workspace/{workspaceId}/provider-metadata: diff --git a/pkg/api/server.go b/pkg/api/server.go index c46e6cd459..752c78b326 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -131,8 +131,8 @@ func (a *ApiServer) Start() error { serverController := protected.Group("/server") { serverController.GET("/config", server.GetConfig) - serverController.POST("/config", server.SetConfig) - serverController.POST("/network-key", server.GenerateNetworkKey) + serverController.PUT("/config", server.SaveConfig) + serverController.POST("/network-key", server.CreateNetworkKey) serverController.GET("/logs", server.GetServerLogFiles) } @@ -144,7 +144,7 @@ func (a *ApiServer) Start() error { targetController := protected.Group("/target") { - targetController.GET("/:targetId", target.GetTarget) + targetController.GET("/:targetId", target.FindTarget) targetController.GET("", target.ListTargets) targetController.POST("", target.CreateTarget) targetController.POST("/:targetId/start", target.StartTarget) @@ -152,7 +152,7 @@ func (a *ApiServer) Start() error { targetController.PATCH("/:targetId/set-default", target.SetDefaultTarget) targetController.POST("/:targetId/handle-successful-creation", target.HandleSuccessfulCreation) targetController.POST("/:targetId/provider-metadata", target.UpdateTargetProviderMetadata) - targetController.DELETE("/:targetId", target.RemoveTarget) + targetController.DELETE("/:targetId", target.DeleteTarget) } workspaceController := protected.Group("/workspace") @@ -219,10 +219,11 @@ func (a *ApiServer) Start() error { } } - workspaceController.GET("/:workspaceId", workspace.GetWorkspace) + workspaceController.GET("/:workspaceId", workspace.FindWorkspace) workspaceController.GET("", workspace.ListWorkspaces) workspaceController.POST("", workspace.CreateWorkspace) - workspaceController.DELETE("/:workspaceId", workspace.RemoveWorkspace) + workspaceController.DELETE("/:workspaceId", workspace.DeleteWorkspace) + workspaceController.POST("/:workspaceId/start", workspace.StartWorkspace) workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) workspaceController.POST("/:workspaceId/provider-metadata", workspace.UpdateWorkspaceProviderMetadata) @@ -239,18 +240,18 @@ func (a *ApiServer) Start() error { workspaceTemplateNameGroup := workspaceTemplateController.Group(":templateName") { - workspaceTemplateNameGroup.PUT(prebuildRoutePath, prebuild.SetPrebuild) + workspaceTemplateNameGroup.PUT(prebuildRoutePath, prebuild.SavePrebuild) workspaceTemplateNameGroup.GET(prebuildRoutePath, prebuild.ListPrebuildsForWorkspaceTemplate) - workspaceTemplateNameGroup.GET(prebuildRoutePath+"/:prebuildId", prebuild.GetPrebuild) + workspaceTemplateNameGroup.GET(prebuildRoutePath+"/:prebuildId", prebuild.FindPrebuild) workspaceTemplateNameGroup.DELETE(prebuildRoutePath+"/:prebuildId", prebuild.DeletePrebuild) - workspaceTemplateNameGroup.GET("", workspacetemplate.GetWorkspaceTemplate) + workspaceTemplateNameGroup.GET("", workspacetemplate.FindWorkspaceTemplate) workspaceTemplateNameGroup.PATCH("/set-default", workspacetemplate.SetDefaultWorkspaceTemplate) workspaceTemplateNameGroup.DELETE("", workspacetemplate.DeleteWorkspaceTemplate) } workspaceTemplateController.GET("", workspacetemplate.ListWorkspaceTemplates) - workspaceTemplateController.PUT("", workspacetemplate.SetWorkspaceTemplate) + workspaceTemplateController.PUT("", workspacetemplate.SaveWorkspaceTemplate) workspaceTemplateController.GET("/default/:gitUrl", workspacetemplate.GetDefaultWorkspaceTemplate) } @@ -259,7 +260,7 @@ func (a *ApiServer) Start() error { buildController := protected.Group("/build") { buildController.POST("", build.CreateBuild) - buildController.GET("/:buildId", build.GetBuild) + buildController.GET("/:buildId", build.FindBuild) buildController.GET("", build.ListBuilds) buildController.GET("/successful/:repoUrl", build.ListSuccessfulBuilds) buildController.DELETE("", build.DeleteAllBuilds) @@ -270,19 +271,23 @@ func (a *ApiServer) Start() error { targetConfigController := protected.Group("/target-config") { targetConfigController.GET("", targetconfig.ListTargetConfigs) - targetConfigController.PUT("", targetconfig.AddTargetConfig) - targetConfigController.DELETE("/:configId", targetconfig.RemoveTargetConfig) + targetConfigController.POST("", targetconfig.CreateTargetConfig) + targetConfigController.DELETE("/:configId", targetconfig.DeleteTargetConfig) } logController := protected.Group("/log") { logController.GET("/server", log_controller.ReadServerLog) + logController.GET("/target/:targetId", log_controller.ReadTargetLog) logController.GET("/target/:targetId/write", log_controller.WriteTargetLog) + logController.GET("/workspace/:workspaceId", log_controller.ReadWorkspaceLog) logController.GET("/workspace/:workspaceId/write", log_controller.WriteWorkspaceLog) + logController.GET("/build/:buildId", log_controller.ReadBuildLog) logController.GET("/build/:buildId/write", log_controller.WriteBuildLog) + logController.GET("/runner/:runnerId", log_controller.ReadRunnerLog) logController.GET("/runner/:runnerId/write", log_controller.WriteRunnerLog) } @@ -290,8 +295,12 @@ func (a *ApiServer) Start() error { gitProviderController := protected.Group("/gitprovider") { gitProviderController.GET("", gitprovider.ListGitProviders) - gitProviderController.PUT("", gitprovider.SetGitProvider) - gitProviderController.DELETE("/:gitProviderId", gitprovider.RemoveGitProvider) + gitProviderController.PUT("", gitprovider.SaveGitProvider) + gitProviderController.DELETE("/:gitProviderId", gitprovider.DeleteGitProvider) + gitProviderController.GET("/for-url/:url", gitprovider.ListGitProvidersForUrl) + gitProviderController.GET("/id-for-url/:url", gitprovider.FindGitProviderIdForUrl) + gitProviderController.GET("/:gitProviderId", gitprovider.FindGitProvider) + gitProviderController.GET("/:gitProviderId/user", gitprovider.GetGitUser) gitProviderController.GET("/:gitProviderId/namespaces", gitprovider.GetNamespaces) gitProviderController.GET("/:gitProviderId/:namespaceId/repositories", gitprovider.GetRepositories) @@ -299,28 +308,25 @@ func (a *ApiServer) Start() error { gitProviderController.GET("/:gitProviderId/:namespaceId/:repositoryId/pull-requests", gitprovider.GetRepoPRs) gitProviderController.POST("/context", gitprovider.GetGitContext) gitProviderController.POST("/context/url", gitprovider.GetUrlFromRepository) - gitProviderController.GET("/for-url/:url", gitprovider.ListGitProvidersForUrl) - gitProviderController.GET("/id-for-url/:url", gitprovider.GetGitProviderIdForUrl) - gitProviderController.GET("/:gitProviderId", gitprovider.GetGitProvider) } apiKeyController := protected.Group("/apikey") { apiKeyController.GET("", apikey.ListClientApiKeys) - apiKeyController.POST("/:apiKeyName", apikey.GenerateApiKey) - apiKeyController.DELETE("/:apiKeyName", apikey.RevokeApiKey) + apiKeyController.POST("/:apiKeyName", apikey.CreateApiKey) + apiKeyController.DELETE("/:apiKeyName", apikey.DeleteApiKey) } envVarController := protected.Group("/env") { envVarController.GET("", env.ListEnvironmentVariables) - envVarController.PUT("", env.SetEnvironmentVariable) + envVarController.PUT("", env.SaveEnvironmentVariable) envVarController.DELETE("/:key", env.DeleteEnvironmentVariable) } containerRegistryController := protected.Group("/container-registry") { - containerRegistryController.GET("/:server", containerregistry.GetContainerRegistry) + containerRegistryController.GET("/:server", containerregistry.FindContainerRegistry) } jobController := protected.Group("/job") @@ -351,25 +357,25 @@ func (a *ApiServer) Start() error { runnerIdProviderGroup.POST("/:providerName/update", provider.UpdateProvider) } - runnerIdGroup.GET("", runner.GetRunner) - runnerIdGroup.DELETE("", runner.RemoveRunner) + runnerIdGroup.GET("", runner.FindRunner) + runnerIdGroup.DELETE("", runner.DeleteRunner) } runnerController.GET("", runner.ListRunners) - runnerController.POST("", runner.RegisterRunner) + runnerController.POST("", runner.CreateRunner) } workspaceGroup := protected.Group("/") workspaceGroup.Use(middlewares.WorkspaceAuthMiddleware()) { - workspaceGroup.POST(workspaceController.BasePath()+"/:workspaceId/metadata", workspace.SetWorkspaceMetadata) - workspaceGroup.POST(targetController.BasePath()+"/:targetId/metadata", target.SetTargetMetadata) + workspaceGroup.POST(workspaceController.BasePath()+"/:workspaceId/metadata", workspace.UpdateWorkspaceMetadata) + workspaceGroup.POST(targetController.BasePath()+"/:targetId/metadata", target.UpdateTargetMetadata) } runnerGroup := protected.Group("/") runnerGroup.Use(middlewares.RunnerAuthMiddleware()) { - runnerGroup.POST(runnerController.BasePath()+"/:runnerId/metadata", runner.SetRunnerMetadata) + runnerGroup.POST(runnerController.BasePath()+"/:runnerId/metadata", runner.UpdateRunnerMetadata) runnerGroup.GET(runnerController.BasePath()+"/:runnerId/jobs", runner.ListRunnerJobs) runnerGroup.POST(runnerController.BasePath()+"/:runnerId/jobs/:jobId/state", runner.UpdateJobState) } diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 2b8cb63398..fd212ea73b 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -77,24 +77,25 @@ All URIs are relative to *http://localhost:3986* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*ApiKeyAPI* | [**GenerateApiKey**](docs/ApiKeyAPI.md#generateapikey) | **Post** /apikey/{apiKeyName} | Generate an API key +*ApiKeyAPI* | [**CreateApiKey**](docs/ApiKeyAPI.md#createapikey) | **Post** /apikey/{apiKeyName} | Create an API key +*ApiKeyAPI* | [**DeleteApiKey**](docs/ApiKeyAPI.md#deleteapikey) | **Delete** /apikey/{apiKeyName} | Delete API key *ApiKeyAPI* | [**ListClientApiKeys**](docs/ApiKeyAPI.md#listclientapikeys) | **Get** /apikey | List API keys -*ApiKeyAPI* | [**RevokeApiKey**](docs/ApiKeyAPI.md#revokeapikey) | **Delete** /apikey/{apiKeyName} | Revoke API key *BuildAPI* | [**CreateBuild**](docs/BuildAPI.md#createbuild) | **Post** /build | Create a build *BuildAPI* | [**DeleteAllBuilds**](docs/BuildAPI.md#deleteallbuilds) | **Delete** /build | Delete ALL builds *BuildAPI* | [**DeleteBuild**](docs/BuildAPI.md#deletebuild) | **Delete** /build/{buildId} | Delete build *BuildAPI* | [**DeleteBuildsFromPrebuild**](docs/BuildAPI.md#deletebuildsfromprebuild) | **Delete** /build/prebuild/{prebuildId} | Delete builds -*BuildAPI* | [**GetBuild**](docs/BuildAPI.md#getbuild) | **Get** /build/{buildId} | Get build data +*BuildAPI* | [**FindBuild**](docs/BuildAPI.md#findbuild) | **Get** /build/{buildId} | Find build *BuildAPI* | [**ListBuilds**](docs/BuildAPI.md#listbuilds) | **Get** /build | List builds *BuildAPI* | [**ListSuccessfulBuilds**](docs/BuildAPI.md#listsuccessfulbuilds) | **Get** /build/successful/{repoUrl} | List successful builds for Git repository -*ContainerRegistryAPI* | [**GetContainerRegistry**](docs/ContainerRegistryAPI.md#getcontainerregistry) | **Get** /container-registry/{server} | Get container registry +*ContainerRegistryAPI* | [**FindContainerRegistry**](docs/ContainerRegistryAPI.md#findcontainerregistry) | **Get** /container-registry/{server} | Find container registry *DefaultAPI* | [**HealthCheck**](docs/DefaultAPI.md#healthcheck) | **Get** /health | Health check *EnvVarAPI* | [**DeleteEnvironmentVariable**](docs/EnvVarAPI.md#deleteenvironmentvariable) | **Delete** /env/{key} | Delete environment variable *EnvVarAPI* | [**ListEnvironmentVariables**](docs/EnvVarAPI.md#listenvironmentvariables) | **Get** /env | List environment variables -*EnvVarAPI* | [**SetEnvironmentVariable**](docs/EnvVarAPI.md#setenvironmentvariable) | **Put** /env | Set environment variable +*EnvVarAPI* | [**SaveEnvironmentVariable**](docs/EnvVarAPI.md#saveenvironmentvariable) | **Put** /env | Save environment variable +*GitProviderAPI* | [**DeleteGitProvider**](docs/GitProviderAPI.md#deletegitprovider) | **Delete** /gitprovider/{gitProviderId} | Delete Git provider +*GitProviderAPI* | [**FindGitProvider**](docs/GitProviderAPI.md#findgitprovider) | **Get** /gitprovider/{gitProviderId} | Find Git provider +*GitProviderAPI* | [**FindGitProviderIdForUrl**](docs/GitProviderAPI.md#findgitprovideridforurl) | **Get** /gitprovider/id-for-url/{url} | Find Git provider ID *GitProviderAPI* | [**GetGitContext**](docs/GitProviderAPI.md#getgitcontext) | **Post** /gitprovider/context | Get Git context -*GitProviderAPI* | [**GetGitProvider**](docs/GitProviderAPI.md#getgitprovider) | **Get** /gitprovider/{gitProviderId} | Get Git provider -*GitProviderAPI* | [**GetGitProviderIdForUrl**](docs/GitProviderAPI.md#getgitprovideridforurl) | **Get** /gitprovider/id-for-url/{url} | Get Git provider ID *GitProviderAPI* | [**GetGitUser**](docs/GitProviderAPI.md#getgituser) | **Get** /gitprovider/{gitProviderId}/user | Get Git context *GitProviderAPI* | [**GetNamespaces**](docs/GitProviderAPI.md#getnamespaces) | **Get** /gitprovider/{gitProviderId}/namespaces | Get Git namespaces *GitProviderAPI* | [**GetRepoBranches**](docs/GitProviderAPI.md#getrepobranches) | **Get** /gitprovider/{gitProviderId}/{namespaceId}/{repositoryId}/branches | Get Git repository branches @@ -103,58 +104,57 @@ Class | Method | HTTP request | Description *GitProviderAPI* | [**GetUrlFromRepository**](docs/GitProviderAPI.md#geturlfromrepository) | **Post** /gitprovider/context/url | Get URL from Git repository *GitProviderAPI* | [**ListGitProviders**](docs/GitProviderAPI.md#listgitproviders) | **Get** /gitprovider | List Git providers *GitProviderAPI* | [**ListGitProvidersForUrl**](docs/GitProviderAPI.md#listgitprovidersforurl) | **Get** /gitprovider/for-url/{url} | List Git providers for url -*GitProviderAPI* | [**RemoveGitProvider**](docs/GitProviderAPI.md#removegitprovider) | **Delete** /gitprovider/{gitProviderId} | Remove Git provider -*GitProviderAPI* | [**SetGitProvider**](docs/GitProviderAPI.md#setgitprovider) | **Put** /gitprovider | Set Git provider +*GitProviderAPI* | [**SaveGitProvider**](docs/GitProviderAPI.md#savegitprovider) | **Put** /gitprovider | Save Git provider *JobAPI* | [**ListJobs**](docs/JobAPI.md#listjobs) | **Get** /job | List jobs *PrebuildAPI* | [**DeletePrebuild**](docs/PrebuildAPI.md#deleteprebuild) | **Delete** /workspace-template/{templateName}/prebuild/{prebuildId} | Delete prebuild -*PrebuildAPI* | [**GetPrebuild**](docs/PrebuildAPI.md#getprebuild) | **Get** /workspace-template/{templateName}/prebuild/{prebuildId} | Get prebuild +*PrebuildAPI* | [**FindPrebuild**](docs/PrebuildAPI.md#findprebuild) | **Get** /workspace-template/{templateName}/prebuild/{prebuildId} | Find prebuild *PrebuildAPI* | [**ListPrebuilds**](docs/PrebuildAPI.md#listprebuilds) | **Get** /workspace-template/prebuild | List prebuilds *PrebuildAPI* | [**ListPrebuildsForWorkspaceTemplate**](docs/PrebuildAPI.md#listprebuildsforworkspacetemplate) | **Get** /workspace-template/{templateName}/prebuild | List prebuilds for workspace template *PrebuildAPI* | [**ProcessGitEvent**](docs/PrebuildAPI.md#processgitevent) | **Post** /workspace-template/prebuild/process-git-event | ProcessGitEvent -*PrebuildAPI* | [**SetPrebuild**](docs/PrebuildAPI.md#setprebuild) | **Put** /workspace-template/{templateName}/prebuild | Set prebuild +*PrebuildAPI* | [**SavePrebuild**](docs/PrebuildAPI.md#saveprebuild) | **Put** /workspace-template/{templateName}/prebuild | Save prebuild *ProviderAPI* | [**InstallProvider**](docs/ProviderAPI.md#installprovider) | **Post** /runner/{runnerId}/provider/install | Install provider *ProviderAPI* | [**ListProviders**](docs/ProviderAPI.md#listproviders) | **Get** /runner/provider | List providers *ProviderAPI* | [**UninstallProvider**](docs/ProviderAPI.md#uninstallprovider) | **Post** /runner/{runnerId}/provider/{providerName}/uninstall | Uninstall provider *ProviderAPI* | [**UpdateProvider**](docs/ProviderAPI.md#updateprovider) | **Post** /runner/{runnerId}/provider/{providerName}/update | Update provider -*RunnerAPI* | [**GetRunner**](docs/RunnerAPI.md#getrunner) | **Get** /runner/{runnerId} | Get a runner +*RunnerAPI* | [**CreateRunner**](docs/RunnerAPI.md#createrunner) | **Post** /runner | Create a runner +*RunnerAPI* | [**DeleteRunner**](docs/RunnerAPI.md#deleterunner) | **Delete** /runner/{runnerId} | Delete runner +*RunnerAPI* | [**FindRunner**](docs/RunnerAPI.md#findrunner) | **Get** /runner/{runnerId} | Find a runner *RunnerAPI* | [**ListRunnerJobs**](docs/RunnerAPI.md#listrunnerjobs) | **Get** /runner/{runnerId}/jobs | List runner jobs *RunnerAPI* | [**ListRunners**](docs/RunnerAPI.md#listrunners) | **Get** /runner | List runners -*RunnerAPI* | [**RegisterRunner**](docs/RunnerAPI.md#registerrunner) | **Post** /runner | Register a runner -*RunnerAPI* | [**RemoveRunner**](docs/RunnerAPI.md#removerunner) | **Delete** /runner/{runnerId} | Remove runner -*RunnerAPI* | [**SetRunnerMetadata**](docs/RunnerAPI.md#setrunnermetadata) | **Post** /runner/{runnerId}/metadata | Set runner metadata *RunnerAPI* | [**UpdateJobState**](docs/RunnerAPI.md#updatejobstate) | **Post** /runner/{runnerId}/jobs/{jobId}/state | Update job state +*RunnerAPI* | [**UpdateRunnerMetadata**](docs/RunnerAPI.md#updaterunnermetadata) | **Post** /runner/{runnerId}/metadata | Update runner metadata *SampleAPI* | [**ListSamples**](docs/SampleAPI.md#listsamples) | **Get** /sample | List samples -*ServerAPI* | [**GenerateNetworkKey**](docs/ServerAPI.md#generatenetworkkey) | **Post** /server/network-key | Generate a new authentication key +*ServerAPI* | [**CreateNetworkKey**](docs/ServerAPI.md#createnetworkkey) | **Post** /server/network-key | Create a new authentication key *ServerAPI* | [**GetConfig**](docs/ServerAPI.md#getconfig) | **Get** /server/config | Get the server configuration -*ServerAPI* | [**GetServerLogFiles**](docs/ServerAPI.md#getserverlogfiles) | **Get** /server/logs | List server log files -*ServerAPI* | [**SetConfig**](docs/ServerAPI.md#setconfig) | **Post** /server/config | Set the server configuration +*ServerAPI* | [**GetServerLogFiles**](docs/ServerAPI.md#getserverlogfiles) | **Get** /server/logs | Get server log files +*ServerAPI* | [**SaveConfig**](docs/ServerAPI.md#saveconfig) | **Put** /server/config | Save the server configuration *TargetAPI* | [**CreateTarget**](docs/TargetAPI.md#createtarget) | **Post** /target | Create a target -*TargetAPI* | [**GetTarget**](docs/TargetAPI.md#gettarget) | **Get** /target/{targetId} | Get target info +*TargetAPI* | [**DeleteTarget**](docs/TargetAPI.md#deletetarget) | **Delete** /target/{targetId} | Delete target +*TargetAPI* | [**FindTarget**](docs/TargetAPI.md#findtarget) | **Get** /target/{targetId} | Find target *TargetAPI* | [**HandleSuccessfulCreation**](docs/TargetAPI.md#handlesuccessfulcreation) | **Post** /target/{targetId}/handle-successful-creation | Handles successful creation of the target *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets -*TargetAPI* | [**RemoveTarget**](docs/TargetAPI.md#removetarget) | **Delete** /target/{targetId} | Remove target *TargetAPI* | [**SetDefaultTarget**](docs/TargetAPI.md#setdefaulttarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default -*TargetAPI* | [**SetTargetMetadata**](docs/TargetAPI.md#settargetmetadata) | **Post** /target/{targetId}/metadata | Set target metadata *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target +*TargetAPI* | [**UpdateTargetMetadata**](docs/TargetAPI.md#updatetargetmetadata) | **Post** /target/{targetId}/metadata | Update target metadata *TargetAPI* | [**UpdateTargetProviderMetadata**](docs/TargetAPI.md#updatetargetprovidermetadata) | **Post** /target/{targetId}/provider-metadata | Update target provider metadata -*TargetConfigAPI* | [**AddTargetConfig**](docs/TargetConfigAPI.md#addtargetconfig) | **Put** /target-config | Add a target config +*TargetConfigAPI* | [**CreateTargetConfig**](docs/TargetConfigAPI.md#createtargetconfig) | **Post** /target-config | Create a target config +*TargetConfigAPI* | [**DeleteTargetConfig**](docs/TargetConfigAPI.md#deletetargetconfig) | **Delete** /target-config/{configId} | Delete a target config *TargetConfigAPI* | [**ListTargetConfigs**](docs/TargetConfigAPI.md#listtargetconfigs) | **Get** /target-config | List target configs -*TargetConfigAPI* | [**RemoveTargetConfig**](docs/TargetConfigAPI.md#removetargetconfig) | **Delete** /target-config/{configId} | Remove a target config *WorkspaceAPI* | [**CreateWorkspace**](docs/WorkspaceAPI.md#createworkspace) | **Post** /workspace | Create a workspace -*WorkspaceAPI* | [**GetWorkspace**](docs/WorkspaceAPI.md#getworkspace) | **Get** /workspace/{workspaceId} | Get workspace info +*WorkspaceAPI* | [**DeleteWorkspace**](docs/WorkspaceAPI.md#deleteworkspace) | **Delete** /workspace/{workspaceId} | Delete workspace +*WorkspaceAPI* | [**FindWorkspace**](docs/WorkspaceAPI.md#findworkspace) | **Get** /workspace/{workspaceId} | Find workspace *WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces -*WorkspaceAPI* | [**RemoveWorkspace**](docs/WorkspaceAPI.md#removeworkspace) | **Delete** /workspace/{workspaceId} | Remove workspace -*WorkspaceAPI* | [**SetWorkspaceMetadata**](docs/WorkspaceAPI.md#setworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata *WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace *WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +*WorkspaceAPI* | [**UpdateWorkspaceMetadata**](docs/WorkspaceAPI.md#updateworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Update workspace metadata *WorkspaceAPI* | [**UpdateWorkspaceProviderMetadata**](docs/WorkspaceAPI.md#updateworkspaceprovidermetadata) | **Post** /workspace/{workspaceId}/provider-metadata | Update workspace provider metadata *WorkspaceTemplateAPI* | [**DeleteWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#deleteworkspacetemplate) | **Delete** /workspace-template/{templateName} | Delete workspace template data -*WorkspaceTemplateAPI* | [**GetDefaultWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getdefaultworkspacetemplate) | **Get** /workspace-template/default/{gitUrl} | Get workspace templates by git url -*WorkspaceTemplateAPI* | [**GetWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getworkspacetemplate) | **Get** /workspace-template/{templateName} | Get workspace template data +*WorkspaceTemplateAPI* | [**FindWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#findworkspacetemplate) | **Get** /workspace-template/{templateName} | Find a workspace template +*WorkspaceTemplateAPI* | [**GetDefaultWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#getdefaultworkspacetemplate) | **Get** /workspace-template/default/{gitUrl} | Get default workspace templates by git url *WorkspaceTemplateAPI* | [**ListWorkspaceTemplates**](docs/WorkspaceTemplateAPI.md#listworkspacetemplates) | **Get** /workspace-template | List workspace templates +*WorkspaceTemplateAPI* | [**SaveWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#saveworkspacetemplate) | **Put** /workspace-template | Set workspace template data *WorkspaceTemplateAPI* | [**SetDefaultWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#setdefaultworkspacetemplate) | **Patch** /workspace-template/{templateName}/set-default | Set workspace template to default -*WorkspaceTemplateAPI* | [**SetWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#setworkspacetemplate) | **Put** /workspace-template | Set workspace template data *WorkspaceToolboxAPI* | [**CreateSession**](docs/WorkspaceToolboxAPI.md#createsession) | **Post** /workspace/{workspaceId}/toolbox/process/session | Create exec session *WorkspaceToolboxAPI* | [**DeleteSession**](docs/WorkspaceToolboxAPI.md#deletesession) | **Delete** /workspace/{workspaceId}/toolbox/process/session/{sessionId} | Delete session *WorkspaceToolboxAPI* | [**FsCreateFolder**](docs/WorkspaceToolboxAPI.md#fscreatefolder) | **Post** /workspace/{workspaceId}/toolbox/files/folder | Create folder @@ -193,7 +193,6 @@ Class | Method | HTTP request | Description ## Documentation For Models - - [AddTargetConfigDTO](docs/AddTargetConfigDTO.md) - [ApiKeyViewDTO](docs/ApiKeyViewDTO.md) - [BuildConfig](docs/BuildConfig.md) - [BuildDTO](docs/BuildDTO.md) @@ -207,7 +206,10 @@ Class | Method | HTTP request | Description - [ContainerRegistry](docs/ContainerRegistry.md) - [CreateBuildDTO](docs/CreateBuildDTO.md) - [CreatePrebuildDTO](docs/CreatePrebuildDTO.md) + - [CreateRunnerDTO](docs/CreateRunnerDTO.md) + - [CreateRunnerResultDTO](docs/CreateRunnerResultDTO.md) - [CreateSessionRequest](docs/CreateSessionRequest.md) + - [CreateTargetConfigDTO](docs/CreateTargetConfigDTO.md) - [CreateTargetDTO](docs/CreateTargetDTO.md) - [CreateWorkspaceDTO](docs/CreateWorkspaceDTO.md) - [CreateWorkspaceSourceDTO](docs/CreateWorkspaceSourceDTO.md) @@ -256,8 +258,6 @@ Class | Method | HTTP request | Description - [PrebuildConfig](docs/PrebuildConfig.md) - [PrebuildDTO](docs/PrebuildDTO.md) - [ProviderInfo](docs/ProviderInfo.md) - - [RegisterRunnerDTO](docs/RegisterRunnerDTO.md) - - [RegisterRunnerResultDTO](docs/RegisterRunnerResultDTO.md) - [ReplaceRequest](docs/ReplaceRequest.md) - [ReplaceResult](docs/ReplaceResult.md) - [RepositoryUrl](docs/RepositoryUrl.md) diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 93b2b1aad4..4ea15097ca 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -27,8 +27,8 @@ paths: - apiKey /apikey/{apiKeyName}: delete: - description: Revoke API key - operationId: RevokeApiKey + description: Delete API key + operationId: DeleteApiKey parameters: - description: API key name in: path @@ -40,12 +40,12 @@ paths: "200": content: {} description: OK - summary: Revoke API key + summary: Delete API key tags: - apiKey post: - description: Generate an API key - operationId: GenerateApiKey + description: Create an API key + operationId: CreateApiKey parameters: - description: API key name in: path @@ -60,7 +60,7 @@ paths: schema: type: string description: OK - summary: Generate an API key + summary: Create an API key tags: - apiKey /build: @@ -186,8 +186,8 @@ paths: tags: - build get: - description: Get build data - operationId: GetBuild + description: Find build + operationId: FindBuild parameters: - description: Build ID in: path @@ -202,13 +202,13 @@ paths: schema: $ref: '#/components/schemas/BuildDTO' description: OK - summary: Get build data + summary: Find build tags: - build /container-registry/{server}: get: - description: Get container registry - operationId: GetContainerRegistry + description: Find container registry + operationId: FindContainerRegistry parameters: - description: Container registry server in: path @@ -228,7 +228,7 @@ paths: schema: $ref: '#/components/schemas/ContainerRegistry' description: OK - summary: Get container registry + summary: Find container registry tags: - container registry /env: @@ -248,8 +248,8 @@ paths: tags: - envVar put: - description: Set environment variable - operationId: SetEnvironmentVariable + description: Save environment variable + operationId: SaveEnvironmentVariable requestBody: content: application/json: @@ -261,7 +261,7 @@ paths: "201": content: {} description: Created - summary: Set environment variable + summary: Save environment variable tags: - envVar x-codegen-request-body-name: environmentVariable @@ -300,8 +300,8 @@ paths: tags: - gitProvider put: - description: Set Git provider - operationId: SetGitProvider + description: Save Git provider + operationId: SaveGitProvider requestBody: content: '*/*': @@ -313,7 +313,7 @@ paths: "200": content: {} description: OK - summary: Set Git provider + summary: Save Git provider tags: - gitProvider x-codegen-request-body-name: gitProviderConfig @@ -386,8 +386,8 @@ paths: - gitProvider /gitprovider/id-for-url/{url}: get: - description: Get Git provider ID - operationId: GetGitProviderIdForUrl + description: Find Git provider ID + operationId: FindGitProviderIdForUrl parameters: - description: Url in: path @@ -402,13 +402,13 @@ paths: schema: type: string description: OK - summary: Get Git provider ID + summary: Find Git provider ID tags: - gitProvider /gitprovider/{gitProviderId}: delete: - description: Remove Git provider - operationId: RemoveGitProvider + description: Delete Git provider + operationId: DeleteGitProvider parameters: - description: Git provider in: path @@ -420,12 +420,12 @@ paths: "200": content: {} description: OK - summary: Remove Git provider + summary: Delete Git provider tags: - gitProvider get: - description: Get Git provider - operationId: GetGitProvider + description: Find Git provider + operationId: FindGitProvider parameters: - description: ID in: path @@ -440,7 +440,7 @@ paths: schema: $ref: '#/components/schemas/GitProvider' description: OK - summary: Get Git provider + summary: Find Git provider tags: - gitProvider /gitprovider/{gitProviderId}/namespaces: @@ -702,23 +702,23 @@ paths: tags: - runner post: - description: Register a runner - operationId: RegisterRunner + description: Create a runner + operationId: CreateRunner requestBody: content: '*/*': schema: - $ref: '#/components/schemas/RegisterRunnerDTO' - description: Register runner + $ref: '#/components/schemas/CreateRunnerDTO' + description: Runner required: true responses: "200": content: application/json: schema: - $ref: '#/components/schemas/RegisterRunnerResultDTO' + $ref: '#/components/schemas/CreateRunnerResultDTO' description: OK - summary: Register a runner + summary: Create a runner tags: - runner x-codegen-request-body-name: runner @@ -746,8 +746,8 @@ paths: - provider /runner/{runnerId}: delete: - description: Remove runner - operationId: RemoveRunner + description: Delete runner + operationId: DeleteRunner parameters: - description: Runner ID in: path @@ -759,12 +759,12 @@ paths: "200": content: {} description: OK - summary: Remove runner + summary: Delete runner tags: - runner get: - description: Get a runner - operationId: GetRunner + description: Find a runner + operationId: FindRunner parameters: - description: Runner ID in: path @@ -779,7 +779,7 @@ paths: schema: $ref: '#/components/schemas/RunnerDTO' description: OK - summary: Get a runner + summary: Find a runner tags: - runner /runner/{runnerId}/jobs: @@ -839,8 +839,8 @@ paths: x-codegen-request-body-name: updateJobState /runner/{runnerId}/metadata: post: - description: Set runner metadata - operationId: SetRunnerMetadata + description: Update runner metadata + operationId: UpdateRunnerMetadata parameters: - description: Runner ID in: path @@ -859,7 +859,7 @@ paths: "200": content: {} description: OK - summary: Set runner metadata + summary: Update runner metadata tags: - runner x-codegen-request-body-name: runnerMetadata @@ -975,9 +975,9 @@ paths: summary: Get the server configuration tags: - server - post: - description: Set the server configuration - operationId: SetConfig + put: + description: Save the server configuration + operationId: SaveConfig requestBody: content: application/json: @@ -992,13 +992,13 @@ paths: schema: $ref: '#/components/schemas/ServerConfig' description: OK - summary: Set the server configuration + summary: Save the server configuration tags: - server x-codegen-request-body-name: config /server/logs: get: - description: List server log files + description: Get server log files operationId: GetServerLogFiles responses: "200": @@ -1009,13 +1009,13 @@ paths: type: string type: array description: OK - summary: List server log files + summary: Get server log files tags: - server /server/network-key: post: - description: Generate a new authentication key - operationId: GenerateNetworkKey + description: Create a new authentication key + operationId: CreateNetworkKey responses: "200": content: @@ -1023,7 +1023,7 @@ paths: schema: $ref: '#/components/schemas/NetworkKey' description: OK - summary: Generate a new authentication key + summary: Create a new authentication key tags: - server /target: @@ -1091,9 +1091,9 @@ paths: summary: List target configs tags: - target-config - put: - description: Add a target config - operationId: AddTargetConfig + post: + description: Create a target config + operationId: CreateTargetConfig parameters: - description: Show target config options in: query @@ -1104,8 +1104,8 @@ paths: content: '*/*': schema: - $ref: '#/components/schemas/AddTargetConfigDTO' - description: Target config to add + $ref: '#/components/schemas/CreateTargetConfigDTO' + description: Target config to create required: true responses: "200": @@ -1114,14 +1114,14 @@ paths: schema: $ref: '#/components/schemas/TargetConfig' description: OK - summary: Add a target config + summary: Create a target config tags: - target-config x-codegen-request-body-name: targetConfig /target-config/{configId}: delete: - description: Remove a target config - operationId: RemoveTargetConfig + description: Delete a target config + operationId: DeleteTargetConfig parameters: - description: Target Config Id in: path @@ -1133,13 +1133,13 @@ paths: "204": content: {} description: No Content - summary: Remove a target config + summary: Delete a target config tags: - target-config /target/{targetId}: delete: - description: Remove target - operationId: RemoveTarget + description: Delete target + operationId: DeleteTarget parameters: - description: Target ID in: path @@ -1156,12 +1156,12 @@ paths: "200": content: {} description: OK - summary: Remove target + summary: Delete target tags: - target get: - description: Get target info - operationId: GetTarget + description: Find target + operationId: FindTarget parameters: - description: Target ID or Name in: path @@ -1181,7 +1181,7 @@ paths: schema: $ref: '#/components/schemas/TargetDTO' description: OK - summary: Get target info + summary: Find target tags: - target /target/{targetId}/handle-successful-creation: @@ -1204,8 +1204,8 @@ paths: - target /target/{targetId}/metadata: post: - description: Set target metadata - operationId: SetTargetMetadata + description: Update target metadata + operationId: UpdateTargetMetadata parameters: - description: Target ID in: path @@ -1224,7 +1224,7 @@ paths: "200": content: {} description: OK - summary: Set target metadata + summary: Update target metadata tags: - target x-codegen-request-body-name: targetMetadata @@ -1363,7 +1363,7 @@ paths: - workspace-template put: description: Set workspace template data - operationId: SetWorkspaceTemplate + operationId: SaveWorkspaceTemplate requestBody: content: application/json: @@ -1381,7 +1381,7 @@ paths: x-codegen-request-body-name: workspaceTemplate /workspace-template/default/{gitUrl}: get: - description: Get workspace templates by git url + description: Get default workspace templates by git url operationId: GetDefaultWorkspaceTemplate parameters: - description: Git URL @@ -1397,7 +1397,7 @@ paths: schema: $ref: '#/components/schemas/WorkspaceTemplate' description: OK - summary: Get workspace templates by git url + summary: Get default workspace templates by git url tags: - workspace-template /workspace-template/prebuild: @@ -1459,8 +1459,8 @@ paths: tags: - workspace-template get: - description: Get workspace template data - operationId: GetWorkspaceTemplate + description: Find a workspace template + operationId: FindWorkspaceTemplate parameters: - description: Template name in: path @@ -1475,7 +1475,7 @@ paths: schema: $ref: '#/components/schemas/WorkspaceTemplate' description: OK - summary: Get workspace template data + summary: Find a workspace template tags: - workspace-template /workspace-template/{templateName}/prebuild: @@ -1502,8 +1502,8 @@ paths: tags: - prebuild put: - description: Set prebuild - operationId: SetPrebuild + description: Save prebuild + operationId: SavePrebuild parameters: - description: Template name in: path @@ -1525,7 +1525,7 @@ paths: schema: type: string description: Created - summary: Set prebuild + summary: Save prebuild tags: - prebuild x-codegen-request-body-name: prebuild @@ -1559,8 +1559,8 @@ paths: tags: - prebuild get: - description: Get prebuild - operationId: GetPrebuild + description: Find prebuild + operationId: FindPrebuild parameters: - description: Workspace template name in: path @@ -1581,7 +1581,7 @@ paths: schema: $ref: '#/components/schemas/PrebuildDTO' description: OK - summary: Get prebuild + summary: Find prebuild tags: - prebuild /workspace-template/{templateName}/set-default: @@ -1604,8 +1604,8 @@ paths: - workspace-template /workspace/{workspaceId}: delete: - description: Remove workspace - operationId: RemoveWorkspace + description: Delete workspace + operationId: DeleteWorkspace parameters: - description: Workspace ID in: path @@ -1622,12 +1622,12 @@ paths: "200": content: {} description: OK - summary: Remove workspace + summary: Delete workspace tags: - workspace get: - description: Get workspace info - operationId: GetWorkspace + description: Find workspace + operationId: FindWorkspace parameters: - description: Workspace ID or Name in: path @@ -1642,13 +1642,13 @@ paths: schema: $ref: '#/components/schemas/WorkspaceDTO' description: OK - summary: Get workspace info + summary: Find workspace tags: - workspace /workspace/{workspaceId}/metadata: post: - description: Set workspace metadata - operationId: SetWorkspaceMetadata + description: Update workspace metadata + operationId: UpdateWorkspaceMetadata parameters: - description: Workspace ID in: path @@ -1667,7 +1667,7 @@ paths: "200": content: {} description: OK - summary: Set workspace metadata + summary: Update workspace metadata tags: - workspace x-codegen-request-body-name: workspaceMetadata @@ -2721,42 +2721,6 @@ paths: - workspace toolbox components: schemas: - AddTargetConfigDTO: - example: - name: name - options: options - providerInfo: - runnerName: runnerName - targetConfigManifest: - key: - defaultValue: defaultValue - options: - - options - - options - description: description - suggestions: - - suggestions - - suggestions - type: null - disabledPredicate: disabledPredicate - inputMasked: true - agentlessTarget: true - name: name - runnerId: runnerId - label: label - version: version - properties: - name: - type: string - options: - type: string - providerInfo: - $ref: '#/components/schemas/ProviderInfo' - required: - - name - - options - - providerInfo - type: object ApiKeyViewDTO: example: current: true @@ -3051,6 +3015,82 @@ components: required: - retention type: object + CreateRunnerDTO: + example: + name: name + id: id + properties: + id: + type: string + name: + type: string + required: + - id + - name + type: object + CreateRunnerResultDTO: + example: + metadata: + runningJobs: 0 + runnerId: runnerId + providers: + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + - runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + updatedAt: updatedAt + uptime: 6 + apiKey: apiKey + name: name + id: id + properties: + apiKey: + type: string + id: + type: string + metadata: + $ref: '#/components/schemas/RunnerMetadata' + name: + type: string + required: + - apiKey + - id + - name + type: object CreateSessionRequest: example: sessionId: sessionId @@ -3060,6 +3100,42 @@ components: required: - sessionId type: object + CreateTargetConfigDTO: + example: + name: name + options: options + providerInfo: + runnerName: runnerName + targetConfigManifest: + key: + defaultValue: defaultValue + options: + - options + - options + description: description + suggestions: + - suggestions + - suggestions + type: null + disabledPredicate: disabledPredicate + inputMasked: true + agentlessTarget: true + name: name + runnerId: runnerId + label: label + version: version + properties: + name: + type: string + options: + type: string + providerInfo: + $ref: '#/components/schemas/ProviderInfo' + required: + - name + - options + - providerInfo + type: object CreateTargetDTO: example: name: name @@ -4053,82 +4129,6 @@ components: - targetConfigManifest - version type: object - RegisterRunnerDTO: - example: - name: name - id: id - properties: - id: - type: string - name: - type: string - required: - - id - - name - type: object - RegisterRunnerResultDTO: - example: - metadata: - runningJobs: 0 - runnerId: runnerId - providers: - - runnerName: runnerName - targetConfigManifest: - key: - defaultValue: defaultValue - options: - - options - - options - description: description - suggestions: - - suggestions - - suggestions - type: null - disabledPredicate: disabledPredicate - inputMasked: true - agentlessTarget: true - name: name - runnerId: runnerId - label: label - version: version - - runnerName: runnerName - targetConfigManifest: - key: - defaultValue: defaultValue - options: - - options - - options - description: description - suggestions: - - suggestions - - suggestions - type: null - disabledPredicate: disabledPredicate - inputMasked: true - agentlessTarget: true - name: name - runnerId: runnerId - label: label - version: version - updatedAt: updatedAt - uptime: 6 - apiKey: apiKey - name: name - id: id - properties: - apiKey: - type: string - id: - type: string - metadata: - $ref: '#/components/schemas/RunnerMetadata' - name: - type: string - required: - - apiKey - - id - - name - type: object ReplaceRequest: example: newValue: newValue diff --git a/pkg/apiclient/api_api_key.go b/pkg/apiclient/api_api_key.go index 535d8219c5..de551cb9a9 100644 --- a/pkg/apiclient/api_api_key.go +++ b/pkg/apiclient/api_api_key.go @@ -22,27 +22,27 @@ import ( // ApiKeyAPIService ApiKeyAPI service type ApiKeyAPIService service -type ApiGenerateApiKeyRequest struct { +type ApiCreateApiKeyRequest struct { ctx context.Context ApiService *ApiKeyAPIService apiKeyName string } -func (r ApiGenerateApiKeyRequest) Execute() (string, *http.Response, error) { - return r.ApiService.GenerateApiKeyExecute(r) +func (r ApiCreateApiKeyRequest) Execute() (string, *http.Response, error) { + return r.ApiService.CreateApiKeyExecute(r) } /* -GenerateApiKey Generate an API key +CreateApiKey Create an API key -Generate an API key +Create an API key @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param apiKeyName API key name - @return ApiGenerateApiKeyRequest + @return ApiCreateApiKeyRequest */ -func (a *ApiKeyAPIService) GenerateApiKey(ctx context.Context, apiKeyName string) ApiGenerateApiKeyRequest { - return ApiGenerateApiKeyRequest{ +func (a *ApiKeyAPIService) CreateApiKey(ctx context.Context, apiKeyName string) ApiCreateApiKeyRequest { + return ApiCreateApiKeyRequest{ ApiService: a, ctx: ctx, apiKeyName: apiKeyName, @@ -52,7 +52,7 @@ func (a *ApiKeyAPIService) GenerateApiKey(ctx context.Context, apiKeyName string // Execute executes the request // // @return string -func (a *ApiKeyAPIService) GenerateApiKeyExecute(r ApiGenerateApiKeyRequest) (string, *http.Response, error) { +func (a *ApiKeyAPIService) CreateApiKeyExecute(r ApiCreateApiKeyRequest) (string, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} @@ -60,7 +60,7 @@ func (a *ApiKeyAPIService) GenerateApiKeyExecute(r ApiGenerateApiKeyRequest) (st localVarReturnValue string ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.GenerateApiKey") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.CreateApiKey") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -140,47 +140,48 @@ func (a *ApiKeyAPIService) GenerateApiKeyExecute(r ApiGenerateApiKeyRequest) (st return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListClientApiKeysRequest struct { +type ApiDeleteApiKeyRequest struct { ctx context.Context ApiService *ApiKeyAPIService + apiKeyName string } -func (r ApiListClientApiKeysRequest) Execute() ([]ApiKeyViewDTO, *http.Response, error) { - return r.ApiService.ListClientApiKeysExecute(r) +func (r ApiDeleteApiKeyRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteApiKeyExecute(r) } /* -ListClientApiKeys List API keys +DeleteApiKey Delete API key -List API keys +Delete API key @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListClientApiKeysRequest + @param apiKeyName API key name + @return ApiDeleteApiKeyRequest */ -func (a *ApiKeyAPIService) ListClientApiKeys(ctx context.Context) ApiListClientApiKeysRequest { - return ApiListClientApiKeysRequest{ +func (a *ApiKeyAPIService) DeleteApiKey(ctx context.Context, apiKeyName string) ApiDeleteApiKeyRequest { + return ApiDeleteApiKeyRequest{ ApiService: a, ctx: ctx, + apiKeyName: apiKeyName, } } // Execute executes the request -// -// @return []ApiKeyViewDTO -func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysRequest) ([]ApiKeyViewDTO, *http.Response, error) { +func (a *ApiKeyAPIService) DeleteApiKeyExecute(r ApiDeleteApiKeyRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue []ApiKeyViewDTO + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.ListClientApiKeys") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.DeleteApiKey") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/apikey" + localVarPath := localBasePath + "/apikey/{apiKeyName}" + localVarPath = strings.Replace(localVarPath, "{"+"apiKeyName"+"}", url.PathEscape(parameterValueToString(r.apiKeyName, "apiKeyName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -196,7 +197,7 @@ func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysReques } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -219,19 +220,19 @@ func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysReques } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -239,63 +240,53 @@ func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysReques body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } -type ApiRevokeApiKeyRequest struct { +type ApiListClientApiKeysRequest struct { ctx context.Context ApiService *ApiKeyAPIService - apiKeyName string } -func (r ApiRevokeApiKeyRequest) Execute() (*http.Response, error) { - return r.ApiService.RevokeApiKeyExecute(r) +func (r ApiListClientApiKeysRequest) Execute() ([]ApiKeyViewDTO, *http.Response, error) { + return r.ApiService.ListClientApiKeysExecute(r) } /* -RevokeApiKey Revoke API key +ListClientApiKeys List API keys -Revoke API key +List API keys @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param apiKeyName API key name - @return ApiRevokeApiKeyRequest + @return ApiListClientApiKeysRequest */ -func (a *ApiKeyAPIService) RevokeApiKey(ctx context.Context, apiKeyName string) ApiRevokeApiKeyRequest { - return ApiRevokeApiKeyRequest{ +func (a *ApiKeyAPIService) ListClientApiKeys(ctx context.Context) ApiListClientApiKeysRequest { + return ApiListClientApiKeysRequest{ ApiService: a, ctx: ctx, - apiKeyName: apiKeyName, } } // Execute executes the request -func (a *ApiKeyAPIService) RevokeApiKeyExecute(r ApiRevokeApiKeyRequest) (*http.Response, error) { +// +// @return []ApiKeyViewDTO +func (a *ApiKeyAPIService) ListClientApiKeysExecute(r ApiListClientApiKeysRequest) ([]ApiKeyViewDTO, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []ApiKeyViewDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.RevokeApiKey") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ApiKeyAPIService.ListClientApiKeys") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/apikey/{apiKeyName}" - localVarPath = strings.Replace(localVarPath, "{"+"apiKeyName"+"}", url.PathEscape(parameterValueToString(r.apiKeyName, "apiKeyName")), -1) + localVarPath := localBasePath + "/apikey" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -311,7 +302,7 @@ func (a *ApiKeyAPIService) RevokeApiKeyExecute(r ApiRevokeApiKeyRequest) (*http. } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -334,19 +325,19 @@ func (a *ApiKeyAPIService) RevokeApiKeyExecute(r ApiRevokeApiKeyRequest) (*http. } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -354,8 +345,17 @@ func (a *ApiKeyAPIService) RevokeApiKeyExecute(r ApiRevokeApiKeyRequest) (*http. body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil } diff --git a/pkg/apiclient/api_build.go b/pkg/apiclient/api_build.go index f454edf3a7..ed9229eec8 100644 --- a/pkg/apiclient/api_build.go +++ b/pkg/apiclient/api_build.go @@ -492,27 +492,27 @@ func (a *BuildAPIService) DeleteBuildsFromPrebuildExecute(r ApiDeleteBuildsFromP return localVarHTTPResponse, nil } -type ApiGetBuildRequest struct { +type ApiFindBuildRequest struct { ctx context.Context ApiService *BuildAPIService buildId string } -func (r ApiGetBuildRequest) Execute() (*BuildDTO, *http.Response, error) { - return r.ApiService.GetBuildExecute(r) +func (r ApiFindBuildRequest) Execute() (*BuildDTO, *http.Response, error) { + return r.ApiService.FindBuildExecute(r) } /* -GetBuild Get build data +FindBuild Find build -Get build data +Find build @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param buildId Build ID - @return ApiGetBuildRequest + @return ApiFindBuildRequest */ -func (a *BuildAPIService) GetBuild(ctx context.Context, buildId string) ApiGetBuildRequest { - return ApiGetBuildRequest{ +func (a *BuildAPIService) FindBuild(ctx context.Context, buildId string) ApiFindBuildRequest { + return ApiFindBuildRequest{ ApiService: a, ctx: ctx, buildId: buildId, @@ -522,7 +522,7 @@ func (a *BuildAPIService) GetBuild(ctx context.Context, buildId string) ApiGetBu // Execute executes the request // // @return BuildDTO -func (a *BuildAPIService) GetBuildExecute(r ApiGetBuildRequest) (*BuildDTO, *http.Response, error) { +func (a *BuildAPIService) FindBuildExecute(r ApiFindBuildRequest) (*BuildDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -530,7 +530,7 @@ func (a *BuildAPIService) GetBuildExecute(r ApiGetBuildRequest) (*BuildDTO, *htt localVarReturnValue *BuildDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BuildAPIService.GetBuild") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BuildAPIService.FindBuild") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/pkg/apiclient/api_container_registry.go b/pkg/apiclient/api_container_registry.go index 877be4642c..e156483b2f 100644 --- a/pkg/apiclient/api_container_registry.go +++ b/pkg/apiclient/api_container_registry.go @@ -22,7 +22,7 @@ import ( // ContainerRegistryAPIService ContainerRegistryAPI service type ContainerRegistryAPIService service -type ApiGetContainerRegistryRequest struct { +type ApiFindContainerRegistryRequest struct { ctx context.Context ApiService *ContainerRegistryAPIService server string @@ -30,26 +30,26 @@ type ApiGetContainerRegistryRequest struct { } // Workspace ID or Name -func (r ApiGetContainerRegistryRequest) WorkspaceId(workspaceId string) ApiGetContainerRegistryRequest { +func (r ApiFindContainerRegistryRequest) WorkspaceId(workspaceId string) ApiFindContainerRegistryRequest { r.workspaceId = &workspaceId return r } -func (r ApiGetContainerRegistryRequest) Execute() (*ContainerRegistry, *http.Response, error) { - return r.ApiService.GetContainerRegistryExecute(r) +func (r ApiFindContainerRegistryRequest) Execute() (*ContainerRegistry, *http.Response, error) { + return r.ApiService.FindContainerRegistryExecute(r) } /* -GetContainerRegistry Get container registry +FindContainerRegistry Find container registry -Get container registry +Find container registry @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param server Container registry server - @return ApiGetContainerRegistryRequest + @return ApiFindContainerRegistryRequest */ -func (a *ContainerRegistryAPIService) GetContainerRegistry(ctx context.Context, server string) ApiGetContainerRegistryRequest { - return ApiGetContainerRegistryRequest{ +func (a *ContainerRegistryAPIService) FindContainerRegistry(ctx context.Context, server string) ApiFindContainerRegistryRequest { + return ApiFindContainerRegistryRequest{ ApiService: a, ctx: ctx, server: server, @@ -59,7 +59,7 @@ func (a *ContainerRegistryAPIService) GetContainerRegistry(ctx context.Context, // Execute executes the request // // @return ContainerRegistry -func (a *ContainerRegistryAPIService) GetContainerRegistryExecute(r ApiGetContainerRegistryRequest) (*ContainerRegistry, *http.Response, error) { +func (a *ContainerRegistryAPIService) FindContainerRegistryExecute(r ApiFindContainerRegistryRequest) (*ContainerRegistry, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -67,7 +67,7 @@ func (a *ContainerRegistryAPIService) GetContainerRegistryExecute(r ApiGetContai localVarReturnValue *ContainerRegistry ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.GetContainerRegistry") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ContainerRegistryAPIService.FindContainerRegistry") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/pkg/apiclient/api_env_var.go b/pkg/apiclient/api_env_var.go index 507044403c..28c0266fc7 100644 --- a/pkg/apiclient/api_env_var.go +++ b/pkg/apiclient/api_env_var.go @@ -242,46 +242,46 @@ func (a *EnvVarAPIService) ListEnvironmentVariablesExecute(r ApiListEnvironmentV return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetEnvironmentVariableRequest struct { +type ApiSaveEnvironmentVariableRequest struct { ctx context.Context ApiService *EnvVarAPIService environmentVariable *EnvironmentVariable } // Environment Variable -func (r ApiSetEnvironmentVariableRequest) EnvironmentVariable(environmentVariable EnvironmentVariable) ApiSetEnvironmentVariableRequest { +func (r ApiSaveEnvironmentVariableRequest) EnvironmentVariable(environmentVariable EnvironmentVariable) ApiSaveEnvironmentVariableRequest { r.environmentVariable = &environmentVariable return r } -func (r ApiSetEnvironmentVariableRequest) Execute() (*http.Response, error) { - return r.ApiService.SetEnvironmentVariableExecute(r) +func (r ApiSaveEnvironmentVariableRequest) Execute() (*http.Response, error) { + return r.ApiService.SaveEnvironmentVariableExecute(r) } /* -SetEnvironmentVariable Set environment variable +SaveEnvironmentVariable Save environment variable -Set environment variable +Save environment variable @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetEnvironmentVariableRequest + @return ApiSaveEnvironmentVariableRequest */ -func (a *EnvVarAPIService) SetEnvironmentVariable(ctx context.Context) ApiSetEnvironmentVariableRequest { - return ApiSetEnvironmentVariableRequest{ +func (a *EnvVarAPIService) SaveEnvironmentVariable(ctx context.Context) ApiSaveEnvironmentVariableRequest { + return ApiSaveEnvironmentVariableRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *EnvVarAPIService) SetEnvironmentVariableExecute(r ApiSetEnvironmentVariableRequest) (*http.Response, error) { +func (a *EnvVarAPIService) SaveEnvironmentVariableExecute(r ApiSaveEnvironmentVariableRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "EnvVarAPIService.SetEnvironmentVariable") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "EnvVarAPIService.SaveEnvironmentVariable") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/pkg/apiclient/api_git_provider.go b/pkg/apiclient/api_git_provider.go index aba377926a..518f7010fb 100644 --- a/pkg/apiclient/api_git_provider.go +++ b/pkg/apiclient/api_git_provider.go @@ -22,61 +22,52 @@ import ( // GitProviderAPIService GitProviderAPI service type GitProviderAPIService service -type ApiGetGitContextRequest struct { - ctx context.Context - ApiService *GitProviderAPIService - repository *GetRepositoryContext -} - -// Get repository context -func (r ApiGetGitContextRequest) Repository(repository GetRepositoryContext) ApiGetGitContextRequest { - r.repository = &repository - return r +type ApiDeleteGitProviderRequest struct { + ctx context.Context + ApiService *GitProviderAPIService + gitProviderId string } -func (r ApiGetGitContextRequest) Execute() (*GitRepository, *http.Response, error) { - return r.ApiService.GetGitContextExecute(r) +func (r ApiDeleteGitProviderRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteGitProviderExecute(r) } /* -GetGitContext Get Git context +DeleteGitProvider Delete Git provider -Get Git context +Delete Git provider @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiGetGitContextRequest + @param gitProviderId Git provider + @return ApiDeleteGitProviderRequest */ -func (a *GitProviderAPIService) GetGitContext(ctx context.Context) ApiGetGitContextRequest { - return ApiGetGitContextRequest{ - ApiService: a, - ctx: ctx, +func (a *GitProviderAPIService) DeleteGitProvider(ctx context.Context, gitProviderId string) ApiDeleteGitProviderRequest { + return ApiDeleteGitProviderRequest{ + ApiService: a, + ctx: ctx, + gitProviderId: gitProviderId, } } // Execute executes the request -// -// @return GitRepository -func (a *GitProviderAPIService) GetGitContextExecute(r ApiGetGitContextRequest) (*GitRepository, *http.Response, error) { +func (a *GitProviderAPIService) DeleteGitProviderExecute(r ApiDeleteGitProviderRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *GitRepository + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.GetGitContext") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.DeleteGitProvider") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/gitprovider/context" + localVarPath := localBasePath + "/gitprovider/{gitProviderId}" + localVarPath = strings.Replace(localVarPath, "{"+"gitProviderId"+"}", url.PathEscape(parameterValueToString(r.gitProviderId, "gitProviderId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.repository == nil { - return localVarReturnValue, nil, reportError("repository is required and must be specified") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -88,15 +79,13 @@ func (a *GitProviderAPIService) GetGitContextExecute(r ApiGetGitContextRequest) } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.repository if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -113,19 +102,19 @@ func (a *GitProviderAPIService) GetGitContextExecute(r ApiGetGitContextRequest) } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -133,42 +122,33 @@ func (a *GitProviderAPIService) GetGitContextExecute(r ApiGetGitContextRequest) body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } -type ApiGetGitProviderRequest struct { +type ApiFindGitProviderRequest struct { ctx context.Context ApiService *GitProviderAPIService gitProviderId string } -func (r ApiGetGitProviderRequest) Execute() (*GitProvider, *http.Response, error) { - return r.ApiService.GetGitProviderExecute(r) +func (r ApiFindGitProviderRequest) Execute() (*GitProvider, *http.Response, error) { + return r.ApiService.FindGitProviderExecute(r) } /* -GetGitProvider Get Git provider +FindGitProvider Find Git provider -Get Git provider +Find Git provider @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param gitProviderId ID - @return ApiGetGitProviderRequest + @return ApiFindGitProviderRequest */ -func (a *GitProviderAPIService) GetGitProvider(ctx context.Context, gitProviderId string) ApiGetGitProviderRequest { - return ApiGetGitProviderRequest{ +func (a *GitProviderAPIService) FindGitProvider(ctx context.Context, gitProviderId string) ApiFindGitProviderRequest { + return ApiFindGitProviderRequest{ ApiService: a, ctx: ctx, gitProviderId: gitProviderId, @@ -178,7 +158,7 @@ func (a *GitProviderAPIService) GetGitProvider(ctx context.Context, gitProviderI // Execute executes the request // // @return GitProvider -func (a *GitProviderAPIService) GetGitProviderExecute(r ApiGetGitProviderRequest) (*GitProvider, *http.Response, error) { +func (a *GitProviderAPIService) FindGitProviderExecute(r ApiFindGitProviderRequest) (*GitProvider, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -186,7 +166,7 @@ func (a *GitProviderAPIService) GetGitProviderExecute(r ApiGetGitProviderRequest localVarReturnValue *GitProvider ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.GetGitProvider") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.FindGitProvider") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -266,27 +246,27 @@ func (a *GitProviderAPIService) GetGitProviderExecute(r ApiGetGitProviderRequest return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetGitProviderIdForUrlRequest struct { +type ApiFindGitProviderIdForUrlRequest struct { ctx context.Context ApiService *GitProviderAPIService url string } -func (r ApiGetGitProviderIdForUrlRequest) Execute() (string, *http.Response, error) { - return r.ApiService.GetGitProviderIdForUrlExecute(r) +func (r ApiFindGitProviderIdForUrlRequest) Execute() (string, *http.Response, error) { + return r.ApiService.FindGitProviderIdForUrlExecute(r) } /* -GetGitProviderIdForUrl Get Git provider ID +FindGitProviderIdForUrl Find Git provider ID -Get Git provider ID +Find Git provider ID @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param url Url - @return ApiGetGitProviderIdForUrlRequest + @return ApiFindGitProviderIdForUrlRequest */ -func (a *GitProviderAPIService) GetGitProviderIdForUrl(ctx context.Context, url string) ApiGetGitProviderIdForUrlRequest { - return ApiGetGitProviderIdForUrlRequest{ +func (a *GitProviderAPIService) FindGitProviderIdForUrl(ctx context.Context, url string) ApiFindGitProviderIdForUrlRequest { + return ApiFindGitProviderIdForUrlRequest{ ApiService: a, ctx: ctx, url: url, @@ -296,7 +276,7 @@ func (a *GitProviderAPIService) GetGitProviderIdForUrl(ctx context.Context, url // Execute executes the request // // @return string -func (a *GitProviderAPIService) GetGitProviderIdForUrlExecute(r ApiGetGitProviderIdForUrlRequest) (string, *http.Response, error) { +func (a *GitProviderAPIService) FindGitProviderIdForUrlExecute(r ApiFindGitProviderIdForUrlRequest) (string, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -304,7 +284,7 @@ func (a *GitProviderAPIService) GetGitProviderIdForUrlExecute(r ApiGetGitProvide localVarReturnValue string ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.GetGitProviderIdForUrl") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.FindGitProviderIdForUrl") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -384,6 +364,132 @@ func (a *GitProviderAPIService) GetGitProviderIdForUrlExecute(r ApiGetGitProvide return localVarReturnValue, localVarHTTPResponse, nil } +type ApiGetGitContextRequest struct { + ctx context.Context + ApiService *GitProviderAPIService + repository *GetRepositoryContext +} + +// Get repository context +func (r ApiGetGitContextRequest) Repository(repository GetRepositoryContext) ApiGetGitContextRequest { + r.repository = &repository + return r +} + +func (r ApiGetGitContextRequest) Execute() (*GitRepository, *http.Response, error) { + return r.ApiService.GetGitContextExecute(r) +} + +/* +GetGitContext Get Git context + +Get Git context + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetGitContextRequest +*/ +func (a *GitProviderAPIService) GetGitContext(ctx context.Context) ApiGetGitContextRequest { + return ApiGetGitContextRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return GitRepository +func (a *GitProviderAPIService) GetGitContextExecute(r ApiGetGitContextRequest) (*GitRepository, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *GitRepository + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.GetGitContext") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/gitprovider/context" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.repository == nil { + return localVarReturnValue, nil, reportError("repository is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.repository + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ApiGetGitUserRequest struct { ctx context.Context ApiService *GitProviderAPIService @@ -1432,152 +1538,46 @@ func (a *GitProviderAPIService) ListGitProvidersForUrlExecute(r ApiListGitProvid return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveGitProviderRequest struct { - ctx context.Context - ApiService *GitProviderAPIService - gitProviderId string -} - -func (r ApiRemoveGitProviderRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveGitProviderExecute(r) -} - -/* -RemoveGitProvider Remove Git provider - -Remove Git provider - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param gitProviderId Git provider - @return ApiRemoveGitProviderRequest -*/ -func (a *GitProviderAPIService) RemoveGitProvider(ctx context.Context, gitProviderId string) ApiRemoveGitProviderRequest { - return ApiRemoveGitProviderRequest{ - ApiService: a, - ctx: ctx, - gitProviderId: gitProviderId, - } -} - -// Execute executes the request -func (a *GitProviderAPIService) RemoveGitProviderExecute(r ApiRemoveGitProviderRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.RemoveGitProvider") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/gitprovider/{gitProviderId}" - localVarPath = strings.Replace(localVarPath, "{"+"gitProviderId"+"}", url.PathEscape(parameterValueToString(r.gitProviderId, "gitProviderId")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} - -type ApiSetGitProviderRequest struct { +type ApiSaveGitProviderRequest struct { ctx context.Context ApiService *GitProviderAPIService gitProviderConfig *SetGitProviderConfig } // Git provider -func (r ApiSetGitProviderRequest) GitProviderConfig(gitProviderConfig SetGitProviderConfig) ApiSetGitProviderRequest { +func (r ApiSaveGitProviderRequest) GitProviderConfig(gitProviderConfig SetGitProviderConfig) ApiSaveGitProviderRequest { r.gitProviderConfig = &gitProviderConfig return r } -func (r ApiSetGitProviderRequest) Execute() (*http.Response, error) { - return r.ApiService.SetGitProviderExecute(r) +func (r ApiSaveGitProviderRequest) Execute() (*http.Response, error) { + return r.ApiService.SaveGitProviderExecute(r) } /* -SetGitProvider Set Git provider +SaveGitProvider Save Git provider -Set Git provider +Save Git provider @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetGitProviderRequest + @return ApiSaveGitProviderRequest */ -func (a *GitProviderAPIService) SetGitProvider(ctx context.Context) ApiSetGitProviderRequest { - return ApiSetGitProviderRequest{ +func (a *GitProviderAPIService) SaveGitProvider(ctx context.Context) ApiSaveGitProviderRequest { + return ApiSaveGitProviderRequest{ ApiService: a, ctx: ctx, } } // Execute executes the request -func (a *GitProviderAPIService) SetGitProviderExecute(r ApiSetGitProviderRequest) (*http.Response, error) { +func (a *GitProviderAPIService) SaveGitProviderExecute(r ApiSaveGitProviderRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.SetGitProvider") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "GitProviderAPIService.SaveGitProvider") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/pkg/apiclient/api_prebuild.go b/pkg/apiclient/api_prebuild.go index cf9be91f0a..f76b593d4f 100644 --- a/pkg/apiclient/api_prebuild.go +++ b/pkg/apiclient/api_prebuild.go @@ -142,29 +142,29 @@ func (a *PrebuildAPIService) DeletePrebuildExecute(r ApiDeletePrebuildRequest) ( return localVarHTTPResponse, nil } -type ApiGetPrebuildRequest struct { +type ApiFindPrebuildRequest struct { ctx context.Context ApiService *PrebuildAPIService templateName string prebuildId string } -func (r ApiGetPrebuildRequest) Execute() (*PrebuildDTO, *http.Response, error) { - return r.ApiService.GetPrebuildExecute(r) +func (r ApiFindPrebuildRequest) Execute() (*PrebuildDTO, *http.Response, error) { + return r.ApiService.FindPrebuildExecute(r) } /* -GetPrebuild Get prebuild +FindPrebuild Find prebuild -Get prebuild +Find prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param templateName Workspace template name @param prebuildId Prebuild ID - @return ApiGetPrebuildRequest + @return ApiFindPrebuildRequest */ -func (a *PrebuildAPIService) GetPrebuild(ctx context.Context, templateName string, prebuildId string) ApiGetPrebuildRequest { - return ApiGetPrebuildRequest{ +func (a *PrebuildAPIService) FindPrebuild(ctx context.Context, templateName string, prebuildId string) ApiFindPrebuildRequest { + return ApiFindPrebuildRequest{ ApiService: a, ctx: ctx, templateName: templateName, @@ -175,7 +175,7 @@ func (a *PrebuildAPIService) GetPrebuild(ctx context.Context, templateName strin // Execute executes the request // // @return PrebuildDTO -func (a *PrebuildAPIService) GetPrebuildExecute(r ApiGetPrebuildRequest) (*PrebuildDTO, *http.Response, error) { +func (a *PrebuildAPIService) FindPrebuildExecute(r ApiFindPrebuildRequest) (*PrebuildDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -183,7 +183,7 @@ func (a *PrebuildAPIService) GetPrebuildExecute(r ApiGetPrebuildRequest) (*Prebu localVarReturnValue *PrebuildDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.GetPrebuild") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.FindPrebuild") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -610,7 +610,7 @@ func (a *PrebuildAPIService) ProcessGitEventExecute(r ApiProcessGitEventRequest) return localVarHTTPResponse, nil } -type ApiSetPrebuildRequest struct { +type ApiSavePrebuildRequest struct { ctx context.Context ApiService *PrebuildAPIService templateName string @@ -618,26 +618,26 @@ type ApiSetPrebuildRequest struct { } // Prebuild -func (r ApiSetPrebuildRequest) Prebuild(prebuild CreatePrebuildDTO) ApiSetPrebuildRequest { +func (r ApiSavePrebuildRequest) Prebuild(prebuild CreatePrebuildDTO) ApiSavePrebuildRequest { r.prebuild = &prebuild return r } -func (r ApiSetPrebuildRequest) Execute() (string, *http.Response, error) { - return r.ApiService.SetPrebuildExecute(r) +func (r ApiSavePrebuildRequest) Execute() (string, *http.Response, error) { + return r.ApiService.SavePrebuildExecute(r) } /* -SetPrebuild Set prebuild +SavePrebuild Save prebuild -Set prebuild +Save prebuild @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param templateName Template name - @return ApiSetPrebuildRequest + @return ApiSavePrebuildRequest */ -func (a *PrebuildAPIService) SetPrebuild(ctx context.Context, templateName string) ApiSetPrebuildRequest { - return ApiSetPrebuildRequest{ +func (a *PrebuildAPIService) SavePrebuild(ctx context.Context, templateName string) ApiSavePrebuildRequest { + return ApiSavePrebuildRequest{ ApiService: a, ctx: ctx, templateName: templateName, @@ -647,7 +647,7 @@ func (a *PrebuildAPIService) SetPrebuild(ctx context.Context, templateName strin // Execute executes the request // // @return string -func (a *PrebuildAPIService) SetPrebuildExecute(r ApiSetPrebuildRequest) (string, *http.Response, error) { +func (a *PrebuildAPIService) SavePrebuildExecute(r ApiSavePrebuildRequest) (string, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPut localVarPostBody interface{} @@ -655,7 +655,7 @@ func (a *PrebuildAPIService) SetPrebuildExecute(r ApiSetPrebuildRequest) (string localVarReturnValue string ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.SetPrebuild") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "PrebuildAPIService.SavePrebuild") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/pkg/apiclient/api_runner.go b/pkg/apiclient/api_runner.go index 7c1afbe486..0c32123000 100644 --- a/pkg/apiclient/api_runner.go +++ b/pkg/apiclient/api_runner.go @@ -22,55 +22,61 @@ import ( // RunnerAPIService RunnerAPI service type RunnerAPIService service -type ApiGetRunnerRequest struct { +type ApiCreateRunnerRequest struct { ctx context.Context ApiService *RunnerAPIService - runnerId string + runner *CreateRunnerDTO } -func (r ApiGetRunnerRequest) Execute() (*RunnerDTO, *http.Response, error) { - return r.ApiService.GetRunnerExecute(r) +// Runner +func (r ApiCreateRunnerRequest) Runner(runner CreateRunnerDTO) ApiCreateRunnerRequest { + r.runner = &runner + return r +} + +func (r ApiCreateRunnerRequest) Execute() (*CreateRunnerResultDTO, *http.Response, error) { + return r.ApiService.CreateRunnerExecute(r) } /* -GetRunner Get a runner +CreateRunner Create a runner -Get a runner +Create a runner @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param runnerId Runner ID - @return ApiGetRunnerRequest + @return ApiCreateRunnerRequest */ -func (a *RunnerAPIService) GetRunner(ctx context.Context, runnerId string) ApiGetRunnerRequest { - return ApiGetRunnerRequest{ +func (a *RunnerAPIService) CreateRunner(ctx context.Context) ApiCreateRunnerRequest { + return ApiCreateRunnerRequest{ ApiService: a, ctx: ctx, - runnerId: runnerId, } } // Execute executes the request // -// @return RunnerDTO -func (a *RunnerAPIService) GetRunnerExecute(r ApiGetRunnerRequest) (*RunnerDTO, *http.Response, error) { +// @return CreateRunnerResultDTO +func (a *RunnerAPIService) CreateRunnerExecute(r ApiCreateRunnerRequest) (*CreateRunnerResultDTO, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet + localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile - localVarReturnValue *RunnerDTO + localVarReturnValue *CreateRunnerResultDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.GetRunner") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.CreateRunner") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner/{runnerId}" - localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + localVarPath := localBasePath + "/runner" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.runner == nil { + return localVarReturnValue, nil, reportError("runner is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -89,6 +95,8 @@ func (a *RunnerAPIService) GetRunnerExecute(r ApiGetRunnerRequest) (*RunnerDTO, if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.runner if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -140,27 +148,27 @@ func (a *RunnerAPIService) GetRunnerExecute(r ApiGetRunnerRequest) (*RunnerDTO, return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListRunnerJobsRequest struct { +type ApiDeleteRunnerRequest struct { ctx context.Context ApiService *RunnerAPIService runnerId string } -func (r ApiListRunnerJobsRequest) Execute() ([]Job, *http.Response, error) { - return r.ApiService.ListRunnerJobsExecute(r) +func (r ApiDeleteRunnerRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteRunnerExecute(r) } /* -ListRunnerJobs List runner jobs +DeleteRunner Delete runner -List runner jobs +Delete runner @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param runnerId Runner ID - @return ApiListRunnerJobsRequest + @return ApiDeleteRunnerRequest */ -func (a *RunnerAPIService) ListRunnerJobs(ctx context.Context, runnerId string) ApiListRunnerJobsRequest { - return ApiListRunnerJobsRequest{ +func (a *RunnerAPIService) DeleteRunner(ctx context.Context, runnerId string) ApiDeleteRunnerRequest { + return ApiDeleteRunnerRequest{ ApiService: a, ctx: ctx, runnerId: runnerId, @@ -168,22 +176,19 @@ func (a *RunnerAPIService) ListRunnerJobs(ctx context.Context, runnerId string) } // Execute executes the request -// -// @return []Job -func (a *RunnerAPIService) ListRunnerJobsExecute(r ApiListRunnerJobsRequest) ([]Job, *http.Response, error) { +func (a *RunnerAPIService) DeleteRunnerExecute(r ApiDeleteRunnerRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue []Job + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.ListRunnerJobs") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.DeleteRunner") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner/{runnerId}/jobs" + localVarPath := localBasePath + "/runner/{runnerId}" localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) localVarHeaderParams := make(map[string]string) @@ -200,7 +205,7 @@ func (a *RunnerAPIService) ListRunnerJobsExecute(r ApiListRunnerJobsRequest) ([] } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -223,19 +228,19 @@ func (a *RunnerAPIService) ListRunnerJobsExecute(r ApiListRunnerJobsRequest) ([] } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -243,62 +248,57 @@ func (a *RunnerAPIService) ListRunnerJobsExecute(r ApiListRunnerJobsRequest) ([] body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } -type ApiListRunnersRequest struct { +type ApiFindRunnerRequest struct { ctx context.Context ApiService *RunnerAPIService + runnerId string } -func (r ApiListRunnersRequest) Execute() ([]RunnerDTO, *http.Response, error) { - return r.ApiService.ListRunnersExecute(r) +func (r ApiFindRunnerRequest) Execute() (*RunnerDTO, *http.Response, error) { + return r.ApiService.FindRunnerExecute(r) } /* -ListRunners List runners +FindRunner Find a runner -List runners +Find a runner @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListRunnersRequest + @param runnerId Runner ID + @return ApiFindRunnerRequest */ -func (a *RunnerAPIService) ListRunners(ctx context.Context) ApiListRunnersRequest { - return ApiListRunnersRequest{ +func (a *RunnerAPIService) FindRunner(ctx context.Context, runnerId string) ApiFindRunnerRequest { + return ApiFindRunnerRequest{ ApiService: a, ctx: ctx, + runnerId: runnerId, } } // Execute executes the request // -// @return []RunnerDTO -func (a *RunnerAPIService) ListRunnersExecute(r ApiListRunnersRequest) ([]RunnerDTO, *http.Response, error) { +// @return RunnerDTO +func (a *RunnerAPIService) FindRunnerExecute(r ApiFindRunnerRequest) (*RunnerDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []RunnerDTO + localVarReturnValue *RunnerDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.ListRunners") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.FindRunner") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner" + localVarPath := localBasePath + "/runner/{runnerId}" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -372,61 +372,55 @@ func (a *RunnerAPIService) ListRunnersExecute(r ApiListRunnersRequest) ([]Runner return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRegisterRunnerRequest struct { +type ApiListRunnerJobsRequest struct { ctx context.Context ApiService *RunnerAPIService - runner *RegisterRunnerDTO -} - -// Register runner -func (r ApiRegisterRunnerRequest) Runner(runner RegisterRunnerDTO) ApiRegisterRunnerRequest { - r.runner = &runner - return r + runnerId string } -func (r ApiRegisterRunnerRequest) Execute() (*RegisterRunnerResultDTO, *http.Response, error) { - return r.ApiService.RegisterRunnerExecute(r) +func (r ApiListRunnerJobsRequest) Execute() ([]Job, *http.Response, error) { + return r.ApiService.ListRunnerJobsExecute(r) } /* -RegisterRunner Register a runner +ListRunnerJobs List runner jobs -Register a runner +List runner jobs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiRegisterRunnerRequest + @param runnerId Runner ID + @return ApiListRunnerJobsRequest */ -func (a *RunnerAPIService) RegisterRunner(ctx context.Context) ApiRegisterRunnerRequest { - return ApiRegisterRunnerRequest{ +func (a *RunnerAPIService) ListRunnerJobs(ctx context.Context, runnerId string) ApiListRunnerJobsRequest { + return ApiListRunnerJobsRequest{ ApiService: a, ctx: ctx, + runnerId: runnerId, } } // Execute executes the request // -// @return RegisterRunnerResultDTO -func (a *RunnerAPIService) RegisterRunnerExecute(r ApiRegisterRunnerRequest) (*RegisterRunnerResultDTO, *http.Response, error) { +// @return []Job +func (a *RunnerAPIService) ListRunnerJobsExecute(r ApiListRunnerJobsRequest) ([]Job, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost + localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue *RegisterRunnerResultDTO + localVarReturnValue []Job ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.RegisterRunner") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.ListRunnerJobs") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner" + localVarPath := localBasePath + "/runner/{runnerId}/jobs" + localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.runner == nil { - return localVarReturnValue, nil, reportError("runner is required and must be specified") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -445,8 +439,6 @@ func (a *RunnerAPIService) RegisterRunnerExecute(r ApiRegisterRunnerRequest) (*R if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.runner if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -498,48 +490,47 @@ func (a *RunnerAPIService) RegisterRunnerExecute(r ApiRegisterRunnerRequest) (*R return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveRunnerRequest struct { +type ApiListRunnersRequest struct { ctx context.Context ApiService *RunnerAPIService - runnerId string } -func (r ApiRemoveRunnerRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveRunnerExecute(r) +func (r ApiListRunnersRequest) Execute() ([]RunnerDTO, *http.Response, error) { + return r.ApiService.ListRunnersExecute(r) } /* -RemoveRunner Remove runner +ListRunners List runners -Remove runner +List runners @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param runnerId Runner ID - @return ApiRemoveRunnerRequest + @return ApiListRunnersRequest */ -func (a *RunnerAPIService) RemoveRunner(ctx context.Context, runnerId string) ApiRemoveRunnerRequest { - return ApiRemoveRunnerRequest{ +func (a *RunnerAPIService) ListRunners(ctx context.Context) ApiListRunnersRequest { + return ApiListRunnersRequest{ ApiService: a, ctx: ctx, - runnerId: runnerId, } } // Execute executes the request -func (a *RunnerAPIService) RemoveRunnerExecute(r ApiRemoveRunnerRequest) (*http.Response, error) { +// +// @return []RunnerDTO +func (a *RunnerAPIService) ListRunnersExecute(r ApiListRunnersRequest) ([]RunnerDTO, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []RunnerDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.RemoveRunner") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.ListRunners") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner/{runnerId}" - localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + localVarPath := localBasePath + "/runner" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -555,7 +546,7 @@ func (a *RunnerAPIService) RemoveRunnerExecute(r ApiRemoveRunnerRequest) (*http. } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -578,19 +569,19 @@ func (a *RunnerAPIService) RemoveRunnerExecute(r ApiRemoveRunnerRequest) (*http. } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -598,67 +589,80 @@ func (a *RunnerAPIService) RemoveRunnerExecute(r ApiRemoveRunnerRequest) (*http. body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetRunnerMetadataRequest struct { +type ApiUpdateJobStateRequest struct { ctx context.Context ApiService *RunnerAPIService runnerId string - runnerMetadata *UpdateRunnerMetadataDTO + jobId string + updateJobState *UpdateJobState } -// Runner Metadata -func (r ApiSetRunnerMetadataRequest) RunnerMetadata(runnerMetadata UpdateRunnerMetadataDTO) ApiSetRunnerMetadataRequest { - r.runnerMetadata = &runnerMetadata +// Update job state +func (r ApiUpdateJobStateRequest) UpdateJobState(updateJobState UpdateJobState) ApiUpdateJobStateRequest { + r.updateJobState = &updateJobState return r } -func (r ApiSetRunnerMetadataRequest) Execute() (*http.Response, error) { - return r.ApiService.SetRunnerMetadataExecute(r) +func (r ApiUpdateJobStateRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateJobStateExecute(r) } /* -SetRunnerMetadata Set runner metadata +UpdateJobState Update job state -Set runner metadata +Update job state @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param runnerId Runner ID - @return ApiSetRunnerMetadataRequest + @param jobId Job ID + @return ApiUpdateJobStateRequest */ -func (a *RunnerAPIService) SetRunnerMetadata(ctx context.Context, runnerId string) ApiSetRunnerMetadataRequest { - return ApiSetRunnerMetadataRequest{ +func (a *RunnerAPIService) UpdateJobState(ctx context.Context, runnerId string, jobId string) ApiUpdateJobStateRequest { + return ApiUpdateJobStateRequest{ ApiService: a, ctx: ctx, runnerId: runnerId, + jobId: jobId, } } // Execute executes the request -func (a *RunnerAPIService) SetRunnerMetadataExecute(r ApiSetRunnerMetadataRequest) (*http.Response, error) { +func (a *RunnerAPIService) UpdateJobStateExecute(r ApiUpdateJobStateRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.SetRunnerMetadata") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.UpdateJobState") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner/{runnerId}/metadata" + localVarPath := localBasePath + "/runner/{runnerId}/jobs/{jobId}/state" localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) + localVarPath = strings.Replace(localVarPath, "{"+"jobId"+"}", url.PathEscape(parameterValueToString(r.jobId, "jobId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.runnerMetadata == nil { - return nil, reportError("runnerMetadata is required and must be specified") + if r.updateJobState == nil { + return nil, reportError("updateJobState is required and must be specified") } // to determine the Content-Type header @@ -679,7 +683,7 @@ func (a *RunnerAPIService) SetRunnerMetadataExecute(r ApiSetRunnerMetadataReques localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.runnerMetadata + localVarPostBody = r.updateJobState if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -722,65 +726,61 @@ func (a *RunnerAPIService) SetRunnerMetadataExecute(r ApiSetRunnerMetadataReques return localVarHTTPResponse, nil } -type ApiUpdateJobStateRequest struct { +type ApiUpdateRunnerMetadataRequest struct { ctx context.Context ApiService *RunnerAPIService runnerId string - jobId string - updateJobState *UpdateJobState + runnerMetadata *UpdateRunnerMetadataDTO } -// Update job state -func (r ApiUpdateJobStateRequest) UpdateJobState(updateJobState UpdateJobState) ApiUpdateJobStateRequest { - r.updateJobState = &updateJobState +// Runner Metadata +func (r ApiUpdateRunnerMetadataRequest) RunnerMetadata(runnerMetadata UpdateRunnerMetadataDTO) ApiUpdateRunnerMetadataRequest { + r.runnerMetadata = &runnerMetadata return r } -func (r ApiUpdateJobStateRequest) Execute() (*http.Response, error) { - return r.ApiService.UpdateJobStateExecute(r) +func (r ApiUpdateRunnerMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateRunnerMetadataExecute(r) } /* -UpdateJobState Update job state +UpdateRunnerMetadata Update runner metadata -Update job state +Update runner metadata @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param runnerId Runner ID - @param jobId Job ID - @return ApiUpdateJobStateRequest + @return ApiUpdateRunnerMetadataRequest */ -func (a *RunnerAPIService) UpdateJobState(ctx context.Context, runnerId string, jobId string) ApiUpdateJobStateRequest { - return ApiUpdateJobStateRequest{ +func (a *RunnerAPIService) UpdateRunnerMetadata(ctx context.Context, runnerId string) ApiUpdateRunnerMetadataRequest { + return ApiUpdateRunnerMetadataRequest{ ApiService: a, ctx: ctx, runnerId: runnerId, - jobId: jobId, } } // Execute executes the request -func (a *RunnerAPIService) UpdateJobStateExecute(r ApiUpdateJobStateRequest) (*http.Response, error) { +func (a *RunnerAPIService) UpdateRunnerMetadataExecute(r ApiUpdateRunnerMetadataRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.UpdateJobState") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "RunnerAPIService.UpdateRunnerMetadata") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/runner/{runnerId}/jobs/{jobId}/state" + localVarPath := localBasePath + "/runner/{runnerId}/metadata" localVarPath = strings.Replace(localVarPath, "{"+"runnerId"+"}", url.PathEscape(parameterValueToString(r.runnerId, "runnerId")), -1) - localVarPath = strings.Replace(localVarPath, "{"+"jobId"+"}", url.PathEscape(parameterValueToString(r.jobId, "jobId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.updateJobState == nil { - return nil, reportError("updateJobState is required and must be specified") + if r.runnerMetadata == nil { + return nil, reportError("runnerMetadata is required and must be specified") } // to determine the Content-Type header @@ -801,7 +801,7 @@ func (a *RunnerAPIService) UpdateJobStateExecute(r ApiUpdateJobStateRequest) (*h localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } // body params - localVarPostBody = r.updateJobState + localVarPostBody = r.runnerMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/api_server.go b/pkg/apiclient/api_server.go index ee89a12b8c..6fce8c1e6e 100644 --- a/pkg/apiclient/api_server.go +++ b/pkg/apiclient/api_server.go @@ -21,25 +21,25 @@ import ( // ServerAPIService ServerAPI service type ServerAPIService service -type ApiGenerateNetworkKeyRequest struct { +type ApiCreateNetworkKeyRequest struct { ctx context.Context ApiService *ServerAPIService } -func (r ApiGenerateNetworkKeyRequest) Execute() (*NetworkKey, *http.Response, error) { - return r.ApiService.GenerateNetworkKeyExecute(r) +func (r ApiCreateNetworkKeyRequest) Execute() (*NetworkKey, *http.Response, error) { + return r.ApiService.CreateNetworkKeyExecute(r) } /* -GenerateNetworkKey Generate a new authentication key +CreateNetworkKey Create a new authentication key -Generate a new authentication key +Create a new authentication key @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiGenerateNetworkKeyRequest + @return ApiCreateNetworkKeyRequest */ -func (a *ServerAPIService) GenerateNetworkKey(ctx context.Context) ApiGenerateNetworkKeyRequest { - return ApiGenerateNetworkKeyRequest{ +func (a *ServerAPIService) CreateNetworkKey(ctx context.Context) ApiCreateNetworkKeyRequest { + return ApiCreateNetworkKeyRequest{ ApiService: a, ctx: ctx, } @@ -48,7 +48,7 @@ func (a *ServerAPIService) GenerateNetworkKey(ctx context.Context) ApiGenerateNe // Execute executes the request // // @return NetworkKey -func (a *ServerAPIService) GenerateNetworkKeyExecute(r ApiGenerateNetworkKeyRequest) (*NetworkKey, *http.Response, error) { +func (a *ServerAPIService) CreateNetworkKeyExecute(r ApiCreateNetworkKeyRequest) (*NetworkKey, *http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} @@ -56,7 +56,7 @@ func (a *ServerAPIService) GenerateNetworkKeyExecute(r ApiGenerateNetworkKeyRequ localVarReturnValue *NetworkKey ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServerAPIService.GenerateNetworkKey") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServerAPIService.CreateNetworkKey") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -259,9 +259,9 @@ func (r ApiGetServerLogFilesRequest) Execute() ([]string, *http.Response, error) } /* -GetServerLogFiles List server log files +GetServerLogFiles Get server log files -List server log files +Get server log files @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @return ApiGetServerLogFilesRequest @@ -363,32 +363,32 @@ func (a *ServerAPIService) GetServerLogFilesExecute(r ApiGetServerLogFilesReques return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetConfigRequest struct { +type ApiSaveConfigRequest struct { ctx context.Context ApiService *ServerAPIService config *ServerConfig } // Server configuration -func (r ApiSetConfigRequest) Config(config ServerConfig) ApiSetConfigRequest { +func (r ApiSaveConfigRequest) Config(config ServerConfig) ApiSaveConfigRequest { r.config = &config return r } -func (r ApiSetConfigRequest) Execute() (*ServerConfig, *http.Response, error) { - return r.ApiService.SetConfigExecute(r) +func (r ApiSaveConfigRequest) Execute() (*ServerConfig, *http.Response, error) { + return r.ApiService.SaveConfigExecute(r) } /* -SetConfig Set the server configuration +SaveConfig Save the server configuration -Set the server configuration +Save the server configuration @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetConfigRequest + @return ApiSaveConfigRequest */ -func (a *ServerAPIService) SetConfig(ctx context.Context) ApiSetConfigRequest { - return ApiSetConfigRequest{ +func (a *ServerAPIService) SaveConfig(ctx context.Context) ApiSaveConfigRequest { + return ApiSaveConfigRequest{ ApiService: a, ctx: ctx, } @@ -397,15 +397,15 @@ func (a *ServerAPIService) SetConfig(ctx context.Context) ApiSetConfigRequest { // Execute executes the request // // @return ServerConfig -func (a *ServerAPIService) SetConfigExecute(r ApiSetConfigRequest) (*ServerConfig, *http.Response, error) { +func (a *ServerAPIService) SaveConfigExecute(r ApiSaveConfigRequest) (*ServerConfig, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPost + localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile localVarReturnValue *ServerConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServerAPIService.SetConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ServerAPIService.SaveConfig") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index 5dff658d29..6de8b4166b 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -148,7 +148,123 @@ func (a *TargetAPIService) CreateTargetExecute(r ApiCreateTargetRequest) (*Targe return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetTargetRequest struct { +type ApiDeleteTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + force *bool +} + +// Force +func (r ApiDeleteTargetRequest) Force(force bool) ApiDeleteTargetRequest { + r.force = &force + return r +} + +func (r ApiDeleteTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteTargetExecute(r) +} + +/* +DeleteTarget Delete target + +Delete target + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param targetId Target ID + @return ApiDeleteTargetRequest +*/ +func (a *TargetAPIService) DeleteTarget(ctx context.Context, targetId string) ApiDeleteTargetRequest { + return ApiDeleteTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + } +} + +// Execute executes the request +func (a *TargetAPIService) DeleteTargetExecute(r ApiDeleteTargetRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.DeleteTarget") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/target/{targetId}" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.force != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "force", r.force, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + +type ApiFindTargetRequest struct { ctx context.Context ApiService *TargetAPIService targetId string @@ -156,26 +272,26 @@ type ApiGetTargetRequest struct { } // Show target config options -func (r ApiGetTargetRequest) ShowOptions(showOptions bool) ApiGetTargetRequest { +func (r ApiFindTargetRequest) ShowOptions(showOptions bool) ApiFindTargetRequest { r.showOptions = &showOptions return r } -func (r ApiGetTargetRequest) Execute() (*TargetDTO, *http.Response, error) { - return r.ApiService.GetTargetExecute(r) +func (r ApiFindTargetRequest) Execute() (*TargetDTO, *http.Response, error) { + return r.ApiService.FindTargetExecute(r) } /* -GetTarget Get target info +FindTarget Find target -Get target info +Find target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @return ApiGetTargetRequest + @return ApiFindTargetRequest */ -func (a *TargetAPIService) GetTarget(ctx context.Context, targetId string) ApiGetTargetRequest { - return ApiGetTargetRequest{ +func (a *TargetAPIService) FindTarget(ctx context.Context, targetId string) ApiFindTargetRequest { + return ApiFindTargetRequest{ ApiService: a, ctx: ctx, targetId: targetId, @@ -185,7 +301,7 @@ func (a *TargetAPIService) GetTarget(ctx context.Context, targetId string) ApiGe // Execute executes the request // // @return TargetDTO -func (a *TargetAPIService) GetTargetExecute(r ApiGetTargetRequest) (*TargetDTO, *http.Response, error) { +func (a *TargetAPIService) FindTargetExecute(r ApiFindTargetRequest) (*TargetDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -193,7 +309,7 @@ func (a *TargetAPIService) GetTargetExecute(r ApiGetTargetRequest) (*TargetDTO, localVarReturnValue *TargetDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.GetTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.FindTarget") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -506,122 +622,6 @@ func (a *TargetAPIService) ListTargetsExecute(r ApiListTargetsRequest) ([]Target return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveTargetRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - force *bool -} - -// Force -func (r ApiRemoveTargetRequest) Force(force bool) ApiRemoveTargetRequest { - r.force = &force - return r -} - -func (r ApiRemoveTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveTargetExecute(r) -} - -/* -RemoveTarget Remove target - -Remove target - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param targetId Target ID - @return ApiRemoveTargetRequest -*/ -func (a *TargetAPIService) RemoveTarget(ctx context.Context, targetId string) ApiRemoveTargetRequest { - return ApiRemoveTargetRequest{ - ApiService: a, - ctx: ctx, - targetId: targetId, - } -} - -// Execute executes the request -func (a *TargetAPIService) RemoveTargetExecute(r ApiRemoveTargetRequest) (*http.Response, error) { - var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile - ) - - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.RemoveTarget") - if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} - } - - localVarPath := localBasePath + "/target/{targetId}" - localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - if r.force != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "force", r.force, "") - } - // to determine the Content-Type header - localVarHTTPContentTypes := []string{} - - // set Content-Type header - localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) - if localVarHTTPContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHTTPContentType - } - - // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} - - // set Accept header - localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) - if localVarHTTPHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept - } - if r.ctx != nil { - // API Key Authentication - if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { - if apiKey, ok := auth["Bearer"]; ok { - var key string - if apiKey.Prefix != "" { - key = apiKey.Prefix + " " + apiKey.Key - } else { - key = apiKey.Key - } - localVarHeaderParams["Authorization"] = key - } - } - } - req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) - if err != nil { - return nil, err - } - - localVarHTTPResponse, err := a.client.callAPI(req) - if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err - } - - localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) - localVarHTTPResponse.Body.Close() - localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) - if err != nil { - return localVarHTTPResponse, err - } - - if localVarHTTPResponse.StatusCode >= 300 { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: localVarHTTPResponse.Status, - } - return localVarHTTPResponse, newErr - } - - return localVarHTTPResponse, nil -} - type ApiSetDefaultTargetRequest struct { ctx context.Context ApiService *TargetAPIService @@ -728,34 +728,27 @@ func (a *TargetAPIService) SetDefaultTargetExecute(r ApiSetDefaultTargetRequest) return localVarHTTPResponse, nil } -type ApiSetTargetMetadataRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string - targetMetadata *UpdateTargetMetadataDTO -} - -// Target Metadata -func (r ApiSetTargetMetadataRequest) TargetMetadata(targetMetadata UpdateTargetMetadataDTO) ApiSetTargetMetadataRequest { - r.targetMetadata = &targetMetadata - return r +type ApiStartTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string } -func (r ApiSetTargetMetadataRequest) Execute() (*http.Response, error) { - return r.ApiService.SetTargetMetadataExecute(r) +func (r ApiStartTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.StartTargetExecute(r) } /* -SetTargetMetadata Set target metadata +StartTarget Start target -Set target metadata +Start target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param targetId Target ID - @return ApiSetTargetMetadataRequest + @param targetId Target ID or Name + @return ApiStartTargetRequest */ -func (a *TargetAPIService) SetTargetMetadata(ctx context.Context, targetId string) ApiSetTargetMetadataRequest { - return ApiSetTargetMetadataRequest{ +func (a *TargetAPIService) StartTarget(ctx context.Context, targetId string) ApiStartTargetRequest { + return ApiStartTargetRequest{ ApiService: a, ctx: ctx, targetId: targetId, @@ -763,27 +756,24 @@ func (a *TargetAPIService) SetTargetMetadata(ctx context.Context, targetId strin } // Execute executes the request -func (a *TargetAPIService) SetTargetMetadataExecute(r ApiSetTargetMetadataRequest) (*http.Response, error) { +func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.SetTargetMetadata") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/metadata" + localVarPath := localBasePath + "/target/{targetId}/start" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.targetMetadata == nil { - return nil, reportError("targetMetadata is required and must be specified") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -802,8 +792,6 @@ func (a *TargetAPIService) SetTargetMetadataExecute(r ApiSetTargetMetadataReques if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.targetMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -846,27 +834,27 @@ func (a *TargetAPIService) SetTargetMetadataExecute(r ApiSetTargetMetadataReques return localVarHTTPResponse, nil } -type ApiStartTargetRequest struct { +type ApiStopTargetRequest struct { ctx context.Context ApiService *TargetAPIService targetId string } -func (r ApiStartTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.StartTargetExecute(r) +func (r ApiStopTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.StopTargetExecute(r) } /* -StartTarget Start target +StopTarget Stop target -Start target +Stop target @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param targetId Target ID or Name - @return ApiStartTargetRequest + @return ApiStopTargetRequest */ -func (a *TargetAPIService) StartTarget(ctx context.Context, targetId string) ApiStartTargetRequest { - return ApiStartTargetRequest{ +func (a *TargetAPIService) StopTarget(ctx context.Context, targetId string) ApiStopTargetRequest { + return ApiStopTargetRequest{ ApiService: a, ctx: ctx, targetId: targetId, @@ -874,19 +862,19 @@ func (a *TargetAPIService) StartTarget(ctx context.Context, targetId string) Api } // Execute executes the request -func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Response, error) { +func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StartTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopTarget") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/start" + localVarPath := localBasePath + "/target/{targetId}/stop" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) @@ -952,27 +940,34 @@ func (a *TargetAPIService) StartTargetExecute(r ApiStartTargetRequest) (*http.Re return localVarHTTPResponse, nil } -type ApiStopTargetRequest struct { - ctx context.Context - ApiService *TargetAPIService - targetId string +type ApiUpdateTargetMetadataRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string + targetMetadata *UpdateTargetMetadataDTO } -func (r ApiStopTargetRequest) Execute() (*http.Response, error) { - return r.ApiService.StopTargetExecute(r) +// Target Metadata +func (r ApiUpdateTargetMetadataRequest) TargetMetadata(targetMetadata UpdateTargetMetadataDTO) ApiUpdateTargetMetadataRequest { + r.targetMetadata = &targetMetadata + return r +} + +func (r ApiUpdateTargetMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateTargetMetadataExecute(r) } /* -StopTarget Stop target +UpdateTargetMetadata Update target metadata -Stop target +Update target metadata @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param targetId Target ID or Name - @return ApiStopTargetRequest + @param targetId Target ID + @return ApiUpdateTargetMetadataRequest */ -func (a *TargetAPIService) StopTarget(ctx context.Context, targetId string) ApiStopTargetRequest { - return ApiStopTargetRequest{ +func (a *TargetAPIService) UpdateTargetMetadata(ctx context.Context, targetId string) ApiUpdateTargetMetadataRequest { + return ApiUpdateTargetMetadataRequest{ ApiService: a, ctx: ctx, targetId: targetId, @@ -980,24 +975,27 @@ func (a *TargetAPIService) StopTarget(ctx context.Context, targetId string) ApiS } // Execute executes the request -func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Response, error) { +func (a *TargetAPIService) UpdateTargetMetadataExecute(r ApiUpdateTargetMetadataRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.StopTarget") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.UpdateTargetMetadata") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target/{targetId}/stop" + localVarPath := localBasePath + "/target/{targetId}/metadata" localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.targetMetadata == nil { + return nil, reportError("targetMetadata is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -1016,6 +1014,8 @@ func (a *TargetAPIService) StopTargetExecute(r ApiStopTargetRequest) (*http.Resp if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.targetMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/api_target_config.go b/pkg/apiclient/api_target_config.go index 16a800a966..5b66eca67c 100644 --- a/pkg/apiclient/api_target_config.go +++ b/pkg/apiclient/api_target_config.go @@ -22,39 +22,39 @@ import ( // TargetConfigAPIService TargetConfigAPI service type TargetConfigAPIService service -type ApiAddTargetConfigRequest struct { +type ApiCreateTargetConfigRequest struct { ctx context.Context ApiService *TargetConfigAPIService - targetConfig *AddTargetConfigDTO + targetConfig *CreateTargetConfigDTO showOptions *bool } -// Target config to add -func (r ApiAddTargetConfigRequest) TargetConfig(targetConfig AddTargetConfigDTO) ApiAddTargetConfigRequest { +// Target config to create +func (r ApiCreateTargetConfigRequest) TargetConfig(targetConfig CreateTargetConfigDTO) ApiCreateTargetConfigRequest { r.targetConfig = &targetConfig return r } // Show target config options -func (r ApiAddTargetConfigRequest) ShowOptions(showOptions bool) ApiAddTargetConfigRequest { +func (r ApiCreateTargetConfigRequest) ShowOptions(showOptions bool) ApiCreateTargetConfigRequest { r.showOptions = &showOptions return r } -func (r ApiAddTargetConfigRequest) Execute() (*TargetConfig, *http.Response, error) { - return r.ApiService.AddTargetConfigExecute(r) +func (r ApiCreateTargetConfigRequest) Execute() (*TargetConfig, *http.Response, error) { + return r.ApiService.CreateTargetConfigExecute(r) } /* -AddTargetConfig Add a target config +CreateTargetConfig Create a target config -Add a target config +Create a target config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiAddTargetConfigRequest + @return ApiCreateTargetConfigRequest */ -func (a *TargetConfigAPIService) AddTargetConfig(ctx context.Context) ApiAddTargetConfigRequest { - return ApiAddTargetConfigRequest{ +func (a *TargetConfigAPIService) CreateTargetConfig(ctx context.Context) ApiCreateTargetConfigRequest { + return ApiCreateTargetConfigRequest{ ApiService: a, ctx: ctx, } @@ -63,15 +63,15 @@ func (a *TargetConfigAPIService) AddTargetConfig(ctx context.Context) ApiAddTarg // Execute executes the request // // @return TargetConfig -func (a *TargetConfigAPIService) AddTargetConfigExecute(r ApiAddTargetConfigRequest) (*TargetConfig, *http.Response, error) { +func (a *TargetConfigAPIService) CreateTargetConfigExecute(r ApiCreateTargetConfigRequest) (*TargetConfig, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut + localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile localVarReturnValue *TargetConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.AddTargetConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.CreateTargetConfig") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } @@ -158,62 +158,53 @@ func (a *TargetConfigAPIService) AddTargetConfigExecute(r ApiAddTargetConfigRequ return localVarReturnValue, localVarHTTPResponse, nil } -type ApiListTargetConfigsRequest struct { - ctx context.Context - ApiService *TargetConfigAPIService - showOptions *bool -} - -// Show target config options -func (r ApiListTargetConfigsRequest) ShowOptions(showOptions bool) ApiListTargetConfigsRequest { - r.showOptions = &showOptions - return r +type ApiDeleteTargetConfigRequest struct { + ctx context.Context + ApiService *TargetConfigAPIService + configId string } -func (r ApiListTargetConfigsRequest) Execute() ([]TargetConfig, *http.Response, error) { - return r.ApiService.ListTargetConfigsExecute(r) +func (r ApiDeleteTargetConfigRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteTargetConfigExecute(r) } /* -ListTargetConfigs List target configs +DeleteTargetConfig Delete a target config -List target configs +Delete a target config @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListTargetConfigsRequest + @param configId Target Config Id + @return ApiDeleteTargetConfigRequest */ -func (a *TargetConfigAPIService) ListTargetConfigs(ctx context.Context) ApiListTargetConfigsRequest { - return ApiListTargetConfigsRequest{ +func (a *TargetConfigAPIService) DeleteTargetConfig(ctx context.Context, configId string) ApiDeleteTargetConfigRequest { + return ApiDeleteTargetConfigRequest{ ApiService: a, ctx: ctx, + configId: configId, } } // Execute executes the request -// -// @return []TargetConfig -func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigsRequest) ([]TargetConfig, *http.Response, error) { +func (a *TargetConfigAPIService) DeleteTargetConfigExecute(r ApiDeleteTargetConfigRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue []TargetConfig + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.ListTargetConfigs") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.DeleteTargetConfig") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target-config" + localVarPath := localBasePath + "/target-config/{configId}" + localVarPath = strings.Replace(localVarPath, "{"+"configId"+"}", url.PathEscape(parameterValueToString(r.configId, "configId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.showOptions != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "showOptions", r.showOptions, "") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -224,7 +215,7 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -247,19 +238,19 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -267,68 +258,68 @@ func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigs body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr - } + return localVarHTTPResponse, nil +} - return localVarReturnValue, localVarHTTPResponse, nil +type ApiListTargetConfigsRequest struct { + ctx context.Context + ApiService *TargetConfigAPIService + showOptions *bool } -type ApiRemoveTargetConfigRequest struct { - ctx context.Context - ApiService *TargetConfigAPIService - configId string +// Show target config options +func (r ApiListTargetConfigsRequest) ShowOptions(showOptions bool) ApiListTargetConfigsRequest { + r.showOptions = &showOptions + return r } -func (r ApiRemoveTargetConfigRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveTargetConfigExecute(r) +func (r ApiListTargetConfigsRequest) Execute() ([]TargetConfig, *http.Response, error) { + return r.ApiService.ListTargetConfigsExecute(r) } /* -RemoveTargetConfig Remove a target config +ListTargetConfigs List target configs -Remove a target config +List target configs @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param configId Target Config Id - @return ApiRemoveTargetConfigRequest + @return ApiListTargetConfigsRequest */ -func (a *TargetConfigAPIService) RemoveTargetConfig(ctx context.Context, configId string) ApiRemoveTargetConfigRequest { - return ApiRemoveTargetConfigRequest{ +func (a *TargetConfigAPIService) ListTargetConfigs(ctx context.Context) ApiListTargetConfigsRequest { + return ApiListTargetConfigsRequest{ ApiService: a, ctx: ctx, - configId: configId, } } // Execute executes the request -func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConfigRequest) (*http.Response, error) { +// +// @return []TargetConfig +func (a *TargetConfigAPIService) ListTargetConfigsExecute(r ApiListTargetConfigsRequest) ([]TargetConfig, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []TargetConfig ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.RemoveTargetConfig") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetConfigAPIService.ListTargetConfigs") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/target-config/{configId}" - localVarPath = strings.Replace(localVarPath, "{"+"configId"+"}", url.PathEscape(parameterValueToString(r.configId, "configId")), -1) + localVarPath := localBasePath + "/target-config" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.showOptions != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "showOptions", r.showOptions, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -339,7 +330,7 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -362,19 +353,19 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -382,8 +373,17 @@ func (a *TargetConfigAPIService) RemoveTargetConfigExecute(r ApiRemoveTargetConf body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil } diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index a390d4f43f..6149122789 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -148,27 +148,34 @@ func (a *WorkspaceAPIService) CreateWorkspaceExecute(r ApiCreateWorkspaceRequest return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetWorkspaceRequest struct { +type ApiDeleteWorkspaceRequest struct { ctx context.Context ApiService *WorkspaceAPIService workspaceId string + force *bool } -func (r ApiGetWorkspaceRequest) Execute() (*WorkspaceDTO, *http.Response, error) { - return r.ApiService.GetWorkspaceExecute(r) +// Force +func (r ApiDeleteWorkspaceRequest) Force(force bool) ApiDeleteWorkspaceRequest { + r.force = &force + return r +} + +func (r ApiDeleteWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteWorkspaceExecute(r) } /* -GetWorkspace Get workspace info +DeleteWorkspace Delete workspace -Get workspace info +Delete workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name - @return ApiGetWorkspaceRequest + @param workspaceId Workspace ID + @return ApiDeleteWorkspaceRequest */ -func (a *WorkspaceAPIService) GetWorkspace(ctx context.Context, workspaceId string) ApiGetWorkspaceRequest { - return ApiGetWorkspaceRequest{ +func (a *WorkspaceAPIService) DeleteWorkspace(ctx context.Context, workspaceId string) ApiDeleteWorkspaceRequest { + return ApiDeleteWorkspaceRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, @@ -176,19 +183,16 @@ func (a *WorkspaceAPIService) GetWorkspace(ctx context.Context, workspaceId stri } // Execute executes the request -// -// @return WorkspaceDTO -func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*WorkspaceDTO, *http.Response, error) { +func (a *WorkspaceAPIService) DeleteWorkspaceExecute(r ApiDeleteWorkspaceRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodGet - localVarPostBody interface{} - formFiles []formFile - localVarReturnValue *WorkspaceDTO + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.GetWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.DeleteWorkspace") if err != nil { - return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + return nil, &GenericOpenAPIError{error: err.Error()} } localVarPath := localBasePath + "/workspace/{workspaceId}" @@ -198,6 +202,9 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.force != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "force", r.force, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -208,7 +215,7 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -231,19 +238,19 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return localVarReturnValue, nil, err + return nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarReturnValue, localVarHTTPResponse, err + return localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -251,62 +258,57 @@ func (a *WorkspaceAPIService) GetWorkspaceExecute(r ApiGetWorkspaceRequest) (*Wo body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarReturnValue, localVarHTTPResponse, newErr - } - - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) - if err != nil { - newErr := &GenericOpenAPIError{ - body: localVarBody, - error: err.Error(), - } - return localVarReturnValue, localVarHTTPResponse, newErr + return localVarHTTPResponse, newErr } - return localVarReturnValue, localVarHTTPResponse, nil + return localVarHTTPResponse, nil } -type ApiListWorkspacesRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService +type ApiFindWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string } -func (r ApiListWorkspacesRequest) Execute() ([]WorkspaceDTO, *http.Response, error) { - return r.ApiService.ListWorkspacesExecute(r) +func (r ApiFindWorkspaceRequest) Execute() (*WorkspaceDTO, *http.Response, error) { + return r.ApiService.FindWorkspaceExecute(r) } /* -ListWorkspaces List workspaces +FindWorkspace Find workspace -List workspaces +Find workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiListWorkspacesRequest + @param workspaceId Workspace ID or Name + @return ApiFindWorkspaceRequest */ -func (a *WorkspaceAPIService) ListWorkspaces(ctx context.Context) ApiListWorkspacesRequest { - return ApiListWorkspacesRequest{ - ApiService: a, - ctx: ctx, +func (a *WorkspaceAPIService) FindWorkspace(ctx context.Context, workspaceId string) ApiFindWorkspaceRequest { + return ApiFindWorkspaceRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, } } // Execute executes the request // -// @return []WorkspaceDTO -func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) ([]WorkspaceDTO, *http.Response, error) { +// @return WorkspaceDTO +func (a *WorkspaceAPIService) FindWorkspaceExecute(r ApiFindWorkspaceRequest) (*WorkspaceDTO, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} formFiles []formFile - localVarReturnValue []WorkspaceDTO + localVarReturnValue *WorkspaceDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.ListWorkspaces") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.FindWorkspace") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace" + localVarPath := localBasePath + "/workspace/{workspaceId}" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -380,63 +382,52 @@ func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) return localVarReturnValue, localVarHTTPResponse, nil } -type ApiRemoveWorkspaceRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - force *bool -} - -// Force -func (r ApiRemoveWorkspaceRequest) Force(force bool) ApiRemoveWorkspaceRequest { - r.force = &force - return r +type ApiListWorkspacesRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService } -func (r ApiRemoveWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.RemoveWorkspaceExecute(r) +func (r ApiListWorkspacesRequest) Execute() ([]WorkspaceDTO, *http.Response, error) { + return r.ApiService.ListWorkspacesExecute(r) } /* -RemoveWorkspace Remove workspace +ListWorkspaces List workspaces -Remove workspace +List workspaces @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID - @return ApiRemoveWorkspaceRequest + @return ApiListWorkspacesRequest */ -func (a *WorkspaceAPIService) RemoveWorkspace(ctx context.Context, workspaceId string) ApiRemoveWorkspaceRequest { - return ApiRemoveWorkspaceRequest{ - ApiService: a, - ctx: ctx, - workspaceId: workspaceId, +func (a *WorkspaceAPIService) ListWorkspaces(ctx context.Context) ApiListWorkspacesRequest { + return ApiListWorkspacesRequest{ + ApiService: a, + ctx: ctx, } } // Execute executes the request -func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest) (*http.Response, error) { +// +// @return []WorkspaceDTO +func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) ([]WorkspaceDTO, *http.Response, error) { var ( - localVarHTTPMethod = http.MethodDelete - localVarPostBody interface{} - formFiles []formFile + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue []WorkspaceDTO ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.RemoveWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.ListWorkspaces") if err != nil { - return nil, &GenericOpenAPIError{error: err.Error()} + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}" - localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + localVarPath := localBasePath + "/workspace" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.force != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "force", r.force, "") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -447,7 +438,7 @@ func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -470,19 +461,19 @@ func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest } req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) if err != nil { - return nil, err + return localVarReturnValue, nil, err } localVarHTTPResponse, err := a.client.callAPI(req) if err != nil || localVarHTTPResponse == nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) localVarHTTPResponse.Body.Close() localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) if err != nil { - return localVarHTTPResponse, err + return localVarReturnValue, localVarHTTPResponse, err } if localVarHTTPResponse.StatusCode >= 300 { @@ -490,40 +481,42 @@ func (a *WorkspaceAPIService) RemoveWorkspaceExecute(r ApiRemoveWorkspaceRequest body: localVarBody, error: localVarHTTPResponse.Status, } - return localVarHTTPResponse, newErr + return localVarReturnValue, localVarHTTPResponse, newErr } - return localVarHTTPResponse, nil -} + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } -type ApiSetWorkspaceMetadataRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string - workspaceMetadata *UpdateWorkspaceMetadataDTO + return localVarReturnValue, localVarHTTPResponse, nil } -// Workspace Metadata -func (r ApiSetWorkspaceMetadataRequest) WorkspaceMetadata(workspaceMetadata UpdateWorkspaceMetadataDTO) ApiSetWorkspaceMetadataRequest { - r.workspaceMetadata = &workspaceMetadata - return r +type ApiStartWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string } -func (r ApiSetWorkspaceMetadataRequest) Execute() (*http.Response, error) { - return r.ApiService.SetWorkspaceMetadataExecute(r) +func (r ApiStartWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.StartWorkspaceExecute(r) } /* -SetWorkspaceMetadata Set workspace metadata +StartWorkspace Start workspace -Set workspace metadata +Start workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID - @return ApiSetWorkspaceMetadataRequest + @param workspaceId Workspace ID or Name + @return ApiStartWorkspaceRequest */ -func (a *WorkspaceAPIService) SetWorkspaceMetadata(ctx context.Context, workspaceId string) ApiSetWorkspaceMetadataRequest { - return ApiSetWorkspaceMetadataRequest{ +func (a *WorkspaceAPIService) StartWorkspace(ctx context.Context, workspaceId string) ApiStartWorkspaceRequest { + return ApiStartWorkspaceRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, @@ -531,27 +524,24 @@ func (a *WorkspaceAPIService) SetWorkspaceMetadata(ctx context.Context, workspac } // Execute executes the request -func (a *WorkspaceAPIService) SetWorkspaceMetadataExecute(r ApiSetWorkspaceMetadataRequest) (*http.Response, error) { +func (a *WorkspaceAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.SetWorkspaceMetadata") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StartWorkspace") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/metadata" + localVarPath := localBasePath + "/workspace/{workspaceId}/start" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.workspaceMetadata == nil { - return nil, reportError("workspaceMetadata is required and must be specified") - } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -570,8 +560,6 @@ func (a *WorkspaceAPIService) SetWorkspaceMetadataExecute(r ApiSetWorkspaceMetad if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.workspaceMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -614,27 +602,27 @@ func (a *WorkspaceAPIService) SetWorkspaceMetadataExecute(r ApiSetWorkspaceMetad return localVarHTTPResponse, nil } -type ApiStartWorkspaceRequest struct { +type ApiStopWorkspaceRequest struct { ctx context.Context ApiService *WorkspaceAPIService workspaceId string } -func (r ApiStartWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.StartWorkspaceExecute(r) +func (r ApiStopWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.StopWorkspaceExecute(r) } /* -StartWorkspace Start workspace +StopWorkspace Stop workspace -Start workspace +Stop workspace @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param workspaceId Workspace ID or Name - @return ApiStartWorkspaceRequest + @return ApiStopWorkspaceRequest */ -func (a *WorkspaceAPIService) StartWorkspace(ctx context.Context, workspaceId string) ApiStartWorkspaceRequest { - return ApiStartWorkspaceRequest{ +func (a *WorkspaceAPIService) StopWorkspace(ctx context.Context, workspaceId string) ApiStopWorkspaceRequest { + return ApiStopWorkspaceRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, @@ -642,19 +630,19 @@ func (a *WorkspaceAPIService) StartWorkspace(ctx context.Context, workspaceId st } // Execute executes the request -func (a *WorkspaceAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) (*http.Response, error) { +func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StartWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StopWorkspace") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/start" + localVarPath := localBasePath + "/workspace/{workspaceId}/stop" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) @@ -720,27 +708,34 @@ func (a *WorkspaceAPIService) StartWorkspaceExecute(r ApiStartWorkspaceRequest) return localVarHTTPResponse, nil } -type ApiStopWorkspaceRequest struct { - ctx context.Context - ApiService *WorkspaceAPIService - workspaceId string +type ApiUpdateWorkspaceMetadataRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + workspaceMetadata *UpdateWorkspaceMetadataDTO } -func (r ApiStopWorkspaceRequest) Execute() (*http.Response, error) { - return r.ApiService.StopWorkspaceExecute(r) +// Workspace Metadata +func (r ApiUpdateWorkspaceMetadataRequest) WorkspaceMetadata(workspaceMetadata UpdateWorkspaceMetadataDTO) ApiUpdateWorkspaceMetadataRequest { + r.workspaceMetadata = &workspaceMetadata + return r +} + +func (r ApiUpdateWorkspaceMetadataRequest) Execute() (*http.Response, error) { + return r.ApiService.UpdateWorkspaceMetadataExecute(r) } /* -StopWorkspace Stop workspace +UpdateWorkspaceMetadata Update workspace metadata -Stop workspace +Update workspace metadata @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param workspaceId Workspace ID or Name - @return ApiStopWorkspaceRequest + @param workspaceId Workspace ID + @return ApiUpdateWorkspaceMetadataRequest */ -func (a *WorkspaceAPIService) StopWorkspace(ctx context.Context, workspaceId string) ApiStopWorkspaceRequest { - return ApiStopWorkspaceRequest{ +func (a *WorkspaceAPIService) UpdateWorkspaceMetadata(ctx context.Context, workspaceId string) ApiUpdateWorkspaceMetadataRequest { + return ApiUpdateWorkspaceMetadataRequest{ ApiService: a, ctx: ctx, workspaceId: workspaceId, @@ -748,24 +743,27 @@ func (a *WorkspaceAPIService) StopWorkspace(ctx context.Context, workspaceId str } // Execute executes the request -func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (*http.Response, error) { +func (a *WorkspaceAPIService) UpdateWorkspaceMetadataExecute(r ApiUpdateWorkspaceMetadataRequest) (*http.Response, error) { var ( localVarHTTPMethod = http.MethodPost localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.StopWorkspace") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.UpdateWorkspaceMetadata") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace/{workspaceId}/stop" + localVarPath := localBasePath + "/workspace/{workspaceId}/metadata" localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.workspaceMetadata == nil { + return nil, reportError("workspaceMetadata is required and must be specified") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -784,6 +782,8 @@ func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (* if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.workspaceMetadata if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/api_workspace_template.go b/pkg/apiclient/api_workspace_template.go index eee695d509..a1ad8eb23f 100644 --- a/pkg/apiclient/api_workspace_template.go +++ b/pkg/apiclient/api_workspace_template.go @@ -138,37 +138,37 @@ func (a *WorkspaceTemplateAPIService) DeleteWorkspaceTemplateExecute(r ApiDelete return localVarHTTPResponse, nil } -type ApiGetDefaultWorkspaceTemplateRequest struct { - ctx context.Context - ApiService *WorkspaceTemplateAPIService - gitUrl string +type ApiFindWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + templateName string } -func (r ApiGetDefaultWorkspaceTemplateRequest) Execute() (*WorkspaceTemplate, *http.Response, error) { - return r.ApiService.GetDefaultWorkspaceTemplateExecute(r) +func (r ApiFindWorkspaceTemplateRequest) Execute() (*WorkspaceTemplate, *http.Response, error) { + return r.ApiService.FindWorkspaceTemplateExecute(r) } /* -GetDefaultWorkspaceTemplate Get workspace templates by git url +FindWorkspaceTemplate Find a workspace template -Get workspace templates by git url +Find a workspace template @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param gitUrl Git URL - @return ApiGetDefaultWorkspaceTemplateRequest + @param templateName Template name + @return ApiFindWorkspaceTemplateRequest */ -func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplate(ctx context.Context, gitUrl string) ApiGetDefaultWorkspaceTemplateRequest { - return ApiGetDefaultWorkspaceTemplateRequest{ - ApiService: a, - ctx: ctx, - gitUrl: gitUrl, +func (a *WorkspaceTemplateAPIService) FindWorkspaceTemplate(ctx context.Context, templateName string) ApiFindWorkspaceTemplateRequest { + return ApiFindWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + templateName: templateName, } } // Execute executes the request // // @return WorkspaceTemplate -func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplateExecute(r ApiGetDefaultWorkspaceTemplateRequest) (*WorkspaceTemplate, *http.Response, error) { +func (a *WorkspaceTemplateAPIService) FindWorkspaceTemplateExecute(r ApiFindWorkspaceTemplateRequest) (*WorkspaceTemplate, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -176,13 +176,13 @@ func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplateExecute(r ApiGe localVarReturnValue *WorkspaceTemplate ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.GetDefaultWorkspaceTemplate") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.FindWorkspaceTemplate") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-template/default/{gitUrl}" - localVarPath = strings.Replace(localVarPath, "{"+"gitUrl"+"}", url.PathEscape(parameterValueToString(r.gitUrl, "gitUrl")), -1) + localVarPath := localBasePath + "/workspace-template/{templateName}" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -198,7 +198,7 @@ func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplateExecute(r ApiGe } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"application/json"} + localVarHTTPHeaderAccepts := []string{"*/*"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -256,37 +256,37 @@ func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplateExecute(r ApiGe return localVarReturnValue, localVarHTTPResponse, nil } -type ApiGetWorkspaceTemplateRequest struct { - ctx context.Context - ApiService *WorkspaceTemplateAPIService - templateName string +type ApiGetDefaultWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + gitUrl string } -func (r ApiGetWorkspaceTemplateRequest) Execute() (*WorkspaceTemplate, *http.Response, error) { - return r.ApiService.GetWorkspaceTemplateExecute(r) +func (r ApiGetDefaultWorkspaceTemplateRequest) Execute() (*WorkspaceTemplate, *http.Response, error) { + return r.ApiService.GetDefaultWorkspaceTemplateExecute(r) } /* -GetWorkspaceTemplate Get workspace template data +GetDefaultWorkspaceTemplate Get default workspace templates by git url -Get workspace template data +Get default workspace templates by git url @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param templateName Template name - @return ApiGetWorkspaceTemplateRequest + @param gitUrl Git URL + @return ApiGetDefaultWorkspaceTemplateRequest */ -func (a *WorkspaceTemplateAPIService) GetWorkspaceTemplate(ctx context.Context, templateName string) ApiGetWorkspaceTemplateRequest { - return ApiGetWorkspaceTemplateRequest{ - ApiService: a, - ctx: ctx, - templateName: templateName, +func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplate(ctx context.Context, gitUrl string) ApiGetDefaultWorkspaceTemplateRequest { + return ApiGetDefaultWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + gitUrl: gitUrl, } } // Execute executes the request // // @return WorkspaceTemplate -func (a *WorkspaceTemplateAPIService) GetWorkspaceTemplateExecute(r ApiGetWorkspaceTemplateRequest) (*WorkspaceTemplate, *http.Response, error) { +func (a *WorkspaceTemplateAPIService) GetDefaultWorkspaceTemplateExecute(r ApiGetDefaultWorkspaceTemplateRequest) (*WorkspaceTemplate, *http.Response, error) { var ( localVarHTTPMethod = http.MethodGet localVarPostBody interface{} @@ -294,13 +294,13 @@ func (a *WorkspaceTemplateAPIService) GetWorkspaceTemplateExecute(r ApiGetWorksp localVarReturnValue *WorkspaceTemplate ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.GetWorkspaceTemplate") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.GetDefaultWorkspaceTemplate") if err != nil { return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-template/{templateName}" - localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) + localVarPath := localBasePath + "/workspace-template/default/{gitUrl}" + localVarPath = strings.Replace(localVarPath, "{"+"gitUrl"+"}", url.PathEscape(parameterValueToString(r.gitUrl, "gitUrl")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -316,7 +316,7 @@ func (a *WorkspaceTemplateAPIService) GetWorkspaceTemplateExecute(r ApiGetWorksp } // to determine the Accept header - localVarHTTPHeaderAccepts := []string{"*/*"} + localVarHTTPHeaderAccepts := []string{"application/json"} // set Accept header localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) @@ -488,55 +488,61 @@ func (a *WorkspaceTemplateAPIService) ListWorkspaceTemplatesExecute(r ApiListWor return localVarReturnValue, localVarHTTPResponse, nil } -type ApiSetDefaultWorkspaceTemplateRequest struct { - ctx context.Context - ApiService *WorkspaceTemplateAPIService - templateName string +type ApiSaveWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + workspaceTemplate *CreateWorkspaceTemplateDTO } -func (r ApiSetDefaultWorkspaceTemplateRequest) Execute() (*http.Response, error) { - return r.ApiService.SetDefaultWorkspaceTemplateExecute(r) +// Workspace template +func (r ApiSaveWorkspaceTemplateRequest) WorkspaceTemplate(workspaceTemplate CreateWorkspaceTemplateDTO) ApiSaveWorkspaceTemplateRequest { + r.workspaceTemplate = &workspaceTemplate + return r +} + +func (r ApiSaveWorkspaceTemplateRequest) Execute() (*http.Response, error) { + return r.ApiService.SaveWorkspaceTemplateExecute(r) } /* -SetDefaultWorkspaceTemplate Set workspace template to default +SaveWorkspaceTemplate Set workspace template data -Set workspace template to default +Set workspace template data @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @param templateName Template name - @return ApiSetDefaultWorkspaceTemplateRequest + @return ApiSaveWorkspaceTemplateRequest */ -func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplate(ctx context.Context, templateName string) ApiSetDefaultWorkspaceTemplateRequest { - return ApiSetDefaultWorkspaceTemplateRequest{ - ApiService: a, - ctx: ctx, - templateName: templateName, +func (a *WorkspaceTemplateAPIService) SaveWorkspaceTemplate(ctx context.Context) ApiSaveWorkspaceTemplateRequest { + return ApiSaveWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, } } // Execute executes the request -func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplateExecute(r ApiSetDefaultWorkspaceTemplateRequest) (*http.Response, error) { +func (a *WorkspaceTemplateAPIService) SaveWorkspaceTemplateExecute(r ApiSaveWorkspaceTemplateRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodPatch + localVarHTTPMethod = http.MethodPut localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.SetDefaultWorkspaceTemplate") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.SaveWorkspaceTemplate") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-template/{templateName}/set-default" - localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) + localVarPath := localBasePath + "/workspace-template" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.workspaceTemplate == nil { + return nil, reportError("workspaceTemplate is required and must be specified") + } // to determine the Content-Type header - localVarHTTPContentTypes := []string{} + localVarHTTPContentTypes := []string{"application/json"} // set Content-Type header localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) @@ -552,6 +558,8 @@ func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplateExecute(r ApiSe if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } + // body params + localVarPostBody = r.workspaceTemplate if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { @@ -594,61 +602,55 @@ func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplateExecute(r ApiSe return localVarHTTPResponse, nil } -type ApiSetWorkspaceTemplateRequest struct { - ctx context.Context - ApiService *WorkspaceTemplateAPIService - workspaceTemplate *CreateWorkspaceTemplateDTO -} - -// Workspace template -func (r ApiSetWorkspaceTemplateRequest) WorkspaceTemplate(workspaceTemplate CreateWorkspaceTemplateDTO) ApiSetWorkspaceTemplateRequest { - r.workspaceTemplate = &workspaceTemplate - return r +type ApiSetDefaultWorkspaceTemplateRequest struct { + ctx context.Context + ApiService *WorkspaceTemplateAPIService + templateName string } -func (r ApiSetWorkspaceTemplateRequest) Execute() (*http.Response, error) { - return r.ApiService.SetWorkspaceTemplateExecute(r) +func (r ApiSetDefaultWorkspaceTemplateRequest) Execute() (*http.Response, error) { + return r.ApiService.SetDefaultWorkspaceTemplateExecute(r) } /* -SetWorkspaceTemplate Set workspace template data +SetDefaultWorkspaceTemplate Set workspace template to default -Set workspace template data +Set workspace template to default @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - @return ApiSetWorkspaceTemplateRequest + @param templateName Template name + @return ApiSetDefaultWorkspaceTemplateRequest */ -func (a *WorkspaceTemplateAPIService) SetWorkspaceTemplate(ctx context.Context) ApiSetWorkspaceTemplateRequest { - return ApiSetWorkspaceTemplateRequest{ - ApiService: a, - ctx: ctx, +func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplate(ctx context.Context, templateName string) ApiSetDefaultWorkspaceTemplateRequest { + return ApiSetDefaultWorkspaceTemplateRequest{ + ApiService: a, + ctx: ctx, + templateName: templateName, } } // Execute executes the request -func (a *WorkspaceTemplateAPIService) SetWorkspaceTemplateExecute(r ApiSetWorkspaceTemplateRequest) (*http.Response, error) { +func (a *WorkspaceTemplateAPIService) SetDefaultWorkspaceTemplateExecute(r ApiSetDefaultWorkspaceTemplateRequest) (*http.Response, error) { var ( - localVarHTTPMethod = http.MethodPut + localVarHTTPMethod = http.MethodPatch localVarPostBody interface{} formFiles []formFile ) - localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.SetWorkspaceTemplate") + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceTemplateAPIService.SetDefaultWorkspaceTemplate") if err != nil { return nil, &GenericOpenAPIError{error: err.Error()} } - localVarPath := localBasePath + "/workspace-template" + localVarPath := localBasePath + "/workspace-template/{templateName}/set-default" + localVarPath = strings.Replace(localVarPath, "{"+"templateName"+"}", url.PathEscape(parameterValueToString(r.templateName, "templateName")), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} - if r.workspaceTemplate == nil { - return nil, reportError("workspaceTemplate is required and must be specified") - } // to determine the Content-Type header - localVarHTTPContentTypes := []string{"application/json"} + localVarHTTPContentTypes := []string{} // set Content-Type header localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) @@ -664,8 +666,6 @@ func (a *WorkspaceTemplateAPIService) SetWorkspaceTemplateExecute(r ApiSetWorksp if localVarHTTPHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept } - // body params - localVarPostBody = r.workspaceTemplate if r.ctx != nil { // API Key Authentication if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { diff --git a/pkg/apiclient/docs/ApiKeyAPI.md b/pkg/apiclient/docs/ApiKeyAPI.md index 3739ec7a67..d9ab2fa437 100644 --- a/pkg/apiclient/docs/ApiKeyAPI.md +++ b/pkg/apiclient/docs/ApiKeyAPI.md @@ -4,17 +4,17 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GenerateApiKey**](ApiKeyAPI.md#GenerateApiKey) | **Post** /apikey/{apiKeyName} | Generate an API key +[**CreateApiKey**](ApiKeyAPI.md#CreateApiKey) | **Post** /apikey/{apiKeyName} | Create an API key +[**DeleteApiKey**](ApiKeyAPI.md#DeleteApiKey) | **Delete** /apikey/{apiKeyName} | Delete API key [**ListClientApiKeys**](ApiKeyAPI.md#ListClientApiKeys) | **Get** /apikey | List API keys -[**RevokeApiKey**](ApiKeyAPI.md#RevokeApiKey) | **Delete** /apikey/{apiKeyName} | Revoke API key -## GenerateApiKey +## CreateApiKey -> string GenerateApiKey(ctx, apiKeyName).Execute() +> string CreateApiKey(ctx, apiKeyName).Execute() -Generate an API key +Create an API key @@ -35,13 +35,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ApiKeyAPI.GenerateApiKey(context.Background(), apiKeyName).Execute() + resp, r, err := apiClient.ApiKeyAPI.CreateApiKey(context.Background(), apiKeyName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.GenerateApiKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.CreateApiKey``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GenerateApiKey`: string - fmt.Fprintf(os.Stdout, "Response from `ApiKeyAPI.GenerateApiKey`: %v\n", resp) + // response from `CreateApiKey`: string + fmt.Fprintf(os.Stdout, "Response from `ApiKeyAPI.CreateApiKey`: %v\n", resp) } ``` @@ -55,7 +55,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGenerateApiKeyRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiCreateApiKeyRequest struct via the builder pattern Name | Type | Description | Notes @@ -80,11 +80,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## ListClientApiKeys +## DeleteApiKey -> []ApiKeyViewDTO ListClientApiKeys(ctx).Execute() +> DeleteApiKey(ctx, apiKeyName).Execute() -List API keys +Delete API key @@ -101,31 +101,38 @@ import ( ) func main() { + apiKeyName := "apiKeyName_example" // string | API key name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ApiKeyAPI.ListClientApiKeys(context.Background()).Execute() + r, err := apiClient.ApiKeyAPI.DeleteApiKey(context.Background(), apiKeyName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.ListClientApiKeys``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.DeleteApiKey``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListClientApiKeys`: []ApiKeyViewDTO - fmt.Fprintf(os.Stdout, "Response from `ApiKeyAPI.ListClientApiKeys`: %v\n", resp) } ``` ### Path Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**apiKeyName** | **string** | API key name | ### Other Parameters -Other parameters are passed through a pointer to a apiListClientApiKeysRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteApiKeyRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- ### Return type -[**[]ApiKeyViewDTO**](ApiKeyViewDTO.md) + (empty response body) ### Authorization @@ -134,18 +141,18 @@ Other parameters are passed through a pointer to a apiListClientApiKeysRequest s ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## RevokeApiKey +## ListClientApiKeys -> RevokeApiKey(ctx, apiKeyName).Execute() +> []ApiKeyViewDTO ListClientApiKeys(ctx).Execute() -Revoke API key +List API keys @@ -162,38 +169,31 @@ import ( ) func main() { - apiKeyName := "apiKeyName_example" // string | API key name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.ApiKeyAPI.RevokeApiKey(context.Background(), apiKeyName).Execute() + resp, r, err := apiClient.ApiKeyAPI.ListClientApiKeys(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.RevokeApiKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ApiKeyAPI.ListClientApiKeys``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListClientApiKeys`: []ApiKeyViewDTO + fmt.Fprintf(os.Stdout, "Response from `ApiKeyAPI.ListClientApiKeys`: %v\n", resp) } ``` ### Path Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**apiKeyName** | **string** | API key name | +This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiRevokeApiKeyRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- +Other parameters are passed through a pointer to a apiListClientApiKeysRequest struct via the builder pattern ### Return type - (empty response body) +[**[]ApiKeyViewDTO**](ApiKeyViewDTO.md) ### Authorization @@ -202,7 +202,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) diff --git a/pkg/apiclient/docs/BuildAPI.md b/pkg/apiclient/docs/BuildAPI.md index 6f3085334b..893f4a9c1c 100644 --- a/pkg/apiclient/docs/BuildAPI.md +++ b/pkg/apiclient/docs/BuildAPI.md @@ -8,7 +8,7 @@ Method | HTTP request | Description [**DeleteAllBuilds**](BuildAPI.md#DeleteAllBuilds) | **Delete** /build | Delete ALL builds [**DeleteBuild**](BuildAPI.md#DeleteBuild) | **Delete** /build/{buildId} | Delete build [**DeleteBuildsFromPrebuild**](BuildAPI.md#DeleteBuildsFromPrebuild) | **Delete** /build/prebuild/{prebuildId} | Delete builds -[**GetBuild**](BuildAPI.md#GetBuild) | **Get** /build/{buildId} | Get build data +[**FindBuild**](BuildAPI.md#FindBuild) | **Get** /build/{buildId} | Find build [**ListBuilds**](BuildAPI.md#ListBuilds) | **Get** /build | List builds [**ListSuccessfulBuilds**](BuildAPI.md#ListSuccessfulBuilds) | **Get** /build/successful/{repoUrl} | List successful builds for Git repository @@ -284,11 +284,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetBuild +## FindBuild -> BuildDTO GetBuild(ctx, buildId).Execute() +> BuildDTO FindBuild(ctx, buildId).Execute() -Get build data +Find build @@ -309,13 +309,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.BuildAPI.GetBuild(context.Background(), buildId).Execute() + resp, r, err := apiClient.BuildAPI.FindBuild(context.Background(), buildId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `BuildAPI.GetBuild``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `BuildAPI.FindBuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetBuild`: BuildDTO - fmt.Fprintf(os.Stdout, "Response from `BuildAPI.GetBuild`: %v\n", resp) + // response from `FindBuild`: BuildDTO + fmt.Fprintf(os.Stdout, "Response from `BuildAPI.FindBuild`: %v\n", resp) } ``` @@ -329,7 +329,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetBuildRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindBuildRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/ContainerRegistryAPI.md b/pkg/apiclient/docs/ContainerRegistryAPI.md index bc32b9c632..12e1792fd1 100644 --- a/pkg/apiclient/docs/ContainerRegistryAPI.md +++ b/pkg/apiclient/docs/ContainerRegistryAPI.md @@ -4,15 +4,15 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GetContainerRegistry**](ContainerRegistryAPI.md#GetContainerRegistry) | **Get** /container-registry/{server} | Get container registry +[**FindContainerRegistry**](ContainerRegistryAPI.md#FindContainerRegistry) | **Get** /container-registry/{server} | Find container registry -## GetContainerRegistry +## FindContainerRegistry -> ContainerRegistry GetContainerRegistry(ctx, server).WorkspaceId(workspaceId).Execute() +> ContainerRegistry FindContainerRegistry(ctx, server).WorkspaceId(workspaceId).Execute() -Get container registry +Find container registry @@ -34,13 +34,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ContainerRegistryAPI.GetContainerRegistry(context.Background(), server).WorkspaceId(workspaceId).Execute() + resp, r, err := apiClient.ContainerRegistryAPI.FindContainerRegistry(context.Background(), server).WorkspaceId(workspaceId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.GetContainerRegistry``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ContainerRegistryAPI.FindContainerRegistry``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetContainerRegistry`: ContainerRegistry - fmt.Fprintf(os.Stdout, "Response from `ContainerRegistryAPI.GetContainerRegistry`: %v\n", resp) + // response from `FindContainerRegistry`: ContainerRegistry + fmt.Fprintf(os.Stdout, "Response from `ContainerRegistryAPI.FindContainerRegistry`: %v\n", resp) } ``` @@ -54,7 +54,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetContainerRegistryRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindContainerRegistryRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/RegisterRunnerDTO.md b/pkg/apiclient/docs/CreateRunnerDTO.md similarity index 65% rename from pkg/apiclient/docs/RegisterRunnerDTO.md rename to pkg/apiclient/docs/CreateRunnerDTO.md index 2537de4e93..a747e07031 100644 --- a/pkg/apiclient/docs/RegisterRunnerDTO.md +++ b/pkg/apiclient/docs/CreateRunnerDTO.md @@ -1,4 +1,4 @@ -# RegisterRunnerDTO +# CreateRunnerDTO ## Properties @@ -9,59 +9,59 @@ Name | Type | Description | Notes ## Methods -### NewRegisterRunnerDTO +### NewCreateRunnerDTO -`func NewRegisterRunnerDTO(id string, name string, ) *RegisterRunnerDTO` +`func NewCreateRunnerDTO(id string, name string, ) *CreateRunnerDTO` -NewRegisterRunnerDTO instantiates a new RegisterRunnerDTO object +NewCreateRunnerDTO instantiates a new CreateRunnerDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewRegisterRunnerDTOWithDefaults +### NewCreateRunnerDTOWithDefaults -`func NewRegisterRunnerDTOWithDefaults() *RegisterRunnerDTO` +`func NewCreateRunnerDTOWithDefaults() *CreateRunnerDTO` -NewRegisterRunnerDTOWithDefaults instantiates a new RegisterRunnerDTO object +NewCreateRunnerDTOWithDefaults instantiates a new CreateRunnerDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetId -`func (o *RegisterRunnerDTO) GetId() string` +`func (o *CreateRunnerDTO) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *RegisterRunnerDTO) GetIdOk() (*string, bool)` +`func (o *CreateRunnerDTO) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *RegisterRunnerDTO) SetId(v string)` +`func (o *CreateRunnerDTO) SetId(v string)` SetId sets Id field to given value. ### GetName -`func (o *RegisterRunnerDTO) GetName() string` +`func (o *CreateRunnerDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *RegisterRunnerDTO) GetNameOk() (*string, bool)` +`func (o *CreateRunnerDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *RegisterRunnerDTO) SetName(v string)` +`func (o *CreateRunnerDTO) SetName(v string)` SetName sets Name field to given value. diff --git a/pkg/apiclient/docs/RegisterRunnerResultDTO.md b/pkg/apiclient/docs/CreateRunnerResultDTO.md similarity index 63% rename from pkg/apiclient/docs/RegisterRunnerResultDTO.md rename to pkg/apiclient/docs/CreateRunnerResultDTO.md index 45bc033c23..eed9a475a0 100644 --- a/pkg/apiclient/docs/RegisterRunnerResultDTO.md +++ b/pkg/apiclient/docs/CreateRunnerResultDTO.md @@ -1,4 +1,4 @@ -# RegisterRunnerResultDTO +# CreateRunnerResultDTO ## Properties @@ -11,104 +11,104 @@ Name | Type | Description | Notes ## Methods -### NewRegisterRunnerResultDTO +### NewCreateRunnerResultDTO -`func NewRegisterRunnerResultDTO(apiKey string, id string, name string, ) *RegisterRunnerResultDTO` +`func NewCreateRunnerResultDTO(apiKey string, id string, name string, ) *CreateRunnerResultDTO` -NewRegisterRunnerResultDTO instantiates a new RegisterRunnerResultDTO object +NewCreateRunnerResultDTO instantiates a new CreateRunnerResultDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewRegisterRunnerResultDTOWithDefaults +### NewCreateRunnerResultDTOWithDefaults -`func NewRegisterRunnerResultDTOWithDefaults() *RegisterRunnerResultDTO` +`func NewCreateRunnerResultDTOWithDefaults() *CreateRunnerResultDTO` -NewRegisterRunnerResultDTOWithDefaults instantiates a new RegisterRunnerResultDTO object +NewCreateRunnerResultDTOWithDefaults instantiates a new CreateRunnerResultDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetApiKey -`func (o *RegisterRunnerResultDTO) GetApiKey() string` +`func (o *CreateRunnerResultDTO) GetApiKey() string` GetApiKey returns the ApiKey field if non-nil, zero value otherwise. ### GetApiKeyOk -`func (o *RegisterRunnerResultDTO) GetApiKeyOk() (*string, bool)` +`func (o *CreateRunnerResultDTO) GetApiKeyOk() (*string, bool)` GetApiKeyOk returns a tuple with the ApiKey field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetApiKey -`func (o *RegisterRunnerResultDTO) SetApiKey(v string)` +`func (o *CreateRunnerResultDTO) SetApiKey(v string)` SetApiKey sets ApiKey field to given value. ### GetId -`func (o *RegisterRunnerResultDTO) GetId() string` +`func (o *CreateRunnerResultDTO) GetId() string` GetId returns the Id field if non-nil, zero value otherwise. ### GetIdOk -`func (o *RegisterRunnerResultDTO) GetIdOk() (*string, bool)` +`func (o *CreateRunnerResultDTO) GetIdOk() (*string, bool)` GetIdOk returns a tuple with the Id field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetId -`func (o *RegisterRunnerResultDTO) SetId(v string)` +`func (o *CreateRunnerResultDTO) SetId(v string)` SetId sets Id field to given value. ### GetMetadata -`func (o *RegisterRunnerResultDTO) GetMetadata() RunnerMetadata` +`func (o *CreateRunnerResultDTO) GetMetadata() RunnerMetadata` GetMetadata returns the Metadata field if non-nil, zero value otherwise. ### GetMetadataOk -`func (o *RegisterRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool)` +`func (o *CreateRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool)` GetMetadataOk returns a tuple with the Metadata field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetMetadata -`func (o *RegisterRunnerResultDTO) SetMetadata(v RunnerMetadata)` +`func (o *CreateRunnerResultDTO) SetMetadata(v RunnerMetadata)` SetMetadata sets Metadata field to given value. ### HasMetadata -`func (o *RegisterRunnerResultDTO) HasMetadata() bool` +`func (o *CreateRunnerResultDTO) HasMetadata() bool` HasMetadata returns a boolean if a field has been set. ### GetName -`func (o *RegisterRunnerResultDTO) GetName() string` +`func (o *CreateRunnerResultDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *RegisterRunnerResultDTO) GetNameOk() (*string, bool)` +`func (o *CreateRunnerResultDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *RegisterRunnerResultDTO) SetName(v string)` +`func (o *CreateRunnerResultDTO) SetName(v string)` SetName sets Name field to given value. diff --git a/pkg/apiclient/docs/AddTargetConfigDTO.md b/pkg/apiclient/docs/CreateTargetConfigDTO.md similarity index 63% rename from pkg/apiclient/docs/AddTargetConfigDTO.md rename to pkg/apiclient/docs/CreateTargetConfigDTO.md index 9354521a6f..96de15581c 100644 --- a/pkg/apiclient/docs/AddTargetConfigDTO.md +++ b/pkg/apiclient/docs/CreateTargetConfigDTO.md @@ -1,4 +1,4 @@ -# AddTargetConfigDTO +# CreateTargetConfigDTO ## Properties @@ -10,79 +10,79 @@ Name | Type | Description | Notes ## Methods -### NewAddTargetConfigDTO +### NewCreateTargetConfigDTO -`func NewAddTargetConfigDTO(name string, options string, providerInfo ProviderInfo, ) *AddTargetConfigDTO` +`func NewCreateTargetConfigDTO(name string, options string, providerInfo ProviderInfo, ) *CreateTargetConfigDTO` -NewAddTargetConfigDTO instantiates a new AddTargetConfigDTO object +NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object This constructor will assign default values to properties that have it defined, and makes sure properties required by API are set, but the set of arguments will change when the set of required properties is changed -### NewAddTargetConfigDTOWithDefaults +### NewCreateTargetConfigDTOWithDefaults -`func NewAddTargetConfigDTOWithDefaults() *AddTargetConfigDTO` +`func NewCreateTargetConfigDTOWithDefaults() *CreateTargetConfigDTO` -NewAddTargetConfigDTOWithDefaults instantiates a new AddTargetConfigDTO object +NewCreateTargetConfigDTOWithDefaults instantiates a new CreateTargetConfigDTO object This constructor will only assign default values to properties that have it defined, but it doesn't guarantee that properties required by API are set ### GetName -`func (o *AddTargetConfigDTO) GetName() string` +`func (o *CreateTargetConfigDTO) GetName() string` GetName returns the Name field if non-nil, zero value otherwise. ### GetNameOk -`func (o *AddTargetConfigDTO) GetNameOk() (*string, bool)` +`func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool)` GetNameOk returns a tuple with the Name field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetName -`func (o *AddTargetConfigDTO) SetName(v string)` +`func (o *CreateTargetConfigDTO) SetName(v string)` SetName sets Name field to given value. ### GetOptions -`func (o *AddTargetConfigDTO) GetOptions() string` +`func (o *CreateTargetConfigDTO) GetOptions() string` GetOptions returns the Options field if non-nil, zero value otherwise. ### GetOptionsOk -`func (o *AddTargetConfigDTO) GetOptionsOk() (*string, bool)` +`func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool)` GetOptionsOk returns a tuple with the Options field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetOptions -`func (o *AddTargetConfigDTO) SetOptions(v string)` +`func (o *CreateTargetConfigDTO) SetOptions(v string)` SetOptions sets Options field to given value. ### GetProviderInfo -`func (o *AddTargetConfigDTO) GetProviderInfo() ProviderInfo` +`func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderInfo` GetProviderInfo returns the ProviderInfo field if non-nil, zero value otherwise. ### GetProviderInfoOk -`func (o *AddTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool)` +`func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool)` GetProviderInfoOk returns a tuple with the ProviderInfo field if it's non-nil, zero value otherwise and a boolean to check if the value has been set. ### SetProviderInfo -`func (o *AddTargetConfigDTO) SetProviderInfo(v ProviderInfo)` +`func (o *CreateTargetConfigDTO) SetProviderInfo(v ProviderInfo)` SetProviderInfo sets ProviderInfo field to given value. diff --git a/pkg/apiclient/docs/EnvVarAPI.md b/pkg/apiclient/docs/EnvVarAPI.md index f926ad9026..e4520b1268 100644 --- a/pkg/apiclient/docs/EnvVarAPI.md +++ b/pkg/apiclient/docs/EnvVarAPI.md @@ -6,7 +6,7 @@ Method | HTTP request | Description ------------- | ------------- | ------------- [**DeleteEnvironmentVariable**](EnvVarAPI.md#DeleteEnvironmentVariable) | **Delete** /env/{key} | Delete environment variable [**ListEnvironmentVariables**](EnvVarAPI.md#ListEnvironmentVariables) | **Get** /env | List environment variables -[**SetEnvironmentVariable**](EnvVarAPI.md#SetEnvironmentVariable) | **Put** /env | Set environment variable +[**SaveEnvironmentVariable**](EnvVarAPI.md#SaveEnvironmentVariable) | **Put** /env | Save environment variable @@ -139,11 +139,11 @@ Other parameters are passed through a pointer to a apiListEnvironmentVariablesRe [[Back to README]](../README.md) -## SetEnvironmentVariable +## SaveEnvironmentVariable -> SetEnvironmentVariable(ctx).EnvironmentVariable(environmentVariable).Execute() +> SaveEnvironmentVariable(ctx).EnvironmentVariable(environmentVariable).Execute() -Set environment variable +Save environment variable @@ -164,9 +164,9 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.EnvVarAPI.SetEnvironmentVariable(context.Background()).EnvironmentVariable(environmentVariable).Execute() + r, err := apiClient.EnvVarAPI.SaveEnvironmentVariable(context.Background()).EnvironmentVariable(environmentVariable).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `EnvVarAPI.SetEnvironmentVariable``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `EnvVarAPI.SaveEnvironmentVariable``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -178,7 +178,7 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiSetEnvironmentVariableRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSaveEnvironmentVariableRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/GitProviderAPI.md b/pkg/apiclient/docs/GitProviderAPI.md index 2fa81645cd..c6f72b1e05 100644 --- a/pkg/apiclient/docs/GitProviderAPI.md +++ b/pkg/apiclient/docs/GitProviderAPI.md @@ -4,9 +4,10 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- +[**DeleteGitProvider**](GitProviderAPI.md#DeleteGitProvider) | **Delete** /gitprovider/{gitProviderId} | Delete Git provider +[**FindGitProvider**](GitProviderAPI.md#FindGitProvider) | **Get** /gitprovider/{gitProviderId} | Find Git provider +[**FindGitProviderIdForUrl**](GitProviderAPI.md#FindGitProviderIdForUrl) | **Get** /gitprovider/id-for-url/{url} | Find Git provider ID [**GetGitContext**](GitProviderAPI.md#GetGitContext) | **Post** /gitprovider/context | Get Git context -[**GetGitProvider**](GitProviderAPI.md#GetGitProvider) | **Get** /gitprovider/{gitProviderId} | Get Git provider -[**GetGitProviderIdForUrl**](GitProviderAPI.md#GetGitProviderIdForUrl) | **Get** /gitprovider/id-for-url/{url} | Get Git provider ID [**GetGitUser**](GitProviderAPI.md#GetGitUser) | **Get** /gitprovider/{gitProviderId}/user | Get Git context [**GetNamespaces**](GitProviderAPI.md#GetNamespaces) | **Get** /gitprovider/{gitProviderId}/namespaces | Get Git namespaces [**GetRepoBranches**](GitProviderAPI.md#GetRepoBranches) | **Get** /gitprovider/{gitProviderId}/{namespaceId}/{repositoryId}/branches | Get Git repository branches @@ -15,16 +16,15 @@ Method | HTTP request | Description [**GetUrlFromRepository**](GitProviderAPI.md#GetUrlFromRepository) | **Post** /gitprovider/context/url | Get URL from Git repository [**ListGitProviders**](GitProviderAPI.md#ListGitProviders) | **Get** /gitprovider | List Git providers [**ListGitProvidersForUrl**](GitProviderAPI.md#ListGitProvidersForUrl) | **Get** /gitprovider/for-url/{url} | List Git providers for url -[**RemoveGitProvider**](GitProviderAPI.md#RemoveGitProvider) | **Delete** /gitprovider/{gitProviderId} | Remove Git provider -[**SetGitProvider**](GitProviderAPI.md#SetGitProvider) | **Put** /gitprovider | Set Git provider +[**SaveGitProvider**](GitProviderAPI.md#SaveGitProvider) | **Put** /gitprovider | Save Git provider -## GetGitContext +## DeleteGitProvider -> GitRepository GetGitContext(ctx).Repository(repository).Execute() +> DeleteGitProvider(ctx, gitProviderId).Execute() -Get Git context +Delete Git provider @@ -41,36 +41,38 @@ import ( ) func main() { - repository := *openapiclient.NewGetRepositoryContext("Url_example") // GetRepositoryContext | Get repository context + gitProviderId := "gitProviderId_example" // string | Git provider configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.GitProviderAPI.GetGitContext(context.Background()).Repository(repository).Execute() + r, err := apiClient.GitProviderAPI.DeleteGitProvider(context.Background(), gitProviderId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.GetGitContext``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.DeleteGitProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetGitContext`: GitRepository - fmt.Fprintf(os.Stdout, "Response from `GitProviderAPI.GetGitContext`: %v\n", resp) } ``` ### Path Parameters +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**gitProviderId** | **string** | Git provider | ### Other Parameters -Other parameters are passed through a pointer to a apiGetGitContextRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteGitProviderRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **repository** | [**GetRepositoryContext**](GetRepositoryContext.md) | Get repository context | + ### Return type -[**GitRepository**](GitRepository.md) + (empty response body) ### Authorization @@ -79,18 +81,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## GetGitProvider +## FindGitProvider -> GitProvider GetGitProvider(ctx, gitProviderId).Execute() +> GitProvider FindGitProvider(ctx, gitProviderId).Execute() -Get Git provider +Find Git provider @@ -111,13 +113,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.GitProviderAPI.GetGitProvider(context.Background(), gitProviderId).Execute() + resp, r, err := apiClient.GitProviderAPI.FindGitProvider(context.Background(), gitProviderId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.GetGitProvider``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.FindGitProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetGitProvider`: GitProvider - fmt.Fprintf(os.Stdout, "Response from `GitProviderAPI.GetGitProvider`: %v\n", resp) + // response from `FindGitProvider`: GitProvider + fmt.Fprintf(os.Stdout, "Response from `GitProviderAPI.FindGitProvider`: %v\n", resp) } ``` @@ -131,7 +133,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetGitProviderRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindGitProviderRequest struct via the builder pattern Name | Type | Description | Notes @@ -156,11 +158,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetGitProviderIdForUrl +## FindGitProviderIdForUrl -> string GetGitProviderIdForUrl(ctx, url).Execute() +> string FindGitProviderIdForUrl(ctx, url).Execute() -Get Git provider ID +Find Git provider ID @@ -181,13 +183,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(context.Background(), url).Execute() + resp, r, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(context.Background(), url).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.GetGitProviderIdForUrl``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.FindGitProviderIdForUrl``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetGitProviderIdForUrl`: string - fmt.Fprintf(os.Stdout, "Response from `GitProviderAPI.GetGitProviderIdForUrl`: %v\n", resp) + // response from `FindGitProviderIdForUrl`: string + fmt.Fprintf(os.Stdout, "Response from `GitProviderAPI.FindGitProviderIdForUrl`: %v\n", resp) } ``` @@ -201,7 +203,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetGitProviderIdForUrlRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindGitProviderIdForUrlRequest struct via the builder pattern Name | Type | Description | Notes @@ -226,6 +228,72 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## GetGitContext + +> GitRepository GetGitContext(ctx).Repository(repository).Execute() + +Get Git context + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + repository := *openapiclient.NewGetRepositoryContext("Url_example") // GetRepositoryContext | Get repository context + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.GitProviderAPI.GetGitContext(context.Background()).Repository(repository).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.GetGitContext``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `GetGitContext`: GitRepository + fmt.Fprintf(os.Stdout, "Response from `GitProviderAPI.GetGitContext`: %v\n", resp) +} +``` + +### Path Parameters + + + +### Other Parameters + +Other parameters are passed through a pointer to a apiGetGitContextRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **repository** | [**GetRepositoryContext**](GetRepositoryContext.md) | Get repository context | + +### Return type + +[**GitRepository**](GitRepository.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## GetGitUser > GitUser GetGitUser(ctx, gitProviderId).Execute() @@ -804,79 +872,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## RemoveGitProvider - -> RemoveGitProvider(ctx, gitProviderId).Execute() - -Remove Git provider - - - -### Example - -```go -package main - -import ( - "context" - "fmt" - "os" - openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" -) - -func main() { - gitProviderId := "gitProviderId_example" // string | Git provider - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.GitProviderAPI.RemoveGitProvider(context.Background(), gitProviderId).Execute() - if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.RemoveGitProvider``: %v\n", err) - fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) - } -} -``` - -### Path Parameters - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**gitProviderId** | **string** | Git provider | - -### Other Parameters - -Other parameters are passed through a pointer to a apiRemoveGitProviderRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- - - -### Return type - - (empty response body) - -### Authorization - -[Bearer](../README.md#Bearer) - -### HTTP request headers - -- **Content-Type**: Not defined -- **Accept**: Not defined - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) -[[Back to Model list]](../README.md#documentation-for-models) -[[Back to README]](../README.md) - - -## SetGitProvider +## SaveGitProvider -> SetGitProvider(ctx).GitProviderConfig(gitProviderConfig).Execute() +> SaveGitProvider(ctx).GitProviderConfig(gitProviderConfig).Execute() -Set Git provider +Save Git provider @@ -897,9 +897,9 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.GitProviderAPI.SetGitProvider(context.Background()).GitProviderConfig(gitProviderConfig).Execute() + r, err := apiClient.GitProviderAPI.SaveGitProvider(context.Background()).GitProviderConfig(gitProviderConfig).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.SetGitProvider``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `GitProviderAPI.SaveGitProvider``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -911,7 +911,7 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiSetGitProviderRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSaveGitProviderRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/PrebuildAPI.md b/pkg/apiclient/docs/PrebuildAPI.md index 51c8eac206..60d47b918b 100644 --- a/pkg/apiclient/docs/PrebuildAPI.md +++ b/pkg/apiclient/docs/PrebuildAPI.md @@ -5,11 +5,11 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- [**DeletePrebuild**](PrebuildAPI.md#DeletePrebuild) | **Delete** /workspace-template/{templateName}/prebuild/{prebuildId} | Delete prebuild -[**GetPrebuild**](PrebuildAPI.md#GetPrebuild) | **Get** /workspace-template/{templateName}/prebuild/{prebuildId} | Get prebuild +[**FindPrebuild**](PrebuildAPI.md#FindPrebuild) | **Get** /workspace-template/{templateName}/prebuild/{prebuildId} | Find prebuild [**ListPrebuilds**](PrebuildAPI.md#ListPrebuilds) | **Get** /workspace-template/prebuild | List prebuilds [**ListPrebuildsForWorkspaceTemplate**](PrebuildAPI.md#ListPrebuildsForWorkspaceTemplate) | **Get** /workspace-template/{templateName}/prebuild | List prebuilds for workspace template [**ProcessGitEvent**](PrebuildAPI.md#ProcessGitEvent) | **Post** /workspace-template/prebuild/process-git-event | ProcessGitEvent -[**SetPrebuild**](PrebuildAPI.md#SetPrebuild) | **Put** /workspace-template/{templateName}/prebuild | Set prebuild +[**SavePrebuild**](PrebuildAPI.md#SavePrebuild) | **Put** /workspace-template/{templateName}/prebuild | Save prebuild @@ -86,11 +86,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetPrebuild +## FindPrebuild -> PrebuildDTO GetPrebuild(ctx, templateName, prebuildId).Execute() +> PrebuildDTO FindPrebuild(ctx, templateName, prebuildId).Execute() -Get prebuild +Find prebuild @@ -112,13 +112,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.PrebuildAPI.GetPrebuild(context.Background(), templateName, prebuildId).Execute() + resp, r, err := apiClient.PrebuildAPI.FindPrebuild(context.Background(), templateName, prebuildId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.GetPrebuild``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.FindPrebuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetPrebuild`: PrebuildDTO - fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.GetPrebuild`: %v\n", resp) + // response from `FindPrebuild`: PrebuildDTO + fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.FindPrebuild`: %v\n", resp) } ``` @@ -133,7 +133,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiGetPrebuildRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindPrebuildRequest struct via the builder pattern Name | Type | Description | Notes @@ -354,11 +354,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetPrebuild +## SavePrebuild -> string SetPrebuild(ctx, templateName).Prebuild(prebuild).Execute() +> string SavePrebuild(ctx, templateName).Prebuild(prebuild).Execute() -Set prebuild +Save prebuild @@ -380,13 +380,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.PrebuildAPI.SetPrebuild(context.Background(), templateName).Prebuild(prebuild).Execute() + resp, r, err := apiClient.PrebuildAPI.SavePrebuild(context.Background(), templateName).Prebuild(prebuild).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.SetPrebuild``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `PrebuildAPI.SavePrebuild``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `SetPrebuild`: string - fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.SetPrebuild`: %v\n", resp) + // response from `SavePrebuild`: string + fmt.Fprintf(os.Stdout, "Response from `PrebuildAPI.SavePrebuild`: %v\n", resp) } ``` @@ -400,7 +400,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiSetPrebuildRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSavePrebuildRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/RunnerAPI.md b/pkg/apiclient/docs/RunnerAPI.md index 83ae39a597..cb9ef0dfd9 100644 --- a/pkg/apiclient/docs/RunnerAPI.md +++ b/pkg/apiclient/docs/RunnerAPI.md @@ -4,21 +4,21 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GetRunner**](RunnerAPI.md#GetRunner) | **Get** /runner/{runnerId} | Get a runner +[**CreateRunner**](RunnerAPI.md#CreateRunner) | **Post** /runner | Create a runner +[**DeleteRunner**](RunnerAPI.md#DeleteRunner) | **Delete** /runner/{runnerId} | Delete runner +[**FindRunner**](RunnerAPI.md#FindRunner) | **Get** /runner/{runnerId} | Find a runner [**ListRunnerJobs**](RunnerAPI.md#ListRunnerJobs) | **Get** /runner/{runnerId}/jobs | List runner jobs [**ListRunners**](RunnerAPI.md#ListRunners) | **Get** /runner | List runners -[**RegisterRunner**](RunnerAPI.md#RegisterRunner) | **Post** /runner | Register a runner -[**RemoveRunner**](RunnerAPI.md#RemoveRunner) | **Delete** /runner/{runnerId} | Remove runner -[**SetRunnerMetadata**](RunnerAPI.md#SetRunnerMetadata) | **Post** /runner/{runnerId}/metadata | Set runner metadata [**UpdateJobState**](RunnerAPI.md#UpdateJobState) | **Post** /runner/{runnerId}/jobs/{jobId}/state | Update job state +[**UpdateRunnerMetadata**](RunnerAPI.md#UpdateRunnerMetadata) | **Post** /runner/{runnerId}/metadata | Update runner metadata -## GetRunner +## CreateRunner -> RunnerDTO GetRunner(ctx, runnerId).Execute() +> CreateRunnerResultDTO CreateRunner(ctx).Runner(runner).Execute() -Get a runner +Create a runner @@ -35,40 +35,36 @@ import ( ) func main() { - runnerId := "runnerId_example" // string | Runner ID + runner := *openapiclient.NewCreateRunnerDTO("Id_example", "Name_example") // CreateRunnerDTO | Runner configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.RunnerAPI.GetRunner(context.Background(), runnerId).Execute() + resp, r, err := apiClient.RunnerAPI.CreateRunner(context.Background()).Runner(runner).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.GetRunner``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.CreateRunner``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetRunner`: RunnerDTO - fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.GetRunner`: %v\n", resp) + // response from `CreateRunner`: CreateRunnerResultDTO + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.CreateRunner`: %v\n", resp) } ``` ### Path Parameters -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**runnerId** | **string** | Runner ID | ### Other Parameters -Other parameters are passed through a pointer to a apiGetRunnerRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiCreateRunnerRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - + **runner** | [**CreateRunnerDTO**](CreateRunnerDTO.md) | Runner | ### Return type -[**RunnerDTO**](RunnerDTO.md) +[**CreateRunnerResultDTO**](CreateRunnerResultDTO.md) ### Authorization @@ -84,11 +80,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## ListRunnerJobs +## DeleteRunner -> []Job ListRunnerJobs(ctx, runnerId).Execute() +> DeleteRunner(ctx, runnerId).Execute() -List runner jobs +Delete runner @@ -109,13 +105,11 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.RunnerAPI.ListRunnerJobs(context.Background(), runnerId).Execute() + r, err := apiClient.RunnerAPI.DeleteRunner(context.Background(), runnerId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.ListRunnerJobs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.DeleteRunner``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListRunnerJobs`: []Job - fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.ListRunnerJobs`: %v\n", resp) } ``` @@ -129,7 +123,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiListRunnerJobsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteRunnerRequest struct via the builder pattern Name | Type | Description | Notes @@ -138,7 +132,7 @@ Name | Type | Description | Notes ### Return type -[**[]Job**](Job.md) + (empty response body) ### Authorization @@ -147,18 +141,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## ListRunners +## FindRunner -> []RunnerDTO ListRunners(ctx).Execute() +> RunnerDTO FindRunner(ctx, runnerId).Execute() -List runners +Find a runner @@ -175,31 +169,40 @@ import ( ) func main() { + runnerId := "runnerId_example" // string | Runner ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.RunnerAPI.ListRunners(context.Background()).Execute() + resp, r, err := apiClient.RunnerAPI.FindRunner(context.Background(), runnerId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.ListRunners``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.FindRunner``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListRunners`: []RunnerDTO - fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.ListRunners`: %v\n", resp) + // response from `FindRunner`: RunnerDTO + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.FindRunner`: %v\n", resp) } ``` ### Path Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | ### Other Parameters -Other parameters are passed through a pointer to a apiListRunnersRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindRunnerRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- ### Return type -[**[]RunnerDTO**](RunnerDTO.md) +[**RunnerDTO**](RunnerDTO.md) ### Authorization @@ -215,11 +218,11 @@ Other parameters are passed through a pointer to a apiListRunnersRequest struct [[Back to README]](../README.md) -## RegisterRunner +## ListRunnerJobs -> RegisterRunnerResultDTO RegisterRunner(ctx).Runner(runner).Execute() +> []Job ListRunnerJobs(ctx, runnerId).Execute() -Register a runner +List runner jobs @@ -236,36 +239,40 @@ import ( ) func main() { - runner := *openapiclient.NewRegisterRunnerDTO("Id_example", "Name_example") // RegisterRunnerDTO | Register runner + runnerId := "runnerId_example" // string | Runner ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.RunnerAPI.RegisterRunner(context.Background()).Runner(runner).Execute() + resp, r, err := apiClient.RunnerAPI.ListRunnerJobs(context.Background(), runnerId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.RegisterRunner``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.ListRunnerJobs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `RegisterRunner`: RegisterRunnerResultDTO - fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.RegisterRunner`: %v\n", resp) + // response from `ListRunnerJobs`: []Job + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.ListRunnerJobs`: %v\n", resp) } ``` ### Path Parameters +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**runnerId** | **string** | Runner ID | ### Other Parameters -Other parameters are passed through a pointer to a apiRegisterRunnerRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListRunnerJobsRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **runner** | [**RegisterRunnerDTO**](RegisterRunnerDTO.md) | Register runner | + ### Return type -[**RegisterRunnerResultDTO**](RegisterRunnerResultDTO.md) +[**[]Job**](Job.md) ### Authorization @@ -281,11 +288,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## RemoveRunner +## ListRunners -> RemoveRunner(ctx, runnerId).Execute() +> []RunnerDTO ListRunners(ctx).Execute() -Remove runner +List runners @@ -302,38 +309,31 @@ import ( ) func main() { - runnerId := "runnerId_example" // string | Runner ID configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.RunnerAPI.RemoveRunner(context.Background(), runnerId).Execute() + resp, r, err := apiClient.RunnerAPI.ListRunners(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.RemoveRunner``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.ListRunners``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListRunners`: []RunnerDTO + fmt.Fprintf(os.Stdout, "Response from `RunnerAPI.ListRunners`: %v\n", resp) } ``` ### Path Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**runnerId** | **string** | Runner ID | +This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveRunnerRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- +Other parameters are passed through a pointer to a apiListRunnersRequest struct via the builder pattern ### Return type - (empty response body) +[**[]RunnerDTO**](RunnerDTO.md) ### Authorization @@ -342,18 +342,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## SetRunnerMetadata +## UpdateJobState -> SetRunnerMetadata(ctx, runnerId).RunnerMetadata(runnerMetadata).Execute() +> UpdateJobState(ctx, runnerId, jobId).UpdateJobState(updateJobState).Execute() -Set runner metadata +Update job state @@ -371,13 +371,14 @@ import ( func main() { runnerId := "runnerId_example" // string | Runner ID - runnerMetadata := *openapiclient.NewUpdateRunnerMetadataDTO([]openapiclient.ProviderInfo{*openapiclient.NewProviderInfo("Name_example", "RunnerId_example", "RunnerName_example", map[string]TargetConfigProperty{"key": *openapiclient.NewTargetConfigProperty()}, "Version_example")}, int32(123)) // UpdateRunnerMetadataDTO | Runner Metadata + jobId := "jobId_example" // string | Job ID + updateJobState := *openapiclient.NewUpdateJobState(openapiclient.JobState("pending")) // UpdateJobState | Update job state configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.RunnerAPI.SetRunnerMetadata(context.Background(), runnerId).RunnerMetadata(runnerMetadata).Execute() + r, err := apiClient.RunnerAPI.UpdateJobState(context.Background(), runnerId, jobId).UpdateJobState(updateJobState).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.SetRunnerMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.UpdateJobState``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -390,16 +391,18 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **runnerId** | **string** | Runner ID | +**jobId** | **string** | Job ID | ### Other Parameters -Other parameters are passed through a pointer to a apiSetRunnerMetadataRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiUpdateJobStateRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **runnerMetadata** | [**UpdateRunnerMetadataDTO**](UpdateRunnerMetadataDTO.md) | Runner Metadata | + + **updateJobState** | [**UpdateJobState**](UpdateJobState.md) | Update job state | ### Return type @@ -419,11 +422,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## UpdateJobState +## UpdateRunnerMetadata -> UpdateJobState(ctx, runnerId, jobId).UpdateJobState(updateJobState).Execute() +> UpdateRunnerMetadata(ctx, runnerId).RunnerMetadata(runnerMetadata).Execute() -Update job state +Update runner metadata @@ -441,14 +444,13 @@ import ( func main() { runnerId := "runnerId_example" // string | Runner ID - jobId := "jobId_example" // string | Job ID - updateJobState := *openapiclient.NewUpdateJobState(openapiclient.JobState("pending")) // UpdateJobState | Update job state + runnerMetadata := *openapiclient.NewUpdateRunnerMetadataDTO([]openapiclient.ProviderInfo{*openapiclient.NewProviderInfo("Name_example", "RunnerId_example", "RunnerName_example", map[string]TargetConfigProperty{"key": *openapiclient.NewTargetConfigProperty()}, "Version_example")}, int32(123)) // UpdateRunnerMetadataDTO | Runner Metadata configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.RunnerAPI.UpdateJobState(context.Background(), runnerId, jobId).UpdateJobState(updateJobState).Execute() + r, err := apiClient.RunnerAPI.UpdateRunnerMetadata(context.Background(), runnerId).RunnerMetadata(runnerMetadata).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.UpdateJobState``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `RunnerAPI.UpdateRunnerMetadata``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -461,18 +463,16 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. **runnerId** | **string** | Runner ID | -**jobId** | **string** | Job ID | ### Other Parameters -Other parameters are passed through a pointer to a apiUpdateJobStateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiUpdateRunnerMetadataRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - - **updateJobState** | [**UpdateJobState**](UpdateJobState.md) | Update job state | + **runnerMetadata** | [**UpdateRunnerMetadataDTO**](UpdateRunnerMetadataDTO.md) | Runner Metadata | ### Return type diff --git a/pkg/apiclient/docs/ServerAPI.md b/pkg/apiclient/docs/ServerAPI.md index 5d57f00026..8afbef701e 100644 --- a/pkg/apiclient/docs/ServerAPI.md +++ b/pkg/apiclient/docs/ServerAPI.md @@ -4,18 +4,18 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**GenerateNetworkKey**](ServerAPI.md#GenerateNetworkKey) | **Post** /server/network-key | Generate a new authentication key +[**CreateNetworkKey**](ServerAPI.md#CreateNetworkKey) | **Post** /server/network-key | Create a new authentication key [**GetConfig**](ServerAPI.md#GetConfig) | **Get** /server/config | Get the server configuration -[**GetServerLogFiles**](ServerAPI.md#GetServerLogFiles) | **Get** /server/logs | List server log files -[**SetConfig**](ServerAPI.md#SetConfig) | **Post** /server/config | Set the server configuration +[**GetServerLogFiles**](ServerAPI.md#GetServerLogFiles) | **Get** /server/logs | Get server log files +[**SaveConfig**](ServerAPI.md#SaveConfig) | **Put** /server/config | Save the server configuration -## GenerateNetworkKey +## CreateNetworkKey -> NetworkKey GenerateNetworkKey(ctx).Execute() +> NetworkKey CreateNetworkKey(ctx).Execute() -Generate a new authentication key +Create a new authentication key @@ -35,13 +35,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ServerAPI.GenerateNetworkKey(context.Background()).Execute() + resp, r, err := apiClient.ServerAPI.CreateNetworkKey(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ServerAPI.GenerateNetworkKey``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ServerAPI.CreateNetworkKey``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GenerateNetworkKey`: NetworkKey - fmt.Fprintf(os.Stdout, "Response from `ServerAPI.GenerateNetworkKey`: %v\n", resp) + // response from `CreateNetworkKey`: NetworkKey + fmt.Fprintf(os.Stdout, "Response from `ServerAPI.CreateNetworkKey`: %v\n", resp) } ``` @@ -51,7 +51,7 @@ This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiGenerateNetworkKeyRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiCreateNetworkKeyRequest struct via the builder pattern ### Return type @@ -137,7 +137,7 @@ Other parameters are passed through a pointer to a apiGetConfigRequest struct vi > []string GetServerLogFiles(ctx).Execute() -List server log files +Get server log files @@ -194,11 +194,11 @@ Other parameters are passed through a pointer to a apiGetServerLogFilesRequest s [[Back to README]](../README.md) -## SetConfig +## SaveConfig -> ServerConfig SetConfig(ctx).Config(config).Execute() +> ServerConfig SaveConfig(ctx).Config(config).Execute() -Set the server configuration +Save the server configuration @@ -219,13 +219,13 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.ServerAPI.SetConfig(context.Background()).Config(config).Execute() + resp, r, err := apiClient.ServerAPI.SaveConfig(context.Background()).Config(config).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `ServerAPI.SetConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `ServerAPI.SaveConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `SetConfig`: ServerConfig - fmt.Fprintf(os.Stdout, "Response from `ServerAPI.SetConfig`: %v\n", resp) + // response from `SaveConfig`: ServerConfig + fmt.Fprintf(os.Stdout, "Response from `ServerAPI.SaveConfig`: %v\n", resp) } ``` @@ -235,7 +235,7 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiSetConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSaveConfigRequest struct via the builder pattern Name | Type | Description | Notes diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index a9420bcec7..eaef7314a8 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -5,14 +5,14 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- [**CreateTarget**](TargetAPI.md#CreateTarget) | **Post** /target | Create a target -[**GetTarget**](TargetAPI.md#GetTarget) | **Get** /target/{targetId} | Get target info +[**DeleteTarget**](TargetAPI.md#DeleteTarget) | **Delete** /target/{targetId} | Delete target +[**FindTarget**](TargetAPI.md#FindTarget) | **Get** /target/{targetId} | Find target [**HandleSuccessfulCreation**](TargetAPI.md#HandleSuccessfulCreation) | **Post** /target/{targetId}/handle-successful-creation | Handles successful creation of the target [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets -[**RemoveTarget**](TargetAPI.md#RemoveTarget) | **Delete** /target/{targetId} | Remove target [**SetDefaultTarget**](TargetAPI.md#SetDefaultTarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default -[**SetTargetMetadata**](TargetAPI.md#SetTargetMetadata) | **Post** /target/{targetId}/metadata | Set target metadata [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target +[**UpdateTargetMetadata**](TargetAPI.md#UpdateTargetMetadata) | **Post** /target/{targetId}/metadata | Update target metadata [**UpdateTargetProviderMetadata**](TargetAPI.md#UpdateTargetProviderMetadata) | **Post** /target/{targetId}/provider-metadata | Update target provider metadata @@ -83,11 +83,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetTarget +## DeleteTarget -> TargetDTO GetTarget(ctx, targetId).ShowOptions(showOptions).Execute() +> DeleteTarget(ctx, targetId).Force(force).Execute() -Get target info +Delete target @@ -104,18 +104,16 @@ import ( ) func main() { - targetId := "targetId_example" // string | Target ID or Name - showOptions := true // bool | Show target config options (optional) + targetId := "targetId_example" // string | Target ID + force := true // bool | Force (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetAPI.GetTarget(context.Background(), targetId).ShowOptions(showOptions).Execute() + r, err := apiClient.TargetAPI.DeleteTarget(context.Background(), targetId).Force(force).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.GetTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.DeleteTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetTarget`: TargetDTO - fmt.Fprintf(os.Stdout, "Response from `TargetAPI.GetTarget`: %v\n", resp) } ``` @@ -125,21 +123,21 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID or Name | +**targetId** | **string** | Target ID | ### Other Parameters -Other parameters are passed through a pointer to a apiGetTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteTargetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **showOptions** | **bool** | Show target config options | + **force** | **bool** | Force | ### Return type -[**TargetDTO**](TargetDTO.md) + (empty response body) ### Authorization @@ -148,18 +146,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## HandleSuccessfulCreation +## FindTarget -> HandleSuccessfulCreation(ctx, targetId).Execute() +> TargetDTO FindTarget(ctx, targetId).ShowOptions(showOptions).Execute() -Handles successful creation of the target +Find target @@ -176,15 +174,18 @@ import ( ) func main() { - targetId := "targetId_example" // string | Target ID or name + targetId := "targetId_example" // string | Target ID or Name + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.HandleSuccessfulCreation(context.Background(), targetId).Execute() + resp, r, err := apiClient.TargetAPI.FindTarget(context.Background(), targetId).ShowOptions(showOptions).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.HandleSuccessfulCreation``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.FindTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `FindTarget`: TargetDTO + fmt.Fprintf(os.Stdout, "Response from `TargetAPI.FindTarget`: %v\n", resp) } ``` @@ -194,20 +195,21 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID or name | +**targetId** | **string** | Target ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiHandleSuccessfulCreationRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindTargetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **showOptions** | **bool** | Show target config options | ### Return type - (empty response body) +[**TargetDTO**](TargetDTO.md) ### Authorization @@ -216,18 +218,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## ListTargets +## HandleSuccessfulCreation -> []TargetDTO ListTargets(ctx).ShowOptions(showOptions).Execute() +> HandleSuccessfulCreation(ctx, targetId).Execute() -List targets +Handles successful creation of the target @@ -244,36 +246,38 @@ import ( ) func main() { - showOptions := true // bool | Show target config options (optional) + targetId := "targetId_example" // string | Target ID or name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetAPI.ListTargets(context.Background()).ShowOptions(showOptions).Execute() + r, err := apiClient.TargetAPI.HandleSuccessfulCreation(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.ListTargets``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.HandleSuccessfulCreation``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListTargets`: []TargetDTO - fmt.Fprintf(os.Stdout, "Response from `TargetAPI.ListTargets`: %v\n", resp) } ``` ### Path Parameters +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**targetId** | **string** | Target ID or name | ### Other Parameters -Other parameters are passed through a pointer to a apiListTargetsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiHandleSuccessfulCreationRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **showOptions** | **bool** | Show target config options | + ### Return type -[**[]TargetDTO**](TargetDTO.md) + (empty response body) ### Authorization @@ -282,18 +286,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## RemoveTarget +## ListTargets -> RemoveTarget(ctx, targetId).Force(force).Execute() +> []TargetDTO ListTargets(ctx).ShowOptions(showOptions).Execute() -Remove target +List targets @@ -310,40 +314,36 @@ import ( ) func main() { - targetId := "targetId_example" // string | Target ID - force := true // bool | Force (optional) + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.RemoveTarget(context.Background(), targetId).Force(force).Execute() + resp, r, err := apiClient.TargetAPI.ListTargets(context.Background()).ShowOptions(showOptions).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.RemoveTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.ListTargets``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListTargets`: []TargetDTO + fmt.Fprintf(os.Stdout, "Response from `TargetAPI.ListTargets`: %v\n", resp) } ``` ### Path Parameters -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID | ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListTargetsRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - - **force** | **bool** | Force | + **showOptions** | **bool** | Show target config options | ### Return type - (empty response body) +[**[]TargetDTO**](TargetDTO.md) ### Authorization @@ -352,7 +352,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) @@ -427,11 +427,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetTargetMetadata +## StartTarget -> SetTargetMetadata(ctx, targetId).TargetMetadata(targetMetadata).Execute() +> StartTarget(ctx, targetId).Execute() -Set target metadata +Start target @@ -448,14 +448,13 @@ import ( ) func main() { - targetId := "targetId_example" // string | Target ID - targetMetadata := *openapiclient.NewUpdateTargetMetadataDTO(int32(123)) // UpdateTargetMetadataDTO | Target Metadata + targetId := "targetId_example" // string | Target ID or Name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.SetTargetMetadata(context.Background(), targetId).TargetMetadata(targetMetadata).Execute() + r, err := apiClient.TargetAPI.StartTarget(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.SetTargetMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -467,17 +466,16 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID | +**targetId** | **string** | Target ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiSetTargetMetadataRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStartTargetRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **targetMetadata** | [**UpdateTargetMetadataDTO**](UpdateTargetMetadataDTO.md) | Target Metadata | ### Return type @@ -497,11 +495,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StartTarget +## StopTarget -> StartTarget(ctx, targetId).Execute() +> StopTarget(ctx, targetId).Execute() -Start target +Stop target @@ -522,9 +520,9 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StartTarget(context.Background(), targetId).Execute() + r, err := apiClient.TargetAPI.StopTarget(context.Background(), targetId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StartTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopTarget``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -540,7 +538,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiStartTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStopTargetRequest struct via the builder pattern Name | Type | Description | Notes @@ -565,11 +563,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StopTarget +## UpdateTargetMetadata -> StopTarget(ctx, targetId).Execute() +> UpdateTargetMetadata(ctx, targetId).TargetMetadata(targetMetadata).Execute() -Stop target +Update target metadata @@ -586,13 +584,14 @@ import ( ) func main() { - targetId := "targetId_example" // string | Target ID or Name + targetId := "targetId_example" // string | Target ID + targetMetadata := *openapiclient.NewUpdateTargetMetadataDTO(int32(123)) // UpdateTargetMetadataDTO | Target Metadata configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetAPI.StopTarget(context.Background(), targetId).Execute() + r, err := apiClient.TargetAPI.UpdateTargetMetadata(context.Background(), targetId).TargetMetadata(targetMetadata).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.StopTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.UpdateTargetMetadata``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -604,16 +603,17 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**targetId** | **string** | Target ID or Name | +**targetId** | **string** | Target ID | ### Other Parameters -Other parameters are passed through a pointer to a apiStopTargetRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiUpdateTargetMetadataRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **targetMetadata** | [**UpdateTargetMetadataDTO**](UpdateTargetMetadataDTO.md) | Target Metadata | ### Return type diff --git a/pkg/apiclient/docs/TargetConfigAPI.md b/pkg/apiclient/docs/TargetConfigAPI.md index c565235755..95b660c910 100644 --- a/pkg/apiclient/docs/TargetConfigAPI.md +++ b/pkg/apiclient/docs/TargetConfigAPI.md @@ -4,17 +4,17 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- -[**AddTargetConfig**](TargetConfigAPI.md#AddTargetConfig) | **Put** /target-config | Add a target config +[**CreateTargetConfig**](TargetConfigAPI.md#CreateTargetConfig) | **Post** /target-config | Create a target config +[**DeleteTargetConfig**](TargetConfigAPI.md#DeleteTargetConfig) | **Delete** /target-config/{configId} | Delete a target config [**ListTargetConfigs**](TargetConfigAPI.md#ListTargetConfigs) | **Get** /target-config | List target configs -[**RemoveTargetConfig**](TargetConfigAPI.md#RemoveTargetConfig) | **Delete** /target-config/{configId} | Remove a target config -## AddTargetConfig +## CreateTargetConfig -> TargetConfig AddTargetConfig(ctx).TargetConfig(targetConfig).ShowOptions(showOptions).Execute() +> TargetConfig CreateTargetConfig(ctx).TargetConfig(targetConfig).ShowOptions(showOptions).Execute() -Add a target config +Create a target config @@ -31,18 +31,18 @@ import ( ) func main() { - targetConfig := *openapiclient.NewAddTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewProviderInfo("Name_example", "RunnerId_example", "RunnerName_example", map[string]TargetConfigProperty{"key": *openapiclient.NewTargetConfigProperty()}, "Version_example")) // AddTargetConfigDTO | Target config to add + targetConfig := *openapiclient.NewCreateTargetConfigDTO("Name_example", "Options_example", *openapiclient.NewProviderInfo("Name_example", "RunnerId_example", "RunnerName_example", map[string]TargetConfigProperty{"key": *openapiclient.NewTargetConfigProperty()}, "Version_example")) // CreateTargetConfigDTO | Target config to create showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetConfigAPI.AddTargetConfig(context.Background()).TargetConfig(targetConfig).ShowOptions(showOptions).Execute() + resp, r, err := apiClient.TargetConfigAPI.CreateTargetConfig(context.Background()).TargetConfig(targetConfig).ShowOptions(showOptions).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.AddTargetConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.CreateTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `AddTargetConfig`: TargetConfig - fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.AddTargetConfig`: %v\n", resp) + // response from `CreateTargetConfig`: TargetConfig + fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.CreateTargetConfig`: %v\n", resp) } ``` @@ -52,12 +52,12 @@ func main() { ### Other Parameters -Other parameters are passed through a pointer to a apiAddTargetConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiCreateTargetConfigRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **targetConfig** | [**AddTargetConfigDTO**](AddTargetConfigDTO.md) | Target config to add | + **targetConfig** | [**CreateTargetConfigDTO**](CreateTargetConfigDTO.md) | Target config to create | **showOptions** | **bool** | Show target config options | ### Return type @@ -78,11 +78,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## ListTargetConfigs +## DeleteTargetConfig -> []TargetConfig ListTargetConfigs(ctx).ShowOptions(showOptions).Execute() +> DeleteTargetConfig(ctx, configId).Execute() -List target configs +Delete a target config @@ -99,36 +99,38 @@ import ( ) func main() { - showOptions := true // bool | Show target config options (optional) + configId := "configId_example" // string | Target Config Id configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).ShowOptions(showOptions).Execute() + r, err := apiClient.TargetConfigAPI.DeleteTargetConfig(context.Background(), configId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.ListTargetConfigs``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.DeleteTargetConfig``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListTargetConfigs`: []TargetConfig - fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.ListTargetConfigs`: %v\n", resp) } ``` ### Path Parameters +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**configId** | **string** | Target Config Id | ### Other Parameters -Other parameters are passed through a pointer to a apiListTargetConfigsRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteTargetConfigRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **showOptions** | **bool** | Show target config options | + ### Return type -[**[]TargetConfig**](TargetConfig.md) + (empty response body) ### Authorization @@ -137,18 +139,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## RemoveTargetConfig +## ListTargetConfigs -> RemoveTargetConfig(ctx, configId).Execute() +> []TargetConfig ListTargetConfigs(ctx).ShowOptions(showOptions).Execute() -Remove a target config +List target configs @@ -165,38 +167,36 @@ import ( ) func main() { - configId := "configId_example" // string | Target Config Id + showOptions := true // bool | Show target config options (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.TargetConfigAPI.RemoveTargetConfig(context.Background(), configId).Execute() + resp, r, err := apiClient.TargetConfigAPI.ListTargetConfigs(context.Background()).ShowOptions(showOptions).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.RemoveTargetConfig``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `TargetConfigAPI.ListTargetConfigs``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListTargetConfigs`: []TargetConfig + fmt.Fprintf(os.Stdout, "Response from `TargetConfigAPI.ListTargetConfigs`: %v\n", resp) } ``` ### Path Parameters -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**configId** | **string** | Target Config Id | ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveTargetConfigRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiListTargetConfigsRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - + **showOptions** | **bool** | Show target config options | ### Return type - (empty response body) +[**[]TargetConfig**](TargetConfig.md) ### Authorization @@ -205,7 +205,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 263855322b..8512fc845f 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -5,12 +5,12 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- [**CreateWorkspace**](WorkspaceAPI.md#CreateWorkspace) | **Post** /workspace | Create a workspace -[**GetWorkspace**](WorkspaceAPI.md#GetWorkspace) | **Get** /workspace/{workspaceId} | Get workspace info +[**DeleteWorkspace**](WorkspaceAPI.md#DeleteWorkspace) | **Delete** /workspace/{workspaceId} | Delete workspace +[**FindWorkspace**](WorkspaceAPI.md#FindWorkspace) | **Get** /workspace/{workspaceId} | Find workspace [**ListWorkspaces**](WorkspaceAPI.md#ListWorkspaces) | **Get** /workspace | List workspaces -[**RemoveWorkspace**](WorkspaceAPI.md#RemoveWorkspace) | **Delete** /workspace/{workspaceId} | Remove workspace -[**SetWorkspaceMetadata**](WorkspaceAPI.md#SetWorkspaceMetadata) | **Post** /workspace/{workspaceId}/metadata | Set workspace metadata [**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace [**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +[**UpdateWorkspaceMetadata**](WorkspaceAPI.md#UpdateWorkspaceMetadata) | **Post** /workspace/{workspaceId}/metadata | Update workspace metadata [**UpdateWorkspaceProviderMetadata**](WorkspaceAPI.md#UpdateWorkspaceProviderMetadata) | **Post** /workspace/{workspaceId}/provider-metadata | Update workspace provider metadata @@ -81,11 +81,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetWorkspace +## DeleteWorkspace -> WorkspaceDTO GetWorkspace(ctx, workspaceId).Execute() +> DeleteWorkspace(ctx, workspaceId).Force(force).Execute() -Get workspace info +Delete workspace @@ -102,17 +102,16 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + workspaceId := "workspaceId_example" // string | Workspace ID + force := true // bool | Force (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.GetWorkspace(context.Background(), workspaceId).Execute() + r, err := apiClient.WorkspaceAPI.DeleteWorkspace(context.Background(), workspaceId).Force(force).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.GetWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.DeleteWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetWorkspace`: WorkspaceDTO - fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.GetWorkspace`: %v\n", resp) } ``` @@ -122,20 +121,21 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**workspaceId** | **string** | Workspace ID | ### Other Parameters -Other parameters are passed through a pointer to a apiGetWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiDeleteWorkspaceRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **force** | **bool** | Force | ### Return type -[**WorkspaceDTO**](WorkspaceDTO.md) + (empty response body) ### Authorization @@ -144,18 +144,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## ListWorkspaces +## FindWorkspace -> []WorkspaceDTO ListWorkspaces(ctx).Execute() +> WorkspaceDTO FindWorkspace(ctx, workspaceId).Execute() -List workspaces +Find workspace @@ -172,31 +172,40 @@ import ( ) func main() { + workspaceId := "workspaceId_example" // string | Workspace ID or Name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Execute() + resp, r, err := apiClient.WorkspaceAPI.FindWorkspace(context.Background(), workspaceId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.ListWorkspaces``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.FindWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `ListWorkspaces`: []WorkspaceDTO - fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.ListWorkspaces`: %v\n", resp) + // response from `FindWorkspace`: WorkspaceDTO + fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.FindWorkspace`: %v\n", resp) } ``` ### Path Parameters -This endpoint does not need any parameter. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiListWorkspacesRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- ### Return type -[**[]WorkspaceDTO**](WorkspaceDTO.md) +[**WorkspaceDTO**](WorkspaceDTO.md) ### Authorization @@ -212,11 +221,11 @@ Other parameters are passed through a pointer to a apiListWorkspacesRequest stru [[Back to README]](../README.md) -## RemoveWorkspace +## ListWorkspaces -> RemoveWorkspace(ctx, workspaceId).Force(force).Execute() +> []WorkspaceDTO ListWorkspaces(ctx).Execute() -Remove workspace +List workspaces @@ -233,40 +242,31 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID - force := true // bool | Force (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.RemoveWorkspace(context.Background(), workspaceId).Force(force).Execute() + resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.RemoveWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.ListWorkspaces``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } + // response from `ListWorkspaces`: []WorkspaceDTO + fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.ListWorkspaces`: %v\n", resp) } ``` ### Path Parameters - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID | +This endpoint does not need any parameter. ### Other Parameters -Other parameters are passed through a pointer to a apiRemoveWorkspaceRequest struct via the builder pattern - - -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- +Other parameters are passed through a pointer to a apiListWorkspacesRequest struct via the builder pattern - **force** | **bool** | Force | ### Return type - (empty response body) +[**[]WorkspaceDTO**](WorkspaceDTO.md) ### Authorization @@ -275,18 +275,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: Not defined +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## SetWorkspaceMetadata +## StartWorkspace -> SetWorkspaceMetadata(ctx, workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() +> StartWorkspace(ctx, workspaceId).Execute() -Set workspace metadata +Start workspace @@ -303,14 +303,13 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID - workspaceMetadata := *openapiclient.NewUpdateWorkspaceMetadataDTO(int32(123)) // UpdateWorkspaceMetadataDTO | Workspace Metadata + workspaceId := "workspaceId_example" // string | Workspace ID or Name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.SetWorkspaceMetadata(context.Background(), workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() + r, err := apiClient.WorkspaceAPI.StartWorkspace(context.Background(), workspaceId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.SetWorkspaceMetadata``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StartWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -322,17 +321,16 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID | +**workspaceId** | **string** | Workspace ID or Name | ### Other Parameters -Other parameters are passed through a pointer to a apiSetWorkspaceMetadataRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStartWorkspaceRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **workspaceMetadata** | [**UpdateWorkspaceMetadataDTO**](UpdateWorkspaceMetadataDTO.md) | Workspace Metadata | ### Return type @@ -352,11 +350,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StartWorkspace +## StopWorkspace -> StartWorkspace(ctx, workspaceId).Execute() +> StopWorkspace(ctx, workspaceId).Execute() -Start workspace +Stop workspace @@ -377,9 +375,9 @@ func main() { configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.StartWorkspace(context.Background(), workspaceId).Execute() + r, err := apiClient.WorkspaceAPI.StopWorkspace(context.Background(), workspaceId).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StartWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StopWorkspace``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -395,7 +393,7 @@ Name | Type | Description | Notes ### Other Parameters -Other parameters are passed through a pointer to a apiStartWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiStopWorkspaceRequest struct via the builder pattern Name | Type | Description | Notes @@ -420,11 +418,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## StopWorkspace +## UpdateWorkspaceMetadata -> StopWorkspace(ctx, workspaceId).Execute() +> UpdateWorkspaceMetadata(ctx, workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() -Stop workspace +Update workspace metadata @@ -441,13 +439,14 @@ import ( ) func main() { - workspaceId := "workspaceId_example" // string | Workspace ID or Name + workspaceId := "workspaceId_example" // string | Workspace ID + workspaceMetadata := *openapiclient.NewUpdateWorkspaceMetadataDTO(int32(123)) // UpdateWorkspaceMetadataDTO | Workspace Metadata configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceAPI.StopWorkspace(context.Background(), workspaceId).Execute() + r, err := apiClient.WorkspaceAPI.UpdateWorkspaceMetadata(context.Background(), workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.StopWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.UpdateWorkspaceMetadata``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -459,16 +458,17 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**workspaceId** | **string** | Workspace ID or Name | +**workspaceId** | **string** | Workspace ID | ### Other Parameters -Other parameters are passed through a pointer to a apiStopWorkspaceRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiUpdateWorkspaceMetadataRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- + **workspaceMetadata** | [**UpdateWorkspaceMetadataDTO**](UpdateWorkspaceMetadataDTO.md) | Workspace Metadata | ### Return type diff --git a/pkg/apiclient/docs/WorkspaceTemplateAPI.md b/pkg/apiclient/docs/WorkspaceTemplateAPI.md index a3b70abf65..23d8bb1025 100644 --- a/pkg/apiclient/docs/WorkspaceTemplateAPI.md +++ b/pkg/apiclient/docs/WorkspaceTemplateAPI.md @@ -5,11 +5,11 @@ All URIs are relative to *http://localhost:3986* Method | HTTP request | Description ------------- | ------------- | ------------- [**DeleteWorkspaceTemplate**](WorkspaceTemplateAPI.md#DeleteWorkspaceTemplate) | **Delete** /workspace-template/{templateName} | Delete workspace template data -[**GetDefaultWorkspaceTemplate**](WorkspaceTemplateAPI.md#GetDefaultWorkspaceTemplate) | **Get** /workspace-template/default/{gitUrl} | Get workspace templates by git url -[**GetWorkspaceTemplate**](WorkspaceTemplateAPI.md#GetWorkspaceTemplate) | **Get** /workspace-template/{templateName} | Get workspace template data +[**FindWorkspaceTemplate**](WorkspaceTemplateAPI.md#FindWorkspaceTemplate) | **Get** /workspace-template/{templateName} | Find a workspace template +[**GetDefaultWorkspaceTemplate**](WorkspaceTemplateAPI.md#GetDefaultWorkspaceTemplate) | **Get** /workspace-template/default/{gitUrl} | Get default workspace templates by git url [**ListWorkspaceTemplates**](WorkspaceTemplateAPI.md#ListWorkspaceTemplates) | **Get** /workspace-template | List workspace templates +[**SaveWorkspaceTemplate**](WorkspaceTemplateAPI.md#SaveWorkspaceTemplate) | **Put** /workspace-template | Set workspace template data [**SetDefaultWorkspaceTemplate**](WorkspaceTemplateAPI.md#SetDefaultWorkspaceTemplate) | **Patch** /workspace-template/{templateName}/set-default | Set workspace template to default -[**SetWorkspaceTemplate**](WorkspaceTemplateAPI.md#SetWorkspaceTemplate) | **Put** /workspace-template | Set workspace template data @@ -83,11 +83,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## GetDefaultWorkspaceTemplate +## FindWorkspaceTemplate -> WorkspaceTemplate GetDefaultWorkspaceTemplate(ctx, gitUrl).Execute() +> WorkspaceTemplate FindWorkspaceTemplate(ctx, templateName).Execute() -Get workspace templates by git url +Find a workspace template @@ -104,17 +104,17 @@ import ( ) func main() { - gitUrl := "gitUrl_example" // string | Git URL + templateName := "templateName_example" // string | Template name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate(context.Background(), gitUrl).Execute() + resp, r, err := apiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(context.Background(), templateName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.FindWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetDefaultWorkspaceTemplate`: WorkspaceTemplate - fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate`: %v\n", resp) + // response from `FindWorkspaceTemplate`: WorkspaceTemplate + fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.FindWorkspaceTemplate`: %v\n", resp) } ``` @@ -124,11 +124,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**gitUrl** | **string** | Git URL | +**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiGetDefaultWorkspaceTemplateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiFindWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -146,18 +146,18 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: application/json +- **Accept**: */* [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) -## GetWorkspaceTemplate +## GetDefaultWorkspaceTemplate -> WorkspaceTemplate GetWorkspaceTemplate(ctx, templateName).Execute() +> WorkspaceTemplate GetDefaultWorkspaceTemplate(ctx, gitUrl).Execute() -Get workspace template data +Get default workspace templates by git url @@ -174,17 +174,17 @@ import ( ) func main() { - templateName := "templateName_example" // string | Template name + gitUrl := "gitUrl_example" // string | Git URL configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(context.Background(), templateName).Execute() + resp, r, err := apiClient.WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate(context.Background(), gitUrl).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.GetWorkspaceTemplate``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } - // response from `GetWorkspaceTemplate`: WorkspaceTemplate - fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.GetWorkspaceTemplate`: %v\n", resp) + // response from `GetDefaultWorkspaceTemplate`: WorkspaceTemplate + fmt.Fprintf(os.Stdout, "Response from `WorkspaceTemplateAPI.GetDefaultWorkspaceTemplate`: %v\n", resp) } ``` @@ -194,11 +194,11 @@ func main() { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**templateName** | **string** | Template name | +**gitUrl** | **string** | Git URL | ### Other Parameters -Other parameters are passed through a pointer to a apiGetWorkspaceTemplateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiGetDefaultWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes @@ -216,7 +216,7 @@ Name | Type | Description | Notes ### HTTP request headers - **Content-Type**: Not defined -- **Accept**: */* +- **Accept**: application/json [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) @@ -284,11 +284,11 @@ Other parameters are passed through a pointer to a apiListWorkspaceTemplatesRequ [[Back to README]](../README.md) -## SetDefaultWorkspaceTemplate +## SaveWorkspaceTemplate -> SetDefaultWorkspaceTemplate(ctx, templateName).Execute() +> SaveWorkspaceTemplate(ctx).WorkspaceTemplate(workspaceTemplate).Execute() -Set workspace template to default +Set workspace template data @@ -305,13 +305,13 @@ import ( ) func main() { - templateName := "templateName_example" // string | Template name + workspaceTemplate := *openapiclient.NewCreateWorkspaceTemplateDTO(map[string]string{"key": "Inner_example"}, "Name_example", "RepositoryUrl_example") // CreateWorkspaceTemplateDTO | Workspace template configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate(context.Background(), templateName).Execute() + r, err := apiClient.WorkspaceTemplateAPI.SaveWorkspaceTemplate(context.Background()).WorkspaceTemplate(workspaceTemplate).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.SaveWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -320,19 +320,15 @@ func main() { ### Path Parameters -Name | Type | Description | Notes -------------- | ------------- | ------------- | ------------- -**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. -**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiSetDefaultWorkspaceTemplateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSaveWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - + **workspaceTemplate** | [**CreateWorkspaceTemplateDTO**](CreateWorkspaceTemplateDTO.md) | Workspace template | ### Return type @@ -344,7 +340,7 @@ Name | Type | Description | Notes ### HTTP request headers -- **Content-Type**: Not defined +- **Content-Type**: application/json - **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) @@ -352,11 +348,11 @@ Name | Type | Description | Notes [[Back to README]](../README.md) -## SetWorkspaceTemplate +## SetDefaultWorkspaceTemplate -> SetWorkspaceTemplate(ctx).WorkspaceTemplate(workspaceTemplate).Execute() +> SetDefaultWorkspaceTemplate(ctx, templateName).Execute() -Set workspace template data +Set workspace template to default @@ -373,13 +369,13 @@ import ( ) func main() { - workspaceTemplate := *openapiclient.NewCreateWorkspaceTemplateDTO(map[string]string{"key": "Inner_example"}, "Name_example", "RepositoryUrl_example") // CreateWorkspaceTemplateDTO | Workspace template + templateName := "templateName_example" // string | Template name configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - r, err := apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(context.Background()).WorkspaceTemplate(workspaceTemplate).Execute() + r, err := apiClient.WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate(context.Background(), templateName).Execute() if err != nil { - fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.SetWorkspaceTemplate``: %v\n", err) + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceTemplateAPI.SetDefaultWorkspaceTemplate``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) } } @@ -388,15 +384,19 @@ func main() { ### Path Parameters +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**templateName** | **string** | Template name | ### Other Parameters -Other parameters are passed through a pointer to a apiSetWorkspaceTemplateRequest struct via the builder pattern +Other parameters are passed through a pointer to a apiSetDefaultWorkspaceTemplateRequest struct via the builder pattern Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - **workspaceTemplate** | [**CreateWorkspaceTemplateDTO**](CreateWorkspaceTemplateDTO.md) | Workspace template | + ### Return type @@ -408,7 +408,7 @@ Name | Type | Description | Notes ### HTTP request headers -- **Content-Type**: application/json +- **Content-Type**: Not defined - **Accept**: Not defined [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) diff --git a/pkg/apiclient/model_register_runner_dto.go b/pkg/apiclient/model_create_runner_dto.go similarity index 58% rename from pkg/apiclient/model_register_runner_dto.go rename to pkg/apiclient/model_create_runner_dto.go index 9be610e366..7d80cccbb5 100644 --- a/pkg/apiclient/model_register_runner_dto.go +++ b/pkg/apiclient/model_create_runner_dto.go @@ -16,38 +16,38 @@ import ( "fmt" ) -// checks if the RegisterRunnerDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &RegisterRunnerDTO{} +// checks if the CreateRunnerDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateRunnerDTO{} -// RegisterRunnerDTO struct for RegisterRunnerDTO -type RegisterRunnerDTO struct { +// CreateRunnerDTO struct for CreateRunnerDTO +type CreateRunnerDTO struct { Id string `json:"id"` Name string `json:"name"` } -type _RegisterRunnerDTO RegisterRunnerDTO +type _CreateRunnerDTO CreateRunnerDTO -// NewRegisterRunnerDTO instantiates a new RegisterRunnerDTO object +// NewCreateRunnerDTO instantiates a new CreateRunnerDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewRegisterRunnerDTO(id string, name string) *RegisterRunnerDTO { - this := RegisterRunnerDTO{} +func NewCreateRunnerDTO(id string, name string) *CreateRunnerDTO { + this := CreateRunnerDTO{} this.Id = id this.Name = name return &this } -// NewRegisterRunnerDTOWithDefaults instantiates a new RegisterRunnerDTO object +// NewCreateRunnerDTOWithDefaults instantiates a new CreateRunnerDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewRegisterRunnerDTOWithDefaults() *RegisterRunnerDTO { - this := RegisterRunnerDTO{} +func NewCreateRunnerDTOWithDefaults() *CreateRunnerDTO { + this := CreateRunnerDTO{} return &this } // GetId returns the Id field value -func (o *RegisterRunnerDTO) GetId() string { +func (o *CreateRunnerDTO) GetId() string { if o == nil { var ret string return ret @@ -58,7 +58,7 @@ func (o *RegisterRunnerDTO) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *RegisterRunnerDTO) GetIdOk() (*string, bool) { +func (o *CreateRunnerDTO) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -66,12 +66,12 @@ func (o *RegisterRunnerDTO) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *RegisterRunnerDTO) SetId(v string) { +func (o *CreateRunnerDTO) SetId(v string) { o.Id = v } // GetName returns the Name field value -func (o *RegisterRunnerDTO) GetName() string { +func (o *CreateRunnerDTO) GetName() string { if o == nil { var ret string return ret @@ -82,7 +82,7 @@ func (o *RegisterRunnerDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *RegisterRunnerDTO) GetNameOk() (*string, bool) { +func (o *CreateRunnerDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -90,11 +90,11 @@ func (o *RegisterRunnerDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *RegisterRunnerDTO) SetName(v string) { +func (o *CreateRunnerDTO) SetName(v string) { o.Name = v } -func (o RegisterRunnerDTO) MarshalJSON() ([]byte, error) { +func (o CreateRunnerDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -102,14 +102,14 @@ func (o RegisterRunnerDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o RegisterRunnerDTO) ToMap() (map[string]interface{}, error) { +func (o CreateRunnerDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["id"] = o.Id toSerialize["name"] = o.Name return toSerialize, nil } -func (o *RegisterRunnerDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateRunnerDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -132,53 +132,53 @@ func (o *RegisterRunnerDTO) UnmarshalJSON(data []byte) (err error) { } } - varRegisterRunnerDTO := _RegisterRunnerDTO{} + varCreateRunnerDTO := _CreateRunnerDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varRegisterRunnerDTO) + err = decoder.Decode(&varCreateRunnerDTO) if err != nil { return err } - *o = RegisterRunnerDTO(varRegisterRunnerDTO) + *o = CreateRunnerDTO(varCreateRunnerDTO) return err } -type NullableRegisterRunnerDTO struct { - value *RegisterRunnerDTO +type NullableCreateRunnerDTO struct { + value *CreateRunnerDTO isSet bool } -func (v NullableRegisterRunnerDTO) Get() *RegisterRunnerDTO { +func (v NullableCreateRunnerDTO) Get() *CreateRunnerDTO { return v.value } -func (v *NullableRegisterRunnerDTO) Set(val *RegisterRunnerDTO) { +func (v *NullableCreateRunnerDTO) Set(val *CreateRunnerDTO) { v.value = val v.isSet = true } -func (v NullableRegisterRunnerDTO) IsSet() bool { +func (v NullableCreateRunnerDTO) IsSet() bool { return v.isSet } -func (v *NullableRegisterRunnerDTO) Unset() { +func (v *NullableCreateRunnerDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableRegisterRunnerDTO(val *RegisterRunnerDTO) *NullableRegisterRunnerDTO { - return &NullableRegisterRunnerDTO{value: val, isSet: true} +func NewNullableCreateRunnerDTO(val *CreateRunnerDTO) *NullableCreateRunnerDTO { + return &NullableCreateRunnerDTO{value: val, isSet: true} } -func (v NullableRegisterRunnerDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateRunnerDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableRegisterRunnerDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateRunnerDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_register_runner_result_dto.go b/pkg/apiclient/model_create_runner_result_dto.go similarity index 60% rename from pkg/apiclient/model_register_runner_result_dto.go rename to pkg/apiclient/model_create_runner_result_dto.go index 59f0cb702f..799f0fcd2a 100644 --- a/pkg/apiclient/model_register_runner_result_dto.go +++ b/pkg/apiclient/model_create_runner_result_dto.go @@ -16,41 +16,41 @@ import ( "fmt" ) -// checks if the RegisterRunnerResultDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &RegisterRunnerResultDTO{} +// checks if the CreateRunnerResultDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateRunnerResultDTO{} -// RegisterRunnerResultDTO struct for RegisterRunnerResultDTO -type RegisterRunnerResultDTO struct { +// CreateRunnerResultDTO struct for CreateRunnerResultDTO +type CreateRunnerResultDTO struct { ApiKey string `json:"apiKey"` Id string `json:"id"` Metadata *RunnerMetadata `json:"metadata,omitempty"` Name string `json:"name"` } -type _RegisterRunnerResultDTO RegisterRunnerResultDTO +type _CreateRunnerResultDTO CreateRunnerResultDTO -// NewRegisterRunnerResultDTO instantiates a new RegisterRunnerResultDTO object +// NewCreateRunnerResultDTO instantiates a new CreateRunnerResultDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewRegisterRunnerResultDTO(apiKey string, id string, name string) *RegisterRunnerResultDTO { - this := RegisterRunnerResultDTO{} +func NewCreateRunnerResultDTO(apiKey string, id string, name string) *CreateRunnerResultDTO { + this := CreateRunnerResultDTO{} this.ApiKey = apiKey this.Id = id this.Name = name return &this } -// NewRegisterRunnerResultDTOWithDefaults instantiates a new RegisterRunnerResultDTO object +// NewCreateRunnerResultDTOWithDefaults instantiates a new CreateRunnerResultDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewRegisterRunnerResultDTOWithDefaults() *RegisterRunnerResultDTO { - this := RegisterRunnerResultDTO{} +func NewCreateRunnerResultDTOWithDefaults() *CreateRunnerResultDTO { + this := CreateRunnerResultDTO{} return &this } // GetApiKey returns the ApiKey field value -func (o *RegisterRunnerResultDTO) GetApiKey() string { +func (o *CreateRunnerResultDTO) GetApiKey() string { if o == nil { var ret string return ret @@ -61,7 +61,7 @@ func (o *RegisterRunnerResultDTO) GetApiKey() string { // GetApiKeyOk returns a tuple with the ApiKey field value // and a boolean to check if the value has been set. -func (o *RegisterRunnerResultDTO) GetApiKeyOk() (*string, bool) { +func (o *CreateRunnerResultDTO) GetApiKeyOk() (*string, bool) { if o == nil { return nil, false } @@ -69,12 +69,12 @@ func (o *RegisterRunnerResultDTO) GetApiKeyOk() (*string, bool) { } // SetApiKey sets field value -func (o *RegisterRunnerResultDTO) SetApiKey(v string) { +func (o *CreateRunnerResultDTO) SetApiKey(v string) { o.ApiKey = v } // GetId returns the Id field value -func (o *RegisterRunnerResultDTO) GetId() string { +func (o *CreateRunnerResultDTO) GetId() string { if o == nil { var ret string return ret @@ -85,7 +85,7 @@ func (o *RegisterRunnerResultDTO) GetId() string { // GetIdOk returns a tuple with the Id field value // and a boolean to check if the value has been set. -func (o *RegisterRunnerResultDTO) GetIdOk() (*string, bool) { +func (o *CreateRunnerResultDTO) GetIdOk() (*string, bool) { if o == nil { return nil, false } @@ -93,12 +93,12 @@ func (o *RegisterRunnerResultDTO) GetIdOk() (*string, bool) { } // SetId sets field value -func (o *RegisterRunnerResultDTO) SetId(v string) { +func (o *CreateRunnerResultDTO) SetId(v string) { o.Id = v } // GetMetadata returns the Metadata field value if set, zero value otherwise. -func (o *RegisterRunnerResultDTO) GetMetadata() RunnerMetadata { +func (o *CreateRunnerResultDTO) GetMetadata() RunnerMetadata { if o == nil || IsNil(o.Metadata) { var ret RunnerMetadata return ret @@ -108,7 +108,7 @@ func (o *RegisterRunnerResultDTO) GetMetadata() RunnerMetadata { // GetMetadataOk returns a tuple with the Metadata field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *RegisterRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool) { +func (o *CreateRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool) { if o == nil || IsNil(o.Metadata) { return nil, false } @@ -116,7 +116,7 @@ func (o *RegisterRunnerResultDTO) GetMetadataOk() (*RunnerMetadata, bool) { } // HasMetadata returns a boolean if a field has been set. -func (o *RegisterRunnerResultDTO) HasMetadata() bool { +func (o *CreateRunnerResultDTO) HasMetadata() bool { if o != nil && !IsNil(o.Metadata) { return true } @@ -125,12 +125,12 @@ func (o *RegisterRunnerResultDTO) HasMetadata() bool { } // SetMetadata gets a reference to the given RunnerMetadata and assigns it to the Metadata field. -func (o *RegisterRunnerResultDTO) SetMetadata(v RunnerMetadata) { +func (o *CreateRunnerResultDTO) SetMetadata(v RunnerMetadata) { o.Metadata = &v } // GetName returns the Name field value -func (o *RegisterRunnerResultDTO) GetName() string { +func (o *CreateRunnerResultDTO) GetName() string { if o == nil { var ret string return ret @@ -141,7 +141,7 @@ func (o *RegisterRunnerResultDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *RegisterRunnerResultDTO) GetNameOk() (*string, bool) { +func (o *CreateRunnerResultDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -149,11 +149,11 @@ func (o *RegisterRunnerResultDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *RegisterRunnerResultDTO) SetName(v string) { +func (o *CreateRunnerResultDTO) SetName(v string) { o.Name = v } -func (o RegisterRunnerResultDTO) MarshalJSON() ([]byte, error) { +func (o CreateRunnerResultDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -161,7 +161,7 @@ func (o RegisterRunnerResultDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o RegisterRunnerResultDTO) ToMap() (map[string]interface{}, error) { +func (o CreateRunnerResultDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["apiKey"] = o.ApiKey toSerialize["id"] = o.Id @@ -172,7 +172,7 @@ func (o RegisterRunnerResultDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *RegisterRunnerResultDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateRunnerResultDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -196,53 +196,53 @@ func (o *RegisterRunnerResultDTO) UnmarshalJSON(data []byte) (err error) { } } - varRegisterRunnerResultDTO := _RegisterRunnerResultDTO{} + varCreateRunnerResultDTO := _CreateRunnerResultDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varRegisterRunnerResultDTO) + err = decoder.Decode(&varCreateRunnerResultDTO) if err != nil { return err } - *o = RegisterRunnerResultDTO(varRegisterRunnerResultDTO) + *o = CreateRunnerResultDTO(varCreateRunnerResultDTO) return err } -type NullableRegisterRunnerResultDTO struct { - value *RegisterRunnerResultDTO +type NullableCreateRunnerResultDTO struct { + value *CreateRunnerResultDTO isSet bool } -func (v NullableRegisterRunnerResultDTO) Get() *RegisterRunnerResultDTO { +func (v NullableCreateRunnerResultDTO) Get() *CreateRunnerResultDTO { return v.value } -func (v *NullableRegisterRunnerResultDTO) Set(val *RegisterRunnerResultDTO) { +func (v *NullableCreateRunnerResultDTO) Set(val *CreateRunnerResultDTO) { v.value = val v.isSet = true } -func (v NullableRegisterRunnerResultDTO) IsSet() bool { +func (v NullableCreateRunnerResultDTO) IsSet() bool { return v.isSet } -func (v *NullableRegisterRunnerResultDTO) Unset() { +func (v *NullableCreateRunnerResultDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableRegisterRunnerResultDTO(val *RegisterRunnerResultDTO) *NullableRegisterRunnerResultDTO { - return &NullableRegisterRunnerResultDTO{value: val, isSet: true} +func NewNullableCreateRunnerResultDTO(val *CreateRunnerResultDTO) *NullableCreateRunnerResultDTO { + return &NullableCreateRunnerResultDTO{value: val, isSet: true} } -func (v NullableRegisterRunnerResultDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateRunnerResultDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableRegisterRunnerResultDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateRunnerResultDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/apiclient/model_add_target_config_dto.go b/pkg/apiclient/model_create_target_config_dto.go similarity index 58% rename from pkg/apiclient/model_add_target_config_dto.go rename to pkg/apiclient/model_create_target_config_dto.go index b66fa5ed3c..bb05ee4290 100644 --- a/pkg/apiclient/model_add_target_config_dto.go +++ b/pkg/apiclient/model_create_target_config_dto.go @@ -16,40 +16,40 @@ import ( "fmt" ) -// checks if the AddTargetConfigDTO type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &AddTargetConfigDTO{} +// checks if the CreateTargetConfigDTO type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &CreateTargetConfigDTO{} -// AddTargetConfigDTO struct for AddTargetConfigDTO -type AddTargetConfigDTO struct { +// CreateTargetConfigDTO struct for CreateTargetConfigDTO +type CreateTargetConfigDTO struct { Name string `json:"name"` Options string `json:"options"` ProviderInfo ProviderInfo `json:"providerInfo"` } -type _AddTargetConfigDTO AddTargetConfigDTO +type _CreateTargetConfigDTO CreateTargetConfigDTO -// NewAddTargetConfigDTO instantiates a new AddTargetConfigDTO object +// NewCreateTargetConfigDTO instantiates a new CreateTargetConfigDTO object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewAddTargetConfigDTO(name string, options string, providerInfo ProviderInfo) *AddTargetConfigDTO { - this := AddTargetConfigDTO{} +func NewCreateTargetConfigDTO(name string, options string, providerInfo ProviderInfo) *CreateTargetConfigDTO { + this := CreateTargetConfigDTO{} this.Name = name this.Options = options this.ProviderInfo = providerInfo return &this } -// NewAddTargetConfigDTOWithDefaults instantiates a new AddTargetConfigDTO object +// NewCreateTargetConfigDTOWithDefaults instantiates a new CreateTargetConfigDTO object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewAddTargetConfigDTOWithDefaults() *AddTargetConfigDTO { - this := AddTargetConfigDTO{} +func NewCreateTargetConfigDTOWithDefaults() *CreateTargetConfigDTO { + this := CreateTargetConfigDTO{} return &this } // GetName returns the Name field value -func (o *AddTargetConfigDTO) GetName() string { +func (o *CreateTargetConfigDTO) GetName() string { if o == nil { var ret string return ret @@ -60,7 +60,7 @@ func (o *AddTargetConfigDTO) GetName() string { // GetNameOk returns a tuple with the Name field value // and a boolean to check if the value has been set. -func (o *AddTargetConfigDTO) GetNameOk() (*string, bool) { +func (o *CreateTargetConfigDTO) GetNameOk() (*string, bool) { if o == nil { return nil, false } @@ -68,12 +68,12 @@ func (o *AddTargetConfigDTO) GetNameOk() (*string, bool) { } // SetName sets field value -func (o *AddTargetConfigDTO) SetName(v string) { +func (o *CreateTargetConfigDTO) SetName(v string) { o.Name = v } // GetOptions returns the Options field value -func (o *AddTargetConfigDTO) GetOptions() string { +func (o *CreateTargetConfigDTO) GetOptions() string { if o == nil { var ret string return ret @@ -84,7 +84,7 @@ func (o *AddTargetConfigDTO) GetOptions() string { // GetOptionsOk returns a tuple with the Options field value // and a boolean to check if the value has been set. -func (o *AddTargetConfigDTO) GetOptionsOk() (*string, bool) { +func (o *CreateTargetConfigDTO) GetOptionsOk() (*string, bool) { if o == nil { return nil, false } @@ -92,12 +92,12 @@ func (o *AddTargetConfigDTO) GetOptionsOk() (*string, bool) { } // SetOptions sets field value -func (o *AddTargetConfigDTO) SetOptions(v string) { +func (o *CreateTargetConfigDTO) SetOptions(v string) { o.Options = v } // GetProviderInfo returns the ProviderInfo field value -func (o *AddTargetConfigDTO) GetProviderInfo() ProviderInfo { +func (o *CreateTargetConfigDTO) GetProviderInfo() ProviderInfo { if o == nil { var ret ProviderInfo return ret @@ -108,7 +108,7 @@ func (o *AddTargetConfigDTO) GetProviderInfo() ProviderInfo { // GetProviderInfoOk returns a tuple with the ProviderInfo field value // and a boolean to check if the value has been set. -func (o *AddTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool) { +func (o *CreateTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool) { if o == nil { return nil, false } @@ -116,11 +116,11 @@ func (o *AddTargetConfigDTO) GetProviderInfoOk() (*ProviderInfo, bool) { } // SetProviderInfo sets field value -func (o *AddTargetConfigDTO) SetProviderInfo(v ProviderInfo) { +func (o *CreateTargetConfigDTO) SetProviderInfo(v ProviderInfo) { o.ProviderInfo = v } -func (o AddTargetConfigDTO) MarshalJSON() ([]byte, error) { +func (o CreateTargetConfigDTO) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -128,7 +128,7 @@ func (o AddTargetConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o AddTargetConfigDTO) ToMap() (map[string]interface{}, error) { +func (o CreateTargetConfigDTO) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} toSerialize["name"] = o.Name toSerialize["options"] = o.Options @@ -136,7 +136,7 @@ func (o AddTargetConfigDTO) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -func (o *AddTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { +func (o *CreateTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { // This validates that all required properties are included in the JSON object // by unmarshalling the object into a generic map with string keys and checking // that every required field exists as a key in the generic map. @@ -160,53 +160,53 @@ func (o *AddTargetConfigDTO) UnmarshalJSON(data []byte) (err error) { } } - varAddTargetConfigDTO := _AddTargetConfigDTO{} + varCreateTargetConfigDTO := _CreateTargetConfigDTO{} decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - err = decoder.Decode(&varAddTargetConfigDTO) + err = decoder.Decode(&varCreateTargetConfigDTO) if err != nil { return err } - *o = AddTargetConfigDTO(varAddTargetConfigDTO) + *o = CreateTargetConfigDTO(varCreateTargetConfigDTO) return err } -type NullableAddTargetConfigDTO struct { - value *AddTargetConfigDTO +type NullableCreateTargetConfigDTO struct { + value *CreateTargetConfigDTO isSet bool } -func (v NullableAddTargetConfigDTO) Get() *AddTargetConfigDTO { +func (v NullableCreateTargetConfigDTO) Get() *CreateTargetConfigDTO { return v.value } -func (v *NullableAddTargetConfigDTO) Set(val *AddTargetConfigDTO) { +func (v *NullableCreateTargetConfigDTO) Set(val *CreateTargetConfigDTO) { v.value = val v.isSet = true } -func (v NullableAddTargetConfigDTO) IsSet() bool { +func (v NullableCreateTargetConfigDTO) IsSet() bool { return v.isSet } -func (v *NullableAddTargetConfigDTO) Unset() { +func (v *NullableCreateTargetConfigDTO) Unset() { v.value = nil v.isSet = false } -func NewNullableAddTargetConfigDTO(val *AddTargetConfigDTO) *NullableAddTargetConfigDTO { - return &NullableAddTargetConfigDTO{value: val, isSet: true} +func NewNullableCreateTargetConfigDTO(val *CreateTargetConfigDTO) *NullableCreateTargetConfigDTO { + return &NullableCreateTargetConfigDTO{value: val, isSet: true} } -func (v NullableAddTargetConfigDTO) MarshalJSON() ([]byte, error) { +func (v NullableCreateTargetConfigDTO) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableAddTargetConfigDTO) UnmarshalJSON(src []byte) error { +func (v *NullableCreateTargetConfigDTO) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/pkg/cmd/agent/agent.go b/pkg/cmd/agent/agent.go index a7960cd1ed..6682cc9cd5 100644 --- a/pkg/cmd/agent/agent.go +++ b/pkg/cmd/agent/agent.go @@ -169,7 +169,7 @@ func getWorkspace(c *agent_config.Config, telemetryEnabled bool) (*models.Worksp return nil, err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, c.WorkspaceId).Execute() + workspace, res, err := apiClient.WorkspaceAPI.FindWorkspace(ctx, c.WorkspaceId).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/agent/logs.go b/pkg/cmd/agent/logs.go index 6767c85217..399b87584e 100644 --- a/pkg/cmd/agent/logs.go +++ b/pkg/cmd/agent/logs.go @@ -11,6 +11,7 @@ import ( "os" "github.com/daytonaio/daytona/pkg/agent/config" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/spf13/cobra" ) @@ -18,8 +19,9 @@ import ( var followFlag bool var logsCmd = &cobra.Command{ - Use: "logs", - Short: "Output Daytona Agent logs", + Use: "logs", + Short: "Output Daytona Agent logs", + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { logFilePath := config.GetLogFilePath() diff --git a/pkg/cmd/agentmode/docker_cred.go b/pkg/cmd/agentmode/docker_cred.go index ff7863a545..1b7f491bc8 100644 --- a/pkg/cmd/agentmode/docker_cred.go +++ b/pkg/cmd/agentmode/docker_cred.go @@ -35,7 +35,7 @@ var dockerCredCmd = &cobra.Command{ return err } - cr, _, err := apiClient.ContainerRegistryAPI.GetContainerRegistry(ctx, string(input)).WorkspaceId(workspaceId).Execute() + cr, _, err := apiClient.ContainerRegistryAPI.FindContainerRegistry(ctx, string(input)).WorkspaceId(workspaceId).Execute() if err != nil { os.Exit(1) } diff --git a/pkg/cmd/agentmode/forward.go b/pkg/cmd/agentmode/forward.go index 2e92e9c665..181750f78d 100644 --- a/pkg/cmd/agentmode/forward.go +++ b/pkg/cmd/agentmode/forward.go @@ -7,6 +7,7 @@ import ( "strconv" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/cmd/common" defaultPortForwardCmd "github.com/daytonaio/daytona/pkg/cmd/ports" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -17,6 +18,7 @@ var portForwardCmd = &cobra.Command{ Short: "Forward a port publicly via an URL", Args: cobra.ExactArgs(1), GroupID: util.TARGET_GROUP, + Aliases: common.GetAliases("forward"), RunE: func(cmd *cobra.Command, args []string) error { port, err := strconv.Atoi(args[0]) if err != nil { diff --git a/pkg/cmd/agentmode/git_cred.go b/pkg/cmd/agentmode/git_cred.go index f12dcf51d0..c33a6f149a 100644 --- a/pkg/cmd/agentmode/git_cred.go +++ b/pkg/cmd/agentmode/git_cred.go @@ -37,13 +37,13 @@ var gitCredCmd = &cobra.Command{ return err } - workspace, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + workspace, res, err := apiClient.WorkspaceAPI.FindWorkspace(ctx, workspaceId).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } if workspace.GitProviderConfigId != nil { - gitProvider, _, _ := apiClient.GitProviderAPI.GetGitProvider(ctx, *workspace.GitProviderConfigId).Execute() + gitProvider, _, _ := apiClient.GitProviderAPI.FindGitProvider(ctx, *workspace.GitProviderConfigId).Execute() if gitProvider != nil { fmt.Println("username=" + gitProvider.Username) fmt.Println("password=" + gitProvider.Token) diff --git a/pkg/cmd/agentmode/info.go b/pkg/cmd/agentmode/info.go index a4e8d008cb..70a13042d7 100644 --- a/pkg/cmd/agentmode/info.go +++ b/pkg/cmd/agentmode/info.go @@ -6,6 +6,7 @@ package agentmode import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" target_views "github.com/daytonaio/daytona/pkg/views/target/info" workspaces_views "github.com/daytonaio/daytona/pkg/views/workspace/info" @@ -15,9 +16,9 @@ import ( var infoCmd = &cobra.Command{ Use: "info", Short: "Show resource info", - Aliases: []string{"view", "inspect"}, Args: cobra.ExactArgs(0), GroupID: util.TARGET_GROUP, + Aliases: common.GetAliases("info"), RunE: func(cmd *cobra.Command, args []string) error { if isWorkspaceAgentMode() { return runWorkspaceInfo() diff --git a/pkg/cmd/agentmode/logs.go b/pkg/cmd/agentmode/logs.go index 7dbd1df771..7b9c07f8da 100644 --- a/pkg/cmd/agentmode/logs.go +++ b/pkg/cmd/agentmode/logs.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/agent/config" + "github.com/daytonaio/daytona/pkg/cmd/common" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/spf13/cobra" ) @@ -18,7 +19,7 @@ var logsCmd = &cobra.Command{ Short: "View resource logs", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, - Aliases: []string{"lg", "log"}, + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/apikey/api_key.go b/pkg/cmd/apikey/api_key.go index 378aa38d09..a1e49dc73f 100644 --- a/pkg/cmd/apikey/api_key.go +++ b/pkg/cmd/apikey/api_key.go @@ -13,10 +13,11 @@ var ApiKeyCmd = &cobra.Command{ Short: "Api Key commands", Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, + Aliases: []string{"api-keys"}, } func init() { - ApiKeyCmd.AddCommand(generateCmd) - ApiKeyCmd.AddCommand(revokeCmd) + ApiKeyCmd.AddCommand(createApiKeyCmd) + ApiKeyCmd.AddCommand(deleteCmd) ApiKeyCmd.AddCommand(listCmd) } diff --git a/pkg/cmd/apikey/generate.go b/pkg/cmd/apikey/create.go similarity index 84% rename from pkg/cmd/apikey/generate.go rename to pkg/cmd/apikey/create.go index 264cd05a64..46f19ce22d 100644 --- a/pkg/cmd/apikey/generate.go +++ b/pkg/cmd/apikey/create.go @@ -12,14 +12,15 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" view "github.com/daytonaio/daytona/pkg/views/apikey" ) -var generateCmd = &cobra.Command{ - Use: "generate [NAME]", - Short: "Generate a new API key", - Aliases: []string{"g", "new"}, +var createApiKeyCmd = &cobra.Command{ + Use: "create [NAME]", + Short: "Create a new API key", Args: cobra.RangeArgs(0, 1), + Aliases: common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var keyName string @@ -46,7 +47,7 @@ var generateCmd = &cobra.Command{ } } - key, _, err := apiClient.ApiKeyAPI.GenerateApiKey(ctx, keyName).Execute() + key, _, err := apiClient.ApiKeyAPI.CreateApiKey(ctx, keyName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(nil, err) } diff --git a/pkg/cmd/apikey/revoke.go b/pkg/cmd/apikey/delete.go similarity index 86% rename from pkg/cmd/apikey/revoke.go rename to pkg/cmd/apikey/delete.go index 439d3eb352..38e30ff386 100644 --- a/pkg/cmd/apikey/revoke.go +++ b/pkg/cmd/apikey/delete.go @@ -13,6 +13,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/apikey" @@ -20,11 +21,11 @@ import ( var yesFlag bool -var revokeCmd = &cobra.Command{ - Use: "revoke [NAME]", - Short: "Revoke an API key", - Aliases: []string{"r", "rm", "delete"}, +var deleteCmd = &cobra.Command{ + Use: "delete [NAME]", + Short: "Delete an API key", Args: cobra.RangeArgs(0, 1), + Aliases: cmd_common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -83,7 +84,7 @@ var revokeCmd = &cobra.Command{ } if yesFlag { - res, err := apiClient.ApiKeyAPI.RevokeApiKey(ctx, selectedApiKey.Name).Execute() + res, err := apiClient.ApiKeyAPI.DeleteApiKey(ctx, selectedApiKey.Name).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -98,5 +99,5 @@ var revokeCmd = &cobra.Command{ } func init() { - revokeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Skip confirmation prompt") + deleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Skip confirmation prompt") } diff --git a/pkg/cmd/apikey/list.go b/pkg/cmd/apikey/list.go index b6375f265a..6e847ec016 100644 --- a/pkg/cmd/apikey/list.go +++ b/pkg/cmd/apikey/list.go @@ -7,6 +7,7 @@ import ( "context" "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/apikey" "github.com/spf13/cobra" @@ -15,7 +16,7 @@ import ( var listCmd = &cobra.Command{ Use: "list", Short: "List API keys", - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/bootstrap/get_local_runner.go b/pkg/cmd/bootstrap/get_local_runner.go index 52212178cb..7a3c9e272a 100644 --- a/pkg/cmd/bootstrap/get_local_runner.go +++ b/pkg/cmd/bootstrap/get_local_runner.go @@ -120,7 +120,7 @@ func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { if err != nil { jobErr = util.Pointer(err.Error()) } - return jobService.SetState(ctx, jobId, services.UpdateJobStateDTO{ + return jobService.UpdateState(ctx, jobId, services.UpdateJobStateDTO{ State: state, ErrorMessage: jobErr, }) @@ -129,7 +129,7 @@ func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { return params.TelemetryService.Track(event, clientId) }, SetRunnerMetadata: func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error { - return runnerService.SetRunnerMetadata(context.Background(), runnerId, &models.RunnerMetadata{ + return runnerService.UpdateRunnerMetadata(context.Background(), runnerId, &models.RunnerMetadata{ Uptime: uint64(metadata.Uptime), Providers: metadata.Providers, RunningJobs: metadata.RunningJobs, @@ -155,14 +155,14 @@ func getLocalWorkspaceJobFactory(params LocalJobFactoryParams) (workspace.IWorks return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { - workspaceDto, err := workspaceService.GetWorkspace(ctx, workspaceId, services.WorkspaceRetrievalParams{}) + workspaceDto, err := workspaceService.FindWorkspace(ctx, workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { return nil, err } return &workspaceDto.Workspace, nil }, FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + targetDto, err := targetService.FindTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func getLocalWorkspaceJobFactory(params LocalJobFactoryParams) (workspace.IWorks }, UpdateWorkspaceProviderMetadata: workspaceService.UpdateWorkspaceProviderMetadata, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(ctx, id) + return gitProviderService.FindConfig(ctx, id) }, GetWorkspaceEnvironmentVariables: func(ctx context.Context, w *models.Workspace) (map[string]string, error) { serverEnvVars, err := envVarService.Map(ctx) @@ -196,7 +196,7 @@ func getLocalTargetJobFactory(params LocalJobFactoryParams) (target.ITargetJobFa return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + targetDto, err := targetService.FindTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { return nil, err } @@ -347,7 +347,7 @@ func getProviderManager(params LocalRunnerParams, logger *log.Logger) (providerm return targetConfigService.Map(ctx) }, CreateTargetConfig: func(ctx context.Context, name, options string, providerInfo models.ProviderInfo) error { - tc, err := targetConfigService.Add(ctx, services.AddTargetConfigDTO{ + tc, err := targetConfigService.Create(ctx, services.CreateTargetConfigDTO{ Name: name, Options: options, ProviderInfo: providerInfo, diff --git a/pkg/cmd/bootstrap/get_remote_runner.go b/pkg/cmd/bootstrap/get_remote_runner.go index f6e2506ea4..016b8d065a 100644 --- a/pkg/cmd/bootstrap/get_remote_runner.go +++ b/pkg/cmd/bootstrap/get_remote_runner.go @@ -179,7 +179,7 @@ func GetRemoteRunner(params RemoteRunnerParams) (runner.IRunner, error) { runnerMetadata.RunningJobs = util.Pointer(int32(*metadata.RunningJobs)) } - _, err := params.ApiClient.RunnerAPI.SetRunnerMetadata(ctx, runnerId).RunnerMetadata(runnerMetadata).Execute() + _, err := params.ApiClient.RunnerAPI.UpdateRunnerMetadata(ctx, runnerId).RunnerMetadata(runnerMetadata).Execute() return err }, WorkspaceJobFactory: workspaceJobFactory, @@ -205,7 +205,7 @@ func getRemoteProviderManager(params RemoteRunnerParams, logger *log.Logger) pro ServerUrl: headscaleUrl, BaseDir: params.RunnerConfig.ProvidersDir, CreateProviderNetworkKey: func(ctx context.Context, providerName string) (string, error) { - key, _, err := params.ApiClient.ServerAPI.GenerateNetworkKey(ctx).Execute() + key, _, err := params.ApiClient.ServerAPI.CreateNetworkKey(ctx).Execute() if err != nil { return "", err } @@ -248,7 +248,7 @@ func getRemoteProviderManager(params RemoteRunnerParams, logger *log.Logger) pro return errors.New("invalid provider info") } - _, _, err = params.ApiClient.TargetConfigAPI.AddTargetConfig(ctx).TargetConfig(apiclient.AddTargetConfigDTO{ + _, _, err = params.ApiClient.TargetConfigAPI.CreateTargetConfig(ctx).TargetConfig(apiclient.CreateTargetConfigDTO{ Name: fmt.Sprintf("%s-runner-%s", name, params.RunnerConfig.Id), Options: options, ProviderInfo: *providerInfoDto, @@ -269,14 +269,14 @@ func getRemoteWorkspaceJobFactory(params RemoteJobFactoryParams) (workspace.IWor return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { - workspaceDto, _, err := params.ApiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceId).Execute() + workspaceDto, _, err := params.ApiClient.WorkspaceAPI.FindWorkspace(ctx, workspaceId).Execute() if err != nil { return nil, err } return conversion.Convert[apiclient.WorkspaceDTO, models.Workspace](workspaceDto) }, FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, _, err := params.ApiClient.TargetAPI.GetTarget(ctx, targetId).ShowOptions(true).Execute() + targetDto, _, err := params.ApiClient.TargetAPI.FindTarget(ctx, targetId).ShowOptions(true).Execute() if err != nil { return nil, err } @@ -289,7 +289,7 @@ func getRemoteWorkspaceJobFactory(params RemoteJobFactoryParams) (workspace.IWor return err }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - gp, _, err := params.ApiClient.GitProviderAPI.GetGitProvider(ctx, id).Execute() + gp, _, err := params.ApiClient.GitProviderAPI.FindGitProvider(ctx, id).Execute() if err != nil { return nil, err } @@ -328,7 +328,7 @@ func getRemoteTargetJobFactory(params RemoteJobFactoryParams) (target.ITargetJob return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, _, err := params.ApiClient.TargetAPI.GetTarget(ctx, targetId).ShowOptions(true).Execute() + targetDto, _, err := params.ApiClient.TargetAPI.FindTarget(ctx, targetId).ShowOptions(true).Execute() if err != nil { return nil, err } @@ -408,7 +408,7 @@ func getRemoteBuildJobFactory(params RemoteJobFactoryParams) (jobs_build.IBuildJ return jobs_build.NewBuildJobFactory(jobs_build.BuildJobFactoryConfig{ FindBuild: func(ctx context.Context, buildId string) (*services.BuildDTO, error) { - build, _, err := params.ApiClient.BuildAPI.GetBuild(ctx, buildId).Execute() + build, _, err := params.ApiClient.BuildAPI.FindBuild(ctx, buildId).Execute() if err != nil { return nil, err } diff --git a/pkg/cmd/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go index bb02c5bfb5..4ca2e8aa6b 100644 --- a/pkg/cmd/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -313,11 +313,11 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { return targetConfigService.Find(ctx, name) }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(ctx, models.ApiKeyTypeTarget, name) + CreateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Create(ctx, models.ApiKeyTypeTarget, name) }, - RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(ctx, name) + DeleteApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Delete(ctx, name) }, CreateJob: func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error { return jobService.Create(ctx, &models.Job{ @@ -341,7 +341,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe WorkspaceStore: workspaceStore, WorkspaceMetadataStore: workspaceMetadataStore, FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - t, err := targetService.GetTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + t, err := targetService.FindTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { return nil, err } @@ -378,17 +378,17 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe Image: *build.Image, }, nil }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(ctx, models.ApiKeyTypeWorkspace, name) + CreateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Create(ctx, models.ApiKeyTypeWorkspace, name) }, - RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(ctx, name) + DeleteApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Delete(ctx, name) }, ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { return gitProviderService.ListConfigsForUrl(ctx, repoUrl) }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(ctx, id) + return gitProviderService.FindConfig(ctx, id) }, GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { return gitProviderService.GetLastCommitSha(ctx, repo) @@ -438,12 +438,12 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }) }, UpdateJobState: func(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { - return jobService.SetState(ctx, jobId, updateJobStateDto) + return jobService.UpdateState(ctx, jobId, updateJobStateDto) }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(ctx, models.ApiKeyTypeRunner, name) + CreateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Create(ctx, models.ApiKeyTypeRunner, name) }, - RevokeApiKey: apiKeyService.Revoke, + DeleteApiKey: apiKeyService.Delete, UnsetDefaultTarget: func(ctx context.Context, runnerId string) error { targets, err := targetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) if err != nil { diff --git a/pkg/cmd/build/build.go b/pkg/cmd/build/build.go index e4c7d7bf01..5d12d3ffcf 100644 --- a/pkg/cmd/build/build.go +++ b/pkg/cmd/build/build.go @@ -10,10 +10,10 @@ import ( var BuildCmd = &cobra.Command{ Use: "build", - Aliases: []string{"builds"}, Short: "Manage builds", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, + Aliases: []string{"builds"}, } func init() { diff --git a/pkg/cmd/build/delete.go b/pkg/cmd/build/delete.go index 4db45f59e0..0815ce9d63 100644 --- a/pkg/cmd/build/delete.go +++ b/pkg/cmd/build/delete.go @@ -8,6 +8,7 @@ import ( "fmt" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -17,8 +18,8 @@ import ( var buildDeleteCmd = &cobra.Command{ Use: "delete [BUILD]", Short: "Delete a build", - Aliases: []string{"remove", "rm"}, Args: cobra.RangeArgs(0, 1), + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var buildId string diff --git a/pkg/cmd/build/info.go b/pkg/cmd/build/info.go index f38fb46b4f..51ca8b9c77 100644 --- a/pkg/cmd/build/info.go +++ b/pkg/cmd/build/info.go @@ -9,6 +9,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/build/info" "github.com/daytonaio/daytona/pkg/views/selection" @@ -19,8 +20,8 @@ import ( var buildInfoCmd = &cobra.Command{ Use: "info [BUILD]", Short: "Show build info", - Aliases: []string{"view", "inspect"}, Args: cobra.RangeArgs(0, 1), + Aliases: common.GetAliases("info"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var build *apiclient.BuildDTO @@ -60,7 +61,7 @@ var buildInfoCmd = &cobra.Command{ } } else { var res *http.Response - build, res, err = apiClient.BuildAPI.GetBuild(ctx, args[0]).Execute() + build, res, err = apiClient.BuildAPI.FindBuild(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/build/list.go b/pkg/cmd/build/list.go index e6491ce66d..039673eb3b 100644 --- a/pkg/cmd/build/list.go +++ b/pkg/cmd/build/list.go @@ -7,6 +7,7 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" view "github.com/daytonaio/daytona/pkg/views/build/list" "github.com/spf13/cobra" @@ -15,8 +16,8 @@ import ( var buildListCmd = &cobra.Command{ Use: "list", Short: "List all builds", - Aliases: []string{"ls"}, Args: cobra.NoArgs, + Aliases: common.GetAliases("ls"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index 4051995c95..dcc36c6817 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -19,7 +20,7 @@ var buildLogsCmd = &cobra.Command{ Use: "logs", Short: "View logs for build", Args: cobra.RangeArgs(0, 1), - Aliases: []string{"log"}, + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { @@ -59,7 +60,7 @@ var buildLogsCmd = &cobra.Command{ buildId = args[0] } - _, _, err = apiClient.BuildAPI.GetBuild(ctx, buildId).Execute() + _, _, err = apiClient.BuildAPI.FindBuild(ctx, buildId).Execute() if err != nil { return apiclient_util.HandleErrorResponse(nil, err) } diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index eed1ab4a4f..ffd0026650 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -10,6 +10,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" @@ -20,8 +21,8 @@ import ( var buildRunCmd = &cobra.Command{ Use: "run", Short: "Run a build from a workspace template", - Aliases: []string{"create"}, Args: cobra.NoArgs, + Aliases: common.GetAliases("run"), RunE: func(cmd *cobra.Command, args []string) error { var workspaceTemplate *apiclient.WorkspaceTemplate ctx := context.Background() diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index c961eec1c8..f7b089b805 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -191,10 +191,10 @@ func RunInitialScreenFlow(cmd *cobra.Command, args []string) error { return CreateCmd.RunE(cmd, []string{}) case "code": return CodeCmd.RunE(cmd, []string{}) - case "git-provider add": + case "git-provider create": return GitProviderAddCmd.RunE(cmd, []string{}) - case "target-config set": - return TargetConfigAddCmd.RunE(cmd, []string{}) + case "target-config create": + return TargetConfigCreateCmd.RunE(cmd, []string{}) case "docs": return DocsCmd.RunE(cmd, []string{}) case "help": diff --git a/pkg/cmd/common/aliases.go b/pkg/cmd/common/aliases.go new file mode 100644 index 0000000000..ea14ce4b95 --- /dev/null +++ b/pkg/cmd/common/aliases.go @@ -0,0 +1,27 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package common + +var commandAliases = map[string][]string{ + "create": {"add", "new"}, + "delete": {"remove", "rm"}, + "update": {"set"}, + "install": {"i"}, + "uninstall": {"u"}, + "info": {"view", "inspect"}, + "code": {"open"}, + "logs": {"log"}, + "forward": {"fwd"}, + "config": {"info"}, + "list": {"ls"}, + "set-default": {"sd"}, + "run": {"create"}, +} + +func GetAliases(cmd string) []string { + if aliases, exists := commandAliases[cmd]; exists { + return aliases + } + return nil +} diff --git a/pkg/cmd/common/await_state.go b/pkg/cmd/common/await_state.go index 36ed28b471..ae665c5226 100644 --- a/pkg/cmd/common/await_state.go +++ b/pkg/cmd/common/await_state.go @@ -64,7 +64,7 @@ func AwaitProviderInstalled(runnerId, providerName, version string) error { return err } - runner, res, err := apiClient.RunnerAPI.GetRunner(ctx, runnerId).Execute() + runner, res, err := apiClient.RunnerAPI.FindRunner(ctx, runnerId).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/common/delete_workspace.go b/pkg/cmd/common/delete_workspace.go index 0b30b65778..3706d3cf19 100644 --- a/pkg/cmd/common/delete_workspace.go +++ b/pkg/cmd/common/delete_workspace.go @@ -16,7 +16,7 @@ import ( func DeleteWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspaceId, workspaceName string, force bool) error { message := fmt.Sprintf("Deleting workspace %s", workspaceName) err := views_util.WithInlineSpinner(message, func() error { - res, err := apiClient.WorkspaceAPI.RemoveWorkspace(ctx, workspaceId).Force(force).Execute() + res, err := apiClient.WorkspaceAPI.DeleteWorkspace(ctx, workspaceId).Force(force).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/common/get_gpg_key.go b/pkg/cmd/common/get_gpg_key.go index 1208348bad..6d5a1da5f9 100644 --- a/pkg/cmd/common/get_gpg_key.go +++ b/pkg/cmd/common/get_gpg_key.go @@ -17,7 +17,7 @@ func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, p var gpgKey *string - gitProvider, res, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *providerConfigId).Execute() + gitProvider, res, err := apiClient.GitProviderAPI.FindGitProvider(ctx, *providerConfigId).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/config.go b/pkg/cmd/config.go index 7992e0b33e..fc3af9cb82 100644 --- a/pkg/cmd/config.go +++ b/pkg/cmd/config.go @@ -5,6 +5,7 @@ package cmd import ( "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" config_view "github.com/daytonaio/daytona/pkg/views/config" "github.com/spf13/cobra" @@ -15,8 +16,8 @@ var showApiKeysFlag bool var configCmd = &cobra.Command{ Use: "config", Short: "Output Daytona configuration", - Aliases: []string{"cfg"}, Args: cobra.NoArgs, + Aliases: common.GetAliases("config"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { diff --git a/pkg/cmd/env/delete.go b/pkg/cmd/env/delete.go index 3d74c4373c..8ad42e0e2d 100644 --- a/pkg/cmd/env/delete.go +++ b/pkg/cmd/env/delete.go @@ -7,6 +7,7 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/env" log "github.com/sirupsen/logrus" @@ -14,9 +15,9 @@ import ( ) var deleteCmd = &cobra.Command{ - Use: "remove [KEY]...", - Short: "Remove server environment variables", - Aliases: []string{"r", "rm", "d", "delete"}, + Use: "delete [KEY]...", + Short: "Delete server environment variables", + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { keys := []string{} @@ -30,7 +31,7 @@ var deleteCmd = &cobra.Command{ if len(args) > 0 { keys = args } else { - selectedEnvVars, err := env.RemoveEnvVarsView(ctx, *apiClient) + selectedEnvVars, err := env.DeleteEnvVarsView(ctx, *apiClient) if err != nil { return err } diff --git a/pkg/cmd/env/list.go b/pkg/cmd/env/list.go index 1ff06b849c..a7f5d7da0d 100644 --- a/pkg/cmd/env/list.go +++ b/pkg/cmd/env/list.go @@ -8,6 +8,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/env" "github.com/spf13/cobra" @@ -18,7 +19,7 @@ var showValuesFlag bool var listCmd = &cobra.Command{ Use: "list", Short: "List server environment variables", - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { apiClient, err := apiclient_util.GetApiClient(nil) if err != nil { diff --git a/pkg/cmd/env/set.go b/pkg/cmd/env/set.go index a890ec625c..90bb20c7e7 100644 --- a/pkg/cmd/env/set.go +++ b/pkg/cmd/env/set.go @@ -17,9 +17,8 @@ import ( ) var setCmd = &cobra.Command{ - Use: "set [KEY=VALUE]...", - Short: "Set server environment variables", - Aliases: []string{"s", "add", "new"}, + Use: "set [KEY=VALUE]...", + Short: "Set server environment variables", RunE: func(cmd *cobra.Command, args []string) error { envVarsMap := make(map[string]string) @@ -46,7 +45,7 @@ var setCmd = &cobra.Command{ } for key, value := range envVarsMap { - res, err := apiClient.EnvVarAPI.SetEnvironmentVariable(ctx).EnvironmentVariable(apiclient.EnvironmentVariable{ + res, err := apiClient.EnvVarAPI.SaveEnvironmentVariable(ctx).EnvironmentVariable(apiclient.EnvironmentVariable{ Key: key, Value: value, }).Execute() diff --git a/pkg/cmd/gitprovider/add.go b/pkg/cmd/gitprovider/create.go similarity index 94% rename from pkg/cmd/gitprovider/add.go rename to pkg/cmd/gitprovider/create.go index a5341664cb..9caf3edfde 100644 --- a/pkg/cmd/gitprovider/add.go +++ b/pkg/cmd/gitprovider/create.go @@ -13,16 +13,16 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" "github.com/spf13/cobra" ) var GitProviderAddCmd = &cobra.Command{ - Use: "add [GIT_PROVIDER_ID]", - Aliases: []string{"new", "register"}, - Short: "Register a Git provider", - Args: cobra.RangeArgs(0, 1), + Use: "create [GIT_PROVIDER_ID]", + Short: "Create a Git provider config", + Aliases: common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -131,7 +131,7 @@ var GitProviderAddCmd = &cobra.Command{ return nil } - res, err = apiClient.GitProviderAPI.SetGitProvider(ctx).GitProviderConfig(setGitProviderConfig).Execute() + res, err = apiClient.GitProviderAPI.SaveGitProvider(ctx).GitProviderConfig(setGitProviderConfig).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/gitprovider/delete.go b/pkg/cmd/gitprovider/delete.go index f11a451001..ca69c877aa 100644 --- a/pkg/cmd/gitprovider/delete.go +++ b/pkg/cmd/gitprovider/delete.go @@ -10,6 +10,7 @@ import ( "github.com/charmbracelet/huh" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -18,8 +19,8 @@ import ( var gitProviderDeleteCmd = &cobra.Command{ Use: "delete", - Aliases: []string{"remove", "rm"}, - Short: "Unregister a Git provider", + Short: "Delete a Git provider config", + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -40,7 +41,7 @@ var gitProviderDeleteCmd = &cobra.Command{ if allFlag { if yesFlag { - err = removeAllGitProviders(gitProviders, apiClient) + err = deleteAllGitProviders(gitProviders, apiClient) if err != nil { return err } @@ -48,8 +49,8 @@ var gitProviderDeleteCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title("Remove all git providers?"). - Description("Are you sure you want to remove all git providers?"). + Title("Delete all git providers?"). + Description("Are you sure you want to delete all git providers?"). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -59,7 +60,7 @@ var gitProviderDeleteCmd = &cobra.Command{ } if yesFlag { - err = removeAllGitProviders(gitProviders, apiClient) + err = deleteAllGitProviders(gitProviders, apiClient) if err != nil { return err } @@ -73,7 +74,7 @@ var gitProviderDeleteCmd = &cobra.Command{ selectedGitProvider := selection.GetGitProviderConfigFromPrompt(selection.GetGitProviderConfigParams{ GitProviderConfigs: gitProviders, - ActionVerb: "Remove", + ActionVerb: "Delete", }) if selectedGitProvider == nil { @@ -85,8 +86,8 @@ var gitProviderDeleteCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewConfirm(). - Title(fmt.Sprintf("Remove git provider: %s?", selectedGitProviderText)). - Description(fmt.Sprintf("Are you sure you want to remove the git provider: %s?", selectedGitProviderText)). + Title(fmt.Sprintf("Delete git provider: %s?", selectedGitProviderText)). + Description(fmt.Sprintf("Are you sure you want to delete the Git provider: %s?", selectedGitProviderText)). Value(&yesFlag), ), ).WithTheme(views.GetCustomTheme()) @@ -100,12 +101,12 @@ var gitProviderDeleteCmd = &cobra.Command{ if !yesFlag { fmt.Println("Operation canceled.") } else { - _, err = apiClient.GitProviderAPI.RemoveGitProvider(ctx, selectedGitProvider.Id).Execute() + _, err = apiClient.GitProviderAPI.DeleteGitProvider(ctx, selectedGitProvider.Id).Execute() if err != nil { return err } - views.RenderInfoMessage("Git provider has been removed") + views.RenderInfoMessage("Git provider has been deleted") } return nil @@ -116,14 +117,14 @@ var allFlag bool var yesFlag bool func init() { - gitProviderDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Remove all Git providers") + gitProviderDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all Git providers") gitProviderDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") } -func removeAllGitProviders(gitProviders []apiclient.GitProvider, apiClient *apiclient.APIClient) error { +func deleteAllGitProviders(gitProviders []apiclient.GitProvider, apiClient *apiclient.APIClient) error { ctx := context.Background() for _, gitProvider := range gitProviders { - _, err := apiClient.GitProviderAPI.RemoveGitProvider(ctx, gitProvider.Id).Execute() + _, err := apiClient.GitProviderAPI.DeleteGitProvider(ctx, gitProvider.Id).Execute() if err != nil { return err } diff --git a/pkg/cmd/gitprovider/gitprovider.go b/pkg/cmd/gitprovider/gitprovider.go index 7cbd308d86..6433df5b83 100644 --- a/pkg/cmd/gitprovider/gitprovider.go +++ b/pkg/cmd/gitprovider/gitprovider.go @@ -9,11 +9,11 @@ import ( ) var GitProviderCmd = &cobra.Command{ - Use: "git-providers", - Aliases: []string{"git-provider", "gp"}, - Short: "Manage Git providers", + Use: "git-provider", + Short: "Manage Git provider configs", Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, + Aliases: []string{"git-providers", "gp"}, } func init() { diff --git a/pkg/cmd/gitprovider/list.go b/pkg/cmd/gitprovider/list.go index ecd11ff4ed..3d5a6d8eea 100644 --- a/pkg/cmd/gitprovider/list.go +++ b/pkg/cmd/gitprovider/list.go @@ -8,6 +8,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" "github.com/daytonaio/daytona/pkg/views/gitprovider/list" @@ -16,8 +17,8 @@ import ( var gitProviderListCmd = &cobra.Command{ Use: "list", - Aliases: []string{"ls"}, - Short: "Lists your registered Git providers", + Short: "Lists your registered Git provider configs", + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { apiClient, err := apiclient.GetApiClient(nil) if err != nil { diff --git a/pkg/cmd/gitprovider/update.go b/pkg/cmd/gitprovider/update.go index 2f550bc972..680cb0e2a5 100644 --- a/pkg/cmd/gitprovider/update.go +++ b/pkg/cmd/gitprovider/update.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" gitprovider_view "github.com/daytonaio/daytona/pkg/views/gitprovider" "github.com/daytonaio/daytona/pkg/views/selection" @@ -17,8 +18,9 @@ import ( ) var gitProviderUpdateCmd = &cobra.Command{ - Use: "update", - Short: "Update a Git provider", + Use: "update", + Short: "Update a Git provider", + Aliases: common.GetAliases("update"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -67,7 +69,7 @@ var gitProviderUpdateCmd = &cobra.Command{ return err } - res, err = apiClient.GitProviderAPI.SetGitProvider(ctx).GitProviderConfig(setGitProviderConfig).Execute() + res, err = apiClient.GitProviderAPI.SaveGitProvider(ctx).GitProviderConfig(setGitProviderConfig).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/ports/forward.go b/pkg/cmd/ports/forward.go index 272ea9e883..374f6e7b26 100644 --- a/pkg/cmd/ports/forward.go +++ b/pkg/cmd/ports/forward.go @@ -18,6 +18,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/frpc" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -35,6 +36,7 @@ var PortForwardCmd = &cobra.Command{ Short: "Forward a port from a workspace to your local machine", GroupID: util.TARGET_GROUP, Args: cobra.RangeArgs(1, 2), + Aliases: common.GetAliases("forward"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { @@ -60,7 +62,7 @@ var PortForwardCmd = &cobra.Command{ var resp *http.Response if len(args) == 2 { - workspace, resp, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, args[1]).Execute() + workspace, resp, err = apiClient.WorkspaceAPI.FindWorkspace(ctx, args[1]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(resp, err) } diff --git a/pkg/cmd/prebuild/add.go b/pkg/cmd/prebuild/create.go similarity index 86% rename from pkg/cmd/prebuild/add.go rename to pkg/cmd/prebuild/create.go index a090d6bda2..80bb4c6fad 100644 --- a/pkg/cmd/prebuild/add.go +++ b/pkg/cmd/prebuild/create.go @@ -13,21 +13,22 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" - "github.com/daytonaio/daytona/pkg/cmd/workspace/create" + "github.com/daytonaio/daytona/pkg/cmd/common" + ws_create "github.com/daytonaio/daytona/pkg/cmd/workspace/create" "github.com/daytonaio/daytona/pkg/cmd/workspacetemplate" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/prebuild/add" + "github.com/daytonaio/daytona/pkg/views/prebuild/create" "github.com/daytonaio/daytona/pkg/views/selection" "github.com/spf13/cobra" ) var prebuildAddCmd = &cobra.Command{ - Use: "add [WORKSPACE_CONFIG]", - Short: "Add a prebuild configuration", + Use: "create [WORKSPACE_CONFIG]", + Short: "Create a prebuild configuration", Args: cobra.MaximumNArgs(1), - Aliases: []string{"new", "create"}, + Aliases: common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { - var prebuildAddView add.PrebuildAddView + var prebuildAddView create.PrebuildAddView var workspaceTemplate *apiclient.WorkspaceTemplate ctx := context.Background() @@ -41,7 +42,7 @@ var prebuildAddCmd = &cobra.Command{ } if len(gitProviders) == 0 { - views.RenderInfoMessage("No registered Git providers have been found - please register a Git provider using 'daytona git-provider add' in order to start using prebuilds.") + views.RenderInfoMessage("No Git providers have been found - please create a Git provider using 'daytona git-provider create' in order to start using prebuilds.") return nil } @@ -75,7 +76,7 @@ var prebuildAddCmd = &cobra.Command{ return errors.New("The chosen workspace template does not have a build configuration") } - chosenBranch, err := create.GetBranchFromWorkspaceTemplate(ctx, workspaceTemplate, apiClient, 0) + chosenBranch, err := ws_create.GetBranchFromWorkspaceTemplate(ctx, workspaceTemplate, apiClient, 0) if err != nil { return err } @@ -86,14 +87,14 @@ var prebuildAddCmd = &cobra.Command{ } prebuildAddView.RunBuildOnAdd = runFlag prebuildAddView.Branch = chosenBranch.Name - add.PrebuildCreationView(&prebuildAddView, false) + create.PrebuildCreationView(&prebuildAddView, false) } else { // Non-interactive mode: use provided arguments and flags if len(args) > 0 { prebuildAddView.WorkspaceTemplateName = args[0] // Fetch the workspace template based on the provided argument - workspaceTemplateTemp, res, err := apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, prebuildAddView.WorkspaceTemplateName).Execute() + workspaceTemplateTemp, res, err := apiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(ctx, prebuildAddView.WorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -157,7 +158,7 @@ var prebuildAddCmd = &cobra.Command{ newPrebuild.TriggerFiles = prebuildAddView.TriggerFiles } - prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceTemplateName).Prebuild(newPrebuild).Execute() + prebuildId, res, err := apiClient.PrebuildAPI.SavePrebuild(ctx, prebuildAddView.WorkspaceTemplateName).Prebuild(newPrebuild).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index ab098c6c15..e70e983ec7 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -9,6 +9,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -20,8 +21,8 @@ var forceFlag bool var prebuildDeleteCmd = &cobra.Command{ Use: "delete [WORKSPACE_CONFIG] [PREBUILD]", Short: "Delete a prebuild configuration", - Aliases: []string{"remove", "rm"}, Args: cobra.MaximumNArgs(2), + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { var selectedPrebuild *apiclient.PrebuildDTO var selectedPrebuildId string diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index 708a47e259..1de0350c18 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -9,6 +9,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/prebuild/info" "github.com/daytonaio/daytona/pkg/views/selection" @@ -17,9 +18,10 @@ import ( ) var prebuildInfoCmd = &cobra.Command{ - Use: "info", - Short: "Show prebuild configuration info", - Args: cobra.MaximumNArgs(2), + Use: "info", + Short: "Show prebuild configuration info", + Args: cobra.MaximumNArgs(2), + Aliases: common.GetAliases("info"), RunE: func(cmd *cobra.Command, args []string) error { var prebuild *apiclient.PrebuildDTO var res *http.Response @@ -66,7 +68,7 @@ var prebuildInfoCmd = &cobra.Command{ return nil } } else { - prebuild, res, err = apiClient.PrebuildAPI.GetPrebuild(ctx, args[0], args[1]).Execute() + prebuild, res, err = apiClient.PrebuildAPI.FindPrebuild(ctx, args[0], args[1]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/prebuild/list.go b/pkg/cmd/prebuild/list.go index 0b43243980..2724be745b 100644 --- a/pkg/cmd/prebuild/list.go +++ b/pkg/cmd/prebuild/list.go @@ -7,6 +7,7 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" view "github.com/daytonaio/daytona/pkg/views/prebuild/list" "github.com/spf13/cobra" @@ -15,8 +16,8 @@ import ( var prebuildListCmd = &cobra.Command{ Use: "list", Short: "List prebuild configurations", - Aliases: []string{"ls"}, Args: cobra.NoArgs, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/prebuild/prebuild.go b/pkg/cmd/prebuild/prebuild.go index a5978ecaf6..f18ac3aacb 100644 --- a/pkg/cmd/prebuild/prebuild.go +++ b/pkg/cmd/prebuild/prebuild.go @@ -10,10 +10,10 @@ import ( var PrebuildCmd = &cobra.Command{ Use: "prebuild", - Aliases: []string{"pb", "prebuilds"}, Short: "Manage prebuilds", Args: cobra.NoArgs, GroupID: util.TARGET_GROUP, + Aliases: []string{"prebuilds", "pb"}, } func init() { diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index a85e3465ca..00dc0b9c98 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -12,19 +12,21 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/build" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" - "github.com/daytonaio/daytona/pkg/views/prebuild/add" + "github.com/daytonaio/daytona/pkg/views/prebuild/create" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" ) var prebuildUpdateCmd = &cobra.Command{ - Use: "update [WORKSPACE_CONFIG] [PREBUILD_ID]", - Short: "Update a prebuild configuration", - Args: cobra.MaximumNArgs(2), + Use: "update [WORKSPACE_CONFIG] [PREBUILD_ID]", + Short: "Update a prebuild configuration", + Args: cobra.MaximumNArgs(2), + Aliases: common.GetAliases("update"), RunE: func(cmd *cobra.Command, args []string) error { - var prebuildAddView add.PrebuildAddView + var prebuildAddView create.PrebuildAddView var prebuild *apiclient.PrebuildDTO var workspaceTemplateRecieved string var retention int @@ -56,7 +58,7 @@ var prebuildUpdateCmd = &cobra.Command{ workspaceTemplateRecieved = args[0] prebuildID := args[1] - prebuild, res, err = apiClient.PrebuildAPI.GetPrebuild(ctx, workspaceTemplateRecieved, prebuildID).Execute() + prebuild, res, err = apiClient.PrebuildAPI.FindPrebuild(ctx, workspaceTemplateRecieved, prebuildID).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -112,7 +114,7 @@ var prebuildUpdateCmd = &cobra.Command{ } workspaceTemplateRecieved = prebuild.WorkspaceTemplateName - prebuildAddView = add.PrebuildAddView{ + prebuildAddView = create.PrebuildAddView{ Branch: prebuild.Branch, Retention: strconv.Itoa(int(prebuild.Retention)), WorkspaceTemplateName: workspaceTemplateRecieved, @@ -128,7 +130,7 @@ var prebuildUpdateCmd = &cobra.Command{ if len(prebuild.TriggerFiles) > 0 { prebuildAddView.TriggerFiles = prebuild.TriggerFiles } - add.PrebuildCreationView(&prebuildAddView, false) + create.PrebuildCreationView(&prebuildAddView, false) } prebuildAddView.RunBuildOnAdd = runFlag @@ -155,7 +157,7 @@ var prebuildUpdateCmd = &cobra.Command{ newPrebuild.TriggerFiles = prebuildAddView.TriggerFiles } - prebuildId, res, err := apiClient.PrebuildAPI.SetPrebuild(ctx, prebuildAddView.WorkspaceTemplateName).Prebuild(newPrebuild).Execute() + prebuildId, res, err := apiClient.PrebuildAPI.SavePrebuild(ctx, prebuildAddView.WorkspaceTemplateName).Prebuild(newPrebuild).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -163,7 +165,7 @@ var prebuildUpdateCmd = &cobra.Command{ views.RenderInfoMessage("Prebuild updated successfully") if prebuildAddView.RunBuildOnAdd { - workspaceTemplate, res, err := apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, prebuildAddView.WorkspaceTemplateName).Execute() + workspaceTemplate, res, err := apiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(ctx, prebuildAddView.WorkspaceTemplateName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/profile/add.go b/pkg/cmd/profile/create.go similarity index 94% rename from pkg/cmd/profile/add.go rename to pkg/cmd/profile/create.go index 83c2ae5300..a5c3eb85be 100644 --- a/pkg/cmd/profile/add.go +++ b/pkg/cmd/profile/create.go @@ -6,16 +6,17 @@ package profile import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/profile" "github.com/spf13/cobra" ) var ProfileAddCmd = &cobra.Command{ - Use: "add", - Short: "Add profile", + Use: "create", + Short: "Create a profile", Args: cobra.NoArgs, - Aliases: []string{"new"}, + Aliases: common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { diff --git a/pkg/cmd/profile/delete.go b/pkg/cmd/profile/delete.go index c623b13056..800e255aa5 100644 --- a/pkg/cmd/profile/delete.go +++ b/pkg/cmd/profile/delete.go @@ -7,6 +7,7 @@ import ( "errors" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/profile" log "github.com/sirupsen/logrus" @@ -14,10 +15,10 @@ import ( ) var profileDeleteCmd = &cobra.Command{ - Use: "delete", - Short: "Delete profile [PROFILE_NAME]", + Use: "delete [PROFILE_NAME]", + Short: "Delete a profile", Args: cobra.RangeArgs(0, 1), - Aliases: []string{"remove", "rm"}, + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { diff --git a/pkg/cmd/profile/list.go b/pkg/cmd/profile/list.go index fd41ca6850..bf28331306 100644 --- a/pkg/cmd/profile/list.go +++ b/pkg/cmd/profile/list.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/profile" @@ -16,7 +17,7 @@ import ( var profileListCmd = &cobra.Command{ Use: "list", Short: "List profiles", - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { diff --git a/pkg/cmd/profile/profile.go b/pkg/cmd/profile/profile.go index 6292f1a3ac..d072d3f407 100644 --- a/pkg/cmd/profile/profile.go +++ b/pkg/cmd/profile/profile.go @@ -13,6 +13,7 @@ var ProfileCmd = &cobra.Command{ Short: "Manage profiles", Args: cobra.NoArgs, GroupID: util.PROFILE_GROUP, + Aliases: []string{"profiles"}, } func init() { @@ -20,6 +21,6 @@ func init() { ProfileCmd.AddCommand(profileListCmd) ProfileCmd.AddCommand(ProfileUseCmd) ProfileCmd.AddCommand(ProfileAddCmd) - ProfileCmd.AddCommand(profileEditCmd) + ProfileCmd.AddCommand(profileUpdateCmd) ProfileCmd.AddCommand(profileDeleteCmd) } diff --git a/pkg/cmd/profile/edit.go b/pkg/cmd/profile/update.go similarity index 83% rename from pkg/cmd/profile/edit.go rename to pkg/cmd/profile/update.go index a68b03353f..b19be1f54a 100644 --- a/pkg/cmd/profile/edit.go +++ b/pkg/cmd/profile/update.go @@ -7,15 +7,17 @@ import ( "errors" "github.com/daytonaio/daytona/cmd/daytona/config" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/profile" "github.com/spf13/cobra" ) -var profileEditCmd = &cobra.Command{ - Use: "edit", - Short: "Edit profile [PROFILE_NAME]", - Args: cobra.RangeArgs(0, 1), +var profileUpdateCmd = &cobra.Command{ + Use: "update", + Short: "Update profile [PROFILE_NAME]", + Args: cobra.RangeArgs(0, 1), + Aliases: common.GetAliases("update"), RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { @@ -111,7 +113,7 @@ func editProfile(profileToEdit *config.Profile, profileView profile.ProfileAddVi } func init() { - profileEditCmd.Flags().StringVarP(&profileNameFlag, "name", "n", "", "Profile name") - profileEditCmd.Flags().StringVarP(&apiUrlFlag, "api-url", "a", "", "API URL") - profileEditCmd.Flags().StringVarP(&apiKeyFlag, "api-key", "k", "", "API Key") + profileUpdateCmd.Flags().StringVarP(&profileNameFlag, "name", "n", "", "Profile name") + profileUpdateCmd.Flags().StringVarP(&apiUrlFlag, "api-url", "a", "", "API URL") + profileUpdateCmd.Flags().StringVarP(&apiKeyFlag, "api-key", "k", "", "API Key") } diff --git a/pkg/cmd/profile/use.go b/pkg/cmd/profile/use.go index 6ab6d78f5f..fd2a7dacf3 100644 --- a/pkg/cmd/profile/use.go +++ b/pkg/cmd/profile/use.go @@ -29,12 +29,12 @@ var ProfileUseCmd = &cobra.Command{ profilesList := c.Profiles if len(profilesList) == 0 { - views.RenderInfoMessage("Add a profile by running `daytona profile add`") + views.RenderInfoMessage("Create a profile by running `daytona profile create`") return nil } if len(profilesList) == 1 { - views.RenderInfoMessage(fmt.Sprintf("You are using profile %s. Add a new profile by running `daytona profile add`", profilesList[0].Name)) + views.RenderInfoMessage(fmt.Sprintf("You are using profile %s. Add a new profile by running `daytona profile create`", profilesList[0].Name)) return nil } diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index c7e64068fa..02fe892b45 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -27,7 +27,7 @@ var providerInstallCmd = &cobra.Command{ Use: "install", Short: "Install provider", Args: cobra.MaximumNArgs(1), - Aliases: []string{"i"}, + Aliases: cmd_common.GetAliases("install"), RunE: func(cmd *cobra.Command, args []string) error { var selectedRunnerId string diff --git a/pkg/cmd/provider/list.go b/pkg/cmd/provider/list.go index 53097e96a9..a2e3c30718 100644 --- a/pkg/cmd/provider/list.go +++ b/pkg/cmd/provider/list.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/provider" "github.com/spf13/cobra" @@ -18,7 +19,7 @@ var providerListCmd = &cobra.Command{ Use: "list", Short: "List installed providers", Args: cobra.NoArgs, - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/provider/provider.go b/pkg/cmd/provider/provider.go index 1489af2ab0..5e9bf16ef0 100644 --- a/pkg/cmd/provider/provider.go +++ b/pkg/cmd/provider/provider.go @@ -13,6 +13,7 @@ var ProviderCmd = &cobra.Command{ Short: "Manage providers", Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, + Aliases: []string{"providers"}, } func init() { diff --git a/pkg/cmd/provider/uninstall.go b/pkg/cmd/provider/uninstall.go index 51d9ac403a..f884b78fd5 100644 --- a/pkg/cmd/provider/uninstall.go +++ b/pkg/cmd/provider/uninstall.go @@ -20,7 +20,7 @@ var providerUninstallCmd = &cobra.Command{ Use: "uninstall", Short: "Uninstall provider", Args: cobra.NoArgs, - Aliases: []string{"u"}, + Aliases: cmd_common.GetAliases("uninstall"), RunE: func(cmd *cobra.Command, args []string) error { var selectedRunnerId string diff --git a/pkg/cmd/provider/update.go b/pkg/cmd/provider/update.go index a996857db9..094a9718be 100644 --- a/pkg/cmd/provider/update.go +++ b/pkg/cmd/provider/update.go @@ -24,7 +24,7 @@ var providerUpdateCmd = &cobra.Command{ Use: "update", Short: "Update provider", Args: cobra.NoArgs, - Aliases: []string{"up"}, + Aliases: cmd_common.GetAliases("update"), RunE: func(cmd *cobra.Command, args []string) error { var selectedRunnerId string diff --git a/pkg/cmd/runner/config.go b/pkg/cmd/runner/config.go index a3da208356..16eb3b4015 100644 --- a/pkg/cmd/runner/config.go +++ b/pkg/cmd/runner/config.go @@ -7,14 +7,15 @@ import ( view "github.com/daytonaio/daytona/pkg/views/runner" "github.com/spf13/cobra" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/runner" ) var configCmd = &cobra.Command{ Use: "config", - Aliases: []string{"info"}, Short: "Outputs Daytona Runner config", + Aliases: common.GetAliases("config"), RunE: func(cmd *cobra.Command, args []string) error { config, err := runner.GetConfig() if err != nil { diff --git a/pkg/cmd/runner/logs.go b/pkg/cmd/runner/logs.go index a5cdc2f0bf..33d244da0e 100644 --- a/pkg/cmd/runner/logs.go +++ b/pkg/cmd/runner/logs.go @@ -8,6 +8,7 @@ import ( "errors" "io" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/runner" logs_view "github.com/daytonaio/daytona/pkg/views/logs" @@ -17,9 +18,10 @@ import ( var followFlag bool var logsCmd = &cobra.Command{ - Use: "logs", - Short: "View runner logs", - Args: cobra.NoArgs, + Use: "logs", + Short: "View runner logs", + Args: cobra.NoArgs, + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { c, err := runner.GetConfig() if err != nil { diff --git a/pkg/cmd/runner/runner.go b/pkg/cmd/runner/runner.go index 0372a2c188..c6c9f4d51b 100644 --- a/pkg/cmd/runner/runner.go +++ b/pkg/cmd/runner/runner.go @@ -13,6 +13,7 @@ var RunnerCmd = &cobra.Command{ Short: "Manage the runner", Args: cobra.NoArgs, GroupID: util.RUNNER_GROUP, + Aliases: []string{"runners"}, } func init() { diff --git a/pkg/cmd/server/config.go b/pkg/cmd/server/config.go index 0ea3079936..d193119365 100644 --- a/pkg/cmd/server/config.go +++ b/pkg/cmd/server/config.go @@ -7,13 +7,15 @@ import ( view "github.com/daytonaio/daytona/pkg/views/server" "github.com/spf13/cobra" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/server" ) var configCmd = &cobra.Command{ - Use: "config", - Short: "Output local Daytona Server config", + Use: "config", + Short: "Output local Daytona Server config", + Aliases: common.GetAliases("config"), RunE: func(cmd *cobra.Command, args []string) error { config, err := server.GetConfig() if err != nil { diff --git a/pkg/cmd/server/configure.go b/pkg/cmd/server/configure.go index f568aee630..8a7555625b 100644 --- a/pkg/cmd/server/configure.go +++ b/pkg/cmd/server/configure.go @@ -31,7 +31,7 @@ var configureCmd = &cobra.Command{ return err } - _, res, err = apiClient.ServerAPI.SetConfig(context.Background()).Config(*apiServerConfig).Execute() + _, res, err = apiClient.ServerAPI.SaveConfig(context.Background()).Config(*apiServerConfig).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/server/logs/list.go b/pkg/cmd/server/logs/list.go index 967002ee31..cbaa62d6ad 100644 --- a/pkg/cmd/server/logs/list.go +++ b/pkg/cmd/server/logs/list.go @@ -7,14 +7,15 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/server" "github.com/spf13/cobra" ) var listCmd = &cobra.Command{ Use: "list", - Aliases: []string{"ls"}, Short: "Lists Daytona Server Log Files", + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/server/logs/logs.go b/pkg/cmd/server/logs/logs.go index ede3996f00..658d0c2018 100644 --- a/pkg/cmd/server/logs/logs.go +++ b/pkg/cmd/server/logs/logs.go @@ -17,6 +17,7 @@ import ( "github.com/daytonaio/daytona/internal/constants" "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/views" @@ -38,8 +39,9 @@ func init() { } var LogsCmd = &cobra.Command{ - Use: "logs", - Short: "Output Daytona Server logs", + Use: "logs", + Short: "Output Daytona Server logs", + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/server/runner/register.go b/pkg/cmd/server/runner/create.go similarity index 79% rename from pkg/cmd/server/runner/register.go rename to pkg/cmd/server/runner/create.go index 971f46f8f9..aac7aebc08 100644 --- a/pkg/cmd/server/runner/register.go +++ b/pkg/cmd/server/runner/create.go @@ -10,16 +10,18 @@ import ( "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/server/runner" "github.com/docker/docker/pkg/stringid" "github.com/spf13/cobra" ) -var registerCmd = &cobra.Command{ - Use: "register", - Short: "Register runner", - Args: cobra.NoArgs, +var createCmd = &cobra.Command{ + Use: "create", + Short: "Create a runner", + Args: cobra.NoArgs, + Aliases: common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -45,7 +47,7 @@ var registerCmd = &cobra.Command{ name := nameFlag if name == "" { - err = runner.RunnerRegistrationView(&name, existingRunnerNames) + err = runner.RunnerCreationView(&name, existingRunnerNames) if err != nil { return err } @@ -54,7 +56,7 @@ var registerCmd = &cobra.Command{ id := stringid.GenerateRandomID() id = stringid.TruncateID(id) - runnerDto, res, err := apiClient.RunnerAPI.RegisterRunner(ctx).Runner(apiclient.RegisterRunnerDTO{ + runnerDto, res, err := apiClient.RunnerAPI.CreateRunner(ctx).Runner(apiclient.CreateRunnerDTO{ Id: id, Name: name, }).Execute() @@ -77,5 +79,5 @@ var registerCmd = &cobra.Command{ var nameFlag string func init() { - registerCmd.Flags().StringVarP(&nameFlag, "name", "n", "", "Runner name") + createCmd.Flags().StringVarP(&nameFlag, "name", "n", "", "Runner name") } diff --git a/pkg/cmd/server/runner/unregister.go b/pkg/cmd/server/runner/delete.go similarity index 85% rename from pkg/cmd/server/runner/unregister.go rename to pkg/cmd/server/runner/delete.go index 9af5591e46..f9034f7b5c 100644 --- a/pkg/cmd/server/runner/unregister.go +++ b/pkg/cmd/server/runner/delete.go @@ -11,6 +11,7 @@ import ( "github.com/charmbracelet/huh" "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" runner "github.com/daytonaio/daytona/pkg/views/server/runner/selection" @@ -19,10 +20,11 @@ import ( "github.com/spf13/cobra" ) -var unregisterCmd = &cobra.Command{ - Use: "unregister [RUNNER]", - Short: "Unregister runner", - Args: cobra.RangeArgs(0, 1), +var deleteCmd = &cobra.Command{ + Use: "delete [RUNNER]", + Short: "Delete a runner", + Args: cobra.RangeArgs(0, 1), + Aliases: cmd_common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { var selectedRunnerId string @@ -90,7 +92,7 @@ var unregisterCmd = &cobra.Command{ } } - res, err := apiClient.RunnerAPI.RemoveRunner(ctx, selectedRunnerId).Execute() + res, err := apiClient.RunnerAPI.DeleteRunner(ctx, selectedRunnerId).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -103,5 +105,5 @@ var unregisterCmd = &cobra.Command{ var yesFlag bool func init() { - unregisterCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + deleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") } diff --git a/pkg/cmd/server/runner/list.go b/pkg/cmd/server/runner/list.go index 07e20e94f2..099a9de076 100644 --- a/pkg/cmd/server/runner/list.go +++ b/pkg/cmd/server/runner/list.go @@ -6,6 +6,7 @@ package runner import ( "context" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/server/runner/list" @@ -16,7 +17,7 @@ import ( var listCmd = &cobra.Command{ Use: "list", Short: "List runners", - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/server/runner/logs.go b/pkg/cmd/server/runner/logs.go index cadc1e29bc..960ad3f1a2 100644 --- a/pkg/cmd/server/runner/logs.go +++ b/pkg/cmd/server/runner/logs.go @@ -25,7 +25,7 @@ var logsCmd = &cobra.Command{ Use: "logs [RUNNER_ID]", Short: "View runner logs", Args: cobra.MaximumNArgs(1), - Aliases: []string{"log"}, + Aliases: cmd_common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { var selectedRunnerId string ctx := context.Background() @@ -75,7 +75,7 @@ var logsCmd = &cobra.Command{ selectedRunnerId = args[0] } - runner, res, err := apiClient.RunnerAPI.GetRunner(ctx, selectedRunnerId).Execute() + runner, res, err := apiClient.RunnerAPI.FindRunner(ctx, selectedRunnerId).Execute() if err != nil { if res.StatusCode == http.StatusNotFound { return fmt.Errorf("runner %s not found", selectedRunnerId) diff --git a/pkg/cmd/server/runner/runner.go b/pkg/cmd/server/runner/runner.go index 4271f18b58..7e0b803e72 100644 --- a/pkg/cmd/server/runner/runner.go +++ b/pkg/cmd/server/runner/runner.go @@ -15,6 +15,6 @@ var RunnerCmd = &cobra.Command{ func init() { RunnerCmd.AddCommand(logsCmd) RunnerCmd.AddCommand(listCmd) - RunnerCmd.AddCommand(registerCmd) - RunnerCmd.AddCommand(unregisterCmd) + RunnerCmd.AddCommand(createCmd) + RunnerCmd.AddCommand(deleteCmd) } diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 29b8bbb4cd..65de917178 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -120,7 +120,7 @@ var ServeCmd = &cobra.Command{ log.Info("Starting local container registry...") localContainerRegistryErrChan <- server.LocalContainerRegistry.Start() } else { - localContainerRegistryErrChan <- registry.RemoveRegistryContainer() + localContainerRegistryErrChan <- registry.DeleteRegistryContainer() } }() @@ -230,7 +230,7 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { } } - apiKey, err := server.ApiKeyService.Generate(context.Background(), models.ApiKeyTypeClient, "default") + apiKey, err := server.ApiKeyService.Create(context.Background(), models.ApiKeyTypeClient, "default") if err != nil { return err } @@ -248,10 +248,10 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { func startLocalRunner(params bootstrap.LocalRunnerParams) error { runnerService := server.GetInstance(nil).RunnerService - _, err := runnerService.GetRunner(context.Background(), common.LOCAL_RUNNER_ID) + _, err := runnerService.FindRunner(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { if stores.IsRunnerNotFound(err) { - _, err := runnerService.RegisterRunner(context.Background(), services.RegisterRunnerDTO{ + _, err := runnerService.CreateRunner(context.Background(), services.CreateRunnerDTO{ Id: common.LOCAL_RUNNER_ID, Name: common.LOCAL_RUNNER_ID, }) @@ -290,7 +290,7 @@ func awaitLocalRunnerStarted() error { startTime := time.Now() for { - r, err := server.RunnerService.GetRunner(context.Background(), common.LOCAL_RUNNER_ID) + r, err := server.RunnerService.FindRunner(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { return err } @@ -313,12 +313,12 @@ func awaitLocalRunnerStarted() error { func handleDisabledLocalRunner() error { runnerService := server.GetInstance(nil).RunnerService - _, err := runnerService.GetRunner(context.Background(), common.LOCAL_RUNNER_ID) + _, err := runnerService.FindRunner(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { if stores.IsRunnerNotFound(err) { return nil } } - return runnerService.RemoveRunner(context.Background(), common.LOCAL_RUNNER_ID) + return runnerService.DeleteRunner(context.Background(), common.LOCAL_RUNNER_ID) } diff --git a/pkg/cmd/target/create.go b/pkg/cmd/target/create.go index 1d658c9171..a0244a53b3 100644 --- a/pkg/cmd/target/create.go +++ b/pkg/cmd/target/create.go @@ -26,9 +26,10 @@ import ( ) var targetCreateCmd = &cobra.Command{ - Use: "create", - Short: "Create a target", - Args: cobra.NoArgs, + Use: "create", + Short: "Create a target", + Args: cobra.NoArgs, + Aliases: cmd_common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/target/delete.go b/pkg/cmd/target/delete.go index b34795342a..5fc0a938b3 100644 --- a/pkg/cmd/target/delete.go +++ b/pkg/cmd/target/delete.go @@ -26,7 +26,7 @@ var forceFlag bool var deleteCmd = &cobra.Command{ Use: "delete [TARGET]...", Short: "Delete a target", - Aliases: []string{"remove", "rm"}, + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -188,7 +188,7 @@ func deleteTarget(ctx context.Context, activeProfileId string, apiClient *apicli message := fmt.Sprintf("Deleting target %s", target.Name) err := views_util.WithInlineSpinner(message, func() error { - res, err := apiClient.TargetAPI.RemoveTarget(ctx, target.Id).Force(forceFlag).Execute() + res, err := apiClient.TargetAPI.DeleteTarget(ctx, target.Id).Force(forceFlag).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/target/info.go b/pkg/cmd/target/info.go index 797dbc3813..e6d09f30b3 100644 --- a/pkg/cmd/target/info.go +++ b/pkg/cmd/target/info.go @@ -8,6 +8,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/target/info" "github.com/daytonaio/daytona/pkg/views/target/selection" @@ -18,8 +19,8 @@ import ( var infoCmd = &cobra.Command{ Use: "info [TARGET]", Short: "Show target info", - Aliases: []string{"view", "inspect"}, Args: cobra.RangeArgs(0, 1), + Aliases: common.GetAliases("info"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/target/list.go b/pkg/cmd/target/list.go index f6a6631658..bb761bdfbb 100644 --- a/pkg/cmd/target/list.go +++ b/pkg/cmd/target/list.go @@ -8,6 +8,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" list_view "github.com/daytonaio/daytona/pkg/views/target/list" "github.com/spf13/cobra" @@ -17,7 +18,7 @@ var listCmd = &cobra.Command{ Use: "list", Short: "List targets", Args: cobra.ExactArgs(0), - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/target/logs.go b/pkg/cmd/target/logs.go index 5b7e03a84c..fcb1dec3bf 100644 --- a/pkg/cmd/target/logs.go +++ b/pkg/cmd/target/logs.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -19,7 +20,7 @@ var logsCmd = &cobra.Command{ Use: "logs [TARGET]", Short: "View the logs of a target", Args: cobra.RangeArgs(0, 1), - Aliases: []string{"lg", "log"}, + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() c, err := config.GetConfig() diff --git a/pkg/cmd/target/setdefault.go b/pkg/cmd/target/setdefault.go index c0a7ac7b31..a29b3fcc39 100644 --- a/pkg/cmd/target/setdefault.go +++ b/pkg/cmd/target/setdefault.go @@ -9,6 +9,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/target/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -16,9 +17,10 @@ import ( ) var setDefaultCmd = &cobra.Command{ - Use: "set-default [TARGET]", - Short: "Set default target", - Args: cobra.RangeArgs(0, 1), + Use: "set-default [TARGET]", + Short: "Set default target", + Args: cobra.RangeArgs(0, 1), + Aliases: common.GetAliases("set-default"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/target/target.go b/pkg/cmd/target/target.go index 61e01de385..d6d4beff79 100644 --- a/pkg/cmd/target/target.go +++ b/pkg/cmd/target/target.go @@ -10,10 +10,10 @@ import ( var TargetCmd = &cobra.Command{ Use: "target", - Aliases: []string{"targets", "tg"}, Args: cobra.NoArgs, Short: "Manage targets", GroupID: util.TARGET_GROUP, + Aliases: []string{"targets", "tg"}, } func init() { diff --git a/pkg/cmd/targetconfig/add.go b/pkg/cmd/targetconfig/create.go similarity index 93% rename from pkg/cmd/targetconfig/add.go rename to pkg/cmd/targetconfig/create.go index 72b0db9fbe..2b104ff78f 100644 --- a/pkg/cmd/targetconfig/add.go +++ b/pkg/cmd/targetconfig/create.go @@ -30,11 +30,11 @@ import ( var pipeFile string -var TargetConfigAddCmd = &cobra.Command{ - Use: "add", - Short: "Add target config", +var TargetConfigCreateCmd = &cobra.Command{ + Use: "create", + Short: "Create target config", Args: cobra.NoArgs, - Aliases: []string{"a", "set", "register", "new", "create"}, + Aliases: cmd_common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var input []byte @@ -176,12 +176,12 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, err } - err = targetconfig.SetTargetConfigForm(selectedTargetConfig, selectedProvider.TargetConfigManifest) + err = targetconfig.CreateTargetConfigForm(selectedTargetConfig, selectedProvider.TargetConfigManifest) if err != nil { return nil, err } - targetConfigData := apiclient.AddTargetConfigDTO{ + targetConfigData := apiclient.CreateTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, ProviderInfo: apiclient.ProviderInfo{ @@ -195,7 +195,7 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien }, } - targetConfig, res, err := apiClient.TargetConfigAPI.AddTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() + targetConfig, res, err := apiClient.TargetConfigAPI.CreateTargetConfig(context.Background()).TargetConfig(targetConfigData).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -240,7 +240,7 @@ func handleTargetConfigJSON(data []byte) error { if err != nil { return err } - targetConfigData := apiclient.AddTargetConfigDTO{ + targetConfigData := apiclient.CreateTargetConfigDTO{ Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, ProviderInfo: apiclient.ProviderInfo{ @@ -248,7 +248,7 @@ func handleTargetConfigJSON(data []byte) error { Version: selectedTargetConfig.ProviderInfo.Version, }, } - _, res, err := apiClient.TargetConfigAPI.AddTargetConfig(ctx).TargetConfig(targetConfigData).Execute() + _, res, err := apiClient.TargetConfigAPI.CreateTargetConfig(ctx).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -353,5 +353,5 @@ func contains(slice []string, item interface{}) bool { } func init() { - TargetConfigAddCmd.Flags().StringVarP(&pipeFile, "file", "f", "", "Path to JSON file for target configuration, use '-' to read from stdin") + TargetConfigCreateCmd.Flags().StringVarP(&pipeFile, "file", "f", "", "Path to JSON file for target configuration, use '-' to read from stdin") } diff --git a/pkg/cmd/targetconfig/remove.go b/pkg/cmd/targetconfig/delete.go similarity index 81% rename from pkg/cmd/targetconfig/remove.go rename to pkg/cmd/targetconfig/delete.go index e6f119ef81..845a1894fe 100644 --- a/pkg/cmd/targetconfig/remove.go +++ b/pkg/cmd/targetconfig/delete.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/targetconfig" @@ -18,11 +19,11 @@ import ( var yesFlag bool -var removeCmd = &cobra.Command{ - Use: "remove [TARGET_CONFIG]", - Short: "Remove target config", +var deleteCmd = &cobra.Command{ + Use: "delete [TARGET_CONFIG]", + Short: "Deletes a target config", Args: cobra.RangeArgs(0, 1), - Aliases: []string{"rm", "delete"}, + Aliases: cmd_common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { var selectedConfigName string @@ -53,7 +54,7 @@ var removeCmd = &cobra.Command{ return nil } - selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(targetConfigs, activeProfile.Name, nil, false, "Remove") + selectedTargetConfig, err := targetconfig.GetTargetConfigFromPrompt(targetConfigs, activeProfile.Name, nil, false, "Delete") if err != nil { if common.IsCtrlCAbort(err) { return nil @@ -67,7 +68,7 @@ var removeCmd = &cobra.Command{ selectedConfigName = args[0] } - res, err := apiClient.TargetConfigAPI.RemoveTargetConfig(ctx, selectedConfigName).Execute() + res, err := apiClient.TargetConfigAPI.DeleteTargetConfig(ctx, selectedConfigName).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -78,5 +79,5 @@ var removeCmd = &cobra.Command{ } func init() { - removeCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all targets without prompt") + deleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion of all targets without prompt") } diff --git a/pkg/cmd/targetconfig/list.go b/pkg/cmd/targetconfig/list.go index c0d32dce4b..7811f34e7f 100644 --- a/pkg/cmd/targetconfig/list.go +++ b/pkg/cmd/targetconfig/list.go @@ -7,6 +7,7 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/targetconfig" "github.com/spf13/cobra" @@ -16,7 +17,7 @@ var listCmd = &cobra.Command{ Use: "list", Short: "List target configs", Args: cobra.NoArgs, - Aliases: []string{"ls"}, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/targetconfig/target_config.go b/pkg/cmd/targetconfig/target_config.go index d5682f8c88..bdf5b8c640 100644 --- a/pkg/cmd/targetconfig/target_config.go +++ b/pkg/cmd/targetconfig/target_config.go @@ -10,14 +10,14 @@ import ( var TargetConfigCmd = &cobra.Command{ Use: "target-config", - Aliases: []string{"tc"}, Short: "Manage target configs", Args: cobra.NoArgs, GroupID: util.SERVER_GROUP, + Aliases: []string{"target-configs", "tc"}, } func init() { TargetConfigCmd.AddCommand(listCmd) - TargetConfigCmd.AddCommand(TargetConfigAddCmd) - TargetConfigCmd.AddCommand(removeCmd) + TargetConfigCmd.AddCommand(TargetConfigCreateCmd) + TargetConfigCmd.AddCommand(deleteCmd) } diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index fd0c5367e8..edc2b3c853 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -35,6 +35,7 @@ var CreateCmd = &cobra.Command{ Use: "create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]...", Short: "Create a workspace", GroupID: util.TARGET_GROUP, + Aliases: cmd_common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var createWorkspaceDtos []apiclient.CreateWorkspaceDTO diff --git a/pkg/cmd/workspace/create/creation_data.go b/pkg/cmd/workspace/create/creation_data.go index 88684d80d6..b1c35b5f45 100644 --- a/pkg/cmd/workspace/create/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -114,7 +114,7 @@ func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesD } if workspaceTemplate.GitProviderConfigId == nil || *workspaceTemplate.GitProviderConfigId == "" { - gitProviderConfigId, res, err := params.ApiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(workspaceTemplate.RepositoryUrl)).Execute() + gitProviderConfigId, res, err := params.ApiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, url.QueryEscape(workspaceTemplate.RepositoryUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -222,11 +222,16 @@ func GetBranchFromWorkspaceTemplate(ctx context.Context, workspaceTemplate *apic return nil, apiclient_util.HandleErrorResponse(res, err) } - gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, encodedURLParam).Execute() + gitProviderConfigId, res, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, encodedURLParam).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } + gitProvider, _, err := apiClient.GitProviderAPI.FindGitProvider(ctx, gitProviderConfigId).Execute() + if err == nil && gitProvider != nil { + gitProviderConfigId = gitProvider.ProviderId + } + branchWizardConfig := BranchWizardParams{ ApiClient: apiClient, GitProviderConfigId: gitProviderConfigId, diff --git a/pkg/cmd/workspace/create/process_cmd_arguments.go b/pkg/cmd/workspace/create/process_cmd_arguments.go index 7a1eb46cd4..1c04e141c3 100644 --- a/pkg/cmd/workspace/create/process_cmd_arguments.go +++ b/pkg/cmd/workspace/create/process_cmd_arguments.go @@ -83,7 +83,7 @@ func ProcessCmdArguments(ctx context.Context, params ProcessCmdArgumentsParams) } // The argument is not a Git URL - try getting the workspace template - workspaceTemplate, _, err = params.ApiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, repoUrl).Execute() + workspaceTemplate, _, err = params.ApiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(ctx, repoUrl).Execute() if err != nil { return nil, fmt.Errorf("failed to parse the URL or fetch the workspace template for '%s'", repoUrl) } diff --git a/pkg/cmd/workspace/delete.go b/pkg/cmd/workspace/delete.go index ab77baab27..e97e6172e8 100644 --- a/pkg/cmd/workspace/delete.go +++ b/pkg/cmd/workspace/delete.go @@ -27,7 +27,7 @@ var DeleteCmd = &cobra.Command{ Use: "delete [WORKSPACE]...", Short: "Delete a workspace", GroupID: util.TARGET_GROUP, - Aliases: []string{"remove", "rm"}, + Aliases: common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { if allFlag { if yesFlag { diff --git a/pkg/cmd/workspace/info.go b/pkg/cmd/workspace/info.go index bcbee4d7d8..dfa47f1b60 100644 --- a/pkg/cmd/workspace/info.go +++ b/pkg/cmd/workspace/info.go @@ -20,9 +20,9 @@ import ( var InfoCmd = &cobra.Command{ Use: "info [WORKSPACE]", Short: "Show workspace info", - Aliases: []string{"view", "inspect"}, Args: cobra.RangeArgs(0, 1), GroupID: util.TARGET_GROUP, + Aliases: common.GetAliases("info"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 42e9390fcd..71e9dc703d 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -9,6 +9,7 @@ import ( "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" "github.com/daytonaio/daytona/internal/util/apiclient" + "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/workspace/list" "github.com/spf13/cobra" @@ -18,8 +19,8 @@ var ListCmd = &cobra.Command{ Use: "list", Short: "List workspaces", Args: cobra.NoArgs, - Aliases: []string{"ls"}, GroupID: util.TARGET_GROUP, + Aliases: common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var specifyGitProviders bool diff --git a/pkg/cmd/workspace/logs.go b/pkg/cmd/workspace/logs.go index d3c3c9e70a..d16ed4c324 100644 --- a/pkg/cmd/workspace/logs.go +++ b/pkg/cmd/workspace/logs.go @@ -25,7 +25,7 @@ var LogsCmd = &cobra.Command{ Short: "View the logs of a workspace", Args: cobra.RangeArgs(0, 2), GroupID: util.TARGET_GROUP, - Aliases: []string{"lg", "log"}, + Aliases: common.GetAliases("logs"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index d82d38f9cf..c6662ceae7 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -91,7 +91,7 @@ var StartCmd = &cobra.Command{ ideList = config.GetIdeList() ideId = c.DefaultIdeId - ws, res, err = apiClient.WorkspaceAPI.GetWorkspace(ctx, workspace.Id).Execute() + ws, res, err = apiClient.WorkspaceAPI.FindWorkspace(ctx, workspace.Id).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/workspacetemplate/add.go b/pkg/cmd/workspacetemplate/create.go similarity index 91% rename from pkg/cmd/workspacetemplate/add.go rename to pkg/cmd/workspacetemplate/create.go index 2d5b2ff5ed..ae945f0f4b 100644 --- a/pkg/cmd/workspacetemplate/add.go +++ b/pkg/cmd/workspacetemplate/create.go @@ -21,11 +21,11 @@ import ( "github.com/spf13/cobra" ) -var workspaceTemplateAddCmd = &cobra.Command{ - Use: "add", - Aliases: []string{"new", "create"}, - Short: "Add a workspace template", +var createCmd = &cobra.Command{ + Use: "create", + Short: "Create a workspace template", Args: cobra.MaximumNArgs(1), + Aliases: cmd_common.GetAliases("create"), RunE: func(cmd *cobra.Command, args []string) error { var workspaceTemplate *apiclient.WorkspaceTemplate var workspaceTemplateName *string @@ -147,7 +147,7 @@ func RunWorkspaceTemplateAddFlow(apiClient *apiclient.APIClient, gitProviders [] GitProviderConfigId: createDtos[0].GitProviderConfigId, } - res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(createWorkspaceTemplate).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SaveWorkspaceTemplate(ctx).WorkspaceTemplate(createWorkspaceTemplate).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -171,7 +171,7 @@ func RunWorkspaceTemplateAddFlow(apiClient *apiclient.APIClient, gitProviders [] } if createWorkspaceTemplate.GitProviderConfigId == nil && *createWorkspaceTemplate.GitProviderConfigId == "" { - gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(createWorkspaceTemplate.RepositoryUrl)).Execute() + gitProviderConfigId, res, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, url.QueryEscape(createWorkspaceTemplate.RepositoryUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -227,7 +227,7 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con } if workspace.GitProviderConfigId == nil || *workspace.GitProviderConfigId == "" { - gitProviderConfigId, res, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(repoUrl)).Execute() + gitProviderConfigId, res, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, url.QueryEscape(repoUrl)).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -252,7 +252,7 @@ func processCmdArgument(argument string, apiClient *apiclient.APIClient, ctx con newWorkspaceTemplate.User = &apiServerConfig.DefaultWorkspaceUser } - res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SaveWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } @@ -289,6 +289,6 @@ var workspaceConfigurationFlags = cmd_common.WorkspaceConfigurationFlags{ } func init() { - workspaceTemplateAddCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace template name") - cmd_common.AddWorkspaceConfigurationFlags(workspaceTemplateAddCmd, workspaceConfigurationFlags, false) + createCmd.Flags().StringVar(&nameFlag, "name", "", "Specify the workspace template name") + cmd_common.AddWorkspaceConfigurationFlags(createCmd, workspaceConfigurationFlags, false) } diff --git a/pkg/cmd/workspacetemplate/delete.go b/pkg/cmd/workspacetemplate/delete.go index 2f644e9f11..08a4b03ce1 100644 --- a/pkg/cmd/workspacetemplate/delete.go +++ b/pkg/cmd/workspacetemplate/delete.go @@ -10,6 +10,7 @@ import ( "github.com/charmbracelet/huh" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -23,9 +24,9 @@ var forceFlag bool var workspaceTemplateDeleteCmd = &cobra.Command{ Use: "delete", - Aliases: []string{"remove", "rm"}, Short: "Delete a workspace template", Args: cobra.MaximumNArgs(1), + Aliases: cmd_common.GetAliases("delete"), RunE: func(cmd *cobra.Command, args []string) error { var selectedWorkspaceTemplate *apiclient.WorkspaceTemplate var selectedWorkspaceTemplateName string diff --git a/pkg/cmd/workspacetemplate/export.go b/pkg/cmd/workspacetemplate/export.go index 230503edd7..306a881204 100644 --- a/pkg/cmd/workspacetemplate/export.go +++ b/pkg/cmd/workspacetemplate/export.go @@ -72,7 +72,7 @@ var workspaceTemplateExportCmd = &cobra.Command{ } } else { var res *http.Response - selectedWorkspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, args[0]).Execute() + selectedWorkspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/workspacetemplate/import.go b/pkg/cmd/workspacetemplate/import.go index b32fe7cb0d..5686102c32 100644 --- a/pkg/cmd/workspacetemplate/import.go +++ b/pkg/cmd/workspacetemplate/import.go @@ -119,7 +119,7 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient var verifiedGitProvider bool if config.GitProviderConfigId != nil { - _, _, err := apiClient.GitProviderAPI.GetGitProvider(ctx, *config.GitProviderConfigId).Execute() + _, _, err := apiClient.GitProviderAPI.FindGitProvider(ctx, *config.GitProviderConfigId).Execute() if err == nil { verifiedGitProvider = true } @@ -135,7 +135,7 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient } if len(gitProviders) == 0 { - gitProviderConfigId, _, err := apiClient.GitProviderAPI.GetGitProviderIdForUrl(ctx, url.QueryEscape(config.RepositoryUrl)).Execute() + gitProviderConfigId, _, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, url.QueryEscape(config.RepositoryUrl)).Execute() if err != nil { return fmt.Errorf("error fetching Git provider: %v", err) } @@ -228,7 +228,7 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient } if submissionFormConfig.ImportConfirmation != nil && *submissionFormConfig.ImportConfirmation { - res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SaveWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/workspacetemplate/info.go b/pkg/cmd/workspacetemplate/info.go index 491d5b8476..a19b2beb76 100644 --- a/pkg/cmd/workspacetemplate/info.go +++ b/pkg/cmd/workspacetemplate/info.go @@ -9,6 +9,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -19,7 +20,7 @@ import ( var workspaceTemplateInfoCmd = &cobra.Command{ Use: "info", Short: "Show workspace template info", - Aliases: []string{"view", "inspect"}, + Aliases: cmd_common.GetAliases("info"), Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -58,7 +59,7 @@ var workspaceTemplateInfoCmd = &cobra.Command{ } else { var res *http.Response - workspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, args[0]).Execute() + workspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/workspacetemplate/list.go b/pkg/cmd/workspacetemplate/list.go index 9fb22148a1..ec0489cdab 100644 --- a/pkg/cmd/workspacetemplate/list.go +++ b/pkg/cmd/workspacetemplate/list.go @@ -7,6 +7,7 @@ import ( "context" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" workspacetemplate_view "github.com/daytonaio/daytona/pkg/views/workspacetemplate/list" "github.com/spf13/cobra" @@ -15,8 +16,8 @@ import ( var workspaceTemplateListCmd = &cobra.Command{ Use: "list", Short: "Lists workspace templates", - Aliases: []string{"ls"}, Args: cobra.NoArgs, + Aliases: cmd_common.GetAliases("list"), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() var specifyGitProviders bool diff --git a/pkg/cmd/workspacetemplate/setdefault.go b/pkg/cmd/workspacetemplate/setdefault.go index d40f673d29..22b7fdc1fa 100644 --- a/pkg/cmd/workspacetemplate/setdefault.go +++ b/pkg/cmd/workspacetemplate/setdefault.go @@ -8,6 +8,7 @@ import ( "fmt" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -15,9 +16,10 @@ import ( ) var workspaceTemplateSetDefaultCmd = &cobra.Command{ - Use: "set-default", - Short: "Set workspace template info", - Args: cobra.MaximumNArgs(1), + Use: "set-default", + Short: "Set workspace template info", + Args: cobra.MaximumNArgs(1), + Aliases: cmd_common.GetAliases("set-default"), RunE: func(cmd *cobra.Command, args []string) error { var workspaceTemplateName string ctx := context.Background() diff --git a/pkg/cmd/workspacetemplate/update.go b/pkg/cmd/workspacetemplate/update.go index 29e7382e7c..42aa518292 100644 --- a/pkg/cmd/workspacetemplate/update.go +++ b/pkg/cmd/workspacetemplate/update.go @@ -10,6 +10,7 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" + cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" "github.com/daytonaio/daytona/pkg/views/selection" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -18,9 +19,10 @@ import ( ) var workspaceTemplateUpdateCmd = &cobra.Command{ - Use: "update", - Short: "Update a workspace template", - Args: cobra.MaximumNArgs(1), + Use: "update", + Short: "Update a workspace template", + Args: cobra.MaximumNArgs(1), + Aliases: cmd_common.GetAliases("update"), RunE: func(cmd *cobra.Command, args []string) error { var workspaceTemplate *apiclient.WorkspaceTemplate var res *http.Response @@ -47,7 +49,7 @@ var workspaceTemplateUpdateCmd = &cobra.Command{ return nil } } else { - workspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.GetWorkspaceTemplate(ctx, args[0]).Execute() + workspaceTemplate, res, err = apiClient.WorkspaceTemplateAPI.FindWorkspaceTemplate(ctx, args[0]).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -120,7 +122,7 @@ var workspaceTemplateUpdateCmd = &cobra.Command{ GitProviderConfigId: createDto[0].GitProviderConfigId, } - res, err = apiClient.WorkspaceTemplateAPI.SetWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() + res, err = apiClient.WorkspaceTemplateAPI.SaveWorkspaceTemplate(ctx).WorkspaceTemplate(newWorkspaceTemplate).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } diff --git a/pkg/cmd/workspacetemplate/workspacetemplate.go b/pkg/cmd/workspacetemplate/workspacetemplate.go index eb1e01be34..728f946655 100644 --- a/pkg/cmd/workspacetemplate/workspacetemplate.go +++ b/pkg/cmd/workspacetemplate/workspacetemplate.go @@ -12,14 +12,14 @@ var WorkspaceTemplateCmd = &cobra.Command{ Use: "template", Short: "Manage workspace templates", Args: cobra.NoArgs, - Aliases: []string{"templates", "workspace-template", "workspace-templates", "wt"}, GroupID: util.TARGET_GROUP, + Aliases: []string{"templates", "workspace-template", "workspace-templates", "wt"}, } func init() { WorkspaceTemplateCmd.AddCommand(workspaceTemplateListCmd) WorkspaceTemplateCmd.AddCommand(workspaceTemplateInfoCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateAddCmd) + WorkspaceTemplateCmd.AddCommand(createCmd) WorkspaceTemplateCmd.AddCommand(workspaceTemplateUpdateCmd) WorkspaceTemplateCmd.AddCommand(workspaceTemplateSetDefaultCmd) WorkspaceTemplateCmd.AddCommand(workspaceTemplateDeleteCmd) diff --git a/pkg/models/workspace_template.go b/pkg/models/workspace_template.go index 3df724e176..3aaa9434dc 100644 --- a/pkg/models/workspace_template.go +++ b/pkg/models/workspace_template.go @@ -69,7 +69,7 @@ func (wt *WorkspaceTemplate) ListPrebuilds(filter *MatchParams) ([]*PrebuildConf return prebuilds, nil } -func (wt *WorkspaceTemplate) RemovePrebuild(id string) error { +func (wt *WorkspaceTemplate) DeletePrebuild(id string) error { newPrebuilds := []*PrebuildConfig{} for _, pb := range wt.Prebuilds { diff --git a/pkg/server/apikeys/apikeys.go b/pkg/server/apikeys/apikeys.go index 9ff82f148e..cf4ef837e5 100644 --- a/pkg/server/apikeys/apikeys.go +++ b/pkg/server/apikeys/apikeys.go @@ -32,7 +32,7 @@ func (s *ApiKeyService) ListClientKeys(ctx context.Context) ([]*services.ApiKeyD return clientKeys, nil } -func (s *ApiKeyService) Revoke(ctx context.Context, name string) error { +func (s *ApiKeyService) Delete(ctx context.Context, name string) error { apiKey, err := s.apiKeyStore.FindByName(ctx, name) if err != nil { return err @@ -41,7 +41,7 @@ func (s *ApiKeyService) Revoke(ctx context.Context, name string) error { return s.apiKeyStore.Delete(ctx, apiKey) } -func (s *ApiKeyService) Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) { +func (s *ApiKeyService) Create(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) { key := s.generateRandomKey(name) apiKey := &models.ApiKey{ @@ -52,10 +52,10 @@ func (s *ApiKeyService) Generate(ctx context.Context, keyType models.ApiKeyType, err := s.apiKeyStore.Save(ctx, apiKey) if err != nil { - return "", s.handleGenerateApiKeyError(ctx, apiKey, err) + return "", s.handleCreateApiKeyError(ctx, apiKey, err) } - return key, s.handleGenerateApiKeyError(ctx, apiKey, nil) + return key, s.handleCreateApiKeyError(ctx, apiKey, nil) } func (s *ApiKeyService) GetApiKeyName(ctx context.Context, apiKey string) (string, error) { @@ -67,7 +67,7 @@ func (s *ApiKeyService) GetApiKeyName(ctx context.Context, apiKey string) (strin return key.Name, nil } -func (s *ApiKeyService) handleGenerateApiKeyError(ctx context.Context, key *models.ApiKey, err error) error { +func (s *ApiKeyService) handleCreateApiKeyError(ctx context.Context, key *models.ApiKey, err error) error { if key.Type != models.ApiKeyTypeClient { return err } diff --git a/pkg/server/apikeys/apikeys_test.go b/pkg/server/apikeys/apikeys_test.go index 0071bce28d..3c427c6e5e 100644 --- a/pkg/server/apikeys/apikeys_test.go +++ b/pkg/server/apikeys/apikeys_test.go @@ -44,7 +44,7 @@ func (s *ApiKeyServiceTestSuite) TestRevoke() { require := s.Require() - err := s.apiKeyService.Revoke(context.TODO(), clientKeyNames[0]) + err := s.apiKeyService.Delete(context.TODO(), clientKeyNames[0]) require.Nil(err) keys, err := s.apiKeyStore.List(context.TODO()) @@ -67,7 +67,7 @@ func (s *ApiKeyServiceTestSuite) TestGenerate() { require := s.Require() - _, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) + _, err := s.apiKeyService.Create(context.TODO(), models.ApiKeyTypeClient, keyName) require.Nil(err) apiKey, err := s.apiKeyStore.FindByName(context.TODO(), keyName) diff --git a/pkg/server/apikeys/service_test.go b/pkg/server/apikeys/service_test.go index 04c4553857..2fc87546e2 100644 --- a/pkg/server/apikeys/service_test.go +++ b/pkg/server/apikeys/service_test.go @@ -47,11 +47,11 @@ func (s *ApiKeyServiceTestSuite) SetupTest() { }) for _, keyName := range clientKeyNames { - _, _ = s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeClient, keyName) + _, _ = s.apiKeyService.Create(context.TODO(), models.ApiKeyTypeClient, keyName) } for _, keyName := range workspaceKeyNames { - _, _ = s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) + _, _ = s.apiKeyService.Create(context.TODO(), models.ApiKeyTypeWorkspace, keyName) } } diff --git a/pkg/server/apikeys/validate_test.go b/pkg/server/apikeys/validate_test.go index 481801e61b..ff13380404 100644 --- a/pkg/server/apikeys/validate_test.go +++ b/pkg/server/apikeys/validate_test.go @@ -14,7 +14,7 @@ func (s *ApiKeyServiceTestSuite) TestIsValidKey_True() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Create(context.TODO(), models.ApiKeyTypeWorkspace, keyName) require.Nil(err) res := s.apiKeyService.IsValidApiKey(context.TODO(), apiKey) @@ -35,7 +35,7 @@ func (s *ApiKeyServiceTestSuite) TestGetApiKeyType() { require := s.Require() - apiKey, err := s.apiKeyService.Generate(context.TODO(), models.ApiKeyTypeWorkspace, keyName) + apiKey, err := s.apiKeyService.Create(context.TODO(), models.ApiKeyTypeWorkspace, keyName) require.Nil(err) apiKeyType, err := s.apiKeyService.GetApiKeyType(context.TODO(), apiKey) diff --git a/pkg/server/gitproviders/config.go b/pkg/server/gitproviders/config.go index 95fef25729..5ba6025910 100644 --- a/pkg/server/gitproviders/config.go +++ b/pkg/server/gitproviders/config.go @@ -16,7 +16,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *GitProviderService) GetConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) { +func (s *GitProviderService) FindConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) { return s.configStore.Find(ctx, id) } @@ -55,7 +55,7 @@ func (s *GitProviderService) ListConfigsForUrl(ctx context.Context, repoUrl stri return gpcs, nil } -func (s *GitProviderService) SetGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error { +func (s *GitProviderService) SaveGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error { gitProvider, err := s.newGitProvider(providerConfig) if err != nil { return s.handleSetGitProviderConfigError(ctx, providerConfig, err) diff --git a/pkg/server/gitproviders/remove.go b/pkg/server/gitproviders/delete.go similarity index 73% rename from pkg/server/gitproviders/remove.go rename to pkg/server/gitproviders/delete.go index bdc431ad78..a3505e10da 100644 --- a/pkg/server/gitproviders/remove.go +++ b/pkg/server/gitproviders/delete.go @@ -11,22 +11,22 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *GitProviderService) RemoveGitProvider(ctx context.Context, gitProviderId string) error { +func (s *GitProviderService) DeleteGitProviderConfig(ctx context.Context, gitProviderId string) error { gitProvider, err := s.configStore.Find(ctx, gitProviderId) if err != nil { - return s.handleRemoveGitProviderConfigError(ctx, nil, err) + return s.handleDeleteGitProviderConfigError(ctx, nil, err) } err = s.detachWorkspaceTemplates(ctx, gitProvider.Id) if err != nil { - return s.handleRemoveGitProviderConfigError(ctx, gitProvider, err) + return s.handleDeleteGitProviderConfigError(ctx, gitProvider, err) } err = s.configStore.Delete(ctx, gitProvider) - return s.handleRemoveGitProviderConfigError(ctx, gitProvider, err) + return s.handleDeleteGitProviderConfigError(ctx, gitProvider, err) } -func (s *GitProviderService) handleRemoveGitProviderConfigError(ctx context.Context, gpc *models.GitProviderConfig, err error) error { +func (s *GitProviderService) handleDeleteGitProviderConfigError(ctx context.Context, gpc *models.GitProviderConfig, err error) error { if !telemetry.TelemetryEnabled(ctx) { return err } diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index 11db91c70a..529612755f 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -75,12 +75,12 @@ func (s *JobService) Create(ctx context.Context, j *models.Job) error { return s.handleCreateError(ctx, j, err) } -func (s *JobService) SetState(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { - job, findErr := s.Find(ctx, &stores.JobFilter{ +func (s *JobService) UpdateState(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { + job, err := s.Find(ctx, &stores.JobFilter{ Id: &jobId, }) - if findErr != nil { - return findErr + if err != nil { + return err } if job.State == updateJobStateDto.State { diff --git a/pkg/server/jobs/service_test.go b/pkg/server/jobs/service_test.go index f0a95d0f6b..906979f952 100644 --- a/pkg/server/jobs/service_test.go +++ b/pkg/server/jobs/service_test.go @@ -122,7 +122,7 @@ func (s *JobServiceTestSuite) TestSetState() { job4Update := *job4 job4Update.State = models.JobStateSuccess - err = s.jobService.SetState(context.TODO(), job4Update.Id, services.UpdateJobStateDTO{ + err = s.jobService.UpdateState(context.TODO(), job4Update.Id, services.UpdateJobStateDTO{ State: models.JobStateSuccess, ErrorMessage: nil, }) diff --git a/pkg/server/registry/service.go b/pkg/server/registry/service.go index 5c02aaa548..723643790a 100644 --- a/pkg/server/registry/service.go +++ b/pkg/server/registry/service.go @@ -85,7 +85,7 @@ func (s *LocalContainerRegistry) Start() error { // we want to always create a new container // to avoid conflicts with configuration changes - if err := RemoveRegistryContainer(); err != nil { + if err := DeleteRegistryContainer(); err != nil { return err } @@ -170,14 +170,14 @@ func (s *LocalContainerRegistry) Start() error { } func (s *LocalContainerRegistry) Stop() error { - return RemoveRegistryContainer() + return DeleteRegistryContainer() } func (s *LocalContainerRegistry) Purge() error { return os.RemoveAll(s.dataPath) } -func RemoveRegistryContainer() error { +func DeleteRegistryContainer() error { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return err diff --git a/pkg/server/runners/register.go b/pkg/server/runners/create.go similarity index 92% rename from pkg/server/runners/register.go rename to pkg/server/runners/create.go index 4c495a83ec..39c27d25ce 100644 --- a/pkg/server/runners/register.go +++ b/pkg/server/runners/create.go @@ -14,7 +14,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *RunnerService) RegisterRunner(ctx context.Context, req services.RegisterRunnerDTO) (*services.RunnerDTO, error) { +func (s *RunnerService) CreateRunner(ctx context.Context, req services.CreateRunnerDTO) (*services.RunnerDTO, error) { var err error ctx, err = s.runnerStore.BeginTransaction(ctx) if err != nil { @@ -28,7 +28,7 @@ func (s *RunnerService) RegisterRunner(ctx context.Context, req services.Registe return nil, s.handleRegisterError(ctx, nil, services.ErrRunnerAlreadyExists) } - apiKey, err := s.generateApiKey(ctx, req.Id) + apiKey, err := s.createApiKey(ctx, req.Id) if err != nil { return nil, s.handleRegisterError(ctx, nil, err) } diff --git a/pkg/server/runners/remove.go b/pkg/server/runners/delete.go similarity index 73% rename from pkg/server/runners/remove.go rename to pkg/server/runners/delete.go index c9c6478924..df2c6efcae 100644 --- a/pkg/server/runners/remove.go +++ b/pkg/server/runners/delete.go @@ -12,51 +12,51 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *RunnerService) RemoveRunner(ctx context.Context, runnerId string) error { +func (s *RunnerService) DeleteRunner(ctx context.Context, runnerId string) error { var err error ctx, err = s.runnerStore.BeginTransaction(ctx) if err != nil { - return s.handleRemoveError(ctx, nil, err) + return s.handleDeleteError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.runnerStore) runner, err := s.runnerStore.Find(ctx, runnerId) if err != nil { - return s.handleRemoveError(ctx, nil, err) + return s.handleDeleteError(ctx, nil, err) } err = s.runnerStore.Delete(ctx, runner) if err != nil { - return s.handleRemoveError(ctx, runner, err) + return s.handleDeleteError(ctx, runner, err) } metadata, err := s.runnerMetadataStore.Find(ctx, runnerId) if err != nil && !stores.IsRunnerMetadataNotFound(err) { - return s.handleRemoveError(ctx, runner, err) + return s.handleDeleteError(ctx, runner, err) } if metadata != nil { err = s.runnerMetadataStore.Delete(ctx, metadata) if err != nil { - return s.handleRemoveError(ctx, runner, err) + return s.handleDeleteError(ctx, runner, err) } } - err = s.revokeApiKey(ctx, runner.Id) + err = s.deleteApiKey(ctx, runner.Id) if err != nil { - return s.handleRemoveError(ctx, runner, err) + return s.handleDeleteError(ctx, runner, err) } err = s.unsetDefaultTarget(ctx, runner.Id) if err != nil { - return s.handleRemoveError(ctx, runner, err) + return s.handleDeleteError(ctx, runner, err) } err = s.runnerStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, runner, err) + return s.handleDeleteError(ctx, runner, err) } -func (s *RunnerService) handleRemoveError(ctx context.Context, r *models.Runner, err error) error { +func (s *RunnerService) handleDeleteError(ctx context.Context, r *models.Runner, err error) error { if err != nil { err = s.runnerStore.RollbackTransaction(ctx, err) } diff --git a/pkg/server/runners/service.go b/pkg/server/runners/service.go index 44180fbcf2..39f85fbc96 100644 --- a/pkg/server/runners/service.go +++ b/pkg/server/runners/service.go @@ -23,8 +23,8 @@ type RunnerServiceConfig struct { CreateJob func(ctx context.Context, runnerId string, action models.JobAction, metadata string) error ListJobsForRunner func(ctx context.Context, runnerId string) ([]*models.Job, error) UpdateJobState func(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error - GenerateApiKey func(ctx context.Context, name string) (string, error) - RevokeApiKey func(ctx context.Context, name string) error + CreateApiKey func(ctx context.Context, name string) (string, error) + DeleteApiKey func(ctx context.Context, name string) error UnsetDefaultTarget func(ctx context.Context, runnerId string) error TrackTelemetryEvent func(event telemetry.Event, clientId string) error @@ -39,8 +39,8 @@ func NewRunnerService(config RunnerServiceConfig) services.IRunnerService { createJob: config.CreateJob, listJobsForRunner: config.ListJobsForRunner, updateJobState: config.UpdateJobState, - generateApiKey: config.GenerateApiKey, - revokeApiKey: config.RevokeApiKey, + createApiKey: config.CreateApiKey, + deleteApiKey: config.DeleteApiKey, unsetDefaultTarget: config.UnsetDefaultTarget, trackTelemetryEvent: config.TrackTelemetryEvent, @@ -55,14 +55,14 @@ type RunnerService struct { createJob func(ctx context.Context, runnerId string, action models.JobAction, metadata string) error listJobsForRunner func(ctx context.Context, runnerId string) ([]*models.Job, error) updateJobState func(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error - generateApiKey func(ctx context.Context, name string) (string, error) - revokeApiKey func(ctx context.Context, name string) error + createApiKey func(ctx context.Context, name string) (string, error) + deleteApiKey func(ctx context.Context, name string) error unsetDefaultTarget func(ctx context.Context, runnerId string) error trackTelemetryEvent func(event telemetry.Event, clientId string) error } -func (s *RunnerService) GetRunner(ctx context.Context, runnerId string) (*services.RunnerDTO, error) { +func (s *RunnerService) FindRunner(ctx context.Context, runnerId string) (*services.RunnerDTO, error) { runner, err := s.runnerStore.Find(ctx, runnerId) if err != nil { return nil, stores.ErrRunnerNotFound @@ -88,7 +88,7 @@ func (s *RunnerService) ListRunners(ctx context.Context) ([]*services.RunnerDTO, }), nil } -func (s *RunnerService) SetRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error { +func (s *RunnerService) UpdateRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error { m, err := s.runnerMetadataStore.Find(ctx, runnerId) if err != nil { return stores.ErrRunnerMetadataNotFound diff --git a/pkg/server/targetconfigs/service.go b/pkg/server/targetconfigs/service.go index a8836083b8..3e78e5b216 100644 --- a/pkg/server/targetconfigs/service.go +++ b/pkg/server/targetconfigs/service.go @@ -54,7 +54,7 @@ func (s *TargetConfigService) Find(ctx context.Context, idOrName string) (*model return s.targetConfigStore.Find(ctx, idOrName, false) } -func (s *TargetConfigService) Add(ctx context.Context, addTargetConfig services.AddTargetConfigDTO) (*models.TargetConfig, error) { +func (s *TargetConfigService) Create(ctx context.Context, addTargetConfig services.CreateTargetConfigDTO) (*models.TargetConfig, error) { persistedTargetConfig, err := s.targetConfigStore.Find(ctx, addTargetConfig.Name, false) if err != nil && !stores.IsTargetConfigNotFound(err) { return nil, s.handleCreateError(ctx, nil, err) diff --git a/pkg/server/targetconfigs/service_test.go b/pkg/server/targetconfigs/service_test.go index 7d20d377e9..108a5ee3d0 100644 --- a/pkg/server/targetconfigs/service_test.go +++ b/pkg/server/targetconfigs/service_test.go @@ -81,7 +81,7 @@ func (s *TargetConfigServiceTestSuite) SetupTest() { }) for _, targetConfig := range expectedConfigs { - tc, err := s.targetConfigService.Add(context.TODO(), services.AddTargetConfigDTO{ + tc, err := s.targetConfigService.Create(context.TODO(), services.CreateTargetConfigDTO{ Name: targetConfig.Name, ProviderInfo: targetConfig.ProviderInfo, Options: targetConfig.Options, @@ -124,7 +124,7 @@ func (s *TargetConfigServiceTestSuite) TestFind() { func (s *TargetConfigServiceTestSuite) TestSave() { require := s.Require() - tc, err := s.targetConfigService.Add(context.TODO(), services.AddTargetConfigDTO{ + tc, err := s.targetConfigService.Create(context.TODO(), services.CreateTargetConfigDTO{ Name: targetConfig4.Name, ProviderInfo: targetConfig4.ProviderInfo, Options: targetConfig4.Options, diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index 6d49b7716d..a2a0fd05a3 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -47,7 +47,7 @@ func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTar TargetConfig: *tc, } - apiKey, err := s.generateApiKey(ctx, tg.Id) + apiKey, err := s.createApiKey(ctx, tg.Id) if err != nil { return s.handleCreateError(ctx, nil, err) } diff --git a/pkg/server/targets/remove.go b/pkg/server/targets/delete.go similarity index 74% rename from pkg/server/targets/remove.go rename to pkg/server/targets/delete.go index a1e06422ca..c3382a9463 100644 --- a/pkg/server/targets/remove.go +++ b/pkg/server/targets/delete.go @@ -13,72 +13,72 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *TargetService) RemoveTarget(ctx context.Context, targetId string) error { +func (s *TargetService) DeleteTarget(ctx context.Context, targetId string) error { var err error ctx, err = s.targetStore.BeginTransaction(ctx) if err != nil { - return s.handleRemoveError(ctx, nil, err) + return s.handleDeleteError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.targetStore) t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleRemoveError(ctx, t, stores.ErrTargetNotFound) + return s.handleDeleteError(ctx, t, stores.ErrTargetNotFound) } t.Name = util.AddDeletedToName(t.Name) err = s.targetStore.Save(ctx, t) if err != nil { - return s.handleRemoveError(ctx, t, err) + return s.handleDeleteError(ctx, t, err) } - err = s.revokeApiKey(ctx, targetId) + err = s.deleteApiKey(ctx, targetId) if err != nil { - return s.handleRemoveError(ctx, t, err) + return s.handleDeleteError(ctx, t, err) } metadata, err := s.targetMetadataStore.Find(ctx, targetId) if err == nil { err = s.targetMetadataStore.Delete(ctx, metadata) if err != nil { - return s.handleRemoveError(ctx, t, err) + return s.handleDeleteError(ctx, t, err) } } err = s.createJob(ctx, t.Id, t.TargetConfig.ProviderInfo.RunnerId, models.JobActionDelete) if err != nil { - return s.handleRemoveError(ctx, t, err) + return s.handleDeleteError(ctx, t, err) } err = s.targetStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, t, err) + return s.handleDeleteError(ctx, t, err) } -// ForceRemoveTarget ignores provider errors and makes sure the target is removed from storage. -func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) error { +// ForceDeleteTarget ignores provider errors and makes sure the target is deleted from storage. +func (s *TargetService) ForceDeleteTarget(ctx context.Context, targetId string) error { var err error ctx, err = s.targetStore.BeginTransaction(ctx) if err != nil { - return s.handleForceRemoveError(ctx, nil, err) + return s.handleForceDeleteError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.targetStore) t, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { - return s.handleForceRemoveError(ctx, nil, stores.ErrTargetNotFound) + return s.handleForceDeleteError(ctx, nil, stores.ErrTargetNotFound) } t.Name = util.AddDeletedToName(t.Name) err = s.targetStore.Save(ctx, t) if err != nil { - return s.handleForceRemoveError(ctx, t, err) + return s.handleForceDeleteError(ctx, t, err) } - err = s.revokeApiKey(ctx, targetId) + err = s.deleteApiKey(ctx, targetId) if err != nil { log.Error(err) } @@ -93,14 +93,14 @@ func (s *TargetService) ForceRemoveTarget(ctx context.Context, targetId string) err = s.createJob(ctx, t.Id, t.TargetConfig.ProviderInfo.RunnerId, models.JobActionForceDelete) if err != nil { - return s.handleForceRemoveError(ctx, t, err) + return s.handleForceDeleteError(ctx, t, err) } err = s.targetStore.CommitTransaction(ctx) - return s.handleForceRemoveError(ctx, t, err) + return s.handleForceDeleteError(ctx, t, err) } -func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Target, err error) error { +func (s *TargetService) handleDeleteError(ctx context.Context, target *models.Target, err error) error { if err != nil { err = s.targetStore.RollbackTransaction(ctx, err) } @@ -124,7 +124,7 @@ func (s *TargetService) handleRemoveError(ctx context.Context, target *models.Ta return err } -func (s *TargetService) handleForceRemoveError(ctx context.Context, target *models.Target, err error) error { +func (s *TargetService) handleForceDeleteError(ctx context.Context, target *models.Target, err error) error { if err != nil { err = s.targetStore.RollbackTransaction(ctx, err) } diff --git a/pkg/server/targets/get.go b/pkg/server/targets/find.go similarity index 84% rename from pkg/server/targets/get.go rename to pkg/server/targets/find.go index e685531fcc..8893e8cb0d 100644 --- a/pkg/server/targets/get.go +++ b/pkg/server/targets/find.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *TargetService) GetTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { +func (s *TargetService) FindTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { tg, err := s.targetStore.Find(ctx, filter) if err != nil { return nil, stores.ErrTargetNotFound diff --git a/pkg/server/targets/metadata.go b/pkg/server/targets/metadata.go index b629e6fcbe..9b8df87ccd 100644 --- a/pkg/server/targets/metadata.go +++ b/pkg/server/targets/metadata.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *TargetService) SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { +func (s *TargetService) UpdateTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { m, err := s.targetMetadataStore.Find(ctx, targetId) if err != nil { return nil, stores.ErrTargetMetadataNotFound diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 61dde8a94b..383062c0a3 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -19,8 +19,8 @@ type TargetServiceConfig struct { TargetMetadataStore stores.TargetMetadataStore FindTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) - GenerateApiKey func(ctx context.Context, name string) (string, error) - RevokeApiKey func(ctx context.Context, name string) error + CreateApiKey func(ctx context.Context, name string) (string, error) + DeleteApiKey func(ctx context.Context, name string) error CreateJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error TrackTelemetryEvent func(event telemetry.Event, clientId string) error @@ -36,8 +36,8 @@ func NewTargetService(config TargetServiceConfig) services.ITargetService { targetMetadataStore: config.TargetMetadataStore, findTargetConfig: config.FindTargetConfig, - generateApiKey: config.GenerateApiKey, - revokeApiKey: config.RevokeApiKey, + createApiKey: config.CreateApiKey, + deleteApiKey: config.DeleteApiKey, createJob: config.CreateJob, serverApiUrl: config.ServerApiUrl, @@ -53,8 +53,8 @@ type TargetService struct { targetMetadataStore stores.TargetMetadataStore findTargetConfig func(ctx context.Context, name string) (*models.TargetConfig, error) - generateApiKey func(ctx context.Context, name string) (string, error) - revokeApiKey func(ctx context.Context, name string) error + createApiKey func(ctx context.Context, name string) (string, error) + deleteApiKey func(ctx context.Context, name string) error createJob func(ctx context.Context, targetId string, runnerId string, action models.JobAction) error trackTelemetryEvent func(event telemetry.Event, clientId string) error diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index 0d79b68ca2..bb2c45f107 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -79,11 +79,11 @@ func TestTargetService(t *testing.T) { FindTargetConfig: func(ctx context.Context, name string) (*models.TargetConfig, error) { return targetConfigStore.Find(ctx, name, false) }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(models.ApiKeyTypeTarget, name) + CreateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Create(models.ApiKeyTypeTarget, name) }, - RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(name) + DeleteApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Delete(name) }, ServerApiUrl: serverApiUrl, ServerUrl: serverUrl, @@ -104,7 +104,7 @@ func TestTargetService(t *testing.T) { }) t.Run("CreateTarget", func(t *testing.T) { - apiKeyService.On("Generate", models.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) + apiKeyService.On("Create", models.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) target, err := service.CreateTarget(ctx, createTargetDTO) @@ -123,8 +123,8 @@ func TestTargetService(t *testing.T) { require.Equal(t, services.ErrTargetAlreadyExists, err) }) - t.Run("GetTarget", func(t *testing.T) { - target, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) + t.Run("FindTarget", func(t *testing.T) { + target, err := service.FindTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Nil(t, err) require.NotNil(t, target) @@ -132,8 +132,8 @@ func TestTargetService(t *testing.T) { targetDtoEquals(t, createTargetDTO, *target) }) - t.Run("GetTarget fails when target not found", func(t *testing.T) { - _, err := service.GetTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{}) + t.Run("FindTarget fails when target not found", func(t *testing.T) { + _, err := service.FindTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{}) require.NotNil(t, err) require.Equal(t, stores.ErrTargetNotFound, err) }) @@ -169,38 +169,38 @@ func TestTargetService(t *testing.T) { require.Nil(t, err) }) - t.Run("SetTargetMetadata", func(t *testing.T) { + t.Run("UpdateTargetMetadata", func(t *testing.T) { err := targetStore.Save(ctx, tg) require.Nil(t, err) - _, err = service.SetTargetMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ + _, err = service.UpdateTargetMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ Uptime: 10, }) require.Nil(t, err) }) - t.Run("RemoveTarget", func(t *testing.T) { - apiKeyService.On("Revoke", mock.Anything).Return(nil) + t.Run("DeleteTarget", func(t *testing.T) { + apiKeyService.On("Delete", mock.Anything).Return(nil) - err := service.RemoveTarget(ctx, createTargetDTO.Id) + err := service.DeleteTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) + _, err = service.FindTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Equal(t, services.ErrTargetDeleted, err) }) - t.Run("ForceRemoveTarget", func(t *testing.T) { + t.Run("ForceDeleteTarget", func(t *testing.T) { err := targetStore.Save(ctx, tg) require.Nil(t, err) - apiKeyService.On("Revoke", mock.Anything).Return(nil) + apiKeyService.On("Delete", mock.Anything).Return(nil) - err = service.ForceRemoveTarget(ctx, createTargetDTO.Id) + err = service.ForceDeleteTarget(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.GetTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) + _, err = service.FindTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Equal(t, services.ErrTargetDeleted, err) }) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index e47b4421ac..d9cd8e1623 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -20,14 +20,14 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { defer stores.RecoverAndRollback(ctx, s.targetStore) - currentTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ + currentTarget, err := s.FindTarget(ctx, &stores.TargetFilter{ IdOrName: &id, }, services.TargetRetrievalParams{}) if err != nil || currentTarget == nil { return s.targetStore.RollbackTransaction(ctx, err) } - defaultTarget, err := s.GetTarget(ctx, &stores.TargetFilter{ + defaultTarget, err := s.FindTarget(ctx, &stores.TargetFilter{ Default: util.Pointer(true), }, services.TargetRetrievalParams{}) if err != nil && !stores.IsTargetNotFound(err) { diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 79523bb6c2..ad2ef9d535 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -6,7 +6,6 @@ package workspaces import ( "context" "errors" - "fmt" "regexp" "github.com/daytonaio/daytona/internal/util" @@ -88,7 +87,7 @@ func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.Cre w.User = s.defaultWorkspaceUser } - apiKey, err := s.generateApiKey(ctx, fmt.Sprintf("ws-%s", w.Id)) + apiKey, err := s.createApiKey(ctx, w.Id) if err != nil { return s.handleCreateError(ctx, w, err) } diff --git a/pkg/server/workspaces/remove.go b/pkg/server/workspaces/delete.go similarity index 75% rename from pkg/server/workspaces/remove.go rename to pkg/server/workspaces/delete.go index 37c93abc26..8300cce4ba 100644 --- a/pkg/server/workspaces/remove.go +++ b/pkg/server/workspaces/delete.go @@ -13,72 +13,72 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) RemoveWorkspace(ctx context.Context, workspaceId string) error { +func (s *WorkspaceService) DeleteWorkspace(ctx context.Context, workspaceId string) error { var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { - return s.handleRemoveError(ctx, nil, err) + return s.handleDeleteError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.workspaceStore) w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - return s.handleRemoveError(ctx, w, stores.ErrWorkspaceNotFound) + return s.handleDeleteError(ctx, w, stores.ErrWorkspaceNotFound) } w.Name = util.AddDeletedToName(w.Name) err = s.workspaceStore.Save(ctx, w) if err != nil { - return s.handleRemoveError(ctx, w, err) + return s.handleDeleteError(ctx, w, err) } - err = s.revokeApiKey(ctx, workspaceId) + err = s.deleteApiKey(ctx, workspaceId) if err != nil { - return s.handleRemoveError(ctx, w, err) + return s.handleDeleteError(ctx, w, err) } metadata, err := s.workspaceMetadataStore.Find(ctx, workspaceId) if err == nil { err = s.workspaceMetadataStore.Delete(ctx, metadata) if err != nil { - return s.handleRemoveError(ctx, w, err) + return s.handleDeleteError(ctx, w, err) } } err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionDelete) if err != nil { - return s.handleRemoveError(ctx, w, err) + return s.handleDeleteError(ctx, w, err) } err = s.workspaceStore.CommitTransaction(ctx) - return s.handleRemoveError(ctx, w, err) + return s.handleDeleteError(ctx, w, err) } -// ForceRemoveWorkspace ignores provider errors and makes sure the workspace is removed from storage. -func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId string) error { +// ForceDeleteWorkspace ignores provider errors and makes sure the workspace is removed from storage. +func (s *WorkspaceService) ForceDeleteWorkspace(ctx context.Context, workspaceId string) error { var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { - return s.handleForceRemoveError(ctx, nil, err) + return s.handleForceDeleteError(ctx, nil, err) } defer stores.RecoverAndRollback(ctx, s.workspaceStore) w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { - return s.handleForceRemoveError(ctx, w, stores.ErrWorkspaceNotFound) + return s.handleForceDeleteError(ctx, w, stores.ErrWorkspaceNotFound) } w.Name = util.AddDeletedToName(w.Name) err = s.workspaceStore.Save(ctx, w) if err != nil { - return s.handleForceRemoveError(ctx, w, err) + return s.handleForceDeleteError(ctx, w, err) } - err = s.revokeApiKey(ctx, workspaceId) + err = s.deleteApiKey(ctx, workspaceId) if err != nil { log.Error(err) } @@ -93,14 +93,14 @@ func (s *WorkspaceService) ForceRemoveWorkspace(ctx context.Context, workspaceId err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionForceDelete) if err != nil { - return s.handleForceRemoveError(ctx, w, err) + return s.handleForceDeleteError(ctx, w, err) } err = s.workspaceStore.CommitTransaction(ctx) - return s.handleForceRemoveError(ctx, w, err) + return s.handleForceDeleteError(ctx, w, err) } -func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Workspace, err error) error { +func (s *WorkspaceService) handleDeleteError(ctx context.Context, w *models.Workspace, err error) error { if err != nil { err = s.workspaceStore.RollbackTransaction(ctx, err) } @@ -125,7 +125,7 @@ func (s *WorkspaceService) handleRemoveError(ctx context.Context, w *models.Work return err } -func (s *WorkspaceService) handleForceRemoveError(ctx context.Context, w *models.Workspace, err error) error { +func (s *WorkspaceService) handleForceDeleteError(ctx context.Context, w *models.Workspace, err error) error { if err != nil { err = s.workspaceStore.RollbackTransaction(ctx, err) } diff --git a/pkg/server/workspaces/get.go b/pkg/server/workspaces/find.go similarity index 79% rename from pkg/server/workspaces/get.go rename to pkg/server/workspaces/find.go index c8f6c7f7c0..fe0c6f88b4 100644 --- a/pkg/server/workspaces/get.go +++ b/pkg/server/workspaces/find.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *WorkspaceService) GetWorkspace(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { +func (s *WorkspaceService) FindWorkspace(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceNotFound diff --git a/pkg/server/workspaces/metadata.go b/pkg/server/workspaces/metadata.go index 0ef6c1389b..0ed3d2e98d 100644 --- a/pkg/server/workspaces/metadata.go +++ b/pkg/server/workspaces/metadata.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *WorkspaceService) SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { +func (s *WorkspaceService) UpdateWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { m, err := s.workspaceMetadataStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceMetadataNotFound diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index 8fcfc82c99..dc301d4fbe 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -22,8 +22,8 @@ type WorkspaceServiceConfig struct { FindTarget func(ctx context.Context, targetId string) (*models.Target, error) FindContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry FindCachedBuild func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) - GenerateApiKey func(ctx context.Context, name string) (string, error) - RevokeApiKey func(ctx context.Context, name string) error + CreateApiKey func(ctx context.Context, name string) (string, error) + DeleteApiKey func(ctx context.Context, name string) error ListGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) FindGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) GetLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) @@ -46,8 +46,8 @@ func NewWorkspaceService(config WorkspaceServiceConfig) services.IWorkspaceServi findTarget: config.FindTarget, findContainerRegistry: config.FindContainerRegistry, findCachedBuild: config.FindCachedBuild, - generateApiKey: config.GenerateApiKey, - revokeApiKey: config.RevokeApiKey, + createApiKey: config.CreateApiKey, + deleteApiKey: config.DeleteApiKey, listGitProviderConfigs: config.ListGitProviderConfigs, findGitProviderConfig: config.FindGitProviderConfig, getLastCommitSha: config.GetLastCommitSha, @@ -70,8 +70,8 @@ type WorkspaceService struct { findTarget func(ctx context.Context, targetId string) (*models.Target, error) findContainerRegistry func(ctx context.Context, image string, envVars map[string]string) *models.ContainerRegistry findCachedBuild func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) - generateApiKey func(ctx context.Context, name string) (string, error) - revokeApiKey func(ctx context.Context, name string) error + createApiKey func(ctx context.Context, name string) (string, error) + deleteApiKey func(ctx context.Context, name string) error listGitProviderConfigs func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) findGitProviderConfig func(ctx context.Context, id string) (*models.GitProviderConfig, error) getLastCommitSha func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 5f9ad77954..c3ccddc93d 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -5,7 +5,6 @@ package workspaces_test import ( "context" - "fmt" "testing" "github.com/daytonaio/daytona/internal/testing/job" @@ -134,17 +133,17 @@ func TestWorkspaceService(t *testing.T) { FindCachedBuild: func(ctx context.Context, w *models.Workspace) (*models.CachedBuild, error) { return nil, nil }, - GenerateApiKey: func(ctx context.Context, name string) (string, error) { - return apiKeyService.Generate(models.ApiKeyTypeWorkspace, name) + CreateApiKey: func(ctx context.Context, name string) (string, error) { + return apiKeyService.Create(models.ApiKeyTypeWorkspace, name) }, - RevokeApiKey: func(ctx context.Context, name string) error { - return apiKeyService.Revoke(name) + DeleteApiKey: func(ctx context.Context, name string) error { + return apiKeyService.Delete(name) }, ListGitProviderConfigs: func(ctx context.Context, repoUrl string) ([]*models.GitProviderConfig, error) { return gitProviderService.ListConfigsForUrl(repoUrl) }, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { - return gitProviderService.GetConfig(id) + return gitProviderService.FindConfig(id) }, GetLastCommitSha: func(ctx context.Context, repo *gitprovider.GitRepository) (string, error) { return gitProviderService.GetLastCommitSha(repo) @@ -173,7 +172,7 @@ func TestWorkspaceService(t *testing.T) { t.Run("CreateWorkspace", func(t *testing.T) { gitProviderService.On("GetLastCommitSha", createWorkspaceDTO.Source.Repository).Return("123", nil) - apiKeyService.On("Generate", models.ApiKeyTypeWorkspace, fmt.Sprintf("ws-%s", createWorkspaceDTO.Id)).Return(createWorkspaceDTO.Name, nil) + apiKeyService.On("Create", models.ApiKeyTypeWorkspace, createWorkspaceDTO.Id).Return(createWorkspaceDTO.Name, nil) ws := &models.Workspace{ Id: createWorkspaceDTO.Id, @@ -194,7 +193,7 @@ func TestWorkspaceService(t *testing.T) { ClientId: "test", }) - gitProviderService.On("GetConfig", "github").Return(&gitProviderConfig, nil) + gitProviderService.On("FindConfig", "github").Return(&gitProviderConfig, nil) workspace, err := service.CreateWorkspace(ctx, createWorkspaceDTO) @@ -225,8 +224,8 @@ func TestWorkspaceService(t *testing.T) { require.Equal(t, services.ErrInvalidWorkspaceName, err) }) - t.Run("GetWorkspace", func(t *testing.T) { - w, err := service.GetWorkspace(ctx, ws.Id, services.WorkspaceRetrievalParams{}) + t.Run("FindWorkspace", func(t *testing.T) { + w, err := service.FindWorkspace(ctx, ws.Id, services.WorkspaceRetrievalParams{}) require.Nil(t, err) require.NotNil(t, w) @@ -234,8 +233,8 @@ func TestWorkspaceService(t *testing.T) { workspaceDtoEquals(t, createWorkspaceDTO, *w, defaultWorkspaceImage) }) - t.Run("GetWorkspace fails when workspace not found", func(t *testing.T) { - _, err := service.GetWorkspace(ctx, "invalid-id", services.WorkspaceRetrievalParams{}) + t.Run("FindWorkspace fails when workspace not found", func(t *testing.T) { + _, err := service.FindWorkspace(ctx, "invalid-id", services.WorkspaceRetrievalParams{}) require.NotNil(t, err) require.Equal(t, stores.ErrWorkspaceNotFound, err) }) @@ -261,8 +260,8 @@ func TestWorkspaceService(t *testing.T) { require.Nil(t, err) }) - t.Run("SetWorkspaceMetadata", func(t *testing.T) { - res, err := service.SetWorkspaceMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ + t.Run("UpdateWorkspaceMetadata", func(t *testing.T) { + res, err := service.UpdateWorkspaceMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ Uptime: 10, GitStatus: &models.GitStatus{ CurrentBranch: "main", @@ -274,28 +273,28 @@ func TestWorkspaceService(t *testing.T) { require.Equal(t, "main", res.GitStatus.CurrentBranch) }) - t.Run("RemoveWorkspace", func(t *testing.T) { - apiKeyService.On("Revoke", mock.Anything).Return(nil) + t.Run("DeleteWorkspace", func(t *testing.T) { + apiKeyService.On("Delete", mock.Anything).Return(nil) - err := service.RemoveWorkspace(ctx, createWorkspaceDTO.Id) + err := service.DeleteWorkspace(ctx, createWorkspaceDTO.Id) require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) + _, err = service.FindWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) require.Equal(t, services.ErrWorkspaceDeleted, err) }) - t.Run("ForceRemoveWorkspace", func(t *testing.T) { + t.Run("ForceDeleteWorkspace", func(t *testing.T) { err := workspaceStore.Save(ctx, ws) require.Nil(t, err) - apiKeyService.On("Revoke", mock.Anything).Return(nil) + apiKeyService.On("Delete", mock.Anything).Return(nil) - err = service.ForceRemoveWorkspace(ctx, createWorkspaceDTO.Id) + err = service.ForceDeleteWorkspace(ctx, createWorkspaceDTO.Id) require.Nil(t, err) - _, err = service.GetWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) + _, err = service.FindWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) require.Equal(t, services.ErrWorkspaceDeleted, err) }) diff --git a/pkg/server/workspacetemplates/prebuild_delete.go b/pkg/server/workspacetemplates/prebuild_delete.go index b1df85210c..7ffb9ca081 100644 --- a/pkg/server/workspacetemplates/prebuild_delete.go +++ b/pkg/server/workspacetemplates/prebuild_delete.go @@ -70,7 +70,7 @@ func (s *WorkspaceTemplateService) DeletePrebuild(ctx context.Context, workspace } } - err = workspaceTemplate.RemovePrebuild(id) + err = workspaceTemplate.DeletePrebuild(id) if err != nil { return []error{s.handleDeletePrebuildError(ctx, workspaceTemplate, err)} } diff --git a/pkg/services/api_key.go b/pkg/services/api_key.go index c112e34051..8991e2c728 100644 --- a/pkg/services/api_key.go +++ b/pkg/services/api_key.go @@ -10,12 +10,13 @@ import ( ) type IApiKeyService interface { - Generate(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) - GetApiKeyType(ctx context.Context, apiKey string) (models.ApiKeyType, error) - IsValidApiKey(ctx context.Context, apiKey string) bool ListClientKeys(ctx context.Context) ([]*ApiKeyDTO, error) - Revoke(ctx context.Context, name string) error + Create(ctx context.Context, keyType models.ApiKeyType, name string) (string, error) + Delete(ctx context.Context, name string) error + + GetApiKeyType(ctx context.Context, apiKey string) (models.ApiKeyType, error) GetApiKeyName(ctx context.Context, apiKey string) (string, error) + IsValidApiKey(ctx context.Context, apiKey string) bool } type ApiKeyDTO struct { diff --git a/pkg/services/build.go b/pkg/services/build.go index d92c4cf6a7..5ea7cdf341 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -13,12 +13,12 @@ import ( ) type IBuildService interface { - Create(ctx context.Context, createBuildDTO CreateBuildDTO) (string, error) - Find(ctx context.Context, filter *BuildFilter) (*BuildDTO, error) List(ctx context.Context, filter *BuildFilter) ([]*BuildDTO, error) + Find(ctx context.Context, filter *BuildFilter) (*BuildDTO, error) + Create(ctx context.Context, createBuildDTO CreateBuildDTO) (string, error) Delete(ctx context.Context, filter *BuildFilter, force bool) []error - HandleSuccessfulRemoval(ctx context.Context, id string) error + HandleSuccessfulRemoval(ctx context.Context, id string) error GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) GetBuildLogWriter(ctx context.Context, buildId string) (io.WriteCloser, error) } diff --git a/pkg/services/git_provider.go b/pkg/services/git_provider.go index 5b2648aeb4..af8373f520 100644 --- a/pkg/services/git_provider.go +++ b/pkg/services/git_provider.go @@ -12,8 +12,12 @@ import ( ) type IGitProviderService interface { - GetConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) + ListConfigs(ctx context.Context) ([]*models.GitProviderConfig, error) ListConfigsForUrl(ctx context.Context, url string) ([]*models.GitProviderConfig, error) + FindConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) + SaveGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error + DeleteGitProviderConfig(ctx context.Context, id string) error + GetGitProvider(ctx context.Context, id string) (gitprovider.GitProvider, error) GetGitProviderForUrl(ctx context.Context, url string) (gitprovider.GitProvider, string, error) GetGitProviderForHttpRequest(ctx context.Context, req *http.Request) (gitprovider.GitProvider, error) @@ -22,10 +26,8 @@ type IGitProviderService interface { GetRepoBranches(ctx context.Context, gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitBranch, error) GetRepoPRs(ctx context.Context, gitProviderId string, namespaceId string, repositoryId string, options gitprovider.ListOptions) ([]*gitprovider.GitPullRequest, error) GetRepositories(ctx context.Context, gitProviderId string, namespaceId string, options gitprovider.ListOptions) ([]*gitprovider.GitRepository, error) - ListConfigs(ctx context.Context) ([]*models.GitProviderConfig, error) - RemoveGitProvider(ctx context.Context, gitProviderId string) error - SetGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error GetLastCommitSha(ctx context.Context, repo *gitprovider.GitRepository) (string, error) + RegisterPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (string, error) GetPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, endpointUrl string) (*string, error) UnregisterPrebuildWebhook(ctx context.Context, gitProviderId string, repo *gitprovider.GitRepository, id string) error diff --git a/pkg/services/job.go b/pkg/services/job.go index fe68d4709f..6f3b5e0f44 100644 --- a/pkg/services/job.go +++ b/pkg/services/job.go @@ -12,10 +12,10 @@ import ( ) type IJobService interface { - Create(ctx context.Context, job *models.Job) error - SetState(ctx context.Context, jobId string, updateJobStateDto UpdateJobStateDTO) error - Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) List(ctx context.Context, filter *stores.JobFilter) ([]*models.Job, error) + Find(ctx context.Context, filter *stores.JobFilter) (*models.Job, error) + Create(ctx context.Context, job *models.Job) error + UpdateState(ctx context.Context, jobId string, updateJobStateDto UpdateJobStateDTO) error Delete(ctx context.Context, job *models.Job) error } diff --git a/pkg/services/runner.go b/pkg/services/runner.go index b1e6c53ef5..b2a60bbac8 100644 --- a/pkg/services/runner.go +++ b/pkg/services/runner.go @@ -13,13 +13,13 @@ import ( ) type IRunnerService interface { - RegisterRunner(ctx context.Context, req RegisterRunnerDTO) (*RunnerDTO, error) - GetRunner(ctx context.Context, runnerId string) (*RunnerDTO, error) ListRunners(ctx context.Context) ([]*RunnerDTO, error) ListRunnerJobs(ctx context.Context, runnerId string) ([]*models.Job, error) + FindRunner(ctx context.Context, runnerId string) (*RunnerDTO, error) + CreateRunner(ctx context.Context, req CreateRunnerDTO) (*RunnerDTO, error) UpdateJobState(ctx context.Context, jobId string, req UpdateJobStateDTO) error - SetRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error - RemoveRunner(ctx context.Context, runnerId string) error + UpdateRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error + DeleteRunner(ctx context.Context, runnerId string) error ListProviders(ctx context.Context, runnerId *string) ([]models.ProviderInfo, error) InstallProvider(ctx context.Context, runnerId string, providerDto InstallProviderDTO) error @@ -35,15 +35,15 @@ type RunnerDTO struct { State models.ResourceState `json:"state" validate:"required"` } // @name RunnerDTO -type RegisterRunnerDTO struct { +type CreateRunnerDTO struct { Id string `json:"id" validate:"required"` Name string `json:"name" validate:"required"` -} // @name RegisterRunnerDTO +} // @name CreateRunnerDTO -type RegisterRunnerResultDTO struct { +type CreateRunnerResultDTO struct { models.Runner ApiKey string `json:"apiKey" validate:"required"` -} // @name RegisterRunnerResultDTO +} // @name CreateRunnerResultDTO type UpdateJobStateDTO struct { State models.JobState `json:"state" validate:"required"` diff --git a/pkg/services/target.go b/pkg/services/target.go index c5573bc4dc..834e4fd8c7 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -13,21 +13,21 @@ import ( ) type ITargetService interface { + ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]TargetDTO, error) + FindTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*TargetDTO, error) CreateTarget(ctx context.Context, req CreateTargetDTO) (*models.Target, error) - GetTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*TargetDTO, error) SaveTarget(ctx context.Context, target *models.Target) error - ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]TargetDTO, error) StartTarget(ctx context.Context, targetId string) error StopTarget(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error + UpdateTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) UpdateTargetProviderMetadata(ctx context.Context, targetId, metadata string) error - RemoveTarget(ctx context.Context, targetId string) error - ForceRemoveTarget(ctx context.Context, targetId string) error - HandleSuccessfulCreation(ctx context.Context, targetId string) error + DeleteTarget(ctx context.Context, targetId string) error + ForceDeleteTarget(ctx context.Context, targetId string) error + HandleSuccessfulCreation(ctx context.Context, targetId string) error GetTargetLogReader(ctx context.Context, targetId string) (io.Reader, error) GetTargetLogWriter(ctx context.Context, targetId string) (io.WriteCloser, error) - SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) } type TargetDTO struct { diff --git a/pkg/services/target_config.go b/pkg/services/target_config.go index d5b91d240c..9fc58a375f 100644 --- a/pkg/services/target_config.go +++ b/pkg/services/target_config.go @@ -9,16 +9,16 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -type AddTargetConfigDTO struct { +type CreateTargetConfigDTO struct { Name string `json:"name" validate:"required"` ProviderInfo models.ProviderInfo `json:"providerInfo" validate:"required"` Options string `json:"options" validate:"required"` -} // @name AddTargetConfigDTO +} // @name CreateTargetConfigDTO type ITargetConfigService interface { - Add(ctx context.Context, targetConfig AddTargetConfigDTO) (*models.TargetConfig, error) - Find(ctx context.Context, idOrName string) (*models.TargetConfig, error) List(ctx context.Context) ([]*models.TargetConfig, error) Map(ctx context.Context) (map[string]*models.TargetConfig, error) + Find(ctx context.Context, idOrName string) (*models.TargetConfig, error) + Create(ctx context.Context, targetConfig CreateTargetConfigDTO) (*models.TargetConfig, error) Delete(ctx context.Context, targetConfigId string) error } diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 85963c8f4f..33e3c3651c 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -13,18 +13,18 @@ import ( ) type IWorkspaceService interface { - CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*WorkspaceDTO, error) - GetWorkspace(ctx context.Context, workspaceId string, params WorkspaceRetrievalParams) (*WorkspaceDTO, error) ListWorkspaces(ctx context.Context, params WorkspaceRetrievalParams) ([]WorkspaceDTO, error) + FindWorkspace(ctx context.Context, workspaceId string, params WorkspaceRetrievalParams) (*WorkspaceDTO, error) + CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*WorkspaceDTO, error) + UpdateWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) + UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId, metadata string) error StartWorkspace(ctx context.Context, workspaceId string) error StopWorkspace(ctx context.Context, workspaceId string) error - RemoveWorkspace(ctx context.Context, workspaceId string) error - ForceRemoveWorkspace(ctx context.Context, workspaceId string) error - UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId, metadata string) error + DeleteWorkspace(ctx context.Context, workspaceId string) error + ForceDeleteWorkspace(ctx context.Context, workspaceId string) error GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) GetWorkspaceLogWriter(ctx context.Context, workspaceId string) (io.WriteCloser, error) - SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) } type WorkspaceDTO struct { diff --git a/pkg/services/workspace_template.go b/pkg/services/workspace_template.go index ccd63db841..859f569f22 100644 --- a/pkg/services/workspace_template.go +++ b/pkg/services/workspace_template.go @@ -12,15 +12,15 @@ import ( ) type IWorkspaceTemplateService interface { - Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error - Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) List(ctx context.Context, filter *stores.WorkspaceTemplateFilter) ([]*models.WorkspaceTemplate, error) + Find(ctx context.Context, filter *stores.WorkspaceTemplateFilter) (*models.WorkspaceTemplate, error) + Save(ctx context.Context, workspaceTemplate *models.WorkspaceTemplate) error SetDefault(ctx context.Context, workspaceTemplateName string) error Delete(ctx context.Context, workspaceTemplateName string, force bool) []error - SavePrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) - FindPrebuild(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*PrebuildDTO, error) ListPrebuilds(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) ([]*PrebuildDTO, error) + FindPrebuild(ctx context.Context, workspaceTemplateFilter *stores.WorkspaceTemplateFilter, prebuildFilter *stores.PrebuildFilter) (*PrebuildDTO, error) + SavePrebuild(ctx context.Context, workspaceTemplateName string, createPrebuildDto CreatePrebuildDTO) (*PrebuildDTO, error) DeletePrebuild(ctx context.Context, workspaceTemplateName string, id string, force bool) []error StartRetentionPoller(ctx context.Context) error diff --git a/pkg/stores/build.go b/pkg/stores/build.go index d05b7fdf9c..1b119d7a5e 100644 --- a/pkg/stores/build.go +++ b/pkg/stores/build.go @@ -12,8 +12,8 @@ import ( type BuildStore interface { IStore - Find(ctx context.Context, filter *BuildFilter) (*models.Build, error) List(ctx context.Context, filter *BuildFilter) ([]*models.Build, error) + Find(ctx context.Context, filter *BuildFilter) (*models.Build, error) Save(ctx context.Context, build *models.Build) error Delete(ctx context.Context, id string) error } diff --git a/pkg/views/apikey/notify.go b/pkg/views/apikey/notify.go index 20ac01a437..e36c731316 100644 --- a/pkg/views/apikey/notify.go +++ b/pkg/views/apikey/notify.go @@ -23,7 +23,7 @@ func Render(key, apiUrl string) { views.RenderContainerLayout(views.GetInfoMessage(output)) - command := fmt.Sprintf("daytona profile add -a %s -k %s", apiUrl, key) + command := fmt.Sprintf("daytona profile create -a %s -k %s", apiUrl, key) fmt.Println(lipgloss.NewStyle().Padding(0).Foreground(views.Green).Render(command)) if err := clipboard.WriteAll(command); err == nil { diff --git a/pkg/views/env/delete.go b/pkg/views/env/delete.go index 6bc978e57c..76a6f37671 100644 --- a/pkg/views/env/delete.go +++ b/pkg/views/env/delete.go @@ -11,13 +11,13 @@ import ( "github.com/daytonaio/daytona/pkg/views/env/selection" ) -func RemoveEnvVarsView(ctx context.Context, apiClient apiclient.APIClient) ([]*apiclient.EnvironmentVariable, error) { +func DeleteEnvVarsView(ctx context.Context, apiClient apiclient.APIClient) ([]*apiclient.EnvironmentVariable, error) { envVars, res, err := apiClient.EnvVarAPI.ListEnvironmentVariables(ctx).Execute() if err != nil { return nil, apiclient_util.HandleErrorResponse(res, err) } - selectedEnvVars := selection.GetEnvironmentVariablesFromPrompt(envVars, "Remove") + selectedEnvVars := selection.GetEnvironmentVariablesFromPrompt(envVars, "Delete") return selectedEnvVars, nil } diff --git a/pkg/views/initial/view.go b/pkg/views/initial/view.go index 88b033e914..8c9f723de7 100644 --- a/pkg/views/initial/view.go +++ b/pkg/views/initial/view.go @@ -69,7 +69,7 @@ var commandViews []CommandView = []CommandView{ {Command: "create", Name: "daytona create", Desc: "(create a new workspace)"}, {Command: "code", Name: "daytona code", Desc: "(open a workspace in your preferred IDE)"}, {Command: "git-provider add", Name: "daytona git-provider add", Desc: "(register a Git provider account)"}, - {Command: "target-config set", Name: "daytona target-config set", Desc: "(run workspaces on a remote machine)"}, + {Command: "target-config create", Name: "daytona target-config create", Desc: "(run workspaces on a remote machine)"}, {Command: "docs", Name: "daytona docs", Desc: "(open Daytona docs in default browser)\n"}, {Command: "help", Name: "view all commands", Desc: ""}, } diff --git a/pkg/views/prebuild/add/add.go b/pkg/views/prebuild/create/create.go similarity index 99% rename from pkg/views/prebuild/add/add.go rename to pkg/views/prebuild/create/create.go index 00c1d0d372..daaf0e579d 100644 --- a/pkg/views/prebuild/add/add.go +++ b/pkg/views/prebuild/create/create.go @@ -1,7 +1,7 @@ // Copyright 2024 Daytona Platforms Inc. // SPDX-License-Identifier: Apache-2.0 -package add +package create import ( "errors" diff --git a/pkg/views/profile/create.go b/pkg/views/profile/create.go index 2839f1b461..f56204ab29 100644 --- a/pkg/views/profile/create.go +++ b/pkg/views/profile/create.go @@ -51,7 +51,7 @@ func ProfileCreationView(c *config.Config, profileAddView *ProfileAddView, editi nameInput, huh.NewInput(). Title("Server API URL"). - Description("If you want to connect to a remote Daytona Server, start by running 'daytona api-key new' on the remote machine"). + Description("If you want to connect to a remote Daytona Server, start by running 'daytona api-key create' on the remote machine"). Value(&profileAddView.ApiUrl). Validate(func(str string) error { if str == "" { diff --git a/pkg/views/purge/purge_resources.go b/pkg/views/purge/purge_resources.go index aab59c9444..98d6640200 100644 --- a/pkg/views/purge/purge_resources.go +++ b/pkg/views/purge/purge_resources.go @@ -19,17 +19,17 @@ func PurgeResourcesPrompt(continuePurge *bool, numOfTargets, numOfWorkspaces, nu if numOfBuilds > 0 { resources = append(resources, fmt.Sprintf("builds: %d", numOfBuilds)) - commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona build remove -af")) + commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona build delete -af")) } if numOfWorkspaces > 0 { resources = append(resources, fmt.Sprintf("workspaces: %d", numOfWorkspaces)) - commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona remove -afy")) + commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona delete -afy")) } if numOfTargets > 0 { resources = append(resources, fmt.Sprintf("targets: %d", numOfTargets)) - commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona target remove -afy")) + commands = append(commands, lipgloss.NewStyle().Foreground(views.DimmedGreen).Render("daytona target delete -afy")) } form := huh.NewForm( diff --git a/pkg/views/server/config.go b/pkg/views/server/config.go index 51b23ee4bc..af558a9644 100644 --- a/pkg/views/server/config.go +++ b/pkg/views/server/config.go @@ -78,9 +78,9 @@ func RenderConfig(config *server.Config) { output += "If you want to connect to the server remotely:\n\n" output += "1. Create an API key on this machine: " - output += lipgloss.NewStyle().Foreground(views.Green).Render("daytona api-key new") + "\n" + output += lipgloss.NewStyle().Foreground(views.Green).Render("daytona api-key create") + "\n" output += "2. Add a profile on the client machine: \n\t" - output += lipgloss.NewStyle().Foreground(views.Green).Render(fmt.Sprintf("daytona profile add -a %s -k API_KEY", apiUrl)) + output += lipgloss.NewStyle().Foreground(views.Green).Render(fmt.Sprintf("daytona profile create -a %s -k API_KEY", apiUrl)) views.RenderContainerLayout(views.GetInfoMessage(output)) } diff --git a/pkg/views/server/runner/register.go b/pkg/views/server/runner/create.go similarity index 89% rename from pkg/views/server/runner/register.go rename to pkg/views/server/runner/create.go index 44ef96e615..29a23e6500 100644 --- a/pkg/views/server/runner/register.go +++ b/pkg/views/server/runner/create.go @@ -11,7 +11,7 @@ import ( "github.com/charmbracelet/huh" ) -func RunnerRegistrationView(name *string, existingNames []string) error { +func RunnerCreationView(name *string, existingNames []string) error { return huh.NewForm( huh.NewGroup( huh.NewInput(). diff --git a/pkg/views/server/runner/notify.go b/pkg/views/server/runner/notify.go index cf738cc97f..a8cd4a5dd8 100644 --- a/pkg/views/server/runner/notify.go +++ b/pkg/views/server/runner/notify.go @@ -12,7 +12,7 @@ import ( "github.com/daytonaio/daytona/pkg/views" ) -func Notify(runner *apiclient.RegisterRunnerResultDTO, apiUrl, clientId string, telemetryDisabled bool) { +func Notify(runner *apiclient.CreateRunnerResultDTO, apiUrl, clientId string, telemetryDisabled bool) { var output string output += fmt.Sprintf("You can connect the Runner %s to the Daytona Server by running this command on the Runner's machine:", runner.Name) diff --git a/pkg/views/targetconfig/set.go b/pkg/views/targetconfig/create.go similarity index 98% rename from pkg/views/targetconfig/set.go rename to pkg/views/targetconfig/create.go index e26b2839cc..9a348b61a8 100644 --- a/pkg/views/targetconfig/set.go +++ b/pkg/views/targetconfig/create.go @@ -44,7 +44,7 @@ func NewTargetConfigNameInput(name *string, existingNames []string) error { return nil } -func SetTargetConfigForm(targetConfig *TargetConfigView, targetConfigManifest map[string]apiclient.TargetConfigProperty) error { +func CreateTargetConfigForm(targetConfig *TargetConfigView, targetConfigManifest map[string]apiclient.TargetConfigProperty) error { fields := make([]huh.Field, 0, len(targetConfigManifest)) groups := []*huh.Group{} options := make(map[string]interface{}) diff --git a/pkg/views/targetconfig/select.go b/pkg/views/targetconfig/select.go index ae086a7fc2..576ff0ea07 100644 --- a/pkg/views/targetconfig/select.go +++ b/pkg/views/targetconfig/select.go @@ -69,7 +69,7 @@ func GetTargetConfigFromPrompt(targetConfigs []apiclient.TargetConfig, activePro items = append(items, item{ targetConfig: TargetConfigView{ - Name: fmt.Sprintf("Add a %s Target Config", label), + Name: fmt.Sprintf("Create a %s Target Config", label), Options: "{}", ProviderInfo: ProviderInfo{ Name: providerView.Name, diff --git a/pkg/views/util/empty_list.go b/pkg/views/util/empty_list.go index b9eda9e115..c45f30b1b5 100644 --- a/pkg/views/util/empty_list.go +++ b/pkg/views/util/empty_list.go @@ -15,21 +15,21 @@ func NotifyEmptyProviderList(tip bool) { func NotifyEmptyGitProviderList(tip bool) { views.RenderInfoMessageBold("No Git providers found") if tip { - views.RenderTip("Use 'daytona git-provider add' to add a Git provider") + views.RenderTip("Use 'daytona git-provider create' to add a Git provider") } } func NotifyEmptyTargetConfigList(tip bool) { views.RenderInfoMessageBold("No target configs found") if tip { - views.RenderTip("Use 'daytona target-config set' to add a target config") + views.RenderTip("Use 'daytona target-config create' to create a target config") } } func NotifyEmptyWorkspaceTemplateList(tip bool) { views.RenderInfoMessageBold("No workspace templates found") if tip { - views.RenderTip("Use 'daytona template add' to add a workspace template") + views.RenderTip("Use 'daytona template create' to add a workspace template") } } @@ -47,38 +47,31 @@ func NotifyEmptyWorkspaceList(tip bool) { } } -func NotifyEmptyContainerRegistryList(tip bool) { - views.RenderInfoMessageBold("No container registries found") - if tip { - views.RenderTip("Use 'daytona container-registry add' to add a container registry") - } -} - func NotifyEmptyProfileList(tip bool) { views.RenderInfoMessageBold("No profiles found") if tip { - views.RenderTip("Use 'daytona profile add' to add a profile") + views.RenderTip("Use 'daytona profile create' to add a profile") } } func NotifyEmptyPrebuildList(tip bool) { views.RenderInfoMessageBold("No prebuilds found") if tip { - views.RenderTip("Use 'daytona prebuild add' to add a prebuild") + views.RenderTip("Use 'daytona prebuild create' to add a prebuild") } } func NotifyEmptyApiKeyList(tip bool) { views.RenderInfoMessageBold("No API keys found") if tip { - views.RenderTip("Use 'daytona api-key new' to create an API key") + views.RenderTip("Use 'daytona api-key create' to create an API key") } } func NotifyEmptyBuildList(tip bool) { views.RenderInfoMessageBold("No builds found") if tip { - views.RenderTip("Use 'daytona build run' to run a build or 'daytona prebuild add' to configure a prebuild rule") + views.RenderTip("Use 'daytona build run' to run a build or 'daytona prebuild create' to configure a prebuild rule") } } @@ -99,6 +92,6 @@ func NotifyEmptyServerLogList(tip bool) { func NotifyEmptyRunnerList(tip bool) { views.RenderInfoMessageBold("No runners found") if tip { - views.RenderTip("Use 'daytona runner register' to register a runner") + views.RenderTip("Use 'daytona runner create' to register a runner") } } diff --git a/pkg/views/util/help.go b/pkg/views/util/help.go index 507d24daa0..bee2ef304f 100644 --- a/pkg/views/util/help.go +++ b/pkg/views/util/help.go @@ -38,8 +38,8 @@ func getLongDescriptionText() string { response += "\n" + fmt.Sprintf(" \x1b[1m%s\x1b[0m%s\n\n", "Daytona", " - your Dev Environment Manager") + " Use the following commands to get started:\n\n" + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "1) daytona server", "Start the Daytona Server process locally\n") + - fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "2) daytona git-providers add", "Register a Git provider of your choice\n") + - fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "3) daytona target-config set", "Set a target config to spin up your Dev Environments on\n") + + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "2) daytona git-providers create", "Register a Git provider of your choice\n") + + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "3) daytona target-config create", "Set a target config to spin up your Dev Environments on\n") + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "4) daytona ide", "Choose the default IDE\n") + fmt.Sprintf(" \x1b[1m%-*s\x1b[0m%s", helpDescriptionLabelWidth, "5) daytona whoami", "Show information about the currently logged in user\n") + fmt.Sprintf(" \n%s\x1b[1m%s\x1b[0m\n\n", "That's it! Start coding - ", "daytona create") @@ -57,8 +57,8 @@ func getLongDescriptionFull() string { fmt.Sprintf("%sUse the following commands to get started:\n", " @@@@@@@@@@@@@@@@@@@@ ") + fmt.Sprintf("%s\n", " @@@@ @@ @@@@@@@@@@@ ") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@@@@ @@@ ", helpDescriptionLabelWidthWithSigil, "1) daytona server", "Start the Daytona Server process locally\n") + - fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@ ", helpDescriptionLabelWidthWithSigil, "2) daytona git-providers add", "Register a Git provider of your choice\n") + - fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@@@@ ", helpDescriptionLabelWidthWithSigil, "3) daytona target-config set", "Set a target config to spin up your Dev Environments\n") + + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@ ", helpDescriptionLabelWidthWithSigil, "2) daytona git-providers create", "Register a Git provider of your choice\n") + + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@ @@@@@@@@ ", helpDescriptionLabelWidthWithSigil, "3) daytona target-config create", "Set a target config to spin up your Dev Environments\n") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@ @@@@@@@@@ ", helpDescriptionLabelWidthWithSigil, "4) daytona ide", "Choose the default IDE\n") + fmt.Sprintf("%s\x1b[1m%-*s\x1b[0m%s", " @@@@@@@@@ @@@@@@@@ @@ ", helpDescriptionLabelWidthWithSigil, "5) daytona whoami", "Show information about the currently logged in user\n") + fmt.Sprintf("%s\n", " @@@@@@@@@@@@@@@@@@ ") + From c2667d4be6dc5b9dfcb88ad5b98beb596016ff58 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Tue, 14 Jan 2025 08:10:30 +0000 Subject: [PATCH 47/76] refactor: service method naming consistency Signed-off-by: Toma Puljak --- pkg/api/controllers/containerregistry/find.go | 2 +- .../controllers/gitprovider/gitprovider.go | 4 +-- pkg/api/controllers/runner/create.go | 2 +- pkg/api/controllers/runner/delete.go | 2 +- pkg/api/controllers/runner/find.go | 2 +- pkg/api/controllers/runner/list.go | 2 +- pkg/api/controllers/runner/metadata.go | 2 +- pkg/api/controllers/target/create.go | 2 +- pkg/api/controllers/target/delete.go | 4 +-- pkg/api/controllers/target/metadata.go | 4 +-- pkg/api/controllers/target/start.go | 2 +- pkg/api/controllers/target/stop.go | 2 +- pkg/api/controllers/target/target.go | 4 +-- pkg/api/controllers/workspace/create.go | 2 +- pkg/api/controllers/workspace/delete.go | 4 +-- pkg/api/controllers/workspace/metadata.go | 4 +-- pkg/api/controllers/workspace/start.go | 2 +- pkg/api/controllers/workspace/stop.go | 2 +- .../controllers/workspace/toolbox/toolbox.go | 2 +- pkg/api/controllers/workspace/workspace.go | 4 +-- pkg/cmd/bootstrap/get_local_runner.go | 14 +++++----- pkg/cmd/bootstrap/get_server_instance.go | 6 ++--- pkg/cmd/purge.go | 4 +-- pkg/cmd/server/serve.go | 10 +++---- pkg/server/gitproviders/config.go | 2 +- pkg/server/gitproviders/delete.go | 2 +- pkg/server/runners/create.go | 2 +- pkg/server/runners/delete.go | 2 +- pkg/server/runners/service.go | 6 ++--- pkg/server/targets/create.go | 2 +- pkg/server/targets/delete.go | 6 ++--- pkg/server/targets/find.go | 2 +- pkg/server/targets/list.go | 2 +- pkg/server/targets/metadata.go | 2 +- pkg/server/targets/service.go | 4 +-- pkg/server/targets/service_test.go | 26 +++++++++---------- pkg/server/targets/set-default.go | 4 +-- pkg/server/targets/start.go | 2 +- pkg/server/targets/stop.go | 2 +- pkg/server/workspaces/create.go | 2 +- pkg/server/workspaces/delete.go | 6 ++--- pkg/server/workspaces/find.go | 2 +- pkg/server/workspaces/list.go | 2 +- pkg/server/workspaces/metadata.go | 2 +- pkg/server/workspaces/service.go | 2 +- pkg/server/workspaces/service_test.go | 26 +++++++++---------- pkg/server/workspaces/start.go | 2 +- pkg/server/workspaces/stop.go | 2 +- pkg/services/git_provider.go | 4 +-- pkg/services/runner.go | 13 +++++----- pkg/services/target.go | 21 ++++++++------- pkg/services/workspace.go | 19 +++++++------- 52 files changed, 130 insertions(+), 127 deletions(-) diff --git a/pkg/api/controllers/containerregistry/find.go b/pkg/api/controllers/containerregistry/find.go index 6b4a40109f..2133258bd6 100644 --- a/pkg/api/controllers/containerregistry/find.go +++ b/pkg/api/controllers/containerregistry/find.go @@ -44,7 +44,7 @@ func FindContainerRegistry(ctx *gin.Context) { envVars = serverEnvVars if workspaceId != "" { - w, err := server.WorkspaceService.FindWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + w, err := server.WorkspaceService.Find(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { diff --git a/pkg/api/controllers/gitprovider/gitprovider.go b/pkg/api/controllers/gitprovider/gitprovider.go index 3337f7439e..9b406361e6 100644 --- a/pkg/api/controllers/gitprovider/gitprovider.go +++ b/pkg/api/controllers/gitprovider/gitprovider.go @@ -194,7 +194,7 @@ func SaveGitProvider(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.GitProviderService.SaveGitProviderConfig(ctx.Request.Context(), &gitProviderConfig) + err = server.GitProviderService.SaveConfig(ctx.Request.Context(), &gitProviderConfig) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { @@ -223,7 +223,7 @@ func DeleteGitProvider(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.GitProviderService.DeleteGitProviderConfig(ctx.Request.Context(), gitProviderId) + err := server.GitProviderService.DeleteConfig(ctx.Request.Context(), gitProviderId) if err != nil { statusCode, message, codeErr := controllers.GetHTTPStatusCodeAndMessageFromError(err) if codeErr != nil { diff --git a/pkg/api/controllers/runner/create.go b/pkg/api/controllers/runner/create.go index 0d102565c5..23276c6fe9 100644 --- a/pkg/api/controllers/runner/create.go +++ b/pkg/api/controllers/runner/create.go @@ -33,7 +33,7 @@ func CreateRunner(ctx *gin.Context) { server := server.GetInstance(nil) - r, err := server.RunnerService.CreateRunner(ctx.Request.Context(), createRunnerReq) + r, err := server.RunnerService.Create(ctx.Request.Context(), createRunnerReq) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create runner: %w", err)) return diff --git a/pkg/api/controllers/runner/delete.go b/pkg/api/controllers/runner/delete.go index 0347090247..ee01621aa3 100644 --- a/pkg/api/controllers/runner/delete.go +++ b/pkg/api/controllers/runner/delete.go @@ -26,7 +26,7 @@ func DeleteRunner(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.RunnerService.DeleteRunner(ctx.Request.Context(), runnerId) + err := server.RunnerService.Delete(ctx.Request.Context(), runnerId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to delete runner: %w", err)) return diff --git a/pkg/api/controllers/runner/find.go b/pkg/api/controllers/runner/find.go index 4dbc49c83c..c35d19288c 100644 --- a/pkg/api/controllers/runner/find.go +++ b/pkg/api/controllers/runner/find.go @@ -28,7 +28,7 @@ func FindRunner(ctx *gin.Context) { server := server.GetInstance(nil) - r, err := server.RunnerService.FindRunner(ctx.Request.Context(), runnerId) + r, err := server.RunnerService.Find(ctx.Request.Context(), runnerId) if err != nil { statusCode := http.StatusInternalServerError if stores.IsRunnerNotFound(err) { diff --git a/pkg/api/controllers/runner/list.go b/pkg/api/controllers/runner/list.go index 724258c32e..4424a8523a 100644 --- a/pkg/api/controllers/runner/list.go +++ b/pkg/api/controllers/runner/list.go @@ -24,7 +24,7 @@ import ( func ListRunners(ctx *gin.Context) { server := server.GetInstance(nil) - runners, err := server.RunnerService.ListRunners(ctx.Request.Context()) + runners, err := server.RunnerService.List(ctx.Request.Context()) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to register runner: %w", err)) return diff --git a/pkg/api/controllers/runner/metadata.go b/pkg/api/controllers/runner/metadata.go index 61785965a5..da01b58eb3 100644 --- a/pkg/api/controllers/runner/metadata.go +++ b/pkg/api/controllers/runner/metadata.go @@ -36,7 +36,7 @@ func UpdateRunnerMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.RunnerService.UpdateRunnerMetadata(ctx.Request.Context(), runnerId, &models.RunnerMetadata{ + err = server.RunnerService.UpdateMetadata(ctx.Request.Context(), runnerId, &models.RunnerMetadata{ RunnerId: runnerId, Uptime: runnerMetadata.Uptime, Providers: runnerMetadata.Providers, diff --git a/pkg/api/controllers/target/create.go b/pkg/api/controllers/target/create.go index f85faa82b4..bac18e54e5 100644 --- a/pkg/api/controllers/target/create.go +++ b/pkg/api/controllers/target/create.go @@ -33,7 +33,7 @@ func CreateTarget(ctx *gin.Context) { server := server.GetInstance(nil) - t, err := server.TargetService.CreateTarget(ctx.Request.Context(), createTargetReq) + t, err := server.TargetService.Create(ctx.Request.Context(), createTargetReq) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create target: %w", err)) return diff --git a/pkg/api/controllers/target/delete.go b/pkg/api/controllers/target/delete.go index fb23b66ddc..acc0911e7d 100644 --- a/pkg/api/controllers/target/delete.go +++ b/pkg/api/controllers/target/delete.go @@ -41,9 +41,9 @@ func DeleteTarget(ctx *gin.Context) { server := server.GetInstance(nil) if force { - err = server.TargetService.ForceDeleteTarget(ctx.Request.Context(), targetId) + err = server.TargetService.ForceDelete(ctx.Request.Context(), targetId) } else { - err = server.TargetService.DeleteTarget(ctx.Request.Context(), targetId) + err = server.TargetService.Delete(ctx.Request.Context(), targetId) } if err != nil { diff --git a/pkg/api/controllers/target/metadata.go b/pkg/api/controllers/target/metadata.go index b7e57baceb..f2d00731c2 100644 --- a/pkg/api/controllers/target/metadata.go +++ b/pkg/api/controllers/target/metadata.go @@ -36,7 +36,7 @@ func UpdateTargetMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.TargetService.UpdateTargetMetadata(ctx.Request.Context(), targetId, &models.TargetMetadata{ + _, err = server.TargetService.UpdateMetadata(ctx.Request.Context(), targetId, &models.TargetMetadata{ Uptime: updateDTO.Uptime, }) if err != nil { @@ -70,7 +70,7 @@ func UpdateTargetProviderMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.TargetService.UpdateTargetProviderMetadata(ctx.Request.Context(), targetId, metadata.Metadata) + err = server.TargetService.UpdateProviderMetadata(ctx.Request.Context(), targetId, metadata.Metadata) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update target provider metadata for %s: %w", targetId, err)) return diff --git a/pkg/api/controllers/target/start.go b/pkg/api/controllers/target/start.go index 0104bdcf4e..3046961ba7 100644 --- a/pkg/api/controllers/target/start.go +++ b/pkg/api/controllers/target/start.go @@ -26,7 +26,7 @@ func StartTarget(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.TargetService.StartTarget(ctx.Request.Context(), targetId) + err := server.TargetService.Start(ctx.Request.Context(), targetId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start target %s: %w", targetId, err)) return diff --git a/pkg/api/controllers/target/stop.go b/pkg/api/controllers/target/stop.go index 681aaf511d..68595e9498 100644 --- a/pkg/api/controllers/target/stop.go +++ b/pkg/api/controllers/target/stop.go @@ -26,7 +26,7 @@ func StopTarget(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.TargetService.StopTarget(ctx.Request.Context(), targetId) + err := server.TargetService.Stop(ctx.Request.Context(), targetId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop target %s: %w", targetId, err)) return diff --git a/pkg/api/controllers/target/target.go b/pkg/api/controllers/target/target.go index 13e8d15f66..580331bd64 100644 --- a/pkg/api/controllers/target/target.go +++ b/pkg/api/controllers/target/target.go @@ -37,7 +37,7 @@ func FindTarget(ctx *gin.Context) { server := server.GetInstance(nil) - t, err := server.TargetService.FindTarget(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + t, err := server.TargetService.Find(ctx.Request.Context(), &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsTargetNotFound(err) || services.IsTargetDeleted(err) { @@ -84,7 +84,7 @@ func ListTargets(ctx *gin.Context) { showTargetConfigOptions = true } - targetList, err := server.TargetService.ListTargets(ctx.Request.Context(), nil, services.TargetRetrievalParams{}) + targetList, err := server.TargetService.List(ctx.Request.Context(), nil, services.TargetRetrievalParams{}) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list targets: %w", err)) return diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go index 00fd241576..c95d754bd6 100644 --- a/pkg/api/controllers/workspace/create.go +++ b/pkg/api/controllers/workspace/create.go @@ -33,7 +33,7 @@ func CreateWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.WorkspaceService.CreateWorkspace(ctx.Request.Context(), createWorkspaceReq) + w, err := server.WorkspaceService.Create(ctx.Request.Context(), createWorkspaceReq) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to create workspace: %w", err)) return diff --git a/pkg/api/controllers/workspace/delete.go b/pkg/api/controllers/workspace/delete.go index 5fb1c9960c..0b5feb1cee 100644 --- a/pkg/api/controllers/workspace/delete.go +++ b/pkg/api/controllers/workspace/delete.go @@ -41,9 +41,9 @@ func DeleteWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) if force { - err = server.WorkspaceService.ForceDeleteWorkspace(ctx.Request.Context(), workspaceId) + err = server.WorkspaceService.ForceDelete(ctx.Request.Context(), workspaceId) } else { - err = server.WorkspaceService.DeleteWorkspace(ctx.Request.Context(), workspaceId) + err = server.WorkspaceService.Delete(ctx.Request.Context(), workspaceId) } if err != nil { diff --git a/pkg/api/controllers/workspace/metadata.go b/pkg/api/controllers/workspace/metadata.go index de2cca895b..8f7c5e3d30 100644 --- a/pkg/api/controllers/workspace/metadata.go +++ b/pkg/api/controllers/workspace/metadata.go @@ -36,7 +36,7 @@ func UpdateWorkspaceMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - _, err = server.WorkspaceService.UpdateWorkspaceMetadata(ctx.Request.Context(), workspaceId, &models.WorkspaceMetadata{ + _, err = server.WorkspaceService.UpdateMetadata(ctx.Request.Context(), workspaceId, &models.WorkspaceMetadata{ Uptime: updateDTO.Uptime, GitStatus: updateDTO.GitStatus, }) @@ -71,7 +71,7 @@ func UpdateWorkspaceProviderMetadata(ctx *gin.Context) { server := server.GetInstance(nil) - err = server.WorkspaceService.UpdateWorkspaceProviderMetadata(ctx.Request.Context(), workspaceId, metadata.Metadata) + err = server.WorkspaceService.UpdateProviderMetadata(ctx.Request.Context(), workspaceId, metadata.Metadata) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update workspace provider metadata for %s: %w", workspaceId, err)) return diff --git a/pkg/api/controllers/workspace/start.go b/pkg/api/controllers/workspace/start.go index 164e0ac29f..b6799adfb4 100644 --- a/pkg/api/controllers/workspace/start.go +++ b/pkg/api/controllers/workspace/start.go @@ -26,7 +26,7 @@ func StartWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.WorkspaceService.StartWorkspace(ctx.Request.Context(), workspaceId) + err := server.WorkspaceService.Start(ctx.Request.Context(), workspaceId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to start workspace %s: %w", workspaceId, err)) return diff --git a/pkg/api/controllers/workspace/stop.go b/pkg/api/controllers/workspace/stop.go index 84e43ea9db..c1363a2d56 100644 --- a/pkg/api/controllers/workspace/stop.go +++ b/pkg/api/controllers/workspace/stop.go @@ -26,7 +26,7 @@ func StopWorkspace(ctx *gin.Context) { server := server.GetInstance(nil) - err := server.WorkspaceService.StopWorkspace(ctx.Request.Context(), workspaceId) + err := server.WorkspaceService.Stop(ctx.Request.Context(), workspaceId) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to stop workspace %s: %w", workspaceId, err)) return diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index 321240fe7e..9d347e4a58 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -48,7 +48,7 @@ func forwardRequestToToolbox(ctx *gin.Context) { server := server.GetInstance(nil) - w, err := server.WorkspaceService.FindWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + w, err := server.WorkspaceService.Find(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { if stores.IsWorkspaceNotFound(err) { ctx.AbortWithError(http.StatusNotFound, err) diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go index c9066f2ba3..3d30306993 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/workspace/workspace.go @@ -30,7 +30,7 @@ func FindWorkspace(ctx *gin.Context) { workspaceId := ctx.Param("workspaceId") server := server.GetInstance(nil) - w, err := server.WorkspaceService.FindWorkspace(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) + w, err := server.WorkspaceService.Find(ctx.Request.Context(), workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { statusCode := http.StatusInternalServerError if stores.IsWorkspaceNotFound(err) || services.IsWorkspaceDeleted(err) { @@ -64,7 +64,7 @@ func FindWorkspace(ctx *gin.Context) { func ListWorkspaces(ctx *gin.Context) { server := server.GetInstance(nil) - workspaceList, err := server.WorkspaceService.ListWorkspaces(ctx.Request.Context(), services.WorkspaceRetrievalParams{}) + workspaceList, err := server.WorkspaceService.List(ctx.Request.Context(), services.WorkspaceRetrievalParams{}) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspaces: %w", err)) return diff --git a/pkg/cmd/bootstrap/get_local_runner.go b/pkg/cmd/bootstrap/get_local_runner.go index 7a3c9e272a..7764ffe5f7 100644 --- a/pkg/cmd/bootstrap/get_local_runner.go +++ b/pkg/cmd/bootstrap/get_local_runner.go @@ -129,7 +129,7 @@ func GetLocalRunner(params LocalRunnerParams) (runner.IRunner, error) { return params.TelemetryService.Track(event, clientId) }, SetRunnerMetadata: func(ctx context.Context, runnerId string, metadata models.RunnerMetadata) error { - return runnerService.UpdateRunnerMetadata(context.Background(), runnerId, &models.RunnerMetadata{ + return runnerService.UpdateMetadata(context.Background(), runnerId, &models.RunnerMetadata{ Uptime: uint64(metadata.Uptime), Providers: metadata.Providers, RunningJobs: metadata.RunningJobs, @@ -155,20 +155,20 @@ func getLocalWorkspaceJobFactory(params LocalJobFactoryParams) (workspace.IWorks return workspace.NewWorkspaceJobFactory(workspace.WorkspaceJobFactoryConfig{ FindWorkspace: func(ctx context.Context, workspaceId string) (*models.Workspace, error) { - workspaceDto, err := workspaceService.FindWorkspace(ctx, workspaceId, services.WorkspaceRetrievalParams{}) + workspaceDto, err := workspaceService.Find(ctx, workspaceId, services.WorkspaceRetrievalParams{}) if err != nil { return nil, err } return &workspaceDto.Workspace, nil }, FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, err := targetService.FindTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + targetDto, err := targetService.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { return nil, err } return &targetDto.Target, nil }, - UpdateWorkspaceProviderMetadata: workspaceService.UpdateWorkspaceProviderMetadata, + UpdateWorkspaceProviderMetadata: workspaceService.UpdateProviderMetadata, FindGitProviderConfig: func(ctx context.Context, id string) (*models.GitProviderConfig, error) { return gitProviderService.FindConfig(ctx, id) }, @@ -196,7 +196,7 @@ func getLocalTargetJobFactory(params LocalJobFactoryParams) (target.ITargetJobFa return target.NewTargetJobFactory(target.TargetJobFactoryConfig{ FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - targetDto, err := targetService.FindTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + targetDto, err := targetService.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { return nil, err } @@ -205,7 +205,7 @@ func getLocalTargetJobFactory(params LocalJobFactoryParams) (target.ITargetJobFa HandleSuccessfulCreation: func(ctx context.Context, targetId string) error { return targetService.HandleSuccessfulCreation(ctx, targetId) }, - UpdateTargetProviderMetadata: targetService.UpdateTargetProviderMetadata, + UpdateTargetProviderMetadata: targetService.UpdateProviderMetadata, TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { return params.TelemetryService.Track(event, clientId) }, @@ -361,7 +361,7 @@ func getProviderManager(params LocalRunnerParams, logger *log.Logger) (providerm id := stringid.GenerateRandomID() id = stringid.TruncateID(id) - _, err := targetService.CreateTarget(ctx, services.CreateTargetDTO{ + _, err := targetService.Create(ctx, services.CreateTargetDTO{ TargetConfigId: tc.Id, Name: name, Id: id, diff --git a/pkg/cmd/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go index 4ca2e8aa6b..0cda54a2ac 100644 --- a/pkg/cmd/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -341,7 +341,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe WorkspaceStore: workspaceStore, WorkspaceMetadataStore: workspaceMetadataStore, FindTarget: func(ctx context.Context, targetId string) (*models.Target, error) { - t, err := targetService.FindTarget(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) + t, err := targetService.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}, services.TargetRetrievalParams{}) if err != nil { return nil, err } @@ -445,7 +445,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe }, DeleteApiKey: apiKeyService.Delete, UnsetDefaultTarget: func(ctx context.Context, runnerId string) error { - targets, err := targetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) + targets, err := targetService.List(ctx, nil, services.TargetRetrievalParams{}) if err != nil { return err } @@ -453,7 +453,7 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe for _, t := range targets { if t.TargetConfig.ProviderInfo.RunnerId == runnerId && t.IsDefault { t.IsDefault = false - err = targetService.SaveTarget(ctx, &t.Target) + err = targetService.Save(ctx, &t.Target) if err != nil { return err } diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index f56708e479..38098c7da5 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -113,7 +113,7 @@ var purgeCmd = &cobra.Command{ ctx = context.WithValue(ctx, telemetry.ENABLED_CONTEXT_KEY, c.TelemetryEnabled) // Get all targets, workspaces and builds to prompt user for resource purge - targets, err := server.TargetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) + targets, err := server.TargetService.List(ctx, nil, services.TargetRetrievalParams{}) if err != nil { if !forceFlag { return err @@ -122,7 +122,7 @@ var purgeCmd = &cobra.Command{ } } - workspaces, err := server.WorkspaceService.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{}) + workspaces, err := server.WorkspaceService.List(ctx, services.WorkspaceRetrievalParams{}) if err != nil { if !forceFlag { return err diff --git a/pkg/cmd/server/serve.go b/pkg/cmd/server/serve.go index 65de917178..e101fbfd24 100644 --- a/pkg/cmd/server/serve.go +++ b/pkg/cmd/server/serve.go @@ -248,10 +248,10 @@ func ensureDefaultProfile(server *server.Server, apiPort uint32) error { func startLocalRunner(params bootstrap.LocalRunnerParams) error { runnerService := server.GetInstance(nil).RunnerService - _, err := runnerService.FindRunner(context.Background(), common.LOCAL_RUNNER_ID) + _, err := runnerService.Find(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { if stores.IsRunnerNotFound(err) { - _, err := runnerService.CreateRunner(context.Background(), services.CreateRunnerDTO{ + _, err := runnerService.Create(context.Background(), services.CreateRunnerDTO{ Id: common.LOCAL_RUNNER_ID, Name: common.LOCAL_RUNNER_ID, }) @@ -290,7 +290,7 @@ func awaitLocalRunnerStarted() error { startTime := time.Now() for { - r, err := server.RunnerService.FindRunner(context.Background(), common.LOCAL_RUNNER_ID) + r, err := server.RunnerService.Find(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { return err } @@ -313,12 +313,12 @@ func awaitLocalRunnerStarted() error { func handleDisabledLocalRunner() error { runnerService := server.GetInstance(nil).RunnerService - _, err := runnerService.FindRunner(context.Background(), common.LOCAL_RUNNER_ID) + _, err := runnerService.Find(context.Background(), common.LOCAL_RUNNER_ID) if err != nil { if stores.IsRunnerNotFound(err) { return nil } } - return runnerService.DeleteRunner(context.Background(), common.LOCAL_RUNNER_ID) + return runnerService.Delete(context.Background(), common.LOCAL_RUNNER_ID) } diff --git a/pkg/server/gitproviders/config.go b/pkg/server/gitproviders/config.go index 5ba6025910..0b0d8d9687 100644 --- a/pkg/server/gitproviders/config.go +++ b/pkg/server/gitproviders/config.go @@ -55,7 +55,7 @@ func (s *GitProviderService) ListConfigsForUrl(ctx context.Context, repoUrl stri return gpcs, nil } -func (s *GitProviderService) SaveGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error { +func (s *GitProviderService) SaveConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error { gitProvider, err := s.newGitProvider(providerConfig) if err != nil { return s.handleSetGitProviderConfigError(ctx, providerConfig, err) diff --git a/pkg/server/gitproviders/delete.go b/pkg/server/gitproviders/delete.go index a3505e10da..0706fe9afc 100644 --- a/pkg/server/gitproviders/delete.go +++ b/pkg/server/gitproviders/delete.go @@ -11,7 +11,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *GitProviderService) DeleteGitProviderConfig(ctx context.Context, gitProviderId string) error { +func (s *GitProviderService) DeleteConfig(ctx context.Context, gitProviderId string) error { gitProvider, err := s.configStore.Find(ctx, gitProviderId) if err != nil { return s.handleDeleteGitProviderConfigError(ctx, nil, err) diff --git a/pkg/server/runners/create.go b/pkg/server/runners/create.go index 39c27d25ce..3a44989f97 100644 --- a/pkg/server/runners/create.go +++ b/pkg/server/runners/create.go @@ -14,7 +14,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *RunnerService) CreateRunner(ctx context.Context, req services.CreateRunnerDTO) (*services.RunnerDTO, error) { +func (s *RunnerService) Create(ctx context.Context, req services.CreateRunnerDTO) (*services.RunnerDTO, error) { var err error ctx, err = s.runnerStore.BeginTransaction(ctx) if err != nil { diff --git a/pkg/server/runners/delete.go b/pkg/server/runners/delete.go index df2c6efcae..f752f41e7e 100644 --- a/pkg/server/runners/delete.go +++ b/pkg/server/runners/delete.go @@ -12,7 +12,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *RunnerService) DeleteRunner(ctx context.Context, runnerId string) error { +func (s *RunnerService) Delete(ctx context.Context, runnerId string) error { var err error ctx, err = s.runnerStore.BeginTransaction(ctx) if err != nil { diff --git a/pkg/server/runners/service.go b/pkg/server/runners/service.go index 39f85fbc96..7b8f499d82 100644 --- a/pkg/server/runners/service.go +++ b/pkg/server/runners/service.go @@ -62,7 +62,7 @@ type RunnerService struct { trackTelemetryEvent func(event telemetry.Event, clientId string) error } -func (s *RunnerService) FindRunner(ctx context.Context, runnerId string) (*services.RunnerDTO, error) { +func (s *RunnerService) Find(ctx context.Context, runnerId string) (*services.RunnerDTO, error) { runner, err := s.runnerStore.Find(ctx, runnerId) if err != nil { return nil, stores.ErrRunnerNotFound @@ -74,7 +74,7 @@ func (s *RunnerService) FindRunner(ctx context.Context, runnerId string) (*servi }, nil } -func (s *RunnerService) ListRunners(ctx context.Context) ([]*services.RunnerDTO, error) { +func (s *RunnerService) List(ctx context.Context) ([]*services.RunnerDTO, error) { runners, err := s.runnerStore.List(ctx) if err != nil { return nil, err @@ -88,7 +88,7 @@ func (s *RunnerService) ListRunners(ctx context.Context) ([]*services.RunnerDTO, }), nil } -func (s *RunnerService) UpdateRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error { +func (s *RunnerService) UpdateMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error { m, err := s.runnerMetadataStore.Find(ctx, runnerId) if err != nil { return stores.ErrRunnerMetadataNotFound diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index a2a0fd05a3..f71c26ea63 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -16,7 +16,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *TargetService) CreateTarget(ctx context.Context, req services.CreateTargetDTO) (*models.Target, error) { +func (s *TargetService) Create(ctx context.Context, req services.CreateTargetDTO) (*models.Target, error) { var err error ctx, err = s.targetStore.BeginTransaction(ctx) if err != nil { diff --git a/pkg/server/targets/delete.go b/pkg/server/targets/delete.go index c3382a9463..048d01a16a 100644 --- a/pkg/server/targets/delete.go +++ b/pkg/server/targets/delete.go @@ -13,7 +13,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *TargetService) DeleteTarget(ctx context.Context, targetId string) error { +func (s *TargetService) Delete(ctx context.Context, targetId string) error { var err error ctx, err = s.targetStore.BeginTransaction(ctx) if err != nil { @@ -56,8 +56,8 @@ func (s *TargetService) DeleteTarget(ctx context.Context, targetId string) error return s.handleDeleteError(ctx, t, err) } -// ForceDeleteTarget ignores provider errors and makes sure the target is deleted from storage. -func (s *TargetService) ForceDeleteTarget(ctx context.Context, targetId string) error { +// ForceDelete ignores provider errors and makes sure the target is deleted from storage. +func (s *TargetService) ForceDelete(ctx context.Context, targetId string) error { var err error ctx, err = s.targetStore.BeginTransaction(ctx) if err != nil { diff --git a/pkg/server/targets/find.go b/pkg/server/targets/find.go index 8893e8cb0d..afdc619e01 100644 --- a/pkg/server/targets/find.go +++ b/pkg/server/targets/find.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *TargetService) FindTarget(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { +func (s *TargetService) Find(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) (*services.TargetDTO, error) { tg, err := s.targetStore.Find(ctx, filter) if err != nil { return nil, stores.ErrTargetNotFound diff --git a/pkg/server/targets/list.go b/pkg/server/targets/list.go index a864cd7a35..bc94d88c25 100644 --- a/pkg/server/targets/list.go +++ b/pkg/server/targets/list.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *TargetService) ListTargets(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]services.TargetDTO, error) { +func (s *TargetService) List(ctx context.Context, filter *stores.TargetFilter, params services.TargetRetrievalParams) ([]services.TargetDTO, error) { targets, err := s.targetStore.List(ctx, filter) if err != nil { return nil, err diff --git a/pkg/server/targets/metadata.go b/pkg/server/targets/metadata.go index 9b8df87ccd..b97132b4f3 100644 --- a/pkg/server/targets/metadata.go +++ b/pkg/server/targets/metadata.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *TargetService) UpdateTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { +func (s *TargetService) UpdateMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) { m, err := s.targetMetadataStore.Find(ctx, targetId) if err != nil { return nil, stores.ErrTargetMetadataNotFound diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index 383062c0a3..c56959d263 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -73,11 +73,11 @@ func (s *TargetService) GetTargetLogWriter(ctx context.Context, targetId string) } // TODO: revise - "remove default" is enough for now -func (s *TargetService) SaveTarget(ctx context.Context, target *models.Target) error { +func (s *TargetService) Save(ctx context.Context, target *models.Target) error { return s.targetStore.Save(ctx, target) } -func (s *TargetService) UpdateTargetProviderMetadata(ctx context.Context, targetId, metadata string) error { +func (s *TargetService) UpdateProviderMetadata(ctx context.Context, targetId, metadata string) error { tg, err := s.targetStore.Find(ctx, &stores.TargetFilter{ IdOrName: &targetId, }) diff --git a/pkg/server/targets/service_test.go b/pkg/server/targets/service_test.go index bb2c45f107..ca7fe219ba 100644 --- a/pkg/server/targets/service_test.go +++ b/pkg/server/targets/service_test.go @@ -106,7 +106,7 @@ func TestTargetService(t *testing.T) { t.Run("CreateTarget", func(t *testing.T) { apiKeyService.On("Create", models.ApiKeyTypeTarget, createTargetDTO.Id).Return(createTargetDTO.Id, nil) - target, err := service.CreateTarget(ctx, createTargetDTO) + target, err := service.Create(ctx, createTargetDTO) require.Nil(t, err) require.NotNil(t, target) @@ -118,13 +118,13 @@ func TestTargetService(t *testing.T) { }) t.Run("CreateTarget fails when target already exists", func(t *testing.T) { - _, err := service.CreateTarget(ctx, createTargetDTO) + _, err := service.Create(ctx, createTargetDTO) require.NotNil(t, err) require.Equal(t, services.ErrTargetAlreadyExists, err) }) t.Run("FindTarget", func(t *testing.T) { - target, err := service.FindTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) + target, err := service.Find(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Nil(t, err) require.NotNil(t, target) @@ -133,13 +133,13 @@ func TestTargetService(t *testing.T) { }) t.Run("FindTarget fails when target not found", func(t *testing.T) { - _, err := service.FindTarget(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{}) + _, err := service.Find(ctx, &stores.TargetFilter{IdOrName: util.Pointer("invalid-id")}, services.TargetRetrievalParams{}) require.NotNil(t, err) require.Equal(t, stores.ErrTargetNotFound, err) }) t.Run("ListTargets", func(t *testing.T) { - targets, err := service.ListTargets(ctx, nil, services.TargetRetrievalParams{}) + targets, err := service.List(ctx, nil, services.TargetRetrievalParams{}) require.Nil(t, err) require.Len(t, targets, 1) @@ -156,7 +156,7 @@ func TestTargetService(t *testing.T) { ClientId: "test-client-id", }) - err := service.StartTarget(ctx, createTargetDTO.Id) + err := service.Start(ctx, createTargetDTO.Id) require.Nil(t, err) @@ -164,7 +164,7 @@ func TestTargetService(t *testing.T) { }) t.Run("StopTarget", func(t *testing.T) { - err := service.StopTarget(ctx, createTargetDTO.Id) + err := service.Stop(ctx, createTargetDTO.Id) require.Nil(t, err) }) @@ -173,7 +173,7 @@ func TestTargetService(t *testing.T) { err := targetStore.Save(ctx, tg) require.Nil(t, err) - _, err = service.UpdateTargetMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ + _, err = service.UpdateMetadata(context.TODO(), tg.Id, &models.TargetMetadata{ Uptime: 10, }) require.Nil(t, err) @@ -182,11 +182,11 @@ func TestTargetService(t *testing.T) { t.Run("DeleteTarget", func(t *testing.T) { apiKeyService.On("Delete", mock.Anything).Return(nil) - err := service.DeleteTarget(ctx, createTargetDTO.Id) + err := service.Delete(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.FindTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) + _, err = service.Find(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Equal(t, services.ErrTargetDeleted, err) }) @@ -196,11 +196,11 @@ func TestTargetService(t *testing.T) { apiKeyService.On("Delete", mock.Anything).Return(nil) - err = service.ForceDeleteTarget(ctx, createTargetDTO.Id) + err = service.ForceDelete(ctx, createTargetDTO.Id) require.Nil(t, err) - _, err = service.FindTarget(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) + _, err = service.Find(ctx, &stores.TargetFilter{IdOrName: &createTargetDTO.Id}, services.TargetRetrievalParams{}) require.Equal(t, services.ErrTargetDeleted, err) }) @@ -209,7 +209,7 @@ func TestTargetService(t *testing.T) { invalidTargetRequest.Id = "some-id" invalidTargetRequest.Name = "invalid name" - _, err := service.CreateTarget(ctx, invalidTargetRequest) + _, err := service.Create(ctx, invalidTargetRequest) require.NotNil(t, err) require.Equal(t, services.ErrInvalidTargetName, err) }) diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index d9cd8e1623..dbdd7083ac 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -20,14 +20,14 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { defer stores.RecoverAndRollback(ctx, s.targetStore) - currentTarget, err := s.FindTarget(ctx, &stores.TargetFilter{ + currentTarget, err := s.Find(ctx, &stores.TargetFilter{ IdOrName: &id, }, services.TargetRetrievalParams{}) if err != nil || currentTarget == nil { return s.targetStore.RollbackTransaction(ctx, err) } - defaultTarget, err := s.FindTarget(ctx, &stores.TargetFilter{ + defaultTarget, err := s.Find(ctx, &stores.TargetFilter{ Default: util.Pointer(true), }, services.TargetRetrievalParams{}) if err != nil && !stores.IsTargetNotFound(err) { diff --git a/pkg/server/targets/start.go b/pkg/server/targets/start.go index 80dedee2f9..c946f55f40 100644 --- a/pkg/server/targets/start.go +++ b/pkg/server/targets/start.go @@ -13,7 +13,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *TargetService) StartTarget(ctx context.Context, targetId string) error { +func (s *TargetService) Start(ctx context.Context, targetId string) error { target, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStartError(ctx, nil, stores.ErrTargetNotFound) diff --git a/pkg/server/targets/stop.go b/pkg/server/targets/stop.go index cc1e753708..1a5c55b89b 100644 --- a/pkg/server/targets/stop.go +++ b/pkg/server/targets/stop.go @@ -13,7 +13,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *TargetService) StopTarget(ctx context.Context, targetId string) error { +func (s *TargetService) Stop(ctx context.Context, targetId string) error { target, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) if err != nil { return s.handleStopError(ctx, nil, stores.ErrTargetNotFound) diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index ad2ef9d535..3fde685ddb 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -17,7 +17,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) CreateWorkspace(ctx context.Context, req services.CreateWorkspaceDTO) (*services.WorkspaceDTO, error) { +func (s *WorkspaceService) Create(ctx context.Context, req services.CreateWorkspaceDTO) (*services.WorkspaceDTO, error) { var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { diff --git a/pkg/server/workspaces/delete.go b/pkg/server/workspaces/delete.go index 8300cce4ba..127613be95 100644 --- a/pkg/server/workspaces/delete.go +++ b/pkg/server/workspaces/delete.go @@ -13,7 +13,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) DeleteWorkspace(ctx context.Context, workspaceId string) error { +func (s *WorkspaceService) Delete(ctx context.Context, workspaceId string) error { var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { @@ -56,8 +56,8 @@ func (s *WorkspaceService) DeleteWorkspace(ctx context.Context, workspaceId stri return s.handleDeleteError(ctx, w, err) } -// ForceDeleteWorkspace ignores provider errors and makes sure the workspace is removed from storage. -func (s *WorkspaceService) ForceDeleteWorkspace(ctx context.Context, workspaceId string) error { +// ForceDelete ignores provider errors and makes sure the workspace is removed from storage. +func (s *WorkspaceService) ForceDelete(ctx context.Context, workspaceId string) error { var err error ctx, err = s.workspaceStore.BeginTransaction(ctx) if err != nil { diff --git a/pkg/server/workspaces/find.go b/pkg/server/workspaces/find.go index fe0c6f88b4..da6af57fa7 100644 --- a/pkg/server/workspaces/find.go +++ b/pkg/server/workspaces/find.go @@ -11,7 +11,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *WorkspaceService) FindWorkspace(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { +func (s *WorkspaceService) Find(ctx context.Context, workspaceId string, params services.WorkspaceRetrievalParams) (*services.WorkspaceDTO, error) { w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceNotFound diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index b7de45577e..bfab5792ae 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/services" ) -func (s *WorkspaceService) ListWorkspaces(ctx context.Context, params services.WorkspaceRetrievalParams) ([]services.WorkspaceDTO, error) { +func (s *WorkspaceService) List(ctx context.Context, params services.WorkspaceRetrievalParams) ([]services.WorkspaceDTO, error) { workspaces, err := s.workspaceStore.List(ctx) if err != nil { return nil, err diff --git a/pkg/server/workspaces/metadata.go b/pkg/server/workspaces/metadata.go index 0ed3d2e98d..55203202fa 100644 --- a/pkg/server/workspaces/metadata.go +++ b/pkg/server/workspaces/metadata.go @@ -10,7 +10,7 @@ import ( "github.com/daytonaio/daytona/pkg/stores" ) -func (s *WorkspaceService) UpdateWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { +func (s *WorkspaceService) UpdateMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) { m, err := s.workspaceMetadataStore.Find(ctx, workspaceId) if err != nil { return nil, stores.ErrWorkspaceMetadataNotFound diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index dc301d4fbe..b2a444e3be 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -94,7 +94,7 @@ func (s *WorkspaceService) GetWorkspaceLogWriter(ctx context.Context, workspaceI return s.loggerFactory.CreateLogWriter(workspaceId) } -func (s *WorkspaceService) UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId, metadata string) error { +func (s *WorkspaceService) UpdateProviderMetadata(ctx context.Context, workspaceId, metadata string) error { w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return err diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index c3ccddc93d..6519477cbe 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -195,7 +195,7 @@ func TestWorkspaceService(t *testing.T) { gitProviderService.On("FindConfig", "github").Return(&gitProviderConfig, nil) - workspace, err := service.CreateWorkspace(ctx, createWorkspaceDTO) + workspace, err := service.Create(ctx, createWorkspaceDTO) require.Nil(t, err) require.NotNil(t, workspace) @@ -210,7 +210,7 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("CreateWorkspace fails when workspace already exists", func(t *testing.T) { - _, err := service.CreateWorkspace(ctx, createWorkspaceDTO) + _, err := service.Create(ctx, createWorkspaceDTO) require.NotNil(t, err) require.Equal(t, services.ErrWorkspaceAlreadyExists, err) }) @@ -219,13 +219,13 @@ func TestWorkspaceService(t *testing.T) { invalidWorkspaceRequest := createWorkspaceDTO invalidWorkspaceRequest.Name = "invalid name" - _, err := service.CreateWorkspace(ctx, invalidWorkspaceRequest) + _, err := service.Create(ctx, invalidWorkspaceRequest) require.NotNil(t, err) require.Equal(t, services.ErrInvalidWorkspaceName, err) }) t.Run("FindWorkspace", func(t *testing.T) { - w, err := service.FindWorkspace(ctx, ws.Id, services.WorkspaceRetrievalParams{}) + w, err := service.Find(ctx, ws.Id, services.WorkspaceRetrievalParams{}) require.Nil(t, err) require.NotNil(t, w) @@ -234,13 +234,13 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("FindWorkspace fails when workspace not found", func(t *testing.T) { - _, err := service.FindWorkspace(ctx, "invalid-id", services.WorkspaceRetrievalParams{}) + _, err := service.Find(ctx, "invalid-id", services.WorkspaceRetrievalParams{}) require.NotNil(t, err) require.Equal(t, stores.ErrWorkspaceNotFound, err) }) t.Run("ListWorkspaces", func(t *testing.T) { - workspaces, err := service.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{}) + workspaces, err := service.List(ctx, services.WorkspaceRetrievalParams{}) require.Nil(t, err) require.Len(t, workspaces, 1) @@ -249,19 +249,19 @@ func TestWorkspaceService(t *testing.T) { }) t.Run("StartWorkspace", func(t *testing.T) { - err := service.StartWorkspace(ctx, createWorkspaceDTO.Id) + err := service.Start(ctx, createWorkspaceDTO.Id) require.Nil(t, err) }) t.Run("StopWorkspace", func(t *testing.T) { - err := service.StopWorkspace(ctx, createWorkspaceDTO.Id) + err := service.Stop(ctx, createWorkspaceDTO.Id) require.Nil(t, err) }) t.Run("UpdateWorkspaceMetadata", func(t *testing.T) { - res, err := service.UpdateWorkspaceMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ + res, err := service.UpdateMetadata(ctx, createWorkspaceDTO.Id, &models.WorkspaceMetadata{ Uptime: 10, GitStatus: &models.GitStatus{ CurrentBranch: "main", @@ -276,11 +276,11 @@ func TestWorkspaceService(t *testing.T) { t.Run("DeleteWorkspace", func(t *testing.T) { apiKeyService.On("Delete", mock.Anything).Return(nil) - err := service.DeleteWorkspace(ctx, createWorkspaceDTO.Id) + err := service.Delete(ctx, createWorkspaceDTO.Id) require.Nil(t, err) - _, err = service.FindWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) + _, err = service.Find(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) require.Equal(t, services.ErrWorkspaceDeleted, err) }) @@ -290,11 +290,11 @@ func TestWorkspaceService(t *testing.T) { apiKeyService.On("Delete", mock.Anything).Return(nil) - err = service.ForceDeleteWorkspace(ctx, createWorkspaceDTO.Id) + err = service.ForceDelete(ctx, createWorkspaceDTO.Id) require.Nil(t, err) - _, err = service.FindWorkspace(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) + _, err = service.Find(ctx, createWorkspaceDTO.Id, services.WorkspaceRetrievalParams{}) require.Equal(t, services.ErrWorkspaceDeleted, err) }) diff --git a/pkg/server/workspaces/start.go b/pkg/server/workspaces/start.go index d0a158047d..ddc4da4733 100644 --- a/pkg/server/workspaces/start.go +++ b/pkg/server/workspaces/start.go @@ -12,7 +12,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) StartWorkspace(ctx context.Context, workspaceId string) error { +func (s *WorkspaceService) Start(ctx context.Context, workspaceId string) error { w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleStartError(ctx, w, stores.ErrWorkspaceNotFound) diff --git a/pkg/server/workspaces/stop.go b/pkg/server/workspaces/stop.go index 2c41f15e53..dca0b6f969 100644 --- a/pkg/server/workspaces/stop.go +++ b/pkg/server/workspaces/stop.go @@ -12,7 +12,7 @@ import ( log "github.com/sirupsen/logrus" ) -func (s *WorkspaceService) StopWorkspace(ctx context.Context, workspaceId string) error { +func (s *WorkspaceService) Stop(ctx context.Context, workspaceId string) error { w, err := s.workspaceStore.Find(ctx, workspaceId) if err != nil { return s.handleStopError(ctx, w, stores.ErrWorkspaceNotFound) diff --git a/pkg/services/git_provider.go b/pkg/services/git_provider.go index af8373f520..7f04e86bd0 100644 --- a/pkg/services/git_provider.go +++ b/pkg/services/git_provider.go @@ -15,8 +15,8 @@ type IGitProviderService interface { ListConfigs(ctx context.Context) ([]*models.GitProviderConfig, error) ListConfigsForUrl(ctx context.Context, url string) ([]*models.GitProviderConfig, error) FindConfig(ctx context.Context, id string) (*models.GitProviderConfig, error) - SaveGitProviderConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error - DeleteGitProviderConfig(ctx context.Context, id string) error + SaveConfig(ctx context.Context, providerConfig *models.GitProviderConfig) error + DeleteConfig(ctx context.Context, id string) error GetGitProvider(ctx context.Context, id string) (gitprovider.GitProvider, error) GetGitProviderForUrl(ctx context.Context, url string) (gitprovider.GitProvider, string, error) diff --git a/pkg/services/runner.go b/pkg/services/runner.go index b2a60bbac8..b294bfac85 100644 --- a/pkg/services/runner.go +++ b/pkg/services/runner.go @@ -13,13 +13,14 @@ import ( ) type IRunnerService interface { - ListRunners(ctx context.Context) ([]*RunnerDTO, error) - ListRunnerJobs(ctx context.Context, runnerId string) ([]*models.Job, error) - FindRunner(ctx context.Context, runnerId string) (*RunnerDTO, error) - CreateRunner(ctx context.Context, req CreateRunnerDTO) (*RunnerDTO, error) + List(ctx context.Context) ([]*RunnerDTO, error) + Find(ctx context.Context, runnerId string) (*RunnerDTO, error) + Create(ctx context.Context, req CreateRunnerDTO) (*RunnerDTO, error) + Delete(ctx context.Context, runnerId string) error + + UpdateMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error UpdateJobState(ctx context.Context, jobId string, req UpdateJobStateDTO) error - UpdateRunnerMetadata(ctx context.Context, runnerId string, metadata *models.RunnerMetadata) error - DeleteRunner(ctx context.Context, runnerId string) error + ListRunnerJobs(ctx context.Context, runnerId string) ([]*models.Job, error) ListProviders(ctx context.Context, runnerId *string) ([]models.ProviderInfo, error) InstallProvider(ctx context.Context, runnerId string, providerDto InstallProviderDTO) error diff --git a/pkg/services/target.go b/pkg/services/target.go index 834e4fd8c7..233e09cc7a 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -13,17 +13,18 @@ import ( ) type ITargetService interface { - ListTargets(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]TargetDTO, error) - FindTarget(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*TargetDTO, error) - CreateTarget(ctx context.Context, req CreateTargetDTO) (*models.Target, error) - SaveTarget(ctx context.Context, target *models.Target) error - StartTarget(ctx context.Context, targetId string) error - StopTarget(ctx context.Context, targetId string) error + List(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) ([]TargetDTO, error) + Find(ctx context.Context, filter *stores.TargetFilter, params TargetRetrievalParams) (*TargetDTO, error) + Create(ctx context.Context, req CreateTargetDTO) (*models.Target, error) + Save(ctx context.Context, target *models.Target) error + Start(ctx context.Context, targetId string) error + Stop(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error - UpdateTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) - UpdateTargetProviderMetadata(ctx context.Context, targetId, metadata string) error - DeleteTarget(ctx context.Context, targetId string) error - ForceDeleteTarget(ctx context.Context, targetId string) error + Delete(ctx context.Context, targetId string) error + ForceDelete(ctx context.Context, targetId string) error + + UpdateMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) + UpdateProviderMetadata(ctx context.Context, targetId, metadata string) error HandleSuccessfulCreation(ctx context.Context, targetId string) error GetTargetLogReader(ctx context.Context, targetId string) (io.Reader, error) diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 33e3c3651c..3497ebf5e9 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -13,15 +13,16 @@ import ( ) type IWorkspaceService interface { - ListWorkspaces(ctx context.Context, params WorkspaceRetrievalParams) ([]WorkspaceDTO, error) - FindWorkspace(ctx context.Context, workspaceId string, params WorkspaceRetrievalParams) (*WorkspaceDTO, error) - CreateWorkspace(ctx context.Context, req CreateWorkspaceDTO) (*WorkspaceDTO, error) - UpdateWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) - UpdateWorkspaceProviderMetadata(ctx context.Context, workspaceId, metadata string) error - StartWorkspace(ctx context.Context, workspaceId string) error - StopWorkspace(ctx context.Context, workspaceId string) error - DeleteWorkspace(ctx context.Context, workspaceId string) error - ForceDeleteWorkspace(ctx context.Context, workspaceId string) error + List(ctx context.Context, params WorkspaceRetrievalParams) ([]WorkspaceDTO, error) + Find(ctx context.Context, workspaceId string, params WorkspaceRetrievalParams) (*WorkspaceDTO, error) + Create(ctx context.Context, req CreateWorkspaceDTO) (*WorkspaceDTO, error) + Start(ctx context.Context, workspaceId string) error + Stop(ctx context.Context, workspaceId string) error + Delete(ctx context.Context, workspaceId string) error + ForceDelete(ctx context.Context, workspaceId string) error + + UpdateMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) + UpdateProviderMetadata(ctx context.Context, workspaceId, metadata string) error GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) GetWorkspaceLogWriter(ctx context.Context, workspaceId string) (io.WriteCloser, error) From 6a66e8aede5f483b25e879697775526d930e172d Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Tue, 14 Jan 2025 08:37:05 +0000 Subject: [PATCH 48/76] docs: add conventions to contributing guide Signed-off-by: Toma Puljak --- CONTRIBUTING.md | 53 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4abbd97e74..64ddae180e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,7 @@ The team at Daytona welcomes contributions from the community. There are many wa Thanks for taking the time to contribute! ❤️ > And if you like the project but don't have time to contribute, that's perfectly okay. There are other simple ways to support the project and show your appreciation, which we would greatly appreciate: +> > - Star the project > - Tweet about it > - Contribute to our [Docs](https://github.com/daytonaio/docs/) @@ -22,29 +23,31 @@ to [info@daytona.io](mailto:info@daytona.io). You might find things that can be improved while you are using Daytona. You can help by [submitting an issue](https://github.com/daytonaio/daytona/issues/new) when: -* A new feature or an enhancement to an existing feature will improve the utility or usability of Daytona. -* Daytona crashes, or you encounter a bug that can only be resolved by restarting Daytona. -* An error occurs that is unrecoverable, causes workspace integrity problems or loss, or generally prevents you from using a workspace. +- A new feature or an enhancement to an existing feature will improve the utility or usability of Daytona. +- Daytona crashes, or you encounter a bug that can only be resolved by restarting Daytona. +- An error occurs that is unrecoverable, causes workspace integrity problems or loss, or generally prevents you from using a workspace. Before creating a new issue, please confirm that an existing issue doesn't already exist. We will then take care of the issue as soon as possible. ## Participate in the Community + You can engage with our community by: -* Helping other users on [Daytona Community Slack](https://go.daytona.io/slack). -* Improving [documentation](https://github.com/daytonaio/docs/) -* Participating in general discussions about development and DevOps -* Authoring new Daytona Plugins and sharing those Plugins -* Authoring new dev containers and sharing examples +- Helping other users on [Daytona Community Slack](https://go.daytona.io/slack). +- Improving [documentation](https://github.com/daytonaio/docs/) +- Participating in general discussions about development and DevOps +- Authoring new Daytona Plugins and sharing those Plugins +- Authoring new dev containers and sharing examples ## Contributing Code + You can contribute to Daytona by: -* Enhancing current functionality -* Fixing bugs -* Adding new features and capabilities +- Enhancing current functionality +- Fixing bugs +- Adding new features and capabilities Before starting your contribution, especially for core features, we encourage you to reach out to us on [Slack](https://go.daytona.io/slack). This allows us to ensure that your proposed feature aligns with the project's roadmap and goals. Developers are the key to making Daytona the best tool it can be, and we value input from the community. @@ -72,11 +75,35 @@ Follow the following steps to ensure your contribution goes smoothly. Note: In some cases, we might decide that a PR should be closed without merging. We'll make sure to provide clear reasoning when this happens. +### Coding Style and Conventions + +To make the code base consistent, we follow a few guidelines and conventions listed below. + +It is possible that the code base does not currently comply with all these guidelines. +While working on a PR, if you see something that can be refactored to comply, go ahead, but keep in mind that we are not looking for massive PRs that only address that. + +API and service method conventions: + +1. Avoid using model names in service methods + - e.g. `Create` instead of `CreateTarget`, `Find` instead of `FindWorkspace` +1. Use model names in service methods for "sub-models" + - e.g. `ListPrebuilds` in `WorkspaceTemplateService` +1. Use appropriate verbs in the UI + - e.g. `Create API Key` instead of `Generate API Key` since the method is called `Create` +1. Refer to the table below for a connection between API and service methods + +| HTTP Method | Controller / Service / Store | +| ----------- | ---------------------------- | +| POST | Create or Update | +| DELETE | Delete | +| PUT | Save | +| GET | Find or List | + #### What Does Contributing Mean for You? Here is what being a contributor means for you: -* License all our contributions to the project under the Apache License, Version 2.0 -* Have the legal rights to license our contributions ourselves, or get permission to license them from our employers, clients, or others who may have them +- License all our contributions to the project under the Apache License, Version 2.0 +- Have the legal rights to license our contributions ourselves, or get permission to license them from our employers, clients, or others who may have them For more information, see the [README](README.md) and feel free to reach out to us on [Slack](https://go.daytona.io/slack). From e0f3d3452c31e271d6391463aa370c8a0a5713f1 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 23 Dec 2024 13:54:45 +0000 Subject: [PATCH 49/76] fix: gorm foreign key relations Signed-off-by: Toma Puljak --- pkg/models/build.go | 4 ++-- pkg/models/runner.go | 2 +- pkg/models/target.go | 6 +++--- pkg/models/workspace.go | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/models/build.go b/pkg/models/build.go index dbce8c20bb..d67af7e284 100644 --- a/pkg/models/build.go +++ b/pkg/models/build.go @@ -19,8 +19,8 @@ type Build struct { BuildConfig *BuildConfig `json:"buildConfig" validate:"optional" gorm:"serializer:json"` Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json;not null"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` - PrebuildId *string `json:"prebuildId" validate:"optional"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:Id;references:ResourceId"` + PrebuildId *string `json:"prebuildId" validate:"required" gorm:"not null"` CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` } // @name Build diff --git a/pkg/models/runner.go b/pkg/models/runner.go index b0853f8e55..cb605327bb 100644 --- a/pkg/models/runner.go +++ b/pkg/models/runner.go @@ -13,7 +13,7 @@ type Runner struct { Id string `json:"id" validate:"required" gorm:"primaryKey"` Name string `json:"name" validate:"required" gorm:"uniqueIndex;not null"` ApiKey string `json:"-" validate:"required" gorm:"not null"` - Metadata *RunnerMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:RunnerId;references:Id"` + Metadata *RunnerMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:Id;references:RunnerId"` } // @name Runner func (r *Runner) GetState() ResourceState { diff --git a/pkg/models/target.go b/pkg/models/target.go index 97c7ed9d7e..e2b9388ec9 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -19,9 +19,9 @@ type Target struct { ApiKey string `json:"-" validate:"required" gorm:"not null"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` IsDefault bool `json:"default" validate:"required" gorm:"not null"` - Workspaces []Workspace `json:"workspaces" validate:"required" gorm:"foreignKey:TargetId;references:Id"` - Metadata *TargetMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:TargetId;references:Id"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` + Workspaces []Workspace `json:"workspaces" validate:"required"` + Metadata *TargetMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:Id;references:TargetId"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:Id;references:ResourceId"` ProviderMetadata *string `json:"providerMetadata,omitempty" validate:"optional"` } // @name Target diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index c10dfa2337..5e9935cd80 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -21,9 +21,9 @@ type Workspace struct { TargetId string `json:"targetId" validate:"required" gorm:"not null"` Target Target `json:"target" validate:"required" gorm:"foreignKey:TargetId"` ApiKey string `json:"apiKey" validate:"required" gorm:"not null"` - Metadata *WorkspaceMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:WorkspaceId;references:Id"` + Metadata *WorkspaceMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:Id;references:WorkspaceId"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:ResourceId;references:Id"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:Id;references:ResourceId"` ProviderMetadata *string `json:"providerMetadata,omitempty" validate:"optional"` } // @name Workspace From 31ec48f860434f5e70ed9e2382265bca88d88198 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 23 Dec 2024 14:15:34 +0000 Subject: [PATCH 50/76] fix: last job ID foreign key - instead of querying the last job, it is now stored in the model itself Signed-off-by: Toma Puljak --- pkg/api/docs/docs.go | 15 +++++++ pkg/api/docs/swagger.json | 15 +++++++ pkg/api/docs/swagger.yaml | 10 +++++ pkg/apiclient/api/openapi.yaml | 55 ++++++++++++++++-------- pkg/apiclient/docs/BuildDTO.md | 26 +++++++++++ pkg/apiclient/docs/Target.md | 26 +++++++++++ pkg/apiclient/docs/TargetDTO.md | 26 +++++++++++ pkg/apiclient/docs/Workspace.md | 26 +++++++++++ pkg/apiclient/docs/WorkspaceDTO.md | 26 +++++++++++ pkg/apiclient/model_build_dto.go | 36 ++++++++++++++++ pkg/apiclient/model_target.go | 36 ++++++++++++++++ pkg/apiclient/model_target_dto.go | 36 ++++++++++++++++ pkg/apiclient/model_workspace.go | 36 ++++++++++++++++ pkg/apiclient/model_workspace_dto.go | 36 ++++++++++++++++ pkg/cmd/bootstrap/get_server_instance.go | 15 +++++++ pkg/db/build_store.go | 2 +- pkg/db/job_store.go | 8 ---- pkg/db/target_store.go | 2 +- pkg/db/workspace_store.go | 2 +- pkg/models/build.go | 5 ++- pkg/models/target.go | 3 +- pkg/models/workspace.go | 3 +- pkg/server/builds/service.go | 15 +++++++ pkg/server/jobs/service.go | 51 +++++++++++++++++++--- pkg/server/targets/service.go | 15 +++++++ pkg/server/workspaces/service.go | 13 ++++++ pkg/services/build.go | 1 + pkg/services/target.go | 1 + pkg/services/workspace.go | 1 + 29 files changed, 503 insertions(+), 39 deletions(-) diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 0d47f51b76..1e98cde408 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -3790,6 +3790,9 @@ const docTemplate = `{ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "prebuildId": { "type": "string" }, @@ -5440,6 +5443,9 @@ const docTemplate = `{ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/TargetMetadata" }, @@ -5562,6 +5568,9 @@ const docTemplate = `{ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/TargetMetadata" }, @@ -5742,6 +5751,9 @@ const docTemplate = `{ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/WorkspaceMetadata" }, @@ -5804,6 +5816,9 @@ const docTemplate = `{ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/WorkspaceMetadata" }, diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 5167742edb..8f708b7f1b 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -3787,6 +3787,9 @@ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "prebuildId": { "type": "string" }, @@ -5437,6 +5440,9 @@ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/TargetMetadata" }, @@ -5559,6 +5565,9 @@ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/TargetMetadata" }, @@ -5739,6 +5748,9 @@ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/WorkspaceMetadata" }, @@ -5801,6 +5813,9 @@ "lastJob": { "$ref": "#/definitions/Job" }, + "lastJobId": { + "type": "string" + }, "metadata": { "$ref": "#/definitions/WorkspaceMetadata" }, diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 8926a08f4c..3de0ceeb6d 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -38,6 +38,8 @@ definitions: type: string lastJob: $ref: '#/definitions/Job' + lastJobId: + type: string prebuildId: type: string repository: @@ -1170,6 +1172,8 @@ definitions: type: string lastJob: $ref: '#/definitions/Job' + lastJobId: + type: string metadata: $ref: '#/definitions/TargetMetadata' name: @@ -1261,6 +1265,8 @@ definitions: type: string lastJob: $ref: '#/definitions/Job' + lastJobId: + type: string metadata: $ref: '#/definitions/TargetMetadata' name: @@ -1381,6 +1387,8 @@ definitions: type: string lastJob: $ref: '#/definitions/Job' + lastJobId: + type: string metadata: $ref: '#/definitions/WorkspaceMetadata' name: @@ -1424,6 +1432,8 @@ definitions: type: string lastJob: $ref: '#/definitions/Job' + lastJobId: + type: string metadata: $ref: '#/definitions/WorkspaceMetadata' name: diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 4ea15097ca..e3148c50c4 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -2753,6 +2753,23 @@ components: type: object BuildDTO: example: + image: image + containerConfig: + image: image + user: user + envVars: + key: envVars + repository: + owner: owner + path: path + name: name + id: id + source: source + prNumber: 0 + branch: branch + cloneTarget: null + sha: sha + url: url buildConfig: cachedBuild: image: image @@ -2760,11 +2777,8 @@ components: devcontainer: filePath: filePath createdAt: createdAt - image: image - containerConfig: - image: image - user: user prebuildId: prebuildId + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -2776,24 +2790,11 @@ components: error: error resourceType: null updatedAt: updatedAt - envVars: - key: envVars id: id state: name: null error: error updatedAt: updatedAt - repository: - owner: owner - path: path - name: name - id: id - source: source - prNumber: 0 - branch: branch - cloneTarget: null - sha: sha - url: url user: user updatedAt: updatedAt properties: @@ -2813,6 +2814,8 @@ components: type: string lastJob: $ref: '#/components/schemas/Job' + lastJobId: + type: string prebuildId: type: string repository: @@ -4576,6 +4579,7 @@ components: label: label version: version providerMetadata: providerMetadata + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -4606,6 +4610,8 @@ components: type: string lastJob: $ref: '#/components/schemas/Job' + lastJobId: + type: string metadata: $ref: '#/components/schemas/TargetMetadata' name: @@ -4755,6 +4761,7 @@ components: label: label version: version providerMetadata: providerMetadata + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -4844,6 +4851,7 @@ components: label: label version: version providerMetadata: providerMetadata + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -4869,6 +4877,7 @@ components: user: user devcontainer: filePath: filePath + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -4951,6 +4960,7 @@ components: label: label version: version providerMetadata: providerMetadata + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -4976,6 +4986,7 @@ components: user: user devcontainer: filePath: filePath + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -5001,6 +5012,8 @@ components: type: string lastJob: $ref: '#/components/schemas/Job' + lastJobId: + type: string metadata: $ref: '#/components/schemas/TargetMetadata' name: @@ -5250,6 +5263,7 @@ components: label: label version: version providerMetadata: providerMetadata + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -5275,6 +5289,7 @@ components: user: user devcontainer: filePath: filePath + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -5306,6 +5321,8 @@ components: type: string lastJob: $ref: '#/components/schemas/Job' + lastJobId: + type: string metadata: $ref: '#/components/schemas/WorkspaceMetadata' name: @@ -5401,6 +5418,7 @@ components: label: label version: version providerMetadata: providerMetadata + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -5426,6 +5444,7 @@ components: user: user devcontainer: filePath: filePath + lastJobId: lastJobId lastJob: createdAt: createdAt metadata: metadata @@ -5461,6 +5480,8 @@ components: type: string lastJob: $ref: '#/components/schemas/Job' + lastJobId: + type: string metadata: $ref: '#/components/schemas/WorkspaceMetadata' name: diff --git a/pkg/apiclient/docs/BuildDTO.md b/pkg/apiclient/docs/BuildDTO.md index 3bb5b605cd..f25122e17c 100644 --- a/pkg/apiclient/docs/BuildDTO.md +++ b/pkg/apiclient/docs/BuildDTO.md @@ -11,6 +11,7 @@ Name | Type | Description | Notes **Id** | **string** | | **Image** | Pointer to **string** | | [optional] **LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**LastJobId** | Pointer to **string** | | [optional] **PrebuildId** | Pointer to **string** | | [optional] **Repository** | [**GitRepository**](GitRepository.md) | | **State** | [**ResourceState**](ResourceState.md) | | @@ -191,6 +192,31 @@ SetLastJob sets LastJob field to given value. HasLastJob returns a boolean if a field has been set. +### GetLastJobId + +`func (o *BuildDTO) GetLastJobId() string` + +GetLastJobId returns the LastJobId field if non-nil, zero value otherwise. + +### GetLastJobIdOk + +`func (o *BuildDTO) GetLastJobIdOk() (*string, bool)` + +GetLastJobIdOk returns a tuple with the LastJobId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJobId + +`func (o *BuildDTO) SetLastJobId(v string)` + +SetLastJobId sets LastJobId field to given value. + +### HasLastJobId + +`func (o *BuildDTO) HasLastJobId() bool` + +HasLastJobId returns a boolean if a field has been set. + ### GetPrebuildId `func (o *BuildDTO) GetPrebuildId() string` diff --git a/pkg/apiclient/docs/Target.md b/pkg/apiclient/docs/Target.md index ccbfeecdb0..0dac5254c4 100644 --- a/pkg/apiclient/docs/Target.md +++ b/pkg/apiclient/docs/Target.md @@ -8,6 +8,7 @@ Name | Type | Description | Notes **EnvVars** | **map[string]string** | | **Id** | **string** | | **LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**LastJobId** | Pointer to **string** | | [optional] **Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | **ProviderMetadata** | Pointer to **string** | | [optional] @@ -119,6 +120,31 @@ SetLastJob sets LastJob field to given value. HasLastJob returns a boolean if a field has been set. +### GetLastJobId + +`func (o *Target) GetLastJobId() string` + +GetLastJobId returns the LastJobId field if non-nil, zero value otherwise. + +### GetLastJobIdOk + +`func (o *Target) GetLastJobIdOk() (*string, bool)` + +GetLastJobIdOk returns a tuple with the LastJobId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJobId + +`func (o *Target) SetLastJobId(v string)` + +SetLastJobId sets LastJobId field to given value. + +### HasLastJobId + +`func (o *Target) HasLastJobId() bool` + +HasLastJobId returns a boolean if a field has been set. + ### GetMetadata `func (o *Target) GetMetadata() TargetMetadata` diff --git a/pkg/apiclient/docs/TargetDTO.md b/pkg/apiclient/docs/TargetDTO.md index bed80d7999..16478ea305 100644 --- a/pkg/apiclient/docs/TargetDTO.md +++ b/pkg/apiclient/docs/TargetDTO.md @@ -8,6 +8,7 @@ Name | Type | Description | Notes **EnvVars** | **map[string]string** | | **Id** | **string** | | **LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**LastJobId** | Pointer to **string** | | [optional] **Metadata** | Pointer to [**TargetMetadata**](TargetMetadata.md) | | [optional] **Name** | **string** | | **ProviderMetadata** | Pointer to **string** | | [optional] @@ -120,6 +121,31 @@ SetLastJob sets LastJob field to given value. HasLastJob returns a boolean if a field has been set. +### GetLastJobId + +`func (o *TargetDTO) GetLastJobId() string` + +GetLastJobId returns the LastJobId field if non-nil, zero value otherwise. + +### GetLastJobIdOk + +`func (o *TargetDTO) GetLastJobIdOk() (*string, bool)` + +GetLastJobIdOk returns a tuple with the LastJobId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJobId + +`func (o *TargetDTO) SetLastJobId(v string)` + +SetLastJobId sets LastJobId field to given value. + +### HasLastJobId + +`func (o *TargetDTO) HasLastJobId() bool` + +HasLastJobId returns a boolean if a field has been set. + ### GetMetadata `func (o *TargetDTO) GetMetadata() TargetMetadata` diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/Workspace.md index 014445287d..0c3d113ce8 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/Workspace.md @@ -11,6 +11,7 @@ Name | Type | Description | Notes **Id** | **string** | | **Image** | **string** | | **LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**LastJobId** | Pointer to **string** | | [optional] **Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] **Name** | **string** | | **ProviderMetadata** | Pointer to **string** | | [optional] @@ -193,6 +194,31 @@ SetLastJob sets LastJob field to given value. HasLastJob returns a boolean if a field has been set. +### GetLastJobId + +`func (o *Workspace) GetLastJobId() string` + +GetLastJobId returns the LastJobId field if non-nil, zero value otherwise. + +### GetLastJobIdOk + +`func (o *Workspace) GetLastJobIdOk() (*string, bool)` + +GetLastJobIdOk returns a tuple with the LastJobId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJobId + +`func (o *Workspace) SetLastJobId(v string)` + +SetLastJobId sets LastJobId field to given value. + +### HasLastJobId + +`func (o *Workspace) HasLastJobId() bool` + +HasLastJobId returns a boolean if a field has been set. + ### GetMetadata `func (o *Workspace) GetMetadata() WorkspaceMetadata` diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md index 6ee85c1900..1bf7bfce25 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -11,6 +11,7 @@ Name | Type | Description | Notes **Id** | **string** | | **Image** | **string** | | **LastJob** | Pointer to [**Job**](Job.md) | | [optional] +**LastJobId** | Pointer to **string** | | [optional] **Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] **Name** | **string** | | **ProviderMetadata** | Pointer to **string** | | [optional] @@ -194,6 +195,31 @@ SetLastJob sets LastJob field to given value. HasLastJob returns a boolean if a field has been set. +### GetLastJobId + +`func (o *WorkspaceDTO) GetLastJobId() string` + +GetLastJobId returns the LastJobId field if non-nil, zero value otherwise. + +### GetLastJobIdOk + +`func (o *WorkspaceDTO) GetLastJobIdOk() (*string, bool)` + +GetLastJobIdOk returns a tuple with the LastJobId field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLastJobId + +`func (o *WorkspaceDTO) SetLastJobId(v string)` + +SetLastJobId sets LastJobId field to given value. + +### HasLastJobId + +`func (o *WorkspaceDTO) HasLastJobId() bool` + +HasLastJobId returns a boolean if a field has been set. + ### GetMetadata `func (o *WorkspaceDTO) GetMetadata() WorkspaceMetadata` diff --git a/pkg/apiclient/model_build_dto.go b/pkg/apiclient/model_build_dto.go index f9c1eb0e71..0000a04940 100644 --- a/pkg/apiclient/model_build_dto.go +++ b/pkg/apiclient/model_build_dto.go @@ -28,6 +28,7 @@ type BuildDTO struct { Id string `json:"id"` Image *string `json:"image,omitempty"` LastJob *Job `json:"lastJob,omitempty"` + LastJobId *string `json:"lastJobId,omitempty"` PrebuildId *string `json:"prebuildId,omitempty"` Repository GitRepository `json:"repository"` State ResourceState `json:"state"` @@ -253,6 +254,38 @@ func (o *BuildDTO) SetLastJob(v Job) { o.LastJob = &v } +// GetLastJobId returns the LastJobId field value if set, zero value otherwise. +func (o *BuildDTO) GetLastJobId() string { + if o == nil || IsNil(o.LastJobId) { + var ret string + return ret + } + return *o.LastJobId +} + +// GetLastJobIdOk returns a tuple with the LastJobId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BuildDTO) GetLastJobIdOk() (*string, bool) { + if o == nil || IsNil(o.LastJobId) { + return nil, false + } + return o.LastJobId, true +} + +// HasLastJobId returns a boolean if a field has been set. +func (o *BuildDTO) HasLastJobId() bool { + if o != nil && !IsNil(o.LastJobId) { + return true + } + + return false +} + +// SetLastJobId gets a reference to the given string and assigns it to the LastJobId field. +func (o *BuildDTO) SetLastJobId(v string) { + o.LastJobId = &v +} + // GetPrebuildId returns the PrebuildId field value if set, zero value otherwise. func (o *BuildDTO) GetPrebuildId() string { if o == nil || IsNil(o.PrebuildId) { @@ -412,6 +445,9 @@ func (o BuildDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } + if !IsNil(o.LastJobId) { + toSerialize["lastJobId"] = o.LastJobId + } if !IsNil(o.PrebuildId) { toSerialize["prebuildId"] = o.PrebuildId } diff --git a/pkg/apiclient/model_target.go b/pkg/apiclient/model_target.go index 325c61bf50..647ba596ab 100644 --- a/pkg/apiclient/model_target.go +++ b/pkg/apiclient/model_target.go @@ -25,6 +25,7 @@ type Target struct { EnvVars map[string]string `json:"envVars"` Id string `json:"id"` LastJob *Job `json:"lastJob,omitempty"` + LastJobId *string `json:"lastJobId,omitempty"` Metadata *TargetMetadata `json:"metadata,omitempty"` Name string `json:"name"` ProviderMetadata *string `json:"providerMetadata,omitempty"` @@ -163,6 +164,38 @@ func (o *Target) SetLastJob(v Job) { o.LastJob = &v } +// GetLastJobId returns the LastJobId field value if set, zero value otherwise. +func (o *Target) GetLastJobId() string { + if o == nil || IsNil(o.LastJobId) { + var ret string + return ret + } + return *o.LastJobId +} + +// GetLastJobIdOk returns a tuple with the LastJobId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Target) GetLastJobIdOk() (*string, bool) { + if o == nil || IsNil(o.LastJobId) { + return nil, false + } + return o.LastJobId, true +} + +// HasLastJobId returns a boolean if a field has been set. +func (o *Target) HasLastJobId() bool { + if o != nil && !IsNil(o.LastJobId) { + return true + } + + return false +} + +// SetLastJobId gets a reference to the given string and assigns it to the LastJobId field. +func (o *Target) SetLastJobId(v string) { + o.LastJobId = &v +} + // GetMetadata returns the Metadata field value if set, zero value otherwise. func (o *Target) GetMetadata() TargetMetadata { if o == nil || IsNil(o.Metadata) { @@ -339,6 +372,9 @@ func (o Target) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } + if !IsNil(o.LastJobId) { + toSerialize["lastJobId"] = o.LastJobId + } if !IsNil(o.Metadata) { toSerialize["metadata"] = o.Metadata } diff --git a/pkg/apiclient/model_target_dto.go b/pkg/apiclient/model_target_dto.go index 6bcf3f050a..61830fce30 100644 --- a/pkg/apiclient/model_target_dto.go +++ b/pkg/apiclient/model_target_dto.go @@ -25,6 +25,7 @@ type TargetDTO struct { EnvVars map[string]string `json:"envVars"` Id string `json:"id"` LastJob *Job `json:"lastJob,omitempty"` + LastJobId *string `json:"lastJobId,omitempty"` Metadata *TargetMetadata `json:"metadata,omitempty"` Name string `json:"name"` ProviderMetadata *string `json:"providerMetadata,omitempty"` @@ -165,6 +166,38 @@ func (o *TargetDTO) SetLastJob(v Job) { o.LastJob = &v } +// GetLastJobId returns the LastJobId field value if set, zero value otherwise. +func (o *TargetDTO) GetLastJobId() string { + if o == nil || IsNil(o.LastJobId) { + var ret string + return ret + } + return *o.LastJobId +} + +// GetLastJobIdOk returns a tuple with the LastJobId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *TargetDTO) GetLastJobIdOk() (*string, bool) { + if o == nil || IsNil(o.LastJobId) { + return nil, false + } + return o.LastJobId, true +} + +// HasLastJobId returns a boolean if a field has been set. +func (o *TargetDTO) HasLastJobId() bool { + if o != nil && !IsNil(o.LastJobId) { + return true + } + + return false +} + +// SetLastJobId gets a reference to the given string and assigns it to the LastJobId field. +func (o *TargetDTO) SetLastJobId(v string) { + o.LastJobId = &v +} + // GetMetadata returns the Metadata field value if set, zero value otherwise. func (o *TargetDTO) GetMetadata() TargetMetadata { if o == nil || IsNil(o.Metadata) { @@ -365,6 +398,9 @@ func (o TargetDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } + if !IsNil(o.LastJobId) { + toSerialize["lastJobId"] = o.LastJobId + } if !IsNil(o.Metadata) { toSerialize["metadata"] = o.Metadata } diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_workspace.go index c0bca449d3..44294c82d5 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_workspace.go @@ -28,6 +28,7 @@ type Workspace struct { Id string `json:"id"` Image string `json:"image"` LastJob *Job `json:"lastJob,omitempty"` + LastJobId *string `json:"lastJobId,omitempty"` Metadata *WorkspaceMetadata `json:"metadata,omitempty"` Name string `json:"name"` ProviderMetadata *string `json:"providerMetadata,omitempty"` @@ -257,6 +258,38 @@ func (o *Workspace) SetLastJob(v Job) { o.LastJob = &v } +// GetLastJobId returns the LastJobId field value if set, zero value otherwise. +func (o *Workspace) GetLastJobId() string { + if o == nil || IsNil(o.LastJobId) { + var ret string + return ret + } + return *o.LastJobId +} + +// GetLastJobIdOk returns a tuple with the LastJobId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Workspace) GetLastJobIdOk() (*string, bool) { + if o == nil || IsNil(o.LastJobId) { + return nil, false + } + return o.LastJobId, true +} + +// HasLastJobId returns a boolean if a field has been set. +func (o *Workspace) HasLastJobId() bool { + if o != nil && !IsNil(o.LastJobId) { + return true + } + + return false +} + +// SetLastJobId gets a reference to the given string and assigns it to the LastJobId field. +func (o *Workspace) SetLastJobId(v string) { + o.LastJobId = &v +} + // GetMetadata returns the Metadata field value if set, zero value otherwise. func (o *Workspace) GetMetadata() WorkspaceMetadata { if o == nil || IsNil(o.Metadata) { @@ -464,6 +497,9 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } + if !IsNil(o.LastJobId) { + toSerialize["lastJobId"] = o.LastJobId + } if !IsNil(o.Metadata) { toSerialize["metadata"] = o.Metadata } diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go index 5d6a6a1e56..dc80d5132b 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_workspace_dto.go @@ -28,6 +28,7 @@ type WorkspaceDTO struct { Id string `json:"id"` Image string `json:"image"` LastJob *Job `json:"lastJob,omitempty"` + LastJobId *string `json:"lastJobId,omitempty"` Metadata *WorkspaceMetadata `json:"metadata,omitempty"` Name string `json:"name"` ProviderMetadata *string `json:"providerMetadata,omitempty"` @@ -259,6 +260,38 @@ func (o *WorkspaceDTO) SetLastJob(v Job) { o.LastJob = &v } +// GetLastJobId returns the LastJobId field value if set, zero value otherwise. +func (o *WorkspaceDTO) GetLastJobId() string { + if o == nil || IsNil(o.LastJobId) { + var ret string + return ret + } + return *o.LastJobId +} + +// GetLastJobIdOk returns a tuple with the LastJobId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetLastJobIdOk() (*string, bool) { + if o == nil || IsNil(o.LastJobId) { + return nil, false + } + return o.LastJobId, true +} + +// HasLastJobId returns a boolean if a field has been set. +func (o *WorkspaceDTO) HasLastJobId() bool { + if o != nil && !IsNil(o.LastJobId) { + return true + } + + return false +} + +// SetLastJobId gets a reference to the given string and assigns it to the LastJobId field. +func (o *WorkspaceDTO) SetLastJobId(v string) { + o.LastJobId = &v +} + // GetMetadata returns the Metadata field value if set, zero value otherwise. func (o *WorkspaceDTO) GetMetadata() WorkspaceMetadata { if o == nil || IsNil(o.Metadata) { @@ -490,6 +523,9 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } + if !IsNil(o.LastJobId) { + toSerialize["lastJobId"] = o.LastJobId + } if !IsNil(o.Metadata) { toSerialize["metadata"] = o.Metadata } diff --git a/pkg/cmd/bootstrap/get_server_instance.go b/pkg/cmd/bootstrap/get_server_instance.go index 0cda54a2ac..39dc7b289c 100644 --- a/pkg/cmd/bootstrap/get_server_instance.go +++ b/pkg/cmd/bootstrap/get_server_instance.go @@ -145,6 +145,21 @@ func GetInstance(c *server.Config, configDir string, version string, telemetrySe TrackTelemetryEvent: func(event telemetry.Event, clientId string) error { return telemetryService.Track(event, clientId) }, + UpdateWorkspaceLastJob: func(ctx context.Context, workspaceId string, jobId string) error { + workspaceService := server.GetInstance(nil).WorkspaceService + + return workspaceService.UpdateLastJob(ctx, workspaceId, jobId) + }, + UpdateTargetLastJob: func(ctx context.Context, targetId string, jobId string) error { + targetService := server.GetInstance(nil).TargetService + + return targetService.UpdateLastJob(ctx, targetId, jobId) + }, + UpdateBuildLastJob: func(ctx context.Context, buildId string, jobId string) error { + buildService := server.GetInstance(nil).BuildService + + return buildService.UpdateLastJob(ctx, buildId, jobId) + }, }) buildService := builds.NewBuildService(builds.BuildServiceConfig{ diff --git a/pkg/db/build_store.go b/pkg/db/build_store.go index 429b66644f..0ff66c60f5 100644 --- a/pkg/db/build_store.go +++ b/pkg/db/build_store.go @@ -95,7 +95,7 @@ func (b *BuildStore) Delete(ctx context.Context, id string) error { } func preloadBuildEntities(tx *gorm.DB) *gorm.DB { - return tx.Preload("LastJob", preloadLastJob) + return tx.Preload("LastJob") } func processBuildFilters(tx *gorm.DB, filter *stores.BuildFilter) *gorm.DB { diff --git a/pkg/db/job_store.go b/pkg/db/job_store.go index af72d30df2..f398e209a5 100644 --- a/pkg/db/job_store.go +++ b/pkg/db/job_store.go @@ -109,11 +109,3 @@ func processJobFilters(tx *gorm.DB, filter *stores.JobFilter) *gorm.DB { } return tx } - -func preloadLastJob(tx *gorm.DB) *gorm.DB { - return tx.Where("updated_at IN (?)", - tx.Model(&models.Job{}). - Select("MAX(updated_at)"). - Group("resource_id"), - ) -} diff --git a/pkg/db/target_store.go b/pkg/db/target_store.go index 05bb98541a..e5e1a37cd4 100644 --- a/pkg/db/target_store.go +++ b/pkg/db/target_store.go @@ -96,5 +96,5 @@ func processTargetFilters(tx *gorm.DB, filter *stores.TargetFilter) *gorm.DB { } func preloadTargetEntities(tx *gorm.DB) *gorm.DB { - return tx.Preload(clause.Associations).Preload("Workspaces.LastJob", preloadLastJob).Preload("LastJob", preloadLastJob) + return tx.Preload(clause.Associations).Preload("Workspaces.LastJob").Preload("LastJob") } diff --git a/pkg/db/workspace_store.go b/pkg/db/workspace_store.go index eb762d6135..a27f7a3cd0 100644 --- a/pkg/db/workspace_store.go +++ b/pkg/db/workspace_store.go @@ -79,5 +79,5 @@ func (s *WorkspaceStore) Delete(ctx context.Context, workspace *models.Workspace } func preloadWorkspaceEntities(tx *gorm.DB) *gorm.DB { - return tx.Preload(clause.Associations).Preload("Target.TargetConfig").Preload("LastJob", preloadLastJob) + return tx.Preload(clause.Associations).Preload("Target.TargetConfig").Preload("LastJob") } diff --git a/pkg/models/build.go b/pkg/models/build.go index d67af7e284..d373f43f50 100644 --- a/pkg/models/build.go +++ b/pkg/models/build.go @@ -19,8 +19,9 @@ type Build struct { BuildConfig *BuildConfig `json:"buildConfig" validate:"optional" gorm:"serializer:json"` Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json;not null"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:Id;references:ResourceId"` - PrebuildId *string `json:"prebuildId" validate:"required" gorm:"not null"` + LastJobId *string `json:"lastJobId" validate:"optional"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:LastJobId;references:Id"` + PrebuildId *string `json:"prebuildId" validate:"optional"` CreatedAt time.Time `json:"createdAt" validate:"required" gorm:"not null"` UpdatedAt time.Time `json:"updatedAt" validate:"required" gorm:"not null"` } // @name Build diff --git a/pkg/models/target.go b/pkg/models/target.go index e2b9388ec9..df50e6e2fd 100644 --- a/pkg/models/target.go +++ b/pkg/models/target.go @@ -21,7 +21,8 @@ type Target struct { IsDefault bool `json:"default" validate:"required" gorm:"not null"` Workspaces []Workspace `json:"workspaces" validate:"required"` Metadata *TargetMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:Id;references:TargetId"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:Id;references:ResourceId"` + LastJobId *string `json:"lastJobId" validate:"optional"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:LastJobId;references:Id"` ProviderMetadata *string `json:"providerMetadata,omitempty" validate:"optional"` } // @name Target diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index 5e9935cd80..1ca3d698e1 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -23,7 +23,8 @@ type Workspace struct { ApiKey string `json:"apiKey" validate:"required" gorm:"not null"` Metadata *WorkspaceMetadata `json:"metadata" validate:"optional" gorm:"foreignKey:Id;references:WorkspaceId"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` - LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:Id;references:ResourceId"` + LastJobId *string `json:"lastJobId" validate:"optional"` + LastJob *Job `json:"lastJob" validate:"optional" gorm:"foreignKey:LastJobId;references:Id"` ProviderMetadata *string `json:"providerMetadata,omitempty" validate:"optional"` } // @name Workspace diff --git a/pkg/server/builds/service.go b/pkg/server/builds/service.go index 5e9a4a2d9f..e632c58357 100644 --- a/pkg/server/builds/service.go +++ b/pkg/server/builds/service.go @@ -159,6 +159,21 @@ func (s *BuildService) handleDeleteError(ctx context.Context, b *models.Build, e return err } +func (s *BuildService) UpdateLastJob(ctx context.Context, buildId, jobId string) error { + b, err := s.buildStore.Find(ctx, &stores.BuildFilter{ + Id: &buildId, + }) + if err != nil { + return err + } + + b.LastJobId = &jobId + // Make sure the old relation doesn't get saved to the store + b.LastJob = nil + + return s.buildStore.Save(ctx, b) +} + func (s *BuildService) GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) { return s.loggerFactory.CreateLogReader(buildId) } diff --git a/pkg/server/jobs/service.go b/pkg/server/jobs/service.go index 529612755f..9924742ed5 100644 --- a/pkg/server/jobs/service.go +++ b/pkg/server/jobs/service.go @@ -20,17 +20,28 @@ import ( type JobServiceConfig struct { JobStore stores.JobStore TrackTelemetryEvent func(event telemetry.Event, clientId string) error + + UpdateWorkspaceLastJob func(ctx context.Context, workspaceId string, jobId string) error + UpdateTargetLastJob func(ctx context.Context, targetId string, jobId string) error + UpdateBuildLastJob func(ctx context.Context, buildId string, jobId string) error } type JobService struct { jobStore stores.JobStore trackTelemetryEvent func(event telemetry.Event, clientId string) error + + updateWorkspaceLastJob func(ctx context.Context, workspaceId string, jobId string) error + updateTargetLastJob func(ctx context.Context, targetId string, jobId string) error + updateBuildLastJob func(ctx context.Context, buildId string, jobId string) error } func NewJobService(config JobServiceConfig) services.IJobService { return &JobService{ - jobStore: config.JobStore, - trackTelemetryEvent: config.TrackTelemetryEvent, + jobStore: config.JobStore, + trackTelemetryEvent: config.TrackTelemetryEvent, + updateWorkspaceLastJob: config.UpdateWorkspaceLastJob, + updateTargetLastJob: config.UpdateTargetLastJob, + updateBuildLastJob: config.UpdateBuildLastJob, } } @@ -76,21 +87,47 @@ func (s *JobService) Create(ctx context.Context, j *models.Job) error { } func (s *JobService) UpdateState(ctx context.Context, jobId string, updateJobStateDto services.UpdateJobStateDTO) error { - job, err := s.Find(ctx, &stores.JobFilter{ - Id: &jobId, - }) + var err error + ctx, err = s.jobStore.BeginTransaction(ctx) if err != nil { return err } + defer stores.RecoverAndRollback(ctx, s.jobStore) + + job, findErr := s.Find(ctx, &stores.JobFilter{ + Id: &jobId, + }) + if findErr != nil { + return s.jobStore.RollbackTransaction(ctx, findErr) + } + if job.State == updateJobStateDto.State { - return errors.New("job is already in the specified state") + return s.jobStore.RollbackTransaction(ctx, errors.New("job is already in the specified state")) } job.State = updateJobStateDto.State job.Error = updateJobStateDto.ErrorMessage - return s.jobStore.Save(ctx, job) + err = s.jobStore.Save(ctx, job) + if err != nil { + return s.jobStore.RollbackTransaction(ctx, err) + } + + switch job.ResourceType { + case models.ResourceTypeWorkspace: + err = s.updateWorkspaceLastJob(ctx, job.ResourceId, job.Id) + case models.ResourceTypeTarget: + err = s.updateTargetLastJob(ctx, job.ResourceId, job.Id) + case models.ResourceTypeBuild: + err = s.updateBuildLastJob(ctx, job.ResourceId, job.Id) + } + + if err != nil { + return s.jobStore.RollbackTransaction(ctx, err) + } + + return s.jobStore.CommitTransaction(ctx) } func (s *JobService) Delete(ctx context.Context, j *models.Job) error { diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index c56959d263..93165081c4 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -88,3 +88,18 @@ func (s *TargetService) UpdateProviderMetadata(ctx context.Context, targetId, me tg.ProviderMetadata = &metadata return s.targetStore.Save(ctx, tg) } + +func (s *TargetService) UpdateLastJob(ctx context.Context, targetId, jobId string) error { + t, err := s.targetStore.Find(ctx, &stores.TargetFilter{ + IdOrName: &targetId, + }) + if err != nil { + return err + } + + t.LastJobId = &jobId + // Make sure the old relation doesn't get saved to the store + t.LastJob = nil + + return s.targetStore.Save(ctx, t) +} diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index b2a444e3be..f6e4e1cf64 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -103,3 +103,16 @@ func (s *WorkspaceService) UpdateProviderMetadata(ctx context.Context, workspace w.ProviderMetadata = &metadata return s.workspaceStore.Save(ctx, w) } + +func (s *WorkspaceService) UpdateLastJob(ctx context.Context, workspaceId, jobId string) error { + w, err := s.workspaceStore.Find(ctx, workspaceId) + if err != nil { + return err + } + + w.LastJobId = &jobId + // Make sure the old relation doesn't get saved to the store + w.LastJob = nil + + return s.workspaceStore.Save(ctx, w) +} diff --git a/pkg/services/build.go b/pkg/services/build.go index 5ea7cdf341..3970c1b0b4 100644 --- a/pkg/services/build.go +++ b/pkg/services/build.go @@ -18,6 +18,7 @@ type IBuildService interface { Create(ctx context.Context, createBuildDTO CreateBuildDTO) (string, error) Delete(ctx context.Context, filter *BuildFilter, force bool) []error + UpdateLastJob(ctx context.Context, buildId, jobId string) error HandleSuccessfulRemoval(ctx context.Context, id string) error GetBuildLogReader(ctx context.Context, buildId string) (io.Reader, error) GetBuildLogWriter(ctx context.Context, buildId string) (io.WriteCloser, error) diff --git a/pkg/services/target.go b/pkg/services/target.go index 233e09cc7a..2d66d0c7c8 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -25,6 +25,7 @@ type ITargetService interface { UpdateMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) UpdateProviderMetadata(ctx context.Context, targetId, metadata string) error + UpdateLastJob(ctx context.Context, targetId, jobId string) error HandleSuccessfulCreation(ctx context.Context, targetId string) error GetTargetLogReader(ctx context.Context, targetId string) (io.Reader, error) diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 3497ebf5e9..5b24a5af23 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -23,6 +23,7 @@ type IWorkspaceService interface { UpdateMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) UpdateProviderMetadata(ctx context.Context, workspaceId, metadata string) error + UpdateLastJob(ctx context.Context, workspaceId, jobId string) error GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) GetWorkspaceLogWriter(ctx context.Context, workspaceId string) (io.WriteCloser, error) From 29a0e503cf8a360db9f6908147e943bb7d5b8dbc Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Mon, 23 Dec 2024 14:27:20 +0000 Subject: [PATCH 51/76] fix: metadata save order Signed-off-by: Toma Puljak --- pkg/server/runners/create.go | 4 ++-- pkg/server/targets/create.go | 16 ++++++++-------- pkg/server/workspaces/create.go | 19 +++++++++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/pkg/server/runners/create.go b/pkg/server/runners/create.go index 3a44989f97..ee6d9766d9 100644 --- a/pkg/server/runners/create.go +++ b/pkg/server/runners/create.go @@ -43,12 +43,12 @@ func (s *RunnerService) Create(ctx context.Context, req services.CreateRunnerDTO }, } - err = s.runnerStore.Save(ctx, runner) + err = s.runnerMetadataStore.Save(ctx, runner.Metadata) if err != nil { return nil, s.handleRegisterError(ctx, runner, err) } - err = s.runnerMetadataStore.Save(ctx, runner.Metadata) + err = s.runnerStore.Save(ctx, runner) if err != nil { return nil, s.handleRegisterError(ctx, runner, err) } diff --git a/pkg/server/targets/create.go b/pkg/server/targets/create.go index f71c26ea63..d22d17c5e1 100644 --- a/pkg/server/targets/create.go +++ b/pkg/server/targets/create.go @@ -53,6 +53,14 @@ func (s *TargetService) Create(ctx context.Context, req services.CreateTargetDTO } tg.ApiKey = apiKey + err = s.targetMetadataStore.Save(ctx, &models.TargetMetadata{ + TargetId: tg.Id, + Uptime: 0, + }) + if err != nil { + return s.handleCreateError(ctx, tg, err) + } + daytonaTargetEnvVars := GetTargetEnvVars(tg, TargetEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, @@ -67,14 +75,6 @@ func (s *TargetService) Create(ctx context.Context, req services.CreateTargetDTO return s.handleCreateError(ctx, nil, err) } - err = s.targetMetadataStore.Save(ctx, &models.TargetMetadata{ - TargetId: tg.Id, - Uptime: 0, - }) - if err != nil { - return s.handleCreateError(ctx, tg, err) - } - err = s.createJob(ctx, tg.Id, tg.TargetConfig.ProviderInfo.RunnerId, models.JobActionCreate) if err != nil { return s.handleCreateError(ctx, tg, err) diff --git a/pkg/server/workspaces/create.go b/pkg/server/workspaces/create.go index 3fde685ddb..a66dea60ce 100644 --- a/pkg/server/workspaces/create.go +++ b/pkg/server/workspaces/create.go @@ -91,9 +91,17 @@ func (s *WorkspaceService) Create(ctx context.Context, req services.CreateWorksp if err != nil { return s.handleCreateError(ctx, w, err) } - w.ApiKey = apiKey + err = s.workspaceMetadataStore.Save(ctx, &models.WorkspaceMetadata{ + WorkspaceId: w.Id, + Uptime: 0, + GitStatus: &models.GitStatus{}, + }) + if err != nil { + return s.handleCreateError(ctx, w, err) + } + daytonaWorkspaceEnvVars := GetWorkspaceEnvVars(w, WorkspaceEnvVarParams{ ApiUrl: s.serverApiUrl, ServerUrl: s.serverUrl, @@ -108,15 +116,6 @@ func (s *WorkspaceService) Create(ctx context.Context, req services.CreateWorksp return s.handleCreateError(ctx, w, err) } - err = s.workspaceMetadataStore.Save(ctx, &models.WorkspaceMetadata{ - WorkspaceId: w.Id, - Uptime: 0, - GitStatus: &models.GitStatus{}, - }) - if err != nil { - return s.handleCreateError(ctx, w, err) - } - err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionCreate) if err != nil { return s.handleCreateError(ctx, w, err) From 01b46c137f55f93f3b9d15a62d060bba03b3b0e2 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Thu, 9 Jan 2025 14:27:41 +0100 Subject: [PATCH 52/76] fix: restart methods (#1685) Signed-off-by: Ivan Dagelic --- pkg/api/controllers/target/restart.go | 36 ++++++++ pkg/api/controllers/workspace/restart.go | 36 ++++++++ pkg/api/docs/docs.go | 48 ++++++++++ pkg/api/docs/swagger.json | 48 ++++++++++ pkg/api/docs/swagger.yaml | 32 +++++++ pkg/api/server.go | 2 + pkg/apiclient/README.md | 2 + pkg/apiclient/api/openapi.yaml | 36 ++++++++ pkg/apiclient/api_target.go | 106 ++++++++++++++++++++++ pkg/apiclient/api_workspace.go | 106 ++++++++++++++++++++++ pkg/apiclient/docs/TargetAPI.md | 69 +++++++++++++++ pkg/apiclient/docs/WorkspaceAPI.md | 69 +++++++++++++++ pkg/cmd/target/restart.go | 10 +-- pkg/cmd/target/ssh.go | 2 +- pkg/cmd/target/start.go | 108 ++++++++++++----------- pkg/cmd/workspace/code.go | 2 +- pkg/cmd/workspace/restart.go | 12 +-- pkg/cmd/workspace/start.go | 17 ++-- pkg/jobs/workspace/restart.go | 2 +- pkg/jobs/workspace/workspace.go | 2 + pkg/server/targets/restart.go | 48 ++++++++++ pkg/server/workspaces/restart.go | 47 ++++++++++ pkg/services/target.go | 1 + pkg/services/workspace.go | 1 + 24 files changed, 765 insertions(+), 77 deletions(-) create mode 100644 pkg/api/controllers/target/restart.go create mode 100644 pkg/api/controllers/workspace/restart.go create mode 100644 pkg/server/targets/restart.go create mode 100644 pkg/server/workspaces/restart.go diff --git a/pkg/api/controllers/target/restart.go b/pkg/api/controllers/target/restart.go new file mode 100644 index 0000000000..d690cec38e --- /dev/null +++ b/pkg/api/controllers/target/restart.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package target + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// RestartTarget godoc +// +// @Tags target +// @Summary Restart target +// @Description Restart target +// @Param targetId path string true "Target ID or Name" +// @Success 200 +// @Router /target/{targetId}/restart [post] +// +// @id RestartTarget +func RestartTarget(ctx *gin.Context) { + targetId := ctx.Param("targetId") + + server := server.GetInstance(nil) + + err := server.TargetService.Restart(ctx.Request.Context(), targetId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to restart target %s: %w", targetId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/controllers/workspace/restart.go b/pkg/api/controllers/workspace/restart.go new file mode 100644 index 0000000000..978bc1671a --- /dev/null +++ b/pkg/api/controllers/workspace/restart.go @@ -0,0 +1,36 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// RestartWorkspace godoc +// +// @Tags workspace +// @Summary Restart workspace +// @Description Restart workspace +// @Param workspaceId path string true "Workspace ID or Name" +// @Success 200 +// @Router /workspace/{workspaceId}/restart [post] +// +// @id RestartWorkspace +func RestartWorkspace(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + server := server.GetInstance(nil) + + err := server.WorkspaceService.Restart(ctx.Request.Context(), workspaceId) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to restart workspace %s: %w", workspaceId, err)) + return + } + + ctx.Status(200) +} diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index 1e98cde408..a816f6f9dd 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1734,6 +1734,30 @@ const docTemplate = `{ } } }, + "/target/{targetId}/restart": { + "post": { + "description": "Restart target", + "tags": [ + "target" + ], + "summary": "Restart target", + "operationId": "RestartTarget", + "parameters": [ + { + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/set-default": { "patch": { "description": "Set target to be used by default", @@ -2342,6 +2366,30 @@ const docTemplate = `{ } } }, + "/workspace/{workspaceId}/restart": { + "post": { + "description": "Restart workspace", + "tags": [ + "workspace" + ], + "summary": "Restart workspace", + "operationId": "RestartWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/workspace/{workspaceId}/start": { "post": { "description": "Start workspace", diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index 8f708b7f1b..c6bb64caa9 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1731,6 +1731,30 @@ } } }, + "/target/{targetId}/restart": { + "post": { + "description": "Restart target", + "tags": [ + "target" + ], + "summary": "Restart target", + "operationId": "RestartTarget", + "parameters": [ + { + "type": "string", + "description": "Target ID or Name", + "name": "targetId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/target/{targetId}/set-default": { "patch": { "description": "Set target to be used by default", @@ -2339,6 +2363,30 @@ } } }, + "/workspace/{workspaceId}/restart": { + "post": { + "description": "Restart workspace", + "tags": [ + "workspace" + ], + "summary": "Restart workspace", + "operationId": "RestartWorkspace", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, "/workspace/{workspaceId}/start": { "post": { "description": "Start workspace", diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index 3de0ceeb6d..b6e89b74ca 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -2764,6 +2764,22 @@ paths: summary: Update target provider metadata tags: - target + /target/{targetId}/restart: + post: + description: Restart target + operationId: RestartTarget + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + type: string + responses: + "200": + description: OK + summary: Restart target + tags: + - target /target/{targetId}/set-default: patch: description: Set target to be used by default @@ -3171,6 +3187,22 @@ paths: summary: Update workspace provider metadata tags: - workspace + /workspace/{workspaceId}/restart: + post: + description: Restart workspace + operationId: RestartWorkspace + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + type: string + responses: + "200": + description: OK + summary: Restart workspace + tags: + - workspace /workspace/{workspaceId}/start: post: description: Start workspace diff --git a/pkg/api/server.go b/pkg/api/server.go index 752c78b326..c43a42929c 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -149,6 +149,7 @@ func (a *ApiServer) Start() error { targetController.POST("", target.CreateTarget) targetController.POST("/:targetId/start", target.StartTarget) targetController.POST("/:targetId/stop", target.StopTarget) + targetController.POST("/:targetId/restart", target.RestartTarget) targetController.PATCH("/:targetId/set-default", target.SetDefaultTarget) targetController.POST("/:targetId/handle-successful-creation", target.HandleSuccessfulCreation) targetController.POST("/:targetId/provider-metadata", target.UpdateTargetProviderMetadata) @@ -226,6 +227,7 @@ func (a *ApiServer) Start() error { workspaceController.POST("/:workspaceId/start", workspace.StartWorkspace) workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) + workspaceController.POST("/:workspaceId/restart", workspace.RestartWorkspace) workspaceController.POST("/:workspaceId/provider-metadata", workspace.UpdateWorkspaceProviderMetadata) } diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index fd212ea73b..683a8d36bc 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -133,6 +133,7 @@ Class | Method | HTTP request | Description *TargetAPI* | [**FindTarget**](docs/TargetAPI.md#findtarget) | **Get** /target/{targetId} | Find target *TargetAPI* | [**HandleSuccessfulCreation**](docs/TargetAPI.md#handlesuccessfulcreation) | **Post** /target/{targetId}/handle-successful-creation | Handles successful creation of the target *TargetAPI* | [**ListTargets**](docs/TargetAPI.md#listtargets) | **Get** /target | List targets +*TargetAPI* | [**RestartTarget**](docs/TargetAPI.md#restarttarget) | **Post** /target/{targetId}/restart | Restart target *TargetAPI* | [**SetDefaultTarget**](docs/TargetAPI.md#setdefaulttarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default *TargetAPI* | [**StartTarget**](docs/TargetAPI.md#starttarget) | **Post** /target/{targetId}/start | Start target *TargetAPI* | [**StopTarget**](docs/TargetAPI.md#stoptarget) | **Post** /target/{targetId}/stop | Stop target @@ -145,6 +146,7 @@ Class | Method | HTTP request | Description *WorkspaceAPI* | [**DeleteWorkspace**](docs/WorkspaceAPI.md#deleteworkspace) | **Delete** /workspace/{workspaceId} | Delete workspace *WorkspaceAPI* | [**FindWorkspace**](docs/WorkspaceAPI.md#findworkspace) | **Get** /workspace/{workspaceId} | Find workspace *WorkspaceAPI* | [**ListWorkspaces**](docs/WorkspaceAPI.md#listworkspaces) | **Get** /workspace | List workspaces +*WorkspaceAPI* | [**RestartWorkspace**](docs/WorkspaceAPI.md#restartworkspace) | **Post** /workspace/{workspaceId}/restart | Restart workspace *WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace *WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace *WorkspaceAPI* | [**UpdateWorkspaceMetadata**](docs/WorkspaceAPI.md#updateworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Update workspace metadata diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index e3148c50c4..3d1deecce9 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -1254,6 +1254,24 @@ paths: tags: - target x-codegen-request-body-name: metadata + /target/{targetId}/restart: + post: + description: Restart target + operationId: RestartTarget + parameters: + - description: Target ID or Name + in: path + name: targetId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Restart target + tags: + - target /target/{targetId}/set-default: patch: description: Set target to be used by default @@ -1697,6 +1715,24 @@ paths: tags: - workspace x-codegen-request-body-name: metadata + /workspace/{workspaceId}/restart: + post: + description: Restart workspace + operationId: RestartWorkspace + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + schema: + type: string + responses: + "200": + content: {} + description: OK + summary: Restart workspace + tags: + - workspace /workspace/{workspaceId}/start: post: description: Start workspace diff --git a/pkg/apiclient/api_target.go b/pkg/apiclient/api_target.go index 6de8b4166b..d5313b31aa 100644 --- a/pkg/apiclient/api_target.go +++ b/pkg/apiclient/api_target.go @@ -622,6 +622,112 @@ func (a *TargetAPIService) ListTargetsExecute(r ApiListTargetsRequest) ([]Target return localVarReturnValue, localVarHTTPResponse, nil } +type ApiRestartTargetRequest struct { + ctx context.Context + ApiService *TargetAPIService + targetId string +} + +func (r ApiRestartTargetRequest) Execute() (*http.Response, error) { + return r.ApiService.RestartTargetExecute(r) +} + +/* +RestartTarget Restart target + +Restart target + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param targetId Target ID or Name + @return ApiRestartTargetRequest +*/ +func (a *TargetAPIService) RestartTarget(ctx context.Context, targetId string) ApiRestartTargetRequest { + return ApiRestartTargetRequest{ + ApiService: a, + ctx: ctx, + targetId: targetId, + } +} + +// Execute executes the request +func (a *TargetAPIService) RestartTargetExecute(r ApiRestartTargetRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "TargetAPIService.RestartTarget") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/target/{targetId}/restart" + localVarPath = strings.Replace(localVarPath, "{"+"targetId"+"}", url.PathEscape(parameterValueToString(r.targetId, "targetId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + type ApiSetDefaultTargetRequest struct { ctx context.Context ApiService *TargetAPIService diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index 6149122789..1e6497dbde 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -496,6 +496,112 @@ func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) return localVarReturnValue, localVarHTTPResponse, nil } +type ApiRestartWorkspaceRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string +} + +func (r ApiRestartWorkspaceRequest) Execute() (*http.Response, error) { + return r.ApiService.RestartWorkspaceExecute(r) +} + +/* +RestartWorkspace Restart workspace + +Restart workspace + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID or Name + @return ApiRestartWorkspaceRequest +*/ +func (a *WorkspaceAPIService) RestartWorkspace(ctx context.Context, workspaceId string) ApiRestartWorkspaceRequest { + return ApiRestartWorkspaceRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +func (a *WorkspaceAPIService) RestartWorkspaceExecute(r ApiRestartWorkspaceRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.RestartWorkspace") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}/restart" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + type ApiStartWorkspaceRequest struct { ctx context.Context ApiService *WorkspaceAPIService diff --git a/pkg/apiclient/docs/TargetAPI.md b/pkg/apiclient/docs/TargetAPI.md index eaef7314a8..97a885763f 100644 --- a/pkg/apiclient/docs/TargetAPI.md +++ b/pkg/apiclient/docs/TargetAPI.md @@ -9,6 +9,7 @@ Method | HTTP request | Description [**FindTarget**](TargetAPI.md#FindTarget) | **Get** /target/{targetId} | Find target [**HandleSuccessfulCreation**](TargetAPI.md#HandleSuccessfulCreation) | **Post** /target/{targetId}/handle-successful-creation | Handles successful creation of the target [**ListTargets**](TargetAPI.md#ListTargets) | **Get** /target | List targets +[**RestartTarget**](TargetAPI.md#RestartTarget) | **Post** /target/{targetId}/restart | Restart target [**SetDefaultTarget**](TargetAPI.md#SetDefaultTarget) | **Patch** /target/{targetId}/set-default | Set target to be used by default [**StartTarget**](TargetAPI.md#StartTarget) | **Post** /target/{targetId}/start | Start target [**StopTarget**](TargetAPI.md#StopTarget) | **Post** /target/{targetId}/stop | Stop target @@ -359,6 +360,74 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## RestartTarget + +> RestartTarget(ctx, targetId).Execute() + +Restart target + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + targetId := "targetId_example" // string | Target ID or Name + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.TargetAPI.RestartTarget(context.Background(), targetId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `TargetAPI.RestartTarget``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**targetId** | **string** | Target ID or Name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiRestartTargetRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## SetDefaultTarget > SetDefaultTarget(ctx, targetId).Execute() diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 8512fc845f..09ee031e82 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -8,6 +8,7 @@ Method | HTTP request | Description [**DeleteWorkspace**](WorkspaceAPI.md#DeleteWorkspace) | **Delete** /workspace/{workspaceId} | Delete workspace [**FindWorkspace**](WorkspaceAPI.md#FindWorkspace) | **Get** /workspace/{workspaceId} | Find workspace [**ListWorkspaces**](WorkspaceAPI.md#ListWorkspaces) | **Get** /workspace | List workspaces +[**RestartWorkspace**](WorkspaceAPI.md#RestartWorkspace) | **Post** /workspace/{workspaceId}/restart | Restart workspace [**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace [**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace [**UpdateWorkspaceMetadata**](WorkspaceAPI.md#UpdateWorkspaceMetadata) | **Post** /workspace/{workspaceId}/metadata | Update workspace metadata @@ -282,6 +283,74 @@ Other parameters are passed through a pointer to a apiListWorkspacesRequest stru [[Back to README]](../README.md) +## RestartWorkspace + +> RestartWorkspace(ctx, workspaceId).Execute() + +Restart workspace + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID or Name + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + r, err := apiClient.WorkspaceAPI.RestartWorkspace(context.Background(), workspaceId).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.RestartWorkspace``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID or Name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiRestartWorkspaceRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + +### Return type + + (empty response body) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## StartWorkspace > StartWorkspace(ctx, workspaceId).Execute() diff --git a/pkg/cmd/target/restart.go b/pkg/cmd/target/restart.go index b3d3920f33..0699eec128 100644 --- a/pkg/cmd/target/restart.go +++ b/pkg/cmd/target/restart.go @@ -51,7 +51,7 @@ var restartCmd = &cobra.Command{ } } - err = RestartTarget(apiClient, *target) + err = StartTarget(apiClient, *target, true) if err != nil { return err } @@ -62,11 +62,3 @@ var restartCmd = &cobra.Command{ return getAllTargetsByState(util.Pointer(apiclient.ResourceStateNameStarted)) }, } - -func RestartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) error { - err := StopTarget(apiClient, target) - if err != nil { - return err - } - return StartTarget(apiClient, target) -} diff --git a/pkg/cmd/target/ssh.go b/pkg/cmd/target/ssh.go index f13ad49b55..6be72468ce 100644 --- a/pkg/cmd/target/ssh.go +++ b/pkg/cmd/target/ssh.go @@ -107,7 +107,7 @@ func autoStartTarget(target apiclient.TargetDTO) (bool, error) { return false, err } - err = StartTarget(apiClient, target) + err = StartTarget(apiClient, target, false) if err != nil { return false, err } diff --git a/pkg/cmd/target/start.go b/pkg/cmd/target/start.go index 9ba3e8611e..bbe28fcc6e 100644 --- a/pkg/cmd/target/start.go +++ b/pkg/cmd/target/start.go @@ -6,6 +6,7 @@ package target import ( "context" "fmt" + "net/http" "time" "github.com/daytonaio/daytona/cmd/daytona/config" @@ -67,7 +68,7 @@ var startCmd = &cobra.Command{ return err } - err = StartTarget(apiClient, *target) + err = StartTarget(apiClient, *target, false) if err != nil { return err } @@ -80,7 +81,7 @@ var startCmd = &cobra.Command{ return err } - err = StartTarget(apiClient, *target) + err = StartTarget(apiClient, *target, false) if err != nil { log.Errorf("Failed to start target %s: %v\n\n", targetName, err) continue @@ -100,6 +101,60 @@ func init() { startCmd.PersistentFlags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") } +func StartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO, restart bool) error { + ctx := context.Background() + timeFormat := time.Now().Format("2006-01-02 15:04:05") + from, err := time.Parse("2006-01-02 15:04:05", timeFormat) + if err != nil { + return err + } + + c, err := config.GetConfig() + if err != nil { + return err + } + + activeProfile, err := c.GetActiveProfile() + if err != nil { + return err + } + + if target.TargetConfig.ProviderInfo.AgentlessTarget != nil && *target.TargetConfig.ProviderInfo.AgentlessTarget { + return agentlessTargetError(target.TargetConfig.ProviderInfo.Name) + } + + logsContext, stopLogs := context.WithCancel(context.Background()) + go cmd_common.ReadTargetLogs(logsContext, cmd_common.ReadLogParams{ + Id: target.Id, + Label: &target.Name, + ServerUrl: activeProfile.Api.Url, + ApiKey: activeProfile.Api.Key, + Follow: util.Pointer(true), + From: &from, + }) + + var res *http.Response + + if restart { + res, err = apiClient.TargetAPI.RestartTarget(ctx, target.Id).Execute() + } else { + res, err = apiClient.TargetAPI.StartTarget(ctx, target.Id).Execute() + } + + if err != nil { + stopLogs() + return apiclient_util.HandleErrorResponse(res, err) + } + + err = cmd_common.AwaitTargetState(target.Id, apiclient.ResourceStateNameStarted) + + // Ensure reading remaining logs is completed + time.Sleep(100 * time.Millisecond) + + stopLogs() + return err +} + func startAllTargets() error { ctx := context.Background() apiClient, err := apiclient_util.GetApiClient(nil) @@ -113,7 +168,7 @@ func startAllTargets() error { } for _, target := range targetList { - err := StartTarget(apiClient, target) + err := StartTarget(apiClient, target, false) if err != nil { log.Errorf("Failed to start target %s: %v\n\n", target.Name, err) continue @@ -156,53 +211,6 @@ func getAllTargetsByState(state *apiclient.ModelsResourceStateName) ([]string, c return choices, cobra.ShellCompDirectiveNoFileComp } -func StartTarget(apiClient *apiclient.APIClient, target apiclient.TargetDTO) error { - ctx := context.Background() - timeFormat := time.Now().Format("2006-01-02 15:04:05") - from, err := time.Parse("2006-01-02 15:04:05", timeFormat) - if err != nil { - return err - } - - c, err := config.GetConfig() - if err != nil { - return err - } - - activeProfile, err := c.GetActiveProfile() - if err != nil { - return err - } - - if target.TargetConfig.ProviderInfo.AgentlessTarget != nil && *target.TargetConfig.ProviderInfo.AgentlessTarget { - return agentlessTargetError(target.TargetConfig.ProviderInfo.Name) - } - - logsContext, stopLogs := context.WithCancel(context.Background()) - go cmd_common.ReadTargetLogs(logsContext, cmd_common.ReadLogParams{ - Id: target.Id, - Label: &target.Name, - ServerUrl: activeProfile.Api.Url, - ApiKey: activeProfile.Api.Key, - Follow: util.Pointer(true), - From: &from, - }) - - res, err := apiClient.TargetAPI.StartTarget(ctx, target.Id).Execute() - if err != nil { - stopLogs() - return apiclient_util.HandleErrorResponse(res, err) - } - - err = cmd_common.AwaitTargetState(target.Id, apiclient.ResourceStateNameStarted) - - // Ensure reading remaining logs is completed - time.Sleep(100 * time.Millisecond) - - stopLogs() - return err -} - func agentlessTargetError(providerName string) error { return fmt.Errorf("%s does not use a target-level agent; you may continue without managing its state or trying to access it", providerName) } diff --git a/pkg/cmd/workspace/code.go b/pkg/cmd/workspace/code.go index adb4430316..e38e4e14bb 100644 --- a/pkg/cmd/workspace/code.go +++ b/pkg/cmd/workspace/code.go @@ -134,7 +134,7 @@ func AutoStartWorkspace(workspace apiclient.WorkspaceDTO) (bool, error) { return false, err } - err = StartWorkspace(apiClient, workspace) + err = StartWorkspace(apiClient, workspace, false) if err != nil { return false, err } diff --git a/pkg/cmd/workspace/restart.go b/pkg/cmd/workspace/restart.go index 0edb337569..9a5f68fb15 100644 --- a/pkg/cmd/workspace/restart.go +++ b/pkg/cmd/workspace/restart.go @@ -62,7 +62,7 @@ var RestartCmd = &cobra.Command{ if len(selectedWorkspaces) == 1 { workspace := selectedWorkspaces[0] - err = RestartWorkspace(apiClient, *workspace) + err = StartWorkspace(apiClient, *workspace, true) if err != nil { return err } @@ -70,7 +70,7 @@ var RestartCmd = &cobra.Command{ views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' restarted successfully", workspace.Name)) } else { for _, ws := range selectedWorkspaces { - err := RestartWorkspace(apiClient, *ws) + err := StartWorkspace(apiClient, *ws, true) if err != nil { log.Errorf("Failed to restart workspace %s: %v\n\n", ws.Name, err) continue @@ -85,11 +85,3 @@ var RestartCmd = &cobra.Command{ return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStarted) }, } - -func RestartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO) error { - err := StopWorkspace(apiClient, workspace) - if err != nil { - return err - } - return StartWorkspace(apiClient, workspace) -} diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index c6662ceae7..7bbcedb072 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -100,7 +100,7 @@ var StartCmd = &cobra.Command{ } } - err = StartWorkspace(apiClient, *workspace) + err = StartWorkspace(apiClient, *workspace, false) if err != nil { return err } @@ -120,7 +120,7 @@ var StartCmd = &cobra.Command{ } } else { for _, ws := range selectedWorkspaces { - err := StartWorkspace(apiClient, *ws) + err := StartWorkspace(apiClient, *ws, false) if err != nil { log.Errorf("Failed to start workspace %s: %v\n\n", ws.Name, err) continue @@ -154,7 +154,7 @@ func startAllWorkspaces() error { } for _, workspace := range workspaceList { - err := StartWorkspace(apiClient, workspace) + err := StartWorkspace(apiClient, workspace, false) if err != nil { log.Errorf("Failed to start workspace %s: %v\n\n", workspace.Name, err) continue @@ -165,7 +165,7 @@ func startAllWorkspaces() error { return nil } -func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO) error { +func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO, restart bool) error { ctx := context.Background() timeFormat := time.Now().Format("2006-01-02 15:04:05") from, err := time.Parse("2006-01-02 15:04:05", timeFormat) @@ -194,7 +194,14 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspac From: &from, }) - res, err := apiClient.WorkspaceAPI.StartWorkspace(ctx, workspace.Id).Execute() + var res *http.Response + + if restart { + res, err = apiClient.WorkspaceAPI.RestartWorkspace(ctx, workspace.Id).Execute() + } else { + res, err = apiClient.WorkspaceAPI.StartWorkspace(ctx, workspace.Id).Execute() + } + if err != nil { stopLogs() return apiclient_util.HandleErrorResponse(res, err) diff --git a/pkg/jobs/workspace/restart.go b/pkg/jobs/workspace/restart.go index d2b5b884c7..ec4a907e51 100644 --- a/pkg/jobs/workspace/restart.go +++ b/pkg/jobs/workspace/restart.go @@ -9,7 +9,7 @@ import ( "github.com/daytonaio/daytona/pkg/models" ) -func (wj *WorkspaceJob) Restart(ctx context.Context, j *models.Job) error { +func (wj *WorkspaceJob) restart(ctx context.Context, j *models.Job) error { err := wj.stop(ctx, j) if err != nil { return err diff --git a/pkg/jobs/workspace/workspace.go b/pkg/jobs/workspace/workspace.go index 10e71da506..c85baad2c2 100644 --- a/pkg/jobs/workspace/workspace.go +++ b/pkg/jobs/workspace/workspace.go @@ -36,6 +36,8 @@ func (wj *WorkspaceJob) Execute(ctx context.Context) error { return wj.start(ctx, &wj.Job) case models.JobActionStop: return wj.stop(ctx, &wj.Job) + case models.JobActionRestart: + return wj.restart(ctx, &wj.Job) case models.JobActionDelete: return wj.delete(ctx, &wj.Job, false) case models.JobActionForceDelete: diff --git a/pkg/server/targets/restart.go b/pkg/server/targets/restart.go new file mode 100644 index 0000000000..865aed1cd1 --- /dev/null +++ b/pkg/server/targets/restart.go @@ -0,0 +1,48 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package targets + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" +) + +func (s *TargetService) Restart(ctx context.Context, targetId string) error { + target, err := s.targetStore.Find(ctx, &stores.TargetFilter{IdOrName: &targetId}) + if err != nil { + return s.handleRestartError(ctx, nil, stores.ErrTargetNotFound) + } + + if target.TargetConfig.ProviderInfo.AgentlessTarget { + return s.handleRestartError(ctx, target, services.ErrAgentlessTarget) + } + + err = s.createJob(ctx, target.Id, target.TargetConfig.ProviderInfo.RunnerId, models.JobActionRestart) + return s.handleRestartError(ctx, target, err) +} + +func (s *TargetService) handleRestartError(ctx context.Context, target *models.Target, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.TargetEventLifecycleRestarted + if err != nil { + eventName = telemetry.TargetEventLifecycleRestartFailed + } + event := telemetry.NewTargetEvent(eventName, target, err, nil) + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/server/workspaces/restart.go b/pkg/server/workspaces/restart.go new file mode 100644 index 0000000000..8f36500aa2 --- /dev/null +++ b/pkg/server/workspaces/restart.go @@ -0,0 +1,47 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/stores" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) Restart(ctx context.Context, workspaceId string) error { + w, err := s.workspaceStore.Find(ctx, workspaceId) + if err != nil { + return s.handleRestartError(ctx, w, stores.ErrWorkspaceNotFound) + } + + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionStart) + if err != nil { + return s.handleRestartError(ctx, w, err) + } + + return s.handleRestartError(ctx, w, err) +} + +func (s *WorkspaceService) handleRestartError(ctx context.Context, w *models.Workspace, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.WorkspaceEventLifecycleRestarted + if err != nil { + eventName = telemetry.WorkspaceEventLifecycleRestartFailed + } + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + return err +} diff --git a/pkg/services/target.go b/pkg/services/target.go index 2d66d0c7c8..9da6f644f0 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -19,6 +19,7 @@ type ITargetService interface { Save(ctx context.Context, target *models.Target) error Start(ctx context.Context, targetId string) error Stop(ctx context.Context, targetId string) error + Restart(ctx context.Context, targetId string) error SetDefault(ctx context.Context, targetId string) error Delete(ctx context.Context, targetId string) error ForceDelete(ctx context.Context, targetId string) error diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 5b24a5af23..a663aae7de 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -20,6 +20,7 @@ type IWorkspaceService interface { Stop(ctx context.Context, workspaceId string) error Delete(ctx context.Context, workspaceId string) error ForceDelete(ctx context.Context, workspaceId string) error + Restart(ctx context.Context, workspaceId string) error UpdateMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) UpdateProviderMetadata(ctx context.Context, workspaceId, metadata string) error From 5c477458f7fb7c5d1ff40c828b3cfc99b17f73b1 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Tue, 14 Jan 2025 15:08:46 +0000 Subject: [PATCH 53/76] fix: command naming Signed-off-by: Ivan Dagelic --- pkg/cmd/apikey/api_key.go | 2 +- pkg/cmd/apikey/create.go | 2 +- pkg/cmd/build/build.go | 10 +++++----- pkg/cmd/build/delete.go | 8 ++++---- pkg/cmd/build/info.go | 4 ++-- pkg/cmd/build/list.go | 4 ++-- pkg/cmd/build/logs.go | 4 ++-- pkg/cmd/build/run.go | 2 +- pkg/cmd/cmd.go | 2 +- pkg/cmd/gitprovider/create.go | 16 ++++++++-------- pkg/cmd/gitprovider/delete.go | 6 +++--- pkg/cmd/gitprovider/gitprovider.go | 8 ++++---- pkg/cmd/gitprovider/list.go | 4 ++-- pkg/cmd/gitprovider/update.go | 2 +- pkg/cmd/prebuild/create.go | 12 ++++++------ pkg/cmd/prebuild/delete.go | 4 ++-- pkg/cmd/prebuild/info.go | 4 ++-- pkg/cmd/prebuild/list.go | 4 ++-- pkg/cmd/prebuild/prebuild.go | 10 +++++----- pkg/cmd/prebuild/update.go | 12 ++++++------ pkg/cmd/profile/delete.go | 2 +- pkg/cmd/profile/list.go | 4 ++-- pkg/cmd/profile/profile.go | 6 +++--- pkg/cmd/profile/update.go | 8 ++++---- pkg/cmd/provider/install.go | 4 ++-- pkg/cmd/provider/list.go | 4 ++-- pkg/cmd/provider/provider.go | 8 ++++---- pkg/cmd/provider/uninstall.go | 2 +- pkg/cmd/provider/update.go | 4 ++-- pkg/cmd/workspacetemplate/delete.go | 8 ++++---- pkg/cmd/workspacetemplate/export.go | 6 +++--- pkg/cmd/workspacetemplate/import.go | 4 ++-- pkg/cmd/workspacetemplate/info.go | 4 ++-- pkg/cmd/workspacetemplate/list.go | 4 ++-- pkg/cmd/workspacetemplate/setdefault.go | 2 +- pkg/cmd/workspacetemplate/update.go | 2 +- pkg/cmd/workspacetemplate/workspacetemplate.go | 14 +++++++------- 37 files changed, 103 insertions(+), 103 deletions(-) diff --git a/pkg/cmd/apikey/api_key.go b/pkg/cmd/apikey/api_key.go index a1e49dc73f..8bbfb171ef 100644 --- a/pkg/cmd/apikey/api_key.go +++ b/pkg/cmd/apikey/api_key.go @@ -17,7 +17,7 @@ var ApiKeyCmd = &cobra.Command{ } func init() { - ApiKeyCmd.AddCommand(createApiKeyCmd) + ApiKeyCmd.AddCommand(createCmd) ApiKeyCmd.AddCommand(deleteCmd) ApiKeyCmd.AddCommand(listCmd) } diff --git a/pkg/cmd/apikey/create.go b/pkg/cmd/apikey/create.go index 46f19ce22d..65f66d9747 100644 --- a/pkg/cmd/apikey/create.go +++ b/pkg/cmd/apikey/create.go @@ -16,7 +16,7 @@ import ( view "github.com/daytonaio/daytona/pkg/views/apikey" ) -var createApiKeyCmd = &cobra.Command{ +var createCmd = &cobra.Command{ Use: "create [NAME]", Short: "Create a new API key", Args: cobra.RangeArgs(0, 1), diff --git a/pkg/cmd/build/build.go b/pkg/cmd/build/build.go index 5d12d3ffcf..03e9746348 100644 --- a/pkg/cmd/build/build.go +++ b/pkg/cmd/build/build.go @@ -17,9 +17,9 @@ var BuildCmd = &cobra.Command{ } func init() { - BuildCmd.AddCommand(buildListCmd) - BuildCmd.AddCommand(buildInfoCmd) - BuildCmd.AddCommand(buildRunCmd) - BuildCmd.AddCommand(buildDeleteCmd) - BuildCmd.AddCommand(buildLogsCmd) + BuildCmd.AddCommand(listCmd) + BuildCmd.AddCommand(infoCmd) + BuildCmd.AddCommand(runCmd) + BuildCmd.AddCommand(deleteCmd) + BuildCmd.AddCommand(logsCmd) } diff --git a/pkg/cmd/build/delete.go b/pkg/cmd/build/delete.go index 0815ce9d63..58c0fa1b1b 100644 --- a/pkg/cmd/build/delete.go +++ b/pkg/cmd/build/delete.go @@ -15,7 +15,7 @@ import ( "github.com/spf13/cobra" ) -var buildDeleteCmd = &cobra.Command{ +var deleteCmd = &cobra.Command{ Use: "delete [BUILD]", Short: "Delete a build", Args: cobra.RangeArgs(0, 1), @@ -83,7 +83,7 @@ var forceFlag bool var prebuildIdFlag string func init() { - buildDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete ALL builds") - buildDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete build") - buildDeleteCmd.Flags().StringVar(&prebuildIdFlag, "prebuild-id", "", "Delete ALL builds from prebuild") + deleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete ALL builds") + deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete build") + deleteCmd.Flags().StringVar(&prebuildIdFlag, "prebuild-id", "", "Delete ALL builds from prebuild") } diff --git a/pkg/cmd/build/info.go b/pkg/cmd/build/info.go index 51ca8b9c77..5cd3a0b137 100644 --- a/pkg/cmd/build/info.go +++ b/pkg/cmd/build/info.go @@ -17,7 +17,7 @@ import ( "github.com/spf13/cobra" ) -var buildInfoCmd = &cobra.Command{ +var infoCmd = &cobra.Command{ Use: "info [BUILD]", Short: "Show build info", Args: cobra.RangeArgs(0, 1), @@ -79,5 +79,5 @@ var buildInfoCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(buildInfoCmd) + format.RegisterFormatFlag(infoCmd) } diff --git a/pkg/cmd/build/list.go b/pkg/cmd/build/list.go index 039673eb3b..1850dc22b4 100644 --- a/pkg/cmd/build/list.go +++ b/pkg/cmd/build/list.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/cobra" ) -var buildListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "List all builds", Args: cobra.NoArgs, @@ -48,5 +48,5 @@ var buildListCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(buildListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/build/logs.go b/pkg/cmd/build/logs.go index dcc36c6817..dafe4c3828 100644 --- a/pkg/cmd/build/logs.go +++ b/pkg/cmd/build/logs.go @@ -16,7 +16,7 @@ import ( "github.com/spf13/cobra" ) -var buildLogsCmd = &cobra.Command{ +var logsCmd = &cobra.Command{ Use: "logs", Short: "View logs for build", Args: cobra.RangeArgs(0, 1), @@ -82,5 +82,5 @@ var buildLogsCmd = &cobra.Command{ var followFlag bool func init() { - buildLogsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") + logsCmd.Flags().BoolVarP(&followFlag, "follow", "f", false, "Follow logs") } diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index ffd0026650..771b3aeb41 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -18,7 +18,7 @@ import ( "github.com/spf13/cobra" ) -var buildRunCmd = &cobra.Command{ +var runCmd = &cobra.Command{ Use: "run", Short: "Run a build from a workspace template", Args: cobra.NoArgs, diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index f7b089b805..1efd518fa0 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -192,7 +192,7 @@ func RunInitialScreenFlow(cmd *cobra.Command, args []string) error { case "code": return CodeCmd.RunE(cmd, []string{}) case "git-provider create": - return GitProviderAddCmd.RunE(cmd, []string{}) + return GitProviderCreateCmd.RunE(cmd, []string{}) case "target-config create": return TargetConfigCreateCmd.RunE(cmd, []string{}) case "docs": diff --git a/pkg/cmd/gitprovider/create.go b/pkg/cmd/gitprovider/create.go index 9caf3edfde..1fc49bda97 100644 --- a/pkg/cmd/gitprovider/create.go +++ b/pkg/cmd/gitprovider/create.go @@ -19,7 +19,7 @@ import ( "github.com/spf13/cobra" ) -var GitProviderAddCmd = &cobra.Command{ +var GitProviderCreateCmd = &cobra.Command{ Use: "create [GIT_PROVIDER_ID]", Short: "Create a Git provider config", Aliases: common.GetAliases("create"), @@ -149,11 +149,11 @@ var signingMethodFlag string var signingKeyFlag string func init() { - GitProviderAddCmd.Flags().StringVarP(&aliasFlag, "alias", "a", "", "Alias") - GitProviderAddCmd.Flags().StringVarP(&usernameFlag, "username", "u", "", "Username") - GitProviderAddCmd.Flags().StringVarP(&baseApiUrlFlag, "base-api-url", "b", "", "Base API Url") - GitProviderAddCmd.Flags().StringVarP(&tokenFlag, "token", "t", "", "Personal Access Token") - GitProviderAddCmd.Flags().StringVarP(&signingMethodFlag, "signing-method", "s", "", "Signing Method (ssh, gpg)") - GitProviderAddCmd.Flags().StringVarP(&signingKeyFlag, "signing-key", "k", "", "Signing Key") - GitProviderAddCmd.MarkFlagsRequiredTogether("signing-method", "signing-key") + GitProviderCreateCmd.Flags().StringVarP(&aliasFlag, "alias", "a", "", "Alias") + GitProviderCreateCmd.Flags().StringVarP(&usernameFlag, "username", "u", "", "Username") + GitProviderCreateCmd.Flags().StringVarP(&baseApiUrlFlag, "base-api-url", "b", "", "Base API Url") + GitProviderCreateCmd.Flags().StringVarP(&tokenFlag, "token", "t", "", "Personal Access Token") + GitProviderCreateCmd.Flags().StringVarP(&signingMethodFlag, "signing-method", "s", "", "Signing Method (ssh, gpg)") + GitProviderCreateCmd.Flags().StringVarP(&signingKeyFlag, "signing-key", "k", "", "Signing Key") + GitProviderCreateCmd.MarkFlagsRequiredTogether("signing-method", "signing-key") } diff --git a/pkg/cmd/gitprovider/delete.go b/pkg/cmd/gitprovider/delete.go index ca69c877aa..d1179ff357 100644 --- a/pkg/cmd/gitprovider/delete.go +++ b/pkg/cmd/gitprovider/delete.go @@ -17,7 +17,7 @@ import ( "github.com/spf13/cobra" ) -var gitProviderDeleteCmd = &cobra.Command{ +var deleteCmd = &cobra.Command{ Use: "delete", Short: "Delete a Git provider config", Aliases: common.GetAliases("delete"), @@ -117,8 +117,8 @@ var allFlag bool var yesFlag bool func init() { - gitProviderDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all Git providers") - gitProviderDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + deleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all Git providers") + deleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") } func deleteAllGitProviders(gitProviders []apiclient.GitProvider, apiClient *apiclient.APIClient) error { diff --git a/pkg/cmd/gitprovider/gitprovider.go b/pkg/cmd/gitprovider/gitprovider.go index 6433df5b83..1a518016db 100644 --- a/pkg/cmd/gitprovider/gitprovider.go +++ b/pkg/cmd/gitprovider/gitprovider.go @@ -17,8 +17,8 @@ var GitProviderCmd = &cobra.Command{ } func init() { - GitProviderCmd.AddCommand(GitProviderAddCmd) - GitProviderCmd.AddCommand(gitProviderUpdateCmd) - GitProviderCmd.AddCommand(gitProviderDeleteCmd) - GitProviderCmd.AddCommand(gitProviderListCmd) + GitProviderCmd.AddCommand(GitProviderCreateCmd) + GitProviderCmd.AddCommand(updateCmd) + GitProviderCmd.AddCommand(deleteCmd) + GitProviderCmd.AddCommand(listCmd) } diff --git a/pkg/cmd/gitprovider/list.go b/pkg/cmd/gitprovider/list.go index 3d5a6d8eea..5984e09fb2 100644 --- a/pkg/cmd/gitprovider/list.go +++ b/pkg/cmd/gitprovider/list.go @@ -15,7 +15,7 @@ import ( "github.com/spf13/cobra" ) -var gitProviderListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "Lists your registered Git provider configs", Aliases: common.GetAliases("list"), @@ -69,5 +69,5 @@ var gitProviderListCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(gitProviderListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/gitprovider/update.go b/pkg/cmd/gitprovider/update.go index 680cb0e2a5..99ddf2aea3 100644 --- a/pkg/cmd/gitprovider/update.go +++ b/pkg/cmd/gitprovider/update.go @@ -17,7 +17,7 @@ import ( "github.com/spf13/cobra" ) -var gitProviderUpdateCmd = &cobra.Command{ +var updateCmd = &cobra.Command{ Use: "update", Short: "Update a Git provider", Aliases: common.GetAliases("update"), diff --git a/pkg/cmd/prebuild/create.go b/pkg/cmd/prebuild/create.go index 80bb4c6fad..937959a51e 100644 --- a/pkg/cmd/prebuild/create.go +++ b/pkg/cmd/prebuild/create.go @@ -22,7 +22,7 @@ import ( "github.com/spf13/cobra" ) -var prebuildAddCmd = &cobra.Command{ +var addCmd = &cobra.Command{ Use: "create [WORKSPACE_CONFIG]", Short: "Create a prebuild configuration", Args: cobra.MaximumNArgs(1), @@ -179,9 +179,9 @@ var prebuildAddCmd = &cobra.Command{ } func init() { - prebuildAddCmd.Flags().BoolVar(&runFlag, "run", false, "Run the prebuild once after adding it") - prebuildAddCmd.Flags().StringVarP(&branchFlag, "branch", "b", "", "Git branch for the prebuild") - prebuildAddCmd.Flags().IntVarP(&retentionFlag, "retention", "r", 0, "Maximum number of resulting builds stored at a time") - prebuildAddCmd.Flags().IntVarP(&commitIntervalFlag, "commit-interval", "c", 0, "Commit interval for running a prebuild - leave blank to ignore push events") - prebuildAddCmd.Flags().StringSliceVarP(&triggerFilesFlag, "trigger-files", "t", nil, "Full paths of files whose changes should explicitly trigger a prebuild") + addCmd.Flags().BoolVar(&runFlag, "run", false, "Run the prebuild once after adding it") + addCmd.Flags().StringVarP(&branchFlag, "branch", "b", "", "Git branch for the prebuild") + addCmd.Flags().IntVarP(&retentionFlag, "retention", "r", 0, "Maximum number of resulting builds stored at a time") + addCmd.Flags().IntVarP(&commitIntervalFlag, "commit-interval", "c", 0, "Commit interval for running a prebuild - leave blank to ignore push events") + addCmd.Flags().StringSliceVarP(&triggerFilesFlag, "trigger-files", "t", nil, "Full paths of files whose changes should explicitly trigger a prebuild") } diff --git a/pkg/cmd/prebuild/delete.go b/pkg/cmd/prebuild/delete.go index e70e983ec7..270d2b022b 100644 --- a/pkg/cmd/prebuild/delete.go +++ b/pkg/cmd/prebuild/delete.go @@ -18,7 +18,7 @@ import ( var forceFlag bool -var prebuildDeleteCmd = &cobra.Command{ +var deleteCmd = &cobra.Command{ Use: "delete [WORKSPACE_CONFIG] [PREBUILD]", Short: "Delete a prebuild configuration", Args: cobra.MaximumNArgs(2), @@ -78,5 +78,5 @@ var prebuildDeleteCmd = &cobra.Command{ } func init() { - prebuildDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") + deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") } diff --git a/pkg/cmd/prebuild/info.go b/pkg/cmd/prebuild/info.go index 1de0350c18..d7b368718d 100644 --- a/pkg/cmd/prebuild/info.go +++ b/pkg/cmd/prebuild/info.go @@ -17,7 +17,7 @@ import ( "github.com/spf13/cobra" ) -var prebuildInfoCmd = &cobra.Command{ +var infoCmd = &cobra.Command{ Use: "info", Short: "Show prebuild configuration info", Args: cobra.MaximumNArgs(2), @@ -86,5 +86,5 @@ var prebuildInfoCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(prebuildInfoCmd) + format.RegisterFormatFlag(infoCmd) } diff --git a/pkg/cmd/prebuild/list.go b/pkg/cmd/prebuild/list.go index 2724be745b..8e66d6b0a0 100644 --- a/pkg/cmd/prebuild/list.go +++ b/pkg/cmd/prebuild/list.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/cobra" ) -var prebuildListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "List prebuild configurations", Args: cobra.NoArgs, @@ -43,5 +43,5 @@ var prebuildListCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(prebuildListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/prebuild/prebuild.go b/pkg/cmd/prebuild/prebuild.go index f18ac3aacb..53b2dfbd20 100644 --- a/pkg/cmd/prebuild/prebuild.go +++ b/pkg/cmd/prebuild/prebuild.go @@ -17,9 +17,9 @@ var PrebuildCmd = &cobra.Command{ } func init() { - PrebuildCmd.AddCommand(prebuildAddCmd) - PrebuildCmd.AddCommand(prebuildListCmd) - PrebuildCmd.AddCommand(prebuildInfoCmd) - PrebuildCmd.AddCommand(prebuildUpdateCmd) - PrebuildCmd.AddCommand(prebuildDeleteCmd) + PrebuildCmd.AddCommand(addCmd) + PrebuildCmd.AddCommand(listCmd) + PrebuildCmd.AddCommand(infoCmd) + PrebuildCmd.AddCommand(updateCmd) + PrebuildCmd.AddCommand(deleteCmd) } diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index 00dc0b9c98..4d8069893a 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -20,7 +20,7 @@ import ( "github.com/spf13/cobra" ) -var prebuildUpdateCmd = &cobra.Command{ +var updateCmd = &cobra.Command{ Use: "update [WORKSPACE_CONFIG] [PREBUILD_ID]", Short: "Update a prebuild configuration", Args: cobra.MaximumNArgs(2), @@ -191,9 +191,9 @@ var ( ) func init() { - prebuildUpdateCmd.Flags().StringVarP(&branchFlag, "branch", "b", "", "Git branch for the prebuild") - prebuildUpdateCmd.Flags().IntVarP(&retentionFlag, "retention", "r", 0, "Maximum number of resulting builds stored at a time") - prebuildUpdateCmd.Flags().IntVarP(&commitIntervalFlag, "commit-interval", "c", 0, "Commit interval for running a prebuild - leave blank to ignore push events") - prebuildUpdateCmd.Flags().StringSliceVarP(&triggerFilesFlag, "trigger-files", "t", nil, "Full paths of files whose changes should explicitly trigger a prebuild") - prebuildUpdateCmd.Flags().BoolVar(&runFlag, "run", false, "Run the prebuild once after updating it") + updateCmd.Flags().StringVarP(&branchFlag, "branch", "b", "", "Git branch for the prebuild") + updateCmd.Flags().IntVarP(&retentionFlag, "retention", "r", 0, "Maximum number of resulting builds stored at a time") + updateCmd.Flags().IntVarP(&commitIntervalFlag, "commit-interval", "c", 0, "Commit interval for running a prebuild - leave blank to ignore push events") + updateCmd.Flags().StringSliceVarP(&triggerFilesFlag, "trigger-files", "t", nil, "Full paths of files whose changes should explicitly trigger a prebuild") + updateCmd.Flags().BoolVar(&runFlag, "run", false, "Run the prebuild once after updating it") } diff --git a/pkg/cmd/profile/delete.go b/pkg/cmd/profile/delete.go index 800e255aa5..252039b6ec 100644 --- a/pkg/cmd/profile/delete.go +++ b/pkg/cmd/profile/delete.go @@ -14,7 +14,7 @@ import ( "github.com/spf13/cobra" ) -var profileDeleteCmd = &cobra.Command{ +var deleteCmd = &cobra.Command{ Use: "delete [PROFILE_NAME]", Short: "Delete a profile", Args: cobra.RangeArgs(0, 1), diff --git a/pkg/cmd/profile/list.go b/pkg/cmd/profile/list.go index bf28331306..6498fb87e9 100644 --- a/pkg/cmd/profile/list.go +++ b/pkg/cmd/profile/list.go @@ -14,7 +14,7 @@ import ( "github.com/spf13/cobra" ) -var profileListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "List profiles", Aliases: common.GetAliases("list"), @@ -45,5 +45,5 @@ var profileListCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(profileListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/profile/profile.go b/pkg/cmd/profile/profile.go index d072d3f407..1f1ce2623b 100644 --- a/pkg/cmd/profile/profile.go +++ b/pkg/cmd/profile/profile.go @@ -18,9 +18,9 @@ var ProfileCmd = &cobra.Command{ func init() { ProfileCmd.AddGroup(&cobra.Group{ID: util.PROFILE_GROUP, Title: "Profile"}) - ProfileCmd.AddCommand(profileListCmd) + ProfileCmd.AddCommand(listCmd) ProfileCmd.AddCommand(ProfileUseCmd) ProfileCmd.AddCommand(ProfileAddCmd) - ProfileCmd.AddCommand(profileUpdateCmd) - ProfileCmd.AddCommand(profileDeleteCmd) + ProfileCmd.AddCommand(updateCmd) + ProfileCmd.AddCommand(deleteCmd) } diff --git a/pkg/cmd/profile/update.go b/pkg/cmd/profile/update.go index b19be1f54a..4902324fda 100644 --- a/pkg/cmd/profile/update.go +++ b/pkg/cmd/profile/update.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/cobra" ) -var profileUpdateCmd = &cobra.Command{ +var updateCmd = &cobra.Command{ Use: "update", Short: "Update profile [PROFILE_NAME]", Args: cobra.RangeArgs(0, 1), @@ -113,7 +113,7 @@ func editProfile(profileToEdit *config.Profile, profileView profile.ProfileAddVi } func init() { - profileUpdateCmd.Flags().StringVarP(&profileNameFlag, "name", "n", "", "Profile name") - profileUpdateCmd.Flags().StringVarP(&apiUrlFlag, "api-url", "a", "", "API URL") - profileUpdateCmd.Flags().StringVarP(&apiKeyFlag, "api-key", "k", "", "API Key") + updateCmd.Flags().StringVarP(&profileNameFlag, "name", "n", "", "Profile name") + updateCmd.Flags().StringVarP(&apiUrlFlag, "api-url", "a", "", "API URL") + updateCmd.Flags().StringVarP(&apiKeyFlag, "api-key", "k", "", "API Key") } diff --git a/pkg/cmd/provider/install.go b/pkg/cmd/provider/install.go index 02fe892b45..a17fa26d6b 100644 --- a/pkg/cmd/provider/install.go +++ b/pkg/cmd/provider/install.go @@ -23,7 +23,7 @@ import ( var yesFlag bool -var providerInstallCmd = &cobra.Command{ +var installCmd = &cobra.Command{ Use: "install", Short: "Install provider", Args: cobra.MaximumNArgs(1), @@ -116,7 +116,7 @@ var providerInstallCmd = &cobra.Command{ } func init() { - providerInstallCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") + installCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Automatically confirm any prompts") } func InstallProvider(apiClient *apiclient.APIClient, runnerId string, providerToInstall provider.ProviderView, providersManifest *util.ProvidersManifest) error { diff --git a/pkg/cmd/provider/list.go b/pkg/cmd/provider/list.go index a2e3c30718..70f73fbca1 100644 --- a/pkg/cmd/provider/list.go +++ b/pkg/cmd/provider/list.go @@ -15,7 +15,7 @@ import ( "github.com/spf13/cobra" ) -var providerListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "List installed providers", Args: cobra.NoArgs, @@ -89,5 +89,5 @@ func GetProviderViewOptions(ctx context.Context, apiClient *apiclient.APIClient, } func init() { - format.RegisterFormatFlag(providerListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/provider/provider.go b/pkg/cmd/provider/provider.go index 5e9bf16ef0..552c91f4db 100644 --- a/pkg/cmd/provider/provider.go +++ b/pkg/cmd/provider/provider.go @@ -17,8 +17,8 @@ var ProviderCmd = &cobra.Command{ } func init() { - ProviderCmd.AddCommand(providerListCmd) - ProviderCmd.AddCommand(providerUninstallCmd) - ProviderCmd.AddCommand(providerInstallCmd) - ProviderCmd.AddCommand(providerUpdateCmd) + ProviderCmd.AddCommand(listCmd) + ProviderCmd.AddCommand(uninstallCmd) + ProviderCmd.AddCommand(installCmd) + ProviderCmd.AddCommand(updateCmd) } diff --git a/pkg/cmd/provider/uninstall.go b/pkg/cmd/provider/uninstall.go index f884b78fd5..fd2ca8b343 100644 --- a/pkg/cmd/provider/uninstall.go +++ b/pkg/cmd/provider/uninstall.go @@ -16,7 +16,7 @@ import ( "github.com/spf13/cobra" ) -var providerUninstallCmd = &cobra.Command{ +var uninstallCmd = &cobra.Command{ Use: "uninstall", Short: "Uninstall provider", Args: cobra.NoArgs, diff --git a/pkg/cmd/provider/update.go b/pkg/cmd/provider/update.go index 094a9718be..34f2869502 100644 --- a/pkg/cmd/provider/update.go +++ b/pkg/cmd/provider/update.go @@ -20,7 +20,7 @@ import ( var allFlag bool -var providerUpdateCmd = &cobra.Command{ +var updateCmd = &cobra.Command{ Use: "update", Short: "Update provider", Args: cobra.NoArgs, @@ -138,5 +138,5 @@ func updateProvider(runnerId string, providerName string, providersManifest *uti } func init() { - providerUpdateCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Update all providers") + updateCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Update all providers") } diff --git a/pkg/cmd/workspacetemplate/delete.go b/pkg/cmd/workspacetemplate/delete.go index 08a4b03ce1..d68a1c89f7 100644 --- a/pkg/cmd/workspacetemplate/delete.go +++ b/pkg/cmd/workspacetemplate/delete.go @@ -22,7 +22,7 @@ var allFlag bool var yesFlag bool var forceFlag bool -var workspaceTemplateDeleteCmd = &cobra.Command{ +var deleteCmd = &cobra.Command{ Use: "delete", Short: "Delete a workspace template", Args: cobra.MaximumNArgs(1), @@ -111,7 +111,7 @@ var workspaceTemplateDeleteCmd = &cobra.Command{ } func init() { - workspaceTemplateDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspace templates") - workspaceTemplateDeleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") - workspaceTemplateDeleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") + deleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all workspace templates") + deleteCmd.Flags().BoolVarP(&yesFlag, "yes", "y", false, "Confirm deletion without prompt") + deleteCmd.Flags().BoolVarP(&forceFlag, "force", "f", false, "Force delete prebuild") } diff --git a/pkg/cmd/workspacetemplate/export.go b/pkg/cmd/workspacetemplate/export.go index 306a881204..45671eb415 100644 --- a/pkg/cmd/workspacetemplate/export.go +++ b/pkg/cmd/workspacetemplate/export.go @@ -19,7 +19,7 @@ import ( "github.com/spf13/cobra" ) -var workspaceTemplateExportCmd = &cobra.Command{ +var exportCmd = &cobra.Command{ Use: "export", Aliases: []string{"exp"}, Short: "Export a workspace template", @@ -83,8 +83,8 @@ var workspaceTemplateExportCmd = &cobra.Command{ } func init() { - workspaceTemplateExportCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Export all workspace templates") - format.RegisterFormatFlag(workspaceTemplateExportCmd) + exportCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Export all workspace templates") + format.RegisterFormatFlag(exportCmd) } func exportWorkspaceTemplates(workspaceConfigs []apiclient.WorkspaceTemplate) error { diff --git a/pkg/cmd/workspacetemplate/import.go b/pkg/cmd/workspacetemplate/import.go index 5686102c32..fdab069469 100644 --- a/pkg/cmd/workspacetemplate/import.go +++ b/pkg/cmd/workspacetemplate/import.go @@ -24,7 +24,7 @@ import ( var filePath string -var workspaceTemplateImportCmd = &cobra.Command{ +var importCmd = &cobra.Command{ Use: "import", Aliases: []string{"imp"}, Short: "Import workspace template from JSON", @@ -100,7 +100,7 @@ var workspaceTemplateImportCmd = &cobra.Command{ } func init() { - workspaceTemplateImportCmd.Flags().StringVarP(&filePath, "file", "f", "", "Import workspace template from a JSON file. Use '-' to read from stdin.") + importCmd.Flags().StringVarP(&filePath, "file", "f", "", "Import workspace template from a JSON file. Use '-' to read from stdin.") } func isWorkspaceTemplateAlreadyExists(configName string, workspaceConfigList *[]apiclient.WorkspaceTemplate) bool { diff --git a/pkg/cmd/workspacetemplate/info.go b/pkg/cmd/workspacetemplate/info.go index a19b2beb76..b1aa9ee6b0 100644 --- a/pkg/cmd/workspacetemplate/info.go +++ b/pkg/cmd/workspacetemplate/info.go @@ -17,7 +17,7 @@ import ( "github.com/spf13/cobra" ) -var workspaceTemplateInfoCmd = &cobra.Command{ +var infoCmd = &cobra.Command{ Use: "info", Short: "Show workspace template info", Aliases: cmd_common.GetAliases("info"), @@ -81,5 +81,5 @@ var workspaceTemplateInfoCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(workspaceTemplateInfoCmd) + format.RegisterFormatFlag(infoCmd) } diff --git a/pkg/cmd/workspacetemplate/list.go b/pkg/cmd/workspacetemplate/list.go index ec0489cdab..9ce0304167 100644 --- a/pkg/cmd/workspacetemplate/list.go +++ b/pkg/cmd/workspacetemplate/list.go @@ -13,7 +13,7 @@ import ( "github.com/spf13/cobra" ) -var workspaceTemplateListCmd = &cobra.Command{ +var listCmd = &cobra.Command{ Use: "list", Short: "Lists workspace templates", Args: cobra.NoArgs, @@ -58,5 +58,5 @@ var workspaceTemplateListCmd = &cobra.Command{ } func init() { - format.RegisterFormatFlag(workspaceTemplateListCmd) + format.RegisterFormatFlag(listCmd) } diff --git a/pkg/cmd/workspacetemplate/setdefault.go b/pkg/cmd/workspacetemplate/setdefault.go index 22b7fdc1fa..882bcb568b 100644 --- a/pkg/cmd/workspacetemplate/setdefault.go +++ b/pkg/cmd/workspacetemplate/setdefault.go @@ -15,7 +15,7 @@ import ( "github.com/spf13/cobra" ) -var workspaceTemplateSetDefaultCmd = &cobra.Command{ +var setDefaultCmd = &cobra.Command{ Use: "set-default", Short: "Set workspace template info", Args: cobra.MaximumNArgs(1), diff --git a/pkg/cmd/workspacetemplate/update.go b/pkg/cmd/workspacetemplate/update.go index 42aa518292..25fb6eaf87 100644 --- a/pkg/cmd/workspacetemplate/update.go +++ b/pkg/cmd/workspacetemplate/update.go @@ -18,7 +18,7 @@ import ( "github.com/spf13/cobra" ) -var workspaceTemplateUpdateCmd = &cobra.Command{ +var updateCmd = &cobra.Command{ Use: "update", Short: "Update a workspace template", Args: cobra.MaximumNArgs(1), diff --git a/pkg/cmd/workspacetemplate/workspacetemplate.go b/pkg/cmd/workspacetemplate/workspacetemplate.go index 728f946655..2de572803d 100644 --- a/pkg/cmd/workspacetemplate/workspacetemplate.go +++ b/pkg/cmd/workspacetemplate/workspacetemplate.go @@ -17,12 +17,12 @@ var WorkspaceTemplateCmd = &cobra.Command{ } func init() { - WorkspaceTemplateCmd.AddCommand(workspaceTemplateListCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateInfoCmd) + WorkspaceTemplateCmd.AddCommand(listCmd) + WorkspaceTemplateCmd.AddCommand(infoCmd) WorkspaceTemplateCmd.AddCommand(createCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateUpdateCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateSetDefaultCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateDeleteCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateExportCmd) - WorkspaceTemplateCmd.AddCommand(workspaceTemplateImportCmd) + WorkspaceTemplateCmd.AddCommand(updateCmd) + WorkspaceTemplateCmd.AddCommand(setDefaultCmd) + WorkspaceTemplateCmd.AddCommand(deleteCmd) + WorkspaceTemplateCmd.AddCommand(exportCmd) + WorkspaceTemplateCmd.AddCommand(importCmd) } From f624bb483452cca5bffecae42e4892aa579020cb Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Tue, 14 Jan 2025 15:11:09 +0000 Subject: [PATCH 54/76] fix: local docker target check Signed-off-by: Toma Puljak --- pkg/api/controllers/workspace/toolbox/toolbox.go | 2 +- pkg/docker/create_image.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/api/controllers/workspace/toolbox/toolbox.go b/pkg/api/controllers/workspace/toolbox/toolbox.go index 9d347e4a58..3c3cbcacf5 100644 --- a/pkg/api/controllers/workspace/toolbox/toolbox.go +++ b/pkg/api/controllers/workspace/toolbox/toolbox.go @@ -77,7 +77,7 @@ func forwardRequestToToolbox(ctx *gin.Context) { }, } - if w.TargetId == "local" && w.ProviderMetadata != nil && *w.ProviderMetadata != "" { + if common.IsLocalDockerTarget(w.Target.TargetConfig.ProviderInfo.Name, w.Target.TargetConfig.Options, w.Target.TargetConfig.ProviderInfo.RunnerId) && w.ProviderMetadata != nil && *w.ProviderMetadata != "" { var metadata map[string]interface{} err := json.Unmarshal([]byte(*w.ProviderMetadata), &metadata) if err == nil { diff --git a/pkg/docker/create_image.go b/pkg/docker/create_image.go index c000f5c8cb..6bc1170570 100644 --- a/pkg/docker/create_image.go +++ b/pkg/docker/create_image.go @@ -9,6 +9,7 @@ import ( "runtime" "time" + "github.com/daytonaio/daytona/pkg/common" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/ports" "github.com/docker/docker/api/types/container" @@ -49,7 +50,7 @@ func (d *DockerClient) initWorkspaceContainer(opts *CreateWorkspaceOptions, moun var availablePort *uint16 var portBindings map[nat.Port][]nat.PortBinding - if opts.Workspace.TargetId == "local" { + if common.IsLocalDockerTarget(opts.Workspace.Target.TargetConfig.ProviderInfo.Name, opts.Workspace.Target.TargetConfig.Options, opts.Workspace.Target.TargetConfig.ProviderInfo.RunnerId) { p, err := ports.GetAvailableEphemeralPort() if err != nil { log.Error(err) From 48b6d89ded227eadd2dd064fd408bfb181dfed73 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Tue, 14 Jan 2025 15:20:19 +0000 Subject: [PATCH 55/76] fix: sigkill on workspace stop Signed-off-by: Toma Puljak --- pkg/docker/stop.go | 8 ++++++-- pkg/server/workspaces/restart.go | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkg/docker/stop.go b/pkg/docker/stop.go index 1ac1c0236f..a372faacab 100644 --- a/pkg/docker/stop.go +++ b/pkg/docker/stop.go @@ -23,7 +23,9 @@ func (d *DockerClient) stopWorkspaceContainer(w *models.Workspace, logWriter io. containerName := d.GetWorkspaceContainerName(w) ctx := context.Background() - err := d.apiClient.ContainerStop(ctx, containerName, container.StopOptions{}) + err := d.apiClient.ContainerStop(ctx, containerName, container.StopOptions{ + Signal: "SIGKILL", + }) if err != nil { return err } @@ -59,7 +61,9 @@ func (d *DockerClient) stopWorkspaceContainer(w *models.Workspace, logWriter io. } for _, c := range composeContainers { - err = d.apiClient.ContainerStop(ctx, c.ID, container.StopOptions{}) + err = d.apiClient.ContainerStop(ctx, c.ID, container.StopOptions{ + Signal: "SIGKILL", + }) if err != nil { return err } diff --git a/pkg/server/workspaces/restart.go b/pkg/server/workspaces/restart.go index 8f36500aa2..9a114a0cb9 100644 --- a/pkg/server/workspaces/restart.go +++ b/pkg/server/workspaces/restart.go @@ -18,7 +18,7 @@ func (s *WorkspaceService) Restart(ctx context.Context, workspaceId string) erro return s.handleRestartError(ctx, w, stores.ErrWorkspaceNotFound) } - err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionStart) + err = s.createJob(ctx, w.Id, w.Target.TargetConfig.ProviderInfo.RunnerId, models.JobActionRestart) if err != nil { return s.handleRestartError(ctx, w, err) } From 9e822d937bc8fc12235151c3b067b3c0a42d9854 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Tue, 14 Jan 2025 16:50:32 +0000 Subject: [PATCH 56/76] fix: template import export and cli docs Signed-off-by: Ivan Dagelic --- docs/daytona.md | 1 + docs/daytona_code.md | 2 +- docs/daytona_create.md | 2 +- docs/daytona_git-provider_create.md | 13 ++- docs/daytona_project-config_export.md | 25 ----- docs/daytona_project-config_import.md | 24 ----- docs/daytona_ssh.md | 1 + docs/daytona_target-config_create.md | 6 ++ docs/daytona_template.md | 2 + docs/daytona_template_export.md | 25 +++++ docs/daytona_template_import.md | 24 +++++ hack/docs/daytona.yaml | 1 + hack/docs/daytona_code.yaml | 2 +- hack/docs/daytona_create.yaml | 2 +- hack/docs/daytona_git-provider_create.yaml | 21 +++- hack/docs/daytona_project-config_import.yaml | 14 --- hack/docs/daytona_ssh.yaml | 4 + hack/docs/daytona_target-config_create.yaml | 5 + hack/docs/daytona_template.yaml | 2 + ...port.yaml => daytona_template_export.yaml} | 10 +- hack/docs/daytona_template_import.yaml | 14 +++ pkg/cmd/workspacetemplate/export.go | 62 +++++------- pkg/cmd/workspacetemplate/import.go | 97 +++++++++---------- 23 files changed, 200 insertions(+), 159 deletions(-) delete mode 100644 docs/daytona_project-config_export.md delete mode 100644 docs/daytona_project-config_import.md create mode 100644 docs/daytona_template_export.md create mode 100644 docs/daytona_template_import.md delete mode 100644 hack/docs/daytona_project-config_import.yaml rename hack/docs/{daytona_project-config_export.yaml => daytona_template_export.yaml} (56%) create mode 100644 hack/docs/daytona_template_import.yaml diff --git a/docs/daytona.md b/docs/daytona.md index 462a56ac4d..2b85864fb7 100644 --- a/docs/daytona.md +++ b/docs/daytona.md @@ -49,6 +49,7 @@ daytona [flags] * [daytona target-config](daytona_target-config.md) - Manage target configs * [daytona telemetry](daytona_telemetry.md) - Manage telemetry collection * [daytona template](daytona_template.md) - Manage workspace templates +* [daytona update](daytona_update.md) - Update Daytona CLI * [daytona use](daytona_use.md) - Use profile [PROFILE_NAME] * [daytona version](daytona_version.md) - Print the version number * [daytona whoami](daytona_whoami.md) - Display information about the active user diff --git a/docs/daytona_code.md b/docs/daytona_code.md index 2f3bb7273f..1ccd206fa4 100644 --- a/docs/daytona_code.md +++ b/docs/daytona_code.md @@ -9,7 +9,7 @@ daytona code [WORKSPACE] [flags] ### Options ``` - -i, --ide string Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + -i, --ide string Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) -y, --yes Automatically confirm any prompts ``` diff --git a/docs/daytona_create.md b/docs/daytona_create.md index b5b0c57083..2404df206e 100644 --- a/docs/daytona_create.md +++ b/docs/daytona_create.md @@ -17,7 +17,7 @@ daytona create [REPOSITORY_URL | WORKSPACE_CONFIG_NAME]... [flags] --devcontainer-path string Automatically assign the devcontainer builder with the path passed as the flag value --env stringArray Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...') --git-provider-config string Specify the Git provider configuration ID or alias - -i, --ide string Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + -i, --ide string Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) --manual Manually enter the Git repository --multi-workspace Target with multiple workspaces/repos -n, --no-ide Do not open the target in the IDE after target creation diff --git a/docs/daytona_git-provider_create.md b/docs/daytona_git-provider_create.md index 22ef3fc907..6e0e1c827c 100644 --- a/docs/daytona_git-provider_create.md +++ b/docs/daytona_git-provider_create.md @@ -3,7 +3,18 @@ Create a Git provider config ``` -daytona git-provider create [flags] +daytona git-provider create [GIT_PROVIDER_ID] [flags] +``` + +### Options + +``` + -a, --alias string Alias + -b, --base-api-url string Base API Url + -k, --signing-key string Signing Key + -s, --signing-method string Signing Method (ssh, gpg) + -t, --token string Personal Access Token + -u, --username string Username ``` ### Options inherited from parent commands diff --git a/docs/daytona_project-config_export.md b/docs/daytona_project-config_export.md deleted file mode 100644 index 312d85811a..0000000000 --- a/docs/daytona_project-config_export.md +++ /dev/null @@ -1,25 +0,0 @@ -## daytona project-config export - -Export a project config - -``` -daytona project-config export [flags] -``` - -### Options - -``` - -a, --all Export all project configs - -f, --format string Output format. Must be one of (yaml, json) -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_project-config_import.md b/docs/daytona_project-config_import.md deleted file mode 100644 index 89e0cbfd31..0000000000 --- a/docs/daytona_project-config_import.md +++ /dev/null @@ -1,24 +0,0 @@ -## daytona project-config import - -Import project config from JSON - -``` -daytona project-config import [flags] -``` - -### Options - -``` - -f, --file string Import project config from a JSON file. Use '-' to read from stdin. -``` - -### Options inherited from parent commands - -``` - --help help for daytona -``` - -### SEE ALSO - -* [daytona project-config](daytona_project-config.md) - Manage project configs - diff --git a/docs/daytona_ssh.md b/docs/daytona_ssh.md index 8864a7060e..653eefb918 100644 --- a/docs/daytona_ssh.md +++ b/docs/daytona_ssh.md @@ -9,6 +9,7 @@ daytona ssh [WORKSPACE] [CMD...] [flags] ### Options ``` + -e, --edit Edit the workspace's SSH config -o, --option stringArray Specify SSH options in KEY=VALUE format. -y, --yes Automatically confirm any prompts ``` diff --git a/docs/daytona_target-config_create.md b/docs/daytona_target-config_create.md index 5923b56944..3b621e7078 100644 --- a/docs/daytona_target-config_create.md +++ b/docs/daytona_target-config_create.md @@ -6,6 +6,12 @@ Create target config daytona target-config create [flags] ``` +### Options + +``` + -f, --file string Path to JSON file for target configuration, use '-' to read from stdin +``` + ### Options inherited from parent commands ``` diff --git a/docs/daytona_template.md b/docs/daytona_template.md index 3d5dfc02b7..355d11cb70 100644 --- a/docs/daytona_template.md +++ b/docs/daytona_template.md @@ -13,6 +13,8 @@ Manage workspace templates * [daytona](daytona.md) - Daytona is a Dev Environment Manager * [daytona template create](daytona_template_create.md) - Create a workspace template * [daytona template delete](daytona_template_delete.md) - Delete a workspace template +* [daytona template export](daytona_template_export.md) - Export a workspace template +* [daytona template import](daytona_template_import.md) - Import a workspace template from a JSON object * [daytona template info](daytona_template_info.md) - Show workspace template info * [daytona template list](daytona_template_list.md) - Lists workspace templates * [daytona template set-default](daytona_template_set-default.md) - Set workspace template info diff --git a/docs/daytona_template_export.md b/docs/daytona_template_export.md new file mode 100644 index 0000000000..3ea35d78fe --- /dev/null +++ b/docs/daytona_template_export.md @@ -0,0 +1,25 @@ +## daytona template export + +Export a workspace template + +``` +daytona template export [flags] +``` + +### Options + +``` + -a, --all Export all workspace templates + -f, --format string Output format. Must be one of (yaml, json) +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona template](daytona_template.md) - Manage workspace templates + diff --git a/docs/daytona_template_import.md b/docs/daytona_template_import.md new file mode 100644 index 0000000000..25a8a3d495 --- /dev/null +++ b/docs/daytona_template_import.md @@ -0,0 +1,24 @@ +## daytona template import + +Import a workspace template from a JSON object + +``` +daytona template import [flags] +``` + +### Options + +``` + -f, --file string Import workspace template from a JSON file. Use '-' to read from stdin. +``` + +### Options inherited from parent commands + +``` + --help help for daytona +``` + +### SEE ALSO + +* [daytona template](daytona_template.md) - Manage workspace templates + diff --git a/hack/docs/daytona.yaml b/hack/docs/daytona.yaml index 09b085da63..c42e2a387d 100644 --- a/hack/docs/daytona.yaml +++ b/hack/docs/daytona.yaml @@ -41,6 +41,7 @@ see_also: - daytona target-config - Manage target configs - daytona telemetry - Manage telemetry collection - daytona template - Manage workspace templates + - daytona update - Update Daytona CLI - daytona use - Use profile [PROFILE_NAME] - daytona version - Print the version number - daytona whoami - Display information about the active user diff --git a/hack/docs/daytona_code.yaml b/hack/docs/daytona_code.yaml index 681575d51c..0af921605d 100644 --- a/hack/docs/daytona_code.yaml +++ b/hack/docs/daytona_code.yaml @@ -5,7 +5,7 @@ options: - name: ide shorthand: i usage: | - Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) - name: "yes" shorthand: "y" default_value: "false" diff --git a/hack/docs/daytona_create.yaml b/hack/docs/daytona_create.yaml index 9236cb7115..b845a7c022 100644 --- a/hack/docs/daytona_create.yaml +++ b/hack/docs/daytona_create.yaml @@ -28,7 +28,7 @@ options: - name: ide shorthand: i usage: | - Specify the IDE (vscode, browser, cursor, ssh, jupyter, fleet, zed, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) + Specify the IDE (vscode, code-insiders, browser, cursor, codium, codium-insiders, ssh, jupyter, fleet, positron, zed, windsurf, clion, goland, intellij, phpstorm, pycharm, rider, rubymine, webstorm) - name: manual default_value: "false" usage: Manually enter the Git repository diff --git a/hack/docs/daytona_git-provider_create.yaml b/hack/docs/daytona_git-provider_create.yaml index c0d498d41f..38d30879f1 100644 --- a/hack/docs/daytona_git-provider_create.yaml +++ b/hack/docs/daytona_git-provider_create.yaml @@ -1,6 +1,25 @@ name: daytona git-provider create synopsis: Create a Git provider config -usage: daytona git-provider create [flags] +usage: daytona git-provider create [GIT_PROVIDER_ID] [flags] +options: + - name: alias + shorthand: a + usage: Alias + - name: base-api-url + shorthand: b + usage: Base API Url + - name: signing-key + shorthand: k + usage: Signing Key + - name: signing-method + shorthand: s + usage: Signing Method (ssh, gpg) + - name: token + shorthand: t + usage: Personal Access Token + - name: username + shorthand: u + usage: Username inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_project-config_import.yaml b/hack/docs/daytona_project-config_import.yaml deleted file mode 100644 index 21218881dd..0000000000 --- a/hack/docs/daytona_project-config_import.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: daytona project-config import -synopsis: Import project config from JSON -usage: daytona project-config import [flags] -options: - - name: file - shorthand: f - usage: | - Import project config from a JSON file. Use '-' to read from stdin. -inherited_options: - - name: help - default_value: "false" - usage: help for daytona -see_also: - - daytona project-config - Manage project configs diff --git a/hack/docs/daytona_ssh.yaml b/hack/docs/daytona_ssh.yaml index 1d8b64e592..4b7e7b2513 100644 --- a/hack/docs/daytona_ssh.yaml +++ b/hack/docs/daytona_ssh.yaml @@ -2,6 +2,10 @@ name: daytona ssh synopsis: SSH into a workspace using the terminal usage: daytona ssh [WORKSPACE] [CMD...] [flags] options: + - name: edit + shorthand: e + default_value: "false" + usage: Edit the workspace's SSH config - name: option shorthand: o default_value: '[]' diff --git a/hack/docs/daytona_target-config_create.yaml b/hack/docs/daytona_target-config_create.yaml index 2f1f93e86a..9ca9eba417 100644 --- a/hack/docs/daytona_target-config_create.yaml +++ b/hack/docs/daytona_target-config_create.yaml @@ -1,6 +1,11 @@ name: daytona target-config create synopsis: Create target config usage: daytona target-config create [flags] +options: + - name: file + shorthand: f + usage: | + Path to JSON file for target configuration, use '-' to read from stdin inherited_options: - name: help default_value: "false" diff --git a/hack/docs/daytona_template.yaml b/hack/docs/daytona_template.yaml index dc05f766f8..7ac016e143 100644 --- a/hack/docs/daytona_template.yaml +++ b/hack/docs/daytona_template.yaml @@ -8,6 +8,8 @@ see_also: - daytona - Daytona is a Dev Environment Manager - daytona template create - Create a workspace template - daytona template delete - Delete a workspace template + - daytona template export - Export a workspace template + - daytona template import - Import a workspace template from a JSON object - daytona template info - Show workspace template info - daytona template list - Lists workspace templates - daytona template set-default - Set workspace template info diff --git a/hack/docs/daytona_project-config_export.yaml b/hack/docs/daytona_template_export.yaml similarity index 56% rename from hack/docs/daytona_project-config_export.yaml rename to hack/docs/daytona_template_export.yaml index eea3e1aaef..303d7392c0 100644 --- a/hack/docs/daytona_project-config_export.yaml +++ b/hack/docs/daytona_template_export.yaml @@ -1,11 +1,11 @@ -name: daytona project-config export -synopsis: Export a project config -usage: daytona project-config export [flags] +name: daytona template export +synopsis: Export a workspace template +usage: daytona template export [flags] options: - name: all shorthand: a default_value: "false" - usage: Export all project configs + usage: Export all workspace templates - name: format shorthand: f usage: Output format. Must be one of (yaml, json) @@ -14,4 +14,4 @@ inherited_options: default_value: "false" usage: help for daytona see_also: - - daytona project-config - Manage project configs + - daytona template - Manage workspace templates diff --git a/hack/docs/daytona_template_import.yaml b/hack/docs/daytona_template_import.yaml new file mode 100644 index 0000000000..9c6aa6ce98 --- /dev/null +++ b/hack/docs/daytona_template_import.yaml @@ -0,0 +1,14 @@ +name: daytona template import +synopsis: Import a workspace template from a JSON object +usage: daytona template import [flags] +options: + - name: file + shorthand: f + usage: | + Import workspace template from a JSON file. Use '-' to read from stdin. +inherited_options: + - name: help + default_value: "false" + usage: help for daytona +see_also: + - daytona template - Manage workspace templates diff --git a/pkg/cmd/workspacetemplate/export.go b/pkg/cmd/workspacetemplate/export.go index 45671eb415..4392432267 100644 --- a/pkg/cmd/workspacetemplate/export.go +++ b/pkg/cmd/workspacetemplate/export.go @@ -20,10 +20,9 @@ import ( ) var exportCmd = &cobra.Command{ - Use: "export", - Aliases: []string{"exp"}, - Short: "Export a workspace template", - Args: cobra.MaximumNArgs(1), + Use: "export", + Short: "Export a workspace template", + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { var selectedWorkspaceTemplate *apiclient.WorkspaceTemplate ctx := context.Background() @@ -34,26 +33,26 @@ var exportCmd = &cobra.Command{ } if allFlag { - workspaceConfigs, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() + templates, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceConfigs) == 0 { + if len(templates) == 0 { views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } - return exportWorkspaceTemplates(workspaceConfigs) + return exportWorkspaceTemplates(templates) } if len(args) == 0 { - workspaceConfigs, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() + templates, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - if len(workspaceConfigs) == 0 { + if len(templates) == 0 { views_util.NotifyEmptyWorkspaceTemplateList(true) return nil } @@ -62,7 +61,7 @@ var exportCmd = &cobra.Command{ format.UnblockStdOut() } - selectedWorkspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(workspaceConfigs, 0, false, false, "Export") + selectedWorkspaceTemplate = selection.GetWorkspaceTemplateFromPrompt(templates, 0, false, false, "Export") if selectedWorkspaceTemplate == nil { return nil } @@ -87,55 +86,46 @@ func init() { format.RegisterFormatFlag(exportCmd) } -func exportWorkspaceTemplates(workspaceConfigs []apiclient.WorkspaceTemplate) error { - if len(workspaceConfigs) == 0 { +func exportWorkspaceTemplates(templates []apiclient.WorkspaceTemplate) error { + if len(templates) == 0 { return nil } var pbFlag bool - for i := range workspaceConfigs { - workspaceConfigs[i].GitProviderConfigId = nil - if workspaceConfigs[i].Prebuilds != nil { - workspaceConfigs[i].Prebuilds = nil + for i := range templates { + templates[i].GitProviderConfigId = nil + if templates[i].Prebuilds != nil { + templates[i].Prebuilds = nil pbFlag = true } } - var data []byte - var err error - - if len(workspaceConfigs) == 1 { - data, err = json.MarshalIndent(workspaceConfigs[0], "", " ") - views.RenderContainerLayout("Prebuilds have been removed from the template.") - } else { - data, err = json.MarshalIndent(workspaceConfigs, "", " ") - if pbFlag { - views.RenderContainerLayout("Prebuilds have been removed from your templates.") - } + data, err := json.MarshalIndent(templates, "", " ") + if pbFlag { + views.RenderContainerLayout("Prebuilds have been removed from the export.") + } + if err != nil { + return err } if format.FormatFlag != "" { - if len(workspaceConfigs) == 1 { - formattedData := format.NewFormatter(workspaceConfigs[0]) + if len(templates) == 1 { + formattedData := format.NewFormatter(templates[0]) formattedData.Print() } else { - formattedData := format.NewFormatter(workspaceConfigs) + formattedData := format.NewFormatter(templates) formattedData.Print() } return nil } - if err != nil { - return err - } - fmt.Println(string(data)) if err := clipboard.WriteAll(string(data)); err == nil { - views.RenderContainerLayout(views.GetInfoMessage("The config(s) have been copied to your clipboard.")) + views.RenderContainerLayout(views.GetInfoMessage("The export has been copied to your clipboard.")) } else { - views.RenderContainerLayout(views.GetInfoMessage("Could not copy the config(s) to your clipboard.")) + views.RenderContainerLayout(views.GetInfoMessage("Could not copy the export to your clipboard.")) } return nil diff --git a/pkg/cmd/workspacetemplate/import.go b/pkg/cmd/workspacetemplate/import.go index fdab069469..17243c042c 100644 --- a/pkg/cmd/workspacetemplate/import.go +++ b/pkg/cmd/workspacetemplate/import.go @@ -25,10 +25,9 @@ import ( var filePath string var importCmd = &cobra.Command{ - Use: "import", - Aliases: []string{"imp"}, - Short: "Import workspace template from JSON", - Args: cobra.MaximumNArgs(1), + Use: "import", + Short: "Import a workspace template from a JSON object", + Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { var inputText string ctx := context.Background() @@ -38,7 +37,7 @@ var importCmd = &cobra.Command{ return err } - workspaceConfigList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() + workspaceTemplateList, res, err := apiClient.WorkspaceTemplateAPI.ListWorkspaceTemplates(ctx).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } @@ -62,8 +61,8 @@ var importCmd = &cobra.Command{ form := huh.NewForm( huh.NewGroup( huh.NewText(). - Title("Import Workspace-Config"). - Description("Enter Workspace-Config as a JSON or an array of JSON objects"). + Title("Import Workspace Template"). + Description("Enter Workspace Template as a JSON object or an array of JSON objects"). CharLimit(-1). Value(&inputText), ), @@ -74,24 +73,24 @@ var importCmd = &cobra.Command{ } } - var config apiclient.WorkspaceTemplate - err = json.Unmarshal([]byte(inputText), &config) + var template apiclient.WorkspaceTemplate + err = json.Unmarshal([]byte(inputText), &template) if err == nil { - err = importWorkspaceTemplate(ctx, apiClient, config, &workspaceConfigList) + err = importWorkspaceTemplate(ctx, apiClient, template, &workspaceTemplateList) if err != nil { - return fmt.Errorf("error importing workspace config: %v", err) + return fmt.Errorf("error importing workspace template: %v", err) } } else { - var configs []apiclient.WorkspaceTemplate - err = json.Unmarshal([]byte(inputText), &configs) + var templates []apiclient.WorkspaceTemplate + err = json.Unmarshal([]byte(inputText), &templates) if err != nil { return fmt.Errorf("invalid JSON input: %v", err) } - for _, config := range configs { - err = importWorkspaceTemplate(ctx, apiClient, config, &workspaceConfigList) + for _, t := range templates { + err = importWorkspaceTemplate(ctx, apiClient, t, &workspaceTemplateList) if err != nil { - return fmt.Errorf("error importing workspace config: %v", err) + return fmt.Errorf("error importing workspace template: %v", err) } } } @@ -103,23 +102,23 @@ func init() { importCmd.Flags().StringVarP(&filePath, "file", "f", "", "Import workspace template from a JSON file. Use '-' to read from stdin.") } -func isWorkspaceTemplateAlreadyExists(configName string, workspaceConfigList *[]apiclient.WorkspaceTemplate) bool { - for _, workspaceConfig := range *workspaceConfigList { - if workspaceConfig.Name == configName { +func checkWorkspaceTemplateAlreadyExists(templateName string, workspaceTemplateList *[]apiclient.WorkspaceTemplate) bool { + for _, t := range *workspaceTemplateList { + if t.Name == templateName { return true } } return false } -func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient, config apiclient.WorkspaceTemplate, workspaceConfigList *[]apiclient.WorkspaceTemplate) error { - if isWorkspaceTemplateAlreadyExists(config.Name, workspaceConfigList) { - return fmt.Errorf("workspace config already present with name \"%s\"", config.Name) +func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient, template apiclient.WorkspaceTemplate, workspaceTemplateList *[]apiclient.WorkspaceTemplate) error { + if checkWorkspaceTemplateAlreadyExists(template.Name, workspaceTemplateList) { + return fmt.Errorf("workspace template already present with name \"%s\"", template.Name) } var verifiedGitProvider bool - if config.GitProviderConfigId != nil { - _, _, err := apiClient.GitProviderAPI.FindGitProvider(ctx, *config.GitProviderConfigId).Execute() + if template.GitProviderConfigId != nil { + _, _, err := apiClient.GitProviderAPI.FindGitProvider(ctx, *template.GitProviderConfigId).Execute() if err == nil { verifiedGitProvider = true } @@ -129,27 +128,27 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient if !verifiedGitProvider { var err error - gitProviders, _, err = apiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(config.RepositoryUrl)).Execute() + gitProviders, _, err = apiClient.GitProviderAPI.ListGitProvidersForUrl(ctx, url.QueryEscape(template.RepositoryUrl)).Execute() if err != nil { return fmt.Errorf("error fetching Git providers: %v", err) } if len(gitProviders) == 0 { - gitProviderConfigId, _, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, url.QueryEscape(config.RepositoryUrl)).Execute() + gitProviderConfigId, _, err := apiClient.GitProviderAPI.FindGitProviderIdForUrl(ctx, url.QueryEscape(template.RepositoryUrl)).Execute() if err != nil { return fmt.Errorf("error fetching Git provider: %v", err) } - config.GitProviderConfigId = &gitProviderConfigId + template.GitProviderConfigId = &gitProviderConfigId } - if len(gitProviders) == 1 && config.GitProviderConfigId == nil { - config.GitProviderConfigId = &gitProviders[0].Id - } else if len(gitProviders) > 1 && config.GitProviderConfigId == nil { + if len(gitProviders) == 1 && template.GitProviderConfigId == nil { + template.GitProviderConfigId = &gitProviders[0].Id + } else if len(gitProviders) > 1 && template.GitProviderConfigId == nil { selectedGitProvider := selection.GetGitProviderConfigFromPrompt(selection.GetGitProviderConfigParams{ GitProviderConfigs: gitProviders, ActionVerb: "Use", }) - config.GitProviderConfigId = &selectedGitProvider.Id + template.GitProviderConfigId = &selectedGitProvider.Id } } @@ -159,13 +158,13 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient } newWorkspaceTemplate := apiclient.CreateWorkspaceTemplateDTO{ - Name: config.Name, - BuildConfig: config.BuildConfig, - Image: &config.Image, - User: &config.User, - RepositoryUrl: config.RepositoryUrl, - EnvVars: config.EnvVars, - GitProviderConfigId: config.GitProviderConfigId, + Name: template.Name, + BuildConfig: template.BuildConfig, + Image: &template.Image, + User: &template.User, + RepositoryUrl: template.RepositoryUrl, + EnvVars: template.EnvVars, + GitProviderConfigId: template.GitProviderConfigId, } if newWorkspaceTemplate.Image == nil { @@ -195,15 +194,15 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient createDto := []apiclient.CreateWorkspaceDTO{ { - Name: config.Name, + Name: template.Name, Source: apiclient.CreateWorkspaceSourceDTO{ Repository: apiclient.GitRepository{ - Url: config.RepositoryUrl, + Url: template.RepositoryUrl, }, }, - BuildConfig: config.BuildConfig, - EnvVars: config.EnvVars, - GitProviderConfigId: config.GitProviderConfigId, + BuildConfig: template.BuildConfig, + EnvVars: template.EnvVars, + GitProviderConfigId: template.GitProviderConfigId, }, } @@ -213,11 +212,11 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient } submissionFormConfig := create.SubmissionFormParams{ - ChosenName: &config.Name, - SuggestedName: config.Name, + ChosenName: &template.Name, + SuggestedName: template.Name, ExistingWorkspaceNames: existingWorkspaceTemplateNames, WorkspaceList: &createDto, - NameLabel: "Workspace config", + NameLabel: "Workspace template", Defaults: workspaceDefaults, ImportConfirmation: util.Pointer(true), } @@ -233,11 +232,11 @@ func importWorkspaceTemplate(ctx context.Context, apiClient *apiclient.APIClient return apiclient_util.HandleErrorResponse(res, err) } - *workspaceConfigList = append(*workspaceConfigList, config) - views.RenderInfoMessage(fmt.Sprintf("Workspace config %s imported successfully", newWorkspaceTemplate.Name)) + *workspaceTemplateList = append(*workspaceTemplateList, template) + views.RenderInfoMessage(fmt.Sprintf("Workspace template %s imported successfully", newWorkspaceTemplate.Name)) return nil } - views.RenderInfoMessage(fmt.Sprintf("Workspace config %s import cancelled", newWorkspaceTemplate.Name)) + views.RenderInfoMessage(fmt.Sprintf("Workspace template %s import cancelled", newWorkspaceTemplate.Name)) return nil } From e5cb7cad9aad469e1bb69fb04dc835fc6a57d09f Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Wed, 15 Jan 2025 08:26:09 +0000 Subject: [PATCH 57/76] fix: set correct error on job Signed-off-by: Toma Puljak --- pkg/runner/runner.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index a01a1db954..a5ac1ef4ff 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -332,9 +332,9 @@ func (r *Runner) handleRunFailed(j *models.Job, err error, startTime time.Time) if r.Config.TelemetryEnabled { execTime := time.Since(startTime) event := telemetry.NewJobEvent(telemetry.JobEventRunFailed, j, err, map[string]interface{}{"exec_time_ms": execTime.Milliseconds()}) - err = r.trackTelemetryEvent(event, r.Config.ClientId) - if err != nil { - r.logger.Trace(err) + telemetryErr := r.trackTelemetryEvent(event, r.Config.ClientId) + if telemetryErr != nil { + r.logger.Trace(telemetryErr) } } From d55690a7266b39c5c7797da1e82db0c3130eb659 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Wed, 15 Jan 2025 08:36:33 +0000 Subject: [PATCH 58/76] fix: leftover in initial screen Signed-off-by: Ivan Dagelic --- README.md | 2 +- pkg/cmd/prebuild/update.go | 2 +- pkg/views/initial/view.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1f5b6ac1a0..7bb983498d 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,7 @@ If you're interested in contributing code to Daytona, follow these steps: Before creating your workspace, ensure that you have a GitHub provider registered. If not, run: ```bash - daytona git-provider add + daytona git-provider create ``` 1. **Create a Workspace with Daytona** diff --git a/pkg/cmd/prebuild/update.go b/pkg/cmd/prebuild/update.go index 4d8069893a..4642f16b87 100644 --- a/pkg/cmd/prebuild/update.go +++ b/pkg/cmd/prebuild/update.go @@ -44,7 +44,7 @@ var updateCmd = &cobra.Command{ } if len(userGitProviders) == 0 { - views.RenderInfoMessage("No registered Git providers have been found - please register a Git provider using 'daytona git-provider add' in order to start using prebuilds.") + views.RenderInfoMessage("No registered Git providers have been found - please register a Git provider using 'daytona git-provider create' in order to start using prebuilds.") return nil } diff --git a/pkg/views/initial/view.go b/pkg/views/initial/view.go index 8c9f723de7..020d7996b6 100644 --- a/pkg/views/initial/view.go +++ b/pkg/views/initial/view.go @@ -68,7 +68,7 @@ var commandViews []CommandView = []CommandView{ {Command: "server", Name: "daytona server", Desc: "(start the Daytona Server daemon)"}, {Command: "create", Name: "daytona create", Desc: "(create a new workspace)"}, {Command: "code", Name: "daytona code", Desc: "(open a workspace in your preferred IDE)"}, - {Command: "git-provider add", Name: "daytona git-provider add", Desc: "(register a Git provider account)"}, + {Command: "git-provider create", Name: "daytona git-provider create", Desc: "(register a Git provider account)"}, {Command: "target-config create", Name: "daytona target-config create", Desc: "(run workspaces on a remote machine)"}, {Command: "docs", Name: "daytona docs", Desc: "(open Daytona docs in default browser)\n"}, {Command: "help", Name: "view all commands", Desc: ""}, From ca5b6b9b5866cb535fe5d9331748b4edbd3c9717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Wed, 15 Jan 2025 14:10:57 +0100 Subject: [PATCH 59/76] fix: target config create non-interactive (#1714) Signed-off-by: Luka Brecic --- pkg/cmd/targetconfig/create.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pkg/cmd/targetconfig/create.go b/pkg/cmd/targetconfig/create.go index 2b104ff78f..f71da8bfb3 100644 --- a/pkg/cmd/targetconfig/create.go +++ b/pkg/cmd/targetconfig/create.go @@ -14,7 +14,6 @@ import ( "sort" "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/internal/util" internal_util "github.com/daytonaio/daytona/internal/util" apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/internal/util/apiclient/conversion" @@ -78,7 +77,7 @@ var TargetConfigCreateCmd = &cobra.Command{ return nil } - views.RenderInfoMessage(fmt.Sprintf("Target config '%s' set successfully", targetConfig.Name)) + views.RenderInfoMessage(fmt.Sprintf("Target config '%s' created successfully", targetConfig.Name)) return nil }, } @@ -89,7 +88,7 @@ func TargetConfigCreationFlow(ctx context.Context, apiClient *apiclient.APIClien return nil, apiclient_util.HandleErrorResponse(res, err) } - providersManifest, err := util.GetProvidersManifest(serverConfig.RegistryUrl) + providersManifest, err := internal_util.GetProvidersManifest(serverConfig.RegistryUrl) if err != nil { return nil, err } @@ -244,15 +243,20 @@ func handleTargetConfigJSON(data []byte) error { Name: selectedTargetConfig.Name, Options: selectedTargetConfig.Options, ProviderInfo: apiclient.ProviderInfo{ - Name: selectedTargetConfig.ProviderInfo.Name, - Version: selectedTargetConfig.ProviderInfo.Version, + RunnerId: selectedTargetConfig.ProviderInfo.RunnerId, + RunnerName: selectedTargetConfig.ProviderInfo.RunnerName, + Name: selectedTargetConfig.ProviderInfo.Name, + Version: selectedTargetConfig.ProviderInfo.Version, + AgentlessTarget: selectedTargetConfig.ProviderInfo.AgentlessTarget, + Label: selectedTargetConfig.ProviderInfo.Label, + TargetConfigManifest: selectedTargetConfig.ProviderInfo.TargetConfigManifest, }, } - _, res, err := apiClient.TargetConfigAPI.CreateTargetConfig(ctx).TargetConfig(targetConfigData).Execute() + targetConfig, res, err := apiClient.TargetConfigAPI.CreateTargetConfig(ctx).TargetConfig(targetConfigData).Execute() if err != nil { return apiclient_util.HandleErrorResponse(res, err) } - views.RenderInfoMessage("Target set successfully and will be used by default") + views.RenderInfoMessage(fmt.Sprintf("Target config '%s' created successfully", targetConfig.Name)) return nil } From 1dcfbf484509117b6fdcdf590ddcf5b73d1722bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 16 Jan 2025 09:46:55 +0100 Subject: [PATCH 60/76] fix: set docker cred helper config (#1717) Signed-off-by: Luka Brecic --- pkg/docker/credential_helper.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/docker/credential_helper.go b/pkg/docker/credential_helper.go index 5507d3ced1..2dcfe303e8 100644 --- a/pkg/docker/credential_helper.go +++ b/pkg/docker/credential_helper.go @@ -62,7 +62,7 @@ func (d *DockerCredHelper) SetDockerConfig() error { return err } - return os.WriteFile(d.DockerConfigFileName, updatedConfigContent, 0644) + return os.WriteFile(d.DockerConfigFileName, updatedConfigContent, 0755) } func (d *DockerCredHelper) createDockerCredHelperExecutable() error { @@ -76,7 +76,7 @@ func (d *DockerCredHelper) createDockerCredHelperExecutable() error { _, ok := os.Stat(filePath) if os.IsNotExist(ok) { - err := os.MkdirAll(filePath, 0757) + err := os.MkdirAll(filePath, 0755) if err != nil { return err } @@ -88,10 +88,10 @@ func (d *DockerCredHelper) createDockerCredHelperExecutable() error { } } - err = os.WriteFile(filepath.Join(filePath, fileName), []byte(content), 0555) + err = os.WriteFile(filepath.Join(filePath, fileName), []byte(content), 0755) if err != nil { return err } - return os.Chmod(filepath.Join(filePath, fileName), 0555) + return os.Chmod(filepath.Join(filePath, fileName), 0755) } From dd3584d3fdce6819fa4c8922ec64c206bd6a1812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 16 Jan 2025 09:47:14 +0100 Subject: [PATCH 61/76] fix: ssh edit command (#1716) Signed-off-by: Luka Brecic --- pkg/cmd/workspace/logs.go | 3 +-- pkg/cmd/workspace/ssh.go | 1 + pkg/cmd/workspace/start.go | 3 +-- pkg/cmd/workspace/stop.go | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/pkg/cmd/workspace/logs.go b/pkg/cmd/workspace/logs.go index d16ed4c324..c568661ed8 100644 --- a/pkg/cmd/workspace/logs.go +++ b/pkg/cmd/workspace/logs.go @@ -11,7 +11,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" - cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -77,7 +76,7 @@ var LogsCmd = &cobra.Command{ return nil } - cmd_common.ReadWorkspaceLogs(ctx, cmd_common.ReadLogParams{ + common.ReadWorkspaceLogs(ctx, common.ReadLogParams{ Id: ws.Id, Label: &ws.Name, ServerUrl: activeProfile.Api.Url, diff --git a/pkg/cmd/workspace/ssh.go b/pkg/cmd/workspace/ssh.go index a22b1fb888..00b14be40f 100644 --- a/pkg/cmd/workspace/ssh.go +++ b/pkg/cmd/workspace/ssh.go @@ -81,6 +81,7 @@ var SshCmd = &cobra.Command{ if err != nil { return err } + return nil } if ws.State.Name == apiclient.ResourceStateNameStopped { diff --git a/pkg/cmd/workspace/start.go b/pkg/cmd/workspace/start.go index 7bbcedb072..a49121a873 100644 --- a/pkg/cmd/workspace/start.go +++ b/pkg/cmd/workspace/start.go @@ -14,7 +14,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" - cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" ide_views "github.com/daytonaio/daytona/pkg/views/ide" views_util "github.com/daytonaio/daytona/pkg/views/util" @@ -184,7 +183,7 @@ func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspac } logsContext, stopLogs := context.WithCancel(context.Background()) - go cmd_common.ReadWorkspaceLogs(logsContext, cmd_common.ReadLogParams{ + go common.ReadWorkspaceLogs(logsContext, common.ReadLogParams{ Id: workspace.Id, Label: &workspace.Name, ServerUrl: activeProfile.Api.Url, diff --git a/pkg/cmd/workspace/stop.go b/pkg/cmd/workspace/stop.go index 5e0fbfbbbb..eaaa8513ad 100644 --- a/pkg/cmd/workspace/stop.go +++ b/pkg/cmd/workspace/stop.go @@ -13,7 +13,6 @@ import ( apiclient_util "github.com/daytonaio/daytona/internal/util/apiclient" "github.com/daytonaio/daytona/pkg/apiclient" "github.com/daytonaio/daytona/pkg/cmd/common" - cmd_common "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/views" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/daytonaio/daytona/pkg/views/workspace/selection" @@ -137,7 +136,7 @@ func StopWorkspace(apiClient *apiclient.APIClient, workspace apiclient.Workspace } logsContext, stopLogs := context.WithCancel(context.Background()) - go cmd_common.ReadWorkspaceLogs(logsContext, cmd_common.ReadLogParams{ + go common.ReadWorkspaceLogs(logsContext, common.ReadLogParams{ Id: workspace.Id, Label: &workspace.Name, ServerUrl: activeProfile.Api.Url, From da71dbeac8d1df9e89a40fba74d73b42903c1ca1 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Thu, 16 Jan 2025 09:20:40 +0000 Subject: [PATCH 62/76] fix: config alias Signed-off-by: Ivan Dagelic --- pkg/cmd/common/aliases.go | 1 - pkg/cmd/config.go | 8 +++----- pkg/cmd/runner/config.go | 6 ++---- pkg/cmd/server/config.go | 6 ++---- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pkg/cmd/common/aliases.go b/pkg/cmd/common/aliases.go index ea14ce4b95..c6465bec65 100644 --- a/pkg/cmd/common/aliases.go +++ b/pkg/cmd/common/aliases.go @@ -13,7 +13,6 @@ var commandAliases = map[string][]string{ "code": {"open"}, "logs": {"log"}, "forward": {"fwd"}, - "config": {"info"}, "list": {"ls"}, "set-default": {"sd"}, "run": {"create"}, diff --git a/pkg/cmd/config.go b/pkg/cmd/config.go index fc3af9cb82..0d838fe9d6 100644 --- a/pkg/cmd/config.go +++ b/pkg/cmd/config.go @@ -5,7 +5,6 @@ package cmd import ( "github.com/daytonaio/daytona/cmd/daytona/config" - "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" config_view "github.com/daytonaio/daytona/pkg/views/config" "github.com/spf13/cobra" @@ -14,10 +13,9 @@ import ( var showApiKeysFlag bool var configCmd = &cobra.Command{ - Use: "config", - Short: "Output Daytona configuration", - Args: cobra.NoArgs, - Aliases: common.GetAliases("config"), + Use: "config", + Short: "Output Daytona configuration", + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { c, err := config.GetConfig() if err != nil { diff --git a/pkg/cmd/runner/config.go b/pkg/cmd/runner/config.go index 16eb3b4015..4812e47a04 100644 --- a/pkg/cmd/runner/config.go +++ b/pkg/cmd/runner/config.go @@ -7,15 +7,13 @@ import ( view "github.com/daytonaio/daytona/pkg/views/runner" "github.com/spf13/cobra" - "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/runner" ) var configCmd = &cobra.Command{ - Use: "config", - Short: "Outputs Daytona Runner config", - Aliases: common.GetAliases("config"), + Use: "config", + Short: "Outputs Daytona Runner config", RunE: func(cmd *cobra.Command, args []string) error { config, err := runner.GetConfig() if err != nil { diff --git a/pkg/cmd/server/config.go b/pkg/cmd/server/config.go index d193119365..0ea3079936 100644 --- a/pkg/cmd/server/config.go +++ b/pkg/cmd/server/config.go @@ -7,15 +7,13 @@ import ( view "github.com/daytonaio/daytona/pkg/views/server" "github.com/spf13/cobra" - "github.com/daytonaio/daytona/pkg/cmd/common" "github.com/daytonaio/daytona/pkg/cmd/format" "github.com/daytonaio/daytona/pkg/server" ) var configCmd = &cobra.Command{ - Use: "config", - Short: "Output local Daytona Server config", - Aliases: common.GetAliases("config"), + Use: "config", + Short: "Output local Daytona Server config", RunE: func(cmd *cobra.Command, args []string) error { config, err := server.GetConfig() if err != nil { From f3269a0c321e903ac1a25867289facdb1832bf42 Mon Sep 17 00:00:00 2001 From: Toma Puljak Date: Thu, 16 Jan 2025 09:59:16 +0000 Subject: [PATCH 63/76] feat: workspace labels (#1718) - Users can add labels to workspaces when creating them or update them through the API - Users can query for workspaces that match labels provided in query params Signed-off-by: Toma Puljak --- pkg/api/controllers/workspace/create.go | 10 ++ pkg/api/controllers/workspace/labels.go | 54 +++++++ pkg/api/controllers/workspace/workspace.go | 20 ++- pkg/api/docs/docs.go | 75 ++++++++++ pkg/api/docs/swagger.json | 75 ++++++++++ pkg/api/docs/swagger.yaml | 51 +++++++ pkg/api/server.go | 1 + pkg/apiclient/README.md | 1 + pkg/apiclient/api/openapi.yaml | 69 +++++++++ pkg/apiclient/api_workspace.go | 140 ++++++++++++++++++ pkg/apiclient/docs/CreateWorkspaceDTO.md | 23 ++- pkg/apiclient/docs/Workspace.md | 23 ++- pkg/apiclient/docs/WorkspaceAPI.md | 86 ++++++++++- pkg/apiclient/docs/WorkspaceDTO.md | 23 ++- pkg/apiclient/docs/WorkspaceTemplate.md | 23 ++- pkg/apiclient/model_create_workspace_dto.go | 30 +++- pkg/apiclient/model_workspace.go | 30 +++- pkg/apiclient/model_workspace_dto.go | 30 +++- pkg/apiclient/model_workspace_template.go | 30 +++- pkg/cmd/common/configuration_flags.go | 20 ++- pkg/cmd/workspace/create/add_from_template.go | 1 + pkg/cmd/workspace/create/cmd.go | 1 + pkg/cmd/workspace/create/creation_data.go | 22 ++- pkg/cmd/workspace/list.go | 16 +- pkg/cmd/workspacetemplate/create.go | 1 + pkg/docker/stop_test.go | 4 +- pkg/models/workspace.go | 1 + pkg/models/workspace_template.go | 1 + pkg/server/workspaces/labels.go | 49 ++++++ pkg/server/workspaces/list.go | 16 +- pkg/server/workspaces/service_test.go | 13 ++ pkg/services/workspace.go | 4 + pkg/telemetry/workspace.go | 3 + pkg/views/workspace/info/view.go | 16 ++ 34 files changed, 938 insertions(+), 24 deletions(-) create mode 100644 pkg/api/controllers/workspace/labels.go create mode 100644 pkg/server/workspaces/labels.go diff --git a/pkg/api/controllers/workspace/create.go b/pkg/api/controllers/workspace/create.go index c95d754bd6..2bed9a1205 100644 --- a/pkg/api/controllers/workspace/create.go +++ b/pkg/api/controllers/workspace/create.go @@ -7,6 +7,8 @@ import ( "fmt" "net/http" + "github.com/daytonaio/daytona/pkg/api/util" + "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/server" "github.com/daytonaio/daytona/pkg/services" "github.com/gin-gonic/gin" @@ -39,5 +41,13 @@ func CreateWorkspace(ctx *gin.Context) { return } + apiKeyType, ok := ctx.Get("apiKeyType") + if !ok || apiKeyType == models.ApiKeyTypeClient { + util.HideDaytonaEnvVars(&w.EnvVars) + util.HideDaytonaEnvVars(&w.Target.EnvVars) + w.ApiKey = "" + w.Target.ApiKey = "" + } + ctx.JSON(200, w) } diff --git a/pkg/api/controllers/workspace/labels.go b/pkg/api/controllers/workspace/labels.go new file mode 100644 index 0000000000..5c938ab6fc --- /dev/null +++ b/pkg/api/controllers/workspace/labels.go @@ -0,0 +1,54 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspace + +import ( + "fmt" + "net/http" + + "github.com/daytonaio/daytona/pkg/api/util" + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/server" + "github.com/gin-gonic/gin" +) + +// UpdateWorkspaceLabels godoc +// +// @Tags workspace +// @Summary Update workspace labels +// @Description Update workspace labels +// @Param workspaceId path string true "Workspace ID or Name" +// @Param labels body map[string]string true "Labels" +// @Success 200 {object} WorkspaceDTO +// @Router /workspace/{workspaceId}/labels [post] +// +// @id UpdateWorkspaceLabels +func UpdateWorkspaceLabels(ctx *gin.Context) { + workspaceId := ctx.Param("workspaceId") + + var req map[string]string + err := ctx.BindJSON(&req) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid request body: %s", err.Error())) + return + } + + server := server.GetInstance(nil) + + w, err := server.WorkspaceService.UpdateLabels(ctx.Request.Context(), workspaceId, req) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to update labels for workspace %s: %w", workspaceId, err)) + return + } + + apiKeyType, ok := ctx.Get("apiKeyType") + if !ok || apiKeyType == models.ApiKeyTypeClient { + util.HideDaytonaEnvVars(&w.EnvVars) + util.HideDaytonaEnvVars(&w.Target.EnvVars) + w.ApiKey = "" + w.Target.ApiKey = "" + } + + ctx.JSON(200, w) +} diff --git a/pkg/api/controllers/workspace/workspace.go b/pkg/api/controllers/workspace/workspace.go index 3d30306993..98b4d61077 100644 --- a/pkg/api/controllers/workspace/workspace.go +++ b/pkg/api/controllers/workspace/workspace.go @@ -4,6 +4,7 @@ package workspace import ( + "encoding/json" "fmt" "net/http" @@ -56,15 +57,30 @@ func FindWorkspace(ctx *gin.Context) { // @Tags workspace // @Summary List workspaces // @Description List workspaces +// @Param labels query string false "JSON encoded labels" // @Produce json // @Success 200 {array} WorkspaceDTO // @Router /workspace [get] // // @id ListWorkspaces func ListWorkspaces(ctx *gin.Context) { + labelsQuery := ctx.Query("labels") + + var labels map[string]string + + if labelsQuery != "" { + err := json.Unmarshal([]byte(labelsQuery), &labels) + if err != nil { + ctx.AbortWithError(http.StatusBadRequest, fmt.Errorf("invalid filters: %w", err)) + return + } + } + server := server.GetInstance(nil) - workspaceList, err := server.WorkspaceService.List(ctx.Request.Context(), services.WorkspaceRetrievalParams{}) + workspaceList, err := server.WorkspaceService.List(ctx.Request.Context(), services.WorkspaceRetrievalParams{ + Labels: labels, + }) if err != nil { ctx.AbortWithError(http.StatusInternalServerError, fmt.Errorf("failed to list workspaces: %w", err)) return @@ -72,7 +88,7 @@ func ListWorkspaces(ctx *gin.Context) { apiKeyType, ok := ctx.Get("apiKeyType") if !ok || apiKeyType == models.ApiKeyTypeClient { - for i, _ := range workspaceList { + for i := range workspaceList { util.HideDaytonaEnvVars(&workspaceList[i].EnvVars) util.HideDaytonaEnvVars(&workspaceList[i].Target.EnvVars) workspaceList[i].ApiKey = "" diff --git a/pkg/api/docs/docs.go b/pkg/api/docs/docs.go index a816f6f9dd..e7adfeb53b 100644 --- a/pkg/api/docs/docs.go +++ b/pkg/api/docs/docs.go @@ -1841,6 +1841,14 @@ const docTemplate = `{ ], "summary": "List workspaces", "operationId": "ListWorkspaces", + "parameters": [ + { + "type": "string", + "description": "JSON encoded labels", + "name": "labels", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -2300,6 +2308,45 @@ const docTemplate = `{ } } }, + "/workspace/{workspaceId}/labels": { + "post": { + "description": "Update workspace labels", + "tags": [ + "workspace" + ], + "summary": "Update workspace labels", + "operationId": "UpdateWorkspaceLabels", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "description": "Labels", + "name": "labels", + "in": "body", + "required": true, + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceDTO" + } + } + } + } + }, "/workspace/{workspaceId}/metadata": { "post": { "description": "Update workspace metadata", @@ -4137,6 +4184,7 @@ const docTemplate = `{ "required": [ "envVars", "id", + "labels", "name", "source", "targetId" @@ -4160,6 +4208,12 @@ const docTemplate = `{ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "name": { "type": "string" }, @@ -5768,6 +5822,7 @@ const docTemplate = `{ "envVars", "id", "image", + "labels", "name", "repository", "target", @@ -5796,6 +5851,12 @@ const docTemplate = `{ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5832,6 +5893,7 @@ const docTemplate = `{ "envVars", "id", "image", + "labels", "name", "repository", "state", @@ -5861,6 +5923,12 @@ const docTemplate = `{ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5929,6 +5997,7 @@ const docTemplate = `{ "default", "envVars", "image", + "labels", "name", "repositoryUrl", "user" @@ -5952,6 +6021,12 @@ const docTemplate = `{ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "name": { "type": "string" }, diff --git a/pkg/api/docs/swagger.json b/pkg/api/docs/swagger.json index c6bb64caa9..7df7ca8d24 100644 --- a/pkg/api/docs/swagger.json +++ b/pkg/api/docs/swagger.json @@ -1838,6 +1838,14 @@ ], "summary": "List workspaces", "operationId": "ListWorkspaces", + "parameters": [ + { + "type": "string", + "description": "JSON encoded labels", + "name": "labels", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -2297,6 +2305,45 @@ } } }, + "/workspace/{workspaceId}/labels": { + "post": { + "description": "Update workspace labels", + "tags": [ + "workspace" + ], + "summary": "Update workspace labels", + "operationId": "UpdateWorkspaceLabels", + "parameters": [ + { + "type": "string", + "description": "Workspace ID or Name", + "name": "workspaceId", + "in": "path", + "required": true + }, + { + "description": "Labels", + "name": "labels", + "in": "body", + "required": true, + "schema": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/WorkspaceDTO" + } + } + } + } + }, "/workspace/{workspaceId}/metadata": { "post": { "description": "Update workspace metadata", @@ -4134,6 +4181,7 @@ "required": [ "envVars", "id", + "labels", "name", "source", "targetId" @@ -4157,6 +4205,12 @@ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "name": { "type": "string" }, @@ -5765,6 +5819,7 @@ "envVars", "id", "image", + "labels", "name", "repository", "target", @@ -5793,6 +5848,12 @@ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5829,6 +5890,7 @@ "envVars", "id", "image", + "labels", "name", "repository", "state", @@ -5858,6 +5920,12 @@ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "lastJob": { "$ref": "#/definitions/Job" }, @@ -5926,6 +5994,7 @@ "default", "envVars", "image", + "labels", "name", "repositoryUrl", "user" @@ -5949,6 +6018,12 @@ "image": { "type": "string" }, + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, "name": { "type": "string" }, diff --git a/pkg/api/docs/swagger.yaml b/pkg/api/docs/swagger.yaml index b6e89b74ca..16292c64b7 100644 --- a/pkg/api/docs/swagger.yaml +++ b/pkg/api/docs/swagger.yaml @@ -257,6 +257,10 @@ definitions: type: string image: type: string + labels: + additionalProperties: + type: string + type: object name: type: string source: @@ -268,6 +272,7 @@ definitions: required: - envVars - id + - labels - name - source - targetId @@ -1385,6 +1390,10 @@ definitions: type: string image: type: string + labels: + additionalProperties: + type: string + type: object lastJob: $ref: '#/definitions/Job' lastJobId: @@ -1408,6 +1417,7 @@ definitions: - envVars - id - image + - labels - name - repository - target @@ -1430,6 +1440,10 @@ definitions: type: string image: type: string + labels: + additionalProperties: + type: string + type: object lastJob: $ref: '#/definitions/Job' lastJobId: @@ -1455,6 +1469,7 @@ definitions: - envVars - id - image + - labels - name - repository - state @@ -1496,6 +1511,10 @@ definitions: type: string image: type: string + labels: + additionalProperties: + type: string + type: object name: type: string prebuilds: @@ -1510,6 +1529,7 @@ definitions: - default - envVars - image + - labels - name - repositoryUrl - user @@ -2832,6 +2852,11 @@ paths: get: description: List workspaces operationId: ListWorkspaces + parameters: + - description: JSON encoded labels + in: query + name: labels + type: string produces: - application/json responses: @@ -3143,6 +3168,32 @@ paths: summary: Find workspace tags: - workspace + /workspace/{workspaceId}/labels: + post: + description: Update workspace labels + operationId: UpdateWorkspaceLabels + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + type: string + - description: Labels + in: body + name: labels + required: true + schema: + additionalProperties: + type: string + type: object + responses: + "200": + description: OK + schema: + $ref: '#/definitions/WorkspaceDTO' + summary: Update workspace labels + tags: + - workspace /workspace/{workspaceId}/metadata: post: description: Update workspace metadata diff --git a/pkg/api/server.go b/pkg/api/server.go index c43a42929c..59829aea07 100644 --- a/pkg/api/server.go +++ b/pkg/api/server.go @@ -229,6 +229,7 @@ func (a *ApiServer) Start() error { workspaceController.POST("/:workspaceId/stop", workspace.StopWorkspace) workspaceController.POST("/:workspaceId/restart", workspace.RestartWorkspace) workspaceController.POST("/:workspaceId/provider-metadata", workspace.UpdateWorkspaceProviderMetadata) + workspaceController.POST("/:workspaceId/labels", workspace.UpdateWorkspaceLabels) } workspaceTemplateController := protected.Group("/workspace-template") diff --git a/pkg/apiclient/README.md b/pkg/apiclient/README.md index 683a8d36bc..4fb781f146 100644 --- a/pkg/apiclient/README.md +++ b/pkg/apiclient/README.md @@ -149,6 +149,7 @@ Class | Method | HTTP request | Description *WorkspaceAPI* | [**RestartWorkspace**](docs/WorkspaceAPI.md#restartworkspace) | **Post** /workspace/{workspaceId}/restart | Restart workspace *WorkspaceAPI* | [**StartWorkspace**](docs/WorkspaceAPI.md#startworkspace) | **Post** /workspace/{workspaceId}/start | Start workspace *WorkspaceAPI* | [**StopWorkspace**](docs/WorkspaceAPI.md#stopworkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +*WorkspaceAPI* | [**UpdateWorkspaceLabels**](docs/WorkspaceAPI.md#updateworkspacelabels) | **Post** /workspace/{workspaceId}/labels | Update workspace labels *WorkspaceAPI* | [**UpdateWorkspaceMetadata**](docs/WorkspaceAPI.md#updateworkspacemetadata) | **Post** /workspace/{workspaceId}/metadata | Update workspace metadata *WorkspaceAPI* | [**UpdateWorkspaceProviderMetadata**](docs/WorkspaceAPI.md#updateworkspaceprovidermetadata) | **Post** /workspace/{workspaceId}/provider-metadata | Update workspace provider metadata *WorkspaceTemplateAPI* | [**DeleteWorkspaceTemplate**](docs/WorkspaceTemplateAPI.md#deleteworkspacetemplate) | **Delete** /workspace-template/{templateName} | Delete workspace template data diff --git a/pkg/apiclient/api/openapi.yaml b/pkg/apiclient/api/openapi.yaml index 3d1deecce9..9ffac0fd10 100644 --- a/pkg/apiclient/api/openapi.yaml +++ b/pkg/apiclient/api/openapi.yaml @@ -1330,6 +1330,12 @@ paths: get: description: List workspaces operationId: ListWorkspaces + parameters: + - description: JSON encoded labels + in: query + name: labels + schema: + type: string responses: "200": content: @@ -1663,6 +1669,37 @@ paths: summary: Find workspace tags: - workspace + /workspace/{workspaceId}/labels: + post: + description: Update workspace labels + operationId: UpdateWorkspaceLabels + parameters: + - description: Workspace ID or Name + in: path + name: workspaceId + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + additionalProperties: + type: string + type: object + description: Labels + required: true + responses: + "200": + content: + '*/*': + schema: + $ref: '#/components/schemas/WorkspaceDTO' + description: OK + summary: Update workspace labels + tags: + - workspace + x-codegen-request-body-name: labels /workspace/{workspaceId}/metadata: post: description: Update workspace metadata @@ -3220,6 +3257,8 @@ components: sha: sha url: url user: user + labels: + key: labels properties: buildConfig: $ref: '#/components/schemas/BuildConfig' @@ -3233,6 +3272,10 @@ components: type: string image: type: string + labels: + additionalProperties: + type: string + type: object name: type: string source: @@ -3244,6 +3287,7 @@ components: required: - envVars - id + - labels - name - source - targetId @@ -4855,6 +4899,8 @@ components: cloneTarget: null sha: sha url: url + labels: + key: labels target: default: true metadata: @@ -4964,6 +5010,8 @@ components: cloneTarget: null sha: sha url: url + labels: + key: labels target: default: true metadata: @@ -5267,6 +5315,8 @@ components: cloneTarget: null sha: sha url: url + labels: + key: labels target: default: true metadata: @@ -5355,6 +5405,10 @@ components: type: string image: type: string + labels: + additionalProperties: + type: string + type: object lastJob: $ref: '#/components/schemas/Job' lastJobId: @@ -5378,6 +5432,7 @@ components: - envVars - id - image + - labels - name - repository - target @@ -5422,6 +5477,8 @@ components: cloneTarget: null sha: sha url: url + labels: + key: labels target: default: true metadata: @@ -5514,6 +5571,10 @@ components: type: string image: type: string + labels: + additionalProperties: + type: string + type: object lastJob: $ref: '#/components/schemas/Job' lastJobId: @@ -5539,6 +5600,7 @@ components: - envVars - id - image + - labels - name - repository - state @@ -5616,6 +5678,8 @@ components: key: envVars name: name user: user + labels: + key: labels repositoryUrl: repositoryUrl properties: buildConfig: @@ -5630,6 +5694,10 @@ components: type: string image: type: string + labels: + additionalProperties: + type: string + type: object name: type: string prebuilds: @@ -5644,6 +5712,7 @@ components: - default - envVars - image + - labels - name - repositoryUrl - user diff --git a/pkg/apiclient/api_workspace.go b/pkg/apiclient/api_workspace.go index 1e6497dbde..f270784b5c 100644 --- a/pkg/apiclient/api_workspace.go +++ b/pkg/apiclient/api_workspace.go @@ -385,6 +385,13 @@ func (a *WorkspaceAPIService) FindWorkspaceExecute(r ApiFindWorkspaceRequest) (* type ApiListWorkspacesRequest struct { ctx context.Context ApiService *WorkspaceAPIService + labels *string +} + +// JSON encoded labels +func (r ApiListWorkspacesRequest) Labels(labels string) ApiListWorkspacesRequest { + r.labels = &labels + return r } func (r ApiListWorkspacesRequest) Execute() ([]WorkspaceDTO, *http.Response, error) { @@ -428,6 +435,9 @@ func (a *WorkspaceAPIService) ListWorkspacesExecute(r ApiListWorkspacesRequest) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + if r.labels != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "labels", r.labels, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -814,6 +824,136 @@ func (a *WorkspaceAPIService) StopWorkspaceExecute(r ApiStopWorkspaceRequest) (* return localVarHTTPResponse, nil } +type ApiUpdateWorkspaceLabelsRequest struct { + ctx context.Context + ApiService *WorkspaceAPIService + workspaceId string + labels *map[string]string +} + +// Labels +func (r ApiUpdateWorkspaceLabelsRequest) Labels(labels map[string]string) ApiUpdateWorkspaceLabelsRequest { + r.labels = &labels + return r +} + +func (r ApiUpdateWorkspaceLabelsRequest) Execute() (*WorkspaceDTO, *http.Response, error) { + return r.ApiService.UpdateWorkspaceLabelsExecute(r) +} + +/* +UpdateWorkspaceLabels Update workspace labels + +Update workspace labels + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param workspaceId Workspace ID or Name + @return ApiUpdateWorkspaceLabelsRequest +*/ +func (a *WorkspaceAPIService) UpdateWorkspaceLabels(ctx context.Context, workspaceId string) ApiUpdateWorkspaceLabelsRequest { + return ApiUpdateWorkspaceLabelsRequest{ + ApiService: a, + ctx: ctx, + workspaceId: workspaceId, + } +} + +// Execute executes the request +// +// @return WorkspaceDTO +func (a *WorkspaceAPIService) UpdateWorkspaceLabelsExecute(r ApiUpdateWorkspaceLabelsRequest) (*WorkspaceDTO, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *WorkspaceDTO + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "WorkspaceAPIService.UpdateWorkspaceLabels") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/workspace/{workspaceId}/labels" + localVarPath = strings.Replace(localVarPath, "{"+"workspaceId"+"}", url.PathEscape(parameterValueToString(r.workspaceId, "workspaceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.labels == nil { + return localVarReturnValue, nil, reportError("labels is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"*/*"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.labels + if r.ctx != nil { + // API Key Authentication + if auth, ok := r.ctx.Value(ContextAPIKeys).(map[string]APIKey); ok { + if apiKey, ok := auth["Bearer"]; ok { + var key string + if apiKey.Prefix != "" { + key = apiKey.Prefix + " " + apiKey.Key + } else { + key = apiKey.Key + } + localVarHeaderParams["Authorization"] = key + } + } + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ApiUpdateWorkspaceMetadataRequest struct { ctx context.Context ApiService *WorkspaceAPIService diff --git a/pkg/apiclient/docs/CreateWorkspaceDTO.md b/pkg/apiclient/docs/CreateWorkspaceDTO.md index 20346de368..6f43c352b2 100644 --- a/pkg/apiclient/docs/CreateWorkspaceDTO.md +++ b/pkg/apiclient/docs/CreateWorkspaceDTO.md @@ -9,6 +9,7 @@ Name | Type | Description | Notes **GitProviderConfigId** | Pointer to **string** | | [optional] **Id** | **string** | | **Image** | Pointer to **string** | | [optional] +**Labels** | **map[string]string** | | **Name** | **string** | | **Source** | [**CreateWorkspaceSourceDTO**](CreateWorkspaceSourceDTO.md) | | **TargetId** | **string** | | @@ -18,7 +19,7 @@ Name | Type | Description | Notes ### NewCreateWorkspaceDTO -`func NewCreateWorkspaceDTO(envVars map[string]string, id string, name string, source CreateWorkspaceSourceDTO, targetId string, ) *CreateWorkspaceDTO` +`func NewCreateWorkspaceDTO(envVars map[string]string, id string, labels map[string]string, name string, source CreateWorkspaceSourceDTO, targetId string, ) *CreateWorkspaceDTO` NewCreateWorkspaceDTO instantiates a new CreateWorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -148,6 +149,26 @@ SetImage sets Image field to given value. HasImage returns a boolean if a field has been set. +### GetLabels + +`func (o *CreateWorkspaceDTO) GetLabels() map[string]string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *CreateWorkspaceDTO) GetLabelsOk() (*map[string]string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *CreateWorkspaceDTO) SetLabels(v map[string]string)` + +SetLabels sets Labels field to given value. + + ### GetName `func (o *CreateWorkspaceDTO) GetName() string` diff --git a/pkg/apiclient/docs/Workspace.md b/pkg/apiclient/docs/Workspace.md index 0c3d113ce8..bf37d97f4e 100644 --- a/pkg/apiclient/docs/Workspace.md +++ b/pkg/apiclient/docs/Workspace.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **GitProviderConfigId** | Pointer to **string** | | [optional] **Id** | **string** | | **Image** | **string** | | +**Labels** | **map[string]string** | | **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **LastJobId** | Pointer to **string** | | [optional] **Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] @@ -24,7 +25,7 @@ Name | Type | Description | Notes ### NewWorkspace -`func NewWorkspace(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string, ) *Workspace` +`func NewWorkspace(apiKey string, envVars map[string]string, id string, image string, labels map[string]string, name string, repository GitRepository, target Target, targetId string, user string, ) *Workspace` NewWorkspace instantiates a new Workspace object This constructor will assign default values to properties that have it defined, @@ -169,6 +170,26 @@ and a boolean to check if the value has been set. SetImage sets Image field to given value. +### GetLabels + +`func (o *Workspace) GetLabels() map[string]string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *Workspace) GetLabelsOk() (*map[string]string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *Workspace) SetLabels(v map[string]string)` + +SetLabels sets Labels field to given value. + + ### GetLastJob `func (o *Workspace) GetLastJob() Job` diff --git a/pkg/apiclient/docs/WorkspaceAPI.md b/pkg/apiclient/docs/WorkspaceAPI.md index 09ee031e82..7bdcdb517b 100644 --- a/pkg/apiclient/docs/WorkspaceAPI.md +++ b/pkg/apiclient/docs/WorkspaceAPI.md @@ -11,6 +11,7 @@ Method | HTTP request | Description [**RestartWorkspace**](WorkspaceAPI.md#RestartWorkspace) | **Post** /workspace/{workspaceId}/restart | Restart workspace [**StartWorkspace**](WorkspaceAPI.md#StartWorkspace) | **Post** /workspace/{workspaceId}/start | Start workspace [**StopWorkspace**](WorkspaceAPI.md#StopWorkspace) | **Post** /workspace/{workspaceId}/stop | Stop workspace +[**UpdateWorkspaceLabels**](WorkspaceAPI.md#UpdateWorkspaceLabels) | **Post** /workspace/{workspaceId}/labels | Update workspace labels [**UpdateWorkspaceMetadata**](WorkspaceAPI.md#UpdateWorkspaceMetadata) | **Post** /workspace/{workspaceId}/metadata | Update workspace metadata [**UpdateWorkspaceProviderMetadata**](WorkspaceAPI.md#UpdateWorkspaceProviderMetadata) | **Post** /workspace/{workspaceId}/provider-metadata | Update workspace provider metadata @@ -37,7 +38,7 @@ import ( ) func main() { - workspace := *openapiclient.NewCreateWorkspaceDTO(map[string]string{"key": "Inner_example"}, "Id_example", "Name_example", *openapiclient.NewCreateWorkspaceSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")), "TargetId_example") // CreateWorkspaceDTO | Create workspace + workspace := *openapiclient.NewCreateWorkspaceDTO(map[string]string{"key": "Inner_example"}, "Id_example", map[string]string{"key": "Inner_example"}, "Name_example", *openapiclient.NewCreateWorkspaceSourceDTO(*openapiclient.NewGitRepository("Branch_example", "Id_example", "Name_example", "Owner_example", "Sha_example", "Source_example", "Url_example")), "TargetId_example") // CreateWorkspaceDTO | Create workspace configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) @@ -224,7 +225,7 @@ Name | Type | Description | Notes ## ListWorkspaces -> []WorkspaceDTO ListWorkspaces(ctx).Execute() +> []WorkspaceDTO ListWorkspaces(ctx).Labels(labels).Execute() List workspaces @@ -243,10 +244,11 @@ import ( ) func main() { + labels := "labels_example" // string | JSON encoded labels (optional) configuration := openapiclient.NewConfiguration() apiClient := openapiclient.NewAPIClient(configuration) - resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Execute() + resp, r, err := apiClient.WorkspaceAPI.ListWorkspaces(context.Background()).Labels(labels).Execute() if err != nil { fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.ListWorkspaces``: %v\n", err) fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) @@ -258,13 +260,17 @@ func main() { ### Path Parameters -This endpoint does not need any parameter. + ### Other Parameters Other parameters are passed through a pointer to a apiListWorkspacesRequest struct via the builder pattern +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **labels** | **string** | JSON encoded labels | + ### Return type [**[]WorkspaceDTO**](WorkspaceDTO.md) @@ -487,6 +493,78 @@ Name | Type | Description | Notes [[Back to README]](../README.md) +## UpdateWorkspaceLabels + +> WorkspaceDTO UpdateWorkspaceLabels(ctx, workspaceId).Labels(labels).Execute() + +Update workspace labels + + + +### Example + +```go +package main + +import ( + "context" + "fmt" + "os" + openapiclient "github.com/GIT_USER_ID/GIT_REPO_ID/apiclient" +) + +func main() { + workspaceId := "workspaceId_example" // string | Workspace ID or Name + labels := map[string]string{"key": "Inner_example"} // map[string]string | Labels + + configuration := openapiclient.NewConfiguration() + apiClient := openapiclient.NewAPIClient(configuration) + resp, r, err := apiClient.WorkspaceAPI.UpdateWorkspaceLabels(context.Background(), workspaceId).Labels(labels).Execute() + if err != nil { + fmt.Fprintf(os.Stderr, "Error when calling `WorkspaceAPI.UpdateWorkspaceLabels``: %v\n", err) + fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r) + } + // response from `UpdateWorkspaceLabels`: WorkspaceDTO + fmt.Fprintf(os.Stdout, "Response from `WorkspaceAPI.UpdateWorkspaceLabels`: %v\n", resp) +} +``` + +### Path Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- +**ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. +**workspaceId** | **string** | Workspace ID or Name | + +### Other Parameters + +Other parameters are passed through a pointer to a apiUpdateWorkspaceLabelsRequest struct via the builder pattern + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + + **labels** | **map[string]string** | Labels | + +### Return type + +[**WorkspaceDTO**](WorkspaceDTO.md) + +### Authorization + +[Bearer](../README.md#Bearer) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) +[[Back to Model list]](../README.md#documentation-for-models) +[[Back to README]](../README.md) + + ## UpdateWorkspaceMetadata > UpdateWorkspaceMetadata(ctx, workspaceId).WorkspaceMetadata(workspaceMetadata).Execute() diff --git a/pkg/apiclient/docs/WorkspaceDTO.md b/pkg/apiclient/docs/WorkspaceDTO.md index 1bf7bfce25..8e1f5e327a 100644 --- a/pkg/apiclient/docs/WorkspaceDTO.md +++ b/pkg/apiclient/docs/WorkspaceDTO.md @@ -10,6 +10,7 @@ Name | Type | Description | Notes **GitProviderConfigId** | Pointer to **string** | | [optional] **Id** | **string** | | **Image** | **string** | | +**Labels** | **map[string]string** | | **LastJob** | Pointer to [**Job**](Job.md) | | [optional] **LastJobId** | Pointer to **string** | | [optional] **Metadata** | Pointer to [**WorkspaceMetadata**](WorkspaceMetadata.md) | | [optional] @@ -25,7 +26,7 @@ Name | Type | Description | Notes ### NewWorkspaceDTO -`func NewWorkspaceDTO(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string, ) *WorkspaceDTO` +`func NewWorkspaceDTO(apiKey string, envVars map[string]string, id string, image string, labels map[string]string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string, ) *WorkspaceDTO` NewWorkspaceDTO instantiates a new WorkspaceDTO object This constructor will assign default values to properties that have it defined, @@ -170,6 +171,26 @@ and a boolean to check if the value has been set. SetImage sets Image field to given value. +### GetLabels + +`func (o *WorkspaceDTO) GetLabels() map[string]string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *WorkspaceDTO) GetLabelsOk() (*map[string]string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *WorkspaceDTO) SetLabels(v map[string]string)` + +SetLabels sets Labels field to given value. + + ### GetLastJob `func (o *WorkspaceDTO) GetLastJob() Job` diff --git a/pkg/apiclient/docs/WorkspaceTemplate.md b/pkg/apiclient/docs/WorkspaceTemplate.md index d126fd661e..45b72cc64b 100644 --- a/pkg/apiclient/docs/WorkspaceTemplate.md +++ b/pkg/apiclient/docs/WorkspaceTemplate.md @@ -9,6 +9,7 @@ Name | Type | Description | Notes **EnvVars** | **map[string]string** | | **GitProviderConfigId** | Pointer to **string** | | [optional] **Image** | **string** | | +**Labels** | **map[string]string** | | **Name** | **string** | | **Prebuilds** | Pointer to [**[]PrebuildConfig**](PrebuildConfig.md) | | [optional] **RepositoryUrl** | **string** | | @@ -18,7 +19,7 @@ Name | Type | Description | Notes ### NewWorkspaceTemplate -`func NewWorkspaceTemplate(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string, ) *WorkspaceTemplate` +`func NewWorkspaceTemplate(default_ bool, envVars map[string]string, image string, labels map[string]string, name string, repositoryUrl string, user string, ) *WorkspaceTemplate` NewWorkspaceTemplate instantiates a new WorkspaceTemplate object This constructor will assign default values to properties that have it defined, @@ -143,6 +144,26 @@ and a boolean to check if the value has been set. SetImage sets Image field to given value. +### GetLabels + +`func (o *WorkspaceTemplate) GetLabels() map[string]string` + +GetLabels returns the Labels field if non-nil, zero value otherwise. + +### GetLabelsOk + +`func (o *WorkspaceTemplate) GetLabelsOk() (*map[string]string, bool)` + +GetLabelsOk returns a tuple with the Labels field if it's non-nil, zero value otherwise +and a boolean to check if the value has been set. + +### SetLabels + +`func (o *WorkspaceTemplate) SetLabels(v map[string]string)` + +SetLabels sets Labels field to given value. + + ### GetName `func (o *WorkspaceTemplate) GetName() string` diff --git a/pkg/apiclient/model_create_workspace_dto.go b/pkg/apiclient/model_create_workspace_dto.go index dab99f5460..6cecf18ff9 100644 --- a/pkg/apiclient/model_create_workspace_dto.go +++ b/pkg/apiclient/model_create_workspace_dto.go @@ -26,6 +26,7 @@ type CreateWorkspaceDTO struct { GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` Id string `json:"id"` Image *string `json:"image,omitempty"` + Labels map[string]string `json:"labels"` Name string `json:"name"` Source CreateWorkspaceSourceDTO `json:"source"` TargetId string `json:"targetId"` @@ -38,10 +39,11 @@ type _CreateWorkspaceDTO CreateWorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewCreateWorkspaceDTO(envVars map[string]string, id string, name string, source CreateWorkspaceSourceDTO, targetId string) *CreateWorkspaceDTO { +func NewCreateWorkspaceDTO(envVars map[string]string, id string, labels map[string]string, name string, source CreateWorkspaceSourceDTO, targetId string) *CreateWorkspaceDTO { this := CreateWorkspaceDTO{} this.EnvVars = envVars this.Id = id + this.Labels = labels this.Name = name this.Source = source this.TargetId = targetId @@ -200,6 +202,30 @@ func (o *CreateWorkspaceDTO) SetImage(v string) { o.Image = &v } +// GetLabels returns the Labels field value +func (o *CreateWorkspaceDTO) GetLabels() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value +// and a boolean to check if the value has been set. +func (o *CreateWorkspaceDTO) GetLabelsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.Labels, true +} + +// SetLabels sets field value +func (o *CreateWorkspaceDTO) SetLabels(v map[string]string) { + o.Labels = v +} + // GetName returns the Name field value func (o *CreateWorkspaceDTO) GetName() string { if o == nil { @@ -325,6 +351,7 @@ func (o CreateWorkspaceDTO) ToMap() (map[string]interface{}, error) { if !IsNil(o.Image) { toSerialize["image"] = o.Image } + toSerialize["labels"] = o.Labels toSerialize["name"] = o.Name toSerialize["source"] = o.Source toSerialize["targetId"] = o.TargetId @@ -341,6 +368,7 @@ func (o *CreateWorkspaceDTO) UnmarshalJSON(data []byte) (err error) { requiredProperties := []string{ "envVars", "id", + "labels", "name", "source", "targetId", diff --git a/pkg/apiclient/model_workspace.go b/pkg/apiclient/model_workspace.go index 44294c82d5..c2d580b0c5 100644 --- a/pkg/apiclient/model_workspace.go +++ b/pkg/apiclient/model_workspace.go @@ -27,6 +27,7 @@ type Workspace struct { GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` Id string `json:"id"` Image string `json:"image"` + Labels map[string]string `json:"labels"` LastJob *Job `json:"lastJob,omitempty"` LastJobId *string `json:"lastJobId,omitempty"` Metadata *WorkspaceMetadata `json:"metadata,omitempty"` @@ -44,12 +45,13 @@ type _Workspace Workspace // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspace(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, target Target, targetId string, user string) *Workspace { +func NewWorkspace(apiKey string, envVars map[string]string, id string, image string, labels map[string]string, name string, repository GitRepository, target Target, targetId string, user string) *Workspace { this := Workspace{} this.ApiKey = apiKey this.EnvVars = envVars this.Id = id this.Image = image + this.Labels = labels this.Name = name this.Repository = repository this.Target = target @@ -226,6 +228,30 @@ func (o *Workspace) SetImage(v string) { o.Image = v } +// GetLabels returns the Labels field value +func (o *Workspace) GetLabels() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value +// and a boolean to check if the value has been set. +func (o *Workspace) GetLabelsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.Labels, true +} + +// SetLabels sets field value +func (o *Workspace) SetLabels(v map[string]string) { + o.Labels = v +} + // GetLastJob returns the LastJob field value if set, zero value otherwise. func (o *Workspace) GetLastJob() Job { if o == nil || IsNil(o.LastJob) { @@ -494,6 +520,7 @@ func (o Workspace) ToMap() (map[string]interface{}, error) { } toSerialize["id"] = o.Id toSerialize["image"] = o.Image + toSerialize["labels"] = o.Labels if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } @@ -523,6 +550,7 @@ func (o *Workspace) UnmarshalJSON(data []byte) (err error) { "envVars", "id", "image", + "labels", "name", "repository", "target", diff --git a/pkg/apiclient/model_workspace_dto.go b/pkg/apiclient/model_workspace_dto.go index dc80d5132b..f19881e444 100644 --- a/pkg/apiclient/model_workspace_dto.go +++ b/pkg/apiclient/model_workspace_dto.go @@ -27,6 +27,7 @@ type WorkspaceDTO struct { GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` Id string `json:"id"` Image string `json:"image"` + Labels map[string]string `json:"labels"` LastJob *Job `json:"lastJob,omitempty"` LastJobId *string `json:"lastJobId,omitempty"` Metadata *WorkspaceMetadata `json:"metadata,omitempty"` @@ -45,12 +46,13 @@ type _WorkspaceDTO WorkspaceDTO // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceDTO(apiKey string, envVars map[string]string, id string, image string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string) *WorkspaceDTO { +func NewWorkspaceDTO(apiKey string, envVars map[string]string, id string, image string, labels map[string]string, name string, repository GitRepository, state ResourceState, target Target, targetId string, user string) *WorkspaceDTO { this := WorkspaceDTO{} this.ApiKey = apiKey this.EnvVars = envVars this.Id = id this.Image = image + this.Labels = labels this.Name = name this.Repository = repository this.State = state @@ -228,6 +230,30 @@ func (o *WorkspaceDTO) SetImage(v string) { o.Image = v } +// GetLabels returns the Labels field value +func (o *WorkspaceDTO) GetLabels() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value +// and a boolean to check if the value has been set. +func (o *WorkspaceDTO) GetLabelsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.Labels, true +} + +// SetLabels sets field value +func (o *WorkspaceDTO) SetLabels(v map[string]string) { + o.Labels = v +} + // GetLastJob returns the LastJob field value if set, zero value otherwise. func (o *WorkspaceDTO) GetLastJob() Job { if o == nil || IsNil(o.LastJob) { @@ -520,6 +546,7 @@ func (o WorkspaceDTO) ToMap() (map[string]interface{}, error) { } toSerialize["id"] = o.Id toSerialize["image"] = o.Image + toSerialize["labels"] = o.Labels if !IsNil(o.LastJob) { toSerialize["lastJob"] = o.LastJob } @@ -550,6 +577,7 @@ func (o *WorkspaceDTO) UnmarshalJSON(data []byte) (err error) { "envVars", "id", "image", + "labels", "name", "repository", "state", diff --git a/pkg/apiclient/model_workspace_template.go b/pkg/apiclient/model_workspace_template.go index 4f3b19f28d..634d8a21cf 100644 --- a/pkg/apiclient/model_workspace_template.go +++ b/pkg/apiclient/model_workspace_template.go @@ -26,6 +26,7 @@ type WorkspaceTemplate struct { EnvVars map[string]string `json:"envVars"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty"` Image string `json:"image"` + Labels map[string]string `json:"labels"` Name string `json:"name"` Prebuilds []PrebuildConfig `json:"prebuilds,omitempty"` RepositoryUrl string `json:"repositoryUrl"` @@ -38,11 +39,12 @@ type _WorkspaceTemplate WorkspaceTemplate // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewWorkspaceTemplate(default_ bool, envVars map[string]string, image string, name string, repositoryUrl string, user string) *WorkspaceTemplate { +func NewWorkspaceTemplate(default_ bool, envVars map[string]string, image string, labels map[string]string, name string, repositoryUrl string, user string) *WorkspaceTemplate { this := WorkspaceTemplate{} this.Default = default_ this.EnvVars = envVars this.Image = image + this.Labels = labels this.Name = name this.RepositoryUrl = repositoryUrl this.User = user @@ -193,6 +195,30 @@ func (o *WorkspaceTemplate) SetImage(v string) { o.Image = v } +// GetLabels returns the Labels field value +func (o *WorkspaceTemplate) GetLabels() map[string]string { + if o == nil { + var ret map[string]string + return ret + } + + return o.Labels +} + +// GetLabelsOk returns a tuple with the Labels field value +// and a boolean to check if the value has been set. +func (o *WorkspaceTemplate) GetLabelsOk() (*map[string]string, bool) { + if o == nil { + return nil, false + } + return &o.Labels, true +} + +// SetLabels sets field value +func (o *WorkspaceTemplate) SetLabels(v map[string]string) { + o.Labels = v +} + // GetName returns the Name field value func (o *WorkspaceTemplate) GetName() string { if o == nil { @@ -316,6 +342,7 @@ func (o WorkspaceTemplate) ToMap() (map[string]interface{}, error) { toSerialize["gitProviderConfigId"] = o.GitProviderConfigId } toSerialize["image"] = o.Image + toSerialize["labels"] = o.Labels toSerialize["name"] = o.Name if !IsNil(o.Prebuilds) { toSerialize["prebuilds"] = o.Prebuilds @@ -333,6 +360,7 @@ func (o *WorkspaceTemplate) UnmarshalJSON(data []byte) (err error) { "default", "envVars", "image", + "labels", "name", "repositoryUrl", "user", diff --git a/pkg/cmd/common/configuration_flags.go b/pkg/cmd/common/configuration_flags.go index aabf4588ad..01d6dc4822 100644 --- a/pkg/cmd/common/configuration_flags.go +++ b/pkg/cmd/common/configuration_flags.go @@ -5,6 +5,7 @@ package common import ( "fmt" + "strings" views_util "github.com/daytonaio/daytona/pkg/views/util" "github.com/spf13/cobra" @@ -19,6 +20,7 @@ type WorkspaceConfigurationFlags struct { EnvVars *[]string Manual *bool GitProviderConfig *string + Labels *[]string } func AddWorkspaceConfigurationFlags(cmd *cobra.Command, flags WorkspaceConfigurationFlags, multiWorkspaceFlagException bool) { @@ -29,6 +31,7 @@ func AddWorkspaceConfigurationFlags(cmd *cobra.Command, flags WorkspaceConfigura cmd.Flags().StringArrayVar(flags.EnvVars, "env", []string{}, "Specify environment variables (e.g. --env 'KEY1=VALUE1' --env 'KEY2=VALUE2' ...')") cmd.Flags().BoolVar(flags.Manual, "manual", false, "Manually enter the Git repository") cmd.Flags().StringVar(flags.GitProviderConfig, "git-provider-config", "", "Specify the Git provider configuration ID or alias") + cmd.Flags().StringArrayVar(flags.Labels, "label", []string{}, "Specify labels (e.g. --label 'label.key1=VALUE1' --label 'label.key2=VALUE2' ...)") cmd.MarkFlagsMutuallyExclusive("builder", "custom-image") cmd.MarkFlagsMutuallyExclusive("builder", "custom-image-user") @@ -46,5 +49,20 @@ func AddWorkspaceConfigurationFlags(cmd *cobra.Command, flags WorkspaceConfigura } func CheckAnyWorkspaceConfigurationFlagSet(flags WorkspaceConfigurationFlags) bool { - return *flags.GitProviderConfig != "" || *flags.CustomImage != "" || *flags.CustomImageUser != "" || *flags.DevcontainerPath != "" || *flags.Builder != "" || len(*flags.EnvVars) > 0 + return *flags.GitProviderConfig != "" || *flags.CustomImage != "" || *flags.CustomImageUser != "" || *flags.DevcontainerPath != "" || *flags.Builder != "" || len(*flags.EnvVars) > 0 || len(*flags.Labels) > 0 +} + +func MapKeyValue(arr []string) (map[string]string, error) { + result := map[string]string{} + + for _, str := range arr { + parts := strings.SplitN(str, "=", 2) + if len(parts) == 2 { + result[parts[0]] = parts[1] + } else { + return nil, fmt.Errorf("invalid format: %s", str) + } + } + + return result, nil } diff --git a/pkg/cmd/workspace/create/add_from_template.go b/pkg/cmd/workspace/create/add_from_template.go index d02fc0e053..30b8f82421 100644 --- a/pkg/cmd/workspace/create/add_from_template.go +++ b/pkg/cmd/workspace/create/add_from_template.go @@ -54,6 +54,7 @@ func AddWorkspaceFromTemplate(ctx context.Context, params AddWorkspaceFromTempla Image: ¶ms.WorkspaceTemplate.Image, User: ¶ms.WorkspaceTemplate.User, EnvVars: params.WorkspaceTemplate.EnvVars, + Labels: params.WorkspaceTemplate.Labels, } *params.Workspaces = append(*params.Workspaces, *workspace) diff --git a/pkg/cmd/workspace/create/cmd.go b/pkg/cmd/workspace/create/cmd.go index edc2b3c853..68f7afc15f 100644 --- a/pkg/cmd/workspace/create/cmd.go +++ b/pkg/cmd/workspace/create/cmd.go @@ -292,6 +292,7 @@ var workspaceConfigurationFlags = cmd_common.WorkspaceConfigurationFlags{ EnvVars: new([]string), Manual: new(bool), GitProviderConfig: new(string), + Labels: new([]string), } func init() { diff --git a/pkg/cmd/workspace/create/creation_data.go b/pkg/cmd/workspace/create/creation_data.go index b1c35b5f45..5c27be3587 100644 --- a/pkg/cmd/workspace/create/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -282,16 +282,26 @@ func GetCreateWorkspaceDtoFromFlags(workspaceConfigurationFlags cmd_common.Works envVars := make(map[string]string) - for _, envVar := range *workspaceConfigurationFlags.EnvVars { - parts := strings.SplitN(envVar, "=", 2) - if len(parts) == 2 { - envVars[parts[0]] = parts[1] - } else { - return nil, fmt.Errorf("Invalid environment variable format: %s\n", envVar) + if workspaceConfigurationFlags.EnvVars != nil { + var err error + envVars, err = cmd_common.MapKeyValue(*workspaceConfigurationFlags.EnvVars) + if err != nil { + return nil, err + } + } + + labels := make(map[string]string) + + if workspaceConfigurationFlags.Labels != nil { + var err error + labels, err = cmd_common.MapKeyValue(*workspaceConfigurationFlags.Labels) + if err != nil { + return nil, err } } workspace.EnvVars = envVars + workspace.Labels = labels return workspace, nil } diff --git a/pkg/cmd/workspace/list.go b/pkg/cmd/workspace/list.go index 71e9dc703d..25bbe1082d 100644 --- a/pkg/cmd/workspace/list.go +++ b/pkg/cmd/workspace/list.go @@ -5,6 +5,7 @@ package workspace import ( "context" + "encoding/json" "github.com/daytonaio/daytona/cmd/daytona/config" "github.com/daytonaio/daytona/internal/util" @@ -15,6 +16,8 @@ import ( "github.com/spf13/cobra" ) +var labelFilters []string + var ListCmd = &cobra.Command{ Use: "list", Short: "List workspaces", @@ -30,7 +33,17 @@ var ListCmd = &cobra.Command{ return err } - workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute() + labels, err := common.MapKeyValue(labelFilters) + if err != nil { + return err + } + + encoded, err := json.Marshal(labels) + if err != nil { + return err + } + + workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Labels(string(encoded)).Execute() if err != nil { return apiclient.HandleErrorResponse(res, err) } @@ -66,5 +79,6 @@ var ListCmd = &cobra.Command{ } func init() { + ListCmd.Flags().StringSliceVarP(&labelFilters, "label", "l", nil, "Filter by label") format.RegisterFormatFlag(ListCmd) } diff --git a/pkg/cmd/workspacetemplate/create.go b/pkg/cmd/workspacetemplate/create.go index ae945f0f4b..f42a8b2214 100644 --- a/pkg/cmd/workspacetemplate/create.go +++ b/pkg/cmd/workspacetemplate/create.go @@ -286,6 +286,7 @@ var workspaceConfigurationFlags = cmd_common.WorkspaceConfigurationFlags{ EnvVars: new([]string), Manual: new(bool), GitProviderConfig: new(string), + Labels: new([]string), } func init() { diff --git a/pkg/docker/stop_test.go b/pkg/docker/stop_test.go index 18b6ff74e4..2848c436fe 100644 --- a/pkg/docker/stop_test.go +++ b/pkg/docker/stop_test.go @@ -15,7 +15,9 @@ func (s *DockerClientTestSuite) TestStopWorkspace() { containerName := s.dockerClient.GetWorkspaceContainerName(workspace1) - s.mockClient.On("ContainerStop", mock.Anything, containerName, container.StopOptions{}).Return(nil) + s.mockClient.On("ContainerStop", mock.Anything, containerName, container.StopOptions{ + Signal: "SIGKILL", + }).Return(nil) s.mockClient.On("ContainerInspect", mock.Anything, containerName).Return(types.ContainerJSON{ ContainerJSONBase: &types.ContainerJSONBase{ State: &types.ContainerState{ diff --git a/pkg/models/workspace.go b/pkg/models/workspace.go index 1ca3d698e1..c60fa98f07 100644 --- a/pkg/models/workspace.go +++ b/pkg/models/workspace.go @@ -18,6 +18,7 @@ type Workspace struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty" validate:"optional" gorm:"serializer:json"` Repository *gitprovider.GitRepository `json:"repository" validate:"required" gorm:"serializer:json;not null"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + Labels map[string]string `json:"labels" validate:"required" gorm:"serializer:json;not null"` TargetId string `json:"targetId" validate:"required" gorm:"not null"` Target Target `json:"target" validate:"required" gorm:"foreignKey:TargetId"` ApiKey string `json:"apiKey" validate:"required" gorm:"not null"` diff --git a/pkg/models/workspace_template.go b/pkg/models/workspace_template.go index 3aaa9434dc..015ae0148d 100644 --- a/pkg/models/workspace_template.go +++ b/pkg/models/workspace_template.go @@ -18,6 +18,7 @@ type WorkspaceTemplate struct { BuildConfig *BuildConfig `json:"buildConfig,omitempty" validate:"optional" gorm:"serializer:json"` RepositoryUrl string `json:"repositoryUrl" validate:"required" gorm:"not null"` EnvVars map[string]string `json:"envVars" validate:"required" gorm:"serializer:json;not null"` + Labels map[string]string `json:"labels" validate:"required" gorm:"serializer:json;not null"` IsDefault bool `json:"default" validate:"required" gorm:"not null"` Prebuilds []*PrebuildConfig `json:"prebuilds" validate:"optional" gorm:"serializer:json"` GitProviderConfigId *string `json:"gitProviderConfigId" validate:"optional"` diff --git a/pkg/server/workspaces/labels.go b/pkg/server/workspaces/labels.go new file mode 100644 index 0000000000..d4fbe607df --- /dev/null +++ b/pkg/server/workspaces/labels.go @@ -0,0 +1,49 @@ +// Copyright 2024 Daytona Platforms Inc. +// SPDX-License-Identifier: Apache-2.0 + +package workspaces + +import ( + "context" + + "github.com/daytonaio/daytona/pkg/models" + "github.com/daytonaio/daytona/pkg/services" + "github.com/daytonaio/daytona/pkg/telemetry" + log "github.com/sirupsen/logrus" +) + +func (s *WorkspaceService) UpdateLabels(ctx context.Context, workspaceId string, labels map[string]string) (*services.WorkspaceDTO, error) { + w, err := s.workspaceStore.Find(ctx, workspaceId) + if err != nil { + return nil, s.handleUpdateLabelsError(ctx, w, err) + } + + w.Labels = labels + + if err := s.workspaceStore.Save(ctx, w); err != nil { + return nil, s.handleUpdateLabelsError(ctx, w, err) + } + + return &services.WorkspaceDTO{Workspace: *w, State: w.GetState()}, s.handleUpdateLabelsError(ctx, w, nil) +} + +func (s *WorkspaceService) handleUpdateLabelsError(ctx context.Context, w *models.Workspace, err error) error { + if !telemetry.TelemetryEnabled(ctx) { + return err + } + + clientId := telemetry.ClientId(ctx) + + eventName := telemetry.WorkspaceEventLabelsUpdated + if err != nil { + eventName = telemetry.WorkspaceEventLabelsUpdateFailed + } + event := telemetry.NewWorkspaceEvent(eventName, w, err, nil) + + telemetryError := s.trackTelemetryEvent(event, clientId) + if telemetryError != nil { + log.Trace(telemetryError) + } + + return err +} diff --git a/pkg/server/workspaces/list.go b/pkg/server/workspaces/list.go index bfab5792ae..0660acb6f9 100644 --- a/pkg/server/workspaces/list.go +++ b/pkg/server/workspaces/list.go @@ -21,7 +21,7 @@ func (s *WorkspaceService) List(ctx context.Context, params services.WorkspaceRe for _, ws := range workspaces { state := ws.GetState() - if state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted { + if !matchesLabels(ws, params.Labels) || (state.Name == models.ResourceStateNameDeleted && !params.ShowDeleted) { continue } @@ -33,3 +33,17 @@ func (s *WorkspaceService) List(ctx context.Context, params services.WorkspaceRe return response, nil } + +func matchesLabels(w *models.Workspace, labels map[string]string) bool { + if labels == nil { + return true + } + + for k, v := range labels { + if w.Labels[k] != v { + return false + } + } + + return true +} diff --git a/pkg/server/workspaces/service_test.go b/pkg/server/workspaces/service_test.go index 6519477cbe..5542f36622 100644 --- a/pkg/server/workspaces/service_test.go +++ b/pkg/server/workspaces/service_test.go @@ -209,6 +209,19 @@ func TestWorkspaceService(t *testing.T) { ws.EnvVars = nil }) + t.Run("UpdateLabels", func(t *testing.T) { + labels := map[string]string{ + "test": "label", + } + + workspace, err := service.UpdateLabels(ctx, createWorkspaceDTO.Id, labels) + + require.Nil(t, err) + require.NotNil(t, workspace) + + require.Equal(t, labels, workspace.Labels) + }) + t.Run("CreateWorkspace fails when workspace already exists", func(t *testing.T) { _, err := service.Create(ctx, createWorkspaceDTO) require.NotNil(t, err) diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index a663aae7de..f12fc17ac5 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -25,6 +25,7 @@ type IWorkspaceService interface { UpdateMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error) UpdateProviderMetadata(ctx context.Context, workspaceId, metadata string) error UpdateLastJob(ctx context.Context, workspaceId, jobId string) error + UpdateLabels(ctx context.Context, workspaceId string, labels map[string]string) (*WorkspaceDTO, error) GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) GetWorkspaceLogWriter(ctx context.Context, workspaceId string) (io.WriteCloser, error) @@ -43,6 +44,7 @@ type CreateWorkspaceDTO struct { BuildConfig *models.BuildConfig `json:"buildConfig,omitempty" validate:"optional"` Source CreateWorkspaceSourceDTO `json:"source" validate:"required"` EnvVars map[string]string `json:"envVars" validate:"required"` + Labels map[string]string `json:"labels" validate:"required"` TargetId string `json:"targetId" validate:"required"` GitProviderConfigId *string `json:"gitProviderConfigId,omitempty" validate:"optional"` } // @name CreateWorkspaceDTO @@ -56,6 +58,7 @@ func (c *CreateWorkspaceDTO) ToWorkspace() *models.Workspace { EnvVars: c.EnvVars, TargetId: c.TargetId, GitProviderConfigId: c.GitProviderConfigId, + Labels: c.Labels, } if c.Image != nil { @@ -75,6 +78,7 @@ type CreateWorkspaceSourceDTO struct { type WorkspaceRetrievalParams struct { ShowDeleted bool + Labels map[string]string } var ( diff --git a/pkg/telemetry/workspace.go b/pkg/telemetry/workspace.go index e6cb7e9c53..3b2cca818e 100644 --- a/pkg/telemetry/workspace.go +++ b/pkg/telemetry/workspace.go @@ -23,6 +23,8 @@ const ( WorkspaceEventLifecycleDeletionFailed WorkspaceEventName = "workspace_lifecycle_deletion_failed" WorkspaceEventLifecycleForceDeleted WorkspaceEventName = "workspace_lifecycle_force_deleted" WorkspaceEventLifecycleForceDeletionFailed WorkspaceEventName = "workspace_lifecycle_force_deletion_failed" + WorkspaceEventLabelsUpdated WorkspaceEventName = "workspace_labels_updated" + WorkspaceEventLabelsUpdateFailed WorkspaceEventName = "workspace_label_update_failed" ) type workspaceEvent struct { @@ -60,6 +62,7 @@ func (e workspaceEvent) Props() map[string]interface{} { } props["builder"] = getBuilder(e.workspace.BuildConfig) props["is_local_runner"] = e.workspace.Target.TargetConfig.ProviderInfo.RunnerId == common.LOCAL_RUNNER_ID + props["n_labels"] = len(e.workspace.Labels) return props } diff --git a/pkg/views/workspace/info/view.go b/pkg/views/workspace/info/view.go index dab8568326..23affb1fde 100644 --- a/pkg/views/workspace/info/view.go +++ b/pkg/views/workspace/info/view.go @@ -62,6 +62,22 @@ func Render(workspace *apiclient.WorkspaceDTO, ide string, forceUnstyled bool) { output = views.GetStyledMainTitle("Workspace Info") + "\n" + output } + if len(workspace.Labels) > 0 { + labels := "" + i := 0 + for k, v := range workspace.Labels { + label := fmt.Sprintf("%s=%s\n", k, v) + if i == 0 { + labels += label + "\n" + } else { + labels += getInfoLine("", fmt.Sprintf("%s=%s\n", k, v)) + } + i++ + } + labels = strings.TrimSuffix(labels, "\n") + output += "\n" + strings.TrimSuffix(getInfoLine("Labels", labels), "\n") + } + renderTUIView(output, views.GetContainerBreakpointWidth(terminalWidth), isCreationView) } From 28084acd6a33bff7a9593955fa855421152801f6 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Thu, 16 Jan 2025 15:33:16 +0000 Subject: [PATCH 64/76] fix: tui clearing labels Signed-off-by: Ivan Dagelic --- pkg/views/workspace/create/configuration.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/views/workspace/create/configuration.go b/pkg/views/workspace/create/configuration.go index acd8fd087e..a182e31c97 100644 --- a/pkg/views/workspace/create/configuration.go +++ b/pkg/views/workspace/create/configuration.go @@ -74,6 +74,10 @@ func RunWorkspaceConfiguration(workspaceList *[]apiclient.CreateWorkspaceDTO, de return false, nil } + if currentWorkspace.Labels == nil { + currentWorkspace.Labels = make(map[string]string) + } + devContainerFilePath := defaults.DevcontainerFilePath builderChoice := views_util.AUTOMATIC From 2b1951f59c02ae43fa81a12256e2db363ee2ec62 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Thu, 16 Jan 2025 16:16:32 +0000 Subject: [PATCH 65/76] fix: hide empty field in target info Signed-off-by: Ivan Dagelic --- pkg/views/target/info/view.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/views/target/info/view.go b/pkg/views/target/info/view.go index b558f87f8b..96f709862a 100644 --- a/pkg/views/target/info/view.go +++ b/pkg/views/target/info/view.go @@ -52,9 +52,11 @@ func Render(target *apiclient.TargetDTO, forceUnstyled bool) { output += getInfoLine("# Workspaces", fmt.Sprint(len(target.Workspaces))) + "\n" - output += getInfoLine("Options", target.TargetConfig.Options) + "\n" + if target.TargetConfig.Options != "" { + output += getInfoLine("Options", target.TargetConfig.Options) + "\n" + } - if target.ProviderMetadata != nil { + if target.ProviderMetadata != nil && *target.ProviderMetadata != "" { output += getInfoLine("Metadata", *target.ProviderMetadata) + "\n" } From 4cf2622c937886f8874a211da582ad4fcc6bde98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luka=20Bre=C4=8Di=C4=87?= Date: Thu, 16 Jan 2025 17:23:34 +0100 Subject: [PATCH 66/76] fix: ghost default target (#1726) Signed-off-by: Luka Brecic --- pkg/server/targets/delete.go | 1 + pkg/server/targets/set-default.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/server/targets/delete.go b/pkg/server/targets/delete.go index 048d01a16a..199a8458df 100644 --- a/pkg/server/targets/delete.go +++ b/pkg/server/targets/delete.go @@ -28,6 +28,7 @@ func (s *TargetService) Delete(ctx context.Context, targetId string) error { } t.Name = util.AddDeletedToName(t.Name) + t.IsDefault = false err = s.targetStore.Save(ctx, t) if err != nil { diff --git a/pkg/server/targets/set-default.go b/pkg/server/targets/set-default.go index dbdd7083ac..bcc67d8cb5 100644 --- a/pkg/server/targets/set-default.go +++ b/pkg/server/targets/set-default.go @@ -29,7 +29,7 @@ func (s *TargetService) SetDefault(ctx context.Context, id string) error { defaultTarget, err := s.Find(ctx, &stores.TargetFilter{ Default: util.Pointer(true), - }, services.TargetRetrievalParams{}) + }, services.TargetRetrievalParams{ShowDeleted: true}) if err != nil && !stores.IsTargetNotFound(err) { return s.targetStore.RollbackTransaction(ctx, err) } From 5eda5c24b1f44047537dd59f8c50bed08531b5f0 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Fri, 17 Jan 2025 12:02:41 +0000 Subject: [PATCH 67/76] fix: create tui fails on label required Signed-off-by: Ivan Dagelic --- pkg/cmd/workspace/create/creation_data.go | 2 ++ pkg/cmd/workspace/create/process_prompting.go | 1 + pkg/views/util/build_choice.go | 1 + pkg/views/workspace/create/configuration.go | 4 ---- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/cmd/workspace/create/creation_data.go b/pkg/cmd/workspace/create/creation_data.go index 5c27be3587..5c8e1ecc2f 100644 --- a/pkg/cmd/workspace/create/creation_data.go +++ b/pkg/cmd/workspace/create/creation_data.go @@ -103,6 +103,7 @@ func GetWorkspacesCreationDataFromPrompt(ctx context.Context, params WorkspacesD Image: params.Defaults.Image, User: params.Defaults.ImageUser, EnvVars: workspaceTemplate.EnvVars, + Labels: workspaceTemplate.Labels, } if workspaceTemplate.Image != "" { @@ -339,6 +340,7 @@ func newCreateWorkspaceTemplateDTO(params WorkspacesDataPromptParams, providerRe Image: params.Defaults.Image, User: params.Defaults.ImageUser, EnvVars: map[string]string{}, + Labels: map[string]string{}, } return workspace diff --git a/pkg/cmd/workspace/create/process_prompting.go b/pkg/cmd/workspace/create/process_prompting.go index df5efe64fb..924fc74fbd 100644 --- a/pkg/cmd/workspace/create/process_prompting.go +++ b/pkg/cmd/workspace/create/process_prompting.go @@ -51,6 +51,7 @@ func ProcessPrompting(ctx context.Context, params ProcessPromptingParams) error Image: &apiServerConfig.DefaultWorkspaceImage, ImageUser: &apiServerConfig.DefaultWorkspaceUser, DevcontainerFilePath: create.DEVCONTAINER_FILEPATH, + Labels: make(map[string]string), } *params.CreateWorkspaceDtos, err = GetWorkspacesCreationDataFromPrompt(ctx, WorkspacesDataPromptParams{ diff --git a/pkg/views/util/build_choice.go b/pkg/views/util/build_choice.go index cefa3e4fbb..24de513dca 100644 --- a/pkg/views/util/build_choice.go +++ b/pkg/views/util/build_choice.go @@ -23,6 +23,7 @@ type WorkspaceTemplateDefaults struct { Image *string ImageUser *string DevcontainerFilePath string + Labels map[string]string } func GetWorkspaceBuildChoice(workspace apiclient.CreateWorkspaceDTO, defaults *WorkspaceTemplateDefaults) (BuildChoice, string) { diff --git a/pkg/views/workspace/create/configuration.go b/pkg/views/workspace/create/configuration.go index a182e31c97..acd8fd087e 100644 --- a/pkg/views/workspace/create/configuration.go +++ b/pkg/views/workspace/create/configuration.go @@ -74,10 +74,6 @@ func RunWorkspaceConfiguration(workspaceList *[]apiclient.CreateWorkspaceDTO, de return false, nil } - if currentWorkspace.Labels == nil { - currentWorkspace.Labels = make(map[string]string) - } - devContainerFilePath := defaults.DevcontainerFilePath builderChoice := views_util.AUTOMATIC From 480e9441b9e1ec429925543a34d4f2cf4b423e48 Mon Sep 17 00:00:00 2001 From: Ivan Dagelic Date: Fri, 17 Jan 2025 15:37:41 +0100 Subject: [PATCH 68/76] feat: readme rework (#1724) Signed-off-by: Ivan Dagelic --- README.md | 400 +++++------------------------ assets/images/create-profile.png | Bin 448839 -> 0 bytes assets/images/create-workspace.png | Bin 429937 -> 0 bytes assets/images/daytona-core.png | Bin 97515 -> 0 bytes assets/images/daytona_demo.gif | Bin 1210609 -> 7654117 bytes assets/images/list-workspace.png | Bin 401315 -> 0 bytes assets/images/ph-readme.png | Bin 185319 -> 0 bytes assets/images/ssh-workspace.png | Bin 487773 -> 0 bytes 8 files changed, 68 insertions(+), 332 deletions(-) delete mode 100644 assets/images/create-profile.png delete mode 100644 assets/images/create-workspace.png delete mode 100644 assets/images/daytona-core.png delete mode 100644 assets/images/list-workspace.png delete mode 100644 assets/images/ph-readme.png delete mode 100644 assets/images/ssh-workspace.png diff --git a/README.md b/README.md index 7bb983498d..b1ab932923 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,3 @@ -
- -
- - - Daytona logo - -
- -
-
[![Documentation](https://img.shields.io/github/v/release/daytonaio/docs?label=Docs&color=23cc71)](https://www.daytona.io/docs) @@ -16,76 +5,56 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/daytonaio/daytona)](https://goreportcard.com/report/github.com/daytonaio/daytona) [![Issues - daytona](https://img.shields.io/github/issues/daytonaio/daytona)](https://github.com/daytonaio/daytona/issues) ![GitHub Release](https://img.shields.io/github/v/release/daytonaio/daytona) -
-[![Open Bounties](https://img.shields.io/endpoint?url=https%3A%2F%2Fconsole.algora.io%2Fapi%2Fshields%2Fdaytonaio%2Fbounties%3Fstatus%3Dopen)](https://console.algora.io/org/daytonaio/bounties?status=open) -[![Rewarded Bounties](https://img.shields.io/endpoint?url=https%3A%2F%2Fconsole.algora.io%2Fapi%2Fshields%2Fdaytonaio%2Fbounties%3Fstatus%3Dcompleted)](https://console.algora.io/org/daytonaio/bounties?status=completed) -
+
-Daytona - Dev environment manager that makes you 2x more productive | Product Hunt -Daytona - Dev environment manager that makes you 2x more productive | Product Hunt +  +
+ + + + Daytona logo +
-

The Open Source Development Environment Manager

-
-Set up a development environment on any infrastructure, with a single command. +

+ Set up a development environment on any infrastructure using a single command: +

+ +
+ +![Daytona Demo](https://github.com/daytonaio/daytona/raw/readme-rework/assets/images/daytona_demo.gif) +
-

- Documentation - · - Report Bug - · - Request Feature - · - Join Our Slack - · - Twitter -

- -
+ Documentation · + Report Bug · + Request Feature · + Join Our Slack · + Connect On X +

-## Features +
-- **Single Command**: Activate a fully configured development environment with a single command. -- **Runs everywhere**: spin up your development environment on any machine — whether it's local, remote, cloud-based, physical server, or a VM & any architecture x86 or ARM. -- **Configuration File Support**: Initially support for [dev container](https://containers.dev/), ability to expand to DevFile, Nix & Flox (Contributions welcome here!). -- **Prebuilds System**: Drastically improve environment setup times (Contributions welcome here!). -- **IDE Support** : Seamlessly supports [VS Code](https://github.com/microsoft/vscode) & [JetBrains](https://www.jetbrains.com/remote-development/gateway/) locally, ready to use without configuration. Includes a built-in Web IDE for added convenience. -- **Git Provider Integration**: GitHub, GitLab, Bitbucket, Bitbucket Server, Gitea, Gitness, Azure DevOps, AWS CodeCommit, Gogs & Gitee can be connected, allowing easy repo branch or PR pull and commit back from the targets. -- **Multiple Workspace Targets**: Support for multiple workspace repositories in the same target, making it easy to develop using a micro-service architecture. -- **Reverse Proxy Integration**: Enable collaboration and streamline feedback loops by leveraging reverse proxy functionality. Access preview ports and the Web IDE seamlessly, even behind firewalls. -- **Extensibility**: Enable extensibility with plugin or provider development. Moreover, in any dynamic language, not just Go (Contributions welcome here!). -- **Security**: Automatically creates a VPN connection between the client machine and the development environment, ensuring a fully secure connection. -- **All Ports**: The VPN connection enables access to all ports on the development environments, removing the need to setup port forwards over SSH connection. -- **Works on my Machine**: Never experience it again. +# Open Source Development Environment Manager +
-## Quick Start +For detailed/manual setup steps click [here](https://www.daytona.io/docs/installation/installation/#installation) ### Mac / Linux ```bash -curl -sfL https://download.daytona.io/daytona/install.sh | sudo bash && daytona server -y && daytona +curl -sfL get.daytona.io | sudo bash && daytona server -y && daytona ``` ### Windows -
-Windows PowerShell -This command downloads and installs Daytona and runs the Daytona Server: - ```pwsh -$architecture = if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { "amd64" } else { "arm64" } -md -Force "$Env:APPDATA\bin\daytona"; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]'Tls,Tls11,Tls12'; -Invoke-WebRequest -URI "https://download.daytona.io/daytona/latest/daytona-windows-$architecture.exe" -OutFile "$Env:APPDATA\bin\daytona\daytona.exe"; -$env:Path += ";" + $Env:APPDATA + "\bin\daytona"; [Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::User); -daytona serve; +powershell -Command "irm https://get.daytona.io/windows | iex; daytona serve" ``` -
- ### Create your first dev environment by opening a new terminal, and running: ```bash @@ -96,327 +65,94 @@ daytona create --- -
- -## Why Daytona? - -Daytona is a radically simple open source development environment manager. - -Setting up development environments has become increasingly challenging over time, especially when aiming to set up remotely, where the complexity increases by an order of magnitude. The process is so complex that we've compiled a [comprehensive guide](https://www.daytona.io/dotfiles/diy-guide-to-transform-any-machine-into-a-codespace) detailing all the necessary steps to set one up—spanning **5,000 words**, **7 steps**, and requiring anywhere from 15 to **45 minutes**. - -This complexity is unnecessary. - -With Daytona, you need only to execute a single command: `daytona create`. - -Daytona automates the entire process; provisioning the instance, interpreting and applying the configuration, setting up prebuilds, establishing a secure VPN connection, securely connecting your local or a Web IDE, and assigning a fully qualified domain name to the development environment for easy sharing and collaboration. - -As a developer, you can immediately start focusing on what matters most—your code. - -## Backstory +## Features -We spent most of our careers building cloud development environments. In 2009, we launched what was likely the first commercial [Cloud IDE](https://codeanywhere.com) project. At that time, technology was lacking, forcing us to develop everything from scratch—the IDE, the environment orchestrator, and almost everything else. A lot of people were interested, and over 2.5 million developers signed up! But we were too early, and we asked too much from our users to change how they worked. +- **Quick Setup**: Activate a fully configured development environment with a single command - `daytona create`. +- **Runs everywhere**: Spin up your development environment on any machine; local, remote, cloud-based, physical server or a VM & on any architecture; x86 or ARM. +- **Various Providers Support**: Choose popular providers like AWS, GCP, Azure, DigitalOcean & [more](https://github.com/orgs/daytonaio/repositories?q=daytona-provider) or use Docker on bare metal. +- **IDE Support** : Seamlessly supports [VS Code](https://github.com/microsoft/vscode), [JetBrains](https://www.jetbrains.com/remote-development/gateway/) products and more, ready to use without configuration. Also includes a built-in Web IDE for convenience. +- **Git Provider Integration**: GitHub, GitLab, Bitbucket and [other](https://www.daytona.io/docs/configuration/git-providers/#add-a-git-provider) Git providers can be connected allowing you to start working on a specific branch or PR and to push changes immediately. +- **Configuration File Support**: Support for [dev container](https://containers.dev/) and an upcoming expansion to DevFile, Nix & Flox. +- **Prebuilds System**: Drastically improve environment build times by prebuilding them based on Git Providers' hook events. +- **Reverse Proxy Integration**: Enable collaboration and streamline feedback loops by leveraging our reverse proxy. Access preview ports and the Web IDE seamlessly, even behind firewalls. +- **Security**: Automatically creates a VPN connection between the client machine and the development environment, ensuring a fully secure connection. +- **Works on my Machine**: Never experience it again. -Now, 15 years since its inception, we have noticed quite a few things. First, the technology we wished for back then exists now. Second, approximately 50% of developers work in remote dev environments, and third, and most importantly, setting up development environments has become more complex than ever, both locally and to a greater magnitude for remote. +*For a complete feature set including Authentication, Authorization, Observability, Resource Management and IDP, check out our [enterprise offering](https://daytona.zapier.app/). -So, we took everything we learned and decided to solve these issues once and for all as a fully open-source project. Our goal was to create a single binary that allows you to set up a development environment anywhere you wish, completely free, and finally fulfill the promise that many have attempted to make. +--- ## Getting Started ### Requirements -Before starting the installation script, please go over all the necessary requirements: - -- **Hardware Resources**: Depending on the project requirements, ensure your machine has sufficient resources. Minimum hardware specification is 1cpu, 2GB of RAM and 10GB of disk space. -- **Docker**: Ensure [Docker](https://www.docker.com/products/docker-desktop/) is installed and running. - -### Installing Daytona - -Daytona allows you to manage your Development Environments using the Daytona CLI. To install it, please execute the following command: - -```bash -# Install Daytona into /usr/local/bin -curl -sf -L https://download.daytona.io/daytona/install.sh | sudo bash - -# OR if you want to install Daytona to some other path where you don`t need sudo -# curl -sf -L https://download.daytona.io/daytona/install.sh | DAYTONA_PATH=/home/user/bin bash -``` - -
- Manual installation - If you don't want to use the provided script, download the binary directly from the URL for your specific OS: - -```bash -curl -sf -L https://download.daytona.io/daytona/latest/daytona-darwin-amd64 -o daytona -curl -sf -L https://download.daytona.io/daytona/latest/daytona-darwin-arm64 -o daytona -curl -sf -L https://download.daytona.io/daytona/latest/daytona-linux-amd64 -o daytona -curl -sf -L https://download.daytona.io/daytona/latest/daytona-linux-arm64 -o daytona -curl -sf -L https://download.daytona.io/daytona/latest/daytona-windows-amd64.exe -o daytona -curl -sf -L https://download.daytona.io/daytona/latest/daytona-windows-arm64.exe -o daytona -``` - -Make sure that path where `daytona` binary is downloaded is in your system PATH. - -
+Before starting the installation script, if developing locally, ensure [Docker](https://www.docker.com/products/docker-desktop/) is installed and running. ### Initializing Daytona To initialize Daytona, follow these steps: **1. Start the Daytona Server:** -This initiates the Daytona Server in daemon mode. Use the command: +Use this command to initiate the Daytona Server in daemon mode or use `daytona serve` to run it in the foreground: ```bash daytona server ``` -**2. Add Your Git Provider of Choice:** -Daytona supports GitHub, GitLab, Bitbucket, Bitbucket Server, Gitea, Gitness, AWS CodeCommit, Azure DevOps and Gogs. To add them to your profile, use the command: +**2. Register Your Git Provider of Choice:** +Daytona supports GitHub, GitLab, Bitbucket and [more](https://www.daytona.io/docs/configuration/git-providers/#add-a-git-provider) Git Providers. Use this command to set them up: ```bash -daytona git-providers add - +daytona git-provider create ``` -Follow the steps provided. +**3. Create Your First Target:** (optional) +By default, Daytona uses the Docker provider to spin up environments on your local machine. For remote development environment setups, use the following command: -**3. Add Your Provider Target:** -This step is for choosing where to deploy Development Environments. By default, Daytona includes a Docker provider to spin up environments on your local machine. For remote development environments, use the command: - -```bash -daytona target set +```bash" +daytona target create ``` -Following the steps this command adds SSH machines to your targets. - -**4. Choose Your Default IDE:** -The default setting for Daytona is VS Code locally. If you prefer, you can switch to VS Code - Browser or any IDE from the JetBrains portfolio using the command: +**4. Choose Your IDE:** +The default IDE for Daytona is the local VS Code installation. To switch to the Web IDE or any other IDE, use: ```bash daytona ide ``` -Now that you have installed and initialized Daytona, you can proceed to setting up your development environments and start coding instantly. - -### Creating Dev Environments - -Creating development environments with Daytona is a straightforward process, accomplished with just one command: - -```bash -daytona create -``` +Now that you have installed and initialized Daytona, you may proceed to setting up your development environments and starting to code instantly. -You can add the `--no-ide` flag if you don't wish to open the IDE immediately after creating the environment. +**4. Create Your First Daytona Development Environment:** -Upon executing this command, you will be prompted with two questions: +Creating development environments with Daytona is a straightforward process accomplished with just one command which prompts you for two things: -1. Choose the provider to decide where to create a dev environment. -2. Select or type the Git repository you wish to use to create a dev environment. +1. Choose the target/provider to decide where to create the dev environment. +2. Select or type in the Git repository you wish to start off with. -After making your selections, press enter, and Daytona will handle the rest. All that remains for you to do is to execute the following command to open your default IDE: +After making your selections, press enter, and Daytona will handle the rest. ```bash -daytona code +daytona create ``` -This command opens your development environment in your preferred IDE, allowing you to start coding instantly. - -### Stopping the Daytona Server: - -```bash -daytona server stop -``` +*You can add the `--no-ide` flag to skip opening the IDE and then use `daytona code` once you're ready to start coding. More info [here](https://www.daytona.io/docs/about/getting-started/). -### Restarting the Daytona Server: +**5. Manage the Daytona Server daemon:** ```bash -daytona server restart +daytona server [start|stop|restart] ``` -## How to Extend Daytona - -Daytona offers flexibility for extension through the creation of plugins and providers. +--- -### Providers +## Extend Daytona Through Providers -Daytona is designed to be infrastructure-agnostic, capable of creating and managing development environments across various platforms. Providers are the components that encapsulate the logic for provisioning compute resources on a specific target platform. They allow for the configuration of different targets within a single provider, enabling, for instance, multiple AWS profiles within an AWS provider. +Daytona is designed to be infrastructure-agnostic, capable of creating and managing development environments across various platforms. Providers are the components that encapsulate the logic for provisioning compute resources on a specific platform. They allow for the configuration of different target configurations thus enabling, for instance, multiple AWS profiles within an AWS provider. How does it work? When executing the `daytona create` command, Daytona communicates the environment details to the selected provider, which then provisions the necessary compute resources. Once provisioned, Daytona sets up the environment on these resources, allowing the user to interact with the environment seamlessly. -Providers are independent projects that adhere to the Daytona Provider interface. They can be developed in nearly any major programming language. More details coming soon. - -### Plugins - -Plugins enhance Daytona's core functionalities by adding new CLI commands, API methods, or services within the development environments. They offer configurable settings to tailor the plugin's behavior to the user's needs. - -Similar to providers, plugins are independent projects that conform to the Daytona Plugin interface and can be developed in a wide range of programming languages. More details coming soon. - -## Contributing To Daytona - -We welcome contributions to Daytona! Whether you're fixing bugs, improving documentation, suggesting new features, or reporting issues, your help is greatly appreciated. - -### Open Source Licensing - -Daytona is Open Source under the [Apache License 2.0](LICENSE), and is the [copyright of its contributors](NOTICE). - -If you would like to contribute to the software, you must: - -1. **Read the Developer Certificate of Origin Version 1.1** - - Please review the [Developer Certificate of Origin Version 1.1](https://developercertificate.org/) to understand the contribution requirements. - -2. **Sign all commits to the Daytona project** - - Ensure that all your commits are signed to comply with the Daytona project's contribution policies. - - This ensures that users, distributors, and other contributors can rely on all the software related to Daytona being contributed under the terms of the [Apache License 2.0](LICENSE). No contributions will be accepted without following this process. - -### Ways to Contribute - -### 1. Reporting Issues and Suggesting Features - -Creating issues is a valuable way to contribute by reporting bugs, suggesting features, or improving documentation. - -Before creating a new issue, search the existing issues [here](https://github.com/daytonaio/daytona/issues) to see if your concern has already been addressed. - -- If no existing issue matches your contribution, follow these steps: - 1. **Identify the Type of Issue** - - **Bug Report:** If you encounter unexpected behavior or errors. - - **Feature Request:** If you have an idea for a new feature or improvement. - - **Documentation Improvement:** If you notice gaps or areas for improvement in the documentation. - 1. **Create a new issue** - - Navigate to Issues: Go to the Issues tab [here](https://github.com/daytonaio/daytona/issues). - - Click on "New Issue": Choose the appropriate template (Bug Report, Feature Request, etc.) if available. - - Fill Out the Issue Template: Provide a clear and concise description of the issue, including steps to reproduce (for bugs) or detailed feature descriptions. - - Submit the Issue: Click "Submit new issue" to create the issue. - 1. **Engage with the Community** - - **Respond to Feedback:** Be prepared to provide additional information or clarification if maintainers or other contributors have questions. - - **Collaborate on Solutions:** If you have ideas for resolving the issue, share them in the comments. - -### 2. Contributing Code - -If you're interested in contributing code to Daytona, follow these steps: - -1. **Fork the Daytona repository** - - [Fork](https://github.com/daytonaio/daytona/fork) the GitHub repository to create your own copy of the repository. - -1. **Add a GitHub provider (if not already registered)** - Before creating your workspace, ensure that you have a GitHub provider registered. If not, run: - - ```bash - daytona git-provider create - ``` - -1. **Create a Workspace with Daytona** - - Use the Daytona CLI to create a workspace for your forked repository. Replace YOUR-FORK-URL with the URL of your forked repository. - - ```bash - daytona create YOUR-FORK-URL - ``` - -1. **Create a new branch** - - Once in the development container, create a new branch for your changes: - - ```bash - git checkout -b my-new-feature - ``` - -1. **Running Daytona in development mode** - A `dtn` alias is automatically created inside the Workspace. You can use it to compile and run daytona. - For example: - - ```bash - dtn serve - ``` - -1. **Make changes to the project** - - Prepare your changes and ensure your commits are descriptive. The document contains an optional commit template, if desired. - -1. **Test your changes** - - Ensure to test your changes by running the project locally. - Run the following command in the daytona root directory to run the tests: - - ```bash - go test ./... - ``` - -1. **Generate docs** - - Ensure to generate new docs after making command related changes, by running ./hack/generate-cli-docs.sh in the daytona root directory. - - ```bash - ./hack/generate-cli-docs.sh - ``` - -1. **Generate new API client** - - Ensure to generate a new API client after making changes related to the API spec. - Run the following command in the daytona root directory: - - ```bash - ./hack/swagger.sh - ``` - -1. **Check for lint errors** - - Ensure that you have no lint errors. We use golangci-lint as our linter which is automatically installed. - Run the following command in the daytona root directory to check for linting errors: - - ```bash - golangci-lint run - ``` - -1. **Sign off on your commits** - - Ensure that you sign off on all your commits to comply with the DCO v1.1. We have more details in [Prepare your changes](https://github.com/daytonaio/daytona/blob/main/PREPARING_YOUR_CHANGES.md). - - To sign off on your Git commits more easily, you can use the -s or --signoff option when making a commit. This adds a "Signed-off-by" line to your commit message automatically, which is required to comply with the DCO v1.1. - - Here's how you can do it: - - ```bash - git commit -s -m "Your commit message" - ``` - - This command adds the necessary sign-off to your commit without needing to rebase later. - - If you've already made commits without the sign-off, you can add it retrospectively by rebasing: - - ```bash - git rebase HEAD~1 --signoff - git push --force-with-lease origin my-new-feature - ``` - -1. **Push your changes and create a pull request** - - Push your changes to your forked repository and create a pull request from your branch in your forked repository to the main Daytona repository. - If you're new to GitHub, read about [pull requests](https://help.github.com/articles/about-pull-requests/). You are welcome to submit your pull request for commentary or review before it is complete by creating a [draft pull request](https://help.github.com/en/articles/about-pull-requests#draft-pull-requests). Please include specific questions or items you'd like feedback on. - -1. **Wait for review** - - A Daytona team member will take a look at your PR and either merge, comment, and/or assign someone for review. - -## License - -This repository contains Daytona, covered under the [Apache License 2.0](LICENSE), except where noted (any Daytona logos or trademarks are not covered under the Apache License, and should be explicitly noted by a LICENSE file.) - -Daytona is a product produced from this open source software, exclusively by Daytona Platforms, Inc. It is distributed under our commercial terms. - -Others are allowed to make their own distribution of the software, but they cannot use any of the Daytona trademarks, cloud services, etc. - -We explicitly grant permission for you to make a build that includes our trademarks while developing Daytona itself. You may not publish or share the build, and you may not use that build to run Daytona for any other purpose. - -You can read more in our [packinging guidelines](PACKAGING.md). - -## Code of Conduct - -This project has adapted the Code of Conduct from the [Contributor Covenant](https://www.contributor-covenant.org/). For more information see the [Code of Conduct](CODE_OF_CONDUCT.md) or contact [codeofconduct@daytona.io.](mailto:codeofconduct@daytona.io) with any additional questions or comments. +Providers are independent projects that adhere to the Daytona Provider interface. View all currently supported providers [here](https://github.com/orgs/daytonaio/repositories?q=daytona-provider). -## Questions +## Contributing -For more information on how to use and develop Daytona, talk to us on -[Slack](https://go.daytona.io/slack). +Daytona is Open Source under the [Apache License 2.0](LICENSE), and is the [copyright of its contributors](NOTICE). If you would like to contribute to the software, read the Developer Certificate of Origin Version 1.1 (https://developercertificate.org/). Afterwards, navigate to the [contributing guide](CONTRIBUTING.md) to get started. \ No newline at end of file diff --git a/assets/images/create-profile.png b/assets/images/create-profile.png deleted file mode 100644 index c5370a5a31b0b9ce060bf82e228fef3ca61933aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448839 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%0DOH=g-W)0ryLQw$pe*v< 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�Q|8eKFa+99+UyA%Ihbfr0{JmEjU%o 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 z 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 JFP;3){TBpLL-YUu diff --git a/assets/images/create-workspace.png b/assets/images/create-workspace.png deleted file mode 100644 index 0a13d36350e6ec6c8fbddf93936d94162f515910..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429937 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

F 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%0DGW$HVKd9T~2X1iiEunuA(u-T(eYxvEj9>oQ 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 diff --git a/assets/images/daytona-core.png b/assets/images/daytona-core.png deleted file mode 100644 index 398096bd9a02a2381c5a9a6ba9715fc5d31976d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97515 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 diff --git a/assets/images/daytona_demo.gif b/assets/images/daytona_demo.gif index beba88ac06890724daa922b97be2c37860f899df..0a18b2e8b1c322de6d1795c2d150b0abc57afab2 100644 GIT binary patch literal 7654117 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

-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%0AYUzWNKCIav(P(kK7~AAvJI3mh~b;XfTo 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

FWzKS<2$0*Ch*xCA%Pk4p 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ⅇ2dnq$& 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 z z5}u~h;X3t9tNjX+>_@C&PS9zJf)RKKMSaWkTJ{%PybhxtOKc>sN?9A6rm9F_%f;Z= zD0)}fE8YG;&GO)OXjL3unh~}9%BarGU(*!KM8no&b<7|Z3u*b)Sq{)XmhSU3MJH`z<3xqM`|~sf6lz#gEQ960ZWG@&4=YwWrJ*IQ{DB%aw=m}QBaz6~ z#fg8QW~ztzpM*`3-OI3Sp2dOfuN^|AKAd+biqen@?7PO7(=Y-9Pk)n(oe+5@=+&C?w zVc<<1hrjAL|I4xTI^MYPXa{J*wvW))c2pf7{uP@-cYGLBz)_Z9yYU+5ek5$|+zyPs z%cOfhs&!U2Ra;KYG&eJ*hvBS{&thI4&@!%WF~paYg2+Y?y3pCnY{ z%(`ta5=>i}^0Cj(dJ+4D1`M3G#b(ESrLVsIhIl4HY3<89!9$ro#Oc(@`ohda83p>| znT3k0Lg|;8Pl?Mao2?szOwts+KbI`C}l+M$AV{qOQyLz;vv2` zS}$}3x};)sBYkZr33*p020=A>tT^WG{i_N<-iD@$Q+w~nwM~0EpcUfj=f0V*2fyPQ z=X`S=r>xgw26)@{*X^W7Gd3Cqq0i=>-#6A1wZ8*5~ ziuSGtAg&dm{M8KGLVl1Px*!9=3u9w;x0E{CBSKTZf!_x5&L0N3+6nbgC>S+&V zF_qUMj=o^+C572@yqne3j$=mwZ|#h@o5t_Tr}nSDF7v#&UDpw&c8+h`aQJoYcD;TA zZ|+@8*m+ycg1hee%6J>?+v)%T_*`OA$Q~ZTH1z)WMf&adH!gpi5$E6Q4~^|*N+*>Q zYW-K(SiUtM*uiL}zb~sbbN3yeypqpTE+C*M3z| zU@hY8JI<75{yZ7$oMQJPEr|kT)-q((iee@k8HXz54>elKnage^%ldWvf(;CoO?S}+ zNHO1MqX!eC4NQ(z z^Or=S5temPjKpR=j5^Ov*03T~E^*Ia!csdF)Mt!Q@k}u$a@|a)Fp{Ow7D$EiiwYps z`abpeHu3YlhW)*u^9Td>3f>U|mZ7YM>j;ysEOnqP^qNju14lZVO8U%fT0u{G?N)ji z5pdulEm0c?Zc0lEOiz`iN(M4UwE!_!XjEZ9`H}db!=y}YP^mUUx+iAI3Qj@`s8%3j z?=n;aCxd4O6n6o_bpko{WYjY^qJ*abFo;Jp|u^tFAH5!fw|G47c~K%W(VPrL}kY_^rNKQ=|Cx2Y~j*s zyt#CxY`IJw&Vp%wlnSyd_n9S0Z}q-OJ;oab<*)`+8oTsGvw1jqyuo#TO^fx~*Wb3E zC+~(DUoT-xtYU79RujH_bu$Jv_YzG7vV0U;YIn!dxu8=WD^&))_&?mpG6gQw=LGE( z&mxF(jAv1GN%Ztrm`~PTdkW4gCh?x723c%8{o?od`EA$=n~%YJ?;<1ut-bTD@6LJW zQqtd(cfMuOkR7|}&n`b{v-9@LHVV!ok5dN8Q8emT?-Rs08)7eiNzVP=3jbgOOQybQ zkAJ?T_a2EiIWqt{)v+aJ8fr=|9Wb poX*pc4E_k>PKy;5e5u5N9^0Gmv1X+A&h( z+TNM>W=K{4?u*gjzO5^S>OyIW1Y5GAD}p-zDd9~VE|J~by#{^+>iul4d-E%c)#_R=Up#Z(#VvMBrDVf_}M3WuAig_G6nh#stYSTd!zpOblE ztVC49e2x*v5kU&^si#3Imda5=it;J&>ld{1~IfCVCLPh?wxkokA`axN$g_zJVA6XrZ`2`+Yu~tRMgKF{Q1yhA$7BMcX{1S$# zxmappDyIMIK%tywXdTX=7#x;TDY2jgo$81XX;mrZURXA3#H-jTt;#iTWNU}9k^14& zdqnivXj+1!Y@SI^UtI^VElT4VRM4HuWZ- z&6Q3Q*%9DQwE}kJ=Fb&B>hdbd+@AGP;mJ?s z94PSW>DpZJkqcbOS;=toqgCHjzJ^{%_zpGJ`p|Lq)jQQKFeKTuHC>b2{pnyodrhS$ zZbvwkump5%|6ch1y1@4VC0Sw=sTqz8!T-So{fWgmA6e&TkZoJ)3y#G672l9RzHE-w;k(S%^xtG@ByP*4(; zuN~whGtV{-e&z1wj-wnn=S#prFHZe{6?t=zhBHwt#W$*grLE4!BNQe1ZZsK@wICTu z@&I(vPm?GIpB);BqF|Q)VUuM%`^pF~gxLZR78xiYvLawX3s7J;x>6Gzm{4gzAaHf% zHc)<=P|bTFu@5@uVRPOX{UDnbN3%f5)$oOt;o?JLND9r123fHZCd|16vt<4Z6g@t7 z5fCpo0P|W^h07S!;)ADa20T(Ga;`(~aOTFqWzi)N!gM}cp!F9XHL*$50H;^hqF}{x zH{~ts@t{>9S_Q)rd5aBPII@P*=En<;6$E#48fc)s19SFemK;o`D^na^R#en=yab`3Nv zIS`L77dHdcf|1n@!>m_q4kW1ej(qcmu4U4A3NpqhwUe#2N9A&=o-|epwoW0AFU)Z}?rv19-LP zMWS!%i6G5V5@$amne3vtA!4E-$C-}tS8Y2RJa?r{Kilv7*XUWRkOzd~PNR2TQw!`1 z%!h2)fBp4(Pw)o=Q#bgDL?XS0sDE1&-+%l9;MpNmWj8*ybHO6kaj2QSIrKu9vefWK zT4vHqDtcNd;D^kavjgS^eaK3^^sB?9KG&tCPMVr`o$5g!m~g4#4HeXWt0%rYXICK? zSn~fhxw7LO4G&>l(YS?Nr}*CmTjm<|EybMUkpr%T;Mczloj>4U`zN@PUtW`=Y{^F? z)RK5?%@PE>boPfE)`Hi<|F(pQvh0oG7(fFExNY)&$?we$>+z{6;03IYI>4Wu!{6A^ zb)238!-ML3(Oa@*oYxGv0I0i#AEdR9^ZOR3q`?dUnSGUylGZ~EB_fan5X>`-wM&3y z@{{na=?%RW5xjc{1(NXFJ3pkYAkwYikvWg;l%N>cP%NX+W3k|O5w_F}*oMoYKjG}V z@B&|O1X!)p!$JkI!sB2ANFDvy0CrpM zI7#%O*ZC0#IU&Lj{4lp=Orv5aFB#bwLa88zFkh9(CfCRk`bdxry&qvzzE%`}qkr!? zR!9ViWU+F^GC`FVmRqv}=Y9lZTHuHq<_>;Xibb?VL^SnQwDWc(PBU!)Ax>`u4x2{| z6(FWM&@DhB1`|KBLn_u|E2dD!3|x$bec($_6N>;7M`#o)NEt_B6h}i9yX%H~a2H7} z7O;})dg`H{SB!b>ft$zgV44sc!X59j9sf(l%+%740D$t6GS+t}5~d`YD91^>C{7qF z+7AvOT$6Cfi?d7^ioT2~Cj;Oz0*pA?jSj{%qySPWb&8h>5hG3Mh!Xf=6XzBZGxI_? zJuzMSrI{gziR!RPIFgQU88Lk{`-3m!$c$q?({4Td$b;mZU{krG>Yod)%kt?WdWcq}h0edCI1{SpkDR)6zyS%Eg&&0JejBCaeCY=9EhC(S3)~wlhV-}2>o}@s3l6R(axx~%BYdeXllu5EXimd z$>_e%=p_R83xEf;!NZ>5Q6PA{1w7f3VJM!WPMP_wSaH6EjAsNy20%d0Nx^dT&-26# zf-nMi1hV$Dvkp9=MqJiOOV%C=j5SKO9b*+rGUN#%v zI{RgvBT@v2>pbBb5e}-3OpKDuW9ZhL0G`#*|0pl_w;Z*W;e~C4vguE4-^HS(rM1 zRTl3xDvrt~p^`vkfOeL*_Lny>%eS{5WWFs;!qWn7 z=DMM5Wv0!5lS^|`yh>6*CF!jtpw*IOVyv(z%p78T$x?5bDDN+z=+`Qxd8q((WX>0i z*kpqFCk$VHdzLk>7Tlm@BaD{4cqns1Eq7x|cWy1~BmUyR1a#8Q?j$as^eP_*WukkL zV%M7E&cD~)HY zwpXr|JUV;Xx*RZ8v98jL6J7C5r9OqSjmD^w-MyLHsPa6gjT{hvFq$7VMs#LP^b57d z+NS+xHTQPZ-OsumQMdioSl$Fl#~fP6;&C<0Y9kw{$=y4HmAU#2WVFfWv3ks=YFIv( z@VJ#Q+MM;amg%^V7qKg^td3N^&U&R?n7Qi>TAc+`>s4Frg-{)csM}Vjfd8lnsk{jJ zSEr+FH@#4u)o2-(UM5~(+q7Cf{?`;dEo>BiKO!G7P3g9munox}4XV0WACGa~-dDXu zYw~Jqs1@iOX6(Co==dgIJ+sz3CfmpMy6Hj=yv^MBE~ewRSE(vTGaT^{ZW=0><>%N8KstlIV#m9CD+Y!UHCg9s@b6qfdYy0ll2bY&)U)Uc^zowcU)>W5b@IS*rvDFGK&8LC zzts${S4x>HE63<&&CYDh2TZfUe9Xwv$J$}b9)Zp-QHc^MX^I?Gk^B^;3d73D!bFV2 zoSM(~+@tu4&-;w2=L^1$VUDA^gG>2vMw}74JkT+*(6I5rx~0wr(UFbfE_qDGbc)e! z%*GtO(W*NGrWg&manvjU)ItGb>pBoqtr@dS%2*xHSG~1boz5Fr)1hDVFPF$=)WOxIfMz;>O{4@}I^+}C-H*MMEu zZOYer4ZwsQ*nW-J8Ep}h2i2X^j(rS{YE2bR%{*oK5suwLDajP^Y!ID&5LKPE2hD~F ztq>~bwey z+QD7i!kyg7tq?-0pf!DqViDbIy=Zm8VWBM)t}A{s?Wf)U4V17K-VVXtcl+Jl{m19+ z-LPBU2C;qQt={m>-LN~};mx4(?cMB+-|>wincag&A<;H*eMni{27!UR*Wdewg*B;n z7g2l_9MpSJ*+N0CqbT7+y%EfJ)E4d#8Xh5^?b$yus?;rNBVH4c2;kMtLcOdwuiBbU zh!Am26a5WgB@UsDf#MIYQN5@uN{u>E(Bs!*u}9h%R4L>aoZ@Szu@#YtjDh1o8$mO^ z7g1gozSnRt>AL}A!N%vPZ=;xT+Xm#^VdjsK-3g)QbC{HC*Nvhr5>Aff zs%FLGCLq~qt+iI;&Bz@az9l;i<9xB=45<)3ZszL$mU9{R=ii~^8%PtA%@hVL6Sz!r z=6HXR?zg2)!IUwA&#mcnu6#0v=Eye?$vEd4<>g5GDX30hQ|=u!Dacd7=w;#PfLjut zj&yu}8Lb}bwWSxfJ{qJROug>3QB~~X$r72~62lG?gr3NS?i0OC>l|Tx*SCG7+1^k1 z>@AUu%kCFVy4e=d)|j#DCjN^K0o@-Fl<0x!-72bdV(F9Y>!UWj0hem8Zknr38Tl^d zsrm0f-R~~$jlc2j7cLXj&eMU6KITsE@cn=eZ)sd85yAcuRtS3bzG@?g;|)LXRKauf zDi!xVwAzvIh}aX{{(4SmW6OvU*O&4Xm+}SwUg}I8Ol-cvB4O|V)A6}Z)9C(=Psz|* z8S%*0?E5a`MO@S9ijB;oDn1}^_V^1Sg#!zNS*A4<3~ttGJoz_pDPt_ z5aeDKMo$xc*Jaq=phBVZsl$_l+v-gZ6I2QJ9M$neuT7=Ol{{JZqtW-94*2Gc5i$n# zNIw!`j}WNW;q&eni*M{}dl8XO-xg8%`_#_Uy{$9v5pa(8PyF^5L7jJ>+M!<)dXMuz zzxS+YKcw7637b)xzXYxmUk2SUrzuLpuj+a1riJdQc&SSh7BD)gcwocM2ZW^RK%E3 z<3^4O5p*no0Dwr601iI<__1KglmuI<3>mW}0GSd`g2b8AqfUn~dD{F5^5##UK~Wk- zYP4ulqD-AWg&I}rRFF%l@*GO=AkB$ZuYLuav`v9hAjgJP7=D;J^fOH)oWaStsU- zl_5|3tk879$9x;M7Hu^0YQ={CgTxkmF=-NtydV0;tq`_Lh9^xDUg|di*X3@To8diL$zzlSe65k}w~&qwte8Zunf{0si2 zjK9CC%da}Ps*A6%`v}r5K?gZ%FsalYba26n^i!xlf^MT|!r&r|kU|kh)JQ`T8`?yn z6bmASqOu-(aUv5REQ%%z85$`^iE{LbN0)fKZlsWaWGSW-gY)gr5$RlL zF*;lGlOjFqq$o1~2t_piQAGu7v9K@|MbJhBqeSdD&d7wxxR0ExZYbrhOiw2$8{)IQ z)DpcY7)5smQqHxMp7p2uZMQ5!w*Y$V<4haX{l8de#4@I-mH)$F$FJ#;Fi>E4e zg*MtgrDbT)fxd$YN^Pm-)=FHv717!&eVuB!tiBbGNFo0-Qr(q&WJyTu;-wedh3+fW zUVRg@bzi5@^*3OF2QH6XkPOa9Lvhgp_RP85Gkietsk%?@5v_Xs*Q6P$-0=3WEz~@w zV`feBoVGBE3!u>|JL5%Z0$6d;UtjERT9LN7C)=rYU8BEc2MLIq#g!OOg?N9RRc<+{ z^S--t)-tlYzselz=!-||`CO-G3VZ6EEF8V<8B6_pymfwxc=6jd|EC6-4{z20#Ld0< z_|FG#X2sJ-YDJz*e=tn;-`1D*!ZSZ-Dd~SaA>jEEm?i6}M}Rn)(gEY}lEmiPDAj;Zu7UIE&z>g_>BH>SB*qz;RWQ3Y&VS8o>5)M#g z0#hgm|L7(`s6hluCfvzakl2nPxQC(jFlSQJZ05VMUgx!CgKioL93Y4aswmYzYrX@BE4eSy;1Ve$$@N0wP03 z8I>?13YzZx;DZFh$A8LFG*eQQA_K|2Wg_Y(SuAK&r1Ug{c7!dMiRe9f(o2nOz#(0v z&qLHwkdY=Vk09IGl^mu~mS(A*1)L&OR+CO@MTn+tE9XWyijAxV9wwxLd zf|rv@Yc7ezqPBD*FU3+*ojO&pn5d)?>8IYH+7SYt^PXGnTxM>HRQH?=j%37*S1A*b zJE0Oa(HbjNp`uo~3MQxL)Xp9`LRV{EMXH9&DCX)a8n8+PqwBGXb`aW0!34HjJq=6$ z7=t=k`0y1`h1CdMG3!ppO0hAxaZKHYDl>{yakIn}O`^KnM#G||^=8G005?{jhaD*Kl9vW^yw zk~OkZO*(Kd+%H532>X}|y`9|C|) z#CBRzkb<=fAcZXifGq$>!WNQ{fP0WG0ZEWT5)?q?1e90;>9*RxOWe!<%D~wc1o;O? z;hpb-lz0mV0XRY8orDSfo8Vp=$QE)f@P$l#AslB7yX7383PKXu=Yq6^l)au=WlGY) zy{4G=g=|fV2-raZGeoSNYop{mK@9`CvdlE}W<7)q_h5(=Z1E4KU*sSXum{tBv4y{s z`yan(#V>%E1Y6kS7xuWx7XE?crW2$MOt%M;xzmcS+dJU{A;s7K0roZjW9hbl^FNeK zin;%y9XBz!-F;(=b}W7F`-V51fANo?y?O3qKM4@-K6b5mJ?epTik9QU9MK{>iY|vI zrANzMj+}Mnr>7-{o%SAeYs9vo9>|G->`x%Mr6kKqfEFT9dmoYis@x2*dx`npMYi)M z>y$~tKU$Q4rFYSHoA?ETq%igp!#U%OUw70WWs6Oaf$ncl{wD6N`~oC@3v5pFKQ?h@ zUnjp&V(%r?Ne2KplWzKHE`aw*$Ay0Y5deIbf&`epMnSS(61y(qyMZV-Pm!?l8aSbx&*HBp8?4L$GM;0(_b3noX_zS3127;HqH_p=@V=~IGflgN zMhQDvD*&-OiR9}k?<1}0Q?lvnCAK379DIm&xQJh95qkis0!WB;-Bulq>3$-nPvlZz=1^k63oVtG# zL&<9q3`x5r5V-n~fK6CBYg4K}Gn{fPuTml+uRx(v%)t5qG(21|Z?v_R$`_iXmf3?M zbrA^w2!lC5fC!j{5Xh0`C=%a`Eo4EyHlqnPy9ggtz&K++DWHi1EQl?LK4ck1ngGHA zP&>GbMTZDQhI~6LM7S17z63~sSxga2T(baNH~pyx{IfoqSWD$YOJ7sVgA>g4OGEry zH;!UAgfPs3D8Pk)vnY5s$xE_U(g^3$#&Qw2Y$Pkx!zK(oDhms!^zzBj14@`nxf{!# zpqLeL?1*Q?xP>q^wdtLO0D&|x#58cVm06kpK{<$6YXwqhgHq6qQcylF@H#mQLnY)p z8@x*-^gi$-gH3=lJaagJVgP)lDEyH;>X%A3dnz%^qu2)paPWxT&F z;JXzuIPAo}@*IWgT#@s{PmVfIj#R&ah_&m4vzuTu@+*kx%TK;YQ2hxP!bzO8NhP() ziq#a&3pEN5K@^27GVoFV;lRTB5KL0AvtZNE%XqmtO(AfJqBz9R&2*33 zB#{Wn0t7$;E%4JsB2m{MtvOuKpz%kvG7K`D2t6U92D6g4uo^`xAKiH!1`JA05{$kP z7is(tOSMy0Dpitej5OE-1b_ftK!MPdrk<2l+EIw|)QPN^kPmIFQ&kiT=}a~1F=MSB&wQ^&>j)0@)`iN5$0$@0 zxyg}=fNPD21R#atq|L(kH*ncg)=ZLlHH@31G13%QrP?%@D)+* zmIFeSSsB&zx97`j#jfC!{dSf4w6}!3mFolLfs6WI?D87+xfsmLl`X~O~lS7@o6I2~D8t%%5x$)DBL^9irz>PAarkHwl+ z!?+tnqOb=k*K#cp)jK0Z6*MIxTCgC>n&qmkEml1O+p!H8s^y7&qc3S|R&`Zd!x`9d z9a*-87Hec1xvi_5+OO3xTcq&Qf&~e*WehWljEE)M^#~18)t*v$TZbT?|1p%0m57xc zS~t9+i!#^3btO&h(*iKty-kYOi&a{cIk%~x%`!QQWm#Swy$Qn_>tQB@T@;^1EJCte z5zSZD^g!G-v!YF#FfkGT*acdQ@F1_n+-Lz_YOz~?)xhFqUM=xl%Gwt2SX^;xUJ!i` zwVK{v>sQKxq~on#2dq`yVz82-jlA03tVxaRb)dWemdo31H)^{?(hP72wr**re4Qf^wi-3Rd}jtz4lZ3a$+dwwITB z-@qLa-^f{J<=xCcV1XjNq?*_$BH;eQF%%|`KYXzg9s0nyvnR3PSo>l;(;Nc4i+E1!qz+XW3-6k?M;dh zw!;h#3O!!n;*sHj@v-E^p*GsqaJ^y@N!}LT)ox|6J~|wVu(sBNV`H+{R>9i;h1{RK z5=R!|#;I6TJ`xGyljB9?KStT|V~Rk&P0&>cT-Ku2nB)sn)H*I;3-*^|WshDa6c@9c z+%+srD-}t)-Pg36ZuudFI5EFf-HMed0O+j=49N)6gY{Oo07*brIRrRQmK z4A;8kYo_Ua_KQhzx8f*NNI4F7>uS}gXN%Hiv)1Xj z?h~_iG=0umrB>;__G|S3!&%-47UC4y9p&TTlrqCT)pd^gI*zS)?BZx^DVl86SZu6q zj!qTb%i)U0h7M1uHThbWGNT@h?ip*08f4w8IbNaBgzESe;nH;0_0_Mx&aberv93<* zpC*(4n>N8~MizG~mbqTR&IW3l@e4OPjdiq2bUtpgu4lU*T<9J*Kf&vd#^m>CUzy>P ze6cC2rel1@Vi95}_fV^vp~*5?vW~8+#eL!ju^xujxd0YkLz?SaBb84v(C; zwle_tZvc<%N4{^Z5bywhj?VV&weoGY{%X#s>;aF{(Js1W$!tB=Yh_+nD03Um$ufpu zApzs#luqbR)B>V4U8>2X7kwQcO4SjVAnqmY0N$Z8Uy=L?J@GJ)*> z%;s)rg$~xaZ_jS*|JG^i*lEqM6yZ2<%6N|5Zk7et@g$E9`9Rh-fr6} zzth$}HVTQ5nF(X3I+-Z{qijN5?-|`X3G;~fWEYq6SE=#4?(HFGkj@~ZqD%53*XZh4 z^4_+e-_CK}hH$bjat1f@pf(dr9qS0UwOxm8fqCLl@x~HfVgg$d)1Y*!kkl+ck@x-y z9o`5SCkXkb2x*^fSc+`Ywwet8lrvY|%vSJ7d1(rdYsp$ZEiW0XFptN-ORgXmu?{PNx@~GXXE@HkeYBgqzeTvclE*Ipj z9`zqDYpz)G(7x~{e{f)(YqYj-Qf}~3HS!!E^&&U<3nvid4j$rm@QY9P=4SRLDOLN? zSZj=XnA4mBnr}cL)^d5hATBp#;LWe=6D7!^MsXq)s&pyTs5uoZO(NBx!;B8Eas`^TtH_>U#|C{0 z6-Ys`Y1L}nNme4-w-e)fbZgY^Pr7ms;?2ocqT9Y6^>!qzF|OeMlz$5t-s|`=t5{+$Jb;Zs=Ti>3j8==eJ zwkh|9O1wDokeCflSZTGl)~%`cPETHUX2t5(!D=@ud^_3h;K!3MZ~i>`^kct^Y_1+F zM1errzpww6H%aj_=_ll$9KUDOj7Q}k%Lgmms6MjSBe>#gkuuq-bhX=QIbkY zMyHjTamx9amUG&9&}m_km*<{H-uWks&sn$JlwBDKKts7zIg)m|;iczhDe-3|PIY?O zR!ElKr0G#Yae5b^m4X;*oRr$9l&PeGoyh=+ONVBq(7*#<{iYNftwe&4()>Y&zPUMP2F0(7rl2Rq_igH;XyN0tw z0004JWYD&WuU+B^tuu>9Gy1M-4DtNrVk;v(lAaHfrF2wJPrdbO3UW*C$Q2`-G1q0s zs4LUyh0StELuv{0f#=z*-rQyfMQBH1Yh7fK(t%eehii{&x3qf`9`oUGC%*WcaJwcr zM%-!{n&b7kWjNzZOG(}f*}RCnf!Zy=Er1Yyk5>kP@ZY2R7_;dybb zVcmA>+)1{3?@ua?c~rP3eHHK^B~LKw8a02LlNV)0;DrK<{u*1xFCJQGS@O=3%JhQe zD4P#zJ?`HD{`7p#-gSgB@xe=mw@AyQR(s$7^6S6F$!eD* z_H`?(Ou0)LEv11!|g@6Ix zgnj~wi65Bc)~k%%etixv~A^q1r51zfMQc^0@Ri0bLWu zXt_l^C1@G9Ui4b%HqApL}-2MTp;LHgeVmxt1C$BWJi!K zKqg%iysH$cg;%FwNv2_4Y`GNc%cv?0mWVCSRA=&7&1_a;mxU~73HDhX?KQMHywf3> zI#63>v6z^;(xlo+sz$;svzYDXJY!;8$zm_21nDfmRs-ChT+}sXO^CG&qSKGe^`Cw* zt!eG*r~5INp`_&@bhE27Qyq6ZyZvQM&|2CK8Ezosy|k-AMbXX;!QkrZSMR)|6e_u|C{*t9c-Y4C2mlF-Sg!#6qP zXTL&V@G>bQ z@u!Tj(x7BN%xE(m=fk?4$Z8v^nFP=Ba@j?TF%;^y)5KY`}9ZqYO4#) zEbCbtrML*GSr8FoVh+n>xvpumNmU)Whj7bjZcdAv8v;+&92;Ey>6@|z@@Df+yCvPq z6}KRQ?dh%MYYEc-_Nuu(>_7t=E8;HqxXKcC3$6Qo*VdQ`!!2%A_k`jD=gfL3{-%iw`{L}bxVkOw zag9e@;O0Jgpyf^Lm9xC%>`K$Fee$~d-kErAW^+%XopO!|=*>kMNN%c~7>@BAVFO9_ z*Q{OfpmX_hrlB^}O^zp>LpySFUW?VU9`7#$&4gITU!1>A?kuBRqj4}SM3ZN;@Q?3HK6^ZW2HSeKSv~qwhyL-N z7xcSL?{(BWrYXd!H)O`V7c8@0zkrJCHOWTE*W1?V49AkMw%_BYcMI{`?mAC_T%4`i zxP6@gsv53b9#7rh<6+-Rk=yoh-2pDf!u1Tig&q05o;8)422PW$J;vUF&t(`ye%*(+ zbxh8I9!dZkusKar5nV)B;6ebOw#7&O#K*Wuj_AEvyB(bl%1i$N-T-!)07_dC65!@F zV9#CupVwud{}ExyW#8Cs2l^%1YpE4kw4X?XPi&MHq^*zU+?I~S3hGp0dX$v{SVdr^ zhsFI0obVaA%^7Fhju95yvRR(bOkn^X9%CTjz-g1={a?F9$Iqlj;{9RuCEnk49=dg$ z$Q9rdN}TsSVrX&T|Hxj%SmKabn(ZA#2$IAnYQ_nsAhJc?skNXSM%zg!okQK z-H&lrer#kysN@>H7hl;1OP1tB?Zi@E1vlLz?G#Q_JtbbLrBHn!W8B18VI^`v)v~?h zozYQBg(c&WkV~pW_fQyNE`<{%b?S`%HC=3=!{W`tJ>P8p1erDL4twVP}Tr5SlXcTCU$3YpIVAVwQh-Y(( zqGImm{K2Mercq7EraLy|b56v3ju97G<$0FoX~JiIGAHopMVY9iN`#^h4W=9EPjc>5 zJ(W~~jU!Ax8*HhkaN?tLE=oidW_m`2KZS_nk%g2&=S%fxLEWZ^c1>Xb1$IVdi57@< zzD6Kjgn$wb(2dlJzD2u0qv)Jch|*rP@Mn$M7@%Y(>>Ny6{-}{IR*@e6DR{WYKp3Z9 z>83?iq*m5vd#aDWsRX4|ja$0fRZ!{dVdyl@T3l>Y z)s50n1ujj%eG#a6D(9xY->liu)0|hGKE|Ype|3ze!e25YLKE1I&9k0PeJzUy#mmP~N}z)JY)wkjyN{^g$T zSEuGHd}ZUTKID5OXpYW=z!W2UwIYbd2^k*h!Q>R4L1=Z6Cgje$1!9D% zpblkCi3MFO9yVI!0}bRrp~I~4visTx~7#DEz`mVl_sjhmY<>4Q1J9CdTOk=Qk3-=Q__YEqsnT;Bx+X{ zK&?_*lK=(KHf`_tqomABwuYJ7#%)1Dg*-l+Nf50@(#iT=<21D^U0K&##g^O-u24K{ z7jiA(&Sp%Wmw`T4nMv;CO6+`E?M={} zhYAZxj;^v81X~Ra#gv+kW+CfZY@g;Wa@a0Zr0qu-uEzTAu7o4x;+4$&n#7)Fomt~} z$lVG;<-UsL>~`%ITBx15+yVg*5FJowI4SFPFL(r*_lB=g%nI=CWaETkl~&|w5L0A^ zYj2nki>u@0pGlb8G;MT-*2 z$^5Ou3|UhIlkmFhy)Y(qofcPsQdLR@pt|q)K-Sx8lK7r5c=ja#_tk(MdcNQ{&;+QfvX{vufFL@y6BE38Is4~G%%PVYDFtq4*IkWH}i=5Uw> zth5uc@O901z!`$q9sf+Xx-t={@;PCVMzj`HKW=M4L>cb%(TRF&y+a$I&ra~#(r z|M5ZauHrT_1-ao5`b7plp-~axU+m5?|LMYpgms#sVZ53&l@UwoajP+a`_YLDYa~masU-cC&4l6Q8E^V+f)dEZe zW)SEUkb(RC>QV3@d3v17gLlQCsb(Gs0KCQa5$=+D0bFNkMBw$|{l6MW8Vrp5a+^2Ie65@rRbBASjEllNhM5du`0o9`*3t>eQbwDDVVoP9H2plm6q*|k1Ek>bR zTXqvZcV5@8xQfv&S9j(V*FspvLNKx{!?v~Mq7fdP=TV#G8QV>71Qf1s(w&?yMt4!q zh9m}_bQpJK7oieHp*wP+%JwrzmG-(Gcm@kn2V(5Qw}r5Oy|8Yc>=jqZ6|1iYaJ> z<+Eh8>{ah8RHN#ch)0{+ubJQWYOBZ!pGH@&Xftbfm;W=I&pDw*hA&q!5sUU~zjh{n zZi}Z4F4r?IgW7zLitPGk5QAYILo!50>3ssL60P`*##&uR+3gJOGRR&-_{Qedi^nQgfHy((cud?mua)wsruk2nlc`@-MV+~W zvEO67F{-z=zDWyWg*gksDYI-f9gli{cC>Fvdo$7cNMJixw0WSz2Ax?uo=+%BV6#(^ zu}Ed^^m3wjOnESh66qu->ycd#%Cdj`X}#OK>`GCMtgytMB)#|u2khxUv>ZOOx{ z?HR7U+Bz0uyh9=TJfkG2Ui#;#il66l3P*Lir+C;Fhf=_gVRJ3*R+Zcw}gvtfU~ z24UC?)`vvVBfa-Fih_Flp4&YMaWQh#{c9?$&MXOThIgK0@s{J8#uKkAgQZvg$g0MM zmS#PRt2x)ulikJt#H_eGK>+hjU?R2iJxxKnKF6<~zvG{aehNX5w$DUs&O5NTy*uT6 zq7#l!u2JLr`z$}T$-rl+MQhoo{s`-<*57p^6FLD+#JpEg5&-_oi@tuceZD)q(L=vb z`F%nFv*)8P2s`kc@XX;M8eONMp+cuQ3WOgGx;N%{&n2N|FvZ{Bh)bB9GME=dk zzLFkm56wS76c9L&U_pZi5hhf)kYPiI4-F=OIFVvSivTC5G^leT&yg!nn#9@A=TM_ZktS7I&?QHgMVCgEI+bcw zt5>lS9U7GXA=Io7y?zxtmTXzGXVI=ivQz=VrfH|XWjZq~+=X&A)>X=NV^F*^`5OJ} zP;Ww>g&79!SQs(Jo_6y>eyp_c;DL<=TDHhjvE+q8J4;3I`Q_+|rVF5!soG+alA2{= z_B@+*ZQHk_%I*k6D({VqqlUieQ#fv`zKth$s2I7&waV#2KU!RRMe2@i>rPp{wsw}V zxrblqJ>hkQ=D!Bb2wpjB@qORFbRD05ef#(E6GU&(y;hq2Kgv(Q0SUzKxrLg0sV%d- zVy{5M9(>5bqzc>bA@wdx?Gz&!~q)KIbJ zJL^ySFg#SOjL>Wd&x-n#X~IdDbJVCxOB-m=G!Oc8DNOIm>CB{>BGslvN7VGmQC;N@ z099j!E7FygEJ##>$Rm!+H4U1vtFm@AlcHivqE*k%l)b508uv`JR{wxC>sj~|Vs%W( zv~8$cUTgYxD^o3ERorPc@~gZ8zU-FMy{etArfboKi6v?4%~#+2=#@8Jz^H|*-+jgZ z3+-Kk4a#+(0~JPitaHV5*t(T0I~dxFkd5~}o-*c>P>XBj%iV!s0~us+&)cY}KOsh` zV~Jso`MrTxe2J%)VJ(1WjgS*I;)9yY=w;eO-C5?NYdv|Rp}$hvD5L3fn$lK>b!uD? zNke+o`kICM$BQ+>S!<-co~S9Q$4*;qi^|4!U9>Oqs!=epqdMTV@lN|dO%JoPZYML{ z2~HGWi?1=b15Zor!2^W3%eFmc$t$KI`V&3M^G2xKej(>MA>_>SxuU(x>OAw)V;f58 zN&_32Fb#F|JYhO3!aOV6Q5UFTO&6E$N~?NrGswOL>N?!XeqIXq$WRL2qqd#@ug@}w z>yqnIZwbe`Lv~BmTw}?We{XlHM9=CH4!oY)ZkZ!+9Tw=Po8Qr;UB(f3zN%?HZH5DERs=@BFc2j_oBioUrLj0yo`%v zHrTXFrX`ESEM50FnJqWs&0GfAqc`DsILqG=8a4q#rinO!Q%w-X74grbi)KP8BCzx*0a(bJme2k*rhc z+e?WGurN6lL32FGBj+M4o$~c-gth7aAY#g!)D^K4J>NX@Rg|0>)<$yO(Ntv$$~XR# zrqxU&Wnp(%hcMQNpdBS`21^yNQX~nM&D&~Cdltx^Hnvwgpjmo{9@wJKsJo>Kt3<^f z(weqp`XnhbJ6qV~7?r7yfj#ohs-^@g zKyWRB_xsrWO)zyPa-V+%+*h>ZiZlPK%ups&sqvXHzM+bnSV&}F2qUmIOnWHG=D1=R zZx+DVgQI@4cDkh^Bta#fF_3Ufupny*D<1j_tzzP1hbb9=N0EpQefwjpCP&4M4e;xX zSK2e)={^-p-(?kI(HAQhu9Rifjt?niH5U`RPqnSnm@LegMR~wAp)*$Q%n{#&CC>aI zNUr`=`fH9GXxnb$4cE%Pkt{ijNRVFG+}Zi^ zWQ#4i`_u&_@$OVQ+uhWBkNcy^&Sr)I-rtL%xxG0WGI@pC>wTwk;SF~<-`aeXR2Tfj znX~s|(D`tUQyf<;Abv;ADzh|@O0RO)wygmQ51 zB-P($tM;a`eQK*Uuekz@NWj_H$5*9@rEa~dzH~D3>293rKZm$z*_`qx-^NXYnj&?> ztnvk`@ynS^%~2t(lq27URpmx{OcTu@9>Np%@MNHU@(VJDYB9o|;CKFz?3SG^@2`8x5Dc3jVQ)9oG^ewq18 zbFf!D)_MB}zmO08VGB=0v(G-)V|MpfW99j1y^YktR;Kc6I3ehFz2)ZzRQx(*NX)7m z)PP`nn#{^0h-rRO?90WzFMF`>_Ykaltj+*wLVw!I=o}00~ZUEmduKF&2V()n< zPo*};?2e8qjOt4S37-BhpW=>9Ql^IgHjn^g?g7VwryQ-caIW(tM*O&s0wvJ+K574u zE&ZYm2am?Akd0KjrC7v81#6@POR52BL;r4Y>MBqmf*_2(MG1$;B4CRogwTiZOI4!B zJSI!?e#r;J1GZEp3wbP%*v*>~#Pl2|ni|cU7N_3ekN0veL!1x@n%U)FD5 zv~7{>LL~BVsYuG2kdQL2BM%RZ-nOSeP{R?|$Abip1^q_#2x>My$j2VY2K8{sf-Vzt z4D~2cUwjISl4j;&><5YNSn9=M!iXgHjM-=q4mA+P4g$^Gum6A#g2*ttfUY5Ygj2TZ zb575rypJG)z-uNYFx>Dcicv`aeC!l4F|UHrZ>XaLn*{-)F~gim0aSwLrsdKa4rh)r z6nhW+kSGuZVCXirGk|LVJYntdMIbwO}ObgR6Li$lG7*dHqvBrE+ zZMwuGGqOPRuMgYkQC#K2o>Dqo<41SUWKIuKzXDJ*NHKdjINE%Gpvs7Sh!(qe`@x>5>IaOQ$WA&Bx4 zAu%t@av$)DIqMYY?K86kOL_NLNF7iDCBClCbIy12KLZmFbeZ6nGhar z(Pic@2P331D`EmFf&>HtIK|FS5c4>Z6UIbR&FZ2#kw^j(f&&Jk1Qby1SaHI%kpFJt zFL`JU$Qz2 zz`@)J8;9{g*GXUh{(?Z4bJP5%KXEZB)&ew=LOKP4Mj>JYvVuDck;VSAN9XND@okI@ z#YKB5VonA&Bvg?Sut7+!BuN4h)stI#P)ak?EN8|JLrfKaFiUJMJmAP^T(nsVXeWhC zJ|Chj_Ok$>Gvh`QN1N>23iRQKbnf!2EL4dcgET9xV#v}IF5J{1Aag@GZ$;q_gd&G1 zyTmukL>2=y0ja773xm|!59%YjeKb~gt`!YadR}Qt4@^~y4^)FwAo3F-TGb%7;2_piS7na}(?z{NkWEG6 zQ*%UE=n2#RV!}l-buS5(RO_)?ZDJ8=Ql#$VcMe5G=Mp6nB}oxNFm1E|h7}@$l_03o zAdEFWzYjjiw7O(eR^?|c@s%pX)gk(nL@k00gl90&CjU;YFoPoVq~#g?rfFr1Y0vh67?{Z&RcF>p$N?;W(WlTpK zwQ-IjUJYVF{nwiv@h564MZC> zWdFxmH40?0q7^*iy9@$slR{+^0##e~Y&A|_opw*t4oH8(`BLv#rS?*BgE)`EZVP}x zf78nU>QZ(>w2}r@Q)$9AW{E^jk>D=qBpOC9UQ^+QVq*1d+2rzZzXDr|wN++36m1=93GEBVCPZB36hE$K@*t2VaCRgG z;$M4LBif)Oc6MDi_ig`83TY`z(`z>Ylx_#-SwMnbo0lebjo)s!=LB*+J98>19+HA!(4Z);>_aJ6+|H-`bIF>$zhqcDMEb~YbPJ0v2=Tmoll zSRsCuegBsssGtMHLW1NMsY162QRkSpZvCnZX4h6`CJs-j&V==oCd_vrHeh&5qE+`( zY?Z@(b@+{C=1au5Fx{9}L(d`DS8mB}cLyRUP4GJH7$+e21IP7Mk9R(|_1gM1Pb@cE z_m=^7N7;PbX2z;2}o3AoSLvzd3AVHZ(VGqa=z`a4(wB17c{#Ijy%zp;y&N zaD~Uh83naaj`<>%xh6h&rM-1iV+95^T2tt_ijzW&E6A3d26Q{(Apm1QoWH>%sBapo zvZ8YfI0DfE&G1R$*b@sUIh}tw5>ZW){tlphIfbqHYB95|H^e-ughL7wtBIAB{~01( z!xkm*dZ|6SQ9pJieK?TK^ryE4mPjcNtJ&IEGoyK_j>Y1VrGhgp1Zpyi@8or9u~fk3 z@lbTGOM!TgvDJL$tHqY}%FY^nv~7?L?XdgWky+P}wFs(N+TD8eUi)p4z0|3N_)z*3 zXD$w!v8_d^_Mr8+v|WWL>BZ>|R%T8@0Cl>dHH-boFZ!;=|QJ?2x_i~gh_hb}}X$8T2~7N<)tRII^O8&IOT zBR#iSOyx0?g{vCWNvn1dYCf`KfXx^+;qW=v@?T)_>x zFa55o37CSeC#yMHfNyjlnz(G`0;l+L3+J)4YOWDBcVDdGDCoyU)rKqLUp0XTv?G4gQDG{EwH5r#I%o^$OxA z-s1ZNFI3{5_NAOCh^jGq!*v-jwbF2x11oGV`9-Yl`JK2e-)?Yl}?R!xpopnh9 zcb0tR0x`--St-`_!xtjJ`BLO69=j8C<9_PgF&!b8=4>8S&v9Nft-e<59Fu~$&lk$v z@#93w@9CczvTIm6Ry?DyWZjt_!9iUqV!oBId^g{{9F2X%{|5q+d`nv_c)n+1gp(V& z-+smmUQfC^C^TK~2q@zJeehdwDfTDF3>?9{+xueOvcsCHtYB{9)fX zVhHv`+hQjfrjyg0Yz9$Fi@bw zi4-eZyofQQ#)=X*7VPLTq{xv26_Py3(4$biZtm&2}(nfXbLr|PK+R>TCGTQWLBPAuX_CoHmumGNV^&|yAT0bvD>%*Tokw~QS4px?}f zp>m%1*=W_03qvK_M;1dZ8Wy5QGoICw0`EbF7(vIGR3mgB+IP@xA{iNDifL)| z6OspY2-jml;x?pl2?pS#LsMqd(Uvrs<)xBhQWT{{M9Jo5m0TscV+1d?SAcIEX?4(! z1;Cl2nylR@BSF`JxzddI{}s0kNl_68*ec0ZhQ^-6S(eNdE0aotjd$y< zN)E=m^l~Ms}RKz3y6;s0o=?rtw&M5@6 zu^%sG>dq%3WNFPeBUE%xLhpKR)EDABby!ZjH1k_5XC0N*_Y%b0OadkRoVqyDDxtkj z`epBC6lM#Ty_1@@wZ>Ov*&>qG#(I(3A6dn5-dEW@rPx{yt+beiAC)Ubn4)de<1`%& z_Q05*WO<6|^}O=t4E?<}N+b&W|D9-=A0_&Col}i6ZgyAhC)ijI6_n!SjwJf)tN&hC zskkru7wP)>PV1tF#+ekdiy?ng>n8)xVUjktN_}PAscNKI4P5etYWp|oUcazBa~)Me>_d!Nk%)))laH!?DiNq8F7A=0tk^q6z{}m_1GT1S98@Smb8N zB%z7NaK37s?Of7B)pT%(M8sba$rQjN4x~LMY={JtGKGRjAcKNZp^z%X!s_h@Dp^F; zo|p!<@V#(e(5Z?Tja4Aa|8b0p7m-sEDZ)mAxG@2C(O-b9s4tLx&mwlz+M1NO7s34u zh6S)=Vk(v|LFTM|U%{gf0httQ`2r{(Th9|Q5=WFoYk~}mo!+Eom@YcXk+6d#;okU{ z1;S92#M9%tvepq+N@gH#^dj>nl1Zb8OH9nmD`<@pWx)2HE~Etf*RB!04+;v{C3QOZu6TAln(MFbw;I3 zlOS$F$VNqi&jRf7|0@4U8OG>BN_akVf6XId(6A}diO8~){!=M@ z+x5e19C=_RkM{F49#8ZmlWPL!KG9y$s$ zHdqR5|9t4!B!6OBGblx8s8T!*fK@z=2QlPiN%)bL$k%Rx} z)gau!J**SCkanQ(*)p^cy=;rwWzsnAQkMHCT*kurET&F2 zFk>U>Enno#M*MM@fymA@@6pBB!ER7}%;rHhkgJe=1h`qFBw0CvB{z%^=K$Jxz7;?Acmn9De(Z>;UrTy#P8$rZb!-Eu-nN14!<9PWrXT$oG0y44|6@efkH=^tl#bwsV`v6H3Lmlk^3TW;yt0G!F! zu{7J0t@N`KJL6vO*U;OF>8Kxi>=FO7(!;Ijl2o1CKUcR@WW(cgH-4pOHE>I!rlum# z7Qj{xLgEeYBXI|T$)l%?sF|$je*@gYs)tR;O90)eydZizZ zqXg7X_urHK$y@Jog~Pt}DPQ!TQ?K%m17FL`hZpbvjwP)($?nItasWPm{6A+#O4rYK zl&`;O-21xJg-rY1EnRw(VztH?Kj`E^c>hAJxhTS^VM8}hPY$7L9$ZPNR|5jc1 zGa%u08&h#_M{JKaX9xFuVV4pXXmr449s)OM9Vl*Fw{=LTbt5KpEQcx>cx_Wbc3pyk zzcz9Q=WP=BfD))BrS@wg(sesjc-Fyz_c0nvcRx%AZ7H~bl)-c&_;;EnbqpARel#!v zmQ8))gy!U0p%gY>wpyU{Nko`)+Hw%hMMSUmaRZSVd#8BQHy0!4Pp8*cYgm2Mr-Zk+ zerAVsI=EVHmxXj!g2V@LU4eXLLLjf_7$UcPZy0@t_J&XcgSQ7ScersTA#g-v7l~(6 zk`@4Fc!6GYcD?6tov4No$8CuiQ&vQ4>0>MThl(3k6woD8W0Hgmr*w8l|1VqC9f=lf zG&mxJo5po4XpKZSca*q=AroOj1BC`rib~-Wys{OCD1u1GiM{8B z*9U!oMk15AkZ7o7H1rxN$!Vc@K^SQ!60T}6mLSLZIx$Y zRu~nd!HQAnA%)0k8|M?u_lKW-0Z_p==i?)8v zSex;cE7oy|RX0#<=X}-IoNhRr*QAlM*NFoMl+7uM!%;L02Tzo#l;@c}2sRRK(wb7J zTds+aNcT?pmV&)BjV7m%2lz@Th*(N9fg@vW^husL*dZu3|2Vz!nYO6xvo%VQUPMg*w+&>4tzf)=de3nCn6m?P(DZVIKUI6`-bO zK$M-JF`6NYh%i|sCzm#@h()V$2yjEc6>1?BC0Sz2y=?bWjW_gQOQ~FxTU}2rQ7#ND4lR6;+0fv-HT-W1J zMWi?a)uERcO_qYFDZ(+VVn0$PGH^vIVx~BQ`lbZ{{~Xf8Mg}QluH+8PKopFiUr5wj`43aK~YUX!kRVnNfKAek1A#rD9RI*Ga823rVL>xv}%eQ z5nyQQtW+2?Qwfz*h^em%qRNUJb=Rjr$ERc3pZYPX=(bO2wnA_e5<9Xm-kPpv5Uz?e)-@d$`zSRdv5eF{$Eu_nn_^hF|FI7`Z|*6k_%}B5+L>Y-A%J8lx#F+* zc@smsnzNuM!Ti3PU0Vm@g)w>D?D z5(6-q%cgk>x#ViLnyRSJ;iZU5x3y}yT+4+|R=LB9r70-2_BXq7D!Takx_R^$49h5o zo3yb5sH2i#A7-(<*1HIsMyxxnIaj^SE4~<$Fc6WpyCY_#nXK{ZOG=Vk4*IpfV?~Ke zWF54#9LxK0lE&7{~ovEBxrHJt8+WIlE5kpz-0KWZtEN|o4j`0 zAhh})0C=EvD@*xX9}Dxo<9o9lrl+MMXVIEgB<4U#O1tp2sU1YYgtc5Sc(niJr*N9R zrG%$Jd#9o~wjb-fIV{4DLcgPxr8J?Q2T3g7#;818h5Dg0-HVErgB~7YdF6z(6kAr( zTP`EIls9Y`){>${92OcpM89fdK>K)Lj91)4!UAG7u;IZL61Wa=V>A0HL58vt1Fcu_ zKYa|a4G{%2alW^t#Q^j)Yg|)8Dp%iHyh9AhUi+j=a$3PeW61Wxq@hz>NFGG9U4SIJ z`}@852*{4wz#=QZx;iewu}YEb|H`kd6rn5=cXkmKbjn9}${G5`p~bQV3oN<(uXCJE z19`>v=)^i!!@Nwk+kW<$cZ>w3t= zMYFIRG!2xpThw1IHZU+XBl_g3d9xEL{CL``iNH1`Ge$$iNSBAlpPKZF$fTnIs%~>= zfs~uYVimlTM;;#%Vn3X*=fcRoY{O9+zZBt=8QHQOExfEOAYw$u8BtG{WX5FU(V0x5 zd?%3zXOcwf!X3JY97lB&c$_V1xZ1g$yjird8IeXg(mg$}L5$8tZPc(*Gqh~3q5*o+ zSfAp^wiP*{2jr7f79*Hw|3Z{CgnUu5!pLYH$Vu7pjC<UjEH=m7?BhgXyM6i!q<%nkOaO~ ze$40Cx(EOu`FsR{0GZvJZHb+`$RL?}{lyuLZR9njbK2dYlGZ?6AyUk~zbw&gEEJ^h(fR5S15BR>F&Nxs z%`^0e#>t)536!6`|Jdy3eRCC(RrlPJ$(y4siUA&X4i3|#?ca!voz>}yMrqb#D2a2( z5+J4$g8ZQL?4gu=F#!^n}%9eVevb&9Er zJPv3->6NiZ*y?sHrnAt5I(293^sl9r#zIV@^m%-TMO`d2}KHn)$?6rI4 z@x|%E$E8ql=^i7=4p9nYUa2h_seyjoZ0L~RXLpn4+l0B>FT>z-hwTt97voNwwaL@) za^|VseWGrcybb6Q>F(#|spaf$R+ShC$}e-3T#SC~0k0IZ)5YSAwZ#&5J2; z&=eDx1w);0hmAdmjj*^{*8O(m?wf`u7w*TG)wqX5$AG>b-z)J5SLVzU2$15?wRfPP^BQKFmYJ@}@1|v4`KnHh2CE> zuQy3v|37DFn2~vGAbHm3N0-RBgq&^jlm6iY`bK^M60CjSehcY5uhIe!_Y-l_Tbnsm zeKN`uxLN(GCggx@iPLfExbflCJeh)B(u>R9Vr6yXhM9div|jqxaFvpwcqNeo|}?@VP(V zfCD(sZd&xn*YWiGaZmh0t*Z!D{;v+TCE*W*aB z{Z%iqXS+YL%R9hopA(yl5^BTm+au{)*c^INGuvp2w?h3%Vg4N3vrlYp-p|m%4-f?e z{|+Qr(BMIY2?r`5n4kbdg%KqZ3^38+MT{9GI@BnzqD255MUEs{(xk$V14AO@cv56a zmoa6|q*>EuNtib+wltYjr%j#%Q~JC}6y?mI6n`!?Ixy+TrZl52{kbyY)S6Z=LZsT& ztH7ruv3~7IQY%@EW6>@>J5lZ0lWz&OgeRpGFk+mor)&?nRDUO7E_l_$f2v|n4Vehm3^{y=YzK$ zuhcyd2;HF_R~Ja)yW!Q5u#0*HKHBc^x>kGJmbsEBbf%7h%*N?gGSTUKm3IxV|C+l* z?B~_<9Y2$9`Sq3CgFUHyeoW1^E8eG^odf|A!?p!? z+}UyxcA^am@)Rv`VJ(+Aa`{5m+Ks4fSJ#(r`Y%0fo1E99s^T@sAu9!bQ&`tBngXGF zzY6N#j2gD7P=%hNm^v~kmG~%^=7m_Ya}oL&UxAvXw^)NyF43!vsrs==P7R8nUYp#M z=*x5)#B0uk{Eb*;jk`k?Xa#Evc{b&OCHldy09{(Nl%y-Hy)d8t3A>Re%Q~U0y}gWB ztHTzXWYSt5J5`gHQjCn8`?lkM3{_l=L98 z*GgOh;YbE%6clf;2X8bt_1JRb6Q0b zee<(x$MVIh70Ugh$ulB@MA%n0P3wR&|GDxPgSY*n#@$w)+m7xF4)f<9n~HRX1FV?NcOw(H_|EzO}!WCamd z`PQSX^LZz1^E*uSSQ5YgJ?B;vyx(q8q$D1xT*Ce`o!Na3Ee5>F>|lc@AUJSY zh=bSr%Hk-KFmQkws$lqP(!5Y5u!c4H%?=IIHT~fSLy@~$|LMLa5feSBL(+Sk3zw(D zp~aAO3Ch-cj;BB)#sr5h5uZ+UleCCfYJ0!xQKBXznEbqrG^GGi5VKbh5(;oo2ZJL3 zX9Iu`8g4aEyqgaV=SM(}4vT?=+C_*+NWP5;k;^+*d$csEIF=1689PrTCuuw+?W$U` z+Mmv@NSY?`(IQ)9i(@twCJE7OerY390P^UyMS^gK7c2@g@t0%5#=H&BPSIe zXeBcAH%A}fo*`|tKNJ;c<#$_cT<-juH zNHw~RB!VgDC0Q87>>TJRy;I0C3&P5;=;fFI1I%Oa{|U}%+2kyilokeyc~C$S6rtzo z=FsEX_iqu2( zaVJk>vcbndDX|E7>tgY$A-Im@q0~yi>`J=O{{Zl4pD5xH344=SMCy%Y!{uUlZhJNm zji&?%p@3jv2{h1tModiKz-pH)*CY(x`t?&EH;_H-U0&oAFieDS;HejR>1%;UV{K8T$0_CO6kW_> zFo#*pXqk_Ftc(!>ROpRBGS_Gny5-Hj|I4Sw8qB%A91%G0@5h$y@|x|6JROdcFiK2S zo@rW>G;$1^nw^z4KQ-F|;0e-5K2$`rvM9}pIIIboG@un?GIVMcA-g3B=rqkfgjfo1 z1|juCnw7`ZxjNM}>Gady5~)|0ktpk$|CttdZR52*X!ZHn5>76Kh{Pwx3GOiM9;xk9bq|L?;;zHd;2ppA2H7h^JMB~ zWad7fB7OomS#b+2u{YxEoWDwQl02A z6mm9Y6s?5XE~)xNwqSCa$+t3)w|M3|-(a1HU65>^$e!Qs^klVF)Q3V=m^e~ychf}l z7Ae8V3BvdSaCpRmBFi&9rT2o6y)QO`q1zEs`Glm4^9V_-{xDOVoclRQz?Tf(`&?F? z$2mKBMZHv=i#pOGy)M+J|5o3DtaXLh-sJK9sLZhM!Hm(W0y_gw7f(`W}2;Bn{N-HA15WD}A2=Zf%30w?Av6Y3$GaTWGx;qI- zt3dym2oWs2RpUL9us(DXiReqajHtM0a<(!PJUZ(N6%@aLNF~K6K^Odr_9KWGyNCuf z7`aG*kob}y{I5O&5l=ZJPq{#Ypr;Xu8{^ZmnutFr96kG@or%D(CV>qEO1zQ6pA2g( zuE;{TNU`=YE7PhZlK8=cz`fWDJE5Zt9T_5;;6WNplLssah6oG9s|ls58V1V0dt(ee z^ue16zJ!Q2*t?4s|3oxNRF4}ZKSjBZnfi}J{0mD%!=Kp1*-(Nc6bQ_-2-~Z&aS23E z)IR#tiRDu}fnvp`6A1+%I=fLg#@GN;fy3QPD6}}YRScvE^03E1z`qbaSfmMFqzNOW zinrPdK0Jt0>_U}!Mf97lKx7S2B*uH|h#{m5kUOcQk_clwh$wJ~a-2kj*hW;V!L2g0 zhG0jMkVoti35cUd=>xYhw8Hm0Gfm=;!&8oliW_=szsXsE<}!$H+^g*CxMX}fi)b5b zEG23*2$);H(eg)!+^TF@Ml^{qnOVJA3%`g!z->9NNF0~SYLZ6`x)2k?bn*+Wn5lG3 zNt%#DY=gjF|CyZKLB;~O!Sr&8iR{L&2*#6x$oB9_QY4A4Q_9l7N0T}fquilw+?Sv< z6pdT3pOAo=SxA(-u!(R=N8_S)qzdHQ7Mlb~w4kRSRE)GdiK*;I#cMQ$FvbY@2>d&~ zfk?-Ck~XW1pJx(~x1=Zw>IlAcM~PAok2EUg8;A{{k)+5SpB&1m`;3HnMzO?*Ou0jF z$;Qbj4rj~Eiaa1XB*3{U2q?Lam@z$<*p!ZdNzs(iJW4+tw7Kj- z5=<@mv`>O~DB@#5zJSe&YRqnP(1A#^aq-GjvCxhfPR3l1_k2&vgF5!Stlzx3vXl}w z1W#(w&WNZy1-PyggbS{a&2B3Q|02nlc*dE~P#Pl8pZvLlU=z{AxE*Csn9|YV)X@}S zj6dAY6y!G106t=BkI=vohHF;G;gp zfC$%XMF{;*tXv9vk^oM15FAxAf%LqXd=Vu53(<={OdZ8u6qvAxBLSHx2hz8kq{XoW z5(|-wck9m;V^bIW4{>xZ3+Wxm8xINz2}vu@Lsf`ftxvifiHPC~rGnJoskf?=5JoLQ zpNO?+@GJ&A3!kdOsEy~;d>?Y`2~KWQ}>!4O)}Sje`C9LV!M zLvmUadCz}^ERg`NhN)AZNfnm`Kr)m?@GM*>jno#|GHeA48J#ldn+dUHFo+Wju!B^u zBTA7S&CZR8AhJ!2NTpI-)5m2*f#_8S;nd67$arZs;H1R0a5hL&U6RO4rOm^qSth;UslJdufv%Q(^zWGzmOklnCMK6BNmpuOES|LhP0YB#-o zPMX*v71dW@WwFLp%P^S$?k&S;9lwb1N!>f74JgH=&B2LKg7{kvvf~O4TdtCz*8$W~V2lS_3r5|qh>|+7ohS#D7*Tq@Sa}K!481@bpP8Cq2OBD; zBbx7=HwPY!NP1q2Oc%n{PX&QI$(@NE2BaRQvu+(x94xRp#3=c|Gw#5V3yxISf=01o z(oq#ogFwj9gg=5nMY1a0yW9S7~u%rnv7Gek+mm(w% z+O!KbNnYC87&}&7gyr1zP+`wom;Y#EouJSumJBa(Op++YAJ#%f|C5L@?w_`i-tMK6 zF-ie^U4d9%(hJ^2#J;+swJIeHFFXV@X91l)Q*knjB7zzX|9j58?nKl4OU`iDl{l(RII)SY|-ABf%Ys z!llgqEy^}|2pp+AOw3ceMNHImm z=lZpa!1PzIz%Woo&j#EnmqZJBb3WjcU5h5RrZpwKEQoX_4YTX9 zrT)c(80t++y)L~8vPFo)w$n3)5qWHtHoZc%(Fw&4D9E*H_wf~YhH4Xb>CTI6lb9&v zi_E^72^}%*!XWDyKF#JN$BVE_RCQ=re$e7^ike$YJ`K?PTsyRgXqD6m1C}-h1{I&+ z>TfI1<~<3w_FjqFY@4oIFANG$En=1N6#mF%uh=i@|4!nb?pL~ou+=bLn*+I>CXrVO zi|sOrm4)q-{@$9Hf_VL=tGsK`5ahCZY2&17gmY!&;0PL7Yf93RTq-IgmG6sI>7Wi& z`>V&wU~oSb(T~3B#{d@co@u-A-9Suk?l5rwHsk*Y?>ScG5l_sA8{2_RR*^7qwj<9W z-iXLr(h#rfzxcbmM?~$RXMnnLn$Et zi9!@Lua0fWUR5qfXb7zf6%DsdZdj)=#Pt}?Oia*3ZNrBpOEtIa=3T|V-q#58+DyV) zEN%0ze##R+5gb|Xf9oZyLgol&TO4L$>J2pmYTpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+{m$`$B!UGiX2I@q{)r8 zPO4nVvZc$HFk{M`NwcQSn>cgo+{v@2&!0ep3LQ$c=+IV1lPVqQDrVEAP@_tn>1(Rh zt5~yY-O9CPyRKlviXBU~tl6_@(}w)2wyi^?Zb8D0>yd5AdM1CByu~pkRC{y-3m#0k zu*s)O5gT62xUu8MkRwZ;Ou4e<%O~0T#mu?$)LNcHi)IOUwCU5RQ>%{aZnf*zuw%=f zO}n=3+qiS^@864COY9B2xbfr2lSc%tyrbfs#G6Z>P95jw>e#bu-_E_e?C0LY zi~k=_TR8di=+moT@0t}u=IrCkpHIKO{rmXy>kn*xzyI@d{U_j00S;*3ff^N99C!#e z=pb7CIrZR#6jo^Ah3F|rk$WPMg5ifChL})vB9>_4i72MH9f`$}qvDG&#wg>AA9+aQ zjX3707sihDIhC6<&BL>Ex4EAqgdq*G*~Vl~`t}<(6D_>E)MT z!dB&EK89&#Wlc&p=9z4^>E@gCtw~#%Aw>x1QgjMsXGm%8*JnpkCKYH+a!$nHorvO@ z=%S1^>gc18Mk?u~U>-{8rI==#6o;C2>glJThAQf)q?$Hpsi>x^>Z+`^>gubo#{Vko zthCl@>#exvs_U-2_Uh}ezy>Squ*4Q??6JrutL(DOHtX!O&_*lmwA5B>?X}outL?Vj zcI)l8;D#&ixa5{=?z!lutM0n&w(IV@@Ww0ey!6&<@4fiutM9)2_UrGz00%7azyxQM zM8PovP$UotlgeTttntPiTU7BtA9pPB$Rw9+^2sRYr*O(F4;6Bf zFSktc!F16qvz0O5tn<#+CUB6?JO?fG&_pk~Nzvi13~Ufq*#ei-NJlO8)D7iKwUIVQ z<;tEfX>v7AR(~z_*db+2_StBst@hd*DLt;)Y{xD4+;rD%_uY8s{Wf+?cmEo;-hc5&Y}P&%S>4qZNMQ>)-GH z|LN-=00&5&{1NbgrEtvt4p_JGG4O#9yomrKSdj@DW`Pvc68$pB!4C4PdNGQE2S>;% z3zASs81#<`QMEzA7!V^bB;5&TNJFrIu!cCyp$=8D!pWqNFg@JiMgLm(5+VwbgE2g! z5`~q-B|32>KYXHz0x%IO(!`2VbP4>Ls4637@i$TYBG`}`hf0AO zlw<|H;>7m(N@>cDp#-rfkR*Cg?Il!s5Y>nhD!N39rbY^iL;yEAdZ&z%lp(7#=|nuL ztBukmb`HIbN@>N?23>R}BQ;V^_jS|C*srE19a=!!G*glcRW&<3YNV8UKcG5HKUApi(%LV{V5)c-<+46p4Y0sxSJ#X1SHTWM`> zSqTIH?6qaU9qyF~I}>|s0xq^yu5>MC*y&P;pfgEsPP7XW$&N+1*43eG!%N=snzyiZ zODuA@d)~s3)s3qgZ+quUUz>Q>SNAPibnDALrOEeJ;0=j4^_dj*^7lY*Jre6JE_KOLb8#Uj2W#4naLDVGKT!Sswe;CxLJ%Z zl!0Pp%5)h{QrKGzuF6;TwerC*&#j@xN75UIcCNrcb&7DNwYtev4QKOfVX&`laMw_mQr77*1 zQ9t<8q#jBXL!Ih$S=H37<_M}imP1(2c!mrmFpeHwBwH&u*29vtmw_FYSx<-6TS0bX zjE$lZSJyJWHuDmh?UHD}nZMR1wzmIA?aL^;k-XkEfH~IfgoIn%=uWq~*PW_!v-{n@ z`8G>@R_m7wGN=z}3Tz>!WVpELdGLy7r(rJiA`L!BU+y}H(!<@Bw49VRL@ zI**iYAFE@t>xwh`*SkaZmWjP2XkWYBQ}lM6*Zo^}pSx}Hevr5ei|^BEdqMoJ_re=q zc7i{=;zt7bv=AO#YA0pZ7f<<=`T6mc&phTDFSLtdUPg&8O5`Q~Pb z)UzI9qn}miht~2PDa`e+r(5iEFS`WuJ~EvDeZ6pxJ>u^q_+vvplx8n{%`3n84QeOz ztK)mF)E@f7qUeyTADi6^^(@B6KL4n~|2$z+@YCM^&GW_2{`R~7{qVmZ`Q<+U_zR}~ zGBN*2(qG>7pHICC!F~3pc}L}ca)W>P!GB7GfJXglVt~TsfPrIY19*WL2z|vg zeJ3Xn3Rq1XI2Io`9~6iY>sNvqn1Ww4f{TKJ5EFvLM0dCYfs{srQNw~*frHTJf-0Ct zeK$)sST~@xEZ0X6JSY@OV^&AlgAlQVO!$OQ7=;KEgog%$*kpwr=7fcjQCf%~21JE| z1cq)VhL}QzsL_Q|I5GiHg#Hl#W=K?7u|a5f9Hv%(_cn+9f`@4cOFGyvddMDFL``o< zWc&9KeHez@gcX0dD}%U)?fGxQPTaiAESAnn+iiIEo*l zIr>M6I?-mH7%t3JR)*0yrWT5*=o71$VX`=jxClUXC{S!j6SdebzZfgQSQ)nnCvjDb z&N7U-NEphvjLvu|tynV6s1q3EhOdN$1|fjYcs|;wg2*^Gm>3ckHjQOLf#0ZY;kb?J z7#2Kuj_as5QfXj@Lqt_2Q1rhmYSi5c+r-|45G-!;b=4kaRJR1_>Joc~=C9 z8x3h8Qif!D^pFWz5&?;e_J}MLS&}lF(+7IR7aarw9_=7%VOsV?Sv(C0SZB*JJ2$JRccHA~%${!jwLglQQUX z{=@bC-CTGW+F-!6%nDa+M&lmB@pbe|cbS*&U5pc!YU+-J^q%Su2&f zn3kcKQh}0%1`?NfC!MK&t)iKf@tK%uE~L3qr>PL8`AcNAMXMQ`K+>8#L7TE^JH}_5 zp`n{*#G9z{kG{Ec17VoTWQM6pX~F3c$th$7Fp{mboUpNm1puA5$x-2hf|P$-rhdSV&FcP1x` zKe`b5nKry>p|?|{rop7ZrldgTa5w^`MY$e1$`w1hmJLCrtQ9K{$EAhnhYOc(PAVCz zMjl{VA6YtfAmV?aX-7)sbZa^hX=+Smsxx&u8F$Kld1|BFF>^->YAq=c{@158nG^MA zsG_5&SO2F=j5>fQ_^7%#5p(LNTz75MIBfcnLT2cFd)iFR0-U1psk1?Y$eTF0ks8nmViZAzYtRt5y<8x~3$i8W^kE6TuoL#Yzxw`WnZItLt*5 zAHssP*@eS8Wz1TwJK?OQN{lpttriJ5%etYf$E(AVjuVuuy<)C#w-Ms18`L?i*6JA<_0<8Y_a9C>Sj}omF}q z-2ZAHH;XC&SP&a96CALzKOwR*3l%RbSVG%8MN2guiyjh-sh8HYM;jhZTOU!27F7$h z5t<`CD_-MqwXz{)^%s0gi?w815wexDzB09B;kBd0ww^Jz-g0A0sJ5I|7IdpJ+yS>` zi-meS7G1`GZiKdEeZ z0lqt8y*6RMLV>{eE45Kq08@Lo3Y?b_F~Ju5DGV$b(7P@2+hJyB!OqBk8C)G5d?h99 zCMVp$vjM_{dX~o$oT7RY0BpW0JUXk$yQZ1Kf@ME5T*K0`iaPu%Jv=E?N0lS|AA}c< z=?IBl6vV;R5Kat9G#ejLJS9Wy!&qz)LwI#pY&%t)#X)hzr6(Tu>ycnAE-V~4U0igq zw83Vw#)k2kUzx_K^2P9oF=C7?b{rdU{Fi$iFXI(^fvG8dTp5L|E_8gxu>Ug10~1<* zTuO|r$gVQF4m62wd@n|K$i?P-XhUVJxh|3XDVi+Fq%0HS+ZMH0V>=5OkK9WvCoruH z#oZFi3|Ge4G|DA&x$)^5d8{5rM`yjPB@@sP6#G2EET*MAy)^uQl|e){W6KkPuF0$| ziLAT03>>tq7OkAkp;E$LHO*55S10kX7)u@3EUeo4K=XjvFS4g?Os+o zND7M`Dt!_p&9sYq7P45=kdf1vW7I~b)RswVKixg~JQP8_8dF_)RsAGSJuq3VL>QfF ze|*($0oE1zAg6S|obi)|{LM2hYiGR}5!OmfJu7kT8*@!_8`G{0!GdlS)exbdySLSA z-6)|f%B|9PfL*qAeO`l|t9^9XB_q~FVMSmY*u&-6Y&;s49Tu5Q*_`c<8BKwd+&V+v zK_Qbw!Pg{X-l@0{593*|{oQ|*rPTS4?oHqA2^I6rQS6Nn=$#R|t*4#A((3_h{T)FP zo8QVDDPKJj!%WV-(@q9jIt8fT7;csU&U91F;3D$hZe3+ix8Zc*Gx<&88Qy zF09_-vL4ydnGrKw>4gF8>*WvzP94JDaK~O8%c*?1uB-+%)y*Ck$&P_1yz7$|?OhR^ z*skkW-r3u}==B3V$#v>M_3d*v?O$@|s8i(N9)T>jz84BX%7*R)zPz(>v&CJ&H1cfu zPBiQ;66P+>SfcJ2B^cHoF2|1J)Y6S(E=2#X;zB{rTwVYTf7?ky??CB;*!S=Cv4nyYYcw?SYQK`$~YG&bR+aNbEUGZ+a>+|B<$O@Qg+!M##f7Db4<2>kA5z(4I+*02; z%>21^yoV5)cK3d?5Pd|*f9Mn&*w3H{<0Ufi(oaNt`sRDPfq$)Bg_KB(X=Ns4xAFu; zzD&w}!sdTS-+mzMe?&q|idSPQ^hPZ2LMY9egqWGEH}VSyeRT7Gj>uhH?Y)n^x`N?n zYv=uutE-%3b)e%-sHzS2mHtHy{}tJmZZ-;UsVnUjQGDft7cWQ`Vd%#jcxiJDuMkR) z=Z1~;NSAi=_DjswTb5sB$SpwXPeoRh@?>O48Tx4kV<8?+U!qJJe0}g_IwA& zR63H&6$av3g(@A-f*~c)HKc%_bjK=I=nSMPpQ=>yXgg(uBAzX$DZ8c;r>UH4G+H_5 zI$|Z|s_yh+RScXJyPiP1Y&tHr>k8V3X`#O#8qOrqQm9@0y$>H%_akw;; zrMvB(3kv#Qni=#{GgpGA{-0{*I5Ndj%Yxd1u_U^mqv_&xg%fFP_Ww;Y7tiF0#a$bg z)R)W^eQIXzQKr0#sLH~>G;`Tf)qiN_Qth$E3JrJZ)0Pa$rpk>rmz$G~v8JluT|WP4 z=IuWJDuVx^nUfhUHpg4)4yUpO!*Qis|Iy4k6RrP4GkZb)rJ1|^VSdPbYUT#zC`#SQ z_LiH&L=?d+nU2=GQ=v8e-;*6}4}Z2kHM44&XZt^zd8)JH6Q;Ts;Qp%$OO@EUs#r-Eq??Nvh4umi}^M2U)pNhLD-$hdY_t^Y$xP%Nz3Pyd13KR z7**pD!B6#$Pt6P~(Ub*bIxy9v=D1MF4CMZnq8lNAYPJ_6Mk21~C&6-@FDS)Bz8_D! zE%ujYCPyUK_**jvksl-*mI@iBm==~Cr2eg$e+`l!raLT}9cH*3lpJPy+#eri`Fx`| z$__v^KgtOqDg95)9Is;jmu4O~&75d{^1su}fh3?*{=L^<`>Tg>T`WH}GYl%? z4WvkyhN!O0iC?Ow0VGnUz$}6{l1*q4^dStf#Eq4igYG(9M z;QgwlKcNoQ}e5QAf>Xw(9p5L7(O*~ zL^k-{9&gOHjUT$D3IT&yG_>8JA2w_bq^N1}m)OeyGN~MBD1%;<*2_S;2>dUgTl^TS za(wVi;xHB{fmqL%!F;f}Y9D-L{RE@=K_c^zh#3O?MAwF)G7$#*cFV~)5?5hKegvqB zh6B`YSK*hZ1n5IzgAA!x5iJtxnqbpHOd8)o^pn4U;cbaL_~OAqW)sxas|^+10lb*@ zc7LP=gMbi$fN*2)J%RixXWGqs7$L^IU(BV&FkwMpHu#-PgNQo*ma$U#+5jfAI*UajR>Z<8QkoKTUB&fla6;%vHx$7hCTc z6O0ngbtN^sKNjyBntt8)(gRhMamNJw) zX&x4nsf|t2;=rcd8hbZQp00oEVF)y*e1? zLSjm5`5@Bss!KnVI^>88oN$_~%kZ5TT%8H? zau_0@K92`%|BpJ-04zrcjl}P{$b|(Ns?wH`W&cD@`RIm$4gI8k#1~ zt=+-bHYX8lGFYq|&0YwY;G0@M&v8cjxo-@*I!7s0Xlu~auO|mKbv{hkFpZ|MeOx?L ztx{k5Rek&YO_ojUOQy14um%|P59nTC|7D2g>kj(Vqg{VdRj9@5F5Y+7O!i7Za5z^8 z?nhMUi0tHbqJQAti#U6@%Eh(NO#1=bREz4YHfr*ZfkXG0mPyfv%CIt#BSG2L*%`yz z0?xN%xh1JNBSyz;Jnj>}HaGwC0>^Uqw^P0EZOcP4_qCh{2gb5(t3Q?R8rry5tju24 z9Ov&^!ov=o(DXKLCLcN(g)Y2oXt%z|KDM28TsjDI?x67+4A?kaMtIxp*=N`dXN_Kw z*S;>(@jiu`W_qSKEpL;eJWr;1DV%bBYG#|*sk+UqDwFurpSroTbMJa}f0Qo5Ii5{H z^>PcU}g|zV6fo&UUkQUZ=s_?oSmzbOm+J=l}7@Bkp>B>fkxBGj<;_`|+|?@F|mr zWZ$n3YhMmzyPlW+rJ18X)ca{aWM;FP9;&+DAG+>e-LpPG(0#xl5sz4XzLC+rn_xlz z@|lnE;Z^d1+4h+v@`Y9NMg7#w$-bPRzQc2As0_B$jbshut(1Q%neYK1N0}O(GE>n~w1zGtASswjRY&Mrr zBeF*Kya5E~$_LB#g4(cgyFuc54@=rZ8n{4u1t#PAHj{@g2e%G|L>4}VM5Bi;)r1h+ zhcF0*mIa2!ntEw9hh{#8GMk2GvxVg+OQx!Y6`T6|Cx?}rBIOp-R4s>n3g&vX@J+;U z)R6GT=J59A@J_OTF7$|Awut^CBA8^gfk%R(0*zuWP?_8;Nmda+%V;k z3vhiI*sBEGba5|(#MnZQJaCEZjs+eanV+cP>^DbVqDNhmq5NTsx`$NWJpxMj82%@^ z0zT0->;Jrv_(WH8hyOjgQfQCn?kfl5=Qo@N#mYfZm)NBN-qgTmG2<_E zHD8eVr;uQ36f*#_ttRhAa@`;OyO8)BT}$?2rC2@-2|1BZbX8LM?}fzQ=$dGD@c#x~ z*+9Gh?+OWbNRR(TAz>gc(jMIkZ9{VVKMDynEhVsTq~({ru&ig7eF&m|p{qA?zqq(* zNVO)G>fh-4cOfA)GeA=G7rL5YSpSW#<4jAiIUOv#%k%=ACXaSXyjTm2T7rj`|3=sI zdUt+a9FkE5Rja#&E>PdQMJ;DIyFs1c&qBg*PSxR`Lc)?X*naKT5H+ib{FD`IqvP)i z=M|GbAD(p4t}hd(Ykp`ldcT86D_z7usV*Kr(Us<3g+#JRB>v9I*UG2E>_3g-NBK$C zZuJ3KmCq;TO&8CnTDI_?g+$ST>v{8G<;z9;U+CHmLHl~ykM_gzWX9ae!>yLKtMz(P zl-6^5f_Lrl--X26Ly@j7$Mss=_s>Ei%lT!0q39oUO?|p%-SB#Q{Ahgl*E{?yBtT%Z zKMRR&Fw9HZ2hLA)9q#^yE9n96AT@-D&R->r2LlNL26Cj@Qv-?z=g#-}d%ET=Bg7Af z2mvfx&Ie9__7h!mU`@pOFjp@>3yJMcIkFnGlfTgw;UieApP+C$0KqRCkTl#+f;ki{ z6OoHtBsRc7UK6G^o{Jjl{5QI;`w^f+4ffH0qN}OYu2!oU4ol-C(A*FU0+exxZFPo0 z%up5g&+rgvZ%vdBERoDRnOIqZJVC&o0uBsRf*`}SW~AjVA*r~y94LMaLysXbXTb=g zlU-c4;V7w~_^3i7QEZ`90fp*Q3U@6cZ!vf*x^7Cg{Ot87x^57BqU-4SU+7v$7c4$* zfO(TV{8u5dLSf8tlQJFgiLT-k<{CGt%SyYnn#mK^ZZ~OLXN8n~;-BbxlYS&s#IZCo z=~OzJh!Q}$ws$<~CP1EeKVHOB6#6kGZDpT@e_B-jJ|f`;cAE_;P1X%rIvwQpNhClr zmKeO5Fpb+>^oe4TDxzti+ie~m9Jw&w31v{&ZT=tzsf6mNLRCtA0UfYJ%0yx=b@jH8 zZK9-+Lqj_ABtC=otwb*P6J2Sd@@&qLvwV zxq&;u@&Lzu&7}pEA$6=;ftXWmo;Qz<8+EQ-zH@dP=mcl9M z>PoJyeyrX%PNq=*jjmzkQ+oxfl^^>)}} z|FdvSSlaA1igQ9gAA{}Z{eoSOk>vrl$(qPdbmeY9CuX4e6%{PCM?hOXILH54NQ@g+ zZZwaWztG3~J{h)>wJ@uCsU}G0fs{bDG--N8#}`Q*Fr+<=3r{knE{z|sq)B{CSV#Va zt|plaPm?Z_Hy)j^zq=yXS@johShuN;1hAf`LuBf6gEg~xX`g4JBkScL|3TN}$=lec z@?#nIRLgiT$v|G|lf+-CKTV(zfdkz7BwAXTOTI6 zD;&PxoB2gsJGQ-ST%sZ^>_`jtM5b;&PCld=u~~b*tPMQ8H+8oxT=-(WZt-$4_o8J^ z`!T+5BhZHT5z1VJ{f(}lg+yk#m;GPp`jm#OLlztUx(E3o%`&RG*&pgYw7+=$*d>Ll zky6K{c+=T3={%{EripgIrHV8WS8|>G1MW!V6J3*V+4C7YBze4B=Zhj^eH6Ld1iRwq z{PP3K{zBKO*~JQn)AZoCGt)n-%X5?WjYXuV*55~02~qB}dbuxL4#)mNSBHg;KX@WigEu~7p-&FC;M&?Uio^! z`C+D=*?yKK`*wom`h4BcdEYekb`d2E*52DG_3#(ErhU8~{e`Zy1-o^hg+x?Wvrg3E zY8Cr)eooh`Zo$V&n{LgUGtN$vH@KS5Hy0nsWFP2e8PH_f+$J9#dLM*lw#Oxn{{$?M z&!-wZ<6mwNdD;5!1Qpt$s5(c$9iEWFP)sg&ARL|1e0{hkZzu}W#ugc>HeWoTQAR_G zJUV~$f4IRp{hmxd|3pJ_CH$GRN_Yh-j%pOCBB?wuX^MtY|(q1nV^(^lb$5U*6dv%KawovRRF zfh?1WXMj>jAVt&!sl^aK#i;EEd&+Z@F3GQm=?xR7&e**VD6NzYC6;f&Ozf|8@pyyQ zY`*ncG!HsT)UeSjKl@Bjoj|eCKNohB*a%i=P)_^6GDv0XA^P1`bR#>jR`H?z?w8Sf z@?u(4_|rRYYeeX5SZ>EeZ82R1!O27~4XsMWXy&>JlQOCbbY}oEo+?QWvVy*yj&Y*_ z6~{qI1DL9}2>Oq-C4U+&Ca{>O;Mb!z!2WO(f>O@WLU}+= zDLZGKT0`N%{to$;rIWWeVupk=@z%I3z~0Ks_#+h~U&;8C=6dZ~BbX`5x1B#!_43KL zAWq#78gx?q^^6!@0 zKk?mYocIh@4E#v8vqe6Xiu)qgt3$r!bsk&I39l9s2g$2YKu zBoayKu89sI(&tw~!6fh`rE?tlNuXFifNo?QPTvoS>Ce>g&8pv+#$&7-nvX65IbRxn zov7Uf6=`*to{kB7=?8x>-waegN*!zx5lpq{IEYyiX^ajHDHIYv;v7jI7s)pCrNp6; zVK~;l;LT)TLO5a z@9b?sZRYSw1g7Cxj}kl3PSE}NKcq_}63oUE?1u8-%nn3vU1LQ^rh#zkqlNduf(E(J z1Txz(BJ)q_#Z(7b2+YVCG$#n(fdibh43OBqOsR?2@)WqM({N^C1S!ujg$?}Vatgf* zK|T$nMtAZe+NDa#=?N9l_~sADE@NP14usmA@VxuaLR!!P=@i?PqXb`+n@9iPsl0t> zpf{D6I5%XnyQOfq_LUu}9RBoSlp^phNp7_ebwO|y;+xQ7r#?=kMdv%Z!(q`{=J&)_ zd01QlM#l-j=xthympAnla>e)}Rzu%MCgp+W!BdsAWS$&||Up-W182Z<=|&J_^5THODEt~r8rYxUhqG$9k&;5?J_xuEk9i{2 zVqm6zKTC+Vhvi5PEY8vP#i14ISl%N-8E5w>+*1rp9&3}?Yxm8d0${OYu9BA`x~|F_ zKE^EvY$!L8KGj%zUVQJ9 z`DHtCs`K(pR5f^B6)b&bfc3IGEaNobXNAZ}{<0z$P+yp|t^*MK1gu8pC}+lOD&r692A?GZ#!zv8X)y?|jX{0EVyPMg?2o_`Eocki9sQ)X=v zkY5=N2U$%Jtz-Pre758Ko4d>WPQK)*6W?yaBGSRfM*QgC#<+5kVd1eAch}nc@&W29 zBp&DPi3zX!5#jDV$MNeu)XdXqn@rqBo|kT3 zw;1G*rOV{$-YtN3E^g??)}eH|HFl<S2>zjpdAe=od;myW3IdDqVb^y|H|4J_LQPFZsv$DtcN6f6|!%@k4ZAqu)D`YpLrAtWgD#+47hheLO-?x zc@n}TCnJQCLBNPri1Gdw1NA0~WYQey_6j;vY#AzFA@*y7!jUS~vW8;_{%%zTm zw1Q!UraK%Q12Jno-fS)y8q1jzce4;L92czMssPnvMK=>HGlHg^q5z)~x}OXXBiH%4 zLT)6kMe{XbI4I80Hrf&+lJ6=}lbkNEE}o(%wh+PLu?usxi?!Rb;kwMP5_tBho$e#(o&v0o*>LoWzIi?-K z0L0?C4u@n4^JlPLC9MK7SopKD9-`_VLRr{JD2@pa#7SSxybjf|UR|9aMv;RmaDCtg!Y9@$()Io+qF~Bj1LdX!{Ffm@uvPQo~(79!_ zCS;Ju{;~-TgOJar>do=l4oR;GqkcxLNDf1ULKc4J!YtLqhejqXMF`bHxMoLCq$sdw z%SU6#TlXy>xr$|SL*k-9BH8DlKq=(cFH9ZDjVQq}g)Ri!&TGUVVSGq@JpDbn*#V3#kz;V(wdEePo^=nE>={W!4@geq=!1@N!f%t4gk&J^Y{#Mg$F z1d$=txTHb$6bJ36Ibudx8Wn$`&xP_W<-;#^T?vT|@&B!!@uek80Y4G~F;uIx*mkve zxu?ia!ke+LY=yr(dL}o$)p#Qr$teuMEmh&`L!^m*iexFmR4O3-7plAl2(cUgpaxPU z1>Q%cvGhZ()QE}e{82cmiqkAkD@O_z@|iag+?B6&6USkN3;zs}>rf+zhvtG|Br9dyucm}|` zN21m?YL+3wpEk7q@Gt0RORO^xjf9(AE_ErVf$T4E!3W7kQsFoR3f(ixBr% z=qi#IM^8+OGD=FlwnAmwwxEF~{V$~^FQw~Hp6U9n0{ZRd6bOFFty2)Lcnbs>YkA-M z+v3ql5QnPAC1@jI5T{P;TiO6CA4LIP6mDOA;$2MY>|$-!UNAb#5Y8=75MDfBgA0qt z+V}43?*ux$+8jSp8@CI)kV_D6HCnDP(Fw=UXwltHu>dgR?s_e8=ri5<+wII(oe(u4 zaN8bt7Cv~kXPA@&!cjR$X&oIPo%X7O8cbGt9q1n2Ws|a;Q*$WX=>xAi_?MipoVQdvu`9 zvZOCm%hDwrAiIu)K8~Sj$t4=x8fl4x$Y~D(QZkzgED!HS_Z?xg4ZbNG#CiU;M~UDz zIu_-M(C*$vOz!neV87;} z#zwz*7(jODym2AeV|zC|c&AFVI|@YHYNXvCyQ7Eo#h3%&w5I^{v%*(B)oNvUT+_Ls zp=;PAMN}vt=Om6FZ5WoviLYY4@SyFa9(dn3Cd`*2b75p4)&b(n>EF0X`7n{%)8-lZ zOO4u{!1QMoG%Y(6mpYIqV%G}1QTtU{+p`n>*IOrYr+)Ab2Sy@~0g4%VpwB)c( z?2<%%!C82Fwt%zP`2*Y)vETgyZ~@?AL}Tu2MFf018-Ujz0p;6gs@X=Q*{1{TtFuA~ zZp$;!+TX&W@R4x1o88_VUCgJCWhF~u)ERi?Jp8@E$nebP=v6EPzeVI=tFrAOn+Oh# zYp3?XL!zV8{e8^%kTsrPXQJo`!*lbO7SJ-2%{zh{$$ArEw4$HAL~x9%T4`)Yd~H{y z0+2w{z5{U>NUiI$z9giv2vW8a-1k-L>X=pvR}Tv$Z)l&gVP1E~-x9a>fF!;Z3n>{E zWKGqf)4H!dQwPoq=}{X5s~d|Hz{n0wrRzHKIIYweJ~ zop78hyhH}wRuVW{9iUNm0IIG|na?#hkfvykqsBN)~UC4{jjpQ-J2K?-Z<{kH)u1RQdt1M3&7Fi1;x${ zZB~19Oux!him3-id;1+2Y#W4c=cc4PpY1Qm?l@KMBG1Hefva1-?`7-}Gj8lx1mCx? zGH+RO9>_CK?zs^3IAaaIU&g^DdFUrEo-LYn?({Hx1p|FZ^0ia)K9H*qpB)b6L)(4` zS~`Hb$BYTcq;1!;$P~>Yz{|o&$9zWJevF}?|4JA1;nD%tmt8q|QdF6-m3qh}|J>8- zN0@P;vFgbR9R5-8EX5)&Y_&Z4`{7lZ>kmhA0cdR-*092l<~{ja%Y^wQTy&X_${`i~ zS4hxzcU_R3-G_flxR+0q8X#AfYJKJg{`pJHr1;Q1`@QiKR1zQWW+j5~;PJ*B@u~#}oK) zXX8H?TJonM+FpQT-WrJb3k4Fy*V;i35mBcd2wl>j$d?j&s|M<-r`h88og%c@P(T3c2NH${CjDr4w-ekAlN8$iY9ElB!5HIS zU$)E^AFJ?;{-ztx4CQ;^|q~0-M;B zg(2hb@ili~N19m;Hl07cvj6Zti-z#V?WBo!#WnVs(?uaORr^$cv{&&1iMYae-XOuD zIicnIrkR>3X6YI$sRBa!p$7zP1^uOzX39I*R{aRSY39q5f?D(g3J^$3A$#Az4FGwO z9OV)DlRjxyL)Z!9HR918mU5t^MX$w__t^pDM4KUoR+KO)@nm8v8enk}j99y|L{w#M z#Zqxn$c$xdQy$Wz^_^w0GTe?5j5QyAX-M@yRC`Ngd4F)!e(?FN$6pR|&)G2zi4jvU z<}m|W>+!%LQm=9@N>7-ER=_-ON8~2D5zX_|qgEHx{6aJ+HLeiJqR2qXr6GNO9=|rK*-G!+6Bz(j zk&C-0mC0K)bzcf7j2K@Lau|L)R_EKbtRAZ$m|`UfEZw6F>sC?t!7HQufDPO7DbXk; zaN_TsoFVI3l5i;mO@ey5}Tok1MLV2{1)9bByYRcM@E>qaH>n$7&nMcgJp> z$Yjkytsj~HPT^H{qifRjh8b9u+BUIEs*G5A9I`tp9tXk)IPFL$JKAf2!fD1W7*tA@ni2 zN*&xAtVB(*c!|pfXz2U(aYw9vC>2{J0NErI$CU?iUaV2W=YSc`3h?j zSu7M6P(y6YIg0iZJO*nrMj^;y+^q1iTA0Qvs?=8(a84F09uzDfHth!;d@EwgkN7LZ z72SN;MEv)GczRGDCq` zvl0ExNMZoqf^vwuboLPg@!3jj^DlNG{3}2T4y-imG5a*GYh<>a`k@0n=6IZ%Sq`s9 zF(;u0S|0k>G^CAvCTas}lLRpW#Aza}O*{FB)xdniX5;25Ou!3rasqgWUSrI|($1zWmZzmPPyn1c*d>lu-WD1FMouY2-X zJ7~i~cySYfj#4gP@CH0osgpsDrUl-DgmO503$3zH$r?t% zeT`^ED5q*Mpq%J4M~YFSP@GtD^2Y@9HC5xiJ+U+Q*=S{Lm3*QyO^a*P^mJWJl^g{3 zlBA;X!H9HoBWayE+=!|;!$@l+5s)3q1X*#1BHX-=3`+gPM5bZ+R4BieV1tDB{7xg* zC2AjX?Q<9}L3$A!3W>F7#1=lkDEKfLwD^ z6KzLkzJ0|I+ifk4);Ol1^F{eAMTt{ojKJPfC6A@r@e zDYLfR0y>484no-<(4?)Op|VnhH%g`?-R-8g?OaN`LP|UkcBzLv3b8BPQ zkX0EEww$@@6f}*_jvn0JXAy1QYcyx%97eA&-74Q71PP#AIbe}&E(;q-r7By2U-2nT zuo^3yP9c16fpv`F(Ei8~a+8%21oi}qqIw^m5YI{%mcS#CB8KeEA^NsBZq5sak8wc;oFiiD+Yw1S^RIEE}_(4f_%?Rj7{S=bm` ztsn5etOuo-sP4I*CmuGB4WNYf%*dDpn`kQ&zg-l7n8k#?rOL3{94*h}X0}jz?MDW` z_N`pRDyQuqu>xO@S~C~pYFWDd?%iWldZk)9?*ttbS2qLmp2i7bCACqY=9n8uQ@Q95 z1;}59WK%$#-9NZVFM4Y19bnvIb0Vl(bjhyQ*6YN&$UvN0f!oYl`W7(z*OYBuTeaSf zr@P!$xCYjJDMZSoP;b8}c9{5CBL!A=mDgAJ+g)~OJ=7a@`Ug2%-fXKrsBgH*m_&KE zY+X|k?zKYkFF(`Ql@`n=aUs6*3_>HAcGUc zr`{ms8FxYCa&MK*Mc9v{)EHxfwftd_S8Whm22svq-rG~BR(il!R)552ZU?Eq)`NJ% z@GQ`6?jH-84=BSTJ+8wnjm}#8$^7omODR-yQX2x@+e=fA9`cKy_O(WTjEf?lSCq30 zXe=EDK97Va0?+`{E~indZGs<_UzlsR5W_CNiv{G3`~(uD3pUx|p660z zoObas*56+8QN!{bv@*Lv3-I_wV+jh6JXI@kA*G7>fDlONl_8SLotF6e%0c)4hVmF=1>(xrOt;o7!uhlOMF5ZYf5;Z;)CnWA(#^+pT_L2_TjJSD)gWoVDkXq6!o>{{m6x}HGI!AG#sy!e5S z9t9$XI#_dXjxahY6M;~?ak@#RnotkP1u>af!!djh7UBHKv-wHg@-Zck+#xA?#_h3c zQ?57D;TM>xwtktAt?XJQn*LD{?$Ga%9D+$?z^3Sl^LUZ?%kkP#+2i^?=d{WFmx<1R z@Q(;eHhdAV7f6iqkaF;5gnAlDe3?4*X`cD1fVgQk2hQ(5p^hvY`uF50+vHAmv9V*u zNUnxi-N_iKW)xa@4#%el#bz)X(FU2B2}J$2c5>g#5BcnW8XJ&>*)#q|RXG z$Lir4N@6j9QS=JfEiL2~0Pu?52c++m+%vyCic8hyP*#A~`lA?HeQ&EVWwqlUy|7`G z$po65bGt6Jw@REahKl!=P%4J>?AP+;AgE_s3S(_E>~8X5*z)yF$`kF;;;?u_Agapv*oBMD5wKU<#_CELi3T^!dWTg;uSIovlEJ*p{Fxs ztFYKA17o;gvk0Ebi(H{9(2}U-HYwvA$C%R1qPo;Urb`&Qjeem=vgt zVP&JWP;=5FgAhS#0EamS2G`2je`81SP0T;cDBDf2EcoCT2*6`IN~zus`lN7FL(MkV zPiie7*;~=#{YsefkwFbq1>=@BHY#0~7=`MSMn1!^1}s}sL3sdzw)~6sK#n9dB#B!7_KB&u#S1;@3^3b8YML5DN%ch z3vpDkFDzIH!C7N0h;Y%zhcx_FSJI@=_$JjKL#J+7Al*5m{_R{Y<*j>srXW*I-9&Lp zpq*`Pv9xyYMTlckCy3O5ha%uoShE+km8W9%ewZs-m6qZWtB6As>{A*C;8 zY}QeAGeT)tGw$Ayb5mHccOGE`4*rO`Icb*JIuPcxVWXgCp|zpl&$*8L%=aar$Ue?+ zG(cy?N}hEc`)XnIxJ_eOm|z~I*!GTxv{bf_Z6kzj6T$cQRRXf?{91f8BkU8@1rTyY zNe`5SENXsJd$!739*N<6S4;x)=tPgdSROwG zNZgw|M35wb_|`H|#w%`H@LbmxIDQr_DFwIaXI1YVAq%L~Q~4PIS+P;Qp`T!?ry~uu zNDDye_6Yn*+Ya0Nxp`G>m+H!3D|=IOV^@%-#93aS^BxlI+a6fQ_$%R0uuK(^ z!JoM41q*UJRvcq>hLy3 zMr4}>{4!<2o;!1{Ms391_Bhf^iG=7PA#ilMspSO%Jn9;eT7El5rnqEZL-eMxAt8hj zEEfy~Sd?LSB6TnHh9D6ef!jw$>y$)0;Z`vun_EW2%dgr{hB{mTtM%4j#)&u*N*jDa zZyVv@8(OQ`4?GMCJ!aHZ=OL zN2UXF1%B2eL;CT`mSgOKTJK1QTu(dVEUO96l!Kr_!6`Ki@Gc*o| zQQhjZ85`{lW|bG{gUO}}4byN&r%L^CY{#Mj%P{1wo&L=SqPP|{F@{5gs~!8*EizRO zpTnf)ISS#uTiGV`JW)GJDvwM(cM2yQ@9FM^v8kPw!~0VO2MH-${bw%b*34xMES3SC ztnB^mX~wD<#-}qIT2DS!bIhz~(dIQEGfgt*ADai~n}dK@5#Xr3h0aq3dFk=@O@%EG zgSTny=!)~{KIq^RfeCh5jQ~M@X%&mP=-mwSg@Ch|6@hsk@she;DS)o-#P%P{4glf= zyn%8~!s!}Qn25k1EUv=^9f{J5<4bTg*8@bUz|!4sa1q#+#*!Cb{-F6kHa_UoqIhj@ z^{Z|bUP1>SL?d2&h0w1SS-ET9wrjW~Kd#1hpC?S9-CF+@bu{7#pH74W`R8I~tgPTS zysd+D3Z}_mR^g0uWH>A@>wU4D>tUqm2+xc?5v8q((auF%4)W4UnlqXo$!rgX;Yx|yA<$9<7m2Wu zn+o>Elos)F4v}>BXSn+Ctj2Vrj!#mK6x+jmqA&&Yw{OtH@r!?sBz`}AJ)9P{hdNeU zpv#c;#<5^Wp(ZtNl53ICy~`!BJW*J;5pqhO=LIF_ymz|Qc2;JXfjWAZlLm%v```tq zY<+Bas4mXP#vI3#UzmLW9gt zfz3p4LfC=_s5%zlsCCS0EUS(ZRs5lT6+^ii>F?C-?tDTJ%XmE8aTT^`@*ohc>tNxm zB$vPYeUPfy!EvAG_Y&CZMR_Hd!%<&^VIaH>d+bwxp304e>p8M(6ufHI;A74QS+jrsli!C1_2eCnq{|IoEz-~*R@u_5AA&ZSPuWSR&?#ay zQOBj<&K=5E&1dt~OyEd*ik9G+S`oV5tj_PnFJ-)>T0~6-$_+ywQR(T`?+M+mh>Uei zEXzK4p6)OElRVtUel}a5RmdDZR+RXEal3bHb;TTG);)VvaKD@|^t<5+7z0H3+M+&a zdGR=)V#iigK(C^`jSP84{j&WyJAy=k5tD^Nb$5; z)T~#ea|Sk6tj)6a8hb;1;4Q8{y!%bt=~B77<~-f(8YqgM*;=}cFS=L1y${`S4NEed z{ZZxIi?Ygje!X{2kn8jW4FUQ3?K6D1#On=!Mq{u%y2S4fK_pcuHNH0KI>t@P<;@dj1!p%?RIiJ z?Y_oh$@#2r9$4jFi;D4Lpi-ClbMsr-v-1EEv>+I*^(&jy&M?${W~mm__5pa-L;8dV zyHm$(U0OlqFU|-524d)@X7{{+OTwNqn;)wj@&T7ix`*sKdv8Du@1e{;bY1)}P%N14 zuqbS?-WTM}cs>z54GMlR5^VT^C>#!%ff(k^If9$EkN8@+xy)!vaH)m_x)2xn1fKzh z%Zh&Gn-Ef1N&?Du5c5tTp$cTjFj^4y*Or(_Y}Dgjv16dpk}k*FGC{n2Z~v~oY^w0S z2^6*ROny(*;2DR`MbMH-=eJP8bJ82^NjhboAE> zb#o)78t8FNOtcZ5`uiqvW3FGdnE z$lW~k z1!)LX_o#GOo!_9am9t`eCFOhC@4|`}!HQOytpqg1u;^D^ zKeU!T6H&BOtQw%W^b=n;Qoo(Bz>*eUep=l-=Lnc~Wz3(1wD833Rh<8i ztb6{hgA3b59XsiYtrgowW81cEHfe0Lv2EKn8l$moHtX~~`or1Jg0_;-_&==i~uvp8nG&EZpA>ByWwCvau>F3a=&TtG`;ih{s=s+vwl= z#C5B+TO>g3njaX#p-pv+hx9=u5EM6hXbmwjSYmwxYtodWiL=o}a3$uL^RkGav7ZE? zS%_bC!9>IO(t^~3s4__I{ys7CK~HTsxJs%7TU&L{!(>Ah;~|ajC_{GS{n<_uWSC~Z zzcFCv0=-AWEUcqZ$wccCnL~x*vryrS+AENroq$~L@NwMK;yp@f>zHXk;AS_Mav z)F`-Xg~l|0!a3(3kxIC20{wC-NI&LC%LS8esZc2% z*2Y9{_(C!=8kP+Xv&e-Z6mkl00`UoH)i6D?T&yH%|}J=2%<#COQ%>}_}UkN{L# zF?#K#64qsP2QdmYm(rn9l~g9Ol5rX1K|Bgf3?9)p9gkg2=9UR^DYK{3S+u4Ovk}l) zm=7)q#=>MDWG1wQx*dT5SJLt~XADyEC_GUkZB5LMAiuw#c4x$O~kIm~N8ytC`N}C$M z+T&C+ZTyK#h4XOLvo}WUg4oP3r*63h)dU<#7^?S58@WO&mXt!X%;KX!x= z3kLg2$=ITLI|_um5v|1c*tEzbbZ(Oik% zsoLby@ZNhPC!*NlQ`yi>Z7V#jIv{4Ff$IHKn7;x&*BgCR5OsE&i>LcUn@E!BPcBn3 z#`sg$vmfYH!lBlgzud3<#LbT!Rp9tpmd+lsJJ*w;*qMlzo6_GYDFO$y1f(MR8P%&* z+eA8lZ|JaaS|<~tbHL^Vd(2h*E}T+htErQ*mkD!RF(_Z$n6baVlb7hCJMUeac6!#T zCx^WlxlXU;nyGV(lS4JXagxlfElCZxw3I*b8lUTJ9k+S31f*)X#h8NF^{PMB4Ygla zsb;SW=dLcx85IUDbLmWgHV*Q_tW#^(yArXRz3nosO*^snVcAet<7u-i9iNds>Ax+} zeR3J+-cUO_$v4+A>r4qG|kIqzz7$s;nhbwobJ*9RF|C~0%u#|@PLa{KGmKzKj`M3ckXc=3eq`KeD zKF498p0ijRg+Y8nZNOc;`8=B!WyJ{@BHy~px%aimqA$jXRy+xv*tKpY)8npT^s`be zO#wD5XzV1(5A<=jKg_Zti7x&O^tWXwnOKt*$yh`g_f`a}rD2clF!wG~QC@ zPM}$)!aL$?_~Fl8$f}xuwyrOhp~3sr>Yu%>UpCWu{M&hFgs`&$d1K`UkEnz$!#KDc z=&KcZ+nAFLMk>bKBdY^jPe&t{48yR`!~iIXz?9*yBZ9_k^nT^tA𖎄(V9*8A3 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±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

r#W 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

ysp_uXl4gVUE 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

  • ZY#&%9@+qR9yW@9vJ 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%0A`r8b<+s%CQY6$v|8iPL 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�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 cbHb2aBe>YN_}o;( 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%0A;gF$){(5w_xpv# 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 z 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

    ylz31|P(8(7`5=>2Na1Uk6m1VAvozxfNkblS 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�EV`$O-+*uReN71WEQL+ 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 FMdWSMMb&%zS$r&Q>qNHo!3 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�=3Ce%U`;r##?Bi(lnwUY7 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⪚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

    )VJD=G}YR>>3_I+KzC7+DiD-_i=0 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�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�e+83{#F&&R*ZqB7oDx-GE_5QnbuX~ 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

    3QZZxKC0TmwIMPr}~ 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

    6Skn-l`$^If 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%0DqGvqtInPzDwtO8kCCQ`@Q-9H&+<>}@6QxY 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%0DtBr4g5V+e*-c3#BaLl znxR7Ka6Jd5KQaJ>t+C7SP@>>Kg0NQ^AP%9{JJ>Bf+P`BJDu6l%bPMmy_vy6N(~=sX;`845^0TEESZWC<=5^+7gX<#EYHRV>8xekJiX{beGn66u3 ze&n_l_L%BESKuR_%7yI!(GttI{q#e$P=Q7ueCBjl0(Bbvr^1E_kP%)~NHomL)2D%N zCl*T^UgGjYD-?U_N4?ga!rIN zha~t=)g%nZjScBnuduRZ8BSM?_yeyf{bX;U03zVFvw?~|kDacqd;_^5U!b5XLU-v- zUv*yaq1Ee@g6hTdr95e7ns_%Qc?{05tSyN5RsWihJ6Zg4rG|4)#`{z{Ijd_d$R$Ak zg*LeSLk_DAzv1$TVL(iLWUqqYb44;*B2=IVQCK~i;JOSUkr2~i&&*79wHwn(!8#z3 zj1X!YO?hqv0qSf4WKPY=qpLa2k&_*I=s@gg#Ql`L$C^VS`hZHSTAcJsk%MOHrzm%| z9&IL2jL&Jf6bewzxTjw-oLLmBQ-gF z+RHwI#IM?{aDvBB$y}<^!wy;@c+>MZ z#9%RIj!97A?�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
    L}OU;;_0+39Y3`L#0e@WIkwSbbyEd{oo8WE*J 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 y@$?fnbrVE&lZHt`OE^Uo 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 z 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 }QSa%gE`NWnl{U@=_9MIDOdf`l|YCQ*Zh1AaJz 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

    hGXdI4H zz|{eM(*iag#i&F?j8Fajl}h*uSd^6i-C#vTM&89CCfc266hzVFAaR^VOe|q?2n@cM zpwZBWO^~ErT^{2pM31x#N=%ndzTk=kn-Ct{PCm$>kyN$8-ig#tMYY_hkp_$q+En2P$6Tw4)VEMGGeAWrbLZgk)KI{Lf{cyfzE<> zi2tVm(dQA+Wh`W4L0DZiB&_@if?bM+KwlQ+M0p*A7UG{JGL}7hp=65TFf}5NAXyZ8 zp-qyXGrA9jvC1fB7;y*$J<5xB;f;KNq}y2`9{I_$$RndIk^|Xdj?mm;f}6GA3Vg81 z{hdVeoelTxSPI_XX_W@66j)=rM;x|?GF+ZiU?KMj4;KcRY$4r09!mNIWFN&!910Iv zsMTk(Xp1^z>zEmlh{Qs$&&;G1=v-K52+dIN$5to>L1m5%22GGE6+#jMBx1ahAP_k>;$>N7$I>Sc{x2*H)=7&NUOo+^)PW({{-p!53<5@UhlkP@OBpa{o7;R2oe&+Q z@X@@qNJ5-xd@+?>E#{lfi0`NfQFPkDY}(aior@x?AZ}wpJ|uoIO$7}XAoWO>)CcH^ zMNX`pW?jV#u?69&6{5h?V&K?r<&TBv*X(`DCG|;fY9krxh#s*@ggFR&>dPAG6r!jn zk6nrs)W-Tm8uML*TpCA;^r5@{6N$JfzUEhSjtGuCM6(c;6eZoCTuQt~=l|Y0gksU0 z4~>n!2A7N|L5c9)`qTzl4%ZWzg-Hd(Es2Nsqr6IB@E`431GSmG7L(dvj;gsi2ti7gSRsw{@cO$8Uq7p=LSpJeHUBHjZ@ zm>oIDZh2Q6aiIfU>#iunBtV?xblgz{+L#^H5*@{9VOR`J0u7Pq0wIlLysh2s#b@M) zh?#4$8tx%3>$Ws!#`(rMT1^A;XzJXGjFyJ7p~a@yq|{v7&=>~gz)UikNY~7!PAHm3 zY@0cu1iKAx$7n@x9$J0m(}tkLH|~Ybh$W|4#!*fV04$}z($y@T;QxulU!#(4UV_%w zENMBJIUs4dLM^Z{rs4R20?BFa?_; z6qXuh8A+3D9L)!k?nDrc>-~moD8s641z@hK@t%^Lh?Ii_X-zzCM}+L^*~QJo)vFec zW@K4P?5gMrW#@KAHjxjaCMQb;6=8*WSYog=imf8K8*@#Z4fl<{%V94Ey zgbY<|6%P%`yzdf<%E7 zu3|76bAb+z(M)tkC+HZ&A5#RVnTDvW=acX;(*V*9(Hh;&M_xD<^I;0Ltc81M2zs>z zr1Z}KwP&wjieC6;Xk4a$0#M0P*kiEqdb-bmc32o+%tuVpH&TkOXi0(Q%TCY~adEf9=I5r63@e@RR6A!be_ zs0@4aVd38KAVK0nhc*PFgFxCutPW4@?g)`^riw2$X$I#CjuHorYsA@9nNzGa@WJVC zt~KeVVuhq^n_5~%A_WJ2loDJ8BWl=${6%gy&8U$OrT>2bk7PQHf?Q zZba_y1nFcVh*_!z!u(|tkB&IEJj8F9kRcsXp4sJ;HiQB|qnz{zojA=7Tpf0D>uM&p|k#ky**!%StJ%2-Njh# zl%$*q0rBi5!nJ-YCe_`dg>8B$T9YY&ne3fTuxl6}ZQ=;ZA&uA4x&%KqjSuD#iL7Ks zd`bvCi;O@>iBk65eX?w^#Er2D4Sh0_#OB4^Hvgu;>ue9G9dQmvFrBfO5{7{rG>0OI z6iZ)u1P<}2Ww?jW$_Pbh5||_q>HT)B<;+oBaub2ufig1AVi+=l6p>k7cP@8|oNE(v zP&RYmQQ(afix9TN)n))4DCZ19VTtnPMS*!&7WA_&Ovx>&3C!&R_g#oxvzpxlHyt4CvAY{I1?o zM(^hq#Z|nne%QDPQ}4aOMycq`vmDN$VHKyHl4tl+o7PkU(BwnY)2~T_L87wW>u- zNGyb8%nE7As7+ip@J_7Js*%+YS+&a8MhOSb(Dcay zuLl-a1Zq|W%P!wLP7AVh0bIKkw)qW*#T$r3zS{pOhe2rp$7;? zT)xieghq{<6X_+WZe%eF&n4ekoqI_F>vTMs#;xoxS*#_8y>OGfOStLZ=RXWg)$`i0 zn^-NzoZ_ifeuO~)gdzY12o?Yk00@AA1QjYwq@>_NKnf!UNRkAIL4rXP6-bmIW5I|T z6#_{TXraN3NhBFeDH3K(nKNnDw0RR}PMte>_VoD^Xi%X;i54|_6lqeWOPLyNNYN%# zoCBY}@LRND37Xs*B#2DP1V@VmEfRfW*`+Gx~aYa@gnHF zmjI+`A-fvlNihTII*-A*-m9>^2xp3K!K3P<>B9{Vyb!1kNrWlH6IEQ1#TJ8_z{MD4 zoRP*Fmj9N&BHCkbu*ak3gq({V*2i}EivAeCH_Nfu3P63Qs0oRZ2at-KP;EVbN{ z%Pwt1LPZ6b693c7GG{W<%rwXl14X2Nt6J@ zLb{?AuPU8>ZC23@eO&5QR?F>i+?%Ruw!dzDk`}LL-Ced_cp3EZ*{IH?S3i3Zt9M_u z@{K56f&HCU-+_BwSiC_Qez?qep^f%iVX0d8snjGCZdrxyYDljL1IUXZkUZ}A&d5qq zEx(fu(*Nsa#L~Le+mTa-Rz3Xh@0{40*qNtDcQusnvA}>h5Fu>D0`BnoX3D=&wQg86ZA6%DDegJZHBK@RN& zaBYfjNfKB9SC05=_}3r1&eZKqSd32(Se19skw-7aHJPd9VQ|$BMSuoMR&%`rsNh^u4~SYjOmQi6soiex{(I}Tj|XA0Mn6{WCQ@+$p{dn5QvcYlVq=X z*%=d}H%Z`=mQ(@6LB+yPe-h+41%RJ##0LcAKv5*vONdyig-`5(hl2ocXhJ9yKZfj& zB2rk5Lwy6tSyhf?E<4Q6IG8dQZjd)p`I&&=LNX&(%xFBE*quHY!3Mp=W+c^@y?CB7Fx4;v~p5OOr$E2ln>%Ka!8JNR(^r-h-wtV5y)VZAcjLN zL9n-4ASeP`_X2<-Iw?K-$*-W%J4k30!4{4ngtxC5)HK^FFS-8bhNpuiH+`whTz+$x z`T-bh!zMc<{z|UYRAw@>rMIaOPA#KbW;n|xAX?JrWzi~7E&midW2#Px?cE(Zacit* z_RemwoJ;Vg#;yY2%XjIKEn+Er6vZwj69vIWQi3{@3|II+iI7Av(D+c1zES^sky4*Y zFj4?1h(w?-i)i8w3b>S16rcS3N@R$en&YI@qPRssYU~Gomg<&vZO9hi+c6@s?nrEzB8WNN ztKoHeJpkx!%T{z5?Kp)|d@%D&yQ+OGdhSa|!TZFf<3 ziSnXXgQ>Qm`!+72ck7xt6>Jjnw#KxRU;%4{JR zC97L3h%-^$u*>gK^tUS#wIRAh(_}@n+P|uxpvtg{bRppgfr!+xzCEm8t*PxkhV!-w z+^7bBX}qor9bsW`UoM>M6aC7N>k{c=&w-uADW9cLjA!DNCzt<76cL&{65Hjn9d3N3 zhb&~ZIFACQ?NbD*W%-%% z#z<~G-#~YFTZ@KKZ5_H!_Mlu24nDC=AzbaZLc!puPGNOBa5!6acJ=n{8eB<_}&s?~VD0B@iKufYJqnZvdQ3&u5&*@FdiD%|- z-%14ju=hhi<_3m5au?dDJ#p@V>YF5!+4C`QU#4rEdW?*O-PC;z1&({e@F z64Is;E@$Mzn&QLa@)Tb}5}J+N;v-osaN{fjB)~$o%Eltj2-y5aE0pgw4CghJ0oV#N z+APCxIzsdah_{fd(cH&l-smGj0wNlsD7pVf8A3Ak5>pXCi+~a-BxNKZIfW;l5=sWe zEf3Kef6y*(6E_8tJ3JyU+s7alDtp3>4-KNC@`<)wtd0QTj0!@;0HKhYE;6>_HPFX0 zP$_@bN;$ofGM}>`#>Y1T@o9`Mg3btAyyGB54Q~w?WJm~@=hz*fYkCMCxwK$@CPY-E?n*0aOA!zP+Tg-)3If5jFu*KzFnx zN#!TB0Umv6Z%mFWxJl%Q3q(bt#^(R2$c(cqJ5Z%as-n&;^)^mwd<;2EZsS~TH5T+; z6hZ;A;*3h-#VqQ@^o@AVbuqGv+w1LiG|uJM>wK(tb9z z)?gw||HI{y!57WbLsbKNsKS!!Cht?DQ$TBNGnLr=?QNqAKy)eu>~=vZfjQ2UE1>QWTe zK_)V<(|l<#XKni=#PuR6G(Z&EyrVEx%{Zv1BLL@(5aO9Q0wv02Lvw5OZq0p^?=@d7 z5Cmg6+p}6%@TEaKH z2auX$J47swj8R6^Y%J;IXNA^E%n@)I1x!-JXa$!=09HCWLWT+X$6j8Az`3JH6R1_OqWo$r$qeKh#v@x3ZsRxah{I18PV92nH8dz)iyx+qOv8*RuyeU zs`#L8CT#yM&rB{aLCQElN1~MBp2vBfn1gt+u$-B4cn=CW6abL6f}l~O$yDNlE2*FA zh@tq2#LVJ5Pqi^bj5!F3IHHU?&{igFu^>9?FQgzCd{GjPH=(^_L9x^`(1@PB2cRdR ze5e&Xf}^1oV4#_8e9&me>Y_W$f-Bm&S|MtDx&u0S)91kQB_rx?Jx?aM&Z&hu7^FdS zBRUYIp{5^03S3G?qWPJ_x;;o!BLJhOm2x#z6gDggd=c-clrnT?Xm_k)pLX}SL~t^I zK!St^t~a;e$Yy$Gjep((JR*~luH#TUuRgd32;9Q>><2YF`mr}+kb8NGkvSMf_l>pU zG1&j&jRHZC7MnUojetnmK}U^x5&DQzyNjG$XU^_5EL)V}Uq9q$F}1%yAv=RyaPQu!e2u#Zcmv#uWD@Q`AnEhrPDYVipTO& zMAz0MiWGh%$*-zTK)Sjk1Og^((73dGh>nR7Ri%tE;1Fhzo&#Th1M%zNGxGkpIe zY%zmUk`6hH%Orem#ravER$E+8>c*A9q=p+TKDeP%94!)|t0mz*A+F=*DQ~?aG;ZAV zu*^5p6EqM!Fp^o4U~Ct8PJU*rgw?0aVWQ)3ydWe%na!ExB%z$2{4klakU)x`>Q>Of zX2xvMVv$qKjbk^4OwEJ3qya;od^0XYY|7|cr03aMK}E+VH_;h-%wY^V`QnfA(tX~@ z#L<>bahO^&A|#ItI+7f~cO9`_Rills^e}0-4T8CLOOgQry4EqC3ILA`S+z|fMN>0< zdyv?;jUl@9a7r%-fRjQks!_Y$GB*NQT+5Kli&+l5wL(S#*yg7D3S>oB63)(GJKES)z62Rh5 z_KXmMlWZ+}utl~{V$>ir_Cmr^<6Db4f|QwuG@`Bf&Nu*i^S4IHBtFhLJ$YjbQ|4ba zw{lIAI!+N4JCX(|>!R&C)Tp#9$&gX$^)z1CSpp>7;#K2akqw@JQ1g~MZsgQxwsQ-S zQ5K&9-nu`ww2v9O*m^z@!a@OIv)sGjXCuB{G!VNT<#|1O5uqIeU@LqKBQTlA5@DuZ zsPjn1slXM2=yf)67K5EjC zthPuzE&3@W*qot%+M$n^JZF{X_(@ekIg^GRhez0&pvy?D7iq7VQe0!b=RAW;&6K%@i-lF%R! zC5jXgR3s@-5`jPfBwR=^k;DQKfn1aXBmhDw%A^G`X_8<9MF$BIOp+*w%z`!x03jKm zAw!ZjU)t0t1xS!2N(!{Bc{3ppAU6dnli0EVfJ8}`W-XB5>COMIV8e#3Dz>cIvuM+* zUCXwu+qZDz%AHHMuHCzM^XlEpx36EbG=mr{K+`JW0)PMjAgCBX5Jia>D}D^fs$#}S zD-#S-bh09bN)qXG4B7Hx(~S!%iToI}O^1Y&DpHmN>gS9A3O|e(5oG1YzzrW%rX*(p zCAAfY))@e4L}fi?0#PIyY5|5aVT!y>aJlueNh<1$ZT)f2m(g!#-mG0F((f}@hkfrp zBE;G0371xyWOnWT>3IiM0FNc&m_qK=#-4)NRo9<_P+3QvV@d?#o)S;=NNdYJlNOQ#zRAOxcK4xJO435~`hqOhQ-iQ^}r`i8v0`f;=PtDbafPOk57@uam zP1WIdieRWAh}4o)OK%a31kyM4E$y5^nEino}0*fZl7^FcwdYOn!DOzby zKw)L6P?im9m86Q9xhPRaIaJ(%7EPA~Q41-C(N$7ZCX!KHH5R~SgKAVjFgz8YP^DLW zl!zpN1OW(1(n*miS4|#OQ$n>R6o|l~8K+Zd zF$I#8q8r1c?NJ+d#E=x@!V6SX_YTdhXs69r zpaf;2_SxZ%am%3&=LDY}`p_?8!%H@PNW>zBB`G7j4$%@(6G@HAP!S2j=3erdSDl74Obh_F zKBE|KJ;hm~aTdK8#h6_^ky?q+qPGN78-*B!S_kQw#lFHRgSc-fj#7+C9D_a>l}lK$ zVwkad78;%;B#Ow1$+3=dtO!XViemqiNdlBH4eS&tB1lOBwia1Pqcr3*&dP~Lp!gAk zVKHWEnxg`+n8=QN<~~Xh2v#zAx!vFoX_o}0GDH&qff(voI{TO;7deuJd=iT}p$H=l z>8z1(%_HAwNKHaXkg1STDGe#4lt2PXis0%xJ;NU)pI5J{6_P1@{HE|QVjPs{@*@I4 z3NYLG%y2d`nfHPSy@=V!o-~s);qNFpK$PIdOO zk9Xt>j7FIhqMWcIb2OqzM@rI?n)IZhIBD7Nmc43Gr$UYCPe)d0Gmj)AKX0-d{}`31 z%fQ55iaSl;7*>#%&ZH+4>`MP`3P2m8DX}B4n@$R$$2g%5r<8R@S#ahhLpUpu23-4`Ks+AQk@~el{T8832!{ICLE$EtlJbMUT4DBmzKvP zHF61IxLP0oScj}M(UK+?il!85WJvu1(eDW3At^-&lNu`?|Dtu)(ZJ|2#0doO?4z-~ z@>MX<(~Wu%D_Q@9R!z{Op=yhF5y#d?8EkwYR}!&41I~t~CY+5W^)pz6@CL1Fijp$A z0x7`u)jtJv&-#vHFPL!2Ll=or>VE54{S-E_)2Ul-Rm$G>y0@fN3F3R_OJCtF>?V^6 zOSa?-mJmwkAd8{YSQ!5k!qoWJFlJHeOdrd+oA9?ROB=9Q4&2|i?C~vPV~K?AOJM|i zSVd)#Z-?Ph;JJ)=!*YtS5wq3d6Eo(%Aa;w3zcQo&ou$Sep7BjoToxVI_s2jEat?ba zZ@}AJg$G9>NMLn@r%w0&-bl5TewX&DZ>}EUr+0c$QvxO?{y*T;S^9^>j z-GbMH4!!?=WcnJ<$fKXhwbQ~=hPfK{{Rpl46 zDMuXFB>tF(tQ~{!G7@jI#`Wgc9)}#%S$5QYPb?Y5?#hhsVlrx~67uGlyW|#3-qJ*u zJef}%#Jd{!i=#f_%Scg^#KN!NHYfFKNm1x$$#8`BJ+@169LbFt616ETUjj89;Si6z z+@l@yRfqrlIFyb0qtMN8v3y)_rP_FZ>YSF(oMno82RUOP^(wAgD)7>ISud3kjFh2k zQQ67Kr}~axNi7ZMO_tQIrbw{EZ(eVnPyFIf|0&g@-u0}{bfdbWfXzc*Z%zqm>re9# zfjo7l$-pX%U0=q%kDiQ>PQ8j-e=u&U-t!NM6!B@6jHxIB`3T3QOjx^{`k*7mH7nrxrjEqa`8gkWLM7eQ&S9U4cG9nkJfSA!_2%v#zhIG==H<^}!qcSPf<`M>`7!y)I$G23! z@quEKFhk=WVPOYRoTq9Ti9Kt>T(Fiv9?kF_uM_9z$9F6xWhN5%qCmH{V z*d6?G9hI_vtK>P)s7asVOC_^ab@_omF8D}*iZRj^{l8W)eaeKLi zwLvP5m>Wg0B1B>vA7VP9kto|V5xe!3oe7jdrEwjFJ1aLJjv^qsf=a+)gJp;iVlgD4 zK|6w(96DAZ$pdstwJ_E(nDya8@u1TTX%;iTS$`N31sXRo^t{)k-|ibViA`y z5WSR7I?*qT0SKNZiUE@m0)`XzMJ$$*i)sQNJfjos$T)gePQt?!GLsV!!a!2oRL1e@%kFrSH=u(*2pp7_1^yv{1(VgU2LeiL!gP0U6hX4w6 zc-m1j2a+m`SQdy?H7)uO2o@7ggQ7ngeG)McyoW@FVV>P0lH~cQ^EIAdfdr7MHnxa@ zv-v160za`SBA8<{pQ<0f^AMFWUP@Gf4Q4#Yag@{Hl}Fe?8WDq)fj_q-8EE)R;xV1X zwG!(=8Vpf^hB0$Hp;~FVQ&&M?L2_m6K^AFQ8X=SzO3_nKDVG1H;WF39F8&pL1Oii! zWq6I^EPSLt8gwF(K|gv_K2in|0ka@^(?J9xHl;!zy%($a;x~tL84=VZ)*`2evnx_! zD1lIdHUVIak{Nv?DKw!~2TCCI5&!{|u7^<}{edAQ(;f8#iW*WK?MIu2F|XwV2%^#? zO#&^Mg;;myQ_PuZp%ER7!bsH7iZv-;AF)3f0UNLimmya$o)tBrk^~H+JN*%`F~}T2 zJ0FOFVCK;!Bi53Y+O$p^7TACmlKN{n`VpKFe8C45SRpP&Qm+`nP^QNJ84S6 zGZr;msF$Nd(Vo{52+jf}0;v;A(=X{_6#{{MltvO$$~0AjRpY{b+%+zyYkr%uKps(f z)glR%$A-#>5I})^7E-#!7`CCvO>3!*oVcN$V=pyIX<%_d0DBNwAy1Lz5G0d9M(Coa zCl)8lEm&x}76C2rNN^>{o}MVSW2&Qw@uM=K047p?@whtk7ms1uqTUl0I~ZXZApxsv zcx$eO#y;iyj=z~Tl8xi8l;rX#z+S*TBF^oS5Mz zi?OcnLa^QuLObh0u|r3n0UJ5xUzw>vJ9;}7TQmp;tUmRtsj-0^bR62VuJ*%Kj@TOQ zs%f0Vvj2*5>ET2M8-Y)$5xY__44Z(Rqk)=u9C<}%RUF06#aKB4nn6Wi!*dhV;$j^X z#mXUx^U+Z;$Ph3n7MYcp%2k<(xf;DGNfb7C?jbs>5gidiQwKJ|2$m$TNoaH7zXIIJ zo?Iv3W+z6mcZm|cl54*#qBs!E`SB5QZ9~b~b2b5#9Eg@c*dNf< zC1lemFmoa==V6%@8pUN3dFvx;x=oth5sd;@6Qy~M_?6^CAlp>3FN-g-5h4fiOH2h3 zq5?ZLqIbU|87yNP3gTbj+jRP>M+bpem>q*V84+x`_Ya#&$#8LTvkf?*Mu;SrQ# zD06OTCBPviJQv%5r{5ax&Df)?)0) zW|Js8rfU;aB6<=UDpfcTP?3sM$57!_qnuWv1rCHbMz-*h90d1N8nMVwcDjhGW_d<` zlH?Q5cN73ifMQ`2uUIML;o<-5C8s4672X)KIXco;I*2dsG9_Ar6Q*JwPPTSU;+s(% zK7*yGH{vgLdLprT_+u|Ut^lJQ{=X!33c+(x2)52_; zaf_4QaK3+cVsw1gb9{m#1;nsS>lSr~=Wxds2R5~a4i}alH)dHUZMWy1{^_8u7xbNQ z0x^?`;AM8JUw7exs43|-25ftQ=VChPYr)B2k?Hm4asJlHL>KD5{_DV=W(W}kV~84d zvX!&usA%};Z5Hg#{_OwI9__hyVXuDZbGU7`F74XB?cCn&aU*ZuK2ok;MA;th=I(H~ ze(rMDbGKIRoX&S?BdMd_Uh|$d^wwTHCSUudH|&e=8#eBB_;2r5cIqzeNw5W*umwR~ zL{fn8TcG1-5xCA~fKCT;2W&PMZ(|A23R|Gl>_wq}#(BM7HWXTfIo58>UVzOWXE%Xk zWmfNck@EB<0UaOVbyBen+71%%<^>PxTksFIU=L)Fmr1bmm>~fPAOS^xEla;+5u{1A zz80;}4z}uezy({N@PvNrV*zdeKnkS5^HYa?0I&tN5Mn6p zIsg57pI2(+t2h5r@DHs3^L?^+5 znr}a1zXee55|lp%V{a7=kNTSrEmE)vlh6AF2736_ipBKhwhNht;X!Ij%8$-pggA=;AwpkV?4Wcw!I zG*>QMTS<2A)cKeo00feWLjEbT>c3V60=UELkaK}HYXJ{bBKIL&!Xj7yBNKA2t-G7F zK4ux&@@2G>cWX=lSZZ(L#WhO#S2qb;g3H?$PzoJm*|I`O+2Wd1<1bPltAk7+MM|q* zVU3?hpI-fX_9@M`hp+y-@rf0q^W9Qc%9bqy_a~76z`X_vg1_j(+ad`B>-tGLl(vcv zr3C-Z8fYRZ>|yXY*!*Mer@k6oXrk{XEU1-szEdEk>j)C*KHxyqDS!bpqL9VTE)qyY zjd0xLAMaK=aJU)^gRw$_D9jO~8WoZ-#`%sa(lZCqTQVgGXCe|O8UIm2Ae0`QtN@!_ z{E4vkXljtctuAWC9>Nk3sUYN%AZsF%3P_@%&I+iiu;n`HizNUK)2T-+mHHAt>STp@}50=OiNmSWz|!3TS0dIRDw}&_i`YvqCJjVp2+{ zoVtiGAaje7sO21+Nuecm-0Dk^s%((hFulX5O@i*}PpMFst@YMw!_;x14tu(m&)EN* zij|;jZJp97`=pC6U3J%Gw_SJF)nuS7;+yj*@hIA)zO2dug1=Ln%dbNI!jft~gC*Fc zE`cWCZ|INqe9f4aMlq_5fmv9HEbG7$iZ zm#d4EGDc<@RZ?u?j;WPMIeDeZbVDhKHm$OyJAqQRB}2jfI<+P@0RWW?hDd7V;Uq%t z)S=4?L#b1Hu%fLq2_#x+>%F#UWs{B>#I0hUFta#V4@t6z3okhi)gu6c;CW|KWHyqZ zuv#I56u8Ks7=VXb8SgH~0LNSFq=B3k)WFDUr8{(wECAGws~Q}-l-qD@vQ7VOJsU2) zoNAN1iLxzLP(l53=OMk#8Y?GzIs-Caoh0~Y^O>OaXfWh5RJ_tRH=cT+!KA{nOmTs* zSj?(gA*}Am4EsmdK^Y{>mX27ohovOADLyef@zRTyW^0j@c$8wrGb0fL6SLAkY?)SO}p8(uS&> zra4D*n*meyx}S_Efsors+4k}tx54mTUj$BGaVkOi$N&UkW9w`mkZsH$TK%{eRp=Fi|pa8LPh77iu!aroPJTb{-3pT;dPipxl z%#5W$K9RsZTA_r7;P8&fu}!dU*|l)S@0} zRzke~wCRH%98I1I$R8X+7Ree(kxAB$`yW00e|3;Ew-mOAwwE&?>S>l}mE_s)zj2 z2DlAsnS$D`^wMWb8Wv=AzDWQshf^ZJ?8hMj!Bp~W>ns4@k0?@L@BhA(P?6D;ee3fa z0)FS#jDLfAQWd8I#Q4TjAcxi7}pra zdqIwCCE!|_jLl04xQECF@{7&@NX9kZOP^NKOr0QyWqO2-N7(n1+!<6Rr6koaf>6-J zb$MrWq8br_6oBw*&yiI%PiNy99=`bK#H=cB5TwKu8zY%7EV*1uq4U!K$Vepra0eOa zwCDU)kA}D9WO=s9Dink7dDBzLPmNq>|A=S{DxUwds|u%eT`9yLsIU6O`b;Q4qZyG8<$D!3p)AnF2rA4=7-Nk_Qy|e~(kWe6)w1D#Rv2Z!>dK=LiInx6Wz5iJw-}8QXb|}?=gwCE4+^BI z6OsAXmRd{tah0uRt8Y^SV01KX8X~~zY^wjpx=%CHoTT?5rEPT;Z9@`~3%A~C>WJc? z<@`l4oi;np_X&|wkm1aPQRpMN`onI@MKN~@+Ddw)lfF!WQOoHPTV0_O%f`LUfw|mQ z^*9rnIm$yE$(`Lu>5lsVt#gB}6i2QTS69(E?Rf!G;@Z>^NG(JPZo_EUE4G}Iq%ApP z!V>ZPn*d!YansVAOs-Jn7sa^AKb`ZGxMmfZ1dL&ba7#ddm9jdvVh2>XBm;jyiE~?! z=+DkvRQG0u9Gokrk9NPiVngTq$VAs=cIJ>iJ7GM1levkU>abG!d6XNnCkxh3FRrY!+6x%-_RLZ9mRl_m=;Z=r|* z)V96Dtc@e9&WSszArpi{!4y=%6*P`|0V?R?6@rlzI;yMCaTu21B;G(af!GfljJSzO zwUU9l6dS_2xt&LuFvFM{^?3+ZxQ-Jc2v^7%g}ATCK(>!CkpKt+AYzH8lCPgIAEGD~ z$?%)FDYRcJvUx+5!IP=#@r+6tJuFcGvhubpGQiwhuu=#oENL-w8zx|hHs1gd?;=D6 zQ4k;~#6ql)v6?rF@v)yEo(+(vjxa<#@h&{^7A&y|98oTrS*YT{lD7J^JBf}DGd~Gx zg*HeP#A&H8GqzxP9FFiko!I{rEhGpDdaIg%4b2m@H_W4wf(}ExMD9x*?qG?=>6Mje z2;(WVH$k4R<2Y^e4~aoB!oWZ2fVAr=FBD2d1(}J_B7=6g1vx9jrP_%S|9R3 zy=h}dFWVv6W0E{+hq;IVajCC@*vL-_ACCYxkyy!)1g>y{HX`$~e<`AH8aNh|%Bjo< zQJ~79Sg!TBh;vbt|JeVDHafAS=oeX=ILAN=@c=8DgSb1=EAs_)7Yjm?Rxi}`7&6RQo;M_UuA&4#XJJ$=m0D!5&m^)JP5r&cyjanX6 z@~uMg5hi&aY61Tn07#8}xkmXr3%1z_Fz0POo3V|7E>60({7ALB=ojb`4+)ULJM6*k`mO|ku2f5i1O+_w zk__Y^g@_}zz7RBeG_QQ=3$5}l^SQ);V~b5y#=96hjfk0*=#vo3mmYaCy<|QBfC#N3 z8pxoF{1X4M-IIbmp&_7=wH~>!`DzgWdmlqRB}BXqZ)B1fJW_A`#4<>NDR{aADvyXf zvpe)fo~Rq#9EfZ($tm+L%bHXGGYJK-JaJMIiwd#QNq}rp4w-0&U&U1pIf-9z)iBf2 zd*U-!tR8qmick`Wy%^R2aj-{CA->`a1tAZy!w7OBI>o7(dBrX&D?hQ3m1evxtiYsr zqKzp?0xpQM;Ak3P^&GPJIv2r=%Fvbgi9Oi3qpBDX?b}94RglDhCNQk9pRkD-t3T9W z3mYR0n^0E+!!lH|t+??B@u`)?!@u>RlW7r&H=-f(khKC@w%#Pw*r=1yh}K_Bwnjp& z^-=%M6bi{1(u)h3yCV&P15w%J)3)W1h!na9HeFMNXeR)v3OVbGZ1o(M1r_!~0*3NO z=@~2lAw^U&AaMa)I(n>*6^XW3jz{g9*>MOMg9rwBhyd}c}_(TpSwiH_hLDEx_1$h$oor(h9V&QPtHpbfd8TIl$* zxVt^L4vee+t z8^76jPW}y@oh0GN*x&W>3tJes@Z}8d?Y>8ijJKa1jUHs_{d}x(EOq&Xgzi-aT1J$0;3U#JOlu;rcK; zAHq*4-k~GTs}t?LsDU24BTeM+iyfkn*|7(h;Fj{07>@|x74qBJ7?A5b8Qe^OhsXb!S@TA9)CeDAXOviHXm*f}@wfhgv(_>WqtA-oZ#q;Y-|Q1n|d&LSb=PXKZ$meZ~K}ZI!d8E+mBp z%BpU-*)fmt+SV5e4?wk+7;{?=ndlc&>w-||0}*SO?%QO6u@cFYc1}dpot+thW@{G6 zU_H0G?nYHc?8H{=gH@2WZi*!_7L@>XW^HD%Rvba?>Xz)X5O2wbitN^r z?GB2!#+BxlZ062xYe|X7w(V~DlNfslZW&JMUhMw{@Bl}_+D`v&;=qlCFm3_=q5@wJ zekP7$@md{930wm0+%6m@xsC}ejv6^k?uHVAbCK(Ai3A57+4;a^R_~3CCPeIoWiXZRsBBv5+X%7-N@+EguB8QI^XL5u~ z?I@>mgp10lyz(lCk1U5%E>{mFS8&~Pm*jSD6@+pvSLHKD^EFopFK2TA2lMn;k~qK0 zB!2VERdeBT@;m2qHs5pd?(;xj^E?-HMm^~F>V@e-SqI?xrAg6K@ylXcZ+X_1?Hc8mIqsB(LsBNA5*;(^VIvqsny6 z)zqdS15Tjtg;-q69<(9HJ@9DhLXs!=;dF%%4~$-j$ptD9-!%288WKembh!fm-bnnis74(idlLrUS@$tznAi^T5ajOPv903v;pE;HN_M0i_q2WB6#FCS@`Dy6~8KGB*q4AE`_r(`Ec=Yez zZS(g6n1H*$s7)Rmg2CycK#KX*HL1pojDKrjG9d#wNvq`1&x0U#0z za_s2wB14QHN0KaQ@+8WXDpz()P>~}>ky8FaERf*e7MlwTIHc&3qC;B~8Nz(IFhN6) z4m(0b>awC!i5L_7!l`uR(t$||koxs8t4#n%n|2f{mSC%iJRh2U$`Nc>xK7&+-14s# z*MFpdhIP5LVaTyNDNcRqwk$yj{{$Cw_-_-?kN~zy8Hlv7$ejc^+4D$LC*pxUHS+`v zAg9Hjq%EJ!EPD08q_K5oc4=#`%>W5z9{%WeXK&XD5|HZbwzpfKq+PF_9eQPLgPn^a zR?XUBa)PRVx72Kpj7hVwVY^I_#XySx7a-m0tl;;Kfxd|A1G3J-=*HfI?=Gkx*CzNnnpHTi^v=05i41 zMTPN2_>V1{*kaXW|FmP`KS@wT#$BYeLP}*Msm7c^6UOFXW<)k;l3hDt2U+YG*}u9F)u{H=A5e>NH|}ZjE+ZVHfQ*(?+bJl;meD$vG#Tb=t|1d3h2znFN)E z6dM3S5p-U9ahfMV5=h0?&P09I1VEn>I3&duNkGJ>j@U&i))bXSIF|xJ24Lw-QjA*H zJyrUJXs8kpwwp^+=t$T?A142(gak^=)l(9EYSxq#k}_nT0sAy6D}|yJ^~&s8 zc?QcKM2|XHB|}~5n5bC_B#UT-Y8IgDv!eaUEK#FwM9~(N1(CoeUX{m@T~9HTgcR)g zDOP1bSj25eiE7n`J$Vwwr>Uvws6+wm4GL~W7TKcaz4?ANEP}l*1cVgON+6I{Z7!6A ztVBVYY=j@1tC+|PDR!BAB3}wAx>E%UGDsi(87E*Oa@(f@HaVO?n*#Uwn|T0C+mWvw z2}CJ-!+v)bqPxjlz((e^3uuH20A?OYU@Kd7y8I%l;bb-)4cfHq2HEfw9lZ;HtsV9H zkH{Y(eB3>#1tCEY7s;bwTm6hk)6MYXo}YrgQa65Ov{QKpPes`{#RT6)atB?o3=jJHHoTOFIKq_>@Eo z`6!u^fFgVGPUsbcsM~I>eG<+beaI@HNnyN&J*TRa){+BNSsJje@*JnYqn4K}Mbr}| zc7#&koWw8bRrI$K02tW4nt-qyg)}TVz4Dhu$d{lLIFp2sf2YSx41*aHmHULP= zaY#|3e^5;#F2w(fdGzv+d+22@02tv}8itU&*k^(mbP)i!kilcQq!k&&;KVLS!NZV( zgso_k5G#bk{)H$u$O|Jy*n_5qlwv{>sRs^i@swY*;uZ;+(5P(T!i(UKL>$6l0l-H> z4(ZP?jEWKoOCi0}6hub__|Rnt#T5);5JNx7Nn!>f#0ui@Z6o|6fLzkSpOg`mu_?uL zTp_W9Y@sUB`ycOYGNC381VoCQ-9>~LAcm|5V^Ww7fs)`yg^1$h6ob0OSYl|sqt6@q2(b}I58Yf zWK{o{LR0@9xk3`o3MtP#kFVqpcq>vyl41gem z764F+NO?9?BRtPCuOGSsFEElLEfJ~DBi`$py0isFSlFZ5 zMFlzdMg1vlisQ7VZb~>j+zjNO1=vJoTH%iG>F;#_KtK{Au#@w(i!eRJ5MF9j52W12 zeNp@&p0LJ3sUGEr;nT^)h>F9&B><=z9m!7#$c2f1QG@uIOCpiVA)AiGEZ8y=miz($ zg5}YYb!`@wDwCcbu8@(Db7YJ4B5wS1pJNh`ktMCF{zh~c9(D4Pi1ec6 zBB=k{-SXBWiF%~tIP}?{+Jkw*Bntl0gTSLCYHF9M&Dh%M? z%_O>y;o9w}`wvOHD4jWR(Ip3>k?E|>i1R?F(NZq!nqcRRxkPcDuh?raePPpVBrJym2uS-1yVk;;X z0&#>BFj5zjqRV(of_udxm8No6Yj}&|OFO%vKxr@u4{jECG!(AX7^Hl)v}}`ibBozk z=C7)}OQ?`c=Pdw1ki8iQA0d60r7_Q375Z?9FESIwqN_q5vrBvc@W{!)$0tb0iO3Q_ zA}K_mLg^GFpn(Z$7jNQdNnz7kf|95TZG|fB$noxA&1T?IpdDUd=NB%qIMmI)RfbLoX-xP(Swi(SCrVdS3-5@A(=$KN5v3oV3Q6iQ5-)j}{| zLFokN-Aj%fg$IM_7OzY$(7}`JMOyfQiusA1(x&>`b$Ok7T)*nrNQ|O3$&G zoi~1CO5ma>_1m7v(`Wp{B$$vo8puyDidmTBc|eA4Gz6%TNJ2~j00cpboYUNJ8)PKU zY|Ig1l+h-DkHr00;J72p)Z%0yMg7H&@_^tr<%W}tlpxK>L}*&{IYd_6oR$bw0R-Mg zw8GtSh4561Y@7>^gpoaz!C8h(%P$MczYjkyiN_ z2uX@YhS;NxsL3AcSpc*oEmnqGq!dFi*+29Te;_4^z)0X^-gM++QrctDF@)CLhvpT) z6#T-Vfy5RF8C*r+E#wp!t>shTkLPeCLj+ui6k`O!4n!yhUEYgV!XZs$Mcw!lcilyxPDc_!DH%mnksw!IzRp@$qiq3+1PD|^j9SD7H0H=?T*i9z1YJf2UUX10p=uJ8f#GSY1;J%l6sDrY z%jQjo6mA+)2oXWljTZsy7T}6H%_xJoA!^W&k<`rqaSJo@A^B`**fpPJl-fXO!D2)O zc*vg;v`fYb6XCpMw|0d{UQ&op6*lzu;$HEy@p6MNMxOc5{}Fy zIfXxvR9ZBJvHY0zG2OHNq`0x+rF|@*RA00IBw4r4ARl5Ir3}tk#N(eh1xV%FOO|9< zR7l3@UmWVh11?+w)R6wblAb=%MevxyTFUT@6Q!_M8dgRp!qahF+MhK=TY?%;j#dbz zqL%!qM@)fX`36HqkuH^}ID${h%v=|pQ7hC@Rb|^%bqLn57hPDaRs5O?ndr=6j5Kz} zl>$$t>|%(lokggt;*DLCZZ78lH-sOxQv!WW%6Ib?t@6HIrgAQ;jgFe9lZraDsR}YoXk#s{~m{1P>7O zL=Rzv^$vyi!BJESY7tJ1(T)W~g5gg8{6hceDj(&eEx5yFP%nm5A@Lk922P@UE(BSu zS>g=Oqw&-ZV%vH?*YB{d7tt@za>NK(Qg`YM-VrGs7M;Ho6GJ@BC#oFsHOxj}2jMwK z@ZLhy02j?j+b_&aX#h_~Fho!6-6h%-cAf`t7*=(1*T_DmhO!mpPMi%ZM$mxGO$e{JJs2Ds5n`dRS@7SQK?Vzl z#1=#`l+sE8eB0)=7KeDwMWOM!md+j?FuQE2xWz~9s23+7-ash87M!q7Modf)g&>85 zu^`Y*s3!n$6Hg=$QfvSg9}Ir~0?O~{sKaR`08GI(HZexvl87wGPifYC!3%((V18`l z1%t$K#fHM+j$$3&tPspBRB72PXc&&tT-J6hVf+wOtV! zuRsumP7=i|5-A{aO&&gx=60?%*cR;2 z@W2R;BvryK+h__B8H|wJNeG}$KwAWsh6xQ$*hd+KP;ttZ0zy-bNJK4xZ6e{wCY&PO z@bh3;w z&h(1(mslL9h0O>&l@Te3ZjL+!L4KI^kjNIC;(F#*K67i+Sy(Fph<6E$w9XboE8{o? zbP*DfK`n-DwZRlbwF8RY&KeGQpvZYx*a$&%VUx~M)KJpdl!Rp2ZaiCAxkS*EX?b+Y zSFgpy#2WOK5hrjGQVjMMw9@9`h;5pXePE43hsa=aK`V`9VA=&lsA~aZO{##>?=Z|= zxTj?#bre;IT1!=E>%~5MHK0;0gH%Q3*~AvGHcbb~jF3XS1Qh~kHIDSpNFBsNKZUqG zqN--m+Epn5xs;{~lv^!c~w0I=5a#_k~b5(^?>hWH+_$AzOG@QPB`iXi>qgnTBPFUCbmx%gA^1^h&mL z0#YBKHnk|h$R@BN%32uHdf&3Oh_cjL1)UqFUX#bU$bE$NN?Q^D-0@Z?IA|BA#!Xaf z)krH;w7vL8YXSzmjYI;F!CsHkCIk(y8srp^flGuaL3j>*hs$1Ene4Q}6tu|Ylu<&D z;6e-6nHz*~QxKr|Tv9YehP1RxY{iZAQsp4o4*7%)A!11w-aY^MoE#JJT;%f}#CKHh zPy(M&4ko()72crNSvqq#{nj*z9NdJGh>R497r6qayXkhBP<^4~kC?F16ihrOCFbD7 zL9~PV5Z9v*mWp2Fsu71Eh25}7Iu=GzJp!RY5~is{h&@_dk_qn zUaQH}4tgTV28VlngiMT!(q2gr)BASZ%qix*-HSbqgrIBt=0kPjv)m3|752^?b{Ou6 zTyXuGA~Kox(UZu8SkyQvU~I%)wn_6w;66Va#1rP9uqBfhxoG~3ggLP>pm+b9&O%>Eq(qu{r(fHI@^@qUkI04c#ChCicqB;rvjm|shI_OGKmbS}ut32C z1ra6;kdR@+0`^EDTv+hmCIAjG7M#d%;J}LoT}jDU;NroACJUgH@{bHhi4Hd^%y@Aj z04c2yqO9q#B*~W}4gSnoVByZ4tu_VyD0F1elngg6mAMop%7jvhJ_QPM>qt^22^MIF zv*6MI1hEF~>J#I@wQDCPu_aO~!?ZKGjJP&04td~l~;!A@CUUKlxZYoY)y=4R^ua_vFd ziBaNCj5YGgB%mV;-z6{@HuGoqKoh-`j%UKDuBKp+FEgO#fDj zt?3zmD^BuHic|m+=rfKF-aJPjr_bt0Bl0u?Vz#YY2p~WJY-t66jSLj1 zK@vywX}|J1GO(c$3EZv1ClP}&rWI4{s>c_(i%P~SPZTc!DhK-xOv$_qEuk@C923pY zy25h1FB{tE$nSJQXgxN!N{bBb8gdZ`+yDh?!UtRVC$NTo`6tmtYi!j2(MKVT6viz` zp)1RTwxEt9GH#UAyN-Tju}Qe3uoTlGJ%w=-PE&2w)mLGSwJcCglH#$3{E}2aNk`30 z){zjf_19r*bTh`n<|J0xWw(6vwooyVY$4@VjQFI8*>AzMGhE=nvu)fs z6$^B{?|Q|^Sa2geSG;%St+zL6p9+p%d-?6xU4IL@vrmBiZI|GKhfTD{gnsD`RfHjq zm`;f)uGr#N4Ze8XWSi31ier#TF8NI;O-@!0MH>!I> z;)IgiCBR2#vF7*)FWSgU*@m%%tvCj?Fvflit8u_i3M(aoGJbAI&4nYgJDP9=V2f^N zm44!>LfvYME#e)CQZh)PuBIu-;DpoJFNLij`AOj-iL(UPp7lt#u!-6HXd*WGM>~WT z!0w!7eVm{T|EM*PvlL(x?ql3*sFgiQ(QhlW34mXO1|sPHG=vONP|&UtlQ@zH#4Qqt zT~0C-!vc&bh6%XPY?L4YK-KOzSV=+v^@k8>6-iwQsi6!7Rl|_2ZxgW@Np5gcL7vPG zis@?;po+Lc=Jg2yA4yLFDyYG9xk!vy6l2z|*qlNo1twBN7oBKEvl|K|hmawnKvbBn zA>!(VSJ|UPj_Abgm~kd$vmu-yv!cj6ta!?zRzuD=69EYbKik?-Rm7(^>9|d68L1nt zsF#yWzA1vOutke*Ha&;f%1r?9~XPIw#CVe_)5NiDcLQokcRIVw>PeqVg1MHrCbV<@#Cn6+S$wbjN(f~c_ zrE{{+RkPCyRJEdEAE{?qNYSuHN{R#slASTrf=G{C1Y4g8PFeOPgY%moE5eg-Eb7)c5)b2(j5DU!>DM*0!R6*e!^yAY3T7{e}~BvF{cj z3bu&uWJ25A%5hOPL97)7Kfejo*#diFGcpH@#U-RxGMJJ-nQ=KUUNO(o*t(P4<1uv_ zn-A?f1zY{&G5$@06zs8A^A;*Q2f`2kDSoKX=u{*D(jkj zL2=Fcj6l|OMm%LvI`#$8UJLM_`4IUj()ngMy}VYqL5c%F!DA~bg^&Q+!X0F&Z)b`q zATP(WC&CIqNV_5(9m38u_aTL2-13q2fwlk=*g_lnn3Cs|<|_0Jr&5$qis;m3Ag$oj zqqVh#0I-h>T~T%PDD~f36~L6M+LlUpc_@Z(p)^fn;V)!uG=YTKc@&HeCeK+@B~bcD zk$g1!NU{(Gtm=iW-~^_8IW`oE#1+SlXF<@{kxhuig<#b6^k9b*OK}f3HNjRAN}(-5 ze>+oQDOD2M5a{m~pi-vH4JL>G+0sY}3!ZGly@ zl0q9eApu+5JloBS%ReAXXX!MZqgXVFJ?4vbbpe2>WvL`W-g!a0}6mFWxK|Ar@V6ClC>4xi2C%6{BUMMLbbopw>P0tGu@D+9) z00zg6t9Qw#?w^wDmSn0}$yj37xyeeSu6{U08Yz&+xwUI+moJ+^4aK;CJs zx?;~FrTJ`$&Isp8jh)c z3O}OCFWyN5V@IC+?;lFxBd!W3Y~erTNi29RHxTNv3ZM+iCnYF^VIE6SbPyr5qq86* z0NNl#utR`mtpIxIoy1B)KIr`{#64V1$)c{u@anzL=Oggr7al9z>aBU|?YID-4C)U6 zs%h$Kp#W?FwQkS<4GYB$&&%2PYN2)r?2^ou{*NL&VkPQ>sk(&}ilR_-u*XV6epaP@ zcr8Q@kn@rPn)VL>-B3FaP&(}4oo)evrl%+fA^~!wq>5r7@MF@XC!0Vd1zAE*wyZt` zffAv@E&>ftiKEa>39axpWbna$#4jMIAWjJk889WVqa7NCI?B&m{-M^S;|ViS zAml=!exc!#pbZx=%)*COYAOhI2(7Xs03(9v5>ezbWZG~85DD%V3Jf>u34#tH^K60x z1LzxhO|#D8L2%1vVQ7q=-7Xjs+Cc+R;i8??901)azOyU5ifVaeo4xubD^I~E?EP~e%2(5@ z%|{3#oqDOCdg(2{FEGBR%5V|HT#Y(72`IL}AEpfO9uGH?z!fee84&^}xK1>sqf`9v zARJTw3uE#u=CS}vK_|3OF_@|qVv|hv!!a}OTAXi}+D@YyOm9F$8Q-yaiZ3fVg4trj z7P6n^Svf2sUU=@ zrr<34b3CgPJ4GS^e!)ka@c%ACp(NcGcKhGC7w(m5UL9Uqdt36swyM^n9DDy z^G6V>;Z~xmm}b^a2+==V!qsje${gDWsyqUreBv?Yi9!_eD&?uiCW^<%aO!@~EwBau z>#QoAgab4QLLW&&I$W_XE0LZaRHif(rnJ*D|Fk4RMFGlbAFHYR7^2Kp4YVHALsu~X z5UM`tA|4aMF?Q*cy2>CPY9-7QdM5QV6T&?pWHTlN&#G$5CakKukEJlBFAZp09_lHo z%GE9+okordr-$7T0zYmoDZZ%`vZI$45GekE6E1=a-UB82^Z72M&29q#IN=|9FgMI{ zDJbQg+$S;t@gmsrIj^!%EYTjQ2D!Y)Jk2YbG=d<~gCe7qAQq<6=xpzT!#D;n4gXF7 z=Jor+@uN7?AvWMq@HBB2a)qGBU1yRe{-j$MLa*XbtT^x?MkoYJWFEPX@mM1N)Fd`H znzhr$Zdr?u6i1|j5{FFJNExNa7G6-h&=4*WB5{W7A$Nv?u&^zAQ$k5B6Lt2TMu@sZ zL;`N_)d&K8OzK*tku5V70BS7-GchGLK|~0xgpv^>4?<->!U!3HwMN!LBqT#F;zmf} z7T}E}46Xp~A@eBcDg~`q6Ngn7vwPaW9-_;DXf6SQAY0;07!e3JZY`-2ud;$9xX_Fdd`Gyj+OT48kNX z)P}}SmDExJ66a9IQ#5fiQ2~-9YzbPF0Q^u3LVs$KIPI7wWYX{~_X6Pm7CMUFNJ4S5 zk7@~uCF)93;IQf#h|6|xS+OG`lI%F}%Z6|QA%SYH=Jsim>?~WN-KMpN;8TZq%N~RS zT8QGYVn?sqApnBpbb*R#wKak=GgK&&3?Gbf0RY4RgVFBPjTn|T9&G^*iIt6ovTqsdVu^B@p0q)^JlF+DTY)|UVh`{hFk|KN!Le6ZG zAT+LIb?7yLAe|)Cl!oX~@CaJLLW96J1?kXi%V3BeWL?GRbKw*JGQkWvSrq{Em2v;| zQEsYFFi{izX?g(TbV@}ECO`^=jC(s)VjaUV;8fyP%Y3fGM^xjfK+HkTvTBJUpjdK$ zob>%f0vapgEEIsrI1nWqbDYXgDwLJb6wo$>F(~R2Efm8yStAKZVO2I^mVYiIY~dd4 z_h+2YA~H0c5|28zg)EMa;7Vf@z5>a%pcTlj_l(0MTEP_%f<*0NPZ+gB`Hm!786`jj zb~Kop(ak9BK|83UR9vW3Y!3iRp+@nHE|N58Zm`u{AzfWjIZu!ZrJxLISrNaYEas!( zhGO_Cms%uF^VA8xQUb9`){=sgmiF=>6#1bBVgv4hE(EdvN>52Z2zBpp^hwpLdI`1o zs0Enijw}LjoSRlcKnyOqF;MBlEuJ|gmd<0#IdP%@R6r#0K=IO&3TH_oZlg1TCWMV- zu18w(ApkVl4cPSz^;lBbBdPs4PDWanUE1_UDU`)$E zDa(;pEoZ|qK1+3n-LMjIVmqT}C8DLrviZn{NQAGsEUs#t4QhIBlB9~dP_pVvsTD34 zqDt>7K%P3V4hU2lsy-ZZe@aU8^pI%>w4Yc~l~IWQ@(gXbV-FhNDOFL(fCj4uTNNKA=uf5{d_1O-JyoQ>u0ntmg0sAAm^Eg~M zg6x6AwL;>K!}}`By8!7Hk|IGaB0-X114d+|sa9T1k$78GQIbkgyf&vJ$ZKzMe@p^D z(6*9qg^JUqkaJ?C3AiIZsNWER&Peo2OsZgeQ++Suza@3TX!16W31KJvnDFBvV*`t7 zVkH_bNuQz&%)|9oXe?-0(Ar$kun;J<5CEbeVpn4Eu+K8BqQcri<|Gp>SIAy{;?p^m z3=nJo@QS{U`f{}v0BRQif_pucSS+fKSXnpuXmRcbY%14;0qq<$aR)-;0vl30BuZ1H#vm>x^ zLSNDLsRtrL590pNRER#V`?89}h@!)K0wG9Yo>gmx`m#e{zWKy6B2E#$_X9-eqOWHK z$}<$HQ}$~)3h&0Y5k2nIpj7DM^Lv74A72e4lpxy-RIfSG9=X0sx24uhDWgX(JAjw}zVl9O4G2Bg@|%7%pA2Y7;go_{^+0w8107O8^? zr4)4d@E@6h6r~h!nIvIHmt+b=D3HLOLWBTJ+UuBbOGp3|Z7JOJFNwfb_IR>P$TPu7 zq)H2HX~olCE1X+B+G?6`q}6|0P&)iYD&bdz2}sq1YOmr&j}pKRl%O&p(u7GQ^!*Fe ztivS#Mgow~Dlk)o2?I3$EcH)9Lxuo0{StVQsbsbV)(WJma4pV;WKI^)igRdatOZEj zQ*iXH)`aTfdGyyY}tX zIdD&?V8eIp30nPY=jvapBs{15>fBY~z_|=X0sul1?@EeW2F6rhoOKLMVH^NS{L&6X zMYZBtPQPgNPf`hO#ndm6DMS&3wgBN6MS=l9%6St4p-^cIIX2fX5sj9cSqWxmUMuYs zW*bqR+0({C2{4oZdvjTrge~gDWl;ejnO8tN>$PUfj0M#48(t3Cg_%H(B~+7SNFMc% zPXD-~P!es#g`PqGTrqW?Et_EH7+(E3)?!QrNLK)f7(-bo+~dli5Y`j>SPas^s$E$Z;mCvVF7KpBV>{*ow$&lCH`|7K~VJ>Xj}^6 zl*BEO%>_hG|A3kh5XpU27(x{BWRgn+X%&|{4t*4%QUC-HL{D9c6x5-Cs`nIpiYA1r zI}gSuB$^iaSXz=?=oVKi0pMq(vC_U3Vn~&yC10U9q3X~r$C_l=d`i$LP_9N{n<;;p zIy9qLr&6Yn6x)Wy7@&eSlopQ{HB3-hM0HuAnO0)f;<8mb1QJ0_woyRGoOT?pmr!lh zXMh3x_h!le3%Tk_Ri!og97g|8Mi@-*F_r3Q6q#n=c}0tbP?}^7Bt@vLYoER6Zk+g9u6{LFi{8H5fSO@wNU-n}Awa8d2N2t7Xx9HPprlI(8QLZXF z6sG_{hMz!vVm4mvvd_LY~hxiC5BH*R7$ks)?_`wI~+o#ScTGT66aRRnh~>IJa^!? zA_Zgrya~4j|4Ga`!chnifY%Bo%ts1aA;Ts}@ip){5O{CNUI8}2Hi-@IcL7L%6yAap z1{!HDoG8NsA7UHeL9h+M$c#wrskU{~WgAxr=XHIG1L@Si|qhsw)hA3In79@~4g)rzx3;`qhI-(%$_0K;b z1S3?EfW9q!(03nM<8WRAJT0nGjzers8w$9-_0Xwg%TuEdZN$GCNnsP42}&zCQIk>> zkb$IdqHuUKz~!9~cm*sAL+({ROoGg1C7S{W8>5j#63;*@X;GNS(3K2MA&%7f9&ddA zc(ok9qz%#$A10?rs!t|l3iYdr5K(CsqG(TsX1XB!bSTEl91@H{^xyu3wUAaW1cPBp zOIgO{kvjfp3rPH;@Th1Igh(MRn;=G1#5N^&)B;X!A)l1GfqRLm_f`8FD&7skMP)dQkV3O3vOb^wKDW3V;RS0PiaG)!i{%z~o-WXdom zUOgyO?7CFq>@BZNz0!v`BTVPHvN~nGYQJEooy9;C0f;?oX#!Ij$e{!Q(2UwXFDoC9 zI0Ub`i5gF?lR>i*ud8^~>`umNme97~iW$)Y$gvwD@SZ!IlmceKyOI;CTo6%6`h zk{5){r$v5ct!mlI+PT#BwVW9&XbEf8EZTOeOq~x~hj&oUoRzxS@!)e>q+L3`HMXzi zu6D9YJKu1}xzRQ6cG$aG!F1Ml=7q0&?;9`VHgzD3y+~v63*Z13paoN9uYCoKV3aIP zsiGwhgQ55#7bbYZR>i9@13X>pw4$OAMoG8K5;E!@m%_2j@OMHKAFIy)E~^J#YDAxP zDDhe6!6Z(wi4&Yv^!~NR+pP|W0Q8+3b4SR0-Rp-2SzhYS#g#f%F^S>J*``LBP2XuT zavK6)E0cF`zvQu(zf4`!3Wmry9u9j=wVm-MWUQ9;F__<6ohyl%wSt**k;lVck8z5I zQm`Fg{0!$BYx%qq=wG0z>s*$6uPWDR-Jz>nV>C}#&5thhqwz~-SY3M40v`0Ho2+Dx zaXQc>;11c$a_Uj9SJkX;wW~|)X8FE));*^6>^yDjTw|EipVhUmf6ZxJ1G~G!F7~BC z{pDU8d)fF!b}}IfW@qD9*u-YGtgVghrDi(Y5~lK_sm*OyOFP^D<5sm2Wapi5Z+q43 zF0i)YT5Sr0Th+D&b-C#s?tH@*vqpyZzM(zj&GwbPmEc~dnmt)0D{^7FpA<=2ic z%=Js>eswjRTc+c=2E%o)lUKP1PqKD2zF&d!+fMf;F=d_XWsrk>>#J?}m_;qSyVJJf zZl^ndU5R+Y_uI<$=D6eC>%_>*(IvSdXG33-Ll0(fjY2m6r&&zt`I5+S3sWG_O9E5q zg^XVE1UJjl1p`K+<~9jjAg6u@Xcfu#S@e<5;TB}<5Z!N~#Z4Uj*iU2?#snY$t2e#} z6~LRN!>Q-{RBTXQ`?4G=AfY)-!V|sE`_W@B0Z37xb&x{jAORo1J0&cQU8wLbm)JJ8 z097ket?J_MUN8Y1j8yq3e7n~{Tkt(>vwshvORtwH?S~UvzzJM{TgD+(G7)+Dq*YF2 z6~5GdriT*e_ESJtflb60;zxD6L3NcUc~uciQ^XQ7)(~rg0C)vFIz}i`#Tc953P=`3 zS%iTIfdEm^eA*#=UlAu)rW;28(tij+MB`Rys|RR=<#g3?Mf8z{ z7bt!nAw!#xgmAlb&Ek4l zC`W_UKi)TlGQoX=p%DGm7jB1rz|=c_mta?DYmH+eT|y&pbSM!bEJDHwBbArYA3 zbqoc#4yY0#7VzD323jmpCyasaO_?XBMc~B|t$rCuWI6q8&ovT5)C%AjFtCG?LQ@ zHWvhADHa4@p-?;l8Xn;or4ci<=nta*BNjJ95J_kjq;Lx!^Hy}TWLxQ)3CS0=*efUj z8DUe7DH1mY?D;c(K0i3a(jnww3BYwu>?#7kUN4F5eS+KVICqS7Y~6$ z4gr-yhA1du9!k(7Uy%^c_)Z8>7p4(n2mum)h8xgS24H~_c)=P-(I14-6&?v!Qv@vu z;1^MZ8YpoKNE3XVgFo0sJRs3kh(V7_aVw!U1@=%Du#pqv!Vt`nOm-zHgF!U9m>L}E zjU!Qtl@}5Sp(Fty0SSPH*n*lZ@qXe(7*Wt;&ITf5S#}I4Vl1e3x92gL(lgRElb>QDb|j| zK@wE=c!4%tBV-%$a~R71@f8xOFfM@*w0bNxQX{#cA3wntav=~_!z3+tuwUT{`0+RK zVi{`2Aq#<8bc%c+;*yv_IlV|IOyOVhfm#SLC@I%3u*f5isgwmk{c{56(i_Os*Rf2py;!Mp`shzQh znpH*=Vmx8O6l(HGX@MCE&<-6z29)Cp?(mEc!5|R&T6y##h|wgN$}uj77)f$GZIP?# z<12v@wk3N~AyFg}&?;PG5J6Cf2SIn1ktaI=vszIVJwYKZVSWbzJInV=dlo-+qILkF zB$yGZ{(%-oaS`_ac`?m&uSJy-K}irDfhbC`1(IbIkJ+v=Q#YskKNo_a^o1EP3p+x| zKK(+AYZ4u4(K<4MRXG(-(1I==d$6wMa&ILRTZy*0dJ*=qxembz9g!QWdO^9Gp%|gJ z!Vx4E;jd@HCvPLUBR3(kOCkV}HUDZrW7`^^bRfzi5R_HFIz>YgnHk11oBcr|46?qT z8Li7ZemaFNXmJrHkq}DqH6Y};L6I5Lp=LTYF+VX7GHJIEx~)HPAi7i~c=;=@q~cNCZZaS@#YD&>tef zkpPf`^4A!0TD-LZOs-ccn}8@h+Wv6AabaBQGk z@lF@4CjYP$TfrkN+&&8^JTI&ex_h!)!ytiDhD_4TTZj+}5EobR4-|?S_AJMIGcJ`; z7_iigQ^3sTv8c`jGAK4f@q)<0kv;?A(o8}Mhb0UXv5KE>suu?JrM7syWXfkebHw$95=>4DH3Hjb z;Mu2xDH1G12IhFky#oNWnsQ3;Ac#^5ugPS(n7sc08`04~eC#Ym6`t;ruYDmMhpjz{ zF{%Kb5{ObMvCFxr0!wp3#$bVx?t;A@LA;*%5zR4Q)j<^lA;TawA^&n9Uo*n;LA)Om z!}MqtZHj>caSNPaAbz0$Nl@c{(G!>CTD}Sud7-%yypOjq+zXKxJ#IUQHMs)+;U3E3 zji#55r2&1GDO7$nay@e6i|CET!{R=+xfg*N(Q%ero-`LSeU6O8?I{&o5Cp%V1mWTy zV+8~;4gj=#R!ez({TPo#XPr0dfj0rb zNINS&vVI=U!ydctKPCbM-h(B2lbcHstvxy^|L~~`vFkP7>f6(-l10o8ksNlVJ+6); zaRC!G&g?dB+$E0Ljj10fQ8oVx92uJu6Gag^TQu~`B{6}r#$h2c(u^bj2Pp%gB%Y!Y z_uxs4_+!e_i}+VJHookb0?12Y6j_JayI3@9^6P7I@A6TTw$Q?s;b>T0j;9d-s9~rm z!H?${uZMQehVe25F+2!Nt45lgr?DRi%_7KSo_R3_7s8?;5+RgsBqt??*mm$KqUHAsuf+8MCpJ{Nh(8(F!LOJh*f$H={12A{A=_+M_Yb z;HoANB%XarbN?+oG(16|5*yg4`I6=x+GL20~r$N>S*63QD6blqYMk+>C z+BX70(!Dd31G;{Q5Ij{)(R2oWB^H2o7=qqajWV~QZu=OyAh-f zu?4Sj&oZu>(RUJYc(MdxiD1)<8U@+aVb4R)sO94lW`e}*11CMoG=IM=L2wc{1OOG$ z^P!5$m!)Ud$7D^6Dm&*8@99~fg7bd$T>y+l+9{Sq?B6y8L?`Vn(HJEhuJp@u0ucWM{tD0((*b zAW-sf%ch3`5(>1Zl2m~t1?+iLSTQF6tQV71v^kP%tA#)RrxqZ?bl^Xc41td1ImMm? zo3==Cjd-u7MyvpW{M&?eX4#ws;W9KRQX^rnwlbEb2w)4^iVPnM)#$37PLcnn(Cxa> z9zy^Lm2?g8bL7RQObcu(pmP%$);3EsobA#cm!AzW($rj_)MuAip9(dNpyFrKty)Fq z&2!|GgQS+*jN17yR_ocdZ|C0KyY~g(#gFeEM6JD;YJJX>8nY!yzAXztxA&{*+#pyJ zD2q+6Do-Wr1(Xoj`G4wiC>feprekWDs7WrfY6I4(DJJ2!Is$5s1;jevao<( z$g&3jAQ)=pqtg893O&vWun>UvumVD(m}U#YBFL=&OF*p=AN++B*x2IDK3o1tFRKG{ zOQP8yX=^dD82sB%OPdA%}{#*w_vA`|_S!B~XIv zO}*R;N{j9s_*LpGf-^TV?lBlE30PZ6ChXACNM4#Y{m9}P19;Wzg0Oo~Fx?E(t|L96 zhS$Ra;nws+dr~Fx#@zg>=*he;LXaT)49`pES^=O?LCkHEQYwwEZeuw;qm7X~;DZ-_ zc;dxV%b=&SC2_gaeIiS^m8Jl;q*hA*WNSmju9jK~5H+%AE}kBfe#MzJlHx7z7sc>P zd41LZ8{THzL!85Zit2$QlSV?2x6^}L@;#!aXKDU=7Sd`3Mns@e9$1h2NA>sU=w|^RB!^&y-MPR zC;U4OL==^viae$!9`@<1SS*9Q5lI_@MHkSpgn20Hj7SLdDvw=7m^O)EoL1vZ zzR=}g1~VpJx~IYnVQO$RSzIgJ_soAOXhkY%ihM9M$q$jJDNXU_B+vOPkG-iPHUt24 z<^?QF{$oeQ6iNbYVVDQ`twnn?&1~#(K?~+3n#v0w7j?5F+F%7D*dd$Y2qUI-s$_|U z%Sb)NNSCsRtA`#U%@WOLNhs1QoEu^ZL1%J21=7SOKiAyIEl)zNh zbqkn9rCej2rI(O`rxp?JUr$*ULc&d_w|8NC?Sd%>cSO;e;4GuzbGS$f7EK|y| z)+RdDmGX@wLUAfr@^~Z?tQ-7hk6Oi-NVLi4U@7OL!8^ z6zNfqX7$Z8S&~|v{AzL~aT8~6wldtdp*mh!N_y&*E9aD}9aC*Xq%NY~vbv5ixw+0u zbE6cVL8Yh4i>ufFK$IzVwPPk)OdVvhv`~1(N{=h#5ney|7+V10PkGs(D)~E-ot4Bs zrcEuULCxvI4*)2nx`X1s$*z14^(7{jUZBveoVjhNzW6Lzh4Bn%=BS9H~$8~N7Ak;o7m`7%|Dek1Eo5B95pcq1C@>>xv-UvH)X=H5WhVsAXhWASREuV{k zT05pnCCIpq7~J{WxLpy*uL7yrd1%_Dof0PHn} zbmZeeEOzXE|B3~a-{Ok8#cmo2M0ZheDQhEX#3pv3F)NTc_lE;7m4CFuFi0`WL>5SPz z2oxzA6bX$Wl)`Dti-Cd)!ZVt@i4E)60+GnBO6r{iTCV^wu^q%hI76vUaT~8en@Bsl zk;oKjLMa(>!rphMC6iZi(ApVO%b6}f8o6umUfq5A$9L54sJtu^fF(M7s;|juioAqKW zx*(kdSj7Wk4bJeRVbll(V60qJp2OfLP3($5@)+%q03DI*CAnk2}?IO&>w z@{lc%1Td2(k!%Q2gNqpP3)1O~O^_h8!HQJWMxe393i_C|fy1uw!Yb?!X39cAgo-89 zl>neci@*?*Fvi130*8#gh{%u57(zNxt$~cg8Uiz#kSfv>8gYR`4cWthyh4V2!D;%O znAF0qI6@i9#z{0pAdDL@GY-U(wiwK|Tckm{B%V>ki}6sDVzLGE0}*gzy;YKw|HA

    imNyA3!Q#l%cVV7g4p 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

    Pr zY_0FsjOK@N^E_Cz5>2ru_bc4`kKjLdxH{koBPuEK%2FAad zV7p&=Qdj^SHshmTbOT5*GvPuo5Ih(~@y_G)Xx1_zmJW~Uo&^**nuL{5?xX-jj;FoU z5T+6WN)09OD&%Y&^9D}mNr!`P{zYEQ6)C3jI-fMy_m^sxswzv~u<0WC@pfTrH*_;q z7Q?t3icK8S*|x7UoXLI6*Bim#!Oo6aB|6FOS}vRHzu)Nf1ivJT0o1$gJoh6b*~EYP z9_k^ys67KXQfsV{iKK-Grv}z56S+TQw$k4n*_UWSi#8q>Zq^oxZRdZmP_mwew7w-> zG0Duk`0gnC3i`DEr+2+CmCyD3LFoEuu2k!*%cJmZT6Ck$g}C=$?E|*Kkfs=_;|~{7 zA?-R6zP9(jl}9~o)Of_-|Hd-8DE^+%@#P-p2! zrr0C{A^(T!x~-UJUkmg z=q$@5ZI5jem!MqNx{{U6sdJbDZaucik*U+2A?CzdW6qyRS0F=n7?jPL26!Z~_>xnv z8GXbSIw3C#tw}B~QKC27SN#Hko*1~7G$@v;7DGzpJ@0)}ZC|P?LUUm08TnF;nnOnx zQYH87wY@QeVBH8w{<%HBD37Le<>bN7pi0gRpr0pAg`nL7rx6jZ^{v%Te*k0{)}epJ(xx z7PB-JYuD21u)|=sM?APGcTi-enVNNCe}tYAQHQMS1uV-w?;i-%DZTc!t*G(S7^6{q zE037V5YIuWcTyZX84Ve^#3eMoq%+u(s&dd&7d*K%YLLeqCjl(tVN)+G8GJNx45kz-<0D;Arkb$r>dw!V`Ell|by)5hJshJ1b#AUTeFD4!T#-RbQwJ_7Fo;pjHf( zUMVR%rJVS(`fp+xi1jYhW9ia6y*4G5R&n(+mC*?cBaRX-SGiKUcaI&?(Vg_gsAqg# z_wVC+nNHcSrkC#eNOGP${OX^@A1=qI$*-{T#8MoeEvIYzHRiwOZa$&CBjG#1{wTs8 zg`S-td0KTL^`GOI-pMjGjspV!)vAf|=LXU8IM%>dNs)KrBMqUFc0u$D2`?oY5(#o< z3|O;rzfhI+RHenq3?z;{tIvzcU{!|o@DgEtEe!n8Sc{~*$_Ls1*9Ya*;DV3rNa_1^ zW8Gn+FzPIbA4Qq|8q|3xINq8r{G99Ab)-&Rkk=NWyaqIL1F^`w5n;WdhNKW#167B$KDef957 zk}>RqdW&@V>#GgXpTJ8J&A?`qL);(w#FEd3x%^phA~ zkBUFCOJwe`l!d|hrAl3yC>7>^a7Oq9&sqJhFbe0^l~7tBx5e2jq1w6lctiign!1%L z8~s)&e&9&nBaM8`!?`)ozQ$W5)1(g5w|(o8OQy}SZjmNN7#+%BR{mFy(+9U5=>ApQ zI%EAkic~))c@MSlGx4vg)rT8Sv@g9PliyKI!oM1mi*k~4UPx31s+n^;S7Gen@GZWgctP6Gewq2h^raH13n%IvU-1K{78k{)aeCf-n_B9MDmzDPc zSOrwPyDw|Mjb0>WWpVeeB(h>N7{=NQ>r{2DhHXr$CG+rWC(;IU@RjT_5O}11ZMsvE z;nB*M^^n$;Qk>-Earc#EOM=M^%;ui5q_8HS!9`?irEpU9e!xi@xK?Qk|KO>dY!EXp zr?B|dd&y~cCN>wv%-hD_NUs4LD<1CXS_qf;oT0ngs~L?HLcq+CHjwp4m>-tpl_ZSk zZNzmeBfEEu=&*bq#%Y`S;LGR&J>bOSOH??PG26|anMm?FzdX{${2vMv6Gj!`3#cQA57ZG1wYMn&a8E2uYlzswUPkPRvv+zIphopMblPYeNWgl zbkV4<<+rWlWIhff^{m}N$6mluN%c|rx5XYt-kC$15$Xput6zwEO#@8R$EI_qlN}(T ztJpF;qLVkymZYVTO4^d)E+9QIOFB(gf|)AO602t=dEn&MV-i6r)^CG|q@xNhNYD;j z%{{M|+={l61tE+T-zSR)=t=ZoEw9`=2C11gbsr4cI70^+Wg7_wxWQq&LaS^(xF-e* zt&f^ndAY2rdy@PN=G%#xqS%W2>o#cUL#(rsXgT!KbUtZj$x?lm#CwvM4DD7s>Sm^1 zX_gbjxNHT_YY%B@qV(#F1xX!Z-&M0HwCr}pA#!3A6haV5N=6LC1idC1iHrbAq#(U) z*>;orYfkaJt4V?nizAZaV=xy50b(4pys-x!)VHJo-h|x{F`VZhvm_+8xLA=QaghpE zfm~7)uUnpsAg=qRn!GOlpw3HvS{OuB!6jf;mL6Nh!)mv2N$_b%lOi6fh&@SLA}jvf*?V;mWwO+L{CJwxXqWH?#x|4Gh!k)uHieiN+oSJU;U3x)U;M zMY;iuvOSiXRK|e@8uY|8X1X|N$UTMAP#7E5`yrU&{eXcXqczu%WnaNDC+4tqiB<~j z)4v>Ie0zNjd}FlHtoId+T5))rF!D%cMycz9%kpqP^NFRN68Qz|7f)Emjh5CquUvTL zbyKwOL1P-XCGMt-HYE$o`nt}T%+7WOq-!Mrg+uq8S>2YBU=1ys5#`rSYq(pZ&~o!1 zIObaE=H6pAy6};6o&4GfGH)&%j~iM&jX~ME!w(MYpUzV}eGq<{I@4#&P-;W*8(X|q z+s{LE7I6x0nsjFbI5|B`fiy?^k2XWFqrX(x)J#Nbp9(b7Q$55FcBAJ@tmK6hSQf9} zgA&5zjbrU7@{K!6)udu1{R&735$i02d9^x>rhw3lve=R_E829~0mO>I(duTps=)J# z);26wV26D4z?vSmsxV_^HY2Ie3S49UtcaOnI%xc1H9m~h)o|A_%oO+db+kdza#T8D zbh*;j5&;OoE;{TJ!D_~TER$5U+(F(`TiB4)C+P%~F$9JSW99|_%NQNvBu2|;8?*|x zS3jcjQh|v~*xlgB7iSFQb73+QqxH>1Y5LKJav(&an6*qn!mK67BM33>Ayt29(ownA z2BR!uUuyqAa^=J$>t%HCt|oHP6`xe9j7^HA*QlXaW~C4IAT8$si($g5OUZ{hRj9GB z*NYEEGhu!A8d2a`*`2WW;Xfgy8IZW9lHUkX$YZxP4b^9LTq0YXx8IkNe2&VQbC7B< zksry*_1Sq3bF?}8H<}pMcE4ZM3j5l$0TX4r*+d4?vt>zFNE!ds94S-gE~m|LfLWbr zHJnIsINX9z-82I|nkz4H_7y*4OP-U;d$Gbq*?)1LCc9Nd@jIcz4YQ{hiXj8}5$v7_ zj>xlt5lG;Wg>30PW*%FW0@Z134OY%oCLIl|2O?RHJ!51co0~4ZJ5n|@aRcp2se1)7!4OC;Czk;4tDsr#e)>gHu z!dg8Li5&4dWb!*UVbfqNM#HoTF4)Rv%+0YKDTgCDd}ldPHq)SIb_FTK92b^q9!wA6 zBA>=JXOCH10b7P(v73cr@jy;2u!2;#PTF95;IKockyAF=a|%+8jhc{@Qgyh~cQX#6 z`0)K6#h(dSK3vWUH!cqg%U~U@>tJSH7sTZcPILXQlEf}V(aLAI01Q|;*`;lI*RIzJ zCj@)vatr~dbEUw=`a3poQDgqg8Flx0RcFM3wU=ex0zNOy!M|FLj$Rw@5D^WVzVT7) zM00!bVs4$O{C-QF02LnJH|MBLs)5ga7ahjT_^U%a^NR=KrOX92+i;L%ZCUxTAq_L- zSX6D>aY_w)UOII|o4%%-A}vn(x%rar@yjBfqq}l_uc+sX3{ZCM>4jYsG5CUQplcbM zvL-v2io`oyNZj3X%|hwl6-JynE#ena!M(@mzbzw|IyZ{$8p6eRIi98iNZHEdmR@b)~((ae6|0kKVp zbs#w+(2QV6ESFC@Spg4lCIz=Ex>LVFY~c=w89&!c5m)Q;p9nW2gw*66_}_>SVX}<> zJaj=2FW^m|*CAA1N_f`FM0qH}Y9cwJV?;d!2}7B`vS@18dm-I@mFo#a5Ch*54>0r< zqpCiNUC5a?u3<0#Plc(+a zPua85bC#COwGBqOhmrt(}rm7|@-5y5c%EkDqQZu{$ zzlRA5@|(Ixd1p5%L08!F6KEJ*r!;d-*X8BF3sdB1RMKux7>S-MsSW_c-g&xCa{V91 z?y9NHK5EoBq&S5pxJyVN1b26LcXugLTw0*GOK^90cPOqcR;-j#+?`^jPxJPj*(ZBu zAMCGiAN=Q@S!-Rt$X;t+y*ms|s?K~P3#(0DV#+b)?>F-NFj-Dyd#Mi`1x@nI(^o+O z&5}XhRL4e=QeBD`%}zwt<~^D|=IKa9w40;pAo0GC*97NQcw3jD1Nf(!;)A6 z^2%dxLvG-H)gE!RQ3-ruBq$~-=nC(ttePTOLn8Dv9;1Uf^;B^@(Ug-`Un`Risl|6H zpYzKt^RsB2#~U;F&hcO$;gLKuu!$3q-Cn=@AZ^NmJB_EP zG5$V8mQwIOlv1`m(@$0P&Scro?Qgqe_uEReU5Dg43t*Q*d#D)7N9$`ft}ZM6;*P4- zUFtUP7U77;!2=V2)|-ni`9FTjWd5qnQmEzK3hDe8zG#7U$g#`TC(G<_KKtBJgkxbc zXR@}BX3%jm$5XFAJV~QDny(*pP2a97yGKI=(j@PtdApT11!P~>=%_wAPojzCMXY+F z<%&eI-aW~uJkxuP>8r3fujNV7JzJay*p+!b26X94KIs(w(uNH0u%oB2v}3t?!QHoi z`pahSU8Ho4ePHssIuNRS^iX5UuHraRmqnraRtRmy(ofxS?Be!5PF4{W{!{AU$MAD* zO#OrE@6q6>MvcjUO^g+so3Ewma%q+y_%JvBi%c<5h{N3`FOplSbR6r6E-3OeN)9AO zUZGv3%D?|y9AB*=D$i~s!kOpce#am7G;uD`xc@J``GCqnvTV(;0c_@%CnYKH=A2 zYvpl70EpDPY#ve;2>OoRSHHA~pY_#|A_jOcu_YtwHI!DY*VJq*I&3Z@KjXV3+)dd` z;(k+{3-LQue-6yp9k7Kl7XhzIL}#mX5Pe<6lZI9zVnSE4Z*dhr&!4|AnwrxJRNG+1 z_6Km?aHW;Yv$i;9MzufCd-?74C=U%l3?OUCQo}67*~r zK{uy#eh`*h#f{j^Lj%T;EghmqYA7u;L?(swmZl;HqNk1*^3dwN#eGopY2f zr}e`u2uBCxHm7V35Jy28hNwt?b=8hXsER_ypfc1x^7;=_@ z*rc_p!_HsDR?VqGj(e&EslG5wEFpi-m6C^!TtoI*Yq=)q#c;IhhvHaJrov#q6onGR z%bg`_y?^1;N7j}*Gd8l9(T3u@%>dvRtPo7?4quzePZQF)f$eJ6{J?Rf|Oy-Dv`@-?O$sHyTsxNbTH$de9H zdL+2`nhL?XV9{zjz2fLr{GvVr!_Fmy{lJ&ynZBfBJDCmzqRdRCc4yDbpR`id%$*w! zIIgFd>+n_BFo+$Gqvx$Se@#0!sg_G%g&Z%ZbINI!0C)Bk=fVOLZ=i%MY@YPSLJg!P zE)9Z!txzFC&pair3Q78cP6bUF*_8RyXhbL*1P?YuIJ00 zynh`{+s+g9c%5-~;q`q_&>G@CV}2*g1i{O0x-?ftW>!CG_9202FMQ|yQfJ2M-fvpjkNF7y!#M)z7d|#xH$6DMO3uW4sjF1m{O#=Y#qGOmm$vqI z?U0}R$3}Uf^4FrhT&JrHJy*Mw4AmmO9bCbtSgv)XYAXe&cY@=)SmrdZO2GnB!l?Jsu#CuLicwts8Pj*nIAc;S zW7(kkeLIbxD@SO-3sEx5Gq^1W!eoGo7%U>Na_;@7I9`Omc7V0?yO>nes4;XXg2Jb| zTfFMI(OiWW|JZP4;J*ws6#G9@S-xZp1J(BKIWi!MP5rex5^5byC%x> zLas()IyOp}5wz1ttI0o6#fl^->iKPZx+s2AjS>6txu3r^1x8ENB5c#sW@f18{l*@4 zEGSr^3uts;e{g}5F^n;#A8o-7$#Ce@jZ zI83`KJiJloUj@2uaTLzE6<5yP74sTe}l^_;D}@!Z!%8135x*fSDo-nU?iFIWM-S=#H= z%o1IwI54D${^!(cPz3s-jgs;-a~cIxVc}@9?4*J;ICL4T)e)n~6q?+5yh4b6|lkPH5#Kria zLI*6XofTyZbi}a2i**wWa)K#V7E?=Tj8PY9=cMx@gDD%9I}<6>IlW`;tHm$8d0rdG zB>NSwLN6sRTT&0U2s(_Qvd-%lcS9ZlJ8AeTHwLy6#<5WS@dpdu;Y>Jjt=*&aYU zp>XVLiws%k`y|z)pf2AxTg59otaI~D-|clO4(SlQMYw*hHp4W+(y#=>s#zh*V6+o$ z4Gi_w*Z&LOiB}XFo6~})ogUa0UlTFcv00RHdmb#?VU8Jmbqf#97Yy&8<<t9aCWyIkK(hs^$)M9IE{2^JNlE19nFN7{-)xmX{=PT zd^T>KC}Lq4We%22NtWd8vZ0|7V*dJX3pZnk-Abv_7X`E*)+s3;h0_Of3$y@M{YdOY z;U|P{z1FRoFFBek(XNSDt2W8>Ia%C)ees$>^*So3eZ1D0R37QtBmly(@;3v=l{j96 z>>M#1HHjyZ-7eK_3#*GXi>*2`o@ybkeM`|F{02NXqzkrL1^KYILTD2@=R^W8r9 zx{0o)}JnZL*cw5PU zl~C)|XEYO6D(&dsuHI=+SQ0S{1&{GQc!9g)^d^1PRkjz6vpoxG=32u+{~=F>SeSY^ zO21)(zkSFmvxzc`nXGJ_;xzmmxH{so5^=|vO*8k0E1#GUxerkeI7XgaG+T#(2ub?Kl?N37_G z7k12LN$D#z2l- z3uJKKDVJy8&jm35N`aJ~;Q3(U-R&`|<2T`G^eV@op=tmT;Kghx# zRr-eb?Kv5O7`K^gv$jlX*c@d@qnxt} zXAkxnv`T;_A;``U7}cq~#Kp=Y5ey~8{_;l>yp$TdQa_t1Jh96PwcVT|_qgr!)=uN} z*i;=M-j?N?OSv-Uf;@3KrgF+>#)uSpGHP5??~K5NfP**y3Q~yZ2A2!}61ZB^JtCRG zwE?>-Z1*n{$_TeyYKwO%fmHA=+Yfu@sb+xCiR~@eMSF3G1@e)gvmNm5{NRF{`@zeLv< zQ_}m2CDx$>?8)-Qo}Va*Xa_+2*1?khj#>XJ0~HU52OuCi7Lag=PMXBg!0qrc@ueKZ z07nRHsi=vk4d8$g=Qpm!6BuH%v~CL=xL={4q^sZEg(;T;9$zyn-wM2u=BR2BY4^NV zErlPnh}>R;s2&Q%%2Hv1X)US*u&tHY8M~jpLZlJCGXx#1rRtfAbjAM=SsUS99tUn6 zzK#*a4=wa|HdRtYiwR}~n zD95zxEkdJJX9HiF3)|WdrGj7Gn?7PRVUq_|dj~NlVn6nR!+9~sFDZ1al>r}z;9k$p zZ`Y(p_oy6p-$Xil(>(vNKHCFT60ooll@Q${TFWQd@SlYoO5^ z4x94u@?$E{0t9EOh4-D`>k9C>wfbX4yu8hpQ#-bLSyaf#eai^(L_ej=3 zf!^_+ApYDX#6)YU-CByGqFBhzt(tb zhf)ST!sfP%Rb(txmEl!tA+^;G`Za=fA(Z~ndX&VVhQ*qzLh?>#A>o0} zSeH0JUnMOgr+*}2U0+rl3_yMaxGXv2dVlpi?A*pGHT>v7H`FE@E-$3T(}q% zLCCZx*qM}-eSCCASQ6QxoR7@q#UBp|>Zm3NU0N-TwsY}5 z%B%zx^Y$bdinsz6{2+ETYp7{O%-o)9#v(T;#(YQ3dtU!PK^{l{EI<24)&UZBuU4NL znNC;@14Zq>z^CV*dKAq^*Hul2GkKlyD^Q|Muol2te%D$!%(c+*W3sQ57&c4$gXg&v zTFt8<4Ni9ufZu7w11a>yys%AZDmsXZfL^xShH^B}?fh>rtbxB9g3uiEU#;7p&9qBk?UT?0jSWuYbJdyvkojviIV77F! z^%u%T1I9Dk|9aysmTvvf+=KzyFiF7p)>F0ay|gO^iy;FlN<011NEGBCk{n_r0Chj? z<}tFRADZxLVhG(?Y!2jdEg&{nU-}QBqC^5J3t+W$hNhA>Y}s4-D|} z0qM(_@G7HUxhKtf1xHU{mA*}jKqvuX{-L>~bJU6s>1B*A5$hkH&{IHT5ob2upIRUr zbD=+@a+)svkU`Y=x}PPgH_lbIHlteU{X{|2wEx3QOFn9 zvO_f9QU1xyiuo`X4dug(LV~h*n>1isCgP*5ZCZ@ZOjHCLAbmYO@E?S!9v$-|Dxdn4 zZUfH+>$inVMV@zgrR6fO;G;9|zX6OE3-@G}j= zuqYcKo{yO+On^G^Ret!K_MCMtWG?>uy(_DRZfbWen?5x)pO>pb!^)%H&PGGHePa(x zRbh23vN5MoqO=D6#*lWVpLM=2TCp~~F=i_8WxLcgVZD|O$R1&vM0Tz6E&!FY&S7&VCWxlf^^QhG~# zb5YET?-23x4wTY=Pd}H}nEVnPz|kI`E&n9Taoo`o?bzeTAEb3eo6*x%WO5O4*F_)* zi?;2!G4Arn`t)T&(IqF1F^L<7k0PkB;9Z`+>lN0rDt=Gi(?dirawwDkS@F;KG~Bul z8L-HpO4cY+(=9=M!WuS)P9nSIO=tQCvI`rSq||n;RAL%k*p*=&mYF2-4)&A|pVb0PD>Hs?YqtvzJn53J z<46`pATXm@5tryqZ*Cj?A*bq#_H3T(r6_X{y8I-RjwjkhvfT1x((CU8#~wCeTePYU;fT#bz0*t;g*X6wQckH3Gw_J34D z9=@XgyXyMx({GSq9g$|DuqXnJemmeD_AhqcoT~x=#^P86o6&r#p6<{R-OD#brcy$t zB9->gqb5zp4tdCSE;1QZ;}-_mz=o?iI`0C=vTXssoSZ5wWTScwgayIe&4R7Y zj#o6yPY>8#`mW}vYwMsN#lwe482<8^#7+E_ly=(=#F8n0^IvYR0|%_wn8o-%*HS(m zfm(VBaVVA1gj$WF{8)MopiX7ikO;C{GiuwqJg6f54I#a+x28?795p!FbsR*W-NUKK zwx=}WNd9}mOFHn5&-b%v%Du0NQ7{e2diRV`B}9kN?C*r!^Y~*HYPj@bo?Ofuw_|eu zl~2-T4?l*u;9Ca7^E(LEo-KxVVrFkSXF*{XU*t~$n6c#eA>N~GEeUXBcd-~nA1=9z zyaO-m$d40i)61gWjrm74tm}+KEP=wdii(j`!VowF6>@CCJA)zV);AY6a`7#%-A(bV zYpZlSY?tK28#bm|PN6J%5?qGQO{`Uipc~Jb{}_TzT-B?bk_v^h0T`H$N{wb2jf_mU zm28NS1=4~O@!jtVy%qS!G;lyT#3g+oZiy|-H9H5pt>ShK`m?W$h>U`RR{1tg_-j-P z1nqqd>u!EBQ`&cXOG%o_tMnsj@Z&{f#v`Y@)}n@Q29NHbH;T1%Xeb&kg=h?C$w=gD z%)f83xWL0`1S~ZD4qP^45DJmN^cV!)$MA>OQ3-;#Hsfq?dJIXVV1?ai7B+OMKWBk> zE({Ap*+|i=YOEMX14nH-C4C{2KT9|WM{j37`N9|M>QuKk8fT)n^-_UQU2YLELWtG9 zdnJvIflgu>pK0|u%r4V8_L%>)vitQ8xO_^Wc{`Hor*l6A7nV958aWed|GUdCFxnLEQ<-}I`3r*gW39Hx-YTYSeG(l6qIPM-taC}<;X?ns@PK-^Gu%{rshsfXclsHKeNVzm8 zqo8dn7rv8C&>Xc8Fg>(ptvpHl(C~Z4D|k-1i}C}JE&@(H1x>P+m$lB(s_3DXGS>fP zZz&Z}!&sno# z`o6|2|MHumS-B(z{4_;PFDk9Ff?am6wtnQ~w4@e;-yF59;<&N`_doKwG|>kfm*x@p z@=WstjSYP@$<@KrM9nA-we) zb);)C1)Wh9j$T|6tEaZ49x*c%5#C(!9+(sPyBlbyxgt{L59fQ&IywqId}sP-3;nl6 zr46y}Syd+DLSzGkt}Kk;B8+3bka{SQVRoQDj zBN`{iPSjLFBR7-$oW)pkJFRsvK3rToo|od5g37s6ASqyL@ikG-2xTbDSI{?y!kQ}O=%5LZR0iJMDTOA|S1(`Wv6(su{NW5HzzksfVHgtft6Lf> z`=#VN`npZ)B=Ng2?ud6BHT92bThlf9F~Ta)Z{WzLbz}+ajIPw|*6* zmW4zcIQ%8Y@Mplv7220eA=w-m;xx4pQXt_jcG|eRZnH?@e@1LFynM3b6wkUpF}P?D z$JHF||M@hVkL^_qa+BhNTQ0*s{QqEkuekAu;z z@WR&p$~MU$L7F`Y7bu2^*>$Y2c&Dis-_ovO7gs;bXLC96ZiE!JD(t;gv6OQ3NTfFu zD>Hufo?8xh`=6r8EQ`s*DMT{Z@@Vb?V-^baJPK$tSne+G<0wf>d85iXQ2aiqT8>nMq>_^Lu@ZB z4>&L@uiBpC%XFNbVkv1s5{(fScrKM9Ag~)o$_`EPueDW(+b`V^Twu=oXm>6yEo~}Z ztKLc!hs~9ZkdPkB!r9S<2%&v}Gv9FnpTCl<8WvCX90x=RVX;U^&xMt@F;whtaAO;y ze3-VC;Hs(6ES>^7jW8w>e`DMXCL?p?k3isp4r)z}!0%EkIHyK;rS@Yf-(ys!h^58I zqSiuwTM@knd;v+@jm!%>=_388$;;|~KaD3!j}_PUFshS9&4)itid}M@G+{|gp>^m~ z1R7Ck6nHKcG1_KN3pq5&!^KMA_Y8LHC)!213|ZD36`Boj`M#w^S3Yl@faMfDo)NmL zWyW$^t98X!RsAy0cLiZaZ}&P6^xG-M{JH<7tgVUHpn*P|0f|ILA?s^lyk52zU*@%N z>U5tKW3yBikB#(Z3X{RUtRCK+_0p?=uIgts&mqMwealL}r&bah)O=C&{}fMmTAHP~iFP)XU_+y=q;F$6i)FJC zFLu%CH_&*?9#UYf)1KcYdWN`g`J+NTFYi2rWCMoXc(;9JtQ{sw!hJ_>Y9(XuKPpI= z>G5CsX7@3{z?;Kn%~{2U&#Tk&uV0ZxxjS1+;zt#0d7O5cQ|w*rlIm7M-$dQx65`vi z4F~E@S$f$P5O_@&V+>!t+uJk0JQQ?L|C`k5Z)6Aj)@2}Ha4Qv)$#|l*V$ywa@!^fN zYWTur5d&9EEw?S#k}%VdNm5*@$?cSOq(C+LOq;?|eQGuYWva$x24d!b$nKO~^lt@~ z)dc_LEDSZL74}D8^{8HZSE-ryZI!0~Y&;7Z!D9*T$Ynu8rK`0I zyNbGQrW<0PG6!Q?^!#njBiG6mfAxxVnVfAKGoU+bcG;C|@AcZUa;GbVz|vLZF(83) zt}Oh17tNT_q_XTl@*y#$(a@J3Xs0+p+kO)DF5fiQZAvD>p)4;1?Wcj&HHjcm@vasQRZJVB)1%CNF|V?HNV)BM8{6YdM-`=Uioq- ztL?7h(58o0e!mc5Ji8$DX{uXlV!d@9I#ifFaT6*B_4FOZLcyyLadE1umfljvh7rreiIvF_iv`)B86e-m;j{2Nr$$?Ixm-u{0+^Ily$*fXZ=B!FapF^z=dn9KjsEVf)cxh$XlgF+^C9gdWR^f`OLNCcH)7 zmoYPZ?>=1H*MQBy6w$&-;RuGp*kpJ7WD#E9s;o4#;65ZDq_G5rxv|^z_^8`~yFBz9 z!z7?eqqq)*&^!TZ%&;iO&dU$nT(k?t0e*i_OysB^gnw>@w}-7t@M@4U;8S zcEosiLwXP5UzNFaKgoPmU^5n^9CfsY@0!7v4D6T^o2xC=9^=th32I`j-**rlWyJju zWSm_C=EB%Gt5^wllda1^lBCuy6$x6Q!NQJ-*e5BbrF0hpWCf49Xk{NqmI8iP$Mwa8 zBM6vIt*G&w+?_iu9${8EOb+UgME7Jq+m5U?Qw9^-{&)KjG(8;M{UCDs_x~vZ@2i}c z5!#t+z&BIo1oR<5uF!B)x}at9g-l^+48pvjS)grO2n-7QSOx}PI0ke{m z8r&)Z9VG>iJ_)TPOylOAF&O$llI zAX#w>@<`&+jJnh`ED#ze04;qQ7!Y6tLPR<4=4!}?TAt)l2IMJQ`^dmRLDRr-?zbX4 zw5$On{2AIxMnL&j1;q3j6vHkyT9lpG5*3jeT&P(Ze7WUzyzS(yoIN2Js}V(x&_-}7 zyAh0_C!D55?=8R8PXwbM1j>b$ZgV3Z#emIT6(!x0UHFZ_b{a|AsLR5-L(SvhlB2~l zaiUJos3xss)c-5$lM=~AECa?V(NAWw>lz`E6E*^LE(e6$t(I`Kk|0}2E}B+`@My-* zH7nd3M}}dKY3_p8Qia4Gatb{_q8^44Kv^lb&a7i{%&pOShsn3ErBFcWt1(6{xsn6k zVm$f~kWFsv1bw$apa^{_HXisGetw32F9MxmF%r544u%$itRE&nDiyI{T4^b?ivKskZZ6a~YL1 z3!k=!SRl$Q5b@Devjk6QmAtw{s*|EvWTf3P25IQEo(E0sFuiRRCTJA!U@9WEREmeC z0r1hcqb0(ys|;KB0WF`GT1o<1sopD&RHq-Ga2Z?I_Jva0thaIJrqW0`5-S$ciLhdy z2~=lQ(o}*hSlZG|iu~SlZ!gu#*XdfRbmro+da)G$D+Zr#gETGuCECTrj=5bsh<31( z`)XLvrVvsTq;V__0f64z_|Ai0L}OOk8_{@zB9ION;O;ij-ViCgSKcng0pH8E`Ktmd zC&B19;9t(fnW-KF6Fr-=o|O2mW#xWMRBVl#dPy()98MS$YPt9;P_TYY>jP2OaASHv z$w+R?hDi>ZE@e=w=pr|@oN#0aHj8E^vX7uHek`^r>}~6hJmAPpTSj~emQ*jgRex^) z$-mG$aXxTo0d$tqxkUlGKr6x1!r|5b_iNu)(AQR;I`A|*boMxM=b(e%UtJ_P=o3$< zB|<4c1)|Dl=$2QzF6kYO;CK%RgNKUpOyxCEwminy31zZ+I~rO)b;~j9W54dqa^z4D zX3Hd#+4pEbFUHpI1(pqwYB%G^b^^bp04ZKWHpquDTbz3ND>NY4T&B&GebL{A?MPI5 zo{ktg<0;)-K;oi6s?QTrxRmacCe&OLBqew@E)z|tlNwUB0i`kz!?pgKjku!iVN^l+ zpMg=TK=nLO`FRtv9T@S)BDfRDCv;T88fH;6GA_7e1k2Yd-5l$ypFLP97xb8R-nB5w zqhHpu=KC{*Mp1`Z-xz4$(`BNM!)ls~I}`VZV#U-Lpvu~4=sw4 zq*8|WpUVWip1W`Xt(*)=gv|;`=d8PwN6r+gzhW!&|Kg8By*|}Nd|>?Yx@!M5WXIt1 zcVhiZQ_QL$W$Srt za+-hQ_{xVRF4byU*KxrMWRGUUKiaCx^hcey$~c)xVhB~TYKO;69%gM>~QNT)W zt+(-iRTgq|OCk^q3bvQt@q(wXGT#efOKWa3)SeBj34P0q)+_V*pZ)LW8L;gZ`XfcpW~^Jttse-r z2^S2wd#aqRY)}uFE8b|mXl1ngH>nTZtaIIDcA>)p&AW27a0Pu!za8WKv3VK8B>{+G z>6@Fo-*{s-RNVJz*}Af_T#>;lsLlMXTg-2_O38ly9@xfHZ{10xjE!9%pBXCh*?tp{gLesg zPIQEcNOov5u?{B*8~#MU*k(%FeT*IsM^s=+q26LGEk#bQH0)RpF#J=!p~0c*o1nhg zC2T45E43Yc6JS1De;q*r>0h0_RC=n*aAy1ibCP+Eq{SG+?$>|$Z56v^X%5n#>to3d zsCV|Q)DK7AZz~6{bDJN&ojc5^o;gZfxtSW<+c?~)|ITdI;*&IFW1bngYxe5d8a(~U zG3g^sQsaLc&3=CykIiO3^*DVH-!EZncSJpjBoHvp2Th4KM9ihxjgUyNx4N={ivO-- zd@R^2VTE*eApvLg$7EyJfxSGAxkJ-v#9IZ{Gb*1zo6x@lCW_z;}x z)3U(>$-a&UGZ=6V2)SN~mcGUU1LuQTRiiGaoI$^~%-G2;Zrnma-9#xRd+vXA7F%vF z{d;p?ZV7|0SNn-}F4wJ%P$u>!^((GN24T{{2RJ5uO)cbnkYCI{HTYOEBqZ#>SKX!~ zmj|zz8)lI4J!cz=I3qI2DVp>5%Cu#NE?|P~lBzWjIV}xOkqLPdh>C-d_Gi+cgNMe| zbAJ4brc0vXz#G}_2o8+LgYMI$_A^25dp-*g-}x`urb)&ceUZl22vp4!(9_oLJ-X&I z7X7|b6AG>S&9}5CLFp>Pr$=6MT3NSQe%7Mgq;5Gh(SW>Um`(l&A&mgd5fpGPlR^v7hM{S8%Q0)$ z*&V@xSu~a#eXUf?5b)V>`NqXGTqqKW4>kT}Nl=C%la%ktqo^6LnMRV&xl$`#V_=Z^ z>q+NKvB_dQiI`0PSOaRSmaF$Y(?vf@YLh^fGYzJVcy~ln-MiMLF!1JL>-C?tYpX#r zD4o5i-#eQUQ`}ZLMez8>wNGM)Q`)|=+oA1zB%`ze~WKSA!3p$#4?@a?adiAc@% z8=mOZGHglWy6*^vMN=xz5;pcFP#IR5^3W8m+#mK*s82XIGa3EcrFQBrqBEuRFe1gz z4506C2DqblYiBYV|6qNp#F0j*h948Ls&%2fBh+Ae=KZW75dcmbmh1o!wXovq{Q|%F za_3phgB#NZ`>(nEbg}bV#7TpmP}#edjY}<&Rh_aOBC@l>zer>WHO=fK>6!2Aa`xw$V^ z*m@~jo4fl1x5E}5UW?UirrkTX z%+$Fz39LvoIR@_FG5HN%f6t>ns`b;Ddx{jk(ZdUU1xkFt_v}xO!FY!eOIPmL zHH>qjE{C2!i}ENi!T@!Gqb`5`f-xc)Zg}kklikoXof;(vXvL(ld_`_bPma(}*fS~q zS(0nCBcNvVV3i;O6H@OIlLa@4>bA#W61EStrp(g=%B&20p{P{iQ*pAfU{6_HdFH?t z#&@c54z0HQ&$e1|Zkx1m>$+iLzWaiTMhv#yG5G|i`~KdqZQBw&6+2|HQjfxEWC@&7 z52(k&J^K|I$490~`8+?ALJs-{#}!A5ThpnSZL1!tl;br)?4ob?fF?P;3_Y0Xe9{&B z-d?kDL!OY4{Fy^W>^x(6me6=G;~qTi^MDwuDy~!I#GlEOn{xti;TUmtX^%2em&YKc zlz8r)5~1blajML24#%smVIFEimS*O;IJ!M`ea3R{TiKXoAOHybzgfJd|1TDAs%3A; zghuB7#o{To*-!cMd!25QFVV~wNxGs^E4NoKmMNye&1TZ+)uYAp{tt_1*yj9WrlW4H z$#QhU1^Tf4wbe22xAJUfgNlLM-b{f?SL2U9|GU#4FMQ5hZ699Y24j)JjKV%*Mx({1 zdnlL0F)-Pl8?+wG#^JixL%&iV&KJwX)2InIA1zh?+b0Wpez!SOZ!=r?W0B9bAy=+w zkeZBt>_>k%F0Fch_s!mv#^K-}mY%z#g))^Q^&d|6XX^^DB)Y}=9(sJnG*XC{w?lz6SQZgP z`i>=re~A}1BdL59v))70j(1`pnU1@$u*%~f;nO!=Yo6QCYHK5mMqL|4*177vB+&=5 z)EIFL=KU00SH*pVVy&#Qw7?;zb*iR3^Fg{Ud-`4qH;%tuhH36PM9RXK`7qm-aUX1< zky&$?OXxanpX)O5jXuA|&MBq92(@M@4F81L!I=Cnv!mL%o)VMsI~w8R(gYkMN3%Ho z8KOeP0%rT-)LlWc7?s*zj+MnxaOY~yB;%vi{qKlCS1(3p(+LRj6ChLuW6# zZR}MpdzfP5-Ex8(>wpcHyW=kX3Arj)15c;>E`xvc9o;_}4dY&SAn{$Uhq0IvcI$8i zOn-cOVfS6=$2a)L;*mMj-%L>Xo!?B-MYG;cL3j>k*e*!+4X0VV&TnVoqpWwIdDk{m z5&TE>cXMDRD>516HS4d13MiNHu&e>4$C55sZIR@a5(=TE_$w&iS3`$H@?~PzR&8Bd zN4AG`@jyy~Id%`T)FE4we$Vevb5{d9sX9oPEYWDgCKB=y1{Cz6)YUuZwyd2== zy#1&G+YqZ8cTA@74yJSw?n7gY0zlV7xxt_>0usEsPg*?2WOh$mL@*B%{u&}x2-2SZ zH+p2m7I|}fDe89hpGHrSyA}Af>x%y6QUzT?`*4(|M`fUr2;H$XK}h0cH4p1~_Xtt( z4In$hq9Uja#s|br`{O65XG@pG{w22j$g(IMM@Ke{f4Cn!fny#BYPQ1!du4eHux7}*W| zlFk&N$dYXTSc+eJO^HdnKj;QMI-c=n*WWWn2pnY_M_z)tuMR`SAC$NF?WO~U+h4o**nF!lGsGp54 z4q>V6sUt!1IFUZ!hF~g!Hx1sLk6?RGPH9G=kWMzt$Y*4&MuX1DJ->Mv38YVPazi5^ zU#ygIR3gOv?U+FjTBV-EJO^JSluji|7CxIs&cB*&wA(qa`ut!tuRNnujHL!k2E>s^ z!Q0s%KUB*yIdcXGr+ZGdf(3M^1hJMR8|^3S(H2h)mN!;1Pe}Yo9OEO(&)>SV_M?l*SC##slLq-x8tb%h*GW*DES9j~MDu9#D$S5$*q5B+TF@}RdG}k&e#0!FBvFaEE@)*Vx8$RCx6 z`?(g><)si+#QW17^ZTO^92gYsi3(3qVHs1W)$SuMmH>)j0ER~>vA+@9BVj?-N5sv? zdDJjUEJE6D0tgu^GmL+7QYp3~6k07zL>3Mje#<#UA)pv;2vP?NYO%!-mHBZ>M^J!Q z!i5FdS=NCNvIyyn@Si&h>g)7c)m-+YB;B?VtK8vUH{ppqk!HLikD4frJCS(dky%zz zWxML8{t+&M42S%TJxfvi!<@nsFxzV4OHvM1K_X)^g4Jl!Ab&RPYkf1hP@$+O6di#a zfTftfW*1U{C?=iPZ{35tBnVA58it722Mc=M#MGA4R`^+G_z2RkhFWn&j7Z1yu7>Br zqETMCz4ZsT7^1YU#2H$}lQVe4WYeYzGIV3cTw#N?}CeW9}8G%CciDFE-;>CZ( zPs9KRo@mD$*;ZnRcJ>n%yAub)oB@EuO|qn2M_}YwLYh2C8{_>REPT^5@hqEQ>nX{J zEAdv4XP=2+VG{UDknDMiVY?gl(#=J^o=kd|e2)d)i1FpIO6f>Vkvd4BCP)@7#mPco zT{@C~^-U?ANXa8fktj*JLq+&W1x!_g->*Y?st_R0)NeZ;Q>dvNC2F$WQi_6 zGA9JyBLFr^p!!BE(UT^@$BSPROBzcml><^>PG7K!`-(`P+>x_ww@1UuKqAt>C5dA; z8M=#UGA-%Nw_fRMW`@%tlU7MyvUa(98Ln8Fyjq#4x880-1V6?z%}}#M5MicDZ10&F zy{6Njma_Qhvu}u{La+s+jhu~TvQPK?336x?u$BF5$YKLLQKH1+^b<3LM6A=p^02c- zZ>$Poz%nHfF~_W8BZ{JLAVf}XElV z@C%R^T~_e^Ci`1x;ofuMs(qndNujP(5kEswnpgN!0O{1Lw29D68oQ$Fn⪙#TbEH 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

    O94)gU8|V4zeT@YUeZ= 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

    A^XBqXUV+YX`xjs>7HizD5x+LA1{;8Y6ja4usV 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�V5Z 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%0D<+^A4JNr& zY|U0}-BzbqK3YwX-uf(GHK$qJg7fSORgKMy_>XYKPqEM@rBK)ENj0K~CP69+pHwE3 zxP{i~iZjI|j{uVD^0fElR)alQHAPtGn^lAD552mGT`DtgEwvp5$y6Oyo?ycB*-@Y9 z|CostikpMh>r&M0Jk@Sdh|lqflZ^<>tFCg@5QK;on;BP;{m^!8RfLGxp5U8I`PfSF zS%v*nk?q)^E!qNz1nJq;SX@$|L`XzjM{K+ljgjk^~VVEfNX|K(r(fqQmsNb9D=^+6kVGGfcA>r&Lx!W13V` z2xdhHOoK==z!8}dSdCcRO}GV3Vc6ue-FL!WqyX0H;a%y`T~{<(;hi3lXobY<|3Kr) zSJSBr9wd^ZC?iz^G$5Fnt*`}uxL2j9onJ66;tC$5c@yIzjnC;1i8Ld!F^|HM54w?> z<%GPg7$Po<9U$}xHjxj1_=O=7!+dq6CpF$5v5>S1ov4{a%~Kfw5h|jKn)|Rrdytx- z*@^3kh~y<3i@=WtrV*X+j&tG!+MS8g@rbnY2@UQ_AMv9MNlK=98~BKwHd(U5W5~v7 zV3-|V8m?g*?zT|4Vb^>vGC14x%)$f7DE=sbCw!As!;ZZP0#^b61+WJhxU%TU~>+_pp*#(i7z@L-~N()j1F)Swt@A-0c92#*$)!=#ThF{{SAuq#>%D zMWsqoh)=uuLc5&e5=MaVNHwYo5BFGG5jm{pgjG7Z2f*--A>t}k3p4=ON>|k-ortDT zDW%=Zy$z zX4gA9nTPOXA}o?Ix(Jr_;Ics^P(qrt3V>ZA=Zb;o)=ZFdvYC_B|LBkyvob)WhTa$v zAxo}lhcX}%m=))orJA1DB_u8q^oeEs`Wt+C?aM+1esNsnbv@Av-R)$W#$XAe5 zh?o&41c@)EATF@bS<&sgZ#E=S+K&DQsKSecPwduZSt^4~CIE+cxBwY>*y-h$n6XhafUL9$Aejq3|;Va~Eg1+tVJQka>w{hXt?g(-$nR-OsLuB1pB-kOFUUA}2cMdox% zZAtO5P&MYP&|^{a8)v?WR`|k>5Ts~&R^-B8j!TN5QI^rZ|0UIx5l$eiGwYGmnUEHS zo!pCQdvJxlgj>lIh?%vBG4qZ%X4j0FnUGK&aD{e|fUkjC*x87b4G;<8341u{oQ3bt zWxmr^Z4A$F4R_2ik&)@hEMeljB~$2>?NyEun$ttOr3eoWxftJ5 z?CA)Aza|`pY!HGVgL}9W^^hFS^`l>K3Df!U*m|2vdZxC;Uh<^znK0gw=#C}Btw07! z4bgGrA;2W~|C+a4Y6cOKHsL~qAf=A{Y@J9e1ORr6 z?@mUGFXFnBnW1nIu^dh)i7nWVDG0WQ*biHnTrtn=Rw(PztRz-OB*T6kvB_V%IeI*- za@g^unn-|W|7IyofF?u;%O1LI#Wn-mP)+0yP&cV`d$_|4!dmiX@OZPYw8Pg;9YQeBOV4=nsm%&+yP^ z(b`q*>5qQx-+u1j{p_dI3N8Ln-TUq@fAc?osQ8Q%byB7^ujA`wMi>8u#Zm8?QrJ(o z;{X1F{WdS13V;AmU?9PQ1`i@kNH73FfeIfYbZAf@!-Ewe7QBcNqePAo8*Y4 zCQqVFsd6RDmM&kyj0qFSKmay7j)b`>r_7!{6-wM9g(b}bJVRg)2AX+`48b4!p}!uid?H$JPxj zcrf9@h7XraAR&o_1PK7-glrTr|3L&3w~%SL=^rV|E(NwxlGkQjzE1%#H0`mZlz;!k z7VvEFacq}TNRi4+u+_gUBq2*)2^F&IAQGugO&ynX?S~X)(@pv~`NpZV7otvxI{Uzp z){V|~I9>Aa@7;mtHJCIxckIeXPfg!_az^xPJ=>qCc4Kh$?cp!CooY2vcV2u2SXPr{ zJU#Zk-%ydj*yjV@)@ncNB9FW%wRqOETHyN?bX)ByYd`^GiDt1Q;812ielj zXcDx7WlCEb)tiDhZ7E=i{|Vi-iEbe!(Z(i9%Eu8yw8?fNnI#fL%0KPc(iw1Dw4&Bq zA0BxULtBtCkxgU>8WD47l1W;k5G6|KSW9Vorle>#M5&|4Svu-Xp@K?kN0c)39H?iW zim0luYIx91FMn%lcM;sve^+`lY_v`ownZ~ zI&^1yUV}K<+!{?d8q?F_x^{_oa=1WD;2>GlyD+h;LQC10Q^o2jA4%P)3o`3Mpb5M21y0O>nRj z2gl|cq?|Wuaw!>YqI^?Wu8wAECNFQ#7Qjv4icukYzUGW-?V~* zWUzkfIFx<4yoF=sYqEB?)Cn0%?|405FkZ3nK}XLqJ%NDUiYz_Q;I$3Xp^n zn#>?vC_o5F6T?=t!#A>Wl$K-#E@lNRThUS%vX1pGPeCnR?7ADZeg(#8p{!I~G^4nF zRV~?}i*phI0*A!YI@zrbEjK~hfre(TySb5WUreK_s_3a;opCe)^CKD!IYmSTj9OPC zqZgIsE!T~)Hry&!tk#I2W7*D%t0Gk+hjc7Qic(>uELW!>)+|v~3sz=CrSNKL%Uj~I zA^bw$|38M30Dv{BmkCJ#L&)%tK>dS+)l*(Cnez*P4dgY*8;C6iVzTWtXh8_$mpyt@ z%mM_8i6hyjAFlmyt4rQ<4r5RX%B$ek0H|Z(($%X3VPnoPX$S0 zGzlWbBvwWYZ#*1od{%Br~XJowaQyIPZYGRv8QcgQ`=nK z{}$KmWOGDj!{$`oiq;@yEo>EX5&idNSJm5ptP zZQE(;1Ejke>QZSdQhw|h9jb9PtZK5WfCQV^tK7~)p|h)3BYRiDku9%>O&e8mNfIde zHn_s=2^3SR0RN%z7t`v}KyITmGcm+|=X@t|1{eT<73CMrE!jYPv&61$g?-$O=vszo z6XOYlhX5F1cm6?!^9pk)$1|pw%v1n@YAJ{)OF%0WFc1=sPQ4>(LqPyF5K?Fto?hw> zl_-djR@lQk_8_o4TOp7nBp93#9@WESchU;Ah9I1X?=O@5PoDN3+YI^5z>=YT$iz~8p|wR(#YUCP$x6FJ1uIl$*$a;l$8vx zWC1eBhjj87!Fnz-{!x@-4zrb$Y-YQ`u~}A@7bi(sWkNP*lc|DpnR)!IKRP5qh+MOj zzx?G!4sw=>JmZ@anMrT`L|?;QG^2&vsEOL+9wug@`J^y~R%n+)QrH4H&zAsU!t+Dt zbTCw0fv_6u^O~a_)M3ecPWWxwz1A$JG70$5?gU{ZBODPrMWW+&lyy2u;PfqwIvwIU zD2TveFQtWYX=xh89*x4>LEQ09$5dp1`u*jb?kh9^bXZ}nfhYhrgH1D`|F^pN{m1G~ zFb2>|rlr}RkR9z!VwGz%~VXnSU`rkiWzu4c8)3XHFH!x~;2UbomD9A|*b z+Tg%OILomuY@dsr;4YqViJz|HhSOZcZ}*=)GEQ{016|VS+SbeJk#l<6V{Kk{pQz0( zsv{3w>0&by+l9PFq&eN}s9d(zod@TJqunQq6lb*Ek>P@is@hPww->Q1Jh06i#SbSV zo9E3uk~OS;N`$MN2dHQDDHwQgj@ic)c14YzJKY-%7L!0&0#f+JqnY@pF4>}F4kZF^Da;w}oFkkK02IUAYTDN66S?i6<2z;FD|MDxjmFXyp-G+81|jdIW3fW|BPBk5L7#y+6~o)nP8UB zkr&%NOcmA~K?Dl3i5El>kbmvkQ>35DK+|IoPtc&>K$zNd6aW^s-TJNJ`AyAn`Nn#* z2LPBFQ&>d+^cp->ljK#zqfG@m?M|yeUk^3MNtx93jaq(H(|7nripg7ZY{EUrVNKZE zffYn+Uf}f*8cA;1Vi(>AX_1YH)Ro>a9c<+m!5y97 z>{f)(2*piJ*St*vJ{Dp*6@=WD=r|+oyp}HV;(`R@F{0Jrw3dt1)>)C&+a=cMab4?t zjWmjm+^Ch3NF#kvif#ejHcrxN0RYfxW5akOa=;DB|FPpRmR;n8-B+PjJCcZWjD<0- z-M~E~PkfeI9o%#D&JoVV-Q|)NP$XGE5z+iZ8O+*z8C91E#1j3X|7gdj4G^~hM?y`P zbaeGJsRnm`y6L68s~Nx=kFPyxu>^0gPjD4~2on@4unJrv9UsaQxAlTqH#iV=%? zF=6cu1ScfaX3SSX1i>$Gkf705nGmJ_aK!)tLGn$@@(~S+{n&>!4?L|DXV`@I72i~l zfySK5zr|2BQ3W|6UTvJ8Ky2buEZBWzVnn&$L-|>D0*< znogV@r6W2fBiWVG)g@#gjt*&6Orc)j&_ScgF=~YB7Ne#O;mj6a31De0#p^`Oo?cee zMCiq#9G^aF@J!@&3YXknr`}oKPEJ}xnUDlXMEmT-6!65m8AMZTK@v&P6yT~&2t{|u zmm&heh&-9DCV&*+>YccWR&0aRQy0I`f=JO>d+14m|rf$ z@%SpRavBH8Afs%7MK%|W5zDyV#1!}!Y5xF0u!1WAJw*UCg^zXzW}GWel$-Y z0#NHsSj8s5q7fN{Q#{55YywO^-v+G3!9K*Wp<#|B&^j(%nEp(WVTY-j8L&8@vxML) zr5Oa$Qqv(^9tBRqSrUCnOV2zR0s4`$$ZYtC(zg(8Ady+;a0(+)(wIS64btG99WB&4 z=eIEJQ(ep(<=>`sl5?t3n)POru@MSpptDpUY3Ny-q3xdyEpLXPw#c8hG_9-3?cDl~ zvcQfe;YCRR#_aHf1T0?ySmnwvjKpxtDuP6}RLafB;cq$jG!E%nWX* z{$6xJ+xr#n$*c{>C(mQe(vyE zZ(5kd_HO9_Zm;7EZuCCy=@PH?f-mcy7LN#Ao&2tnyoJn+FY7Mv;EomL((V58uVIvx zPasEkxki-`RR12XQtX-a!bnAEguF&2@Z#z3Z-}m0EDYto@JX<+0SiwJi>_b*h72Eu4&yLND1fg9 zaS{7g0wjSH9EcHTaFkRKEdO#a6HBq8OmP)kF{4HC6>ISpb8%Eq@!V!HzDRFM&}$c) zG4KHK8LROcvvF9o>Tsp87Kd@}>TMg_F=4#%9cytM>v10wAs^S$1X9>)Yg6!%UZKd@Q+FC~L=D2wtagE9x;3y+9|BMU~b z^{(^A#QLW4`#vz66aW&8f+iq=0za-QcaY#ZM@~A}Pp~o_n*=A51b=ng2D7d)zXU8> zvM^>=|4vO^05XpFF#IlwY2Z%EBn~Ni^EVse9P=UTloQIRDIZ6wpyI^Kt-CYVk(h(b81LnQQU2h;TiPh1BnhZJN( zD5y0OfN(^K14BOqSC2Ik$cBz3(>>9ruRWp*FK$H9vp96H6wH13&i>SI}#s6ig<=j5)bg0`xNyPYVzn^s=@J z5+i^@L&6v*1r$KERIG|YY$SL<9;Vpd-LhloR*m6WxNz!6^WlktM7CLlN+T;x>Nz&y zDqBd*7WM9&>)afBqY@$?bwi|{^xjIhCW@#&NI(-zQG}L%!w4xs38#!(U0cizcZ+sV z2Do$#Q~%504KBH)NV(*|Mv`BV)&iz;z@*fjF!KSr@gE*+QIEVre;G?OEbv9&zIEX_wlr{UowV}Vw z7KnpfS70QpLliKF1Z0Aki$fHwh|WpDT8B9yJ7X*TtK)LHw^{5^9F#8Q!8*mH#HGM#5@zNApj^rLg5tB zB2K%dY=4NV+_9t;smRR3xlPyK zTyJ}M*o%En5HU-H@dQW;qauJ5gu+^@bvU5+LyH1796EZlk2-`yCa85b48%i=12(jM zpdWaii^5*>z5I!Hp7V90TV587Lnr|Lrjs)ONWwzf-nThEeIv*yB>JI?LV{mX68{uF z63DuIBLV5Jb)Soae@6kXv$~&$0|H1z0L-)OGlb(O`rwp8+o zKMh&M>HUH`$j?9Ag2^Bk0d0YS1uJw21>fZjQA#XK0Yrf$1=>j<^>0&w0una;vUiIV znIr%J6aWyQqQwHXNKpjPPGNy51roLrsBp_aGE!RolK>!r6f*W~*(0+lfx?SGGAbmc zP(r(Z12_KLBE{Cd1ORGoDS*&cI{@|yZ24uhfXM*%er-xws^X@9_O>{sD*y6d0ht>I zCi&G$!qZI^J=WD(m*QQ#dhPbi8xpTai-Gz69lSTN;gE|HXC%zHr_RBU_b#@aS1{(s zjWtdN{I~!{&z~b(Hhmg(YSpV*w|4y+cIeo%Y1g)W8+UHqyLtEa{Tq0JrNf2yL^LW~ zCM3%dWLg&m0FY7Qpe#I@B%C;&nN~ppB0U=ti%3Q(&zm4pru6HVPp=+Doc09bM)4#c zJ~RL=;xfT39w3rcBH<|jL{?EwEpbEvLW)QW0^i4-9} zvd1G^TB*oMjDR$0sfzxQVmJWa%FCW7opK6*ft)IiIFztbD=p!Sq9}oToJt@_pKPfp zi7P3RpcN^qa)}}->~u=cJr%;J6_Y#)AOO@nYUjzE3iv6cBC}$Wq9nzo?XQW57dNL%krUZZtkgD>i6?YQl z!q${>`YEGUMzwCtBwoTO(Q13d(Z+18wKgYeL&CAgL1A)Lr)stJ4_j}ywXw%-$E6n5 zb=8eGBySf}SKD*p-8bHL{WX^&e8sIO(ST($m^f@Z{V&|$9RGe8;)o@lnBt0Y+tlKW zHC`>z1TYpZBq+ua1(3xwQ81iP#94>N0-~5O8*#!Z00>dUK>&!5fWQcek$I{}3U$O0 zTAgrMMnXXXZ7u)_n?=b+Wl@ljQWBOi!wADDb_O7dakAhkiBYsEKog>eR)@lqBT*2V zr<?vgzA)Q4)wvHy8S+6;cXi)gomJ_=OXo|53m(o|5z^ z0j!kGYpB626)d$LIU3Ydk2sk#t6yZ_=-FEnLOxTSmjAy@ieK&_>91S5Y=sQiLrO^j z*;MO1u8$iEf=eiRuy0Ql8kKoa7}E&p`l1Ai*-8NFZrZKm;Tp5s5u6Clcim z1vEmDjZ6UHWGzDiD~c#0?SyDC^Qlj#Vs^zRM*m_kn;MrzaSr8qKtV`%IFsmlyRDE5fU zIc>3tVy;9de)8C9Fm@{`e5@*?>QOIk@~ce<=@xTI<^KdSmR20JNcXE!0)NHEXDx*b zE%^r*##N<`7DqCl1LY<`mL+dmOEm&14mRJ;*!tx`onf{Am;PU1#BiXPr z)rgZB>DWtwXHJ!B5`vlROkN5m#DiHzr~kSEC=jVyRjXbVt68O3TyFEi=p;&HUsGS! zD3XK(0099bLqq|TAdYO{>||O)fF?E}9su-gK^i%nM|w6lf#|Ji;=oZ7BCs_8NTE9u z%)&UdmZ(UK!>>|s+s`x!){#L13h{wP0VF{pg<$AwVR~9p^)@J#$#oMj@)1)3P&l5L z5HJc!<(_gCq$V+GBSiv|kP1-HoD?dB!Q(2(LTA8^=qXUa8`EIUx~Y)_N&;9>F7Qk@ zrQcN~y3I_2L;%nb(?xeATX>dQK65-8)+;Zg%S#)CMH1frPA5bO(=YVo!5MDPGGRuv!!-4cmX_{rL*=uaW|^#2nr)#Q}XmEuYF>+KePWvStvGH2ek$P@}VsgRK3 z7j5C4Y;k)hS_!dFt(Zb|It2hcfhnEo+$5}mc%Ia?m|*7t-l58cUV?o~ruoTnz_7Pc z8$+g_GHe(?iQJc-NNI$pncC~6kcRV5Ge!^>qt%< z#eoDFi6W5M;Rz&GVaRN(13v+fPRb&I$vI{zU^?1j(g5HbLpldRTZn|y9HbBjl{phq zKmd8f5sE;H0~5hyDbuFY#7-|HKAF(OhY zi(XkF~qDc~1 zA`*)T2}|-D6Y1<>D+Ag?3Q1UC`l4$KZrkD)tMkYd?lDhb8AV!PPJ#j$l>n~(4kOX5 zN>*YLK#WMiSH$60!622s#W+hgSOLI6rl0^n&BaXn-qcWk+7vilNjTfa(@+B7j?e*j z3qrC5g@IcJsa!k(L`pEo0+7Igo9S74l3!d%d680#C1FhY$3Jw8Y@oZUr8{*hU_^uT zF#D&LLC57svyB>#qYK5^7HO7Zn{=y&)_WxHX%8X_JkVJN5=H`M$ArvFRM&Ji`*O37N0C~F^T1TB7Y@8JV z(~)9!!XeuDY+h;sNP^1vp0gG9Xs#5>JcZ)+`7?f2W}LrU&^A9JxmG?C*#KM!0pnWH zoL;uV>aLxVV2hzM3M5Q<68uD2P>N_yw*PR*Rd&tMrHpPNXK4fKtYt&-CK#OpG5*j) zcbA&{5&%jVzqb=5-l5xq!CO#DpF%vCAedw3ZS@zL!%z$bIMKnq$`&EqhN|}=+4AC-jBf^%uARge}II4Na-LLs2!BV zyK(}Vd?GD4qW}KxEhLBnBgV}yO2S|Q4gwwMF`z7lZ0PhH*Fx1WmiO_~xs0d+5 z%2>;VDkCr|i!ek83C~OJvQP`RkPEvoVutF+b_!$$1qhM=2_Q)}*2$ZqL$0vsr+%-p zK4W1*0tuqv41w&dq$~l@a18J8G6byaOyjIf2gv5Iqz>_oOmB|vg{d?mN6O=h(Cc#y z(GXqCtO9_m$_^;#ViFfd0+Pv_FesT60!#d3P2A9@3Lt$147&)CF*-3noGqmUA};=7 z>t5wN^owJJ!(#;O7ELJMR7e35AblJz19@sTV1nB$!`XymxF`{en(-BbF*Hu9V^lFT z0^oBn#{YCi@q~=g0qLa0WXUvs&%RPhq$0_vL@KHD3W8n=$ZkY^VoDRSQ0+bg5IJRr za$*tjupMIqg23g3NXnNu#p*z59=%W@7m^_x(jjXDgkocZd~6JZh$%Y zQvWXx)2jFoF&8rn4U;Sx^I?)e60~NW&eAF&CNjJdGB>kg0Ln2r6Es6pG)I#(OVc!g z=rgS;K{GX56Ek+LJC_qXx6?bn6FkFnGz z+tWSY6F%cpKIfA@>(f5(6F>7)KlhVA`_n)FlVaEtKnIjS3)Dal6hRY|Aq7-H8`MD` z^f|i|LMN0$E7U?S6hp<6K?O5IJJdrzbPJ793%dYBA4WnkvP4r^>Ryt^cmmOHR6;` z?-WmA(@yi0Py5t8m+Lv_)K3RB%g&Tg50y376j9~wL>IL`_ta4%bvB7YQY+O`FV*cP z08`;pQ8yJe6|z%3Ra8fnR7=%VPZd>DRaIA&Ra@0nU$svm6;@}JRx#C3YZX^>RXhb% zS9{f0fAxlV6)gj6CJt>u6 zRTN(XmSC@}U=J2y7jJ zXy0{ck5*}yc3riJHhPw6i8E=VmTE0VVypH&uQoQW6l*=SWxEzQrxrGx7Hq*1YReXF z(^hTQmTfOoYz@{lwYF_pRc`0jZtoUc>lQZx0stZT1O*BJ1pq7n009871e^i@2>$>J z2pmYTpuvL(6DnNDu%W|;5F<*QNU@^DhV3pExTSF+$BrOFiX2HYp}mqQQ>t9avL#4c zE>pUSNwcQSn>cgo+{v@2&!0ep3LQ$csL`WHlPX=xw5e01t)5DqN)=+%s#slq%*qv^ zudZOjf}HtMtl6_?$)a7$wyoQ@aO29I%eEffyLj{JEpT;jM746aGW}K6*GYtj{VHC} zxUplDY5`+)caZYq%a}83-pskP=g*)+iw4?vwCU5RQ>$Lhu$5$jwn`g)&ARqb%eHgp zPOQ6k){MRz!mJg%xbe?~1=Hkxyt(t|q(jq&PQAMI>)5U1#>+||@tdS*e*e!-zPv@4 z=F_X+34Fc#mfPRUpHIKO{ejc(>)+4+J@ftm23Qq40v2fCfe4!RUxEx0G+u)cM);Ur z5>_}DfflZmA9d(CCtFwbbeQ3YB$gOni72M1;)*Pu^6gejqQ!5<(6D_>E)MThMAI~+O}t)4dF@Xp@`}vW1@_{mnK_- zHmXph3IVDZoD?nwCsCPlX{e;xeG2MRqK^6)rKYCJC90~n+Eb?zP5-&lqBlM2>a9d| z=ToU~*^2A0X8H=Ootu(6tc1cItL(DOHv1&4&PJPHu|B~n?X~nJ>m{$)c8jC7-i9mg ze7cT{7Pvp5Ywo)2w(IV@@W$Jfx;+sl@4fiutM9)2_UrGz00%7azyud;uwJexcksdt zH|+4k5JxQW#1vPYnWZ9KVe!TsckJ=UAh$}dK^TW@^2rmIg7V5Nx9sxEFvl$O%rw_* zb3)wStnHlp|+;bnqw?TaSE%-`u z4_=Vs1Qp&8<9qjA9pq_OzElE0B#;E=3jtBU=Ad)FkRr+`5r{!jBvMf5Wec=<<_c|2 z5a=Z(p~&s3KMoS>5NW;;?=>l*Nb9Z(L^(yod+a+!nJ1qT>-=z%X0QaGPL zz9+&G;_ZE$gC7X_Cc^q5q=6JM97H$>7aclBZr_VY`~L>#L%1CTfDJU<5apHxDI`M~ z25j8^lwm&Ng)e&{3BYGGx4kGXE_4ggoDzb-#j=$R0mf@x84H2{+a=+2ildzz*EqPr z$!>Lm6W;0)&_+cp4wvdM;vq79rW*+D4r#hI7NCs21LNlc znMO-ul6BMjBo|%xNr|DYkefro@)Dp*gS>7aXnW-(H<`Rq(o&M2YosM_xi>iyM1hG& zgdzy}M@K3mn5848>7DP6D@^AH6}P`!x{Z@fB%?wei2uRX(T$z|qh=6RCxLWEFp$%v9}YEF z&D4Q2osbhC@%qU(6{azT1wbP@+xa<;<}(QcZCfBEy2(qLF@>@NUlY^WOOK)yjh|zw z!@x(=7v3|W_OmHXbE-j|a<8U6mF7?THdGkav~37n;0gVAPYssPq2Rk63ngk(ZwYB_ zSK1yzW(fe>9n+Qx5hENkNxET>L=EITRtRnRTAY^cR7VhL&5f&cEvi*AvgZa2Bx*Kx6dx>ek7eHYwUt}v6l z#pH1{DZS8jb$Dd7UG6x!+|q(HwwUuO6_XLb+Ijaq(88Bi-NsfYDv*DYNN3x`Da>m^ zHHO)h>frWwK5=rBt&#|Y73=v%Nm!J<{)6r9>g!*1I<%hz5oZDEX3}cn_Nf^x;b99% z!1A6Cf$79xB0SeWZq86|CM*Db`@2953-ERV8L>DsOwRNbIK`4EU=RxY!2JocfC-Lq z63{44{SH*VQg!i#rQqY#WtMyc-Z6ez3RTVE@Fq`QVN9Y77OmDWh(NvK2!ATvY0mGS z)->Liw>&`_PP2UnOd$mM$JB)44gY}@W;2X4r(i5<51s{3<>tu9XG6Ntwg=I3B~vNd zK#X#LTvS9P`^Z<59y6xHgX5nw`Z=?vGt$%*D=hU$%2WzZum^!8Aq{J2Mi11E(6ufZ z6FEGS(h$$HEC8ZS8cA}ln$rWEU33T7TF=V$(r*mppQ-C;zOuTEt+n)@Z5Ke)o=$eE z<(nH7JL)_=m?x|poGLTNZ82{zbEhn!B*$yLS2r%!#{1%{Gf6{}jvJnC6lNek9bG%J zGTy_?wXBDCMmy)Eh--=FO}Y0#z3orG)$`y^FX_2pPE*nFBeIfbY|%>!bASDdFbZ+( zLPZM%f!vh96cw1f2pTnj)&K0C=QQfjk4qt)545j=F%Crof39s2v|u!CnmP5Y(4iRq zU<4Jt@__(B0{y$4{*K9Jr9#lb{G_zZ=PdLMdk~EjFB?WvtcXh{6_IUgqA(Q!Of4SF zr$FUtRf$;CoF0{^k8^XG(+)#|Ah5$i-Z@gy8sG{eP#MbbxxbxbWq}|eePvCnG0jTl zfdqiC+$&r2EX}vn#rKUFb>r#KNZ9mUw`>5Q_eFE(#sWrK)P3zbDVrBqq zqdRTQLvo<%BO?O*YD;+Ta5lKg1^$(f^zQw%GwRn$8=A1L zJN>VHUD81ZQjrKh{{MWgEt1BQwVIZYWeOOQsB!+oHz)W(O~^tCMuP>gVip)=>a%w$gi-|{a!2Nb zJ0){rhZz9ZAX>&{6cj!mCWJMFL}rFJVJ1}U!)5NnbBtp_IH-W_By{N|K^hoUOr>5Z zcV9YVe*EEn;QwZH>nA!MqMnBYC#NYpLc{hz2^5 z1Z?_+JBMXxxrA7%vrcuxY_?TOs)#!Z;95|0aoJ~zomE?C|vG0QJiysYXnN@Q%s^{My1qg({nqe_-wINNz#^%pm<5ys6MI26XXYhQ^94| zB$1tSSTaRn!*ooC_(A03VLeB3k|b}0h)o%(LYlLJG?)O&H*Yd^aV5D(<+D&Yl~fuT zVI*l$asMV!C@D+=gku!RaFA4V7|D`5Sw&KIaqCk;yC^$7Swb$RU*p4T%GZ)arjh3p zNXn-^H+GT(F-C&OlQc9)$CNx-8DKDFFm8x;eb{!FRAwiaKR?M+jq`SISr9lS5c3vf zFl0`I2tI*OJ{BcFS!sdp2$7<(ZNHUgztctOw~Y%_ZG04erzC$|6n2s5N|3`x=H_mO zmqwELLI}_{>}NLvq;HM$WXtqGn3+G4LqCpGiKKKx#&edmbC!*>M~VYL{wQ3?XiuB; zKxf2k>$Hl*Mw?tjUD9Kl`*$CVm=Mib6Ur$ReA9l@iHu*iT#N%;{0LmhNujy5W$@e!J#41oZ%J`@t6=J z8ft;o5@i!^-YFI7lL*xoF@@Ql`0-3l)0i~M7BiZoeS)J5!J7gRohjj?J0Yay@sIWWY5?wU&1o6!4Qyl=;AW%` z5sBuPP7j!8_lQ5Os;M4opXmd5pM{ZX6{JNZsaO%J3jwQ&L9COyGct6g_L->dxDXC^ zL|O)@)oKxR*Ny^*5XU5wp{ihW+E{URgi-(qGnYG0lc~#UC+*j+8HIC|G(XhYZClli z7PvrwV5_UeIVTE$2GK^m)`>wnS^CySt-4y$2vO42Ri@cXhJ~)KUZ%0DnmEtL>_?F#lz<>Iy2# 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 Ti#;9Wj+UFnf+b7(!Bhl7~?U0gYNk)65)4 zHVe6HM5u}!n`o`C1(@o|l?3MjzzZj&#TE>&y#f^Fiw!cH+>^&n1b5oK&qid^kXG)HX%Qszn%GxBSogzb+_ zA@sb;AYd~(3ZfPqf)qz7sXV}Jj*bF$!3u>cYuXuzNB@{fNk=AF!3$Mhi4_(h&p8hu6T+WTJ+8U90?B(W z)exK^dV|2W=HM}jZu?Vpj(9(PxPSosEylPl@8iyN$n2=SlB8o8g49tdMlXC}o zRg_NoWFSnW6`SC~U+O8vE5^&Z;UUE>D5Ez%ZQ&l0l4hgJ(7VxwS~@J6GZ`N8WVgbV zAgdb4)11;jDzaHUNMl%2Kyojr=7eQeLFqkkhX0_b=0w*D*{TplgrD$?QG!735LF!V zi+HKlU^W~qo%31KzDoKpFU)5~lOVqM5kw$mOmDd{n5;pM%yIn_iAHt?9M)XrLNpxJ zKpxk^4h?C6Aq|mTNFmtPfTY~gVl}UW?i%e!O4FJC9J#NVRC_m7}hYrVkNuV5-<)tY=;8*P1L_e5D_hTRm(2{H5&B z%SBK-M3;%Z4R{jJvX3swLl4xE&Y+VJw*O$$c_B#-P3x%;7*nykXBLQVQKM5;+Aw8V ztPi!u1<_v3B=8DJpLdILn_-{G)q#o3B%5uaJc)+64;2VTPBL%6NF)GDNdS3-R#fH$ zzHQjUnS@5;8JL6!A+Hy*k`myKI+BP^Yy8ONO_NVuLQ;8|S=NXOgV6q5WU0WkElTBB zvr^%fJdeZHg{ER6q2;HW1<=iHf`^f_%?>YuF_dN8f%^gzZZv-0TNn+}8a&-YIu>%_ z;-0VJ$3uwpP>KMUB8j+{)|(UOX%d+@31XrNEE_LmvkKeO71GJAh*-0>stJz}I8ceJ zPk|Db$Pfy`lLA{cdtfdOl9LO0zW=_;Hk67J=@SoWVJ;f+7X6Wsg}|wUV!n+LH_tnX zFxdi5S&=VkIT*nv(5ML~iLjEp3@*Y9)4C4wP^L0brJ~sz86gdh;+DQ~oq-SuOnNcn@Sy|p`e=(3Y^i96ltLr8bhU_AAh;K+xQEL zNImhAHIGOcd~+0pz_)Z8MgNIGm!Zffc`FZZ;fd%tiCYnh-6()UNygr?ApO9a9f_e6 zgpuy(5P7qe#K5DG!I_cikDLHTs;Dlum_u!%Je+YRt56r$k+oT~Ky}Fpe6y9FX~TX4 zM>9&MU2KyAi$(m94wUK(1k1&8fkl~_HNoo}{7R6HxQCgr3S6^5%95ZbYn0Yd7ue{w z&=4Ao_=h&|j>MQoV!Mr|c$+UQrC*3J%9tL+z{vcVo_x8L+Cs#WDWi}IN&1isoC(QR zaI31RsRJ1q;P?)KX+$vkpvN*0C~1lb$jG>;DRmh{gJ}}Cnj{n%yGs13mFy@eK_=Gf zH>(SP&)J-T00P2Di2tZCkYsXRQGKh#9*miAy&!c(a~(ALxk1gn}n&G6Lh|oC;4>B0dO<1(v0?;j(0>Rp? zAXN&}qLIO94-t7CG;xr3>aO4bik6%*&0$cWP>3Y~(S&G<8M{hD*&L55z)!M7aU+Fr zqrw~QNXxhoj*^X@=upw%s7Cx0F31VTGt9wwyDA$|DZHe2`qJhC3OC`?O#%rigC`}O zok43Cf=~b@-5e)vJ}D@L4&?{{g{x{yA1*i#^vcSYAOnkXrofWWH;oO#VzlN`2mtlL zkJyCEkd_&1gE0&MDWIsPnz2%l0xYr_1{{bnaEK|53uUW}P*E(Mh{R-KmSFX*R(Xit zdch`nQU4vCiDVs&0*n)hGE8J0Lz5sDnjn{`xGD#|jZM|Wk+dpa*^I!-C+on95M!@V zg;!DyDSUGf#u(ASI#s<=Qkv)umr#I}fI`vI9jl@!PMV%pMH3Kh5AO&9GFZJSAS~Yk z*POuBJY_FAtpI%|>wpZ5Py#niOER?#f%v-`lZf`X)`);u zbJ+rF0aOXAyew*0nxU|ss4_E=)vNPQr9~v4TUwK2l>&8Iscobn{Ru&mt8B(M|h z0N1P?l>L0!uho}F8e3LrTC+_rEMgYQY=t%$lQRR`L@GD2tqg;ZpNn`~$G}k{THA$ zj=8&Tb1x!){WeZavZz_UAtx6YjIZ5+( z$M8McMWn?=9|qJBX+baqE8IYQmRy+*!~xmyc+%iq+{=Yrf{-uFWftf~u;e}4-x955 z@mo&dTH{g{>vfj$RaWec-?iXc&K=)oS=^?5*1v6*IcZ%-vR~o-Ug*`j0sdX@rHrc8 zj`dYVw8dZ91v=l&9{NozRsrDc1z-S{+pG)OReavF_1$$HpXOuS1h$9;_FoiUMgO#g z!xU~|7yh#sb`e62VeTbc8rHf4zTd6e-uvC6t;^sAgFHs!;RJJD@V(&|CSnEyVkB;2 zXTc{LK3u0&VkfR*E52gZE#TJGV%BA1{`6ujRwOQFBrtx`F%DxiPU8hTV>J$51uJ6) z&N?<8+d0PJHfFF?LZ3U{V?ORKIA)21I0ofF{N(nH-mREl)WqG#Yfym*? zEoIzInr7DESZ3xxT;))f-phqm1}ikkJ?8=zUt7Lq%Z1?@o@jn{I!8L^W6tRKg+o`C z=C9p?Jhm}?{I{O%q$$7E!Y zV@Vn}Wt1Zm&r%`N=ss3PqNE>Mz7B?X3Ut^om49~{;rfO{&yHV_b#6itxm9C<;nT`ip(~U4S zGDv_NPEyJM&^&Fl8G7IG_!9<%?cBy{>FDdyuvP)HF>u`0lyp*MOYDYq3P_BC&K8Vd z!3^KdHofi%1pKWjhzjSHQ)?wrc9jUPfxj2ruQ=kMl zi35+(wK#A{9jh551(z+#ix4J8GygALP(WQ#gBz@Dm4Nz= zZSCF+TgYRe1zL^vXrt!m0Zx~DcbTto;lKN(SdYIFlMNy|!YS{!rXu{ZyvG#@J{ zRu-c0xu>q31QpyH1wPcis;@+((`6(j2r(dMl?+>RHRrGz1)rFK5iW?Au<6EH4A@(! zkHp9qQnZO)nsSI75c(8lbE&1}Ak+I$05(C2h6t5igb|I=vQhj8=K91!;imxba&jC) zhR9eDsVNCLpO7pGq~;m}X^5k-6-ODileyjQJ50;2O#g$dne2p-gTzjmqsWM~51FaQ z8JZYY7o3ntsQ;je6d9W(pYx=~mYy^esV;M;X7f8-$}_tOBnb(gOAaOqNib`hA72R` zq`06-D7`QvQwkGv`67_$HzUW$C2x#;nFzsoY}W`Ck|E3i#*vViA;L`SyqHLsK@cbb z_eeS-*hCN#8%rREMX^9jaQZcp8%NjRMUt<*Syz`B89#obPznN;(C~Q}QI{wh#x&2$ zTGzyIY%xnYDjj!SWNnBPv9C+nxfWpvE=r52BD#y@3yH8rCqaqi*rljY9y*foOsWaf zIGCJq3CoHIq5!EYFKSABFa@V`8!kI|p^51_4*zzazO5NwHisAARcNYCtt;`Z=`|I- z4*R-${ z<;St$C<=p60J4mZ*U(hz7eTYvE6U?IxH1+t5xW=BZR?KwCOabhv$sh>iGoWJj<1yC zzX>RrJEC}~82paR2`$IQvZ@L1YnDlNdJv03%Z2assPP`CJ(l<_pjl^gAoC=+L-`> zMtcR?y%c#b;mm>(3fRJ#6=~E0zjpe}N|0uPB>y6!O=xec&Vp4FQe>D`N&%PvxD+7s z(4Jm`D7%um8Te#^oB%d~6d9Oq!32C0`Zc@qAy#{gp&CqDFo`Xv1%j&G$&w;Vh$)k> z1dx*8W4~ZG5`~QLqDYviC5kLa5~D(rX@3I`E_^ug;>M377ryBi%e(-#aJ0uNb%L8g zQ=6r`yg_i0HoORk1a#G8|aif3Ce z_S9CSoJ5hCBITOeS_QRI#(>-gxt1hV>h%kcWCDNyn~gF05D*9q#N=8-qAO_u%cT|o zyWb@RK%&=~wV;*u7_8Q(4$}Hri*zN?XKA$lG+(0xJ4M$dpP361T6FOxU$(8d!;{bt z#Y~U{Cjl{&$p!tA=x;PD#2MsZt!0xEs<6L+1J#Nk!YHF=~h z>m^5R=%bTfdg%nQSk^ypGFksXVyXS@R(V2iB*Dly1?pEq|L)pVP>$(Um+%US%M*E} z9YtUP&4xr!r4+%|oOza(!c%|ttTk{#*%dT-NSUYPQ=fs2IV|?Zs_fW;gDLcx6o|=P zkdvFZ$62J&@>qc!$KuTyb zLrSeq3Loi<5{zUI1zm+8jv)+Ac9)^xpvgZrA;XDoMHvSnL^b#M*jWUk5|SjzLH8&H zVjw~k1LX#IlnKBO-zER8f5eGZvpEQKc=(U%B_%tqN);LfLXxW_g@6P4$QCftkPY=q zAg*YI-FkN}yeaC3jp^1wl(-+cP>Nm#;ZJ2g)FRPzh74PXkYAuOg)Q8}6|%|AdIDw; zJqDm5Nik$4Z}*oi#N~=C+slg{^b~^3gcSC0#gMcp!LGREavYIOLr4QLS84DG09M~u%0Sd*6$|7PBO%{Y^H8~<>R)R$>Qc#VlI!IM6ND2iA zjv+SET`Uvx%BBA?Ekz|`NnjwgzrVoY4jJx26nS#zw_ml-uvUj7eaR;%xg_P_ zJeW9^1i}AQjR9M5+5_C>ZLL-SNKbbg^*kUZX}5@rA4`2Cx0t$Oxl|L>XXs?0AdGEQ zY4OXAy!OGcTBup#vdBI3aw!(B4kr=%#cigF8MLkoEK>M|J8q^oUHL{)pyG-rGh379 zSVSc7$<5tFJCsd;Fvj!B+pa!`(cXbnAhzvEH0u&rg(8K9l@!Q=K=&CR(J7&jrLYH8 zQk|JFSt#w;h|r=H8j%3^evD~Vl^z1zFHd*A-7={`Cef>RPa;$a;814V-CmO%HkrMyHp22t3#aa?r4On0 zMil?KAilB`m9=^jb;zV@qYGq@hY-j7!ny-$QY%K-sO2{KTy6>>z#!&Chx8jYV1X)rTYwGx5koTI~85YRK{x>l5e?BJmdX--2Fl9Xs!93sy}D$`8dINdK? z%S={E=8^#XB93U8Q8OXuyq&aT3MMfN1-&S@%DHYUd2y2VAd?rUz{(c)i1(JT3=&f7 z=03Xnj4iex%0foOnv-0TkbxLWAn~(GCVYwNiw^M>#-ybSsa(dvf)F$1vYCjPf)XPt zKv)sw=&Lo>TAsr;eyK$)YeD(yD8fUuXC+_NR8#}c;-j-Xnfmu7;oYOxki(K*0x8R- z0xC}%sYM$~Siz$Y1#M9qQI_pSxw9>%@T8a2k(`}`&k03Cxx`2Cn13)(#x4Iy0%%F( z8ChCH4{dx0H{lC`RTGwR$UoeJNjZi;SzttEP65WsO7xs)uv=t>Q_23_pLg-8KLkWY);M0=3Q7ZyMnbl6=@%U|eOMFYD7&#VFjINhWZHDZ*bWfA_bEq0Umx%BPr2MoFiwP$tLy3uVm1x zM1?z8$ORTfP40{}mW2Y?2L8kt zT)eMt_#0mL=P`v+^;-H0NltF_`8Aoi` z8#Woyw1Q3bgv_jDaw%3TIG0T1&tE-cTBHc*Twzu|4)R2Vf=!+o1&R*&#)Yg0@DvmZ zO3%mmN6pAh#R#IU6pu*gBO`If46aC5#014S7P{=leEnjIh}AzxWJBCp8`$g zy(Ngn$)02}Pjf_AY8)0q^o@#;hw;qN3>k=bs$*SX&sSx|RrH0}P{~TA(GkgnK|xMu zs6__xiX?f(j9kaAcn5x_US&0)oGcTXbfSu=(Ig4a6d3=+1tn2~6$Ke2L0qJSj!8;P zc^*+Lr-GIhs1S@y^-6stQ|Lj;4;BO`97$og5+NQ2dA(!m2^7;ToT=ER&J2!@nIK?h z#DL&nX|PLoB*1hjC_*gKXo%Q@yh&R1M?&1gg1ADk1O^-x04E%mY=qM$;SUhG13|#l zW-0*yMB)}o%v<4}M_82Mgv47Q&j(&%5-e$xnII6MhGrxjQ|KsG}>{$4L~-UX}mEN(6-zT%k*-&Bg7Gb-9FCG>x2C zk&Fr}#UU3|Gz5aoW*5!XXapr%Ad5;eR9e)X^@-qmZ0Qme*o4jvA=(EZR*$vzg{tVq z&NY&v07^rh2GE3_RCcEgT9O9=$bNud&V*>&MA4k^sh%dlOj4XiNCb!En+WP=!HSN- z76%vhoYfp%MC|9zEM=4c6G#Ao1eoM_=n(gyW>ka_4@HPUyvJ|xhO(u^Uj@lyxgvjL znSC(ENsMUnQ07>+2!%LFqO49?bOvc;W?58;EpS4U846N;AnrWShV`oYl|jtlRnhKR zUL+$}><Bxc1VCp1 z)0TLxEig*jz|*=)SX;2}mCDR?nIVGuMMr$gmY5-y?8(=%iSl68Q;=27JWOkzRIp%# zceO)OdX~jLiTa_(!+g~tsl@G~#s%Tpbj{}EdB@Du+doLDu!@HiaGjchu1V2o*Tfo9 z_=9eAmy$IOaBas6WfQRphrqmujsE{l?Yf2a3Pnix!@}iF^HvGTogKl9FR~zjY`Kog zn8|nnt3*1CL7a_TLD9_(OGMm`i4|BTC7-iwrN~;=KO{-36og0dP?G>GVK}aze3hvX zWvsm!?u<}Mxb8d6#nNzDd?*q7Mv%!ACf*3wa)6oT?k&?G5PS8`14$(o#x24|)#!Qg z=pgFj+-tsA+^--M&?=VC`A9=5@#F>O!I2&Q80+_u;4}S2<~-_=fzvWAr)#WXLTLqD zP{nfnf>o-<0%>54uvJ^Vh?$BORe*`H_y{}Ih0h^iZgd}bAcZ8W(9Z>|X1%d4ehd&& z3m4SLPMim4RPw?RMD?_BMo|C9W=_jJ&_x0$flcynlQ~7Xodgn^6qPy2dT?26G@0CJ ztkQsGLUdn*`Aa23s^T zILd92L@(QzlGPrDG;nMtX(km!bBT-U;Z$ZRjiWdTAIs0DvGGZ=@mc-G4BF1mrB5eE zUJ<4;I}t>+j^*5}6~Po~r>b)hso274PyruOu*3y_g+u_f16kaK6$xi8#)Pv{1WAMh z76$D1*@BM2p9YObMaBP)ML$InJy9SZia(EZ*kFr7&_-iMXsm!mjeMWw>eb!V8%;KK zM3__iIm&tlfT;nLo8eDQqtW@H)VnHK-E~B{C9v21UQT(lN?=TqVNz%b9R??%2-l}^yEuzSfh#@OeVUmY;TXOs(m(v;oLPL|L;G$gqb}XiN@rh+D7H~`*j1*8@ zW27QWD8Onv6oIDgt4fk0nI4kF@Tbu~Wud)r15m zT-O{&Tr8C7SZmB3`hbxMA$vDvxC*5oY_@;9GhsVLBzr(wt3w^km3!j13kSJFR6zE4 z>OniY_jpZPo~s18uM=v>D0{r8MG*AV`4pz8_&QpYyKK+~Jl$jxx;trjNl8SAEf5&J zRI{hTV^qy(y7xP@=aReodjZpn?tr?i+q<<_5}^)<$OnhY=R0uN4)#O{_Ba){(~Gz- z{IOF9%7bx+LwUO&hnk$vSIB$&v`@F&cJLKDyU+Vl;t4@?0-G;XPfi)e)LDXp%cI3=RLL+U&{wS)k}Z(Tm0l(>$%Ii zCr1A8Q-;J;ziyJh_lJG9m%rDmJo}dp^vgf*TTN~zrL5n7{qukS14IFV0|^#1co6?# z!h!)5HgqVE;XnWn3r?hX(V)cw0U~1bcrnSqkRM5wG*c$4DJ1U`utO^Co~Ql%(|QUv<4=~AK{5k~Dvm8DdzB_}@JI`wNDHyY)9FQxR3`>G*tNh~lU}n{O$uP7UB!!;ekE)au0X05lZM6eyZX$D#%qES&rTmkgT40i)+Z{@g5cptn!hu@ePQ zos;mFypPvK{gKSSExrx+Uv6+HhSutcK-X;J$szF$JS&NRNVyNZ0|5jNw*p#`Vj>9w zNRE_$)O)C@Bw9&gBJQk8tT6>Ig3v#Llp{#M2ow5FK7l0g4#fhJkRpliasm%47G*Rs z!X1_PE~<_a(5|4hG@8yexI&AKAf%iO56cNlT#iVBh~u)!(uRtyLLC)Yjv*zPj8Vz| zO8aO_$t3daDIueJ(#<-vBuTgWR>RCD&1@P}vOxnaG&}16kZI5a^efcRofz8UpXa=k zqP&QJ_(i%TS{kq*MK=UMKp;L1qP&B(LJkbuM|y(6t(V)Pl`cSvU+np(o!D$jz^_gINlaVGq-ez+Tc~wcf?4g^!locv zY3J-#)Yh&QTVz#x%uQ_RT2KQEXvasJsI{jRgF>1DM)F!ATO$9&Ea(-0MEm|2?+Fyt+Pf+!`md+xZwrD570(`Wvo&5;aylw#G?)t-_)V2j} z^z<%(Z!gK{x|P)nn0-V@Mf`9eQs!<0MS`EL@7jv?#THU=>n`BAkz0~|-a)tbGS$NW znPTd|>>*=gi{MJ&{PZ<$`F)pb48NcT0k5dKSf&4~ZG}(5Y9eQvP)gvkK9kS~Di`z9 zX6BS8F{ut$u4&oG_7bzeY)nuBQd-NfwXX7%!XDRZO3_?{nG4?LU4|;z)GTg!1Q>iGT38@nrRUBIz+hg+^QA5qS+uXq?z(m zCz#5zS}P#wAz+!3kTC>6hp?9&f%J_OTX0(39P~T4X{IIlF_Gm+K?-~PLM_gF9`u%^ zBS{)+M;Hp!)Hac;c?ODaSQLmY`gkqx1jbVZPyqjq=+~orkfBG~Ndl){hOdDr!9WfT z$tDu8g zWFnOjzNSM^<_u&4KV9cgrP5Iyg$Q4uD_2E5^f7HY4su6pmq3D0Qniq1NBIhXc9fUU z5_y$~Az_kjl#nVC;pkg7>5&p%NYHQ{Rdq14P17D!R(HinsoTpVh6HktEdb$0-->He zud1UdATKcG*#yNjI8qWZq-omuXH)#r!z3smW|&focOZwDk_Kv(E=lN6tU5K$V$rMm zJS{*aa6YhVkShKl+XggitAExce{vECr2zkgBPbe=Mlt1>T0bkGBb{}nM>|_*e?_fe zS+4+X_?c!%;W+?wZBSg>*Ff@ly#nxaQNPfgqb#MzM4@Mw1NjFRmeU4)sa3q!BTuD@ z^otK|W+G_4*1a@4l>G=#JzS;O$6E5Qw<<5L+~L~xZfFy_5sD1%_$?4=6{t;3?rv_& zns^c8pvv@ZW}mT+uzta~Te)t&f)q$~1#`UXTWjZrGrL{TMM>z{KMvZJ zDfIZs-|aC7t)oWvQJFmGVPuCu!-fAI+k#0T-Uy2UU^#(2jd2MG^4)x-yuRT~31@i_ zbs0%Sqq)c^_p{19wt~QtQ1T*-TMtRzBjr|bY9e#95qpX#<)?X6jcSY^&`!uo&E&Di zfa`RS^}`Tz@=nPUvDzRzWM15Lr8;aiw84%XXHWmwYEL5@dzRcY-ub8ic%7~3@8ZlJ<0hhyy%YfTXmlXwzQ>Vwm`*A97ywJ| zbV&BoW64mecQ^y_MEci~mRSFe$9m>r_@>E7md7xMBQKxCu4X0nE*pfAaSiU|hXo>*< zrACy1Xk*pGVrI8Z@`LAl_IbMdMVpM8+M%ei_F&ryNf0I4GlWt~knP(idVisxB;-es zT~TV=eSCXovJcNTEC5^GfoD6(NrKcw$xNW^L=3Yos@%?Ksh7H!&ChOUlE z_tHsJ0DcMzpJXtmeK*4OcAU7dX*5YKXp~Loybs zkFsgSO04!Guq(PoJFv?&PzMM^(T2RHh|tIWIH9SuV_3*207yZAIwTO8u!I0W0qE;J zoMvu>(L%Z=XTXdHt5GHzhQl_2a26|HuB&gZ zEBJJ=E%b+|l#gf(=D$2lV_a_XKF5gOh6bV* z%8iI55-u$1EpeVy1t>$8EwXvB=;zABhtV z=MMh~ZcI7^p}Yx$fR2uouZ(~w`n&|ElxWAO411i(ORT0mMsFz0$s*Ye0YQp8jfr8V zi&EsNK_Kd+Adch8!_Eq2C`zouN&}_Hu`N@@9Vo5s^oSB`>HaoB3aDjrT){y?6g{X@ zKP14Bz^Tdpflw?5q|jq>mW1GtZq7VJZ5VARz{`9haBKJz@$4x66ytYb%)T%&?LH5x zI6-G5DC}D1#9}6DSZ2Q1?t~sCCX6#&M$aETlJ@pPCQ5-;w#6kNN}fWJQbGj0+NVdA z=V7W8bR5p=c8hmhYHR|*sK%R~#{9^`uQq0E1_tVmlq~=5 z$2AelBQoYE2x1C!W?j%{P?}RCa%;klMtO>Fx>~_(y5?uPCTe&vPamaCR}2pg)fTXH zOeUgGqvHC=NHe7CQ_<q4v^E_I?M5ie{vveR_Az7s= z5f3FUhh?z4yAx)+Tj-RrSlAibUr1Y(h4y+tZ-n^y!s>xl?7}poeB>`TP>+I`p7-uq>3CUKK#|DCFd&X&@ z=UJ>q_Z}r)G^dsn@riV^pXQ_^&8pT0v(=t#V*;RyU?_XOi`}|N%K`)8YSKlpf=kI` zQWERuLM|5j29k`ax-h6mAuA!PBb!8IPxB`yZF7#4s$e@JB+L|2gOWW#YBFibCi==SmG-fmTB?&vpf@m&W(kgWXYa;)OXbaX3q*{V4 zn*uE_s0~num0q%ibhq5t5!m(;@F-_QqoQB~<(noVi16*pekt`(cX-$%Hd94Zb;Ls= zVlt-`1t%}a{7ZH8k7=YzdNL^}2OpRzFPlr`z zdxgGimnZbDBe+Tz%}21%OK(jw3Ud2~&;6slx+t9$=7R9PVF9#)R`5U*}v zuQYzl`p~I5Ja1q3Lv5C``Aq-Jc2I{zlt(7I3*4v;m_gGc9qw76(j+*6HVVS)DDyCs zM?GXBkG|$sEJdvrHX_RLT2!ekbXF%kLnpSb*mx69>j%gx?4JI&e6-A834%sGsm};v z!Rp3m|BN^RAbz)ML*ff^sD`q<<%XC9Z5f9EgUOrkrEdRAB+Ed}eB3K#?sg#dLp>sE zYEapQ?g?#9dU(8rly59wUy-%Nkx)i)ErNzM1~^z(M}YJ_ za%Jl{^=PaT@$OESuJ!){1qyov7nv@qq0d4#?_XJGM(v?9J`FUUWLO+!aym^tg5c#w z>1f{gr7I<7yiqdDR5O5JZf*)@3pbI~2I^i0nwFTHT#c#zAjqjbhn4A~xb1yiZYK##USPXmJz zDMc(xhIg{*;)*ro7>As;;1JA={>5mZ(I z>1ou_K^Rxl9+a_)hQ7(*e(nc$UhFniIw-*pJ(M!>cxwy(`L}W6DJ-?SDS}dQf+29m zZJL6d{Ovkg+`U_~DePfv5DGyb*L!vLeMs6m;2RJ3L$MR{_mt0K$!4n_aSF6F@o*+8 z(8C?dk|6#$d*=JSX=W2+<4gs|I>?}QXef*~mp#aAc-)3&w%{w%Jgy%PFG00rs!<9= zjp;5Ek=6T2DCKHEr$KCi3zmtyIHhHa9E1N{^u7Dbj?s{GpTpS(RUpt~QC*KjFNlU) z1}U_tca$%iYVdp+H#+8gKkWQRD<#?DC)Fe}Us>|c^rK~~oOXsu0$N@f9rl4n#}x$(OxJY+S)pT0%q?PCEZ==w&s{0KKLSs6|9JfwYGy&fW=}l!tH1C<&x% z$;M=GPD;~Hsdp4{#UiP7+Tl!u`g}+M2{!@|r)E?HEp(4b!mwv26i;>-XX!`BVma?; zA_*7uxhx{$EI2+bmU+`20`Cg~(;6uPVFc-eaU=T2Z3;Fk+lJ!YC=X$@aJ~%bi-$Mm zx0>xRP##f!&ungLieHi$JizY}1x_H!J|ksb)a*E%d9vsyb3=YeoZKZGE#yP$@u_YecU&3IsuJWJojJCOpH_uANgMRPqZ$|UT|lR+1+($Oz#d?VL=YdLGUQ-Ur|~jhY_4u@ zEOv9U=6W~*AZ*#Q)ha=O0ss=UBa;vSf&vN|CIE1-KoDD-C<53BvB0l^856d%Re+=| zQU#LO8adD&8H5xMl47V4KmY(_P!_m(6TnQH1thR+mE<4*DFRzuTm|81bYlW{6*sloQovrDq6Nsb6le==#kUAKu?=}}%T#-0W2#*GcJIcR2$4#G zNij()j|H{>CiUxI+nNRo{0#e;t5l_}0K?tPxwGfbphJruO?otdP5-Wv25fLksmL7z zY&m=|Kt(cAG}@yL*EauL%?Dve{yWhtT!X+n15VELDr}=FlQ8#9ddokuorMG4{9HA1 z&J??s9#6i!`Sa-0kG9R4lvMyp{teyE}}U6$b)Nh6k4s;B0fY_>^8YHf~2%0CO)BOhQgws>Y&UnT%VgC+Ji8W4h_XHzTx z9L6Gx2?W3*gB||`xF4YlZboUGLBv^~rkr-#nJxd6F{eESJ&LB7N`7`Jo2L3{TL6Y7 z3WS#hv|&%Br>5s9uF6$3tA_)67DR?Ycu6Fexf;6KX2*thBA~t=l&5*7c2;enRFb!+ zhuB`}+@F7O1Z{;C<=Nn>wV`{Ex}{Yc?z_x(#x9iU&8sc97jDGkME82j?zoXm=kyG@y7w%Mn)^H@D(q}p8k~KK~f}) za;FGN{4tI%*K9MV8TV)3#=6?Pb5l19nBKNV%1mC)K_{*B(jGrZ^wK;d8z|09S8esx zq9Lv6tH}RmiuHKaTz}oO*}S5ycEMvST=v=uy9M{$beE?!igo9$chYz7?Ki7` z2QK*54i0WOwO_Y=IMydVopGz3c@5LL>tQW-MVFtP<(jLON-pJ6r%K35JqPcFY$nu_G2vr9>xjoB_ZJ;*GMYdfDUBAI5pRX@maX;N6Fsr|p7 z7nAqZ>zD+T5HRpfj7AC3-pl$1wn&voaa7|U;vmPL`*o*%9qAARXXHS{od`el>L8Xn z^tS)dfbf1n(%|eGSH9UXP=QtRO%fz9AGqYNXfsR#PnwfI3c*JLa@#^~sCSSYRwyA- z5RVayXAvbzU_X&**(UUdpDkQ$FuO_#XL^`Ggv>CBfGLU?F{ec_I_-v>Ndj!FSfq*! zOO0yu8h(#ehR3>ZfgouPW;xXTq%w!_-Ef29K6B#r1#M8d_SJFt-t- z4s1o+B;m${Q4KZj%3|wVqkzwqv4s@9d34Nd}~d)rak^JUz-3QI|m04aRL zHr8>Zb=rUs)NI0!5Zy?6laStnxVO9~Ey-Iq(~4hA!72Y(3IN)09r{YvCMHedoCG`( zwLE7a`D@22HG)^ZL=qy`84`U60;5C~WguSsMJs415QC(W3{%*`6r@0?mTf_ZZ?Z}% zQ&QiQ06+-=zDg_FksK)s5m9xKY$G#V07Ol3P7wtHqP8$(#c+)xCxQPKk^3SLDa4AO z+I*8O{J~Fy5Jdt5`Bi-;DK~uq%RgNyW-OWF6I-l`QKM5*vD8c;M{QSh^TN-Rf5Vk$ zmE<}M`v)d1k~Tn*;U2i^$xeoqs@8GyD%ZkMc;>7h-+>1>KJp=6`RT1H#Uug0$cS$; zl*Kq}x4E97RBgpI`yXq(spxP*hB(p;Ubqw;EXy^KBm{l4QmBLR4Z-k{28R~^vQAt-E)F;0{h*AGx;tC#@Br_Ws>OtB; zlvZ$JJ{|oFV=B^yh7e?uJ}tmVnsj2(#>c0rB#Q#Jpq7K+CLv_t1e`WOma*QcH~>dT zS`+h+;t()5EZw!njAB%Z$h=ViAh?c61(=0{Cqq{)vMoHGnT$s~;YG&eM1B!bh%n4O z?Z}qN@S5V8G>Yeh;rd^aKnhYQrZs?Gs%DB~9kX_3DJ`ohZfkQ%1Yt)C7o)kxBp?S(d9tb)qn-UBq3;k6WB!un1PnHTp*ZS-&He7M<)mI9;h)y1eYIb z^e0ZIM$gm=?m!U=P!t>C4z$4-(s2>AK@uO)7-W%363`HDQd}3{f*eX{ zW+?%AEu|87ArLPCW}qT+QN|Hdw|-&B6mrK>AyNN@KSg+3AX5;bMusFGwy|RqVHLlS zM^^E6dWC3~QXCss06?&Y1>hJMHib4fTPfFGsWEz8cMw=tNeKXA2XPD1u?fEbE)?Mk zI!8&3cu+G`04!w{`0+>v!b&4#Ct)`gOjT^K;curAhbs|ZB&SL&F?CHLTf-7b#F7%A zLU4CdT)Gti=CvD+ffj%$VWe^pl>{oDSc<#Y4$q>5HWpZaGAf`_1_v<(rZ{mfCs((U zDK+RvhG6-#j`cV=xI;aWU`Iv3Ivh4lY{+I4InL|eX_XPJKc> ztTl9?)hC~kY4k=IPeN?}0~7l3Y{T|$(NvS!^pnjYPd*t}Hei zCT{dbl2SQ2&Ngqy)0Ej{gx3EtKfhf`eYGH?05hW6~U>jseaEZxCu7^}jkz<{wM;j(r zSC~~110VmO1jbR9tx#12Vwm`W8b*Z|6k#3uL}V*N5*m^jT80-pF(*MWjV$5{ng|rU zSOE8cNhwuHyr>XzSgmjmxuF12=WQ#abO#|>3ik_{;ud)2 z4hmo(g2hnGm{p!(pR5xf8Icw(WgWcnk%&Pn5-=7=cvMN(pf4dAmK;SOxk5*HdN zptxxK0&xZrWvA+9Kr{boNAa+1p%@I6A$rIY#nMH)p#(s*5(vR{&=DD!sS*)oUXycG zkHSjb#z>LqqM`PR8zEy&;%~$EMJpjgNk@uyHlAZOjW?J-vDXxqYLq(3Ll6Z-USTTK zkw4ZkQh^a*FLIe9<*i&tLuJ8UHCIG%QbffF5s>t17?}`2KrGj?Sk=~T##L_?*_Gv{ zF<$YuF*%IXb+cjlOigjK;F7oEqLNTs0NIq2PU>ted8I9Rlt>ANe72Mt!EDD?Y}52k zN~ySXcDL(fAtd>e#+7EK+iX0UPRG_-&&HMG#AekNwP2{FtN-as(68}&NeaLjVs7t{?6{u7ab)--lh$WMYzW5TyW&BAPINxQ~T;azOK(2~kl4IIuNT3gOxu*by<4SY1U| z8>2!Nt5{^yxS~_I8B+kC3<#oSK}l2Ca_)*zoW@wc02U3&FWqYuTws13Rb3L70F5;g zj@X<=N?9zWhrx&_Hbsq)h#(6$Rt`)Co6vSP>~=nJwsx^r6o(+ULWLRhq}0a=q`(O_ zoD)`Y60~BAxb+ba>v;uGo?a0I*Wo4FXB|KjWd+J~!G#(aB3Jh?g|Lzu#eo`1Dvv}p z5g%6(ah3lcTL6#;X%F^r3)n18&4q`4e}E7P`a znp-2dlgvDRn*3?b?0=r&oBfi!oe_nEQgnFr5*cz}#u%IxF%Vl`M8>dM1d2NJI$28*`6Lie=u_0$L^q+UUK77+MG^A&5jJ+8tVoSP1prYuMDRKv z3!DFpE*GuuL=Dk! z$t;@`kxCN~Mj%9vSg2iPz|n}s5d?(5FtNfrlamf+8%rTp`W1!&5M=?k$AZg|3qsME zA+pk(MJ~~ON$?Atpos91A6W&gF?%2sp?%7M8by&QV!?Bf0cuMzQqn zb%AS&6*lQd!i*IhB-|y47um#&A$q0F4`N)lbGTtCZl>#oQHyP8%9TSxVWFfXU@8Ai z@MO2lL`_$DO*L_A!KRi%3B2qSPg+@TSt+`jfs?~al{o2=Q<;&|1QYVsx!6739NE<7 zt!9UN-ktlo<~F(Xwo$*kOztF=!yQ>6B~Y9V&gXHQnpqGfVGl!HcQzpq3rrvj2OLKQ zhx9ln(jk}|K^4@IO1z=P^kJI?l1dR3MM5+iZaIhtCW)BYBk{qRhTJlF*9vs>CPK4= zUi6qv3splMn4PJY6k*48Vd83m8~6E^_wlWZ1d-|an-p;mZ79#B02HH#R|Nr}6>$q@ zyA)pL(mL^PX}zqia1$(*Fl6>W(%Q=Fi+0hw5tXV|NlHf6TOkc&B2qlow`u>$6~aFR z2Z`OQfDN^S2_YeTnQ-tyAl|u&C;?^=m*v;OQisvslQf453Yg0ZM))Lm3G^oaDW7Xx zp@7i_?oeIUF%cVjn&jo7Q(#)M?0bs(eB88N!j9wiwMaq3EnTR&>a zbl=$tIYjUV4Do%&1pVY_8R3r(EVSiGjuuySOs#v(Cx5 zWjwnM>J#x05(uaQh^VmKroF|e_?Lls`b(v3r^h2*)RpYIt<1%Q?9rT+v&HS;ex0Qy zTA}QJmrPyHUQcDAASQLT`h6bJD0*9a4{dN5cT8Zm;IQmmgKKfey(#|?TJe}>;STwg zh7v}g_d8*3t7S&Dj|ma4zq?~GK~Zy|5xP2nG(8+OLDr|~i)>+5JC?o>VJEi{6EQ{+ zl4DXOKYf3})c462lJ&MV*rgtUQK}{K2JsRE0V>!bbIfa42kEk-cfwx8)?twvK-OYN z&lala5o-}4inxh%;#Wr4C$iIs)Juz4K@bL26$!}_tK=m&3lzOG%tdsH9+4Y1nKMr;6)0KmWi0|5jmkWk@3g$)@NK%h_{fC32$ z5Hy$&BgTXUHx}?X5XeA*7YjCYcu-@=lNSw!bb0V)OoJ3n*0iZnWI~G!bLxBuv}VVb zKY0edSaKnNi5XEA_-CtOyMIruUbUJ8>sGE^y?*^FPy(q|QVL8_n1t+EivgsN*;HT? zskjL@!6n6s49F>XNtLNvKuRmZQY^~dGFWiVByE%kJPiL}3n^QqwlFS`1hPhfZnq>% z0(UPd%Mv$9_!$5QnFI(CLS`D5qS`HFNRyJ#knk3zatn~UsIWHEr<*EYUMO};?zE*W z+f11U zPt7OYq?P41u?RNU$^*_U@}wX|w7-%-Xsog%AdoYrh)e21_uBg{GlY&h5G1u4+)km~ zS~(3v&6pxDp()7X%_yt915cqTzH3o}7~4xPDZv74C7Mf z&hrf9%0Q#yOb$>cH)|+Ql|DqNEtLoz^iDq`^E1#lt#S>zMVTzdmJ4pb^~$MlZE}jcjGPLBT#{szbx|OA4bG|{5S5kL zc(FoOMrBo{sJ(Mtx;NlNmuhd)oF?rGp`7Y{is3qm(#TGGDV2!QAgVnt;(s;v%HdHF zhI1j2^_8|QJnJ+$V`ia4`Q(UOQ;H-!g8=_|;fS#sN?oM-B~@9Z0`Q0{pO`8MIsk7# zkiUnW-Ba0=<89ZfHShJwW%nMM)L=JFl_-G2KHP9(e8B}fp@^QcD59z#9{A?4UEbH; z0_#+D>9yykyY9Nj_Bw2jL2Y|fy?wSjaEwvfJ8Y5#_eue)6i2*quk>^r?Phh2{N%$a zu3TF|GY1=F&OZk|bfF>B`l-uB4;S-cCr7aoM*ss!8ccEwZN(t&SSJ-&xxqVmr>*@BKTcp1yKl10rzux-< zXl4q+@*}@?UhlCd{(Z#5x8L#k^XEV0{{IL6U;yc+6#*9TTW>R<-OhIv1SZgd$IIIT z*VaG@R?vbM#9#(BxIqqf(1U?{n(IOsHXwYkco{4jL+kI|-hGQ74>c>JF){uTS z1j`F?xWg7YkU2d3)(S<|I2|SoEJw4K5HE+!G)FZYknhK#nQsSifCm{9GVr-f|y1$N{cIIbXWr1mo$~ZOmYB#f+n<3 zLRqbERxzPt1mDE6j^J@*7mj}iYJ>0w>fT0egV*= z9K9&KZxN7lUz}b7VY!vw1uuO8tmRh!s5rM=MzDyx>|!u6c&wE{u2M3SltUumuT!A} z38T;i0PX9;S&=WI_~#yHLGCWz1An>{^170ynQYCn{yLQLaM5Dl< z(;4e6%aIeGAeEX`J+YrMEI=#%L7&($YI5qsT86Axs)aJ}AX~^*srnbK2~yOB*Ak|W z0tn3SHS~Hl%V-Z9=g|*xRA~wfDd^6JlZUXBTumw1Ci#?h&CswqKK0;ppDk6#RwCR24OXWDU@mKX|h00_-?PM1(jS#*fga+GA+ zVbDUBN@f69OAZA>hN>{sbj`>aI{f; z-)pg3Z?%Nka#K%@ zWMLdneN7Ug>*NT4)wwlEf+!$C)0IQ@1`OXc4nTD-4o^f7C?^?XbmOi36A|*yB1CA&je0y@@qR!4~!? ziynWI>Q+P{01!$*D+;g|-*l%P1!xCzl91{)493+2Y>H|iLm6C`C?U7zHI^DeAAz*m z7N@aChd6=lR)o6$N^Nj8C;Fw>Uo^-bkzvW@_O>qVeRVTB`|5|Lw6F^y({vf)$w&(O zD|$0!B>j$-LGV@+P8D1=843zh($#N;^pYfC1qw{%MI8KXY$H}zd2AU`o*Q9(cIr{beUyn)W2s<; z7yP)&3HliiEk3QEPRC;Ht7e*2wHj(6Rpl}LcSRgcRn>vCMX3&wEpVYA6tap2dNB)1 zKwpWV*U2%I11+9_qXJ+namWTJK!m5tgf{~Mq7nr}0IVpWrzCK)^wNZJ$O0fh0`dYu z6-2TY%#0|A1R0b;DL?`w=&3!61SdlPBp9-2{Ij*{DMUa3Nw7c! zhyoh_oWU9NL2ZBnaZs~N5C@JDkMNMOaqFg zU@Nz3iJ~b9QlqtkF$h$1iB07fuq)#u zHj0o9$?&{$X{m>(43Y?p_pk@22mmf1puIRVfjUHwpp2n#u)~Opiz&B*^Fu{h3Oiw` zlZd#%Nx0mf0`j#`YjP!T7k zLdH1!w3+yxA_Bm{!5s)BM;02uj7k8;(IR1~2uN53M8gnE%Z5zwCbRN^Dg z*g*L*xa>j#QV=uZkOH7Ps-r?X#bXMa0|F8xI;K(wn_?2LOE9d%u7rSubr8EVK{6m1 z1%p%vghYZ&P_t3U2298@AZRj7g9KI(y8=*vrW-TH!$QBKIePlJqFcY@K!k3RuUY}h z0+0a90}<;0jt2V&fe<$0AdGc;4}a5EMVb`+Gnu~{xM=h^XIwzk2}ch9DoxQD z&Hs^`azvfwNuBLs9@dN;_KCJt@iIH3h#|`aY}n0A0KtNEGMig8AEY#>QVAurDSt_V zFN1{Ugai@9L7M`sG$hVL+s!OMf=Ih2Gt15kaWgmr03?Jeroubtbk3)eJ589!EX#%h z&;)fbGbJ3P>0GpiXtXqZmpt3T5-KY=6s`>kfH}M=_tFqZq%|gy0L^&33u#4)5Vgy5 zg@-Z3mg0h_APmd%2qpLhMk`Z(W6YtlRYXF z$Y41+S|5C~Go4r;O`!;V^Ef!+H=8)PGt0Mx(;n3*I6F+gn;-}?iZ)GiiLY9>H|?+V z!zgWez}7iU**w7O*;5sYtv`(=KTWCbQi}J|NJ2V@Ojw68;}DN@JB}1Weq4npkUmY= zjs$q7fi#qZp@^O|t_0{v5)?v;kbuBT2#TCctP`vN$VlTV$Zz`6r~!bs`?8NLy6E~k z0KmGJEP#&08_3XxQSisV+d4)Y198BFd~y>gh%fTn6jw8m&FjR0;DoAh&^lR4W%&gG zD-c`@j{91dp>)KYfDhw4%FW{p^msRE1=CFekbfucy1WQk4?OaS~0Gf3FLB9j84%?23+EGdwLFpGrTh|aAAI%wFkWPGMF z%s~nqIxWb%;*0<%3GN=g3(2r6}fGPL|;VYJ4JgkqUOYy_S zd!sIcT|b%ysAkD4|MEV>L@fLRxVs`mWBe6dM3zhu7=$Sbfyl0Zda3YbQ;gXdk5iPP z0VsXxQy#ism8CHUdRhJT-;^y}itxyTR0p@K2q4gcgG>iRpeHFf$gc7+ASkMk42K&$ zU@hRgaOgn541jooM^Y7sk(fH8qNji);GwICxof(k8b~SNJ9Pk7?j<|4lT;|Uy0Qz& zqT|PPAYcpL0s=lN?3y}kXu6`CDLjF%Q8lN)6e#2Wd&)X_J?~n{h(bEOl^&Eih=CPdI|#6%rxIGLy=A#w=2TAQ3C+mPhiM;R##3&#TbTo_Wrhd} z)aJAh<`qG!?9}F7Hs@Q#W`MB@PJ64ASPCxxaXA2xf+>&!^G#5KNCI^{2`TvJhG5(~ zWDc`<455S&rob*&(~s-?)qU5sAl6;o632=o24j$Vq>8j6gAMxA(-pFlW$LEnjRtUqze z1Ag9|Cb&Op>ep1{=7CvoLFEi$<sPu!7+-?I+(*s z?6v`>^6i)pi|ex|Bt7etQx(YnT$;f?nXb8OirE{C#jv;OYz*5Q($=N2HlePT z?HUs6+HM_BYKfOlWyqYNlT`>#nrs4Wh^?k=dS;^O2_K#z>)7t0^D*q$86lgY?Ff{m zLPeiIjj?Un?r*f4>Yg3&cAV0@ZT}T-+^%g}HlXviu|yL=ax8E3mTxY)?D@9u`^N8B z&hP!c2$s{J_~!4r@$Ud1YXax*(;RREhiL_8a0deL4FV?h?jH$naQmU~3O^*(45(_@U3?46z2*f-FHM@ z&!JT2ox?ixKi8!cW0=D*Y~P89g*z<6_G`6a@=8CsYN3c)0v?bO8>%`Wuj%ebT5txu zbGY`ORM+%WAN8j>7>_w~K|f!C=`0A!4Om)pVaoOIfkUcB2^^=JRrrctr<;LjheIBd z_lQ2}*z@2JC786fXvA~EVYACK4BIQ5#t=$6_KJEA?iW*MrNOvgH<-H^wok;0yI2hl z_2kbUa0EzD2zm-zSVV>Y0CsL^gUllfbiasA_yyoK5@Ne|WtR)$>k8YjiPH7MR@e@f z8~259Hip;HIBp2zsJ1Vph~4Xt4QUV)srN*oHdEvYjeiOWSW1Oyj9F_41-Q|@3X+9S zc4aa7Fd7VZD2p}bc9e+t|F~k?)0R$z(}eiYr}$i+2>CewumlMCcnJ+xs}Q44H8QB? zGH{1)n-$7%d7~$ceD{{~nE8ch3|uphh%ot7>vD5{mC1OM6uo&7FO(7*`b{DOo{tc^ zlH$xD161>QiD-q~@a(IP`fA?2xm@vS@{TCy#c> zd4pbf^GJZkr~ESiAO%Fxk}jWuHqZ(jcjFJy5~K$ijd$^2Li&wT2w|UZ*g!qptBOz? zo-~56)IaR&UGm^~lYwf)(~*JzJO0?mBpoua`SC;Ji%C6F2l!mVkTMFI5*A z+;a6yhnjeyjDI*}gAa~Y>yD~;e(r~?+_&PZ_W1q)jn^Xu6^(YQIR4C2QH4M~r~wF4 z|45Ot_b*9-0&V`a64)+bLI9lpNdZs*KoW`;Atr1!&|@ozw(K=z$PqxRUmP>qBjb@& zLJ9VMjk5KR%te-@JZ`d>pg;n9wjcsf@~>sPe_JftYGrZbMJWsm9)v12B*%zZwH6?m z)#9(7M1i*dOek>Yzo8rhTm%aAB}kF>2o8j35G_`gE(iL&8@Iq!SFLP`{n>S>MYc!D zB&}FrOWI8~w-C)JHsQ~!L^m-cV=xI+iwL&1{Y45YWGN8Y2DOz$3c>;)1!9dT(D2Ev za7`+1c@}Dcc0<`F++xt)&z}nJ+QbRqYExTF-5w?idGKJzwobQ=c-3>&B(1QwGT7Fm zQs4rWer=n+fCTiaw*oI4dSL^0**-lL_`2cpc(*% zt+(w14# zxKd0@*7ysSNg#-#0%j(WKoDyolth^vDc~kVG}ejdlG|-nBVY#=_fG;{nmI*)o&^vl zM`v=W7DVMGcT)kx0m{)xm*SMbJ(T5HfN7XvngFJS&R6Irn87C`5P3>9ACd)dA>>7= zK{P8zWc(8mE5Cq7im(=y*Aa4NRn?KOoZ3_AFF1y|C#Meqbx%mF2?gMsTXicaL|c}X z9EkbwXy$0hneJ@x~2rkc}QeukBI8MHSZnKiRjM z)A9E3C>2SZrNxm~992$Ivd{f$DNzocG?8qrAZWXY8C}kBDI1%ltnSx3XB2mqmp#Qj z%{@Iy02vH}Ds_>HJ5K>%_UL9232ZL_Mi~~*%90R>0S8Y77!4bc2BW74Bq8p|Urg8o zfYbm-gYy~^#L&|U!<5S+e7T4~f>59HeM|yLVaQxI#yo+DMGMC%57g#kBqdlx0qDV* z0+isL@Ti6@kV!}c95b(+@Q7bX+s;OSkRHj51tKW}&S2WoDZr2pM72=>rb6>Cs009Y z667DVXFogB(fSaT81Xc31Z63Ji;f|UepLNz}DSFi42GE)5HA5(aWco@b&!2Du>d6dH7 z#FnW&9*0Mpn;?7Qrp#p~qzq(RTie7DA!zbP3v%nvIGCx;|7^r>0Z78a+JX{$0Kgqi z`3X*Td6Aa%2qjLzlT=8tqXYnrs&Puj$PlZ4a3LWht5F^kQVK8Cra!`IU;%K% znN8qxdme#}uP6hmun2E-6r|fcO-GRgxWg7WVj3lHW(z4OASnp{0m4XNv_=(qgfLq` zouG~i88RdRGOjsPqIkxywA2$KzLE{4whB&Lx`mQTaL$ifmzFxsw5BL(7i9k73bOE& zh%ws`Fzpeih~UU(V;zYr<`bl)F0z!!LMO#6lfof!HBw#u#~8@8iLfvQq^d$uFGo^Y zn2xeoNs;GfopRJDdL~KW8wmq*DxQ4>g-t%J3o)et%u@+P3X9xcOcfvnh()Amswvu% zb_7eH;Hi8YTho|)(p7&z?WM@1jAuOZi&FTgm#%2Z&!lFPuWn2N#HvVPqs2xT+rO zK?Fz2!%8Vg@(hcQrToR}_L$-V7-gYRRf0wf zu+lB~ki6S0(2{=qAAg>0LPDm{D2^;-bttor1C*0$V5F^({DghmDH7$>vbUvR*<7dT z5hh<%(x3RlEVcl^hotZewiv8KoZZ;#^!6OeAm~h}D<1&jw8DR6=sAt7C_)wIF2IZ_ zsavG6*l+_G%J`&DcLH#Kw$!Z+Ixx%yC?Hcxk)azlE?oCuUAWpJH0!A3fjE;&A*I5) zjI>c8OpH=jM5HK-Br?=0%FPx?7m*-DImiZVBBpNtr5w=>#50tBN|+Q1nN8H1(`oEc z1pl$LlSoA@%TbE+B8jt3&rgN%lxn*Ikj4U}c+c4*9XhkOx>5cT#`6lEI)Y&r-*ut*=2o_z*eqRs?{>~9;x-A@}A^e~zlnMTr zZJR&)ahJ<8B)0f1Gyp)rk07#H&?wDrAl^t^b;vL>v~yRo!%^?XqxOr)L`BsTj>e>f zq1k_>Ls0S6FWPZAKo<%jocP6w$Txf1I|O1j38nN}u__=`wG}S=PvgtzKes#(YoM7r zdtM0>zahNQC}PY=T+?Xdgz{BM+FYT80(+eT4FEt0&~kr{qbW2ib`IJ?d2CYBPrmFH zIk|;FaDu)3f)34ua3n=Lw2ndagra~7`%Mgr+(J9-$yRZMQPhU6WK1x*%yLzr=E2x~ zgw1?(4QAj;g5^YwtWnPhMXFd#tt0^dD;z~HsY{srL`6B;b!3b)Aq(z=A6o?p2YQsD zjNZId5^ynBPHoKrrc{f}7O1JnB1us~1V92Pfkyxs6rP~39M70gkmec6OC1Uf=?=mv z$(mS;u{{RTfXcK1&5T^u(zM1BK13N3p@!^WDYTURB*bWxpn0`R=Gn*gEY=cM(7Z5^ zboo%R$O{RY8EF`lyX?qD*o?)<%vF)lE#QdKxXTTWMr#CFMhF^ zQq7#%hhzl9kb)Fk6>LP`6kbICpOs&cn2p~kfMl2i0I-YQsG1jbV|NhC?0FN=T$MEv zg%mKxdsxKSHAjUE$Q^x6im6@zG?WX;3q$}Q8N}ndQ4~aVAAD3zgG~V!RHKWGThfR~ zE9_NqAdT8|-Bn2ts?5dXDBtYNht)NOJL(q04B?lM+foET04R#D0GQQ%)BbqK8rp|b zAY^dVhGvvV0Vu#6{Zm8aU#q+c*qp?`JxLlV26x<56!2j}J`6~yPjWn6DLzHa@kGd} z#woT#{uGSM+ydZ8MFMEc$8gF!(anBcRc_c&QgQ^gP~Q~h5pe(;1F6V&>0}D22B#ep zPyAJYT$E7k1V~T@&Zv+7tF#3KHqcr6*18B27+pm}j6^HMhEbL(5u`cDn^03$*rJ87g|8uJ+CV3TC`j9|-G=lCj@S)mK!vq9 z%sM#*00hC8U`RjK%|?*K?6pCwOs8xlAQ^Q9J^5z2^oOy`knL$Ba0G$V&5R8q%HJ3Y zyS$nYWeG6RmFoZn=O|Gac9lqkr`!OOu8|@~m{W(ir;#M3JvbB9#S|EU2FyeR5Ms!^ zILW9b1iPFco3xJq7NO4Pr6z`eQHHo74mHbB?Z*_j5NYIHenCX4jK_EwAZ6HsJM;xs zKni@!2M2{z#w<-|sa;jj+AaJEadn5h1O-lj4Mx0Kket#K^@L1;*mxX;Gl7_r*it#o z+p8cVDM3US7U7^7mUzmfiu?it-3zGTm(>vu5Vq;Yl#0PQ=}=16=Gg_6rPv553TAAg zqr4?dbje1bN=c!q{!L5kme%Qo-+=}v9tg`IaP0bx~xR6XpN3Llg*Bymxjh!v!+C>5CKOwE5l$dZ- zBZ6#!XE<%xz?;i1Cw)lI^X&)5N^D|KltsqVZb<=K5N$lxg_Pzj!YD??vWHBt3CQwA z0N4coDS&M&m88x(mHM>AaN!E!Yyug8ZH%Oxltf&nuuIM|T(XQ@HO_=MRonQ@oXLeL zRJcM~{4G}SgcNk0MJxn0E<|-53G^_xw9#r6Q;7EFOXHmwvaEY5huK;BfL zEEWD~#8q6CO{hlCZUN%P(-cSn0G8jEPU}Ea;|=w!$r*|AF|4u7?iQAjR7}$K>Wolb zmFkXF_Xeq1?xi@z56fhqL&4i_A>umWmo0?K;zpT45UzwtMJXt6L2^X6#p7^oNSJw* z|FT=ocAXW0t~d$=CjhTl^c(ADia-Rg<9<%hAOUa)=ho2_zkn_1{zU&e&r*O>-3IXg zryT>b7V4cD*@Ym+G4Fn?H-s%pjXg+@3M2I#fIJ(xxtM3;`NUqs-9N^sIj zhL&TH!D#@ijvz;m5KClmlX&Du>1E0`+Kmq##;dJfWQZSp6b(aEXr(YC!$f9=1b}4B z1TDEOjICIIIM;u828_)m7B5v_(3v1+;}jHCK`!ogd=)YI;Fd<#Qej3)^cEnEL@NrB zhY@2!gkvj6h8mNG6!2(&JTha9a-ffP2_0cwv=ofF^sjsQ6)hCDV*{g z%j8jH7G?-*Yi*2n0qdAF)gJ2}C5J^O15);oW*r3H}WOl z!iE`hr5vYZ6!9G6bIaxE;$n=xO!JbAhH=c#ao`u_V6#Klai4f|J2=>!I+Ld8^RCzg zJnIHYmhGny@JoHgLu|QXf6xZ=l zeb-6n1v@LrNlP-8^s@vh>~7Q zUxBR6Uu%V1|3{Xv&65cBemt09BX$DlncFn>f;3TM$Hv+;9>BphV#jp=fErf-98=~s zUK_Su2Qyl`3ua?By%zT56v$#bTKOq8ZD-@;@^ycdHBi8I;_dZa zhviyRNTZp}ttGegxixYNNWeyRR$Mn*Gxk?^w|9RxgH$(G14oV$NOLFNo0NCkvP?u| z2{fJef^FXBj7c6#?&&thZyxR4{ckheIH8~Kl=?UG0N)d^mc zOSzR_IhJR+mTx(iYdM0{_t=2BYIpf}n=P5&xR{^0n$K&R<2Z71c$@oOoTsKXwYic5 z_L_@$kk5IZ_qm^Q_gCNfpZ^$yXt*p6ET0d$qNlZYKc0opc%9SYUmLpM2|C&&`iZLz zGhw=8kN2hv_@alpE^_*h8wll@IP4U6pV79cSNPdfx$Gr)TFN@DA6b{hO_3Kkg;;u| zn0KoGdZz0-hNpI{2YatK_F5nLf3FRT2RBz6`;^Nlfharwc0)U(Kf8dyc6BHF2LXG2 zqk3NNcT~0wVVgRhPdm2jIbd`9*aS$G!#Y-*xefz4tjl-t1YcJJBR8(&n3D~B|8VqG zo>tEug!)Ixv{Ty>JBk}TuZK5YSNGaPZ+AZhM^qywZ8C8vX1Nc@wr6->?hTY%$R*z z(+7rBV`_$FHpVRKAidB-J<%UFaF|HIS{~9PHlNd8?bYaTa}&^m{eTSL&oiFQYvaj> zePN&c)VBvUeYs()J%0{;oXdP-%YCbFx|;C|R;;!E+6_fRJjku%=ip}rkDY|R|1vN# zMz7a+x+lOdC_yK)bo8|*`7w!i5`q8PKokg2pa6h@1Q7}ZkO1L801FicFbFZ>L4*k&E(Cx8Ap(sa z8DbPkvA{@-10_C`I1r=Ci3|yzgb1Ky#*hU6HDctL5M#oa4+REoNfM_|f;($6+-cD0 zOPVz$o@}Vms8N#;Svs{CHRw;B7d1*m7&a_ekx6r6o!Jp>NR1C$mMmD7CsChYhcbLx zuqxb*cB=*!JeY7{!-o+kHfk~OmVXII-2yUrAeqPQZ28PM*DcT_MT^o*03_qyr~jmY zF1?r2uOt~s{n9*^@ZN+9{z;JX@AGVe5+&r`xcE+Om$d$6>=%3IB_p~Mqx zGlGDKil%mob7(A}Sfr@Jx=PavfZ&Egh_t8nf(b173K$XqQfzs#ATq2wGNY_qf{VEm zZ?sK5B55Kpv;$i~$QFA5c#kQXwy?*@rihws#~X2)@=eCJoNvp5Ji;a6o{+nPr;tG3{R%=bBQ8EOXxS}{ z9!R$YOkS>lDQ33N>H>UK7B!}LdOB-+(j`cO{t^JMQG}+zmm#D}vZs{`x5#SVR-An* zfr>BWxuA9{Ru(3n$-PhR?Z}up!>6Q>VqP+EM(F9fw%`Qf7Rx3XZk!m>5TcR`l3)}F z|K0-fvlcS>II5!+iE3m2OKz59pFSIOn`U&X2zB8<+44?%>y1K<}@OdHO&k^VL-C#WVuiK&&qPCqEFWa7&1j%xzx zdip`V3MKO*no6|(t#lTz+~p&ldLLH$XQZ<%@O)z#3Hw&kKlLp~cLTi2O+Yn4^MT5O z*Sp_Vpu(}6{N!)#+aLVo0ur>SBw#inAVb*a7b9`xfh{};U~+Yuu1hmnpwY#||q zI0iCJk`MU+V409Li6HCxM{NFqp{lw5sRbGaTq49VV;s}Snv#T8RLqWBe2w==_pOv%$dq9F%qG;+wG+W-SC0%` zZq%h16P+=ZODceM9vK@l+N>n)$YKFvNlH5Y0%rk8mTc4$#sYvbK$^rIc_v?$3e?dTq}(U&7PK@*QaGcyla3PcsOq%3+dU3=N78zW>b zcO}6U8{J~QoCw8pF$b4V3644C#yuK^G)_u14XsL(r&zV>tFCfVSp$?R0ksNNi4qj8 z#>$rzz38i1VpEFDB`846RaJT&D_!jxr%DmZtr0YASzeVWMak8yk2))%n3E}o)KxQz z^{ZkPr7BhpimrU^;b+e?0nk<@qqXr6eNy_eTO<*0Y0;g&n$!x?i3E%P$(v-Ecu&!jeeFf=eTP;f)|!9j+2GVyt#ZO92MyV&lM> zlM99aS0raV7%NHkM2sZ2XF@DMBMTxO$8|Aqj@b}qZ~`C5jEsS9*JX+_dkk5RV zAWv*mN{y1N)Ih9pz7pzdE>sHJkS!rVES`%O)I^-5>B2c_1$-!4q(=HJZsfWJb`z4C za_!ApSxmrg=BQsgQgSe6dZ<7cGKHj>*fRPZCPtF5vxoeH6KE3R-ZIl(oP006`E198 zq#{KkjrUvXS(0q}xgi9#l4~Vt#XS-bfZgy*(H!PdrWj`woLSdciPlINI;o>2HR+`P z*n9{w85qS*-NIG2_I z{)AZg1Dism@*A=!@FjfF$@yA+L8`29eQHTIXO8U`qgqNcXHlQ8F@>XM%a0^qscczf za&2>|RFkiMYP1b^ z_=?U$L`+G6PouF?Ok%|Cj0=P-3(2FPypx0k1Yw;$`vplya|>xnXd-POlNrCZ8GDq1 zkY@~&8#BU*TNI=ezrfmNy7(WF-(!(U9O?Ts z873t`0lX?Gas-susVJLBNlhzw5+HJ6@>2>sk5Ja85*!=LihI#=M=O|Dv46cYLU>l! zV|;=j_R_nSEkS}&G}N&qj9QMIUI@-ICOy|6WQ%pAr5)oN=ie|?oct;iI=OyE>pWyP z1;Q+x=3}Hyxx`~M;*%@v2*hPs2j`z7%+*~XteDK&ahr(^Lgc=ny(Q~+602n3ibxPK zPmfRR!*lw6R8QyKq7-Q#ew?_@9wl@Lm!wgGdZhLku>Gz&oJ40qSp3JdCmuFUBGp4M zU7mGiL<+81qIE>}9w1P3U9Ff*fkY-F90Mo1D8od9PpV3sa_aT|N=u~w!+%h3t~lc2 z6k^~`#86IzRUGTF0E@5~ zq{FpzM1WkV+h&42C<2_`D?!K*y8;j+(nO+03=C}{2*OQ(f@~^I=uG-1-l_|m!0;dJ zV-uRB5ijI3V2naWv3#tlrVs)YNud%B$-Hn7Pb1|*g=Bmg9!Hy{c=2!ac=38K;^@rvmwz>ti>1S9^%SEPd6_6G+o(S6M3 z%?M%>THzI|g%sMLxrX8wGRG(!>Wcy(D|8WWGO3_4@x4k4d=Akxk_MaNjJoC}ih|J~ zgh?v;Nm}lQnk)~d^pG2SM&Zsx2{%?I3y;9@INP!E^(H?LH^MZ`Z?#(7?>-o0FeY%nKFeH9XWiBpJMqmOk{$dN|LfNDO zgVrY;F=*dpgaQ?$zw8Zlno=nxXjq;Ch1|j_wXi86$b;zrWM-JMD}gO6y$#t&;^3%~ z5=rQNB&Z?e0)9M*5;Z7-mJ;3wXn*MKECg;XA}CInjoBb53;B%-&%;-&NeUSgKU|64 z2qFlg!bZ@7eMWFDy2xiTVi9@K@I!BfhIg%*6W2k;5dBNtEQgzQ#kW zPck(kW0sD5A|myaAcJzVCl&@YZ)Wl~rgN;$0Ea_*Cdv9lqy^*SP*NoL%448LgV0{) znGj7d3W*z`@M>gF0e}d6juR-j>b;^QA#x9>#O-;2h(xYwLnP!iw#Tlx%;jd&A$9}8 zSja@M!;LJ&O9Vjir zfIAWAYwy93+GpkmlFUz`&t+5j`uDdY-ZKuIPkgKh|mqx<^l zL*C0nl~A$f@AL%gvGj_p5>7sr;!v1yvE1rS6K+mhP)+S*0)OqTqI6XD4sicgogcO8DUr>#YF2q^N=oaMv=x~b5TC4=^9s*sYPFF7^!`i@SsL{Gu zaxOT*i0U%+umX-2Gc6p#F*ITd3=y{qtiU8OxMFEUw}~c|ts_{}er$vg-F?xeq zek@*Qq7?vbqi8KCl&8AFq@PG(IhupHB!XIHqJ(PjB0kareIy~IC@B-5nl7Z!CS*hY zr7#Z1zW#G$M#eIfXTx5jBr%p$0jd_yCAB8xATkyx!ehPIMZl(REyjWj#H{alR%YBG z&gf=7xJiVlLdpojJI#jZK8nkpf<{XJp>?f$FjDSUDBY&bEWP4%H8Cq-H-yT^EwJ)+(QSjE z1AmT#hWHI+<$?n7!X}!{O4cS+jrZX;qLK8-87)Or+GV6Lt26?sk=&sTa*8GftdZ=< zSmsCqg1{ZwR&Ma9Tpps45X5KTs7V2)J7!Hfpx49JX_5+}ms;T#MyiPZp$$IFtR(BE zVy=Jvf(yiNxK=EPrj((sib?SQXfn=d)*Q-PG1ZxlR0Q7(o6b=qg5yDgsENpA3QjKg z9EGG-sTG*4D(vAFK4ZyH3qgp9YZQ3UIwr%o6(LHY4Lp%1t_UHbN4gP8=N&V_~Tp$#z4GOkXIY{MBp#EB3Dkht_9R+hjd<)&m}KJW-Vn8=48_2{D7iSWHYkl)v)W{X>B8WCXqDsLP zU`$^&>KJ`wZ+@YQe`84EA~m8WMzsfGW2p|;>3c}HLl8ub+JPItxT)X+fc0k9qR$xz zf>!FVu$;$)JWa@;O{IGcd_zZ2E1C1f9;pR}jQ#2E#uFf?6yF zLH&STfY;WmZc4%&kL)Sd#io0dWb7j~_{ArrKwdyGSy%!>rcGIxgjzKf%7AAwnuaxlpifMd`&zc3>0*)eX3oXeUW=eT4G{HB z*$NYY59rzul`n;DgO=3@3sd#3vNxTwDZ{D&G73Xny~`7$*q0qYU_IGs zoPU-B;MRQFks{iKecSIt){P=YLRH(j-7xIL2Fbk_$6eT4bUB4wDusPC_I&YR1V5a8 z(8WF7@jc%SgWdK0)jze~6$9YOyx$4F;0^xZU)|dg9#j>c*%$udAwJ?Ie&Q(};t0Os zE570}Uf4yeFiI=qL4Mme9#rpL-vu5qM!wJqz2p}?gq>7D-BpB~N=O+oNn=NVJ=q@BeLBMCJB zK?}g0%NxEpkp1O@9x-73>5knfB-1>M!$#sY;Q5^}wnkK}9#^)e?tvWd^Bmueqv7X% zPDV@bqkixyrQhS8@MqqG$eniieCY)P2u2|a1dcGaKocxK3KBvSHX##4!CV{vJpPz4 zBtR3!!1D9dCn_KF2?GgMArp|G&V7^BrC_2LLJ8tUF{(pmKI`q@zA*e7vJ8+>VfWaKy)h&F3gLuv^Ly;iL+KIUC?+4_?f-bo{{8`?fWUzS3mQC#FrmW#g$xk_ z08jux0)hb|8cgu;;XsH4Ayz~%N)r%;6_Jb+HPT>4ivaAQM?4(6kPcQJMvzj1#$Yp+=2G3ncjW4~WquU?)~=DA3+N zDQJCata!HLP>B|aw%z!%BUQa^?fps;ATC#qUkfC8xHE3tf$qQ-Xh+c2zhD1a0azTg zt6RjHH?J%p1uWPpmkpAte79rX)B}^)ve&fj*MCV=7Ujx1H|Nzsw>Hd(J0kGh#1#VP z?G~@_jmwKWe-1smz}V8OGq)}s`Evx=yLB_vFBn$7#Cwj^$92c0zkq_6OsaO zy$)=OWL2h-?(tG@34|8nWP%q0kgO90XVck7(0>9cW}kU~393*13B;X|6VipiknC-`5N6|Xik)_^TI6a%wK^wjLATETsw=M)<))#p!Vc>z zbwdSlUI0&p5>6CI*p$UcNob;tDA^Dcg(jkeBSlI8Bw>>%kzn*xCgNDDNhD`xq*DPV zWrBz(+GsJ~LsHnJiBua&GKy3qT?RlF4Nzl&lZ3JOhD{m@aIrs%^ z;f~d0q?CZx?Kn-_&;Uq4x4(!5M_=Ym-3+j$LIs8*k8%O*9*G2DCkYtfhM1!sNuA|p zm3m8Wdh?ltY-NH*$%v!o=bI#X1~(IA&O?Gltm1$$gd{{ukxIy@o~W=_C~V4 zC?SR~)ZAr&u!U@>BOBXN$9|AN3Yf%XM4%DJ4#nXicdbH*|LPD45=Ie@q`*WtiLu}l zV-gc_gd!r5SRzc+Q5zu%C=+y1PZuLWqO^?yi8>Sq6oh1+0!ZLoKv*LbBC!r6AVC}J zxKI=`6p3wx0~_jy2@q110Bwxpko4(d6r(5(bwz}LrwWmN(g?Ezo=iv)nL>=nRDd@8 zV+*Gtg(uqpIpx`-0RKpx(^xqtR*p?FQXtDe#@0ToNd`0p_>%HOBe(>tQY~OP3;-lk zC9uFP0eSlcD{EszqOh$>GIC4;C{rb?O{8j8Q(p5}nN8T(5}d3I!f{p-fMklsn^lXE z@h|G;Tr3C_dNM{sou%{qmq$r8=x zm-kSB>;_s*dwdHl!-L#Ja+FNj$?=ztvCQsIuB5Z8yJVGy z5Uj}D6@?^3AretYL{3a1j+RB@CTX*Y$f9tSkpVywEZfRX{8}*pVAifr;cEdF8->&| z_F38ptSBI1E+hmp8zM88#0-PP*FvFXVj-Ey{|aD}{S@}KXWEQ#WTum}CPxbFfzdow z@}=A&q*+)iRo6OWoftspWNpQI{ zl}82wqbhBoXDu6f(9%<<8ST+7XSrsVZckihmoW}83|NarM)x^WelUtEftetYTb~6 zf&`q{^oS@+O<+yA6G3$P;2{t+ z5m|vif)!{ifCB!QmjsAo6ztPs8aq_#Q{6d4qmZ@!9(7EU(g`6aZG}7f#6? zOpS%+8`0Q8a|0c4i_Z6tcI+g-#v~=%x?Jy}C;@9+`UNQ-ZoO4)#Fm7L$Z1x&yIV4h z3>Q~kZRP|w04QL~4}lUyP6|$7|FTk!bfL{eDpR>Z4TKAHVpBae5*p#mCY2-|)M-3f znbRado)HP!D!rnX*8Sv7QlOOb9%5ro-sdu{?UXt*H5J~6lpde%ou)n|3Qo6vkxK=&?*MH4QXem=N%m@~ z8*x;5%tR5IV!F}9;k;HpA0E&93epM*D|9?h`qc2m(wLU?2}oc98hJGdR=`!VXWb+mp}>ZG*rbVmy=N|R4Q=<; zW-SCnA``GhKJ$T)g#l&5|6|rFfF{(@veS;^w&0>|N@Ne*l8qz?HbKHjBoP%!f=)4$ zS!#7ouJJRd5dh|sHq=2DesNO$78(P$fVc1uE%I+rgEwlo6;y7xe~SWg!KvKnf&B3R{S9Y~wi^RZ0Q@BeozdP*NT(286|v za;#)Fv9l2qAxdNOD|NFJgY!u_$QHhoOjfc{|6q6+^@0j8WBe9B_S1MqvKW@4A{pU7 z4FidF)+v%0Xe*H_|55c+nMfCycpLq39zvptcXKlQB!F*$X9n>yqF6!K0TjyBdfD-c zvm$z|=n%1Ji?@i2&XE{Qbux&s4v{btXORhc)FyT0MyEwb2(U5=wFQ#!AWtM8OciMC zMnvL<5_^Rb8ZsY3(jf%Gh+RY?$+iwegcPEHXv_0N0|E(aL?C0tMXL}AOL8t8ksgW^ zI|+~tc_a{HkZtT?RF@$lBmx&@6o-`YTzoMQ1El~1RRB(h5e&Bzl9MBr;)Z3HEEB;! zs8NUja8l01bL=%IT|+1sF$JX%PyPiF5?~`pbrJvI4!dz08khiKBqO<_07+<)qeBLz zP&fckP-P|;|5frhL-;tv5OCKDX7Sj zo@aWwm=LVjDW=IQrAZvxF^eU{8?Q-=stFx^340XeFdc&kcPM{$6$PU(3U^gk*boJq zU|PTiTPLwGQZ)+Jl2~aokd{Jx!e$c_VG~+_2m*r=2_Oa8;+#=X071~5*hYR>Lwt~s zE$V;`|DahxC2H1(JXf*5J_-q_Bk#EU@qcOc0 zt?)`mC`*geUxwBiN7gjv(~%MOVg-;sE~*yZc0L8bIk~eI45JqB(>0?>Hj_~sLBJyZ z#WX~E7@NQab8SMUWFp3bS#9U;#FikvkHw36vpWHR@e$5Mg2# zJaYmjWL8rGQC?dJ79x3M=YuQ=$2IW77OUi?Pxmbb8K=QxH4s)7Nq~bPM;m!YXtxn3 z|B|X)!(pk*;~SOQX9l<~=Lo8XcBw_?L78f)8WKUOF%>Z5iV_s6vY2L$!e`Z zWNYexTk8<4(MYVdR*e?)7RCq##^|e#R7eB@0K*up+t?w`rVikFt=SMo1VUzZaT%QE zZaoDg+M#J47nWTYq%&s^Y*Aj|WEmJ?ff2!Tywo+`^fx<5O#|^`rqfMOQvf_CbD%SG zA~i|mS`o-38dDP+jxnYsnoW@k0FpCvNg5GcLQaDhp2{XgV0=yp3TU438?Cx%z>zAXLco>SDyiCfmCLz6VT-lO z5UYX5btjN*P&fg2u|2^%~KMmA69n`F$(nCGV zsiC<>Ei6#1)J;9l5mC{)ANVj_8iiMCWF>-xs)W%3=*0bJ=09B*xv!yKV2)I9nXG^t9HH7;9=UolFp({*ayK) zq1Sq>z0%TB29#65bBPzJxDpJA5P%^N1N0E5!3jfC&d6-snoST|DBCLWGR7gt&Yh}@ zMj@>76FECI-oh6JBO|v!Jl_zUst!bEZ34~Haj=^FAuuB0cEZiJLu7GLOKcOE zx?J3z@_9$%5ecAWii!{i1t_QJ9jQIm`>o`bOGEkX$V<*EQ4NLPF}w&7)x@!lPHqra z&Ki^pIfiFQxa>V03iTk!vVTE- zOtcf{8{*(_q~{yw;Et$4xV=H!`!9hmDpx+e|0$!euM62scP3y%`xmu$* z81Wj^lsFi%I=Dj@O}IFNk^t$$kZ|+m!(*}%VGCp+Jv9YVxWm|O>)lgRITBG~hVdFa zI(9SWqE;CI;SK;I*_3HvITbNwvEFeNYBhj<6y7Ei;} zI=W*uT?QHhl}uApY;$ot*nW~jVK#mP@jfw;paK9z!)6Fr865|=O*wGP6ebCeKKI@f ztFr|M1}2mwcPf7G!hU$YZu74q;5vmu|Gyq-2VT}J&Dm6quioJ?#UT#FGW1X0n*Y7A zA>S|o&@_4@!w~^rf_tI|*X-x2hx zi3zuOE$dtW@dqB>PgXlIO@Ln}|1qy9wv!P+Xm@P6Ww) z6g`$9ltBj&QVIwxkYr$i0su(;lL83#rNFNOQ+@&% z3RZ3buQ+YlOIQ)%Qc{m0S}Z!&GE1B`OG@V4IiqLLp+%4G%u#e((wsMwHl5n_YuHd@ zOKv^ewdTjDMc207+xKta|G|Y1Ctkca@8PSBFYm2@`E%k(pxYKV8`5;*n@#5&yQS4X zTLz)pBl8$%$X4wNl$|M|>`li7f2Dm~(ICMBL4Jv?NIo}0AojCprkOfwM~Ze@*@O)B zHu(jJnfybj4aPWo>7NQgTF9POrV8u9ifnqyuJmmA=cNKju>}a8pdze*^jfj!mm~;m zjKI6Z3WBG0eu?O>3IXu09TT7OsXUe(3!g&idm2A9GIqVAUjL_5& zHFVK08FlngNF$YW|58dTwe+(~Q`4;gAUeCQ08B(vG}A(nBh@XI=A!QwPBsGoBT}}w zimJP&%51#Sx{@j`pSZ&5mdHl5(n#(wb4UtXNFl|gR?6D~E}Zt$&?pO2{HIkH(QD@) zQf#Uz#DfHC7Fkj_N^hr!6e{aYFVPLrA_>s4jH8pnB16`j79!=%fBbTYllpe*iZRPj zy$mt5z~btzeK+A^io_BcaXXg2^>(Gl-a8mIQX+CmMS_50Dc+0#Fp8?UAp7he{$2$P z+{|)1H9MM@8x>MhXMXKwohxlEXHtQ7P3YG)B@F@3P&1k{qI-7wX{eurChFFbNY=4h zACpirl;V0S|1-J-4I(Vn?4r>z09XcTYordssK6V?yJZTWei7+Tvb-#VO$$+4s3E8T zx7Hwx3&jL94C5Vb7h^(Uw5rdGsj95%43A+bPFern905(L88K+4sggD1< zP#aZW97*;Z(nzvrTbs$j0yp_bJoiQ_us~#2+Ts?B14T%8kN_Z0(EiHP8YPGnw^7ij ztG9l)>$9J&Y3*U-xqI-#7vE;{mdix4P=>1xI#G;McM~b3AYL+8(28HO_|;1*0fDBF zA_0zM#vW4HLX8k(m4A>S2?UWBOYRYwPT9{WUz^vwOoA8yq{$|2$sbfWB7veT&@@6B zODm!z{}d@$tsUMnNmd9(wk=35MK+NFc$6>~YSpkqQuu{>4u&eLbR-FFlgo(^h@!t_ zF`PRux> z0DCA7OR0mA1jHpfgDfivJjqKE?$HVfC_yq#d$u*k2OsD5B3&W97O^rl0XC6 z(#AI$OI|X3k%Zd!Qo~72hO$!9$sQ>!6@^MApcKFO2Zp@z7&6*}TN!ajE2Wf{Qeem^ zWEjxESVKeV_@Fs|6uhk3rU7TG1BW{p2GM zDq@_bD1G`#Ftlk3+ul$r(*^J7paYcwu;`0!^=H{?UL#%8pNmt#-EU`$XtX(U6S>x~&|FfIr zY@|%J*UmPzt}}B?(>fKKNNUG1ZIRVaHqt21xQed;0_$khB_0HvmNvGjjc)%c9L;j} zs7y8LXfGSw&?Z;8%VjRqklWnw$u2fadv0h(W0q5<7_<7daA$m5SkkOUwv+V@hs$eQ`+m5?D`qivG#p?Pw^*nu zCQX7d*;s_Ul4&vSD|0{zG(-X5sY2CpjYazz8(T5~MYfGih-PCMKkdau|BLb_k36X< z0~N|uX4ICK69Gw;RycN~9XL^wnE-g1Y5#K{k6m*Ynl7iRzuDAkq+myZwZW@>4a#B9 zBWBPvjdK|5O_Jimn*sI4&0J=5qaA%oHDA`0k5&yQjB*lQf~7?|g%LF!!XBumEK#EY zHTI+n;#}FTuDprgQQ?Thrzz@Lx^z(j{`S4gltf^gCQT4MLnPnqTGU`2HjXJ>*(?t= z+0b3|u@Q2{DmR;`M3WI2ItC-f;&g0}`O#?)Ya37Ysy8%lOk>IYm{L${PbXIIcpnl; z&<5F~h~iMTalLL{qm9?1>1Sg{jM|%yilL#Ec2Sod92Fnj*_tf4|E3oH8bsX2QA?$; zD=exMmSn|Ow&e)jT48ZzwmLoyQ2@U7MCOnH5I%^Mj0C3Om-!S(R(0u$t;X0Gtzt!H zII-gvk^~i`$Vwoskx~3s=b4`0c{4*4QVcnx@uK-vGS2hN(cxOMaMq9$@$(A*up+pO z+=qW8MVA(Mf|a1-3u%X1;NP&aldKRoG<(d-9z_kV&oH#ukAx0y9L(Q`$2PN?RCs)e zv-ZGKmg3KT6e=IHK2&2T(###^Kqvx)@0h5gq9I6{m;!)4naD#vc?m}iHGI<}x zr|0G65YH#DB6F$HSpLCU1Q?38NWla^0BTZ|#L>X<;+2#EquJRf4m=F!ktHd}3x(1M zmf4_esiE2{h*`q6^rHydBM5boiy;~h6d@8`i3!JQ|D(y_HQw+DE=d46#0@-*3%nbR zDNDf0LOe$yK-(}x3ac+01F}b%JW&Y^LR3JHZ;s1t`M1<;6znRu4SvWVmfKnElhMNG)Y zSV)F+HYP(VO&EoT3^5bxm=h@pTeycfT8xtc{|yjyi0%Uk5X>0<2mp5S5`<72$$}3N zsT^r}$2d|cBq2j%%n35&4N`y$n_!Q*K!Q}Uhpr=xm-r#oxGQ!-4UwSqT$E|2wa0%mCq!RJ_5j0f~(JL5?VoSnLX_)i0ys$GO7P}@nKkOHa$4RMSYB&vwr0kPO2O3MR@8d5Sg$lAU@> zMVSFojsP{o0)Tfcx4Xfor*MzWMA4G4H2-R(%9twTp{g56Pthm^cW{h}Xq37560kHV zlyI_y(4BJ8Pv*!^%Bn6mjl}CQ|IGT_9yaZa_>7I>d=$uAI9C`Z!idnjAP;@%j3_C- z6Hy5l+=9t@3D{XElPSvYh=_A4tjxF^0GiaIP^ie56Tq^IRuY^*jSTQ8lTP`EGMH2i zO%j_7OE+25&`{6~xhQON5_Rd6LAACsG|mD1pbJ8X=z9wFppunr8FIXdJrhriY=c<2 z3C8#lvN4$iG9iVsH2>g1GCYPz~xv>;z-Ow@z+DFj|H&|5E=dd|KC}Ac|QxgH#UsR22PFH2V}E5Mr$e z9Xx}SJApGUzq71#Dc%0Mlr1A%J5^nMZC%&(nL2&l!Oe|H)jY)#nBds5)>xX$g$?dO zQ`eBU=~x=g+mh?y|6KsvTlfN4*=^q3ZNTvn+$w|D0HfZ=SddsTAVcfj^E$0Ln+@x= zshzo$gJV=O5D4o%lr~*4)^*d)uEU&@+a`t4u;{a*kkOymV% ztP0@!QeFd2U6FUHu? znhk;V-Bj8!4Bp@tGfKCB6ic!o5Tl`PX{1jIHb%nRORBF1E))~yVd&VD(LG)5VO;|p z;ojKV>>)SiRWR-fMc){>DlVJQ&>iWOu@-(` zC2r#;bHGWA|Af2^FtV~&9BWB^?a#{ZPkEY6Fs3bVrt|d*1$hikAhULufTNlm&-kuKL1p8>J<#ZrGdAJ# zy`7D73H4%fNNB~Z7g_AnYJ(+@tNZZDMlUCRQmg0g<2v>+O2&dSWBw$u_-GX*# z0}oM9aBUWfV~|aTDHJ>ja-Fd6wJ=47F-95ZO0MKp0It~hJcX#JI8zV6Sq#7^lI!s~ zZd>1q>I^CL4ay{qJYk7?A*a6xtfRAtMom3{G8Qo`k7U6R%~*(t0FRv5mhZ3!S5U?{ za)o>N|D#!w)(ashk2sM@-5mHE)(tY=!HXfC<7XSpS!B@onvyO6Q7eogr8X>(epzv2`xj zdlrhK1kzrFVE*onqqd&P=}JCgZ7WWmsY2gexhL5mh^pvpusn=*;F6(uSn@V)c>V|N zEP%biQC1~CYzH=%L4$ z9I{Rc%V44G0aAlLtt1OD`c3|beFyy#dn-u{<(7-*fu!UB+|28gQ z40&k<;%3IVXd8<@9uWB^=O_=q@ClMar=kS6qtve+ukzqE@}3g#`(|`Uca2F~jx;W? z8VV+Av1rTq)0IrleSS!bsG)Ik!7xo6lGLSE5|8?MDN%hFaEU&OX02ZQ2jZ3z6GsW; zVHv_W!JYhK+l4=TV%5A#0Ha`x#n_;2>5+t4lnuM#!<<RCMg< zc&9IWvp;(|li%!-`bZHNwm&ekU-Y(5UN&X>w})ROe>4Oh`XGlC?`^U&abeETc(gBk zI}JR(51&1C-@6a+uWISWw`@oe! zrL+JlpVb%Q2Wx$5cQnm6d`7AK+3y(%*aCL3V=dpY6|~TMaoa{_|1qri4e$8ozja|m z^Ap)3eZimOBG=+V2?sBmEb00|Qo1{>WX3iYLuTBviOi-g zQXo#*IAvr=0Gry7!nv|wLx&)ZlH5Yjq(+qr0~BcUkBirZC=E&>@mqL#HAJ{`1kL#NxB~s+v%83gMQ(cGU$TDokcFcu!od*hZYFthQPbdj|cI zq_Y3u)Z?x2AvV$`2HMyXQ&wf#r%nk4xvW7-{KLseG;;RPv}Mi+VnIp#aukXl$wZ1R zWEK~|s=}pq>9u{y=mEnG>Y2oM=xF4&b`Cg;;cylaMtN@)rtgwJ&FeCkplNL z`zl1_PGrxq3z1m6+*Xe*?@?Cp-U5pNI|r_r|SK|?<3(X|GZ0j*?U1>nwU1{v0lJyt)q5h=A(NXp!# zNJyue3A8f)NB;f8u1D?3D<T6cZBRwPHtxLrm;clK?Wb!WF_Q#XlU_3IH)^YH}JH z4}0jt9D)RH{Q4mg%hIxx9I=Q^83}C&606MtAP7`zNvxhIg`(`GCsfY1>b;w}lWk%09svH?~_PdVng2o5zzo2YaMU{;yP)hv>vB+afN3V@bXWHq`c zdgLVvuuuV;HTi6PeJ*g-fkyiG9hg198eplm~%*%ja)Z={G+#&bu506{1W6v{gfA|EoekV0;$$;LR+ zp-oWaEvxZXJD~EWFL6nUDqSf{TdJSvD1=hTiepJm6|^LN#XBZ58$z@;1*@SAEGa60 z61b263Fz~McCw`!10aE|fG0Il5USQn_oS}KXD_eP)JLGks&#=1Eb>8!5~Agh#dXeb z1LV-9&RW2$x#W2EB;QDa{}iGkg{O24*(*~T1HQC5$ZA4;OhXFdidHZwe^VRDVEO9U zt8HvhYJ8n5+VPMM7350^!JhmcQi`^@j8B3p;7BkltMfqWKTyiwgxpp`aGC5{^;zrw znCK+O*rRZ@1;Cy_c)lu`#719Q$Sq80Sd)SCVI8be2QOO@LV@H%8&S=B&NAAG05mop z8H~ap)5HlS!Hans?_)B^u7r@XNj-$DCkZb`$FzFd0!|3Hq6%tLarD7;Wh#@sDwvd$UX_sgAyJ_~f zK~4g~FBAg=^A?~T&Dw}fz&EDNY|(oidC4zQ=wCp;1SdT^2)x{35P)jaBE$ViGwZ1k z2XPgeHc3DbfGL@8Dx|;JED~6HCrXJeH=C*qNxyb2qx4F_MUmrat-pNz*5oKTr~^TyJCd{~a`y7u0@$N&eAOF|A7+*AFeYkQOWi7M zu_}TDSWZ8ih%UR#TB+L#20?g2+~U^xow4N!2mq z7G=Ee8sCQ?h1tTLt6G3DVl78jfnlF)l9&QaLNdi7)w4l`=58nH&clSVn!Gd1^;CIV zapwzk7_E~q0^u!QZiq1htTuRi*(#+VgNpV=_ql;bEAZcXoSc^#4ktK7kW7=q#0uzi z#4SjOL-3Q@6%IsfMKie*nPgjCY{g52&_dKp#Jra%#n-#MU!a8$DU<=M(UYXm(=#PO z8*qYaEK@-Ml%2?gF3H}SI1uF_)7pKGqp6iaOq!*9T_OP!jgSNvw1S1X4ora>kZ^>- z|8NdkSXxOO+d&{+0dPXwNI~cTiC2+RU4Y2sHIGg3%nllkBZUO5CDdLF+7+4?w@DU^ zNSkd;f%RbsVrYg&lvC>gVjv1)LD*gauokCH9G11cvZI*N>%*x15&((UoM}!uRwTs=O0f{8~i-fiWox0O(xe1c_0Fh@vC` zm*kHEB*360K$dO6QI$l_6`6%l9C#qck5vanjF(oNj%uJ!``JP;E@L!87kDtE;qc!t zF46TQQpHpG(pGR*+U1b~kVrxdQj%=ipN)wv2ul#y zl|c;BYcW=BB#1Lw;kP`7p9G0kNQFPT$5Vxb8j->+KqQ(ZKxGZY8O0ZExX3|?W0AST zy#z^sb=px3O8m^2>u^MHsNGEdAracbE;=Jp9N}Le*b}bMRJ~-C^aq657B;coogmA( z4Psi(RZ0{M(+G`QUIbi@OVAXeez=O)Bmv~~24+x{RWYMo%osF+Q3CuF7F|+P`q*KH z5^QuIvUt^g%n{850R8;KlC?t35E792pF+4oWfp*CE`)|8q)1d(64*yo|D712SVfd9 z*^>Q4TtQLkWSMGIWlLCuE5J%mK@LRJ;@rtgkR;UdOo%>qP}?Y=kbK5SF2o=OM*?V* zYP_9CKpq+Xfgn+Mh{NrgwTa`|AiK%EmE1_kA}#L z{`Ae$h#*4}X-ZTS?7WF4MJcOEz%OpmqD7P=?yCg`Y=#LsDfC5aW-v!Y^AOP8% z#JTPo;Wj&O#86zi9I>$iSuqk=1{ zP)q=b>i4l~kE92_1jvlJYuS8~%M3-6jjM0~fqIC@wk}cK|1Ae@91x=rN4tFmwc#tj zI_v#p4EH&TbdZPRwguSg6qK z(l$q?G40b%2U?cJ#A+zx}5E`;F@Zb|5E;--q)+AX>* zF5^mWZv5@!T5eiK?&WIk=Azr<<_i+7rOzsh;&N`o|Ca9Q?g!$UF6y#w>$>jiLapb* zuF;0>>;mbU+HUTWO6BTq@A|FpRxI!e@9+|D@rJGJ0x9wu@A5M5>k4f1LND}YF6>Tk z^jh!rVlN<8Z}ws?_lj=RDzEp7@A#5$`3mCMLazCG#rCRi`?~M@!mmoO@A~en*YfV$ zKCkM9@22c;{Q3<0&TrlN?*J2Ua-eSkb8Y~WYx+j*=Az{T)2sp`@B~wE1-owlQt*vn zumy9l>Pc`1gK!9o@CcLea(r;}Zt&2Oa0-`j3%l?OOKxGoFmr_I`<}4n-Y^2+?+o+s z)9&!ZU~gQn9DZZWIHr z5N~l9i}46AiWf^U6Z;Gp*DD&2aU1&(8;h(O3nCWFG4;Cf9pmu}!*SVWPaXs59{X_v z8!t|o@y`Hq{L<7ByU64gGTGL#?P~GLN|;GtF}cxg4^?uKHFEE6av*0|CwsCIKXNFO zaw*sF-Im)SQ^yB`veK4vs@!iYzw#`D#3gg^C~xs8)ABBptSa;JF9)d=FDuJq(S zbV}>)OD9=N!*tu$^ybp^O(%3t|1yS=G`b~obLcY%zmY<;Gb(%XP?w5KBQ#Iz^iyxH zQX9udLvJOHuSi36R-+15Cz(`lvsPaOQ+uydzYFbJt!o6eHhVQ#v$ZBqFj<4}PXn%8 zCs|sz^B(GnT5`2#{}1mP2#1GMGZ z_I_mca=11v!%c6~w%6u%a1-|+liP07?8ywNWIt_e|BQ40t`b4F6eIWKj&^o1ckyO- zadUSEJ9S?x2URN(c(Y!&7EyI~ck698X^Z!`wzotBji2WAdQ%vEr*}wz^L@i`elPEI zJF{2#H`Cg;em5?GFD+*$uYq$cdMkK?Tkm^2_)LpzrvP^m4LEZk$AwFHgmZYRRJaS% zvla97_VTLhLU@Ol?E)k)BcnJEF?jao^os`#c|WZJ47W*qcvM3*a;SKVPqL2}_bgpn zN&t6`Td<4=B7$!bTidsWyzefMkFS#_$BiEc0iQS#T{)C%c`94(V2`i_2e?SkILR8h zUvGJHeAt;&M--H}8<)A7_wbv;xesMIOG$Ys%Q**AIr;K;Dc|{)m~cVlIRnS=oWt&* z6EUI>aE>E+bG*}^`>&$6IHW7Hq>FK%8#=3$aiI^*p0kwN)_JDObEr3On~S>ojyVEj zt)){3t9y8K@AIi=HKk83sgtdc%R0@v`XJgmX@|C1&pEAQZ=;`Vs^|K#`w(OY1OOrV z1O*BJ1pq7n000261f2o^2>$>J2pmYTpuvL(6DnNDu%W|;5F<*QNU@^Dix@L%+(_{j z$B!UGiX2I@q{)*gQ>t9avZc$HFk{M`NwcQSn<;JK+_}@9!+#-t@f=FDsL`WHlPX=x zw5ijlP@_tnO0}xht5~yY-O9DA*RL&IfgMY>tXZ2L&nj%CwyoQ@aO29IOSi7wyLcJ4 z%d2rO-y0z=q3)@XL=!!G!+jo89-tAd8@838J12-sqxbfp(g}$6UcQx|o(4$MAPQAMI z>)5kHEUvw~_wV4ti~k@0(Kh+>=+moT&%V9;_u^~8pHE+{=KA;vGSAPyzyGfL{U_jn zJw+rRfe1=vUV@Zy$KZnyisxH|6jo^Ag&1b2;f4kU$l-_c-3Ov}9_Cfzh$yNwVTz$S z$l`A7yeQ+0^ofX&jT7NWS~oZiU0cQc!fSC>#Qh&%Gaj2_KFg(8y&bMu)Y?1TBAGNT9>lM9#m_u%z`8= zfzdW=?MK8~h3vK5TKH_YPi_k?fvS$1m8s^YtM0n&w(IV@&!G$Ny!6&<@4fiutM9)2 z_UrGz00%5ES+>YK@WBWtoD@(BH|+4k5JxQW#0~*_MFAI3tntPW55V!qAaD6?$Rw9+ zazW*utn$h%x9sxEFvl$O%rqmMa?LpBtntyL(66XU!Z?yCUAm3i;%dZqb#Jty}fJMR^-+jwt+-v^%Wg(D~^;p4Akn!BJ z&*%D7X)n;(b>V-I{~!TiK?G>O0%8Pv3h|r#1k${`6(D>cf*{KlNS69R1c3q5gaK88 zyMlPmeINm0P5ei}`G|0XC}htGQ+O2Ntx!za8pz20ML?yMk4gH=+9>*!!-VLqflxu5 z5dT>?kQx#(AvZgs5+(A&CE^QyqHAIkok*G<^2CZ%%%T>z2$m8;WQr65VgbacE--TO zjA%TI8Naf|G@cBL3u$9a1n9-;*|8;W!(I~V*eyA_(Pu{dqae8k#{#s@j|d^-LSi=% zMJ9xg7EA~NF<2Bz5=3u-9Hb`m6~0K0#FGOF#wJIJD(aC0bw~k(NORo7AXEqI(DiepXX7`_SdJ|?^aGjJq$Nxx+ z^fM;^^xiz>EP=xx+ot^<9JZAz?giI7675(CLGV0L6Ei@}1O-(~# zGt!QNB@!l$2uHDbla(5zqyb~6AVZqch``h?HzgvZSmx5WTvR4Gt;$b{($j+kbtCRO zDh_K}RLYPuBsA^iMc^mJjYQR9O-;{G4cRcI>MU*?b!6Wl!c4E?hLHg!h&>&$)dSWv zU1ohNQJ85EX~?x?S=Go@M*;x;*_0yy%qw^ZDAPImRA0F?pfBU96jRD1ZhI|>8QZGY ztT;A19lR@U5Fl8UT(*c!Eo@RUN!g3gbs}s1N+21l5z#8dwfaiy86$MvRaaXLxUON~ z0~$OD!QI^{#WlFQyIXOmElz?5hvM!O*HYZw-L+7pI2Bg+K3HSygZ&%kJeXt5_j>MX z$olJXO>;Jd0=6=G|8x~Y3ow+y@Gb2|!;>#VzA2{5o|g$Bi#qkpTeyKpxYl z_2ZATE`&(oR~17q-x#|dcuzl_(5B}vdq|j9SKi}Kn{P~^Um|4}EDU)MGs!F&#GaEk zGhN!*nI7!COq=#$23$j^H$^+Gj>d>Z!IY0K4ZiAO7MQP~VH)HcS#K2@<$rz9-Jxq* z8LbX@oqwlzLSt(ACMWIf{oCjq)@O7S8&>(FZ^M;0QG*vpT}Fnnrs!&kO+_}5r}eK> z$|~&g%O=Od)mW1pzcsQ+_Lum|$7WcCuH1LAg%5v_2*XO8l=4XXi)R=8V+mlP`29x0 z8_)CX$lm&Uvcg?|lhl}so3?#ZGM|qDO;==lqgabOxWhg&vBJZ?p1&G*VHlO&-=-ctS!{BHf_wTAIL@Y z!M}Y0S-)y&La;_*RdjjIQ?4NFY$IxkNKYBU1pKoO;~hMYCk8yLG5UO)B9vDyoDq_Q zLX7{?+59IeM-A)pa((&N()$9+5>K|r3F(gn5q^RCb?%424`x_3-%S(iG_ys%GLJ0_ z87tG?*FYM#xd&d%`OUJc+N$Afc7dbum`zy{6hgEnj>nT~M6GyN|3po|YbJ_!wKl_E zeZ%t%^wPIY;^9JtRYr?>`d`Ci`h2Oc>r*o)s9|O7=0go&zhT~f@}4u7GXcJT@*mQu za>-!GJHUa|f#13RN7j@PvUd4=u~}uCTh`F8O6FFx3r$e(##bzsBBA51)sLJ-&Q4ot zgMpsEVjkbjiOjqNcvRngc|z|fBiUFD4m;cqKx-)BGL`tArSnR?xib2CZ%q}5nwG~x zz#-_3wm&v{(}}c4rND`y?wiDH{RHUyWGs#g%FqYW{PiP4Hu$K?6QE!j!Xyv5@q@&n zIsp7Zy-TidZ$4lkG{4D**hqasDg30|7h0bIJSbPUxe0mA0Fzb_P{Km#q(apTKlTlO z+-3x$@P{M|1o?!D#rcHc$>GyH0r@M!NRstZ-h9w345tH$%lm|m>F6=e*}{9na=pMY zUZG9W&YZ}R8B$^M4Xz>x&#|fG_^-u|74*#wPN^^+$+9>V_16DB8wFuHR5!+^* zQgJoM@*`p|_F}_P9WTN9JPM+305s?Z(n}7Y zEdaOXBDm)^{>zin`ywAKzj&0w1iihmK0e6d6Ug2_M&R*@L~k&`mPY9} z5k7Jjp9#?6$>o*>~>Py!c}(v3)NHbCM&0}2UIiaMrn z)2LtECtnE?P3fi5Nr}k_kzO8ZXry<^qR2pzq2OX=bOG@+0N z7(OD23K@Y>X!EZ|Przf|6P^xb0C_m_l3ml=Dv%KPc(7LzVDTraBdiQ7A?Z=FngIls z_?h!O$flJL-vD6B8JO1FyF!jIfh23yGM(eCkCKNO1KcQH02pf+hQ^IC$K&``(T9~r zLUt{CgeEF$j3@0GNZUbqwc}}1=gH0?Vf+sc`piN)R!QTu0&&&{%F9a2 zl%)-wfuqMD{bv;1KDmbaxt7DKe;RVOUxo7Okli~R!JE$zEO!yuY(3&m_uEzbg3I)OF`(gL#FdrJis-91d66;g+R zgm)z*4WH>AfsCw)!6?wga1IbETGP{+ESVAQ|NUd>@t8sYhgB`&^X?4G>@-Lq23JmOPvT5f#y<&}I{xc@P zIIqZA|3chXjrNZmga+lHeBp2W!rxb~0czkX9MNkvuwfJt4^OQ zXNn=%IcW8R))raX`eH@k3FCk00xw0gRB>6EaxE{7^8rqLEwgX`Iv@jzW>eI1Rl zz=H)~(ilg~XUn&Hx>;S2<{(0=Co;F_ zDyTK_Sc(YI&HlQlD?gOHi{%s0N-$UP)snVSWv^RMvxj`IC)2^P;}`2sETZf4n*1@M z-%&A^K@^CzZ|~-6l#m6#8xy|C@n;P9DuLgs>-Vjaj8vFObceau57Em_#0`vNC7bNU zY3iah0l$*<=ZDtPV|NnH^$CnM@fY`_NA#7y5K^;;$?z0%2NQAz4=}}X3CBS=CkY5u z=%ju_=(-1H*@)`>2fsd09;^(odU-$w`)ez>92dgb2)dPZ2DNzx-`*E_DuccT{o9#v z6UpKF_1tD2ntHZBXp2p#q+*iwbBLY=zP3J0b31^?)IUs*kIz`$RMqhfi_;~CUJIL3 zRH*KA#E9=}O?=QK{*-*XZ4l7~z&%Ek(CC6QoE-mbmNadXw0^sC1HcGz2LJobVw z!zCD4?7iGyNRH8{D$@&G7|XRBFDDNV+$?xIG}LC&rK-@@cLbzJ*O%Pr}ze@zGCwuj;4OFjoHN6zRXYVOvaoiyI0Xo zpKW&R&}etN;VsVxv zbk<_8dk=FCFC{maes0QYmac>VRcwm;W{#zA?p_oac^~u`R~H*TB(qn@Y&lmE`tGA> z(f3z0a&EC{Y{Wc3lnv`EJv$D?+kk}5J3+Kp4CykpHJu})kk(U|x2Ap_QcW4%YFXS7K?QJ{@XtRCaqL-kB%N;oc zx03|pqWlN;i_D0yk2vpYXyzfHRlC9^<5Zm2&_ybbsZhyf?$3JpWq_!!DYC@NJT$Wc zd#OzRCUH}|CZXY*rgr{|DZhaMe8S-eP>9d>QtV`{x$9)PMIhx* z|6#8>6`12ShAa-bSPULHO8ICVf~CfH?@aDcOK~Bzv)HXkYS}FO9zQMmV`~g}!1w^y z@=!UL^v!Q=9+v&<-{88tq0jbC3l^quAz9vgn%Uyw{^Z_(W8m1iuFlV{y1 zQ1?B=v!_=5BUk-jTRa{#2x8qrQ;W_mwcLgVDVdend&x8Ji0lH8> z#L&gmNAbbwv1~trH1fm{@gFRQ=WG8hdhPw#G$XmB`(chK^M;%mk5e9tUurgHkcXb5 zAfH@vQY?MkYAfHq`E{`m>SBOcwBUl+^yN3+gNy5oiW|O*fv>g3IE2f#(99tn%2y^S zSwGE?^x8>i8jRC#-mnYKzuT#KmPJG^P zAU{D6`3wQ`43|hE5F4NGhZ&L2A#oXv@LP3ozHU;xBG7%h3i}f<@jvxA4~lnqxuq(W zxU`qUzW8Epz=PsztiB^}@;xBUgGk@Kq9vY(nK>IZ_j0Y#0U#NXhD&Jb~#L*gaC9y@HxSZIH5Zrwxe*Sjjyxj=3*Ou40^ z0WHrLVa=wsVIEzo=81DeoM6D zxB651jSKXety$P4^XjL)KlNjVpd{EuQ$p!jBKqXj`;qb$c_AJNRM0CKhK554&D7YF zj>4f3k093EhsF?am^t7hC$8W@#NMrE{1DqW;u6R>?-kUmVQR zK2bv;QPb`k{Pm;u=wf*kls1vTHt5#Yy&#b_}-e!Z-L2zNvXgj4f z7^wGSJw+>P6A)O(CKt=TvEBYnWf%cBWMrQ|px zPJIOXP2KwLL@rTiVLUNCJPQ#f*a(ioae9Qj})qE zsIkT9WJlB7b$IE~W?r1-+N}m*imer>TH`gt&W+SRI)B6Zlh)@HCKGoLDpNyspr;Dl zaIJ+xrX3sDWaLj7*i>j$u@@bY;(X&w_;n8RX!IPIcAb_wBB2`rEQe7N*SpSMfXfFPn-mOZR3S~ z{ajk+(fr;?(MkP>)U;TQev2(dbxQ(IJ$YK^WFI5fHZ(RynXyi9T1Wj@Ha$cPJRztn?|gcJPvAr#8QO&L5>(!`(wR}%XS{E`I!K_z>7FA# z__?Y-#VE%knbi-#CPu-8aIs|Csgs;ADLcEaqLu$DIzwYb;jzwrRbkXrfQIn^b72y@ zZ}Q+eHBT}+f%!)I%uM)2qrA;6aK|d*XImRk9vkoW!_V_ir*0Dux;ve`Q{5fdPd8+s zQpGj=+4v{xmWZjHoL-;U(?_#uaD|IwU~vT&8}_tF$uuiuWcHbMAGd?PlK%Bz^ie$Q z8@!-iYc*v8os>6IE=x8LC1?lAc}j}v5&IenskShg9Pav?TN}UtA^x|0^=;W(=_Bdn z7zUFSQ;Xm=?cINH?C4t%Sy*Hw#A8n$8r^@OgU3$KPYNOkgJvlxhib%Rs88C1=pLr* zhgl`@JO&0+4HyC_`e;V;o|3s)Jp{HiEnSR~<>3EXeAqA4#?7Ot)G?>=7+KbaRsJJk zl3(6R0Ri>xqv_Z`ZDQWQ7fj0ZLU_=J64^p2WhIA_aAJ}eY}v<%@QcP8Tr84W@YN`v z1(jkmPg5v_O8o5T#$niViq3t9vL-^n|N5ii(F!dUoI3IgPr2!6f)7}l`p4vBpqV7j zCGYnYlTA zDzGPT(S#Ax#)b4%R3S1F#Q0~B0||E~0=;DyIg z&gN)H9*U4Cve=FZT z{Hn~KljA@KJbAAy+dYKQKu@a^uWH-cpIv0tQM$>vMI_J>KkBDWYfy9-P5*}>F=9sA zl%Z&p2yc(u^njr+VOGC@jl@-n9Gh|PfqBSDlR6|ktm{h3AjEp(UrRN4u3A&@Tdk0b zf;7bH?tS#AFsEm7+H3cr&p0vDm!KO>b|(5;qxi89>!Qhb{p%^;X`Gb_=NF6 zi&_Qr%17C^VGca@f0B;fNom`txh<)G&{1=*&W$X`*JD^8)T5Enl&ty`spKG*8O9d4 zlGD?3#2g}5pQm+h9!i?#t@bH|*f7VNwRo-GGrYHDqbF~5Uv*6n5b4yhXz*YKS?T-P zbJFbDCN}7+Fuhg`W_U6-%=$JxGUL?S?B25V4j5}Wxmx-Q+&qk?q`HFa=*XCc?GSw{ zzOK_>(rL~2=l!97lfAu+1wZz@tB-`-MkHk#(^J8Q5*G|P{_B3n5l!?WDPHZB+@;0# zDK^Z}+Bu6^w8{emqDOD$iL&G-h3x-t_niTplh3d&IS-h^-^I^&j<7NM#6D{-wivzC zMW_8pGK^7F^9tQi^{Tp%j0?(Mj{}_5I!;%a&)>UZtlBTP5V`mYZ71?LA9T=k7n6E( zD$eA7r?MohYq@`lQQ@@-<1#kC@hOR_Kf03UTbi{r;*HXAP6~2UXonN?w6obUn!iyw z@~pOP<9jW6fPZf<0EY)TBfBtOd{wyi+CLf9hd!fc`CO@n1)sl_;9lm6l_JwKcfv>g zHAypP)1IexT>l~37V&j7@5@0^e5*R4*HJjN&20{Pk%QI^X{(7O6SdiNQ)BP zG~xney+6oseh4K`Uc*r?;$QGNRzoCn+u`>85)1)2Z$x`>4ke$%Q?YCqaei|EFC?kX zgxf$;K&gsqBrGsHZjNQ_-&k^@V8F*BR=8Cs3b41);9DAujuaJ6UPANT`7N6WoXe2{ zNg-kUyeHkCXK5k6!3#i}N~9MX10l~mUF8_#?Y%X|Di#4WH_=8gi*eNSfhTd02BdEf z%3e_*GV#4d%iP_BG;xn?7$3X;C+CMLp^{QV0R+M%xn88h z#&8Nq2E8h>ad5xQLNF!_&9QL^f&j0kB>-!v ze7yq()-8fkMTQ$Q#-v~RH}XgplH#YJ&PE4?PD{9JF~Gz|WK|={6*V;iNhU!MXupX^ zAT7s$K|Ru-xJ|62Isr?+0C-)D#AuA9X^e(aE5uz_rs%*Ieq~Rt)(HwR+U3x2d6XxF zf6YzmDbE39rNVHE#eJ8zn53d;|keDzDqkfCR%SWcEpO zP~Wtm8gq8MTlP@NZszotDO_pXy}SNofSSw(ZKZ!9f_WOc#+9Ka+qt!(z)J@!-_CcN62StXaJ2SY@wor!X6c4H*$CXl;8!(;DT_| zKlW3(&c@e`ZKR9zcS)uhB4cO3V*Q%V*vEIP>*vrVho z84eTpu{x0!8b3^6stkZtjCpZGO-!GJBlvt|I}U~v=uLl(AjOpS4;a)GgO5Qy@DM=w z5@WayG0CM4D_9z+&}p?Ov{D5a|45;$USQn9BA8W^IUJUK0v83KaQ8@<@6%$zwRWOljn7vC`=OO~&7pLm$zc!8_gZ@2 zyV=(zGwZ`iZy|*H77M|$8VQJHT-()9)^SU;{MVY^%&<_^r2zJCIh3A1Ct+x7Nok^Q zYNuminbB`WLWXV#e;4j*AH zGVEH*KCw_`Xj&=OO?_3I-hwuzCU^WjGfW(v#S$uNF{Z%5UWZ9$mr@x1ewmA;Ug!9# zlrxK~i8hrpOC>cGTklg2am8?u)o?Qv{E{gHN}0^^0Cc0p62|H?(vk3s{o9c4gl(qvYCk0DZVQ@58f-=H z>TLH9P0Iz1yymfNAX=(5Qi}}${Tb3B4vYZ-&2o0sF zY7kn~EG%;+jt<~?kKJj?7a3&v2arK*H-1=J-dZTV`vHI_m-`=L-&8CCgo}GV1ORX% zaVB8C=xXz0w_xTaaFb=M{@Htd0x(k&W=UCD^P-Cu>}?f%*-Oo|j&syd!%`>OE94olEYRjoS=M!A?T~AT)4z16 zPI!oyYBY_KgVT378jP3`wQ4)#{j6f^8*?=K!CJHRXh|7E9qY*0Zq*cB0*gUQc1}FK z_Mlxz)r@j!>w5E-EL^0g?2$t&OmY_%IO@g2=8%9%yKO3%o?N&!eVzgUU+CLhT1Jmr z{HZvCG28iP9fca4{P4F|tHs&M#fib(gC`xXJz+6??A;6)iOH<>%d>V-0~}ItPTaGb z3t+j{Suq?a`KelG^|HQx0`7~&!D4zwa`6+QwgEHNvA(|W6)_g87MRv)swgKCnzFSW zZd_)PS`(n~-}ioYdmM!hlI`t&6!5GDxX?bkA5~ycTF9BzD%R+3m#1LA(8;!{;1t>W z?mF|`@HS!;t8{Zjn%Qr38fvV0S?NbFN=7+ z!93}9@Uwf(6W8pSC@d*kS%*Bj@adkLn{T0DDHhfq57p%ZBvoFVoh87$2;!R|@!aL-pn- z^%ZTf$4$bh2Uzpc@2AJkbtWBC9Q~UVhDR!Rh-ctsd{GGx&C1V2ch4+alW^|621&;! z7XbDf_tzd-z#qE-&F`MBa3+@MZzH~N3la=IE{yZ-pW@Hrg0E9|cV50$c1?SianDpD zSAcD^P0ya(&tS5O7WspT>&bt&r|uc}ew)#fr*?yYQV}@!NqT_`;6Lf>dwe&DmRD&V zOl#)0&*)x46eCN==eh4{VAQ4k)U7LB<5~d5^X7Yu!GO*99j~*OJRj~Z?pC*jmZk7L z%9l4WXSVO^pQj>zwg8Bo)!{>omkyzTLwqXrM2n^)AJ%;L;?;+@ zzqm*QetHEwxT}+`nE^V>N}?)!5Zv;oW`zStk6x^v$Xgh0kE>^^?Q%tF-uYvZ?w85! z7q5fyK5_2UcA@FfOqnpiQ!_H-D*T32ywDWlV|#K?dbC`=Hz+;t2hJ|2|3`4U3j)e*{M?(j* zJ6u!uM_>{$vJYI-48p)nS~U(lG$FBQC=M5=nlvMc1bi{43nmQ@NfAcw3JYziWQr?-L*6@<#R{!*ty-sh*5w-BG^ZA&Cg-Ul ziN568N{k}HMiY{KsDU>fG+9#bBZq>WEnBY2o7QlJm|depH{J1jVw>y1*G@RbG>5b1 zjbv&lg|Vy)KCdkdU|}_VA>?#2QzRwfB0_pY5Elf&Djq^Ft@)o8AQ|E9BDmn_QFRDa{Jq@ynxYE z{Ha3C=KA*mvi@~cEh1ezdq=mW@~TK0mbg3<%i_wA5U{2G0sjuN%M zWdOuVa3ffRgm@#GEJko&g+3c%2BQ~V)r@BBe4>rx!ELsR;~)1w2w+hwwSF(U|3sH0 zg(*ajz+5w+PgV>op-)MB`%Iszxz3-Ss%sR$5XNEEF^ez`d@j{{H4R%!&a@UjF3xhS z>L`QBrezhVxiyj?(o@d>hPhtjQH)s$W0gz=p_rr=c?N0E_6gyvPDe&Gghs%kZree7 zrAWKxEopvJc^273y`!@tN{{TUgdInKnO<>>J`z$nCn~Eiuayx9r73KPuBH&&9tmwR zc$-ySZIxDCCnRf>R0YBj7`Gi#vmyWR^5djNK~v+7yam#b43;0^J#=j?3Y`F^eF4Q* zK~H)hE{ZWcWTl-D29fpdA4`$0(4%=q4V9a}!&C{8Ki9!_f6clIBNZNWW`q7iW6Boj z+#X6M{2gNiVp2%A(s1r18Ks6(YnQtr$jJD&)U1}%cmiI5zPeYs+)VUJhF2dKzZ8IL zn)Tb88n8fPl0y7TPNeZ<+Ma;1iwqTslXQN=HgKv*X>yGkw>YK-rc58FOXEkJR=r}LH)8AxIlodrq&YQad ziWJshs{IYnn$&b|+K_tZf3`ceZ2Y(Zc;z}zp#d8j64a6E@Y*DklC8d$$zU zxgD;ZV{^kV8AE|mjWW7b&YZR$z*7Y$K)0$9-73!qpJy!Y5Z7X+-`O2*3U6i9_{5X0 zI4o5UQFu#rdw0PMpELyaNo}s}D|P~teq*ft5Q=_9TQsNqA>z^UX-&tz3uo@oSzvwe z4`Fc{>NEyMhRm{T4-+ktc*!RMOUh2_{ca*#TuDND02-ShXj>KSBcovg^s+G*k9ROo zn1>h(3rQ^Mi7pDKp^)6m0`7RG@tAWcz0^ybhx~gT4ARQt zI^lGi1V4Tl!7Bh?9J4X0gomDXU}>2ChzF4nOiwRCFs3+Ni4bf&OybVMSKUS=rHZN& ze*LMSCU=|?E*j5d?l3N0Ht$&tIbwSU8GSXFZ&WJbKjir4Jz+vyl2#i$#^o`f{77*K zMw5yorpY?tz7jLbE?R-;gdgnCDw3$Ab+Z(w*Vm1l_b z9(^oP*YMD-M1aIsODmTXEB6z{EXh6o1&FJ*^#d#Yk2DEt3qMQn>GhmsU*Q$*0iBJ%`1 z9FQwAl46}u%MYdOp-Hp|>W^hb13@tgAO^ky&WJMIJr?fb%(@IE-TZ57b(Mf(#bjo* zJYmgKX_!-T4d-ArnmZG;ssq1b_|;a$1DeFq`+{g|92Afx$JDOuWFAxPZ9k&BjK0yVpI*Wi%3dgb=;8M#j!0H!MQeDl5*xWv zcD4$%pcK&(*FE~=&fgrK^o5Q>r^bxMdTo=|rn#RSU^RE3HI6dOBS!)9@F*7ijFiqA z{=@dbUwQdIh77@9bhfTo;Pvd({Q^TnPF)YSwj3DIyNX{fX=R_YPKM>ae%j>x(91$P z%(zJ3l+&-jDU$kAj)ATx4e&|g=W3Z$294*Eh4kMb5gkrP0rQ5+w$3H>Rh@UXOLOP% zr&9N5J(3e?s;=!NCpSPT#B#4Mwc}AKKR3Wl?L$PCZs9x^`y|nk!veU#IDFcDvK2vX z(J0LrF;6RMoaYh7^#+8w?g~9$$Cz3adqRH(F`a+`y-a{qu-Ge@rSQeX8(3 zRC_L}!^!%4HQg3}g>h7W-dF)dcDa#;nVInP>6o{0Wf)*)@;vT~BGPDTKa2K(F2@|Z zaydinv3?ioBBPS`9q`{nds

    )dlFghM5&WnR*34&b77u?NoW?6GobE8$SFYG3Ikj zZz7jz982ke!RnAU=3mp$)-ajEL-f~?`|s;x^i@VQ$PlM$;3>-fe@DNu)LF7H*384j zmf6ShDPD}olHQZhr$yth3Cz;o-v?=1Ha4ZTzEIfCi~IP|gM}Ilk&ki66H660@jYsF z1OMa;kgZAKoCu;$$au3rYvIG6#ND0X*d?GSL4DC5bo#M7QAF0;S*oEy-?znPvAUAPg9W%HI( zjh~zM`)tNBJ=*+@Z>r4nTw9?KuAcF{KqH_XZW86|q56AMtiGi~@oDvA%E#;mx2F^5 zPnz$qJ|6UO{k=)~Hs-S8{k%~BmyG8VLziEBv1s;h6)oNG)}|7+jMv4_pKj;^-id2j zVmOVVKQ@s5T{9@Vq3RnXmbOh&l$4(5DEPyIML8!&*Ei{xL;QG#d4au!430qAA4WGA zvJ9q>jxdB46d1BYjj!ifn~h#Ap-RnEDyBo|wCitZDP~&+e`!K7EYMJS(WNA}q+tWX zgQNfOeADn~-GZ_pK!_Vxl6 z$BxLYdL|XEnE#P9DBobEeKlf8(Li@iD<=E=1ab*vswB)5a z*F@Cl<$83;wJg+5cVugF3;xi+b?E01vLyf;g=`AhY#TXN48>M@mEjVVgawu564iAq zu(!PNsLy`AOQP{F$9 zNGJgnKN_h{DuXHRqPQMvxeco2vh8R*t#0$t9?d8_yNGTHYJgI0fw-1RKY zP!!#y2g#inU3Md!7!M>zkKU^=QJW!-&q{+6PGE779_jLVhl+!n3jW#9puZ!$>8J|? zRyoAQ{ttjMF;e^86Bmc#f;dA#Y39J3m{N!I$Z2@I!Da*pG~jR4+wW`I?te`Wq#VgSQ^Wkjs& z>vbO`e`Fdj9s9g_T2h$@H-uihmivig1jih@bDpL=rZL9E zZW+s8oW!*_@>e+`tvmi9VadC!jGc8%d5g$uENV%Y)PRD+n_?nh)r+icSBT zbq*;R_?{&_6{=A?AZJ#%_}f7b?dSq}CwVILQenT-V`6T0Zqw55Ol8y_KEQ{~Xi>OsCgKS<+1id`S|x)g~)w|ivm zRdlXoRMKIGUbn5lr)L*&SO~AMZ(T|*4j@*hKab^R-wj|+86@xeo(?2{HtQ9{iaLLj zX32GQ%;cVn^WFZw^v_bqOb%i(n~e_1Yj(7JD8=tXaT+-@ZRA3PHhJJ{i!i?1;-hKGMGX0>U zXIsh4^DbPi=Jtp`()GWgVl%3%zs+ zWLPQU3$2~*p)QF-4J*YDC)um??DIXn&ta`lMg@nN%{qkwBc+;}>HAV&J(iNWVIu=M z*Y)pd!O?Bq9Dd;F$Kk>K<gow3nB3Gn*)=)e28={Anf_w@n5Jy~jQS@OcW z&cVSkj#dA7Xi|T>q?>-JXvAchQ@z~Jx=J0`j^ z>SB7PHX64~w>#9pT{rk#j714E=n|@72plJ)#c?nd0|J6x(Ln=WM#P!X`Z0gk;d7=h z#>VMYscwWQ5aY!_@eVRA8wckD;SYCLhjG@@+>kWXUfQYrH+as;I;j(R(N-kb;vjda z-D~+(o(Nj>to`!P-)@S-Wjfa`daKtOyF4?<7)_zGHOXA}vQ$V0#V*oc6#R3hlQ*Em zo&l$ERG*$n8_7t;iWy_AiOV1K4yjgJW$DKzEizVapH#=w&Yedagu;>B;FbjG3KpDor%E} z5{C_=TN=yrV$vV!R?w3ty9n50BPC+K6N>~mp?=Js-y2kK^5 zEn}o>zZqJsBm`{aeJ7DdEzfZfIs&&!t#*8`BzEt{D4UE~d>`yKN_-;t!xIFY%3Gc4 z1)R&z9$Oz$1Y7sE<~67YT-sV4+$vmle36w=wG*|JulU{Y{NxlP)~w!oEKq)4^!0q_ zM@wPU;WV#5bLhP@x)b~m#obo^$F~^F?MQ^+(s9;r z=dECZ#Us`IV~F-pm|L!U)uVtTgEHhv`HVKP+UR?R}hB!6)R`v>-@h;%q<$Y?3Le_yoraD?$bHHO?W!4E+1?UK;pd6HGbNRHQR>lhN{0w}U z978>QsxpRF$+X0g7&aIy7VZSTr~maSRlQ=l!{J)c2RmrzN9QNLKmtaolG$fThhO_7 ze#)$!Ep!-+0U`+_&}BkLObR+d^5EUVD14v3O%7L~sKtqtgP=>E+itlTl!#d1U1 zH6t28{8jhjq;mzeT?Bn$M6e+vVv0>{IYWN38WoLL@Q>}E6u{SV=fUL}0!YyCVizKJ zEow$YZZQ_MReN~D&wL~N>z4Atk_0?QJ!SSkF_vwvkyw*;ridZD_Er2QM{C(F=is%S zuVh0XLN2}@$Pe!F9WN*^Y*y=>?W>Dtn8+TzuI`mn9ZFRCcBQ$#jviaH$l8c!jw+59 zzs=kY-aY!GQ?Yl%gxZXS)cig_2U)Y{9aHA^j3tT4fF&5{j~_IA`yewn!>++ z&;JM7LssAaFSHN&8U+M(#{Ms~A8nu;Fs77=xpQ!)A52Ek%>I9%y=pqX8zp;1Q@MJ0 z9d8wT??Oqn9&z;cd}8Jo51LX)m>uz`VvTY8(!OUy50zwv~RH>5Mp zNgX#QPRQjw=kGiFS4gw0%ngEfeNVB(!e6P>d%B-*PjyFdM3X9?qRt2GgY$dD9Z$G# zHdZPnoXq|#|L{xJ0JP|Zgo2KIHT>vk+Kr`eEFaQ1`p%9m9Nl}t{+gQ@bJEQC&)D;cmACvaTx589`W8up{(Ag%At%#OfeDCspQgZtZysj-8fSnOLDYYE4B00 zqQDuPx~uple5NtmIi!)o%+<+fuWM&DZws9kVjKS+ZYMMzFEiElqIb;~^@2Ali*t^g z5V0b>@-dQCMs~5)w0*1>Ek1^1h*nFXoK=w5^vYU2? zRhvrj9UjU{caFX4^b!H@D|Hj0!UncFYph$ zP@yiKcZ+=P$!ONc1UJr$lhhB}>BUxUHrFyrntwO<%2sd?_(mi zQmXfQ=YYN{Eho=B`5>)w-Mel@wS0J|n%VgKUk{tHsrc2hsyiRlSE3_CRHxi@U!K5L z#yZdMN^M(B*YUF}t>)_R?7v;y`u9k^iYOpiqofU-snPs*kuNvc)}UU?M)TsV67{{j z7jquqK{2QOuzSl5BcC=$DDA4EF!zT;HR!Lc70U_+1xu*wY4c;Xzq2cV4>b-W-oXP3mS(;8K7TtLY6>BjZ5juC-Uw$eJ! z;H?HN>S@h=a>t+2F{nRN+96t;P3;rpEsF63H+n2iKgV}E&S^m==5)8q%7|bFndCb| z*(e>Q*ukL`SeS<1xB-aIwSs%qWSzKnaVm3=IlB{X$IRuIB8uB&nyNLY_;Zvf(AOsG zKT8I2I{eoWBM83s6gEQaKP3&Bq9%FV+b#Sv>HOkR5BvX2G4cQhqy_F!(U}WHL9V7b z>jtl!cOc@Qy*d+v1`)}|LKRSS0?mL{hz?c&lQ(VqznILC1jurT4tiY^@J*YLj-mfq5C?Q5)(<7!9qw-AYFb4E{Q}+X5gp0j%kx@jFZ;SoB9{n4c zjq+Cwo1~#z#kg&Jy2+wty4pV&_J&0ULplrUTW7dO%qj zG~F#(W)6L9+OcjpR5DlaOJIK8^eArD7P4E0l|-%AZ^xWz_{_US5u+TQ8TGYelfX4Y;1=@OqO9n_k#+sbVsT&-TG z{{79&`RsIDwirO;m)DdR9h0B%!E)w*0C7N$zkn9h7V0SwGnWf(fz~sRv4!YF?>PbG zd2>c2;OI(ct<5G`Lqw!(=}s3w5-@?ZNb+3hh78)%sQ&Co&X8(37kDFi2H1pQB85V= z`qq&-C$78f*i(;3(z_0}#-wavVH-O$7@@RCl)c?!JG&|S#YhUCP3>x1+f9&hTCuOq z?QVO!e<0zsPQ?A~a+{~o=DzZ#tTmMmD}>zXj<>w$eK2^_``-A@cZe9cDF^HO-vAHz zOx!(5fgAkb2w#psTw$GUC;Z_MkGOf7%_(I|{Nft1cx6P5@s4}^;~7hTz=tQ@mCSC%7 ziXa_ZP3K6|do*=HRlO%qPfymRj+v{AWb5`(hNEA785{;+AVElo*9)-r5S<-8NT`U* zlVBN|Cq0aG7f9Y00(OP$-Q>PD4bCb;_J(L-A$Fh4DmJ2VgT%cdQRw@Kln@ijUncPa zX?s*KZxUs@JYt&X2zw*U8dhU!KRm zr1X-Zy-pG_BH<4i>Bc{@>}LXe)72Vf9U-{9v@sA!uq63$RzyU!51Hj-Wck1k1pmyM zUy-!~|NJ94eL>aV5%SZ7{V;R5`Lg2un0o~N3-NtKGNF*TW4|J~#~A;25c-!91Lza1 zM;9{3eJf#kFyVkVL42sk5Cv!v2RMNZ0VRjSa3Ql0qW~T@7xDZvBgccEc zK8O(sNP!qAUn;j3P#_r!kPz$O5klBMDcFS}!Gr=)f4~BUq_KA9r*`cpAYzz)Q^*)M z2oVZJ8c|>nytfzOP!mu0eD=YIxx|1oafDUYh7b{j24RQ_L5LUee~8!-PyeVE5a?=q zQFs;sY$Gv(mcf4wQG#!%5Ls9NFIXC8*b-T%h>;SCK}3cbF^bM6TH~+~mbeiWND-gc zbHF!?2hoTW0R&fviY;M^XJ{9`cr?S<5RXVjy4Vl^V2G@U5x^)AqV|Q#m>$X4Y9%*` ze36C%(Toa_g3qWx+;|t?s1f715XTsd+f$5uQH?k^5T{p;7y*3nI1}^eQ5s- zGNjXqM5d1VHjyA1avW!o5y5ezhmsaikpp3OD*18)!IC{OdM8;>;s3}GIawDZxe+~S z5h;+*%GSQj2WqOH!&3)`E5JtY(XhzGzoa=@TO96cE`F zU&#?j7j)5Re=`x5!J?LYQIu-YmGTmm&Gdvxc^RsBfPoiK5zrKMh?QD4mPdk!a@iw6 z@QG;TWDW5t=UnoijO9 z*g1iqRaQBY4RmpbP0@I>G6@(Vf!-MzohcBVDTpqyd^2be`)Qj#C3YdvpF##8QqdHL zw-q56B3tN)BLQ~DDH000nb~Q8he(`RVV)S#oCv{r&sh;lkfA2wa_VUlwb&8rCu+KB zZ5KKaAlebGshSA^n-!{^^%0>R@t`!y5t=wFHA*M!H=`l~YGk#d1{y}(n4I9@dM3ex z8{v9LiV*afo^l5nD9MtP84&|oobPv)10kZy$eYlKqT_Ly^q3G)czR4~9!=+UR|*kD zdY(L@qqA2Lcj^&%Nf%H$9*`ENFd?OWqNd#AmKoWeg8!--j7l1W8aIU4r&uO`3^Al! z_Y+kopDSUJoY)dRN)dfYjbC~Y>bH~nS9Ot^5MjEFE`f%#(u_Ozlg;<2Zb%x`S(d0d zD|$K}y-FIt$`EDX6qqU*c?fzWGLMMrQw3T`w%Qb{3LSOo6w8WrYxo#3>L);`8{D~< z15v7aF{;oJtlN{V1`(9cdJx5EmFx$nkrJ&(L#e4~69C33)tIh$3a#%-jS)ep@Tw92 zdJ*^O>DGIJ`+7h~0up1Gu%%_Hv;f$tOG$`Vey5Uf|VR@SRDDLp7u??}dV)=EO!-P|}wK9RVZ3>wQ!Kf3<5av2{OG~a! znWHtKxCw!!Af%7kPJf_2;BO$!B@~Hsp6t5OKX3Gn`(hhyW0E_&1L`8FcVEz2{03 zV=1#bLB2GUy?SB4$g38Rs}q?k5Z<}DnoE%jp$;+ucAP2@SC|04Ck{pX7_Uf`pHz&4 zIvxVtouaE6kvI^|TA-rVsS3diQyu@}L}&NvzPYM~Vbb2-PxeS8pFoPmPk#sU$lb*mOLd=sWD z8LIfdk6a!xdUf3^8LZ3@qO5|JL3vXbscA>cFG0nU`!Cd~6!x>=Fz~ zk}PSz&{?Y*VW{hQc|Bo>E&n){Cp#0qh{9%wiX#nQid)j1rK>C<)Dh9s6>-az0n`%w zs@J;IOJ&jVOHkG5&k>=!NO=*!r?@mpcSgOZc0twJe845^wFu#wUHuca_Mprw$B36B zg*zxvZ5q!T*R@>N38Byi(Z9yQ*8K{#rgyu!iMtSYwz?^pVjH&57}Etn*B9N83PHp~ zILUg}m!rzpM_Uu>nXasdogdxHcA=hx>a&cIuANQ8XTsQa-AwAGUVOdSrO}3{ozxM7 zbm%LNHKEiZl5@0|y}{aZU~Q*CTGn;ZtK50k<2%Rn=ejdN%c@ryt!)xfki%Osx~-fZ z(p^_F2h~wn+NPV@0{@5GS~u3Y8x`CF;x@VcZq*+p3|p z#sS``>{BOw+fLWEHMu049lE*L5@u`Q;hPbRn$dT?!`!VS5B|p9ZAkH=*TK@n0>aA@ z9+ASbv>VNng5uBxPP={z$;KGg8zI>yLEivK7m7&K@oW%x*~7{$MsEDv8G+*)v3QrE z;}sn@XRG3nIN_6_1p3`nu7K2jg3c5H(Wtx-Os)|I?BsrT5Ik-Jk(V02BzPXeh^-Lb zshN8>j9s00EdP$>RlX3!S9$?^;0!^*MBW%e-c%O85V}+6EaBxd0n-oxgm_(jGC{^6 z5#{F*>KBo=7l`4a*cc4{wC)`e>?r4yapX3Nf~_gu-)9_ap6HX&-!tLKW!e!DO64Yz z4T0>SXgd&!(1wYSe9QbCj|{?3Jn2}o<;>1yv!>~ek$fNh=L|vW8zJlnQKx5|6>5rq zz>K9MJKpt66Q)dln%A|XhwArz;@utN)n2l93Irlb>r@7N;GKKH zEDr8_5&rJlfUc!1vF?o97@t?9152}++))~Rb3jOnCd#edP@_s4Nm<|(O-(wirs@7p5@z{eyxbyt5A zzZ&r_z7gtJr?rg`xyNy*XQp;v0D$j;6kqsxUMId7obarR0lTUwIrnal(_)Ws=ctw^ z+;Lzy?^Np)V%Xk-!jMtS5=9>qZ>RPgf!DxTbv^y|q6fVhW2uhO?oq*h!5Q0~`efK? z`|z%z6MxF)5%`mDNL+vs!`cwsUUNwpgKa;iN7mVp4-wDr6mR!*x(WPIamhM6j<8B1 z#s4o5_c*p(`j|T5uNo`y2#yi8ANH8N>`evr!G9#juaI7i9;QFkc47TjR{zRbANCE8 z01=>ozybvg9wc~B;X;ND9X^B@QQ}036&C`rI1xZbjt&!clo$l$$cG|Ho!1u(*#nNw%Om^*!@?Db5$&_i*CGF&9UkT>0{aWnLz=h<9X!h@6=#TxC(z^`XK$I=0R|WO5}E zdy)p8`6q9X$CC%KEuEy;@I&j*_j%uqv`&oM=0R5P@i%g+c)-!XdpPttuX`oXA6>vgER&8&d)^ zOo@J+h(?#nl*m9fIeL>J{vPtu%o6QXXbOh50ErYl7g}eiIu}xsp%*b4lmDR#8-nuB z?%YZ&tw9-LQmDk5QuClm|IAcS<>ExMw@QcG)FLT53ZyhgS9Q&~g)rOlp)C`2=|$!= z9LZLPIIK!n=3D0MN&p|3o13Gc4aabu7ZYr?b@ikT`1HUReDz~a8Y8GPM_>uNfBwqr6^v6 zpGvD?l<-}6tRlTCGzxli>-E4$6oL*znf}d4-*7>8C}4&XxY(ytD_VIqlt>mT<=b9G z>EMW2T$tN|Wa^Y6k#FAFA%#yGTHK;LDimmxvQrwWpCN*|t5ADJ&i~|yWPWKQo3F!~ zqkd5%II6IlK1dR>&(3M$s1h|W>8ctn2s+v}j%{IQA@ddDgRDNuvkj4k;KlalHTKC$K&#C81>4zUujKvEIcHW!~&-)C5 zznu^eYTE-)M05jy?-e8f$Kp#&8koPQ7!Z0K_?-aLL=g=_1pj@ndrb!)CqfFMW`ZU3 zU~e48uFyE;gD8}V=N3XQ`OSoc2a1UW8v_*p=n#f(f#5+-NIuA6k6#A4p+|nW#34D$ zUd=m*=9qXgE}iIwLiEiPy8^o;UPX&4Nyu3scEzfYk%LWBlK{JD7KfPeiy$FGL-fQE zTFK9iSlrA3ed0D75+z943yJ}u_(q(drX^S@)g8HnJE!;>gE|5+!Q{TqYZ56c3%Kh7QqI^3n&Q(L{uLQQ2DcP0n z-=tOPNiIqn3AoHAUml=tqyUwYqA1Z)L=p)%Jt@1P$&V*ozFi|y8 zf~g`(B#r9X=R(>!mZ7~eqR<4HDdFVDiCA<<8r@$`g3`^44hfkh1<5i)sz7U=PKKT2 z2zAaTPmaJ7CDKfdVn9lfmXYL}jAPglXM)rAv5}d@5vcZBSCE}5>m#(xh(LM7zI&on zX~*#>?>1({kysFaO)cYrk~*9p2`Frg(H2-$@>8D*EF%V-q(geDQmY(?pvfWX@A8^D zrb=Z4!+B{4b3#*z(A6S?Sr-yXg41FtMugxpXa87NV%V!?F><&W>rtPQS+)GIDPQC4 zLB{sNyIQs{YhnofPNdc!{*pC;6;na@cv3u8#7Q?x?5|Km*^8FeDcsfK5qe%}HpESd!b%rcl#sWL2fs+gl)?F&E~{8u+p+lfG&dSkRXJkcw_rGY17yu{sdgd}GpEJj+A!MaXX3*OriJV5 z300*M7#e4oBHJ}cfPeD6sM#gPs0rSY)Bl%TF8L~1q{Nr5K!@TlZ8UZyR+f^d2^A)v z^Tkc;GL;R?9QK5~iu0Z-g zS9Eq&e0^TmMBB#jD<4O&^1WKSb;l}M@vmv)VTDi{B6~Intd-T{hcx=Q(-wC}($Y(O zB_vDMUJ1OVE9=HF=E3nkXJp-i8UJ+CWWPU@;%+?ES(W^IEGs+>!MIK8lz`XEt%*wm zPo!+OFga3uJ+ngrUK}MP{M<5e+h>4`Z-(dkkuoXpYgq0S+)Z%SzMBv|wsJdnJJt=PsqFq6DG z5XD2ppAC7uPYiz=;Yg_<3GXgZwi@Z7;A$b_I8tKrCTfQaGj|Qm35gvOmsowaHbE8& z-{buE_Y@?;65$Pn+l{lA=>NqsiI6?Tdq1tdj^tD~-x?p3q-V%Nf}xLCe7m|-tPY&w$dcuYv~1w2T?KNRU(osuW9H_2kzcz)_cpzXIvve?~a zs4l*vuN=H>Qk|lEiO7qHJqxS=tR+?eiA5Kj{ktbhdaS$ z%Q^ZxI~hY53;MKp>j}+B3lF@O3-qG$s)*4U9To9FkVrwN%L&Yo43Cn*r}#qb0~#aC zm$h4>ZhMXDa~aqRL;r>1ipIOGAnb}Zq@#|wy@$BNvDh$~;lQUL!s5FzIed$8l8+kH ztftAq*g7JaVnMnnsCasa>&l1$+l~m)1ck^hFx!e)`9XwP3cf4BFCr*k^A$Q2M6v@z zLn^fwWJEmSi$7$JPW-Jakwvrvqm$@~`nbXb5(-$%DTv5Jsn9@`*u_&c#vtq-;rO_* zn6eXFv#YBez4##Lb2A`ph%!U2r;9==a>irSC)sEXoU2)dIUsR%VYfxxfvAu4nUoE$rvbiY_LJ5)SJsYpb>ledo)K%aoZmmG=n zF~J&%$2GJF12joD%!!KJCn)o?rZl*bG0L<2wa=)d)43v|gbX!|CbXm`qjbm<1dh?6 znh7FGnpCrqWC$e4N~pXJRZxgHOs$UaOSyDOw6MX_AxmkStdbP7t(%D1Y6#?6E+qqw z$5hPSLXM(Q63jqIi^wytSfjeEo*_CUs@$DvBt2*Z#{o3KIw=#>bhStl$3qON;giA| z*~~L4$p3?*Aaxr}hKxI|xJ2TxO^8U&CUOn1j2_4YrP<@jeQe3jEJEzWlLjfyh=5Cx z443YVikO?ioiN0%H?p9zkvqEgNQ!N z&Vy*qF%zlfkfy&G#_D*9V3@_l5QqerAf2@~eHk52B5Vg_+IVl7WUyq zq~xd%GF%fTt)G~Pi~6{qn?kSltWZf!A5NXq_%xl4SPi?sI4cd%~+sWzBa3fHKjAB zsu44qpqGtO6?HKX8reb$(jf)6*62j~?7<~X+lkzlDXPcva8`aD5~}sHaFR?iIj*v` z+lFE-zfBhkg{kIg)v8Us^c)E!7!0;84qp-4m+J}$gw#MBD$}$@8=TCb5gjUJOW}lD za`ZNoMN(d6+RS}Wr^H-?)l`pMyrL`B<@g@F?TE;g!#J^wETLV*<=kV;tp8%<-M9@f z102}$%%8#7UD}aaeAOwK9S))@Sz~>T;le&pTIgGkVjv znt-*h`D5B(IZ2d?0oN(VPnbWYAimYa#PWu z&*+_2ll5GAS>sZ>Sc`RAg5)8iwNKZ`xUI06bM}chA?V?#=YB0U;5F!yDvZ_YXCayC zOrGVqJxDKVwGK{*oJOavK#5YUVrW=mgL= zt?J%5oM{$GLB8g($SCi1wLSi)nPA+QT^P;8X!eb1ZDi`KCfX*3Ws^27RI_1xEQN|Wwu7#t`-WkPUM>*!@`j40@7=5^eBa%h%kE>XVYJjJ*T$IYbCa4 z$6h#_%~@!&W{i|vysK4ZnMxg<$iS$zOaTtJzL`q8?EjCsvzzGc#gNWwWsQw+GQ9p1 zb&Xh`uG!(p?GVi$+M){Gw&aWcMj(A{_-p2+W=8!YVjij*)(^yb(VQ(uf&hakhlOSfvDH92_ zkFh8=XKrV2TUTm6o6=Ndz3P(USYg!o=9w69WX5kWj_2#(?2f&XF(IIs1F1~x4Q%jT zoj{WicVgtwKq)|QaDp(aDDbMlj1=CAu=(Wn?D5QAm|XT?Xa*W3t=)ZVY(Bo{0!Y@X zVCCoDn}dMqA~)Ix)AE=2aQyJ*CJ)_=xNnB|DgPy~j4ns*hnVuOUT!E~U9W@U+PNYO z=ZG@5vR7S*V3rBx^LZoM2}~H1g@% z&)^Qv>3wLR=`y^qHp12kCCCxUXmiYlXnYRqh)`hgLUjAnbC9Mz^;ML5bvc)fsyi0m@KQX7W3+McNN){8 zERQcAIPjkHAG#hI=Ow2gLcAcM7X`+*{pSL}zZ3szc~=e{E`Y^mZr0%Qs1SvD&bLb^ zZxILhMXHFT3ig2qnv{FavBQ_h&9b6aJNG>7Ur%3@dvAPmjM}Qp`rP1 z2v+t=bH5prr^uh6_m4ioL7E`A6Ll>ziAf<>|BLn|dE(VZjtL5zZ0*dMUapZG@0;f| zFJTf`!*?Tu@QPNY-93vxuko=|`Cgy!I4=%+#a2)*?9yFnC>402&Uv08q?P9qe~S6e zJ||*Fc(6ahwRd~pX=t~=c1$gmrmW_#e|tCwD7tF8 z?Xq(e{Z*=VwdiB48H?!bid z*T+<{YybX5vF&T=U#q3R`Y8ek1O)~XENJi`!h{MJGHmGZA;gFhCoW7tF`FbK_@23hK)nWU#eo+yPnBwElW(32($ z7)|Q*B+{o+PXc*bbt=}ZTDNlTs`aWsuTPhXEsIs9Lv>~kMy1%aVOxpGuu4LiXl>1z zN+`y)i&yGhwreK=4NR4xBLAm}|MF$*xWLl42+2YWi??q?%a1psym~St!=GL~i{m^n z+*Bk5R1aibU?f7d2Q|->Y&vJ4+fo-htecd#RNE0f>+VTeW`H2Tb7Cfl^Kov5%_S1& zynJDFhSjqQFYdkJ_V418N})Nb02Hm_N*^58lJ-Ni2Vu|W&bWKly?IZHZu#7+eg#Z7 z9)SfqbX;-aZHAwLUJckFgkr%*(o7RVh~Ps3N<5b z{iS#iinS5MVnQ^Y6k~CQWpy1wI5wmsV?fd*WC6+)`67}@MyTLz666FLV0S zlZ7oU6{v0)R)&y`a3TcdK!#GpsFIGFB@laTnrR@PF9xXLRBt+zsDYruiPWWvBD#>C z1>HGNsuX!@Dy$UInIuxP<|L_i2~1GX6tNokQdzBTWviw-DY7b1v=Mt-rpP5!YOKEb zN)xdry}A~%K~1}DS)!Uo=!+Y8g$TDgg%sRqNkOWR$b||BYg0a2 zpQlW?e;E>q*LCkT;^f}bk;SO*udx!g^;?$uHo{jN~#j^obv@ChX^ zXI2{(pLk5(dhK!Pk1c;ZOuS={((~1C|NYi*PVW7T;44a|`RS|QlVygJkNxt`D@57# zaABo=sQ*eS>TUJa*ZB1VNE!IvBKDBlSE;VF%U$D9!#Ly z?7G6b&Mh z3L_WsvLz~s!-o*@lE8xJlp}f&i!!kyM0mI~h~VgpY$^o?rGm#;^-3lup(f66G9Uv7*hdR(7PSjiC2Ap}~EDJ541w8nz01C?iL zgJ5nWDd{Q7BC;e%BAfRV`57df7nzv|t*K6ggz_(Bprg7-Mj*qXCMJ5m_V1Nzzq;YzJQIz-*CR`{;J{bc~ zvvl+!tng<+IA9PC$WuK186{BIb)d~e6s09xSvn_DhM17hAOqc}bF!%uXFl#me<|tQ zi29U`Dg>9ZLn;Cn_n4NN1y~8Wr$Opz78@#rtEPdeQ-Eqpf!Q)A5tt+Q##x+30{^9n z1Yzc_9s}2g46mjz(u!DV!ql-03@Zh-sYEa;1qs+yVEyb0nZSxJ0tJ$8s$^4C9-EcF zvWc=fn}}s8k~E6~)>nCj5dKEAV#DwMA>F%#gbFzBSQKD+Gy^MLIYWCL7+;I-`16}HJ7nKN5 zVR81k-MId&yE(I;W0102nq+sp;<2N9>Gs>cSZuv9u}J$4XkDvORXYoU-cF+`;%w2)>Pr@{b?+IsO-|PxicK^0BV0icD zVfFR4a}6Q!ieoHe-Pm`=Huf-h7n0)}lg=$Xeh7#oWXDtqxG48EFO1L0THO?RA^T-m zkbhi&?MODVr9;BIl5sUPnox(OA6CYB`kNS#hK$Z5?|yX8K2!8(b`Kd|{|eP-p&jDNa+9Ys+CFUq90@pLpS+V9vgvuiQ+K`4w~nq10zuqM!&0d`iWuoBZtitm`| z=4zny8A1a!O|gfT>;gy@XR%^yL~>mKb8ZF0G_eJ=8#L1Eo`e&Qk^eMS4vi9Vhk4k3 zeNpJXOOckUx*|y;_d|LL=&qgmG21?ff(-=kHaT}9vQ`L`SaNSa_ZTMEllD_W-4KL_ zIoJ*CO1|rj$&*lf-a6T-#J!_%pg26R1zL6i%q^Z@D3u}m9tuG~PCJG)n{%Qo5IlvL z@g+%3nCVovaWg%Te?z3*2q~*UIzE$tZc%Qxwx-XWlI@7Jd@IMU_<&I?6O6OTHfhcZ z4Uhg1nal0uj7CTSr6O{mq-)VK;WD7wDBC1QHBCAt8= zr-|_+CjQMdv~cB`zgcu2Tdm8BTb_pq?8(mbZAFZr-)-dG?M=~4@E__qMFSQ<*iD45 z5kw>vKn2D`Jxo_kn1u77goO|X+MS8yiOGOm9h!+AoX|=6B}C{XfC(F&=Gs z5PaaugOp90WCX)Wj*;a}YM~$*mZ2G*VbBmx=(U9K?N9i?SrgXQEa@4i;aSEoM3E6i z6e7uom{Gy4l74+1L$KH4FEhIO~B3Y>>N&*DuZL%bi_s1pwzQ_vt+I?BpK z@E%M+$-gB}3?Ae`xTCLR-#O+PMTUk%03$^x6+0Hk|3PF$77IkQq1)hML*!jaB18h7 zNm3@o(OKIkaz;<~MEoJ6ZU|(;)TI8*gaPW3O>yHxc7@j2(N;RfuBFK(31Up_q~ntEajAh*^Nn0XB06s?b z2#?S}SJRE)pE*R>tsy~#rUyy{a^Y7heWgA+#sHcez?i02_~l775vX{gN72L)DNfZ0 zCFXd}J|-A}xE)c#rMVeq0Vrof=q63H-&XKuLVzcA%#B*=gm<1DLrPg;y{A^}TYD0q zMaD#DmY5v^m_*RXu{FqOc7{$+r^~I}{X7I;LIip~gn1rbOQ_~-qGp6_r$huOO#G)# z#0Z8Ys6n*l^$bXOIHxl%s6*r@=bb1*(4%Q6m9SW-f&S$E6{S`<<*?k4s5R(cxDJhO z=3*j*M_SDM$tOWjW&seWLl9|J*8f{^ZpC%#1Q4(Yju>fI?A!W{+FRWQ9^ohqUIby< zjh6akLx^NdAgN5m5SdCvXu(&|IEhKLCQY2_gQA3nRB1xc9@XhaD`2P$QiPCRVOBim zQ@E)09YlQ|gcRTrTp?#ZF2sLgrK!~A+?-UvaA?{kiFisNLeOYw_742OW})e)y71_h zUZYGfjyNr&a7vY_Tqa&b6suZL2+a(Io+cM54xpxI?_E*s!0A*t>V6i4h(;Y`9wV29 zO=G0hor%Y+lpVqtj-kA2s*0NLD4KmDi7DERU3mz#q9|&`p*-@8!~|=!j%y&2tGROI zxweG3npgY)qKEma_-re>+W%s*-i!|_YADhY*$m=5&7p)UM91K3aWxo0Fe|cVNao;{ zqs?l%n#Q`SB357}|IFHpMkFRO&$pUJ3~p>10w#gM>%%o{QQZ|$z~UKZP=u&u0<;1K$?VE3smRLCA|+CvqN}5*s6?QxG&Wj8d}*#EgfM|E zd#M$YfQw5y>r>EdxnL2~=8}y1p^}iOLny6N_-xpEg{ldz0wPgCC>3U?ElofuQ|g49 zx(zPb1fYtH+?q;MK>sR5u!4n{U4u}q)buTqm~KP>UD>K?x5CN5J?!eD1f3pkLBO7k zbZKfXSq47Etv*ET7E?rQu0u$!PYB~FwV2^9M4mRtzxdqmf}%k@?35L(p<=~ZLder* z#q6f)^9qgL76hcwM#(-#?>>d_2A%aNiS+6OuX@EG!RbaNulZaK=?-53kk%Azuf>T) zsSq7w5H6TbOZVo)#{H{S=x=$AM-q9@7gC1*5`@kwgr3R-0>9-+5N}UFZbZE1-%Z2= zQ-txotmzE!adC_IX{xWt??F(J2qlULuZ4WBFG@tEx1pcwp-9yzu8iDfk2-9yEbbpR zgbw>CLFAg-F8{<4cg3tmk|dN_q9k!aDCfiCoP$-5E;xe(F>t z-QJzA!d@O%ILZVIt8_(h0pKoPnX&So#FDn}=fEsbWLpKx#0T3Ac{0Qrm&FjXZ2~_9 z3L69f-_BovNpR3EMmWU;ldwT}t_QvF!FmOWndm|Un-&)_Lgc3;Q?DaW1yo_MPEav1 zIz&1pfQEh2^$y*6K7}18MJRKNAIb4n)bd1xv0L^h!8S7RvhF1Vg&U(p{1MuN$gmRA z>p)29K_uOmhGTv1u}m1?am@0j3iDQcl(peadAJ@HgW*B+ak)UT(5Nty=&%kq=|FTc zp5gLWB>x0CYt1KB?n$sSL#W&!cOFH+^FDK&H7@h=4MY(oGP31_DNh782iS|C?l5QQ z&E{x9BsBVJn%BZkPpDo2E1^-41;d%d*EEzfBgqsLu(#qdrA5R@J0VPTnI#V^^wQM& z1notSvQ6JKPD`9Jqr@RMbSm#~Qq*(+GiHbZg-~Pc#k39iz}QP$A;mHw8}n>pKBX@c zhBp2mfj+E`&Qz z+VZqEN>J)RT(G1NG=`vFUGIlwHEV;s^Xb3h*wkR8fIah48!stbXTvDLq zQ`99qM-M*Nc1-NIR3LY_Bnf*zhPUBITsXA4xOZ%o0#Eb`{)ukeX zHAiuxqfxa^D7Z{`9&!8lOla~%P;^od$2^xeO=NYDKiHlFtcqtZn;Wx1H1|W`dEKy* zGNH3+GugCEfuhRjfkv-9yJ^_D5L@ZBUq~_bcy^P=cd)k$9{)QqxPcUKVtbIke=V+=hEURWX=$jsTdlG~#Ic$8 zyO0kCMMgs~c%sWhaGyxe4Qcv%42qj1l;?yWF$(>-+Z{cH7IX#23vIx}yqNrRL|{`^ zI~>gy2j)>SP%wM*r7gEMge-xIEkyiQ2srRC#&E^%t#9!0?03me#81ph!1E_cBoeg| zyjj#WMA-XxTn?c%))9*7Q<%C#Og+{wgs@8lxzmJ+ewK}-ioQ}OQuMV4!tO~;=zPZp=M=?RsU;OuMK~G%}P~i*n?EX zCQXac>{^>>-7ajq5J6nKapB(8yO(cYzf1qtz zX=yq{av3tz!JKn~F8OmV!P1~VBUF6$rr5HgS(@dTdh+9xr&rqc_>{JUyAg527Vfw1 zPTg*UdzBd*amnMu6)r#c%c1nuEp%W+B?6Kq}nQN_l7|hx;to3A#U{;wHqu` zusFuW8VZCbX&obPic|KQPqmTiGS4KD^n;Ee{>00Qy6sHjh{1~{R4_UVh1$w8@(8Ms zAr3KgZ8xH@14<(U8M>#T%mkv%6_k=w=`;|t^6jY168{WQN3UWWDMybKP-v5kf_gD9 z6kF=?G9|UDPqMo_d?-qn9;|7|gSIe836)el$`%U&bcjWjY}`?!DoZ?yy|>JC=tqNc z?2?D3f=L&uk>sP zNtNEzNDHg}D$}GjAIdT%PC|sMQaHsdi3kLpV~5ZAe%RA8J*hVizK{A#54yu1ZsFTGb%*3ix%cSp}N*AaySy zkE$?TvNI(~H1&!ibUUhr*~sKwXfuWWm zfPzu7Ryarn(l|}17Cus=MQyEBIIi%77hlmvIf~>)4~Fxieq*jyBXt>Mx8}4awy;|Fonn)P=F397?ndVF9 zz}?c1T$ezcd?dlUt&Hx5Or4eUuQVqyvcfnP2wbgF56ocS{BB%!`woq^aJ5saWpFCb)Nl_%(Xf-XPEd5=mLkRaj(f|WA!DT_TLQO}nc?0v<40c;K88nQmVaBUy} z)ClzS;=h)B?ji~VmOubtJ+X-IB&8#X;uxYh5GqS6s-l)$_L9E7XfPwAbBOk;W|xRWS_g(t+I48`I?8UoQYcA1`Dgjf(AHm!CA@nBb;NW_cu(1`5NW1JhA2E`%TwB5^Rr3@F)lciqUq8V!y+p2 zlchA}DTx@A(b+IAldMejP#H^EVr_)%TBJ*!lPOoqEHa)L>e)R7Op#9r*0==4zRFUN7z8qInzX@Ic>!eU+NK^g9B#7 zTJn^|a7B>eY-c0gxuad)^EWP8XE)L5BzxkHQM4PVGj|Ba;h>S94fRn<80t`bc4VIt zO$<3LI++oob2gSC9|D0mm&ZMcn|wK_a9{|}PS&JLa5*VT{3k)EaBzwx86#A#n9__~ z(I7e<$VW4}7I*zIL^>-?SpTGg(V+HCAV77A{u<)IkzCP3i}`0)IJd}(Np&SbK^FxL zG6|Oep=TW72>wFUIAB4Jb zqIRU6?+U`!|M7`0gEB~7GtxeTh}JUE3(j6ab6LZB#D3kwh-|gwk}bh70JTCbhUWK9 zmEcw&V$~JAcA~<~7FH$LwHZlnQGm?~ghNjuZB2qi(~C^DBf?e4a|L3-gP^rt9bp!G zL4zisY6rNO`N$`A%m0$kHUzT9Mdj+ABVW0)^C;9M32$w(s5iCEG6wz%ek%jnk_>n_ z6-C=^y+YrSxC19C#hY!6BCepQ*Dt;pZ9{v7m1<&GH0;6+g)c&~B_bDLaiQ^AEErxx z{n#Um0+EIlTwjCmxP(cO4(BXfl2$Mok1OHuPS$rehUUn?U_DBIy?K=JIs}mHa<50I zti_U?8Jinb$azCp05?mM$R;uFm0J?vZ3RZd3(@mIyv(C)d1SzSHc6eK)2cPKWu&0_ zT+dG9UAH*+E`R>6C<_qXj4-xeIIhg10)<@#?vlkuEQmjb%a~NJTAP2t8-z)E5krrX zAyK{vtO{7tlmB?SBZy`Qo&)3ItT^gdXWk~Od&*3O7#p-e^mSb3d@Q@Lh|-3FwOFp* zMf>s+I=mL=K_uO5fjA2}25B_1S>kQ@e8tu^ne|#Iau4`Urqo>#c2EKNocaW|pD0N) zx(_1cmYjPfV3wW#{@o`9&AR{wZ^~HzLU3y)2F}Ag=SUn5aE;q!%whmLK*YbP_F9zE zamw5~Bf%+CX~MnnsAy#jmPxr310eFf&?Y%=diTSnTa#>?GsPm&Nkqe}a&(eh=pY3Q zN!rbAOdk+5FZE2(KS^{V?z}IzbNWfBzL%?Ca<_?r@LaMkJEw0QiyyuSo}>=-fdnV) zM^_NpsYW5S&z=A7J}e~wCIt5(eyr{&(R<%r8yC`^rs9Afd?_AZp$=jG-c_#`HpXQ_b9uhjRo(n$mYr|7 zzZp@#sCGnOKlx1TI`=u%B*b6xq~le}%cW0S^dtYFx_b)gZP*qXE6PDq}~9~ zP%KS~5{~yo<7r$>Aa?JYfQbBd!aDrVFAlIF7SJmy5dK=tBc81Q8gM@hWddvDA$ZHQ zM&s?Y;@bZpkTM>x05otd3h*G3j*&hox&lDmS_?LS&MO8(!4jr>j)SqF;^q#9W<+q} zD2|gZt}!~Q`ctk5Kq>>%)?0H6@I%4x}RPa#ak1W_Uj`65g- z#|*KqLk=Q-aDuGdLTA`8u`Y%nWR9}D;$^gk*$BeANFoLuVh8EyuNJ}&N8$)Gq5~Vw zE$X81K2W0S&?ZDH?Aqo^Lgotzg1dC(+TH}Q6mI=$Dv$8*hqkbrPLU*Zr>S5A!iaD! zB#s7MLU?A-A!^b7YOf?{CJ)!kpD07ft}HVY5j27$L8u})000rQt1=J`*f3%krAP=h z!WsYL#qYw9>pVi!45A%^#y47U8e5334u%R>0_eJfBA^j#0Ea3>j3k_jDcX_ryy6wL zV-js;E+SD!zOixk@%&OE7A@oms|g^l5a*K|JKn!L{;-scswVp=NBBpZS#Q-UW4aQ|e{ivAD!l5Hfu z1S-YirU>#NlqVj+C@3>R83~Fru4eLVf)NwrBY(;BZZRV;axEZ?C9CpbO2Q^pBG>;i zis7EBTy{b#bH%&Jl5b)%T6~fu+%o$T!zBCB>yVHj7BlGblCv_(FE4^rk{}{2ugC_% zw#-s)x+jvn@-n3iX%rGE5;IpS6FLZywT5d4rO{Z9PyZxKhLTe0v|^WH6VSd5DR8s5 zWCSl5kNJjk`-Cpq9^y42FMxIvlS;3qwhs4HNeQ6Y9v*GO0)YE`lm4(q6!@AQB=n+0#3_iy!cQ?V%S9P)>Fy~;IuZ$Q&+K5sJY+-J8k9#@DsE1bK}DmG zJoGu!FF(TwK#Nn`;zmL#R6i$UH-B47LbwLQDBcZ#D1sC3jY$^6K4otpK+!faL|%2Jntt;@BFrShQcMJb zt7u{(%T+7LEnxZ1Aplh)Mw44d!Xh!`O|A%APPU-tk0c^iHfc?mI^u|s$}QFeR6G zg&;^ZC3xe~NHH>!vtJit3t6^LKf^!>b0jV>SH#6brM4ha7T*8-!X1Q`ytp$>3!r8R z?Dt@3ZcCzS8*wCtWHCb4&+g)0RaPdOjx(Z0Aa3DtYXZA8314eMYRfiB-ZdkBL30U3 z=*GiA8A5RjKvW2EC?3NiZR3jC=WUzgA%a9Z!eedwf+;b@7fVS62|~D#@ssuzBYamL z2f}n6qDxj~b#^YLyip#_Vle!NVi$sS9neA^vLSrRcGHp}BESnp@dfoXEB)dgaFgi% zwj*$5KDw77lpq1t#u<~Nu+Y^nv=vmeB5&^$NrA?g9)d=w!@$jHSdF#?4jf}s}4 zX$@ivd#C~hXO0SEuOf*W@8WpT_96aZF7nn?z*j4{HnLU?dqJ-x9M-nHLcxyEg-f(D zc(@_r7byt$Lzpx-Ng~&1oV@Oazgt}lEKarwz2;Mkyi^(16?<@~~uI@sc_xSb?e zN-?>WNC*JaZawD{eHCOb3e{K(@^&}WfX+)(6{L}O3R^FuCz7{{x^_tn_po0@C68fA8B4C)aAqGJL9iEoNAb;(-6R8C7|DntsBnM49e9=`-G1`SwYg>zI@o zqKKoGLSqEeazDel9QIPHP~GmD^-60K26N(T;bNo@rU5shKlGqD~b$ zj&U(igOjyOTcmAbjZ{LZ4+5$j@fP0$@`-aZim^C6n zNTaXqVy@qdAS4@d8zPVw;%UO7kgHoE*ub>)LJ2y0zHrsu|J=49(!<-(~<0bDO#`vmo{?-)+QU*#aETVu@? zq95Yrgzq}WC`OD&yG!C|apFPH$Tl1-Hita9pxT;ZwyFn0wpheyPHI);$ z-K5fEYbF)~d_!7w2V@ibc-a4MSVhy-?aI1MzV~F>ZBVy>-|V~ zq+HuwFYG$4Z!{$ekbkE9)=L7(of{+8#M~p}7bfL$xZNSpWzJ7^xE;bBH2osVa+g(>Yt8+qFn8S$v7<4TU7xTE2@(Dk?OZVBF#aZQuz!&DCD{h=?Pc z6EBfMHwOHkWgR#P0^|P|!sj0rrP03cBQK|iROJdUlA;yD2KuSbRO;})AfBt!3*xZ_ z!twdoAeM+C3|uUfs^jt5n?;-Roz;$PBj(3NEH3{dv^POCKO^Aqt}Fer(Wl{UzN=S0 zltC-vEnBOxrtGav+q2F=C0?oh_>ji2mOdW=8x@cuX#!?WNEV)07?$M?Ru zH-AC%W}T(zb`k{l<{qvqPxqr7@!|IOa8nvx;P_=$_)Qv0i9P;07e3+jDA+ERoU{Ay z?tHH5^k{!407626fdmU0Jcux%L4gHYD13Nu0>p^}0Z_b%F{4I|KsF|{=rN?o0w70D z4Db{R=p- z;K6~j-X&ZBW#5n%7b6zCQE1i2gdM~DIvJv6${8gxox<7Z=7C5E9>$mr@aVn&2%4RH zdhYAcw3(`%4L3mS#G(s+#hshr>e|E!W-d59c=4LMF*aWgy|x0n7^NKC&}MJ)r-wCl zMaubk!A#N1KmKJtz54Z(#TR_(o;}*_>4D1^e*dZc^<=s(IXGQ@BCS$be*0mh#CGj4 z)yjIn#RvZq0AvC1+d&7Cgd2G8xn|IX6$z-&OYos(Ur8G37g&76iI~ud?5Rl6aS*|n zkXbO&=$l?L8Wq7r^idRGMkOS)0Ei-aXyjS;Ohw9BTWHnaL!}^O%R@~PbW1^;Jha-6 zNy6k9l5%-Dm6&kt_+?N!83z}cPpRc*Olfj<8%Abc6z7~qZBUbU6omsNUjvP5ss0e*c5LUT56}B1IfgxdUu94s;5SkO3{d>PL-!#d_F|N zU?3M@GP|(i2|2JqYRXYt|Mh360RM3#4SNp%GDrrjYem#RxLq_>`59G z)m)u%S@;-N2q+4fNcB>NrdF{%T%)5tUCJtcWx>W2#duj8l0yZNs~3R?$-7)6389Q> z0fGW*-j&Fr7jVrs-+VL3IPVql&dOq>^NgK-xZ#{iXp~(U2Mt*OxJ#j{&^QG_onu~9 z4|KIbnLr|v)C$47T$C5>OHq~>we`@^2$>ypK~E0k&PdrI>(q@Tk%&-pSRL{ zM{Og9y6NF+g!WQx#XeM}2kWI&kL(rtm#P>$*A?#~0e<&D$4#CdSFL+gdRN51`19#= zJ#SL;YoWRPr@$lZmCyts&lLF5+a8|JYOlJVQ!lOF8^YOpKXmoXA!a73cKcXdUqL4~ zoAvQ;=otOEjxVW#PD%Q9EdNo*CCbsv0BHlKr2y=9|62$@$h~<%C0Tl2;g>Ydco;lK30Mo+yOk{#0fmEJ`SOD=U#E0u4qhE#yM#BGzv1lE1 zVtIB#Ml;qhNoHiC9q*Wy!PGI2cqCkM+<2;%8L2PCJ0j2qHm^Q%&?Ihh~vr{Hs%#azqV8g?;0Ua}y( zEXY0!GPi=%VCQ6e5tnxEG6ityB5^0ekkPMZiRV^T14rEq{Y-u8mYDr>ELsse}R3Y}TDO08@QE#Hf zsg$v7aaPG1lkinm8A&Rg%2!v~WOY*ak*QxVf?1MQl!8uoOguBnnLN(?hZb80*4h9eV$q3p_944}<9Shf=65 z_jvlb$S%dab73z==6VrePGqoip>JLxG6nf+B&#ef&T)yG7x&orbms#NLJF&Zdl)!% z1`%s=p9Mtb4n)Epi4}ZnLN%v)?ICuBpH-*zGqh^tNxfCbWQ!x>Hx7iavb@ND13VYu zB4oh@cyR$H_*%Ih#6^=Zh4HD#uWc55AR*za@ z3rUj*6It9RPrgA6#N6{EQpmvR%0F+ zFGB7?;qxwKw5GXlLFjA{Ul^LHhxXKu19Rbi4o)LB-LwBk0xgmWVEQLM8}m}W%uv91 zti%Rs@}mWG;-{P_)l)h0Mv4p(L>qRLB8l71o@_y*5L%>s9LN5Tx}F7DunI|S63-G%k>H++Cbms*%7BeF zYevYxlL8SL7i8QBv9(69%$#Iv_NYKia+?tn<(HT|A#vmQMLcfBeaf34G%HHx$j0i7 zto$Hzb%o1)jFEgNq~G6D97cAIkR&5L-gsTg6jJ|O5TY+7$wK!Yon7sz)qq?iUaBHN zypC}l4in<#$>12H)%0Zc_pk&crE=xez|w9OnittL8=1#Z?Hz_jST}cAgz`rQ3smfn z*|)iC zd#1R0?Z=NNx{q?jciYa4)UUpSybpe$euzb_4?k%~;wA+czI$>(k_{gQoaNI-^tlET zso=U4GsfqYjcnr`UlLfO6iM`#Ksoh88=?O@O*1CAXMUnoeSJp}T(Nm2wR;BScvbU3 z$U-9%$au$x84Y+t;>S;f5rFLjf~iK>rWJ+;!iY5k98Xw*7s!N4^b|7(h%r)0rsE1Qrx#zig_-AjJ@tvB zSO8>*dZZ{93b!gAvwm}7iEFWlRJSp^A7>aZAyPU6G3*hCd~d8By4Kx`&F0 zr-vCKjG!oZ2_Y^*2otZU7q>VSQx%KGf-D>ugK=mTFZL2pw-%;Yd6Yqg#b{enczNeI zg5>y7HL-LDxKNt@k3i&u))yG9kcOrsa`e|6okLFL zhZfi{jsO)B(5PDl(Tn9lhl|#L>@|-D;g4sr zlSW~P8sU>NcyfFg63(I)jWPdn_mNK8xEv2dA7&vFn{kl}n1Bw%lO6$q^HYYjhJ70+ zhevo3Tac6r0h1T8iv}^3GbV-;folaolyt`tR?%>IDH6gHm>cm{)i@CUmM%@SCT|H5 zskRcFs26Lfj)bF)MFEyx*oQ7?g2myOxY%AH(I0#1ivvWFRwN$06KH2B5@H33Tk@Hq zIS?R+Oq%(B@#8z0;znc1NRv2Bo3TE;*O%!i5>-`uZHW-$Xb?F^3Q;+1BXO69cO?P| zaG^nGkeMGvb)8lbS(~SY1#k~Rsd`eP5xlvc+G&2EH;f6hne(Y0vYCIjNF@kipHCr; z1=NslI1&AsSIH3@`gs2kO?i3Ak(>pwpCPdYgQ-qCmJtYg5YE|zX);91mp*H9o7uFM z5tvM^$#w%35*_+ELh&4)NJsR^eqono(G(jddQCs5CMt>+waB6_iHaf`I40yKGOD8= z**i(XqiB|goau)EwlO){OpUiQ#ABnb1EhC_LJ+ttOsYObCpilFS*k^!7D|~WC5e9# zN0{f9D;kQI7?JV$d^9AcOhg~hH4&;wj0#btDps7w$T5I1r6PDA5Lu9-sZvOCmLz(6 zANm-DijZ@HOk6pnSoshOilKW*pXroBObViP%5{{gshEm09ojrX(Wj;or4J+(bo!|oQ66Th{+geN*P(&qG6;Xmd72+%BOG{p)dHYkV=w)_?EwELY4wZ(-r~LwWrY$ zLDa{i2Ffx^ag!Otd;0>caA_{BSrl~vriW^$M;frd<3FL=R)=(_SBW38`l$4Hsevk_ zF<6?6rh=a+t@mfCjv`N)x~45?q@D`0@5!zA2yfSlN3nOOt5KfU*Q;fMVa~UJ`BZ-% zo1Twht;-lyNdg?GI;lY#vJRu14vT~C6gqb#sRj{?32?LsF|iZ@Y7X_Zh!JL93LQ`4 zo?$wf1F`=&GG$gpHjj%*5fr)f!;(MmS8i@vRC=hE9 z6Sw~s1Y8?7Dr}OQhYB1RPj)Bbb0V+x6&|x>;!%|z5nc}gKA0;?50k%@TTB;pe}@-A zOkqjUdmkT65WRvBiE9w9yB4LQUiI>37d#MZYZOhE5Va+sdI=Z%c9&X^m4N}BKqRAG z^0~ZQf%_z?EW4>P>!N}P#g4H@P60Bc3$1ctz5`K3(TBqLlO9|%!Zk4|-^-&_ zplk69_Vp6vyS7UC6pDrzva1&_rotL{zaZ?0?Fxck#K%5Ey#=5$A_2opvBpLLthf7@ zFk!~k#|nOtyOd#%G3qnTQ>!%*j1Aj<(nK5B)2@ojzapW90?`*m;*d^S0I`_9dIA5t z81c&GvBe0{QDo_KmttV%GRqQb5WKUO;vvKjv1C%f$Ogf#3Q=x2d=SIDns*z>pTk)< zn8zzL5ywopaWcxyLZ++x%&U4=0a!u`%ZJ+H#B>!<=tr_66un3suHM=nCe){kW49x* zpwqFtjqJX7_>-*a8+igF8nhvX;V3dHf$!#eGI2!ow9k=Amm|xo{#&9R)xO<46|GFs z6U@)x*BAfFB`#aK-zUI=!NE&9vggdresswYt*sHQ8ff>was0k1s5eYxCO?Y2Oia;r z+kl5_e$-=+&V;EWy(*K_r_&scpjpv$%M@5FxH(<24855GbjAe|f3lGm0Yv|a9VpRI z-MLB1xm&#)BKOds3$RXopXg)O1oOORU48u{isHP-Y|7S-W7O*V&N$oD@1>6PS1Qfn znZPyIA@s%FS~C_svL8s&U5!V$s>&Xr%#xXj$A?`@xP@kNPK23uy!Q*?nSpm9CdgAt z@{7-7gd-0e(jmdqiv83f0m>nKN2OZHLkPI5jn|H|c%D=M*nkj)Od9+&)?N+QHVeM8 zo!I!dv8nuf5=m08WW^tiM8NIG=XcVY(%1khz*&LSU@UDNjTc}S7(j4PCB|9VE2M%# zgBQ_Tu{;rnJg%y`(ucHq))E9{A=K{N#OcA&nN8eQ4ZrA~3#v2QZQz~1~A#jC@_fvT8k5~YB)0bY(UEtVzSrM3#z zU1>snc~bRC88F=79Vtf+I_oNCwhDzH|z;@Ulzd|r%LxOageBQgOkn~{J#dn_}~u^A!e zh!MaCtl>A?-kRsb1To1<%ye*pnDaytPm+i+2@${0ARtcL>r4OQtQ zVhrX6!P8`pMDBtYjmvmA@?F2+<{6>m9z7ANz7#X}vGG)>@y z9_d-TKqxZnkphGHe7wf<-pKMFW$m~-3X5KAdM!=|I$qRUAt7t%rHC>?DV<6fczKej#$pzBZ`U zp;*%bB|uU=uzGl<3Es|%{_mLrt^5Ao{H`5qUJ&{H@R+R-uzq@^xSz`-J{6wrAv8-U z+VfHD>O&vMHt){G{ne+Kf}*X*)jsl>OZ1^6dYqEwG+F=kYvCoM5+6?g^w&EW3IOqT z6!vcF?YJ)O6fy99RPvq3^j$A11(@lIWJXtC9CV*jV;|IdQB`e^7itSK=7P~&&)r}V z=uvN`G^#x|4epnc@j|bRU5G~CF030*v3P&g4CwPoui;oqf-l^r>W7xUx9%v{@&Ws_LHih#@3~L;xT*Uj>p|vh6-+%>^btw* z3ge{OW@*38#yHVtFTE`8-|!6l8XWyO8{EL1q95!1*dFbmeoT@d_ttK*K3n!W3l~g{ zdqzJIt#8|Zxz5nPyshfos6YQYZMlL?M4Ar}1qA;VNHEZ#!GZ-3E@UV$KtqTTB~GMR zvEoCE5D^?Kh>@blj1@Z;02$KYMw1s)u4HKtKuCoHONLa^Pyxr5IWu~ksnh3ApecI> zwHV~*OQK1YMtq5M=~IDDC!&NZG^Nz4S+x=!y4CAfuwliH)!CKo*`zleqGcP=Y}>3@ z;SSt1_n=(65+yv1nb+^%s6gLl?F-m&MZ8-_9?r^>@z=zU2Nqrla*Jf2F_Vx)I~Xhg z&vp}s3mTcFY0Rk^hBgTVGi#F@QLFw;`ykbfv#*ZTZMe5j*j5+*ZY=zx%z?x$QZ9fy zD07y3_iBZ1yW-}GQ3@bItG$4C>xd6tW+?w9rE7}S!>_Muo;~5bg@db+qCz zrGi3Sh{2r5kjP4bAe^iK@&>vmr&b^eV#Ob0gy=UJ!J^VF&P+^t6v&ITPB(pesXmF`s?JpEG%Wxx&zj{k)t0zjFWrOs1I*n! z3s|;Bh9Z0RpnWA;g`x@t(k4QRXr*XLi%`5bGAr7X|S+81BwQfH<6Zl)phI%1=RWT$ zv!HtmKRaL4xc1F+(nT%_tDYiDU2DS|Dv7n#8^YG;(rbrnZrkC)^hM@yw@|6aVeHAi z;0H&`_dwgs9W&$sL({mjmtSq;;+4lEEZ10=<3T%V&?i31i3bHT9S-P4Z6UM{wp3_7tI-g8 z=d#WXG5A9u1`#ms`-=YyQ)NWI_^>!aq>T~{q(k^E?=4VlAnRI!7b>2~iXYPo2kpYZ zC;|qIEG(00vN%PeP-P|(Do_a1H=N_O%`D{m2_1=&MI1Sii8!>;()O4WJx)YDc4}3t z3h=$TfDur3sb2Bo2C)E1#xqE?TX~uYBMGw1dQ9VE5f8^E{pn~Vlx)``$!4PwR&q+U zfs+?=R~SY1P)4r<1nNBQb5hpe) zkX@nYMC1jhMxw=)E+t+=qxVHm0+lFsv`7@jVKBHX)hEiNh$s#sPv=>5eFYGy>>}dN zxo{yXRISK}1{#ruIg}+|%M$mT3YMb2G%pjqYhUM*R4)3ETWKniK^z2;g_$I!2N{J| z4Yb(v86;6Tkty~X^3$9!s;qUq9z-_V$(b&srlEuvT!_Wbuz<5Id1WLg5yuvCn(K2= zaV1}CIivrz1d)NUd}>g*##V{&mL*uF(J075yQjo8ED~EOZEVXD;Et+$5m75c@~M;Q z`jsscMM_LOdKR&wYIqOqY|g^#D(x}mtzSXyCr`Q($WA1_7_1%vR;9Y{Gl>#} z+Yp69#2xT_ZrZ+kQT1I?yU#fbD>P>qwz3wn12HaHzOC?VcxI#V0j((n+e3#PH!9w*_j5ck1_D{yFYq+H--1jtVb@IhF-kX`|R zh9$O(R%@Ip`$Wz;W)tMvg5ymOgAI$;IdDe0{AA0~Cc9uZ2zGEhk@GghWtsGGL;i%# z4!Zv~JZF9poymMe6=&+dcjj4M>|Cc);m4kKsvLigb;@*B+Y?qOY+I zSJCoi{>6{au)^1-JAD>R=g7${`O~O9eQG(E4veABi3C{KyW0KPl!tkvQWkw%Mx)wB zrk>niYbP5PJ;hJH4%tJEEo?;Vx`z1!3af9`5a3ouw#R-CobPsAgPgZO7fQ8;g2HQY z3NOfx(kpJ|cO&$G(0M z6e!=y$pnsbPAH2dS!|>8kx2$_W`)P*P!T%DfSxU^_fW=30Y_@a-l&+fYs4wbh}2W_ z-EI;^<*N+J$>%302<<)WssY!H2J{laM=$OGr+b@o6o99D#VK-0%-abiDuJZgrF*nI z$Jb6en-Au_p7%=|`rg5_A4KO2{)vvYGGCL#jPwS{8cR+Lk<=eVV@qi-((@FN>ptAw z5Ls{VIo_)?4>c$5x&7=x_A-}4CHF~5eD><**oL_NMKhlWlRs~mUNMCG5-I<(K~ijx z&jOz!nm0-BrTU`PA7tx_^14!nJdx&Ch~0yT+FOsg$u2$dvldg0%9^-LOPEBf7P}I@uZX-!>ye3= zJN^MROY&NJfAom!+iI}W~z`m6jJ&D*bi5P_pk-enIumXTRlu|*R&<_dBk@SlS zJd%s%v%6fI3+6hu^2?dUL$jP>i3}VF_B)F$w21Q>jLL(EFg%sc+oRx^KC7b$9Rv_e zXhG+TGnu(Tw3CSOTP?9DLjlSO%sPuF#4dq=!JB)KR53n+yEda@i$VXqxWkjYJ3~N& zh@p@evmZgkhCo7=pc#ELh%98H`LhvAY`lypL=IyJN`bc;M78>}!9UVOh;YTa3dJjw zj5fTEV~Hj8SUnnK36MGnCCt780L9*FEmjE%ZP0{)nI5RNIyFPM2S#E zy9mFZutuLKMf6*bQ%nn6iwte#w4Niug&0M)2oX$)#lPsO`}>$E^b3{ii3P+R)DSFz zo4v>>MxPK!h#*Mz*u}QUzaR3(AF{=z=t3A_#Ghb9D~v&jkjFb@3u9?-OTsC&`J4@uPymn8VpC&p5(OcM^}f#84`&Qk3IQ z{UprAQM2L@JG~bHgAXeI<%eAPHLl7u%~e zHHitGQ+g{wEA=$stV|mV)CDWYRGQG1&^abOOF{p=tA}{cLsL_f2@Xkh(_~Y#79vr% z^okRL5(H3)qrnx36Z92HWPg`}lL)3UWz zZ#^c-0Me<*uQVwPDrqASbk3YG)qiW-x#+U3)y#(_Tf*yFhS&gS;>12P%Yj|Ya%Ebz zHCuKGCZh7#>cqOgHCW8eTdU(%i9KAXe2&&dR*11q!ONOzBL|$`upH>8*UY* zv52Ls{0ftG!~h*pN>U)-QAs$}QMO6E`d!=YeBC-N)`{5Pu!vc} z#Gp0F-vv$(hB#n`u*3>_lQT;I^G)5eL_Bf{yrIh%vT^GX9BEgbq~IAnRR--_i-n=n1319q?RY80K5DP)VV~Vag3nJbW7f z#SuP^(X7DXH}PJ9m}5}Y$RXr26ng(sp#iqyfwKrorom6WVnDN3TsCE1P22TtiHQ}Xxv1&EWY*8U z5vwyaUW5uojp>GHukWH;E~*>|H3{e_M~R*{i(qQjE3>u;>v!TEpg`-hIFy(WXzO5W zvLK?9!4J81!6M#@`ki934ht`(=C(+HzE*0m;E~>(+yJubpgxJDE}XrHX*yG4#fFLt zhKR;CiIjdJme^&CRtgC?<9#J*1N312RSiW|=5AhPhNx^7&I&+|*qRM4vkm}fu3@jB zDvYp1S=DC%Ih2B42#H2WBvK&G28tL8TcS>2xQJ>vVQHY4Y@b*an*9st_U57XRO%My z@XfP78n2#|?Q8$N+fo+Qyp}4|P73d}qw_w%2~OgJ*k#bhN9}e|vEXPx;ao0^=+^$n z`t8oU?zi~_ia~L1+VDxTC}SB>096eO4an|_sO}N1h{1Mh94hX1erj8?)x2)1E?%%N z0|5V^6X?iH(M|~nXJ^Hj>mbz$3rFw3wPO@-zp@6?tzd1SzHX8E@1Wc1lF{*7Hu06P zar3!Ug@EZp#E}Er$aTi?4u0sj@NpVZ;j85BmGdwk8VUk09Oxb>rl#`0#jz3BiN>b# ztP|^^?(l~FSbLpI?&j2pxa^0K-D1L1TfSo;kLSaH>l!a{gAnqXk?R(Z2;O4qKyL{s z|1hEAX664Zy4RW)@D`-69Ots>=qf%zl$C372@gzboE?9fuNY~yA@lMkO6bH|usCsX zwr(9k_4nWrj;tcaW91unZ-%Jl#r})R9?pS?HfEl^fNdAvCL>n=?rVeWwLbPIHV_q} z=;LLNLyvKLVWMHb5k2<_KYw8k*|Yc-^qR@m3`Yo{b>&~q@`)&P43BMYo!>ILH<64D zO;?Ju3r10&#)qEuV4jG-W?RYR(}O@H1RaQLSDOuhWeFhnp9px*d8-L0WKPrSMz&XZ zJ2=~g;*yZ)|Mtgkr#`ZocNymM_FjpB@@0)0=y#ayqkC=9n-`kT-*jTTOSc-Smz+t1<`p$X9%J%oWs|%!H4aZu=TI!`KO<8s3?J~ zK=>7$wN*h}zNdVh$ZUw7i)vp9_c{GhzjFc(3AQ$H)dOzbMe}I)>iy1$J;U@$rwLWx zOw8|k!*~@=G&^Y;O1^(??XvL4hxc#xdlG;9MKATDnW2+WoM4P;-{}ir_Q~dhg_1_Osx6SY_O9FZ^A`hx|99D8PRvCaOAaEeT zf(8#FOej!_z%mLSLX0TUV1S7hB__D2aU;h989Rd9_%UQh2@DNRAvtiQ%9b4~x{T>j zCe4^EA>OPB5~j|cK7WcVz!NCZqDGG*O{#QhNC^`a40K8}XGE$@51zalQ3=$7Nr(>R zIH6-#rezIUEgDuU$g?-ovL#toNddY8&nmP_kR{x>eqF9bd+_U2gncg(p2#vn0me!X z|Gi5wvP7u`yW;g3WTisLl#ecf=#<0fiGhuhNE+C4>DI3OW+rO6CDhqVp~nAyt-Ii9 zmjDDN=uJ>K#M}aZ7chR+aRJ)~l_S_4QMmJ`J(XKzEj=Xh&jPlCfBbxRU%eeS5Y?_R zF+uD;iK~C;{@~d0$>)cch@U)gv-x==l~G#k{a2ts1R6+_dC4JGAc8X`_z-#mRmY%x z5k{2Rgf=0BS9}H`XHbO#r6ksMVExrydn>7!9fTUyw^58F&8SdpBZfE9hr0E(AAcAo zgyUs@&F3SK5VhEuOh$gjHBVI+fMkSxE||WrqSu2@;h+30W9K58`yB zf}dUamt|!p<>ZcSZRF%e6><3&nraF)olnXwsH9*W%}JY53J?fW0yqEVdDKZ|2Fhn^ zZ5k>mL2&*zlAUp38qx%mN|)QFmXgY6p{1gls;a9NKw3+|4Z5C8t`5Y7O1aT`(Pm6h zkY13Kc?MZpf$jO900McIufSIcemm;VD-vWsN38l@!b!Dx|CDHHG^#+ z(P0;LGJTSD9dtrd19quQOCM@r$3}fEDPC|(3hH@&-JELQBO7(9*}LJ5wV9P#*V5l) zUma9YWf{(RV^xvV+u#s)lvsTH?!0OMk<-l`({Vj%brcUw(YC6ZtLF7d#|gqzk3TG zPQ1AB+*pMVA`=%9oa`jRaN8mj1`j5g}%qmV`_>7ZluuQb0JQrmE_ytma1wX#lkUD(kGY)@tjmxaO+suDtf@>#x8D zE9|hu7HjOW7A1h}vdlK??6c5DEA6z@R%`9G*k-Hkw%m5>?YH2DEAF`DmTT_0=%%Z# zSO~1^?z`~DEAPDY)@$#*_~xtczWny<@4o;CEbzbt7i{ps2q&!Y!VEX;@WT*CEb+t? zS8Vac7-y{U#vFI-@y8&CEb_=Cmu&LMD5tFQ$}G3+^2;#C3|kNd(A?A(4!0}w&OF;2 zYtKLj?U}Oo0U`9!NGGlI(o8q)^wUsBE%nq?S8esxSZA&E)?9b(HH}7pE%w-Cmu>dh zXs50A+HAM&_Sl|<(Ox#`R1H=?)m4Shc5c)q?c~Gm6)8a`s&U4&HC%G$1eNqwAXI??YQTz z`|iB=?)&e+2QU2a#20V;@yI6+Hz3M4@BH)7M=$;K+-5`l_1I^x{r221OnLX<-fe^Hi5+X>!3R=)~o=Oq^F37%^!WO#lg)od^ zWc(+?8rsl5G`!(uCZNL}`tXN945ASKhe*UC8u5roOrjE($iyZ(@rh83q7TYLcj*m$i_Ch@r`hdBSF$9$2!{aj(Efj(elX0 zKKk*G>uIdr^;^_$-thkc2N+U1MQMia4r!R7J4K{H8fiqD8M?c>yFt3UB}7RH5$RHy zFQ3@m&+fH*-FtlRn?GQF4*$- zDN8aLjs5rxxA3Bt5nQ@Vvf!kBrO~G~{qWqnSl#pBm*U%A2wYG8anUZ9EQQrv%AZy0 zsU;T-&qnp~K~sul7cIyr{#VmldB}81<|Q7ho{A%Kg&}-Py6F=Jv}fr>F{}J?Mw_sak+u zQ-$$$I9@kAp~g_3#RRQ_Hhr^_Fu01`lwf>W>#jjDkm!XIxk$liFfEYqL-E^jPBM+9YES;AT8nfJv#*&Cm(2&8MI`MDIlrbFvO}_By;!9T z#!0f}zLaU~d^4F^#oH#AYjK?|Z%$NPJ2bd%U!JUXZy8@d_P*}ez^?HeR{V69e%-mR zT;u)WhcJ8n_4|{k8s9y|&v&cWT{n|8e%Irl@9(a=0bjD-us~i6;qdj4xzan}eN0E@ zx#`7?t_^z;yX-!<<0d!_sl!TNxJekt4&I~qH?t0On+_u;Et3-?$of!#(?U}PZRgIVws<>R zD_qYT%3}~p`%)BlGbX~E`6QG3aw2!LvC+I#Xlw_AwQUb83mc0CCT*^B+vam|no8xB z4>dBp^;7)Ni&Q5MCk>hxBkQ;-t+2CH=M5w!C!v)am9LCHuPSGN{e9jk+kyBr2g-_7 z>Lb`vEO>sb%tSXgmMDL-9iCYNXf!r0HXqs-@C3T(*9xc*uCS& z`bl(4=bo}-Nl}OXb+v~SO8IxcA3r_=9=G77MSdORz86|3QE@AVyg$^NZeMDdx~xXX zOdCJ$SRPins?Yd!WUbn<`eEv-x#QP2rqGj26%qOZFe1V;THcW$7m z-t={2o_OxHY?4gh42j&IT55>yw5e>58s48dOa1JAg!~V)03QA-fm#1-76N9Y|Hdpr zbx;4TS%NSq|6iHqV>9J{Zx;Jn;(wTBt(9_ZY_g-}`{$mZ-_7E@)qOy3czrog|M<#Z2xAKE|AP0W*K3q_`6vY zsgdXYvspw|Y7cdYLu6MP|1^sNp-Kje!j>dK|BSZ53Xh`nwX0fHl zZffLF{kvISK5_kEl7)4(8~{=NA7=Tct$e-inZoG)$@d!Z&11;tFJ^gKv=S~5ZMG3D z&wjg;_!qN?b8Tmb-LvlGr#Rdll$Jc0rLyJt!7RELE`K+R$ZK~Ww7cU!&C*RwH^lhP z7$Erzhwgx~rosL@iqy0o&6wd2x8#PsONXnXuNV(z!QA(~-T&<8_h1%B^Xuc`mjvf$ zA09S4+_Wend>8h<|II8C*S#DLy`(8Xj6cm1nG0n6%`7K@q!YQQ0wac%Ohq%Zx=EO}T~3jI}SwV{F&c{uA@^_SmH!hoiEd5B=pK}n5+oRgIQ$i zd~4xqm6&)1e=|!yFVvRZ38DJHecNd? zVKD8}>p#rmk5x#8R>mlTe-;ZXX)|+KQX3_OLM1_|}+awruiE z+PO$~DWm0C8DiS+?mP#u7%uV%Iul5Kkqc5Tl_D9N2^GG`!yTj$qaDlA>pFg>oro;k zQIr{lqZLBFUiw1Vh6Vz=u#E~Plv5p>OK$&%S(0}PNZL!3J%r2PSCA4>>~b~7#t<0; zLOG_84aQNJCONTf=_<{^q0TCqyHt{>s;nW?n={1#z$GuGY=TzJ!;(;6)Jz%;TPynh-6g|!A~Ee^I!Zrse^BguTWwCt@}fJWshu3YqVcZL=;*;L z(~%Au%d07$0{=9N>8DHbuyPSIV;?tuox+I^@8$FD%KX=!{Mu>}+WIy9c9L%+sz=}* z%2Vv;y%#GO#@F3y=$s}An6GTyba_ZZIn7xnHrt`8l^x$|N4TFf(=g}_0EM{1b(Pf4 z>Td=)qn#)B8O7T|^@b$k4+ET!Xm8%84jU*j$A&%0zQeyAQBe8QEVrX-Q`GQ+Kg=TZ za82oj(5@W1`}qAiM^eXx%)Pt$@JE+ZqB2ZNTZeqaq*HW5=AP1?@Y?N^=Tt-X^~9d| zkK5@OUY=u|<{k=F$e_RRj5|SAr7T6r@Nt)^mJ#J>Zh8jnc8Zxzu$f6c{*7dqobmkA}-tUSgavr?+>$hZ?&&uC-@gCr#X1` zkIr6AwRG*Bnn$IDmB zecPrV%#x_sGXtk|pZ(1&2-O3XVXlP&c9y&fc4Vywvz)e{S9MPw8b20U?qR>GPq96; zRQ1W~sJ;rz&(br03Hj)Fan;O|^@U=3K$<45yPXmL!1+=Hu;OstSAuq;PSg3jS@!IY zqjj6MXjN~=9?X(Dj9tnzeLLlIf1dmJ{l2{F-CV}~1yi8tVFdT>qKLv}^}APJ%~XG^ zs;(XW$atG!GR@VpdVk%MqOF5Ow_`LdaxZa?G%aAh5mq#jqba-Tmt%rn~Bn4RN=IxWAe1zQ3ME=yY`> zL{HxVtO>pf_;b?uqo(>}wEAN$`{T6AfNuQp1p^560*E~WNS7s0Qt8^S*+^3Ys7M28 z1OwMJkm)=F!Ks0YL5|FVoD|D}oTNeAftHRtkngiW=W(3s)*(jAAtrSpRmh>J8otJQp+`X> zmZ_n(t)X@>V@x$U$7L@i7_BDw2@=vjgRk~qz=yI%{a=CaKSiql4Se2qMgJ*MwQGU@ zh*a#2CI1?!h#x-48hsi4e~eU<2GxH?sZDDyd?|m6RPMVu>OcAZ z5vjn&!Q{@K^FidH58x{fPqe>VjE1$@354+}dUBGvbmz=ue+r{(w%sh%A4TpjH7Yy7KUcoJw`0HC|K-?8Eypr9;x0XPBMFK zW!*ePs(%6BL!>$>!noUyyI1}beC3RPk5oA}-hYc!#zY^wev4F&eab&ihuWfko=pgF zq?}F3bG*+AR(1S!d4m-5tG>nY`>(%8s{7mhl7~p86;&nX8BqJ#c>NFXb?>)on(ck> z-mRuhrZdodk03ko$J<0kwm}xyW_yTKzk^S5)+s-bR22V$`yo;VIs`raYovOm|LONg z#k*cHac^8ojZ4hv&nrWXNr77PWC=A)9LrP(VG8~|Qo)$1=Ivku4B1v;Di4tgvrlF~ z!kNpVVv7(m-_Q0Csl3~0ECxVB+@?{mkAaC~A4VQtIH-#vp`m@Ur!X9uR~NkjrFeQx znj#W965xwPS98ZWB1O*4lqOh6LjsqQ;695BIHjfQ*crJSt#g6CiKJuvBT~&B(17LB zx|HM36643|{s137B>y+?2{j7Lohc`@TEzI5Dyps4r}Pje%=_8oK~c|B`8VmgV=N{t z*h5lgwPC9s>XIM-y2$C^OIj5gz?spOr&W%pFiyxcUc+6&gDhjz3Att)4x3W>|tlnIq&nz3&=U&l*rBsV%LWBvUksl(}G@-im(>M8~ z@5g1e8`K9cc*3#y%oKQp$pYITF?8!7YR&TWm@#u?Bnl?Q-y;>FKKlzjmEI4t8O;hw z;t${pg9<0&UzRE;musYqEffo1mWjkOX%R3k+FZUV$FBhEw2=2II3-nR+iU9;6b;p+ zUshTg9MBAhFE!&pkR5&lANfGV+~x1!3maO>vUaQS$7VIYW7gxpZ>kj+X4OKESRN9- zs(Y@P`fDV&qD(TG)jjGXDSL$Yh$u>FCLgAewBqWCb)IHHQP$a+{%RO^b5m{9H%0tf z%@xGzRdefPl>>e9%KF_^ON2VBQ<&n%E%NKu$qso(?+By9#HKbTR+Km2dCS;Fh#EKY zj`AFM*N0=NS5;4(tTAU9a)y`m$oP zZrTIt%61{}t^T5i7&5wnnD)$Qh^I;Z*#!ggf4oOLD{o9;tm52$4e}Io>;dt}T zC!Kfu)(CH7Bo%?hi2e*~kSUrzkA#h2)+TM%d8_C6r!NhZXS_XjiZ?Xbj)WsdcR0Oz zBPy%!Ak1HAL9Cuvr8V*ae0T55{Vs=1Uyuuqrw>)CU{pCyzFreu^|AT_Diw-W+yJSz_EEF8BlG%h;+80M zH*ufB41aEsP75ksRh?cScWzTXZX1!GDhekE+onUP3MngBpCylf-)4_#Tld9#<{|y$ z%L{J7smrhRNMlCo7@eyR;Dfr(tMB8lwx#~$O-4rJSeFT-O)5~iEZ>G4==>R}kvX z>-`C=CTEr4*~^Rq_-w^Re+SCrXYVt80GyRUTHyj?+GuM^6Jwa<0GQfo}J)bEGoS7EXN-`CB~QG`-hz zYdNaFA_d<`j@NXJB|K}~|6B&FoRvd_G`wRwewT2ys@i?`;@hvQ{nI;Q+jmVH&+#tI zg75L;o@bqO-{1d0AjtCH)zkRjOZx#vh=KcHR6Ww49{xC_B$yy=wiAEC8@urUGCaKi zm81X~t2gA!%HG!j(((R_R(>=J%2^t=4+R?AQ;N>onPZuW&6@Q|s#H-+pr8W5)dvo) z)SzswAaT;*%%&izWeOR+VA@Ry9z8w=Sg^`Xuv#mrf`_nTtFzjCkR~u#L5^)+*9;%m z^ROgDu|d`JhLHK@=~i&awFjvMOvaWpr0_D-DK+GsOE77HntSTIN`bIWjSwW7uu)`~ zAW~>8J}|Hq>IIgx9|@xg5spA8(8Me=z+u4&Bd}yocxo!#!3CBMCXcfgbn3Uy5)99; zQ}hnFC!($yrFAYX0EkMm((M}raG#i}d95Ip< zQ5qDP^D44$ITDKjCnU&if;6~?lmq*MV17Sx6+|?)kG}|hxLxPnQ+nH^j8fZtQ%?!>N`3Xwi@#pD*G#RxA3CV2% z8mDP3D;Zs6lFhdnnS&{P`k6y3Mgli9ZTdu2WR$%^TGJ5Yicqm}H>k{QQjIcDnF$VfS%ra9b_Ia1Eq%lSEH zHn{f?&!1_e(3RJRw>dA}qHWUvDB-y{?Zntn(HnhEq&v!i+gvm5gmtdGr|NllNPwrp za@6Idk8D}+3@D!1;xl0w(PKOvhv#vIi;%2xAaUliF6MKk7km#W5MC{S*X0+O7l;cN z%0PK|yq(d?8K3GEDj67yLaC+h0_Gu95L*)ULq1&tDMnjo?bX8UxFW2fEODel#yl}6 z)MC|u;kB z{|(|9i7NihAl~g`UczG@w4E=o&|Ibldge9#I8jAR?@>|qaH5_D*{(TT{ z79a7)AU>>o`mcldt3L+uPTyGnGKkL$IW{WYl&iJ>eGm^emBx;K7{t5Ph5c`Xc$dUi z|H~l$k2B7H9K_qK#=895LHu9NIR9f1|JSHJrh#8vEKCTXt~-pac!Y#-)wQi2cju<}8DOH5=j! z_DC9Zb!<`qIsmYti(EvFCZ3KKg1g5MTU`k!^*NTh9b^9begT;}ggbmkQLXD@%NDl+ z)sf{jJ_gl-BN7H9FMD@9FYD|e#dE@7LUfMC?~;{%cE=LCrYy2ux7nR8L*bEju|2HA zqUxhm6M?+4T*AY+7KcI%N;UNz`9gnARx;A&m_hLi@3rIsqvpi^^5*eW0 zURLTFw2TyIT-CN?0$Gqz0992d=)gQ+IRVFOj=`A(MaNlWYTTnUAjIV7 z?4#L=yLRMJa+!fy501+Bz04*~o2D5Z92JlqCEW7%0)tZt{Ee=k%@_F?1NX@2{y-Im z=3j%3uT3KsPX|h>uK7;P0u+!>pEh&s5=9xWK>GmndVus(4hsUKw3!K6(Oj<@Dr!2a z&VAX=drBFPdfU98(E{CX4{-EP&y9ipa;EmN(EIu<^ah7N$VVuzbDE}{yuD9HjOFYIjZ0l`8x}C zkN1jH?n>Db3kN`zb4RNh!)zSsw8RL)pTI0GZhpHY`6Sd`7`deSW) z7=_^~VFWvcvZix$GAXD};TYH|y&zYHw?CJ2G0X)Tl56WXP2kmp`9v0dyu0CB&ccq7 zk=~(e0SSyLPbWt`+5G_Z8ku6!NO&u{zJH%8@RGUS*;>(rnsKz{EbcfCZL?4^)*tfZ z{+plPLLyzCi)2mx{tAoB5Xh{-?+IO=UZ*LPz#z0pPk25ywgM3rK zQ5s-|-cCxp%04}fRclcGlAytC2&G~$YJl#1UrW7=Xx+;$ zVQVVWa@;<2y24gh8`{%SkU7$%1q;!uIp1B4{g8#Ar%Kd|QsLaL^w>oxy(>_Z_nox zCrvSd)`+i;*6~D#pVT7Yur73NNh%C@0#+ni& z)bB0kLCK#UNoTsptvkl@CB7*<;z^a?ih&xUdNBc{zw-36j$Er(eAD}+U5SB}w#Hxe zv8jfZ&*Cijo%`G~KwJjR5^%$PvJ$!BwIgJt#gWp#owL8c&LwXBfX(HO(GqMe}}_NHju+hH-8fL_7m9dcw{K+m4p zdJ!m<$*dAfg++qnPUfp*L=2Z*sbto5Qy6!}%i5i%VjgJP;Vv^&)S_RXi7-nOLHoj= z73j`q>nJAkE1NLCp;1#H>l>gWsG!Dj)ef zj$nzd4GqIrN&9w#3f(3sA5sz*v+7Zm_+?`1>|-wS3hamU_J~;K8nC|g4!Dc0Ftb-K zqF9-ftUz}2Cu;abwwvr;xBnsrzOP$Y;{GaE{gRKrt%%m)v$x{-!>7gV%|^!#_LCzu zNV$xYiKH?G$L87vzcH#EZf!GPuknr9r%hVJO^82X;tumelPxNg zp5(8&@lV>mu3IyB`e`v~NFj_!yCC!8^P^|Cyq10~C=DDQhF|#&!@8(sUl%&kTJx;m zVV^YoFsO^q^Uh{y$Y8B_&r(5gmmgC9!ubgU_383Xv&C6v1*;zw6t(SjTYc8x#Zg@( zDoCclVG4=!c`q#l))IRnt#PHmg|l@gQf!BjHlh zfJ9W8(qSpeU}n(1I+-<(@&`-RH*YZcdFr;rcZx;%wxwC-HMK7!Lbd~m=h=BI*l`;L z8G}W{+=7s)tpE#RJf2c`p`02zoX_a2c=go4a=2t9;xoEh)`P)_B^3z(o9Ye+_8U2b zv{h*!V2svkFA(sem4k=Rig!fUQX#~#71sgAkD&D*t`|}K5^Ub2uIJ%W>FR#3%T!yh z2y}M0rZWOxNUa9LfW55dh#dhDROE_$q4JGn#T%E^X6_ zOfq`^Ci;Xl<_tu;AsBPDOfPB{Sq_e*eHDG(N>y+Yv*m&}VU72BE4r+e2W>M(paA!d zRD2Q~i+}LU6BQ4+KNd4jl=Fi9wI#QlmeXmn)8m6E;s$je9oP?-I86N@f|Yortrr;E z;a75ADCl^W(!6nq1iig2X6ayG1x}Oa4~NfGfFzS>NT|@Fl}Ft<6q2Tt#*>ghDi}8) zcC;U_qyLnh0ne5p3VT%J02PmW$sfd+{M3r;ktXK~(CpbGkoG{l>wqq+TfCIKDy3VJ z`^wX``p}t?!0aY=B7NMQM%P~ccYZR`MP|>{i$u=DLTiH{5)z`)=+L@U+#&)XKVKv~ z4fIi-Yr2_jIvKQbt#{?hJv}70gq-e?mi}dv{d7+KNr5xGS^F!EQ*?sIP?)!LDX>>9 zg$-;bu^o&W3XtgMeO!X;KoSnh6Gfb-Xr#Cmxtd8z@PzhflXhPEbJ`}Zz#3z3j&h$zx~Dwh3KcBhQ+eC7xf?kxd=m0kreApIm}y4>MS!Y zQ33HV34aL}Fq0V^7x-+|f9^(f$Sd`gupUlOiF;B$>tOQ2d0b|jP*y)VOBkrz$m$yEz? zN3Ih}2(eys;g&h@#j`1G^`_W9lUvYtVh&MvVa}vv%yRcg78zolxpjJW$#SywoTC8Z zHL7`+Uwkf~hY=tm-z<0^4^%vN{Hn$2z>Jg**B-6b_2w1fAk|y&gg>UP#|VHEsK?NKtz%VuN-KnSxl+jgDmrVmo*&^u z!Hh{Pb16K-AO zPiuTocw?tV1McZtnFxHUmWD-w%o^@yqF2q}!uZF%5&kz^FGTPr&QzbthulG%=>nV< zrJ9T*7`)bSt6d5mwF?4R@cN~>cH5#jEnDZ7V9Lep%s*OjoNFx`Td^fYf2QNkEwwRy z&Bd!W5SEH3Sc@+%*C>@nNE~^*qJZ zU`HdV-@?G6NcPAK?k6NitZjpp7ww?QyRH3l`LYEP*t|ufy3HM7`Wlafsl**I)@E8! zoUF%dXA`xv2D826?PE?!`YL17)@6S9o?uq=P(%3bqqyGN_n7nVF{!(;1iO&2_yIq= zk$>jt8zvJ=CZlP(%*^|vnYFvzWco0Odo;az+Wra$-n+A}iR+1LYW@DWw^_)!u=1>t zn*zuc)YjnBO2E~=zf$-yr3=B3`(r@HImUtoLR{W^U(n26THeTKAwrfvJvKA zwvLh*HAROU;PJFRf^rkV*34VSF_3iU2wd++tGZ!4@MB+Pa^{caj`My;L^JDpzH1_x zz|xj}><2rJ0ev?^>-S$%3JN%3>2^VU+O{1Gr{}t1f;v$(zE%G zfGh5TgZ=R#WI_zSt=;&N0sf&Mg}6Dxg-zeownWHjkeAE_OU%V9KS$WPtsqx^vg_!! zZk0wapd^e~wM;|4Ykhtd(egEW$51v*I{R};-**ioKQ^HKgH!4>Jl{-0wJXF0lB6&6AaFs86h)MDTW3 z7#&~}p)FE1rfEs1B;L-x#V6l8UI4ZYf+^<#OKRE_m&G_!#N*@#?>-8kJnuUQ?I~FvWrHap>F|Lk}&0 z6@y)k`h!0S#qXxThQ#xXN!kF{)o~A< zV+(oapEH~DX(hA+AiPxBgu1KZca`5Hgr2y2(XwHjM=Xy}}+H2g(128*%61k2LG|-A*1s2!tp);9ylXtY= zWF4_=`%wf|P&cMs`A4-N7BYfd4X(W%AYUkYV2~{<&fYfq7}L$Tl~} zorhdET%f{8(<})@3#}Rz9$B+v#ggrE7f~l*S&QB`>t!~w&KP;T))maG{xxI7S%IgX zKypKx``oa6*=N1tg%|;W6Cp-#7$g}F+CS-#-YaIC1MC{G{e zdZ}Fy%1P4GFcp0+-@i*;ikq0uFJQsbiXuG*o^KcrYWWet{80pe3#dZ{*asEW z84lXWlrh*j&MhtQ0dBW#6U(S86=uV|Nlc*L3f zoshA#m%E34y{XK(CCASo>&T&2wU;6fCXWEmKQdKe^7eE_9K;vBml6zeb~a!mhRMAS$~z1wf)h2LJ&WPq63?Hu`|!i2#M#T8UU> zI30ViHK!R842MUq6U-GyM@2-B0zsC6(#T5Efi>vx7-E5_kNq0;d(4o-(X<($i84|% z8R&8t!JeEWV{}w*@w`wM6XkLteT+`wI*IsLf+9Mbv6fnOvq`-5MPn08mE;0%ohw%*4Nd{9hwM0t6kZ zOGlX2s92NuP|+n^kt{Ht4=WYZ6{{|S5WcHJPxiSSsKOJOpu~kcvh@C1Bw!|e?%pOe z0(#619iEBL{(`7@Y(kLJAV?`=-95j*>^eQR#`WYP|MYS!}bBId8hzRz(22l5B(Sn1)VmstoX~5^RSplS% znCfYan6Yd!5#TW!F1D7PdPR z9L61oHtcllV=2|%-`jN!1JD>+O@bcF3BC#;u_QGNG{A09WkOc3dlkVkBxn{T@TJu( z<~gd+PA917>Sdg&oX~F6xLTV<%F9q8%QUOvHp>jhAt9?sh&!RVr`yoDdAe6J%sLlI zoM)pT#j@R|B!@U{Ms|~X1hFrQmQ8M3)$*nNbxpV5l1Tj<*M#L$4O4u<#sH#ZJ?D2i zZoG^4Z&<#ztYzuZOr$18s{XoK6p@P_D90|?-I&6x?E1CZv0{!AL~$Z563j(c-74i< z>zg!Gq1Qs+cXlovbeZ_Mcl^Hj&G-)tOuG*+RVm#A>YzaS?haa8bs)a2Lzy`tgpfLQ z!IcFUAPaoj)u4x=RrI+x&{`x;qJf+x{KA)@`j>D`16zPhXCqa9m4`~axxyjFBA@!V z`&Z>4GnH_vJE92MQyzo)Uq|a7I;i*>NFrw@=1NLH zLck_;6NU-~er6&GwZRDbaKoo(p|k<#>O(>rsgN2SmmV}!CHjl6ILKdvMCF7|Xh_Rm5bXi5VFgWoGm47D4JM^mkj$Qn56BpQW)_A=ehSec9gVj~-k@acl4Hq;pKV2H7}Xk_fNeay7Ifi)7j73%(3dqCx)ZD)0nlrD=wkRu%W=2F{(1O=7ae*vV2L zD4q)%TW=L7R31Sem>2^+1SRGGH2+-;$!nk3D&1?ZKm=rNdnaTkgo8c+3HaUHHgcewBY@liiQM~db=x@Al{_QZl~1aNy3RURSuYyOuk4ROo|6S9OLTe zRl%g`JDjpryR=kg$Z}-4sVMXuAF-5JwrV{ET*zBE!Kv#BA|u3 zA)g{bZKNF+t7|bUWzf#@QlomBu*69qKxwdkZzvK+M#wwE(44bB6Y5gPit7?XvoX&I zK%xfkYA6@UXl0%P(1gC2+T-hM`kNE>2!D3f@YI=4f{R&34gQP@9ZSzn%|tC4AI&8j zm!_UyU}P-!!Uex?$O!dz7o6sM$tAl(x#3&Rio!JMO+<~3T}0n;(u;*F{D_&pE3{Dg z;S058k-~{5I32=5lODM&`TW|W?Pz&l9K$0%?$2>+KU>Ff>pak4iDOUxoTN-nGEtyt zITOAnIhuqjO8qnP$H|GpMP7Y8Se<|W7jT|WBMzhi%{_DauiRz@95xopnBiAn) zyYEu&_OP-;^ZNZHDY&~YZni+SF&QLYN!4`l1_#sRE6EisV&F?cRe|vHoHwYk4!01R zE|S6ux&RMdzD=nq`(*aeH8x2bJF{}(gkb)?K%GhGty+BSo3O$W)nWSkEOihLrW zN7E*pYlL^+@?%XeIjv(XOYcYM|vCZw^b!3<_DvGI|5)!%01w+=Lf6 z3^@)t6)AI|;V`S&oSv3})DNHUYl5tlb;ZO4_<){vfgpl8Cd4U)EFgG%6Qm&o3OQ*L zXn1;}i9vtYa2(JYRt7RBhz>#y1dNc#Qouitz(!N^Frj>k^Sr-=m>0q2?f68Ob)smA zIru=f_}qpn82I>(SMgDyiCJq9m|YQ1@>K`Cs0ZVaOY(4~oI(_~Wb*8*bF+Q{{mwyt zUbv)HNA47EoV+6DRV}Ch7Fl*%!Cyh2OxhnYUa``X7Y8QF5qyq-`?J>E;64({=CVUC zq3B=6Y^1_K4i;uX7G{Z~5---n5UwmDtdNdp;fH`wx$%jE6X4h#u;9{GUqhIrd8I#X zQg-gc&sB7%!xS5{@=6~QlVjkmMCQm9$ z6(uqfKy&S|{Z!lqsW!sMm@o5;l3N{g`+}oX;gc*lNO&R?KdT;{iwuKVj@6#rj794m z5bTu3Pzhq2i#DOFM>h!7hK9FqlXeEpM}35%I}9Yb;@4#WhERNmoBFHD<`Y*0dvp!( zRc;HQn{;*quz<+nUa}%isf?l@mB7M6D8J|#+7A;?(LQCLW_jpgfLS7_eCBd3PqcB$)2BeuL@|iL%#spV( zJ|NeG2PWkz1=yfePKcvt!AOPj2lns5F^vNFj0zM_C5fhfmZ16)WFu1nMjFdU zb9K2fWIYo|&D)Y(c*N^Clzm~W)I^V1;g@lI2qGGMO)^-mIc#-SY4J%<7*m;#=~Tgn z(r#?d=CVwOfh;w!rTngc#+u?jVj%1sBl30qW4M5yA{<=`^i4~!nQG))BWsBZ3h^+NK^Lzg1uGlVt3bCR&@-H$_+z9Z*vYA! zn2LqwiG^Qb)6D2G7i#^(J<-KJq8ob%aeL78}LF$48it%dsdVG5uEQ3w}Tj^Ta66>8amVf9GN05XPqA z8E0mq2SQq@J{HlY1h)2M(tKV+!}@6xK$4 z=zHd)(aY|wY|!3RMg>|^m%OL$vEdQWr0$Yb^bZEmDg|Ui8sJ=nE$^Bl6PRm9NTU_b zv9MOd9hBL2c$wo;o0D;)UoiJ0NTpy;-Xwi4#OJ?2ubzi*z$axOI5T#o#PCs*Jhr0T z@vFM1zVJ!RN$}gGN)@DKGy@JNL%}`Hw(!e`e+?BgRMNU^&!E8sN>AFh(^_%E`@s_! zRBHYP+}VDvNsy%GUfY4{d{z?V*eMWxyqSR`ImJ$|!AQ?)L{(cMy)-bN9?m1gSIL-A zO0OIzm?F~Jqy~^S>WBB}loc&?U9LqQV1qK}S$+w%okW|Hc2rv{HtQJ;66p^IB-r;Q zea|nj$II%qz^_9)kgZFE0(Zj^vP&d(!=wHy^x}o*vz-LghKd~ zA7_%Bd)J56UkG8M-)?+FWSqQc2c4t-;6FTK2L-PUdi&DhG4E@Q@M=JOBi6? zq7Zz4T{1_H9d#=9E#NZ}!v=C_y6o%pBQY`*{*B;Q8>pchAaSf;QN*p(FVS%#(NNO> zU1T^z8;?<6rKy{w<0oKNf5PS8#MRj(vV7HI$F@*T?U_bvkcKHX+J3^eGCc{NIx}Jy zq7#XakZ*%I7Lt!(N2-!%9gAX3;cq#>6L+%KkLZnCsf>#xd&t8-F5;16oV|=c{6ub0 zgd7ffd_@4Zh?id6K)j@*j6`lRNlPFO-4-k+M{I7gzTKXG#oRnXn2}!2T@Vpx0^YbJ z8q;Prup`v&h{IIBmyqo&HeoY9Y>h>_I!)kS+JA@%!!r?;G+C$5H_jZ{`uL+IgQh z*Yun%C^d3hJZ0r>!(Uy6o7`v(Rif+Hf4ZHs5c=})@>yTrqZjpgxB!;o&-rq!5$q4E z#i*Py9OC4tBS6@vvZ7p_M`PSGP})kCbcr;2_iPYBK5SnPUG4TUf{5_WEMkaMLnb^P zu0f}xA6>T6k2qu@eCIV1%-)Xunoi-MQvDn8qEqL=BLTNc1;;q-uY8=kOi{R(DW+SQ zM?Y{acSg1C>!r21*OifRGD#m>((ESCf9KqmqAv14KWGzyu9B9&j@?l1X&jgrCYrh*k(VKh8|{O^@0T)t{K-Z1abWed<^+vKTEF3PD#*HrPXY zYNG=WpKnJ5vaG%g{nBYKBYlrSdX`n(^+kt4%1@uUfDoP}qLqM8Q&t^5E5TYbbo}@j z+gSzE{Oma|bC<6YrbG|UPbkAq{}70*<`GiS({Fl>37r*&g|C4fA2t#-^|wjB3=h+N zAAWR@Qa*M9`zpE!Lb5F!i;Mo|kl7yxzttD~@-;I48?I{wd>;T{6ieQ=PP8?MejYJW z59!3?dK~5XijWCCY6;8JXZc0b6FAEgdLhjhOz+!*20maNqM>KMlRZ^GY$IG)dh?U$ zCrum1Ezb=|Ar}isdODgDLC`2TYd#vUjvQ4n6}^Lc_#7U+U+V0pD9QZFiFg?Fbhyey zAHPwU2=VYRB)CC4!!spwp@8LimQoo}rO&fg;+gkcAS6hEs_@y-mFuHV4QlY7efaAW z8B8tyq&_%&8B4O8i|O%R~=D@U4W<^b~k5|)JD?wPpj z5l%eCg2N_6A17?aNVn9Z9(0wFV^m(kwN%3AUpf|7_h$}ITVKm_6{P$kPbNf5deix^vvRUziOw*FVUhgQ zDAGs(%G54bR>_g6P%rTe50_?XaQx^|YR7TzQH5 z-D}Cd({w=_tA!z|jOX8(;k06%QG9W+J*V19%9sbIqqRa~vXv!;%Sk0LS~HOHTHVf< z)4Yj;!g<~XB(fB;-V zu=R{dpbP|q4nnv?H2`>oM298gY$6FjVP^ox0$}(S@r1;{InI$mWGW&iWMp-9d@A%n z1!R2lJo%siZiZY>&e@S%cp|3~Fs?){`zew&p+fD(2py@wl@hG}P%T`dQ1GK|gGp{O z3gKO1JaA7XMPBn>Yim9i0(iK?X|d`|+gnHoAy&dwh_6p}E$iBCTijejRJ|s^@A665 zQZ7UlvgKpBtR9h(qv$t(jq7Zd0>MTu7xF45Ok--v-W^eE8p|$`KgWvq-jrt=D@18G zX!HMGZWsi7_M-L6dVGpScy)MVxoXR3j7E*aFX5}B)fU(9$G=2wPPT>7TpWubl006y-_!&|3RDl2hctZ|gSvc#jlvMaEkiD!Z zSTBJMoDM}{GNlTpWa!HcW~TR?Q=vu14W=O@!UZUy>|4F0g38>O1b!d_`AbQN%D#Yy z1Efqtl#;-?e$Qw|a^mRe`{KC;kw*SM07F2$zfv-aC=-NB2C{filgix`ND}{GJ|rWM z8ks5KjgxJp)`tOz#$!wp0_A!e(@g;DoV zX(m~Bm3^0GR4Q9l#bg^01ivgZNDdYBa;gQ?Se@0~^OYz#^S94By@hCwujWAuALJ*uigZfko7%_WPX(T>I>QCe#+X}=n z3f(9P#+y;|=#u~g+RQpPl3jJwvL#9Bg?`ynkc#Gn6AUIxa3iWyrx-#Z1dK#LEJ2ne zVnP?To#jDRQejf)gui4ZM<6WXpMUIRAvY-~CNpWDGQ9Po2z@UjG+|po0$`i&oklID z>Is16M;l=|(Ikp+Q`EFVMZCy`d3O0v35^prCISa0nG%=}ALzfkG%tt{`A89&v!@`0 zs#zB535Kw^G5L9FT+PB1TPOY3G* z69GwrC5kW&5G3&;35jJhLD`7ML=rWp;0P;HVI_V>a*+SIoMa*dNkCv+hB90BiC7iu zpHYHVJtP_=8R+86#cZiexg8}Wk-H86xPqUt5T!Af3rQuF#*?%lYbBNJ4Om9v$)FWr zWv@~O+bBaD>MR5$0Qk#uCejpT(&kA(!JH4@0=AAFO(<&Qwdt^CgSlxSQUP&dMV_`IGbRmfXvHU()N;tb8B0?U{K)zo zg|$d!1Z|ZSlCk7^ECzOjPmJyAn3R|upUrSi_xXta!qwTNcuOx+lETy^6|@^Q2_>Ud zkc}t^AQi?BuA{;2xHgppXEpUnQDT^zoCTp{ac@~AOw+1hQ<7Ar!_k*?rM?rB_Y4$Ow6u<5O>C1Et(;PgBc^l$~6b)de%S!47^fgxTek z&?dAx%zUbOy6UCeS=c11sn3so1jop%GjRVHzOac2a?7`A=fc+s@pd5C7s92BJY~g> zh}(lv3?C%L)G;xTfQ(n{q>MT;snL$XbGgBkh@5f_6NkTJ5+r-4Y$c(wb}R%D4?{#u zQ8w|7pKRqGYZWJ4jxm(g0^=H^_$En?Fr4Eo=Q-24!I@&8?hcVRExa+>n0bz5N~TV;frFsOAp8f2{C$(T>OcX0f^>F7b&!I6@Rg7WFDP zzVwA_hGnu67I(W&aTy15p)L5QS0srL;@Lf()ec*BdtCpRDLv~{^g(zQ>dwXof?ln3 zY7M@g&N_P2G*^?%MNYx?7K`TV+ump&cyzr`FtJb9tx(#_Thae1Gdo`)Oqn^@n{Ra0azK?XdX#br(WA@1LF@+WAMRVRnS?>e)K~^5?0x_N&kJ=N5cA9*fWWxAnB8P=)*L8qIqx-9ev2 z%yrE<)9}?Fnk3EIY21Un2?7e&06to8l^oPH$;f4oqe098_J!|R9K#Hts`QW1;hqP6 zAPBlzRJe%pERd9hi70Il0@%jG$VMWN%|eXC*tpDx;6?$AL~=m{SHKk4?BE7Y7%b7C z>LkYwPQ@~<2_>;tN%;SXB}I!4A_PVB$&&;DQGCq^&Q9o<9_Y-TqfABB=?{+N7QQi_ zHI0mO{8CIo;cQ^x=8>D{jSLr+)e#m%-i;m^GL7f;nB(0|=p4?c;Nen8gs*5`JV{=| zwIP1dp=34O8@7$?Ek@hK3{v&f&RESwl$gvc#nm{XAHLB|O@@l869=-=8~W16fME!x zqAKFva)m_@)rt53$kbqn=~#*J_)8F|PJ>vNzr+NeB*H^w7Pq*f9z6suw#bmYRW4e| zL-1UQKo(;u8VnUle1wTIBnyieMO3&^`y?WOfXR~>l6}fg?XdZ7hohRO-C{_o| zz@vP%)g`KnSc_h|F zO3!uRD&8bcLfg9ym4I-?Kh=!a@MJk90ua32UKohL1W3uHhD(GZ0@MucsKtQjiHsP{ z$uw4ODM~{$rCI^ht6{|KNr;~eNVS;;NibytxkT)c%~j}P!t|ukxD8p2UR!A)g^dp^ zU1AtY7V6=h#4MsxDBmWIALo4^=K&k(?MzNU&DB`qyZt2^avSEEB2(?*WPVB}`k^Eq z$s}gx)6xHq$v3_!vjZO#VWQQkxx z*XrdYa0Vx@5k!HY%}`9uGC~A}=$A}*(VPSmL*P(TDZ*O$M=pZZt5gVu3>1rCNr5e& z2mykNHO~fmm2mZl4Ru9wp(g??P{3FbuK+dFLaFq$zZ;63_f9>2anPa#2>+9cY^2)4iPbr;F%W^sYN?&%(z^noity!@ty=q2ub`0b$0(( zk5rT3_@Wsx#kSH3Ze|3=#UzfDe>a4MFq>zHoMLw(3K5eZ1g`1hhn8;7jc+DpTjcpJ| zo)&-vP$xo=h1<;s;ZOu7O>ERm$HIV!MgZiR8U-6g4Or0OkJg{saE)2=OHsa{OaR4N zl7$2WMmSCFUCC;xs-C-!7UU)F$lj`FC?*#|dv&sGMxD|AeHG4J3rVUWhy}gf=jWn(%(|F!d#=11|q9k;3ryF=+(f z=LE;^k$&6rPB9fjm4_+XTwt7@FvkdUtYMTcraV_km{`jA?%RFLb)ZUiz>>YmhLfT3 z3!A2z2nt*<7oI&GUTiAemI>qD98X^& z7oO?$S&dyX%=Ih2jmHc-9;AE=uyP0O>D;%37Sz11+%&}@=S8}_PRms>EXQ(G!K8H{ zP@(B8$ma6RjD!-MS9ciPok^y4*vX#|Qd;P8;Z3r4m|u8c4!iMX*p0^_Vuz0<)a5aA zd90Xq;M{NW8F*mvEnl#odD}S0i?vCyET^+N?+!K}MGJ+8^b!AF0X&W}pc9rYk}E31 zo6(tNuCwh$bEEmQKo2yXq4T-`H1E7IBO!El7&JjYG(<bBJziS6|=9mh}Py76{KU3P&>r^V#mn?7%uu(-tW}|K|iwu#Ubm)>vq} zYOY^5HDY(PCyR{YN=SRj>fFW5gazKM<^XYi0h%F)pT@FYp~bf58uA|YvrmX@=*%vpq2g#s-zT$Gau`eL+9b*F z*8I_2Dpz(u8wqfuDfIPEVpq3BtL)4U?Zc)d(8?T#IIPvJ>qQD5#O^iiGL3-r$dMAH z(2j?=(Q@V$uZtF3?g6w+b2ojrrr?2@rfy1Np;$vwDxl;nk-4l7C)A_BpEQSUc3pKwk; z;*_s68(O)3f|+hR+Usf|Bz7X;WTD#SZq?ilKvGYrm`^M9HtS(xfih~q&8~zbswyAO zQK-4;9#?a_7;=}mpFiyr-8lGS=SeP)E#heM42Yc!SaU$h-q=SCQVFDE?_gLL42h6+ zVUP5{3YqA&M#M<*LWzwq1*HgxG+O$Fw8&0;5`AFE3yB6;eTrz9&!2gy9-dqhC$SI< zTcRm3uM_r!7Dif&Or@DY;c6-5pvb%fe@gc(H<-AJhqJ(bOvl#++;fQO19O8IUDIqHu5G=DB?cV?{u zY9ltH&?9|mlDQoBb0jK#tVX?V+vOJOc6pQT&wrHZty6BLBd!|@D}()@a<>>(A|{T^ z@Zu%GrfGq){UCE1*fHhVj`OOyV`pZZ~)%-PMzed6)h? z61>cwBc~b|b1ST5FYAQCUS#(jK6WyTrs>O$Y}GCDKib{7>pWWwKa=0#fHy4CRk%FL z(NU!HH-Gh4f5GyxO3OX@mmO>Wo=@aUVHBA?-OqynMOTlB z#+*d2cn(-(NF5`_iV>$(76m{A0RW(YBp^W&DJhTuK!QX;3PhABks$&gQUXCNFffRe zM2bKTych&X5-C6e6!54hk)&jbfNV^lC<%Z74JAtYh%+KXpFB4Loj7!&O`!vcHat4; zCqse}nG!A9RH;*_KBZ=rSoQxX)~yMyas^8jtW2?0wSG;zR%%zFY0-XtE0gWevPrE% z1%Lo4f}&4{MySF7T^i3dL3I?!)m#S0}?F3Okj;KiLmhZa4WbZOJ4 zQKweDnssZ}uVKfQJ)1V@Bn1>H$*l-u(A&zA#Ed-IW`QJtf@F*tR1xsyDQ`c#B}xaq~fo>Xl`4?+B^ zt@@-waUu=3(hx;1QS*_?`jF~SOQ^hT3r+CO)C$WhYl~CPIq9s^&O7nUQ_ns5G%bN3 z3`_!0KpSc)qY=d{jHIhL#OR~wA_`===^{$xw)#$j2!QG)I_x2e3JCJko*vo@5Q7ks zWTT5lmFhAnNRli`hidXEp;9esPg9AUv=pkIs``jgv&Pa3GdHOs2&||+D+{N?j$J6O zxlF{VDbaXB>sqylmDbrDvn4B9x$dH?v$*gIYum8eDi>XD8GBdVPziHvF%LH+tl76H zleJsoK1<87PWAtK%3dBb>+7%2@Fh+&w)pZ(v!{IQ)8dOU&RFA(IqukF*~a{Dyn;ji zZ@&ce3uL3)PSmYFh}6qYz4e-FkfkJVQ{>Od>`P?X$7BxVN%80lLJ{b43q&{X(n2{s z0&|QsyT58aFGH44)@ePI)%z1E{T513vNXEAfRH4J>^WRIqlkh~XlB63 z4@MC{z2yqn83n)GMT*`PnY;)PC^Pa3wkXCdZ1HYEn}N)?rbU&?h-E5nDHmK0NUn52 zDPaHVodyS!!Jt%RG9*OY2p9G+0j8~D<_ZgC;uWK7TwPbHmHbP+@F=Vc>e0 zJ0T8{h($Ew5s^5zHl+qdHnG$ai=w&=DTzK}YFbUuqXZ}h#!W=Y&WS8UG0_2rNl7Bg zm)4Rd4mB_|TQp4vN%N&LrSV6h+EN{(NR%>C1Wc^s;u=fXM>7rujfQLCaF#P9&}a!n za|Hin+8D_;x{;BMXLBPVlOo7Fo^g&X#ABC8$CfjR#FI%h#2hG#9i`X)KZ{ zJHioEu1pOAPW6$N9HcY0>`9|;M#Mdu(wD3pA}xP8r~bimh|4tQGocwxX-<=x6S>VL z=VYH`Bw}o;@e81WBSd6Ylbq!==Q+`tPIabpoa@|EJCg`cch1wD@}#Cc>6uS`?vtPW zgeErq8Bl=^l%NGQ=s^)$P-Qg^Pxu^HLLr*aVxq>D&eW4dffP}VZj_@Pos%s~`OwmI z5TI7NokQPfyNQleO@>(uM$grmVcH3$9<}LBahg+|)+LrSxtvfgazAEfC6=vPOOgL( z2UF6l6f{gdBSl$69VLn8d!m69Y@B-4*I<*9J(=m?9;z9of{I|pnyQfa$d*6dg{|CK z)=uFXSGgXvJZG%YXNYzhL6%3WO;aOj;2D4h6;g>4S(-AQ1Rsznqd9|A-XJ$QpvAr@ zYVf;G9Rb6a^n~*&36Tm&niHkX3MVasZH^+6Va?_^XG7^h?Z^snSk6u)0GEwOdKjyn zu$?v#oWU(`BhnjyHY5qkPzHgbB_5Tn3?nlwi`W9QS%}Ppv8lBzV{=Q}+m6Sy*bQw= ze!E=b%yx-S+=y-aq5~2@JZd7sVvmu)q<@=-)U<0A5$`4s_rTUtd6g#LSjk+F~*>YxyR7X&bBHySI;br_0QdjU3 z)Rtq?k&KXUeJZi?AFE6fDX>J!DE7{Zm*dRfeObr+@m{Eqx67XJ*p6w$NKE{aogUle zQ!iRE`SNV!Q}x*)E>TYhYwBQC+X)G)t|#dfVl22Vg(R z%V|&mEG6L03hkO0AxLe*nQi=3TDc8^?07XISSbMFo3_b?I^A1;ZMZ)avCmfsl?l`;$5?Lmh+&C(A#JyN>6f5 zLdbJ#DLsQEn!>fDZ==!Muj$^9}VH>cO>ve_A^VmXZ%J1Y9t(L)NY9(C#~+&KIN5>V(S2m?j+Cj%)5?L)K2Q7R3uc$p`)MA2;f7@Wm-Y zaXQ>)AjF3yg2Mu{0xUGGmhJ~I2t(7VVrI4kK%_$>>IFO^CeRk|Af5%INb>1XkK3IFwQz&xk-CO$8fmC`BwY^bGu*ha`Sd0d?#t+vj>( zB7SyheWGvXP%QOeWxvjEA)k^{Smp9QMFRigEGDSWvsALGq%u?h>{h%l`YzBQ(9*@a zgL!mgIvfHfgvTH%@O>te1yKUjmP7T_GPsP2_(sfE65v#74OS|X_eRC;TF)+CZ^hEO6o!cvg)eBfg2v9 zX2?tGj3%6pO+S^V<-*CeRFU3HtN;HBvAvQ|JVNd|4o((v&LL$kdxc|>#Z1z5D#B(9U;U; z-J?68Fc5EV9znEBd-F`uw4fBAAUdxlWUv6t(+JtBFz(G!1_wSA>{v=gEhrKzdQ31E z!onnHDrPQw{0$67^KY*IR)$ILY1B%uOO{i0l|qeGpiGe7mV zTIC_j#j_q%{w~ujLo@!W?*{(`^Z7)~B$`ano)Xlq$~NULQvelOORx#!O#U>5&8Sr| zp#s2!heK{u<3#K^Fylrq&BJVSSuf}{F&_|X7B3w>q3QS2INo0yf z=6b{9k`N^{4mt`wS%J4v`Gz$Nt!)o<|QgksChlW64^ca67<;ad`4OhyxMhWZ-$OKry&pa%vH@B&GCn?^Y9|_Du&gzt+vy4q|;W0yv(rbWQeXc61rpHntS3 z;GUu!70VB`)?t13ck^TiPXi7?gj1nnI|!&S6hhD}QY-vYRiGq_2%;qz3sNG|K7$PW zxG9HZ#UoUOCSC+pLUMhOt{@I20j{qgUZNp_s$I|pdbea=HTBKB7h)NY|6=XUKyIgEsZ0$ys!FnLJ1hFNuujglDXV;f_W3VIlYZ&H`Muc)SLBlMU4(3dY$Sc6Fzh;KMh z4>;>g4+Zl#_vlYYEHhAB@P}98Ba-1IL9Hm#$BN%4JET}A7}JK^7M2)MkM5_G;MjH5MS!*cvvP0PGo3m1R@?H2!2Mejw3t7$T*(% z2$L-t(UK*vfI&ES~q{+IhqbY%oiZP}+ZX_hxXqdGgDYAG4tS5tJyo(Y2 zsEYsoYMcnmPDmP$mZ-1$5!gg3uIWg20vkwlvo-#DlN!4&N{Y&!S~e2fu%F5`7CTEc z+pIaev-w1-M<-)&=tih9n*wD88&Y08+hfLRwO#wQVLP^Ed$wu2wr!iUL%JdHB)4zd zqd>d2fjhW``yYS1V~U%>GTU}8NjKZ1wJm!;Vbt?$3dH@y#3|yz9jn3RyT)z2HQGw+&gG_aP3|t-GuZd)NMlw_q?dj? zOQ01{c$Fw#EFO6Zvrpo?jk>7gMk_!pV2|ohi#jH(r>c~^dHI_$07d<_lE`&LijAvz zTOt{z0nS!S^7M7blpz_?9Dbz0`7ClWm0=ndC6*ZQ=~;ZIDhGe)fCHy*jLYh@*uX zlTxb3wYrJwNK4m39hXTWS?<#9=&rM*xNJ zNYk^Fz(=%bC5i)k(VdWy7&l1uHVl%fTEcd}M?spGxICgJNTpWt%I+)$C;U>2_|T06 zT+NKn{3aq081g3nj#Wan$sEM|N^CDFB6uq2A_mJNC_V^UY*o8`{k~_VrDNga7vbGg!?`9&sLpF8fvEk$mUJl;{hUD3-jxZ2s0;24drOFJ0cwkGP(S!7wHyKJ_#y?JF|SoB5`g28US|J{$7b=h)O1Nf zxpmzEKfWU~gNK5fQ0u&^ZxMZr=$2;(-|{tU9b}2CCCmK4L?rp5w#2? z+*qO)+0DR)f75OK5fQZ5af5kEpW$f2P)f^YT;FFxv3n{O5xFTzf3)^dB0DCpKr%Wj zAg=hmzdH;+wKk6V4NE}x5c-d6i%i1US4=&K*_xMY%=2&f0ir;F0*V3^08*ep5=8|S zDN_O{p~Q&_6(s-?L{SoqiUJ_4cyOYUL?I;x(D-rU!jck$NQ(bRaiPbAN(>_Wcyi;# ziIQxFOj0vRqMZU626DJDp`t`Vjv6eGF=>({5rHf$n8ariDOFig{0cU#*s)~Gnmvm) zt=hG0+q!)VH?G{dbnDu^i#M;{y>dwoOacG^5Ge=~DFHGPBjLaR07()UcrXwk01_}Q zFfvHsK$0*@Wc(R`0;T{E0DwACLD@u#DkHv}Sz_k`PYVF3nJ@v=M4f{qJX*Pc6w-o+ zYeuVaVj_~ogZS26;4($dAE76du9P_tNkNhnK)~B`?(Vh|NfG#+w{zv*qbr#>IFRq$ z$rB_$I6EPbfw5^TsxFar#bFnnBKk?O9!t`(rk@fCN|yhUb=DmuMIaw7cb#_#Naovy z{Y`Y#M*svt*g(}poxYZNFYVUF~ks#^D&rP0i&Uq5CYT< zgur!@+y`HUDaA+k^L8w$iJs#xUX;LKdoFenVSb%*zreqb1O>QLF zjC{>WXPtK5iD#aA?#XALe*PKPl!3iBQ36wS)FuE}T4f+*BQ_e?LW0p`(4v85G^Iq2 zh6WTM37mGCeoz@WR!xEduuw!(Il9topi(B$QauIs=}1Cd6%ndtrnTKuBOWGErwIk1 zL{by!Ium*o!K4sGwndkv5{-Tutf5PlG?G^%1pxn)PZcFg6G<+?lu#gDG=7#dZ@7oOl25MxUregLQ|TikR;0R_zbJdOdpLjDMbafgj>H5T{SR6%3QQiRtxR4(7*$GOVCD1YHBK*SvfRQs68SS zYEHRATbQvU12OWbJDItzvmgbCZ+i;`Vy!Y@YJ@RL&o*q^N}~b_cGzN%O?KI4pN)3f zywVEfR!;rr9=em2xY=WrZAiC$8)X(5VIqQ-kYGY-_GzdADkPR=N>qmGWe7Uz*nZ4? zDxrbF*hV>TZ_6hUVT4n3^H;mZ>fJ@g>DT|;S1yUC9Ffvd`6H>y^|X}i;2k#Oh=djE zy6k~d7n^Pg95wJqWBNAGX**eUlct1aS>W3V8nsk=Sc0`->bWt`@`3xMc^_+Ui`OQR z0)-eOp&5$G{6XB>iskhP&bQt7(1K-Il#5*xYD66hl7}K38cZ@8VxcsBaC`v(QbjcMnkTV_fZ9`=3ttGs7|L*l zG_2uXjy9{xGzw%u`QJe<1t|cWq-P`RVWc7!xWI4sP z-K0WM0YZ|n_^g&7N{OK|6j+ePtoZ-L$XG%FSFn)yMrM(yHYm|ewiu=em^|!bBzaO! z7KJmK6{U-+Qv|SjI3BNjWr$C@qsWX^p>X|#DDf%_Bb8zku84(eZ!Afxpz^LT#>6mf zauy=L^)W$W5?fJ97_*dRvOt7tD^K#6NCcS^hMnt_(o$rqRHCwWDFXAHqX=#!P=!t8)|c#-0Y?|zX?vaOeRKY!cuT%v#7*K#x_RkOaS@@ zs}p6XGU4$JsK{uW#u2VG@KR)0I1>cZkw$N-wXFk^|5PCv45xm*Y zHb&ae%4tFdL?GH$Ca$rzFB)btAR5%KRk0iEq)iOniAt|}uSL~Bg zfI{V|VCj)SQAE%g`3sg~Wu2O0I!*~-C`dy6A9VI}lY$`cCRec^USHxHX+>#;0k9H< z82HwE5hgnM3F>Qzbdvx8;y>mKr)4jT+01HovvtA=(*koel)dLKvLq!zBsP(i87zx= z>=&sLp$vOA5j2qzrV>-@kqPNYf2?_B0j$QXm^tJp4tl4wl4rqWm;T5bu`R15zpX40y*6r%8mHBnMi%2=|UWU!=~6v>FUh)J+yiPpDY5$3zZM zBY+3i+cUa0zMiE@;EG~mioC0qJW_;ut+FHxR|LDz%g~cn8O==1cxJ=$u4#9iVEtz5 zG}aX(2RV!6BrAEzOxA3YbORbFr-^l#W1RBzLpcP7s)^_k-uL{L&)Ggpc|H^feuGn% z0N!?%qCALhKO?-Du(dij4omZH{6BRe^vHaD)|`r@+02$9m*3JW1ov?*vjrSoXnQQa z7|txsgUhzrDwmACawfZm;kVm@Q@5O(Plj9fx@}nQX3Klt^scwPIeToeFecw=A)Ycg zcWSd(nQ{DPil2 z+c@I_s?S`zWied5VUF{h>wM=t?|HKe?sL8jgyumny3vo0^rS1D z$v|IvUJCzB?~FTr>Qt|~)eYY3un;|M$8I`XBy{z#3kc)eoH?U`zHYDA3G8F(I-`qS zaj{7q?wOstpU{pMyN7-6bV@=iNYRQd2wdfV+Qi?#JlBCOmM59<=5(R_ zSS-JF-AKS5WB`kt&b{%iAK9gu4qUknl>mx!O9D!eGTOG@Zm`7uD|#RNSYS{1vCKZ( zC%*lwEw64(&3g-^$bIeYLWc8vWDEZgd{`m?`L`rN0!dIi->;7s=KtOKBbCAytSE)> zD`5)IGt?9&BmwVBK>~Oo1K|I`{?ItS0D!jzDb52O07zi|YcV73-zjwfum!C^fTX~E zWx@YxUuQV&&IF&qa*xBaKS-25U6`n@DHT0Z5nti zA(($ENPAhfWwe4oRW>0XxPoG_1@`a{|ImQK!#IJH1iyfTtuTW?7f~&UW*Dd&?-Wt| zmnOjh08(HJ_FxNJpc_&^fThq1Sl9~Zk%fQ91)?;7w$Ok=WQ9T$7*<#S1Ne6YXnzUV zfhZ`0NY#S@LJCpX3V=}n1h|H+U<;cdfO@zIB$W_=r-ye408`)!SZIJkl!k>U1w$Ad zlE#E#ktFF>ddH%8x|dIAVTlg}I%bh>o!E&8Xb(Ghe{?8_m54o`I2NKP9RDDQ03iQ? zTab44P<)}|ieI6M4+Mn&U=P-ZeZeRfQt%7)wFR4Sj9Wlb$%u@BI1%b+9TI?yTX2lP zm=;O!579Rfw(t+`$Bov(d~#8T8F&`0po6Tyjh)vPM2Lx@Vt)=OW(7b7_P}NB=7F?V zZTL8em?%o|D1U(CkNOrVh4X^XmK$bBM)|0Z|5%U+c~9|3MyHkl|Ih~0*B%7{e$b0RmkJUz7`S@+1F$Mq74rE}C#bJvWDmbU3iJ32-a&}I*a|6G0BxXy?ePB#-6#=O zsfW5@j%=udr?HZ)fP*H8l+RX=b|I3vmxBKg0h!nqz&9r(=pER&3BmFYdwD1AU<>sX zdGA;kRQU^bDU6BP7B?7w&q9stCjr!$5Z;#nl^GMtI3d)i8%cnf`J`LWQGEr_n92ie zVqy>MCuO(xinLf6eJK$Vn3pqRD26L-QfMdpyfnkp4 zv3ap*8^I}$u$YIf5Gt@qE1<%GA-am0R)uLIh$DrERrV?(+8)SBD-gO&I^sYlHYU2I zSSn{7_aZ#gw=Ul&r%_OBhEk@+cQ|6GJk1v%_P~7!fSaI$oOz0x;rAI^ai%JPrTS5y zxwkQ#rxNE8dt-tsoVFEUF^|?L5lEnzr%D!6FqMU}sA;$fx^e%EFzADi$uPE=Ce#Qt z^XGk%po~(0j9tTw6v`OH_@ZmsIWanrIU0pPSd+G~c{$juX_%HbiIVi^i$Dm3NpzE| zx|Xwbm8XJ@T&SgiF^{%!mFDP+6Jn0-(2))qI8gWxzrcsZmnK~44<$Ge=-Q2-GOB6V zd_=~LKN6au?Z1{eOR%0XtMjN5MuaF67a7&yMHiSeABmn7FmTa z`IJv-g8GMpFS$6MF^-?H1^3XEwm?!(XtMU80E{S-`ewtDmVC(7WxmTrjU#$BJk>qJzI~A!+aEKtM5dpAAy!i^n)z< z3sTTT12L+Up_h3Wn7L7@_IMhOGAWgtPn+_v+(>}F_+(s}gY?R>v}msMYJVmxgre!P zQCO)z6dA!{3-{^|&WE%)=nEvJv(yrka2 zL!^qTN(QUH*p8nPnY5^=%E-R~Fc8$pzXdv5>ev5}649&br0E8MCqhJpSv66~ff`-Gn z{K>CsDaNp!Qpp^|DYNA zhowDPlM>LrqEvz1x@HEcv$Uwe+(&(V*`-nVeWg&AS$i7kD3sCruq7CNx`D$7s$*zdFen*r@*ma?3a*n0|E&W#Pye63BRO`Iayn!ci!Z zRyL8G7n(1KvQWm6g~NxdDXBgCq&dok>>7dDc!IK;L}8S*5XyYX_YZ!$qK`O>w&9vk zx`PuO$DBILj~JS!QEf?rmSPFXi<|)F=pA@jn^<}g;H!*&3IsYxeczZSr3eI@7ntT- z$T?V}H$w`=m>Y2z_{fe(jf_`bqr5FWTFtm?I&xd-8MIyt{1B7E@j_SCg z)n|_V!p|jZsChV*32@Ru(y#MN({ix|+$w)P+?$+Yv4a@7U$K4>{E%qrekFYx3>Yfq zD#g#jhg(LTl)G&cNxB69mCJk88;k&&8lWUKkIXj)`}VJb@e5ZifqQvwecR1V1h>MG zxCOwaIa-`w-NWu@*`z>ymu=bS0nveT#i7D^Ub?S=VGHak1(wYTmhBxI45cq@8=o9z zbj=tkTBY*Jt-y)GxJ?;CO`Sno&lHNL7W%>n+00M@l~7iFk}W1u4Uj~p*-?2O0X5t7 zn#;E}k2!dUNo2N^^RJS7j75B`oavLG0=MLP4^0_n)w~5{unDNGjxS2YiHA>mE77w( zu7S}8^vD=!nGjvsi|k6bXI=l6^aqvhhp+#LIZ+vv?Ty(wWf{ zk??ntO~j+OtfK?hlmmg5`TmrtD*<(ggRfp?x$~ghNV^H3)`i27`IO8OfVT9R+`y@W zG#MP`D24+*q_qAE_`dBL?Cdzqwwq`0k2t#s#0u>I&VCpeP3q7H^o~*eqBk>ep`!&j zSP!JIe6MZ~dzt_1I(r`MEc7wxqZARcfLRaHEPDnF$z3jZPsY&1E`@@)uBA=F2v1iC zz>T&jh`Lb=Oiroo(d}odso!yxtm_@uxzG`v@9pb{5;48gyyJ-fmU7_N*l^8dOaBP{TOoqWnzq`2);21yyo?EAL-is#|B?Lqyd z50YhC72lz9cU=|`h)}Cgf>S*TzF9zR z;h9PcB>C0Sp3HxnW(quLZ_7@T8h=SPXpc6o$5t6d-D_GZ_FinJ)fE zS7WPIQ+fK-&3djDNfLx6v1PA#agj6aqsj3 z@XF|{#QwoCKE7=E2)CzZVhg~MNMXvQsD>Pfw#%+-OQUw4Y$rFSa69iVE&xOkr^qf! zU^$KKX%7IAE=m&s1X=+RfRG9R3O0noJP50%ggmdKB~>bm$d7P7%aac3|&nS#?N0D#)-Cnf<1preQOJ7_<##56O*XS;K@0B1m$ zzkoH9)%BnxzSXEUYw@b-Gf3X-0x)qFK&Xc>NB<1Zp+fRuE~Mu>b^&dvCt`9VmU#Spm2qR+K{9V0rMzaxtqM%GSuLX&EyRY z0;&}$NcpENoJu17N0BC?%JpwW_b6h7+W9&pQnqO4bx_grOGxF2zf^RFg109*i2fm? zB%4^PeR$jMI+$F(YG>&2DO&lZb6}%dOsT832x8ZNY}q0rkBJ%-0GKSgSH(t&Enmge zWwq||p13J#u5+Hr2t%5WnQS5dbKQpK*S+8k4=@q2NO77qrc*VmNfNV3M#AML*X>Ji zzH^{vEVG4Mj0IJjQOZ_IGZ>iRh=9UNPX0tkz$t`eUuCOa$y%`qhIs5c(gULZP6p<^ z=U^lv&3a*qHkgyEM5HnM%ScV!M?*?sL}VFigY*RQk2XxlWMm)(8C}Ab-C?a2dK#j! zHrPZbMx`gT5sGExBfZkuW`@s$OV}QU5YO<*I3+xciY_v|O-R9afDwMpK&8gl133V7rUJhawc=3g_?y z9r(0FBiq!bu^Oct{V0ScEE;Dxp)wH)+E8?ILXKr_k`(c^!&tKWq47TdcpMxR?Kn3g zj*?b#P>+z}WXZB)0zybD=8)nf2P4_sk_Id$oztPOBO|&X@;o=)a})M3P8I>M1z25& zIo&JiPK;9}do1jNkCK3K#P^s-_0mnPkjX+^5`dD-4@DW(mc@3pl5rwON&ISJ1R>5# z-vch>@Kikv0c%&Hh19i9Wuu-cg-3tNR@U5tkAfl2paSF6c96oc2Pwt#>^Ykd{$dIm zkrzrY)+)7Pt6w}BUMr?Ln}hy!fhAoMP9*v$I4SllQKAVys3o zM_tx&Oe`e*&R|>dpCpVoXiOtdeRF~?-8grp$#SYz4aZlwT!a)a-Bfcei(ep3<-5ac zPXhS55Omemec;`wo1V*;^GXK^$AKw+srg|LhgifTc4kScq{;$4%c`86ra-PFw*vi# zK{(Q%-S)JR8zHbGJLWN@z=oidtXMZU-iwT9Jd^(znIjhyvNJa!8ng6KK%PMifxZHu z(dcGOD+O|IgiJXBW$T>1d5D5;OrQh=*~$Zgv6!2D<~3vg8O{L`=TzK`}gz7QRM9hJ!?^GB?WCDp9);&%!H64v+17!(y;;|8cYM7v1 zdx>_krN8?rKA*-n|K%XIwX5e5YFA11EUF4SsMN8}ga+M7T7;J!0Xtf)vFD z(3APLi8f@h;Tz|8$EA5_kB7WLNg%_Ov?_9xr(EU#2Iuz58_sH%#~gt$m-(w}esi4X zT;~!3_0E0%bGx-1=tC!Z(H{hIz6D{@MrXRwk=}Hu2k7Zh_xQsV9he1yo8}E-3aqzI zb+AY1>kpc>eZw9gq2t`@s{XmX%q-$h>1N((NBO>&E+D%@bKiMC`@z4dH+Bl9Z(Y|i z)?>|U3C%hQ#U^}$z8s^zM_zAqU(k)KEb@Xx^Cuy;syRozb_0Rl%bwQT)ITix51U@{ zt7pA#!bP_PwW1WXhSch&V!LYZ1wlitYDVTVb~GCeM6mwFc#5i407WY>bACPL5p)p= z=w9H4dkkS90^?Lm{6WC4d~9OcHd}dk$gs`-ad-H&9|hFvLm*Z@giH&~VEtnXbKU~Q zlmGmkRLCmgDaVop$BQl}L zi0+aAwJ1EgyRq&{i>o*fzH^YROM)?YK9Z{y+hCN#(Ipa-6u$dCfT9|OUO!$7UWTB4~ag(;FXjR=C4BM#pw72QxMz_^zL z2m%7k79hA6pSdW(8mk*bvtVk7v{O9>Avx@u3aTOu@8H2lL$L#zkes-TYqP#ji!(wC z#2e8H*T4?(Sh2}T2_@`3788rtS+P0)>%3h1v>Lm+0Pz;vP_eyXin~xI-3S1OA+zPV zh^dQ;fDx^pP=La-#F7!e8Cygo!XLeihz84Ew$6a0}P zdw8TwIjQF{nGBp8F1w@RYlW~{LoS0K>5+<%_=ij}2pxK)BnreNLy3&|kLc08w5Y_Z zqX|45kOccN&@c{DN-7518#i<@j|q@eArKUdLkMw099%$LyF99hlkTt?s}jg95)-P> zF(tG?w(1I`FcVozfZ{X5g%rFUla?*mn6jfi&^kzrFefdkH6?r&Y(qQ(ah>|Jy(60t z*$|L>biJ5d5Z8eebZii<7_=n+)X9rHJO#0nnNR|8u|?}slqDmKxk|#B1H>Dn7r;8o zvfGav8%Y+cGPlz-O_R!n6f}UjsLQLdo*O?w5zCOqmem+cA3~zrqj`XNec% zI;^(*h>Y^WKx!g+GM|Td2%xC0@) z9+H!uaT1BF;GVnCrth%4CNjz~fs0#XxVixf9SacDw6<@-gr;W!piP(nS;H4H(#1##0FyY!a4C(l*^npeiWeKs3>h3G$O@ex{g?t4DI)~bjV)pg|B#dKAc?r4PPr)@>Nq+2K+lU397?Ir^U(_CbfbfT z9U7UzdyI`{s+_^FxXWRS!MTwMC5=g8jp;$B863Y~n5gbB8mqEUx%m*xF(aOspJe$? z82zKR*$_D?qYT7F-k6HjL=P53Ad(B7`!rC9{HU2Lv$&KKTagJevK-p_(PWu|DCNU- za;O-EiU~ce6;%LID1$BplZ&bdBpnJ{(b51j5h=aVjJYntA&rN~3YobD6pPaK+8ows z0~D*z{}c>S>W=sS!HOk4((07aiQBPzh?30lnHe1?2Qt&p!P2&&i%ZLh4y{jP8Pk<0 zoSnFwgCHCxqKWjh1<6<$GNP1SF;tA3)r>HhRpo>jWzyjkOo1?nHQI?9DS%|^3nO8p zySR-2LssOulHH*jG`fg@=^5QH&)^})qM07A@ENheP%YhrL_@)m*pmo&(y55jT2e<9 zO&xYz3U$@gO4W@k0g&6gz4UxEy5P=ry3tMLiPV8m=$OfI9TQhvSM;nM3hmYzfgHN9 zP>s;m^W?|f9FUS=h)xk0*QpYnKoO`>tIK+n06-~bIx4n!s(&y@fmn`}jVbRl8S?V3 z;s~PZi;QUhaT=-+nYO|WpjaQ8unKr|mk;`ddLS>TfS1`I4!%09qG>A3Jfrq`o-7)$ zrV5yhEwE$aE9u}XIs#tD4>8x=7=8TAXC5ih0q$RoYL6EJPFrmbj5>5#P;h+0HTlHov)kk-+}7v(Vt37CS-x(UX3TaExJ3yw7&!HASCVAX-z zm4Y8kq7ft}mGcq{ZR-iPt)XLS1z#}8nHXYw#gZ(ZTCpiN?C3OTEr19B;5(*#s8O%@o<`BxRT`hgUI?jN#7`dF~Ce&Mb;?_7h$xI zhC=6@fsS9u4OdQBbecj@Ic*pEs@8IwWBTKZ4W(8PGx&TKnaY`d_QAOSM3INs;A&A) z7OsgfY7!5zr?P14jM^ChXoDTvY}(ZprLbw^0q@Q|3Ga3m&c#LA?dQCh5~10x(vSkC zJrAl3&JrGKW7QR^(w72ho#Nx31~*$S7A3Ov3%tk)HRcf;mX7mSO(z0zSY8<+l9>1^ z6^X844~D(lfSp{?oL-q5MM(nldfmYNZf0bnHA(>C$ZRlqW2JHB9Z{0SyH~@38;;15 zDXAA_@rZ05%~hflmk2!QTk%UFg3{2Iwm|UBlnRhRt}j1}5j0&+-}7zxnCeogyH0be0G$U{ z&p_&PMHh~5>5A4L-7Xlx7vu0 z;-CwbyplyX@z{7J1R_WlC1q>L^-xrgB#`x=p$SEtBRK?fvB(V6%*>vujh5hbb*lwk zc1>UB;-g4{<%oCjVG)0DU?us!wCo;mO<0sUr*)U-0CBSg1}5crgnkM@tG$ZBMj z@lCh|V!c`mnhD7cG|vx=hd9p1Zj9dSp@jIo^-)%|iux&drBTt>?FrCDU?7pkl}Cy*N>T_-D`7KzkAj07%%*Rzd&;3P@DNObC<~CW_mCh@d#xTy>G@9z z!U8~kk-C|1%fFBpll&@3kc`8bQcp@TdGqELkT*AxAr&_4mI7P+B><{*lfa$_QMUWJ zwSXhCT~8WovwQ z`2qpV>J;30SxJ$WM9mc-(Oe5|z6D2$ zR~0ox3QZC)CSOtsWrb050Cd+7Mx^|MApjQwfLZ}rZIV__BEd(7J2nDNC1?wNTlH8UZ~Pf_*q9Bb^r8&hEg$xO4S}XOKcP2{PIfWl;bH-(% zX#r%V#DfaJ7hG*A5@ynjG`iYn0#{nbVtgoRspLf%C9wrXMTNO*g09$kQiW-;NK}7I z?)DEUEIt=fD_&)~DPn=j2&{-ZdPU!654rcyfe3{c>td6^n#7h^762c9`^iMw>TyOiDAs_ZrGX?^N%0*m)6Swm3jqZp00#5+_=vUu z;gCuXIsA~Vp_|50nK9Xolt_9q=jB0?I^$Xjri0K%J#YdN| z6s_1q*GfA!RTWhT1n=FhcWZwU`n8i`6ZZNAl6LYO1T}<38JZeZsArVQ!RmVd*cb0I zG$bS?00_wmRM0HL5qE59 zY&%SufxhTzZz& z3hy99F>{()ac&~WbXC!a9h=zn_?DsEZ3H;eIuCG;mpafm26%zG(A1*!C6wF|cHoIm z9tjtykwbZrcZwVECD3~jY1{$y(lXUj94}oqsI5V#fuO590HlrNF0?-ZStHaJ<}GH zQV2vMF(Jv9ToOZo5sF1BsS7B#P?vm`LO%BR(l6YVfY1G-E^~DVh@#+$QlUZ47b6CnI{IoTXsmoEm09jRw%H?;znI4Oh>MrC-^`c~OX)79u zk&+D7atqb}h(jT&(J{qnr1)V^Tb1aggLZ6DUn+^1%9L2sL}Xh1ENiA76p?&-ji;)G zqbis3kK~ksfR%!aVP9m>ih6WJdel@&vRYO$w6&42%4!0V!yuDw7CZg4NP;TbP!Cd5 zwINA@YS|Mweo7>Bm1-?g(YMgFx@003t*%Zz2mloQ4v^9OM=4xV3JGP@nQR1rmd?bw zd@l63$$cAhXVg(#X{58_s^~5B3M;VI4|en&Y9e!#kmUU5vyg30PDu+)lR3{z8(rr? zBN{5eV#gLC$x33Wo6?1#4_YT&A>qL0ZozzZ%hVm>7-R>YJrZ;Q)$9g^O-!YnQk zy@_4_L#rCL*lU7&4R88_Qe1tSg~;{x|V8&9hb5JyH`qVP(;WOwaR2V z0ylXdsNINYM3M|FUIW16D#>UE39vcD9yS6Yc(h!9<=McI0CReD%^$Hx3Yb=l{xHb@ z9!;}kv7Ihs8~CDJgdEypGCnxEb=_%kW%7H7M$8M@BW(%Yw0IYpHyPNLYrY($ztdAf z!^ct-8WFooSfR?RRmPkj{rlZfgJD?O5O0}a?843Ab}OU^oK2L$;rsyvJd^zLpJj|+?3#-748kpuuvxO(n`7ofVg ze)Ve?rSp8TPM4V3oI|U}ObpCNk>+AOX2s=#m>H@5a;rjOAN~ z9>vaNjuNk5OWA$F3L7R3eAct3?3;a%vt#@Co=2_LeUY~I`K<+%EN?;T7PnDiP6nF* z!Qz_%0t_+z%|gRJ{`8DJ){YjsoRi7^G~552UVgN!t&aW$z+>E3AZ@{|JP1(L(Jvv8 zc+?-zKul}&pD?Kg0!p^a^29&9Aw{srJ}C;(+;B66X1w9i%)A|$e5 z6xc%G;7B0KUnhEEYt%~sh~Z_hO%&n^9L_}@x)FkC5Guw7+eFnE9%2n{1ym5l@8wb( zb|F2*&-Q%bR{WmX1S4xSNMo?eYz*Trx<(JynW5mIYqXIc%0{3$Qfz3U1j0r#szxYg zO`Es|C%WQ(NgOSPBOH$69==PW1i>$&Vj?<{3uC} zDZXGBV&hySqdVTj9Gwk4&f?j`<1mpUYc%91UPdxTWNTEUFgC{jMXm-#X5?%j7evbA zZXf_wDV0J>)ieBBb>pBM#cEGzPS>q--QX!Lg)C zss=R{8aV!BJz67D!e0XTWKtd_RL)ZZ=!QJyBo_+WO2&p(b|O(WXUOwYq-eq6LpI7>2U<&475@ul<=3&ZT zURvXz0p@}rX4)`iQa0vef+b~I=37SQS}NvUX69vjW=eJ@Wtyd1j^<~Y=4sATD<?S{+;%a=MLLN&0V9tm!(8 zNj~U$O67gN#(a3EeZJ33@}Q24p^o4q{6W))ey7OLqtNMMSe$490SI=qU6No2SXP{AV3x$k&CB=I6P?1Tm%7%O8rqlf+ntWv z7~GnSNI`ibLFBn`XWHM!MD4}Y!R&mw~hEQjqY{GBU(MmE^aTbc$SqPNv$`*iy%_QoC>ZBmX zpfeueCUK2%_y~hm~P} zg1YN!2r4MP=VfdlSZ2y($i+S!(3RD0u+(~_Msb}fX{^5fq0Q(Oau~;%I2WXmhX6s3a|P1UT~ZejWdZ{1YXr>x#O%QgZ9nQr&~=(%cN9*9f!$&Ou^~+FHQiG#F?9zw23Gd>iaV2KadfizFZ|G z#4#?W0xhG^8mj#wYN490^B^iC5t>H!;4rc(f*h7S&5>Tz%=ftyUTFp676ezAOjyB_ z`UHse;KxoSkukkUdFX`$rwuJlU_%PaFzO4PQUv04RaxMVt!U1?2Cn>R1gK%eV%>vL z9T1-8Y?(9?i*lE`L@SI;i;$&GUGSTksnx!)2QamRPe2=4nFwKg;iugd8yVDnd?9je zpm}_bJ+uK%LRwucu0*xO<7C+XLQHLRwE`D#1P~nY8^+5?m4Yka1rO@eR0Ill<4=2U}@kXh^(EHp~ znz|TWWfn0d5MG$k+K-(_I)(~HE z;G_;+Os%kVNVF_6zy*TZ-&M%abMz#i+2 z1_>$ZNel$^0LAhGjZA+hjf{v=TcDvtPH$w>PqYr~gv6ZHutfI8a!{#E;Am zJ5=^WK(dTnNRr$FtWX8xWJNn5SE_VeR0vf})JY3JgcjrxL|utWqpzV@H(#-7wO=g)u>>2UzD3j^IUOv&VXMR8Gy^RMa$AlGbux6I2|AYTL+q z@d`~C;g>+vk8TQ8XwiEK5OU|lX!Oc1wUlkl1a3BWL(Nd=S{qHMAoc*=WME8EBoAfy zHW2A(QmaY3G)PH|G0w5YV8ta{h<3a9Pz5fk5pfYNUtn`9)k`CfTo4F^7YFJc_un-) z?x2!b{I*ea)K5U_T!6(uh=meO4J4PuTMXOT2J~!GR{GeruQ2u5sfcKkLUsmlQE-Cw z*vL=dg|lE(T>Q5SH3v};MSI&vq6W7yZ9>y+LHtY$MjQooQEA9>c#<$RlWAyUPx(I_ zv`DB(DJH=G;?$a6iA$}O0<`(*5;|kvObzr9s{b7KfhCEveAa1HEdg_Q(!Jhs3q)dk zh=^y?hsV&LPRL^rIZY&hKe%`+;oLxs7AwK?VL^pDmqco06m|E>ZN$o7B*>SCc2{Tx z07Ev8L>+~v$}S^$GzrN%MF~ZTIGBh;hL^et|Fi(1TIblV|NYJS2#fHDv7n5Ifi%`n zge*(>O5v1+nAn0p>^0)fi2$Wp<1T9CaLdcE8&hw_W7JHlF7|AYN~~}J>9ma}^Txrc zhkC?E@I;H095}mK26lv0`T&3e*uyj*A&3MmD)MM?gdn%!&j!@Tob(l_yE_#2AqXAw&nr zaok5j7&(5-iupP)d;Hg!nnu53$rkmn5mJko*;dpXD!0UZyD*1_x>FfVu!Si-Nw_9Q%0=3m*dOK3YXx=LG(-1@%4Ln&s8VJ6mgC5W_{=c-G@Ps)qHtbD9qH( zvV(u_aMGM$ZBJC-^ghiKpATM7Q2hN)BH?=(2IWpG0nznbNG;Q$1J0%Yv{ zvsa)10006DZ2Ff3K!Jao0JQo?>S2La1?;sdCC#JKoIBAi2#6%l=7?HKfO)=0Z90# zQ^H84d~tf@nS`uG2?Z4VV;VRjT~cJl@&$mg-4?kC3Ev_`SRu|f_Hd?jIC>Kq#Ur4N zXWB|)s}&h3wi^Eft+T*zhpedvAFf}x*r*DMxP}5m&b+2PL&%}RU|LW&GIFzMsI2UP zttgP10^&O9uu5RTnV`#x42jfBFEWK3OYu9nQaVhop0;3ZGmYv(NGzQ2gQm=0w4zyn=>MJ7e z(tOJ=5F;~*$B6J-Q%#--BQqu4nq-eHE?+!vO2tAlNFw(N;AFSI{@DyCA3@8nfF()s zWv9OeB4vw>D)fsZoPr#2KvLRJh(p@g@(#!J)=Lge5Ep9;F2m~b&Yltxl3>D&!h$I$ zwbsfpsNklmH97m{64WFneL~evj<(nYy2&(BtFWSyR7x!^5mL&QvEDk0Bl+4ouCN*9 zN+36kD9TQ%{2~%Dw@q%@s4(P6CF(|#GJ5bxw_e=$$~@C;h%LwT+BUH;A48~Kjz%gj z(u*L?6QfF{E9y)HIx3(p$7UicFni7`Ak28RyR0{ijY3%Q0QoO%-tdyTCrSIB5ZiuimobEN%L z^sH3?iqeiq#xiBjmIQ(f?=(O$V%n&@iZsk0TUcRwF?6-N=-s3v3oM}ogG{xRrSWR& zmX1jIMXiBMb*g|ME21w*fuu-6f+RNI{PMR5LP$HNNof}$vfWbZv!=R}&8N>f_dGd! z#@MK7wUCPOt~_aDb|y!CFK{LPrcwwnW{XOoDBo)XLQsd8Zh9tC;6KkZ< z8>raJBb1Yp{}Ljp-Do5_jPYNfU`3S-o#rB@yPIPuQ@Jlq<#2JDk=uCXy={F?37;V!403bY+0BCA;ejKXF>vbox{!*uRKRoye@=Lx>2>h=_$L1-M5BMZ%@A4bEFS8;bY_B$ohS zBuM~(X61rXk#@K!Vlfh(u|oHh;v`@SQ-MzVt}@bykWVA@iCR!p2dnWs>=*nAQ&u?C z4l<~dFDqirjvAuUsP$-@DG4h6h(bBm45^gaf!0MCWRwSi#76{z$vV+SEROJG3c8Y$ zE|XXl5Sb*X#{=& zh0lus+blGJl5j);m~&N2K+hInC}`P)QCaq{5W*ClBN^SA)(b04dB;`9vX~)bDnG&& z&p&V_>5l$MT(DR+f-NFYP(oN!+eo1Qg?J4~0ms>57r!_w0YHjWNZ}K|ctkHwVT||M z63hJN5&#YvMK{T2Odj#Ec#Hhl4b1})qy*F;OcBdYI-?c^SOkUkh>UKI)DBZAS0^~p z&1UR}HNV6Sd{b2my5Q&#DKL*_5pm2$5`bl%K(vqn3>Aw3le#N?32Um`mg@pmk)&V@ zIh1S3Squ$Y#E4nN@2h3-(g;90Z=`rbc})N#LN=pfB!a<oXN7PIROdSiMa;zo;aa#Fl;Hxk!Io;xL{-^ASq-B z1=YxJIYi6*3&}l-2gIS=W=#+O#O9kNQZp`d#@2DDX1LfyF-iOfQ#bNk#smx@ z5o%1(3g^_p{&XNPfhbS1Q`>SnC8GM{ltz#RQNc*XG6^wgt}zDSIIGemzhR3Lw`WD* z_HToX3EW#m7Ho9^APB|Q&Srw-qXx3($@!%jLIy5vIRg-&W)qp69HPY}(nl;cTeeN? zv0bo%&s7mSl8;uhF@_U+BfY8&*|b+Yh;zGk8!w111+vH_FHG3TB3yp6Gm{g-CF(vR zxLkGoM>0WJCU}0!%4>2HhD+NbTOt`kA^-%2d{Sb2U+6zrk#A4;E{;vv$x8lM%K`my zTN=r>6t=r2$T!oCAW5G8LgtJ1$h`!{p%=Y4d%hfLzK1zXRY;qH;GM|6re0&qsp?R_ z977rU7hBhFlHSh8Y_`IC?0ig;bd&pTMJ7nya?VTx zdd`%9#5_i18(j}trplajS7oHbd7PIXqn?8mKRwimO75G}j^O{Eq{q|E)N3=J^w80b^|{{4b6! z3Sz24O5VaEmZRKkhFQeI{HzKiI3_V73iT8qYDi5zl4M4fL$8u1FfvW~)(JTpiQfQB z`Iw3T!LMfaBljZzr~C>oa)4kXRFL1q!a3|DF?4AvRB+}D1R*AH!V;ifnoU)hqg^U4 z1aF8fY=t@21$kIS47U)D@`s}&PWja1>^ji&c!JLEjpni`jrh$_QsT@KVhl%O;ZhJP zy6^;31u8tkRxm<6W{^0JZ?Y@`Dk{VU@$gnSilKt=WLRSdK?}ej=i$->)N=1lN-zBG z>PQC8F52(*2#7hdjeDRXG1g`8RL$6^&|MhtoxYGcj3ZUr4XVhg4~+5)JBKr2mv;2>G#dz{EGq(BK2 z(nT~MPG@vQ|ne*&>|)%qDcKCoqQ)cZ=NoLIGN+HuzGiL=hy8a&x*0E+~?dA_W>N z#C*{IC-Q9KoYurMNs4(?W6%)uD$wU}oWdqDaw;aXb8ND6C}%7W2qCFrGepu}b}edJ zs45_mq^4jKd^0Y0GXZWgO^oU-^YXA7Ge{_h$Eczxqv(8wa*Fn+*`y$(I!7o}BQe?H zh>iy$Lnt+kDk;Y^t=Ug=wS6T(^+S~3ZmdCmx;cb$*3w*z0B!;)Fh(jh;x94BENE>WG5;WLJPKF3yR|?K-BJV zi=DtU!WA3hXW3GiZ|QFB2dN?gmE*Qb>oi#Zv8XIEP3vYB

      L`F|R^1xdI6KGD&+#EBqx%!^ujEroFnNYhcU0vQ$i8EbO4OD`wPyA`fXWN`|O~)zhR#Z>*v`YuoP+P1{^)yknbWWx8P#<;l z=8`M^bSwB2oNNIDhsIJL6$H;L*R*0fiH170LQ=g-RIQ>^ofKV~ax1iBWr7Fz4AWG> zDOINe^o(XyP4H;crF@M0`yJ?D{d81wRKj_X)97STE{i?&UI2{l_faMB~lAmvjSWpm0s)rb*v1v z1plX5pEdNh)L#D;U;{Q?^HpGnW;|O|Tt^SNxMEWa)?r1JU>{auCzfI*c2O%9V-K}q zGnODXb~rf}WCzt_C01QSR@=DqWCu0ROqOL^)@Vl7Wn)%mk7izH)?xV+W^Gnyca~>+ z)@OefXoFU0hn8rIwr5LL)rK@@iBvOFtt*grHeoDRMQ>`OwpX(>VZmu>?G*&G_Cu1E zOua%lZDzs!_D^+iaYeotGWZ}d~s=A7A z#|bmUQAnSqv}ThOO77k`$We zbeg8Ok|2G##x`u_$ad|oG8c3y3Y17G+RURBcq@JXHxfxn3Mis${x^4+$kpEBS;!6{ zxWGD4rvRpaX+X;_+Qcw3<9}D;e@{n##icQYEqBs4CkqirHuxkZj%(h+E(|z*HEnzF ziz_-WB!Xs1+~v6WYPS69RTwxU)iCH|(;h6ZaM z@@1`}H`sSF4Kamls1<(luOt9~GuR|1_$_4XRyZL9orZgr4LZ2Sa+ai3+~;)u*D0W- zhs`GHbY?~{czp%6lsF-T1FC@k%5uFbgj*q`t~3GKU<&M|YoO_12n_K))+v;r6_g-q zCBPzfj<}*UH`IiVb7w1fxZZ?#iv!1R`uB=ZIBL8YKDZz!{k3h6LvmpmE2{#OR&qeD zHZgbhAcrbGnf#pV@VENC~Cq;&;m zDk4BC)z^S+*cL_s;cQJfd7^}x)O^pEE9^o85kn`AqTROtPEHm@;snJz=Iz5?xnlTJ zJ*Yg)&Lqf6EtJ8uSV$@2^rRJXZ^@1%vS6!Qpu<%~ zN~NkIvUHIvbSjy;0#v@Dq5#&o>}5-DA~;@mca4{55=Qw#sF7xi&a!B8nuM2}Ibu4Z zASA)!(x^dDkcPBEEXb{Tc3FD(hX4B@UAXMxs zKtimoDl2;KtIL`okfp08s(d6-epAAkQH)&sBaoo~@T6&~3B%<4N~*R5Xea(*RK7zy zP(>-C!Xhqcnz8~Qd#F)`1_-i|k9oqXViB3fUR3RMB zA}R&Rc;#>SZASe9ZM0338E!L7ia!ft3xWin+EQ_wC?(3E`Y5NoPqC!Wq{_H+K1qiy z2c&m?P771QVCINjKPJHk4x661SdxsfSLUa9GNq7Xect;#=Iov~qGIq7P@qY}^(DuS z2UsS{fJk$Qcdbu@;?r2HT$5vZ{Sq!Vw~%iCuubU{Ch`m3dTl_i*nMitD?v~uk0)9c zi-E0Tz9J$q4#&{4&G7c|vGO7)o)0Fl%=dg#?cl=rQaR7^tP2@VNd5s$3F4vo@wBWl zEwrsXThvJ%%lgQtFD!AmnDIALHnt`LK2W7eNba!;Nsq96EeOydGF2i@=r^Nu#_%nI zN_@~DtdB&@!~A)P<~(S+Cuv?qDBjy2mO9NUO!AyUQ&^<&8eNa3B4gtJwO!TQPZfe#rqiCSdu99F!1 z*&-!0;ATE(&Zp7@BrXafhNQ>pLR&@{L8_bPSfen$gbe6P!D=SBelvq6YtfOzp61cu zVWlmQ%W&38FoJ_AAVz%tqpgJnG3$;r4H0f0Bq>KHyC51p0IVW%FCpT2OJ8p=W&B&P zG?)ycM93`RpYNo4$*dU8_%y;QTH%+awR!z5y}263tBbTe$vCBc60Bx6BZzC-RhI;Opeepsh)VnyC#0wH1x zW@T3-;;ax+KRJo=#0+w6%i@Xu9#!O5A)3ZrEQ+LNIi4LvB*bGUZXyU0vnFsxIwm&+ zNsGktY|+pB5h+_ymSa?oqLl3^CD_UNE-JPOuKG~rrAEx15h*lo#6eCa_Sj;!QBd{h zqDu;+u~3DhZVBUgqBtZgqey1FGtpg2j}#z}rXFTnfDbsn#rMX7SiIOKUdlmWBex6> zYv$`P4#EScx!eO1AQJo|Q=kBVf&dZ%5J<29sb31o{F4A+%ccTA0BrgP#G$Q+|7=Mq zh*4oik|;@L-1Mu!FH#8+W{g@sRjZO$q0&q^6F}1clwiY(9ZR;X*|TWVo=x}4KyTDhz6M zu4m9%A0G@IxnSgvG!Z6jM>S}{m#%#iU6{nT>HvjN+d~cjZr{%dS_>{9B`(PX_Bt1Y zUfte5@80_kRejJo<^+g2+avrFz17ZbZDnkI+OSo_G5;mmDjQ|1Bs~?dQ(f(hWLE)O zP?r!Xe+f8}ElEgGTv%5f_D?HPR7Vwp1(cFRL%Q{c;6O<*C|6K%Ns(1q-fbemMg~#$ z(iBlXa!vr6kM%HVBko;<;J3bd)abOZZ}T#*h@UE*NTz|Rrixys_o<$ z0M!lHTwK`oM3s&PO<5OC3#CaIbwJrx7yz6=lu&I2(1qBI*lk$cL7RvqAOQE#1*nq7 z(H0|J0oc>qL0T~<84%w^T0mPKF{tQlVhL&#Rml~gK#6>z#$jq#6~IMX2}snLrZ>@) zVOtqiCL5-lg=E!!o+|2HfwS4dR}z;}r>kU@h4|Q8acR`oln4!#Aea9rQNSj2)wx)P zP#Q*FL5iyOQ)R7O2q0hvRYyt!BVj4lth3FP-E7#U816-?Im_Qc!%Yj+jXnZMVuA)S zQMIiZ^^bM<{Zgt#5K3jNLI{inEwwW)IV-mTLkn;#wbTW0nb{>f z9drd`+)6tMCA@_{=<<~;DHYcBDn;b=N2^*u2QBo_M3a?Wot6z36ad}YauHEU{L)uo z8|`!*WHH8=8dMooCzljtY(mCPmi_|TMN<6YZvuVl#?pSY-bj*Gsujc=rb|tBP+nov zDYxBb08c=$zZYN+gyi8C6Vn6n-Pyua>Sg3O(C1Fd05B~xL zx*3)(#nN5YJ(S}QH%NCuU6OHCJ3VO@)aQ;nUMxZ{;|FMBTj7VA=mmXSC)^$t)KO}H zxm6Y9H$p{H|9g_%!<_U2R@=OQ7InYL7CU+Al1{A}&gNov{*L-dYlHp6~g0dHb+$2DCdQE*0m6Dt} z%1I=Fj#i@MtCk#upT?0R7sR%OpfIOf4xLobGDD(RMJ}Qei4s47`=6F+qmfV*k$a)YW{YGo9WiI`FxA_)o#ViNYH0r?cFJGD``$n_Ti7Aa$4iixvE zbVHd6s%kL{s2N$qDa)>>Isk|OQE;}@xNISbEz4!buu0@18(A&wTgX6?6H45`r4)YJ zNEWkL3X~v+PWl?0cVI$b0ZC1-{Yl$?Sb{x+umrOwsV`Nz(pf5@<|rVPF>H-=)>&=} zwsrPOFF!h4gJAg~QgG>we&Vaom1>(ig%rJhQxU*u*;jpmi**CMJCa=FD@!2*%;30} z|I#ucD|DOarui|CC}b#=8H&?j8q5I3Mm4>gNhKGBYRSN?Bb&GduG@0M|7doFCJZ8l zMRrLYsVSs@W7*|TL3CIC9m-VXqY1Z4n1!5<%o7prPtfoX4nIH>31yZ@`;OD^k-D0Jx%OloTFr(u|Vj zVW$A@DD=@xBFPSEEQnMwjnxv;o+84tM^rlNob}5jk@Jt?=8WgRQ&^|LeUEFt6C6RH zyF7>F6w-`>Pnh30;#%H2PrZ) zOt~>a9?yDgxfnjkNzml#~Dy1Jd=V- z_mec8!4_pD7C?noog;WDfgXetA^}1_$Ja{Y0Wf0SG#Ee@Fi2A^lJ*px#1bL2Ai#4F8B<3d_oY8VqAt%K1+jlR)Y}Tk|4X| zOG?m5`Gz13R43LUO)()mQ&DKIM;B8dU=A@QQ!+TIfqqH`htO3>$-)|exDm^vc$|TP zYc)%{kz!MnF9NY>N)}=w({F=uDLxfoL}FQo$Us-YGA5`R8-WDRR}jSlV=P81g9I(& zgLh(qOUw0w#<+owh9YP}P~;JKvXwEPQ4krES1@!H|9w#tLo`;)#YTpGa< zD+fitxNZ@_Bg^MiM5PebaXUUyMa8lp9%vA#b}WbYNWIh!FQPk;Wgw-J5K^W+31N>s zGZI&Uf-`g&w;(DP0Xg)-E`XCE@+KJrQ8}SB7V1MDNrp)_v~f3efv_V146;WG$s>Y; z5)D=mgJ_jrc@z)QCJ{-4Vk1OcW^{1zEDOdT|JCOk!G@NUQf_ru08trB3PC+`IhYf; z9Ympz&tgM9_dUHrl@?KtO&Dx`W^is;Sy#qCTd)PcV38GO5r>wNUPT5rbQUin6*#1o zF0v83mpKG+6{T_|gh`O2nO9?p5KHE4J|h&?=w+dD6nOL(Jah{hSr63VD@9UjCShy{ zArPsl8+24FW3v}(lad~DSe@m9O4TD^1A$~AmsE5i7I8bU^EruAMH{&^mPBeyGipik zm(TWHQ6o>#i7feNBrkFxs%AxGgL4*vbNhBIWC1R%S(G0WHLb7(P$5>|Qd=j5cwDE6 zD)BijW*t4jVH=SZakRa!wpNIP(~ugBp^;N=oL5$RtfbfSm18 z9e>d$R)btPvmrVu8KCH18^R^_uw{bT8=Uc1rGhierVv>;Vw(0WD%U3&2o?ySrcM(Y zKlU8}vk>M-6RY$v%yXwS_<&N7U7zuau91st<*GsAJICT)gA*fDP*-JgTHOUN#GxS9 zVMm`QPC<1xgi>^q#2kl%r>wd(|Mb!zr4lYJ@f~;sgp)D_8qur@a5REar+tMr2Voi` z<{cYiDM5ENwJKxZK}=(D6}|c$%!9127bCEts63%~^b#*^X{w-C6fpv=nqnFx!A-7O zf{k_|V(NmsqF`WJoo{ulw$N;Jfu?pMQ6lkmB9Z{}hbg3RuikeupSmuqQG7h|7uJDZ zH!-R=)ga!Xky~OIT!bfUxtbqd4617x`MPLeYo>aUl^f8yvQRS7Tto zf)GtB7^N~5lN1}ysv2n%LPshfzVa6YTRADq3V^YUYkDzGo1$vFwzE}`4`>?<=NoB; zDWmgJ#ZerYHyfFkJwJ00|89#B!3965M=L?FT!uR#)|axvd54R0xQ4qHNr7eFC|ie{ zJ<20obQ>0Xi?U#GkbDw?m&bM2!MJC!w?5i%EP6TovsSM)x?y1@Hlh-mE1cJX5>^uc zrVBr#({SLUuR3QIUqKU_d!AyEc`p(psk6H2V^@1CYrq>8_M;j@)^{kyxCv7?TM#baD~>?(#agGHAxgj1bjC%7VkuF^=cK@7(R)@59+MR#a6BCdtG;&3 z$NJkN8f7-usltU^7Fv8;EL?+0D#T%dzHqF?&6mT2JjEnjG>3d-ojf!Hq{Bxxz0>>2 zDS^jCGry^<7WDeZFKNoOOv@uY8v!5zO5jqw+`mObf3}JwcI#4PcyYiCKf`>(Elgy* zoXn;SzoV?f{|M-n0~gA*{AMF{&4)A@2jj)pJioTv%)PA5D4_tm?9AkRThW}(PiY|$8<(Hgzc9No_y{m~$u!@eBSBwf-btrjDF(nOZh(iKG z*HeASXWVR%0Y6%t#MTtbjO{zEt0_N|a*Lf7cO@bK{l9hc*=2|pg`zmJ@_|_M#z+m- zI6B0bah{!W)o=YX1U+qjh)qjeBp1Eer4i8JBf?`X7J;TFDZwE7MHaOoxYMoOQ*GGK zEyO!Y)kbzu!5uV#`xunH7Q=nX;e8gIZOO1jG#N75aZNN4s=!gjXF*2ME<_UH5@OYK zGNkR#XI;P~{MIL2gXy#0)7!g;a^4C&*gMra3# z|3NXMP}K^Zu>p^!D04SBIXArUvLB=wV%$79CnIHr*2XB2b0kp)W_05VxjnN%ixTKe z%@Jw}AVeYYQP?4Ipqsu?BMGW{E-k*0f4WniBj7f|JlO)WdPNGmGm`*JEi3#sbMr?d zEmH&LCv$h7-lo({-U?sgq!J@i<`m~*VPOBz22{r-xPv8k8XVu%EX=B95|f2MfUqeR z89&x($Fjx((gxsRP5=@{l7Xmyxa5xGCzkPOK&ikkW>vki1$i+*f4att_NQpV=YGy5 z)L8&Q@Dbs93y&sNLjHP8(|uaUq8(8=K(Gb(AaS-{8OFuHD`9LwrNW^-Ck2bC|HL{c zveq`0WR?N5g$FfpyYU}TE-L-xw)e3(eqvbDGEM7}w0*uLQlVwnT4=QM<}1~)P+ranmv zxyIue#emgAzA-ppGcUTh3E>hp*8F)GrdLj*^1Gy5fH z=k#@mu(KgV6E+fXubyL5f$qcF#l&lz2`MUWM*veD{fln3QdZikqTvA+*U6#&5y}Dn z6NlFIpU37S8O4Mq1q>2Ma8V%ZbPy|M9KXN`1C&>)A~yRt-$iv`8etEd!!JkSo?Lk{ zLqUf01~CdC_Cmz>|9~9kViDd!;f9fxu_vJ|K_||Ff7fv|qR&HB8?aBU8ZEKU)O? z001E6-#-Ze3KVGduK+}eQUGisv!y`0Et^D&v?b+YLjW077EoYM|D`}u3?UA@=ul_Q zf25QYV0dxUKag9qb@H7$Qc%F0(($%Ch1wS ztb~hF$duh8GVEN1O>^36I@IV;dl$(jEEu-n*a8JxwW2E!Ks&^Af7!K2SMp@aEA7s; z*SG+J$~hs1jl8k*A`7_#Ewqftu&5@)YBKPjHVWfyLn$iyOp3tB8&9)~?mNq@&!Cb(rHD>T zLISi%xoNxcfCB)C^V%AaBju!c>ZmPF;|rpvV#D$!DNciElV391@JSVWf+(SeiVSN^ z@1XK>K&PlGU?`rLl(L-yfKYM^kFxSGwmaE6NH+j4LhC!Q7Hg$N1zNHP08(xt4lD^w znnF+o3V5)mi?*;Q0DI&jWx`EZVu_K!{>Jt)q)>+qFsnmP9Qs??OB1 zmn0yv#iS}*lfqaE?`nz^TPj2k)PH~*FCpC;1<#g9|I7U6G^>Ir=~L7eD#OcPP@FTh zKV?n8q+{EPYYGE(0t>9K0Lb^Ihkh*yN4mh-_$l*95qI`dntzEfGVmfE>F z;*HxVjWMVCx=0D4qIB4`n>QpS(ttlJ(w26L^cc&K1!Yg$xvCRrE(h_9GhELK;`$;W zqyUt<+`?pA>=EZW>g%I!V~ef88eHrbi%=xhv(F%c@ZL82>a8V~BI}UEZvpW3&tMBX zOe?P+d-t-CZJrCQf^#Zp%!EEeLM5WG4)3?d|Knr5b=O~KFT-O;?1*2SES=W2YYn82YnsS`J>^a%zXkxmDWIskXutlxxJ=5hy9d zynW3gkGQ42D#aus6R`xE3PP~m3sRjRsH6oRIJ|V#o#~(iyj(%=DFsWydH%sMk&wb3 z_fcG76f!}e%%mlxAXV5@<2Tn-#c!}d%u`asD!&ZGE1z45cQ!H<0Ek3y4=f8}cK44d zq;GevaD{0+l(%c)`62v6rAxCsbO*po+C55Yn7ot#8l0cTYXyj3Pk^<7s z!MS z0iH^%78{v>Dr6qXV1Ml7m%;(XSbl^MoeDw_Kx%L~1lfp0>`@jb=}Ur`1Pma(^^m{t zFEAo`m02h$9qVN%6lrp5sD5F?H0AQb`G zifTdRU$=uC2GL`YTs0{`iu;Tm?P!_O;3ZEQArXuI0!{CP4@*-}$@$7MM2vW7fnk|a z;e1pXiiM{j*Tc@O)TkbeKrD1X0ZK5(6C0as#A*vnk2Y7Qnw(@LhGvt<+Kl8HiELpx zPHBh~bi}x!Y?N`?G8|e4xS4F)|7ePzX^cdG@<6*>$3u1rnSg?sz79EXL5v#70=E*n zO_rq{Y}!c7<_0^W7S*V%BTHK5H75+3L<$dKW|NGC8d?477b0mPLQJwMi?}0FK}Fhd zMg+M?A#Fl4EycQSVkRIY&S{}(gRMGL5~u8~P?fUCPycbIi8KT+DIpaZ{A3TJamaF8 z-2!)1avh{ul_`EEtQzv#!1@!Z8g-X(gqa z6MPE>1cAK8nZYfEL?)H2@f7JymO>2Xpp_%RLa?&`Xh&5&Q_b9bH31Q>pPxd6n1)HA z6@Hq+FY0%ZDLC;i6cLcNisz_YI+Jm4H7LYfxD$j$h7)4FR9oREk+2=tLtoX2MOY-B z9{ww2$vQ{?8g&tpq1Uh@l7vQD6B!U~l`S6f+LZ3Jk@pTWF7nEWM_h}{!R6*jvMn$~ zq=cBZ{)}&Bo-dFAKv;u>wWCp57sUi^|5vp_6eR#?0W}PQ@uBk+W>-pyDkzx zbZJ&Hk!c3Tp$nYqM$oc5$YL@ur#j|U{K}*R#teZvjo~EQNfs_h@J_gv&~f`nX&UM1 zA3$K{S6|i4-H61q0vfGE^it+X=O?(W$f95c*P`HMGI*7P*)+YW5Re>3nlNk3&<`V# zhPV zhTc;4WM@%2GK1e|?qR{eEF9a=14|o(B$1f?v@wd=#IzoAce2hoA@|`ot&=_H%SfHc zWr283hSCa$!-U~MJ-0h(__3VCL`mTaoFetMF(wJbn}8f|R45aG#K+9`h{@k+LS)aJ zyrsv!2f&OVvb3o?5ho8(uyR@KO?R+pxhi~VR@w3|!MR(3nSToAT{+($$>eW6bTUR@ zy-DRjC}t0ImuRRD{gE_gNhMi`1tZvFx7Hd)U)I!*Kl$(%%pQ4iWfh^&AHr$AegJ_ADsTfN73;^MT zgBUWy3X6hCt)CLJh0rn%8HzTunFfK7W}%p9`n3YwC)AjvDVidpyAAdltmXlUkWrHa zXswMPnJ7y?km3-}xrrrX6d*YjlDHZwF{34Wx$!`xy&?~%F~!no3do7AM*^4Gff*TL z|D#FrtlQd{=lBJRNIX$AMF~U*8WD+uV3Q^LjHax2ql2CUt5Y~GdmM}r$}PExnZmDKrd6l3&cPS>a&GXXb^`mnXzCv!f_KOF_UJg zE?ktXg~}!=FcjYt8we>F&yqp_z`|joi-x%^JAAQ0M2t45Mb|nLt9gkE@e?>R|182P zjjch5O9?Bc6f5yS!~~e4`r#k2-~yI=7SKSDg}RQk(}=$lN{b+x4Jov*kvH_C#;yFF zGP#h?*aVV{n$*H2fkQ9fpbE9zM6-w)-6$=!)D2xRnvGx!m4Lw82n=b_F(*QfsEHbk zm?*RW8fv1Gw#rN@`9L#-jTT}I(v+V9XiA{_Czt`6g{-!3)X6Ob&fs*95EQfdN{HH7 z4&1qwPgA%%2@xI>IQw&-oS?qYI1jV42fJVlKza>?0loz}9@oH}19A!$S!R z1aZAqTvFK!xjmIbi(nNANPvq%nB_3af#k5QP$#_^2=i3Wun8t$+86K1o<%(md(p0_ zX`~1Yi`^?A0`v@^_#AIpj<F9tP}A^l=SQ z@uiPsBysY>vLHB(fJx4?h%LB~jYxn$5>(<*w1F824+};Ei2#1m$7I^FPu+@&kcia- z$H)Ps4D!kjI*Yks1-t@M)KF9^QiyW9ryHz@0Fq9Rb0>wsyr$3ytJ$JNlhrbVF#Ex_ zXtKtgQY4M*vR^CKy#f%-%Np!KrU;NEo-3RMA~xZq*op-UW(o|Mn-eh$3jxfQ+ljDh z85NdO5h_8Up;D8L5H8E8zO^dMP^(Ga`iCems1)%vp<)<~DiWO~x?hl|sMSJ9{mF5$oFLNr|2)Qn%w{>3hB2-jF|i*5 z6~scykr1a#D@qCt5-3p+-!wNe!81Nd#yML?Cb1RRm_Uy!k-+Sb6)^}O#T_|pzqv3y zh#k0P3`U7ah+<(g08kp6v!)R#u@DUn=v<6zN*Hr3fHJVKz9<-xa213SKg2VO5;<50 zOh`|nDwSZD#$XG%ptFLAtGi7*S_=4|4aFDg~!2=m}*wLIY7v0iBt@a zQ;6q=d3!nTZF*^vhs0q|1U|57ZN^w-Pd0HluppqyF=THg6 ziWO3@IXz<>E!&W+Ew*zhH&VkYj5t;`3lHvim93&T{%R+xQX2u8sI$EaQfY;7tJo{P zV#$4{jiHjrIShd)g}yKhCOrt55s41mzh8J9FeD}JT%juQIdO@UXIe)Y5>*aarGV;A zvx%;lsg3y>t7c6ueWDzmNI0Zxh`o6V4pNT+G&5oJI8A!h&v^(%@su&y|n;@7h1-9_m2nJ7N5e;VT|J?2l@99#4V346MG zc#MTWrVDAQUh!gED2O|Qx?i%r(Qy%yTpts=4c<7&3=y-8aD{J6S59h$)Cij=wU%@9 z<7&++?8Q`3QHfH>9qPqij5sddK*CpTj4#3EnB7kA zZD9&r25dV5YjH(7oI0-^f}Y#3paZTW*lH5!hx4zHKD*lu2E|Vk&HR+JhU7I2Xk4}DT=)so5^1dw;LGPPDITV8JP<*Bh zId0$BzqR@>7Qv7+25rfJ|M0UbkLvIk)#%_25x`%%a6fSiB#{-t(mL@-%=SLnKBtV~ zvF@nDDF8Xy`LUX#-8G;!v&-1Ifk^L6WCeB^MCq83lI++XCzR)gZ4^qp%+PLP?+MegchoM;^%t4NpqW!ibB0j|)MajOFOUddHIRF^VuEt=9Rk z$^iKFAeQKmjE0AI;cQ@uFPq)#j1d`lq)iNZSGbf&c=zz6M+tL}ADFptU9ss!_DK1f zBzeL(z}P`rLG`47<9K-;`G{W3PhuRTEf4Ue&bi1Av7pxV(72PYz3=;auZ)W4`+)y@c{TirhkT+^Pr(Qa zcBy>Hu>8gMj=z*Qmm+$muRc*5cg{~g_pmRSC#r>DyOVdF25#WYFRIsnod(W`ddhg@ z78;@4HrR)qZltjW{`|LRebeerQ9JxCT&TuZkL-AK$>Ar$hmVwx{+{Rh^^kskBHpPN z{@Cvv&i_N_ZynyB4Br1Gh2a>hX=Ozd|H)t`&X;!O?~L^ye#C!#*a3dT2ZHNgT1mkC z-3N#Q0tXT-|7h?a!h{MJCIoO02*ZdH5kj13@gl~I8aFBo!0{tUf*uJ1a2WEWMw0^* zNRfi_CCr!!x44{GQsqDZBQqu_xKk#~pE)BY&{?1-P>e`F1^`erDb$TPql&yJlq$!c zC9z(`>a{A!1WA^DEo)XH*|TcbvTf`3E!?-R6^-^wYq!LaQ(a#Br0dGbVXE|OUGDVb+86fp*t4ff@C9~y zJ{@x@|N4&(*E8?9(R|YEF`r|lkJ_y9`R$J`bm*PAN9;|-9zr`UmETYUGFRPxz7@nE zfkg4t8ifRP_aJ{3eOFLo8>Z#ae*&R57Jo}g5K)L3>V_d&%)zJNW2b?5kWdaK7G8x` zErbAfH#LRZ7G&I19RLz+aw2^!C7Ba#L7d2?6g2(j z&{$iQ6hN3#)YeK(4+6IZDXnZm&=#mUl|(^F(3IGT3Yg^3o>VqArG10mWG9z|nki^R zhdMYA8FTvPC~`QBNob-C6{_iya3vvu5*;S7lLB}WB!yTKd@6;i5>&*}7N!;e#Fqk* z|9I1QSsFp}?!a4)kfTz9LJIs%cRgK&XwO=cucc)`mcBq^P+hro~y; zZKaq#x5+<~-b6;Z{psXTD@frfY+=R{B`>pXilynPG}%c?og%uF#B)JNaV4UeK6O;P zb|$b%8?E#^kgA44OiEGqDY2)UwK7C$rNO3UrN)lZ2XapQc5KiVWwb)ZN?|II=%3Sx z6~U(fw;XH1;etD*o6l_;6{ef8%q2;dD$29Dj80lKlW#fobV)stVo$|RRqDz=S^r|Q zZ>{{pHDqa3Tr>c-P;F8I?G#{70Tfp%h1Xj|4S*DE3q-L~{|v2SQC_#QGC_9l|6SA+ zdaJa>KlWt(aJmAu1Kyl$+v5^=R$n+b(f|lORMlh0Oy$uhAN4cYi6UiBE523z=fNEp zB|*C!w+W>t1iFa>KY0OLD6Tju0wMnJ z-|IQ_kH$mo)I9YADW0|BY9c=UKXNDW&n7C_qW1dZCw^k;Yp?ww)7FKd}RH|4KAb3Wo9k76&o=PvFwd7A~^!%vxrGq0!t2$k2&QlIvS%rX*$)(rv7FA4z~c|HzO8xJk1jZ%iGC zP$v)|tk8+7LYEYfm4JT)aACt7Al2^X3W$})3!y; z&;n}70-W?@6a^UZY62XyaZDwqvc)FEa<8MT5C{pFYo`^^*olw4p-A^mr zajd3VEpNsHfMJXKw3WvBL{JvjR(`RG>$;*%aY|;KYVx-g?sp1K(H4YBp)n~$xIIq6 zuBkE@!{1Jej|71*;CvIxm7$P{jhk`;Z_1GM;jxqf=q{ITfy8Mwu}z))iRN#ul+X0V(#*#@HhmyiC zZZg0&)hW9LgOl0%OVs^Fw2gI&6s{o15N?Yb|HU`if=37CQkSgRiGK@m1Vp{)>V=ZO z4J^sB@ir@!cbh#z-U240`x2}!$cyLvM=7xC6x5l-Y%oU;rr%hrZcQDwv09X^hH2ZW zAJeK;BLmyS=|QdY$8T|(({uPtV>pV5Hv>UjPfqmTGFZ7%axXwT;OI9I7laJhMO~~3 z>b1v;&>m$jo$4s++p7Y=9&HdA;eEs3@F`F7|7b_l3^yw{((RnT_?r*+*anIU1fw4O zMMl%O>7gAhIgxuh=w(^1)HPJ9ms00T)z)_l*@FvDt7U$Ddv6-Hqn4R{xtxuHb|~Y$ z*;^|>DgK9FIhS)QwQNIj9TEgdJBUYk|6k}YI1yj)R#=E&rt(Xz+OKX+)YHWVDmLQ` zu#KB*$Eg3COITRjl#dfN%;zpF>~)hIT9~Q0UE2T#5*WsGA;k?s(=y>nNkEu|ZG|Fv4V|?c zyR2CPG~?*_2Dv2DJ;;~NaG56ofCB9n=~YR4CDTAiQ>74)dBKh`u?Iy39t(9-{kR?v zNn#6Dpc65X_1KM~tOf&8NjYvstzo0^jE+5unM0@>yT!@p2+1G~Q1vL!(2$u!eB${b z#{kXQ`q&u|4iGlgnh4#Z@_d{~nk^Wsg;a2&?tWeqI6?XAa=cQ0f0RVjg)X=O? zabedsQB4BC&OeL<=7gOIG8J~+$q^DxCuR_(EoBY4L>qladkKVfxkyO_!9OU$3;~oK zsbU9V(|CDHPbky6xYya>L2H-tWkb*>KQrg$rWhQ&L7_8z@dmF%#guRKpbw^Z3@|RLOeQiAULG zMIhOP^2$X0kHfi05YmUMaS7XCUh8qxidvXYwb8&3T#O=?Kt$Hrc%mBd`d5EsJDQ3R)3I#1->0>FsV(ll1gWZ?(#DdMbM^f<*mNJ&vl-%XI8 zPP_^U|0dJR1m{7*BTv03Q5{?7&EINe$iK+ipNMKz#prXemVg+mVU=gEQV&!z+ZITI zHHr{$teQ#?2cAg6Kqy+r^h2;u6HmR$XL?;rB2}u*4l|-l_ z%s<3NZAfK_*n`?qp<<2Jmrh`%NSejIL8^xY#l!Q{XY2 zRAM6|HQK2Zn3`5kEftnHE?$M%&67M?YFJTeGL)xn!k>y4G!>gQ72E8#L;-BnOEKlT z{|Ia3;tByRCIOBP-j!14y;$}FO1Vf60HK~kyb;7kn@8fN(TPyyCdgaCO~$Rq!lE6Z zF6ft5+#F$3krmKHeI)^fXWgVuQ4A1}9Un+;!4`1A7MzIdax4oiu6ZqMc!=IOyc9nRen34$HaK??XY4JRSx9}+tTp`?+Wpq~mc$!c6X|+pr2y1MwQo~^X}Y@Sq1d1l{~t_~ zR?c5d$~lRuqVdRjL?GWf#rM)rGA(7zjZoj9FhZyiPaHQmx`6-;5t*N_9$6pRzXY~ zK?Kp4I+*oH;^;XO+r-90dWpH{OF;~?lv*>k70}lwoT=cc!aVZx9xrss~fC=kfQM?a|`fsI> z8<(`N{9-EGVBG$}9tG=7n2=O(85n?-joOS~%u%67)RHwrTZQe7hZcmV|DKyeP!i8f zl$11uhhF9{f)#t-^Cqybck+ec_ z;M82DFqEY+n>N$dQ<2qfRx54g7eqJ{cr__mp|vev#00p-5}2Y0MrVzi+jOi5~q%0#}77*4rc8K962s)UR8CQ zV#NX|BxMc5@g^SQSt}}LHd^EEoaFxMPkMzSBS%wg-J<;6#MDd|{T5nDv^Jo|4&qb~ zgJoIN;p9yy6blznop_q^S&rV*GvK+4j-yYM4{ah7h4F?HwWd_8Us?4&+}&wZvE&F_om8N{7n(! zNswYXic_9Rh*e#Y5>gZn-oSPmjS(lvSE43xPauvpYj)+31#@C{9irq@W*n3E2=?WlgOV1>m0KekLTBFeccL5fu`6{qUTv zvCu&+2x+<1P;66K_KJns&_ore_{5()@=u-Fn!^R2N|a}vxMz2x1iVFhJ2W=&IZtHG z5k*xYBQ0l(@~)^FbL@>1Y1xWfS78Fx1i7z-a88de|K@6KB%$L-yFiq|ZC4@C_em%-Btvi z35HPzRUErM=0eUTOi|9z!yb>uS+DTZVm6bxvz~1}DK3i`RKD6o8&cMgfh);ZgNbdD zj)_ML6JwVmGV5v^1r|@q-3)5<8=0y}0sZf|#6$8o-3wO4YE2#fma<_Pk&(&eXH886 zR$|gs0+H6D!VD|#+hU)5#dy)N0+ZrAjzA=RDSDS}nu&4p?j{$+`RJfrr9Imv01rW| zojuUV$1puZaZ*o7L`t2V(clbDPp_hreYTM(|C5i_Xl%rWAm1mAvGySpuh}jIXA`A0 zcb^OrSJ>dYJVmjMS=Eo3t>pdJF+cziSb$)GBnAH2B6zTXt$)A%A+!agfW3+lA#Pdt zt6c#A1Owbt_-o%f0+N%j*)4!QB zr2wElJzIB$NvP zBDwa=+hPjq2r4T%zXoc>F^_J0YpH_z`z*n!V1kggBue{ALI^J-!=kcY@@SKL3fO|R z_FOAWI{>WPZ7Bsyyljf%?2|%@007udio>QVEy$%1NI)Y5U_6cso(l6VNgb(5PqrX5 z%1XHeR~saZ*vA=}O*gK+yV zNyAJ_K+gaULJu{InnNu~^HS8p|0{tGg0V*cfPyT^ipaS1tMh=I&_Je^nrbx*kJ^Nc z8ZCo~lLCTpD>RD!lvGIFWF7O&JLQw0N-0Xbb-2Sml3){3p399#fq)|uStW!6K-aw5 z6LQQt$y{?nkkm_J3Z__7HbqlW{VQ41ti6v#*Hi?NDvj8M>(+I5n-#186ku}90De^T z&E}YV(KP42@-^QC!3~%=s;txXFM)Vn7zizJM9@Bl|H)M1%A|k|L4`j8P+r%J>@8CB zoRhX7QX*Oyx#y_m^V+X45E2W>WM6>72fd08>;EE1<=!KI$ zH#l3)TDmf&IYX{u&Vrs!|7x%{`9*7jMBKXP>An_wGg4YfJMDJJkWRg_&BiQ=R@$Lk zZ2-4!FIk_Pwv0ZdcK-OQhWRc!?!ysJT=B&jZ`|>vfsmk`U!HoLvjnyZ%JIG}@7(j7 z_twoVMMIO7%&jjr&cj+|Q`c#%B^5}yMBr9~Udzo8!R66Z>?sqoJpUoBs08c=$zZ%ULaDNZn zj0Fb>KHx3wH<)Q)vMAWHjCVNX5hR5vL6Sgb_&FW! zP;40F;SW1kIUrUB2oW5j(-N?kAx3D4Q-fO*q3Ap#YDS5{i{cfrm_;pa5oT4qB8-Ii zI4^RMjAe`)Zq&836E1FzW^^M+$T&sE4JmZS;-MVh=r|wdk&k`!;~%%!Mzb{#kcBkl zArYBKMJ|$&nb~6_AsI>y zmw8+DgIR!Q zeleOSEG7+YnZ{^3@Bfyw?94Aw8BPLzl7ylJUoJ=ZKyWtGoZuAN`%IWkZ`M+Ti<@RV zyJ zmR3hgWGRa&X#ay2I#;K)Ns%FKmzC#>WU~c@%n$%b!qAKKW*-k3i*@1?-@VwER%^vd zMLTs)dnB+b)tCyc7IS5qrtl@$TiLxe#M~C_AU@|2v z%?*naK++Uc%79!p5hN(kGD+(2#TS2W0d0OERB}0yr3C#ose@}pDKs*up5QG-t+<6f zqDqERv;tbjRbYyOGAwX?HJgAX11B`XJff~|!lW}@0%RMh^_69(TmY@JNFjmU)~3E{ zLYw*)(xSI82mry&DA;(L+yl0CNXbiXT16$F0-TCuX>F@{=qp~TB-Kzu9-VTtnVTv2 zSaTRw!2gSa3&+~(2D#6%>wwT`B&))eUnO&*rDAukvKcP3Omo_cGwT%$XKB1MLh(_s z{1MjdwypI&%89K*80vgUHDmrRP7gOJ%_dF7WW&$fkoBmdVK4zWfk-PDA`r18M^yhv z50AuxVVOV#YAzX!T^!=+x)4Snb+eCCUJL-X)GZ-vO<7tZv*U&kq+&3-T0!LEEXH*D zC1RQNPV(9!DOg%J|Ii3_IxQEE%;eYZYDg;_0+&rF1k{mgiY?fps9|G=APzFunelUN zw&=NbKy!^)95k5_0?j8eGk1&199cqRlt2_qi%z1K6@(NRW#c8vj_+-k0(3;ZYLSYp zss9TATWHQ8I%$-qL@Mkf-+bSW~eif_&?epkh;uz;1aS5)PB(~pV=?e z_5jjD3h?L>O?EtX5sRmHd=-IHr7;sHc*||!4$+{D)vbWlW3ba2X&Q&XaXJW1W`YtM znmZ`4c1VODwVPr0oZ(;2E1~;#kjBttH>C#lN6MR$$;~z3X*sx0u>B9Ar)bC1F&?9! zi$96yqlgTHf`isUeoCuJK0>KX4AWmj;G0n^qG+Yv7GI7h@ z)GzN+u1?zFEOLz?pvF?R;6dt%yxzht_M`J4B-o5YM(RY_qRSxkhk}k}Q6MAr3gYkX z2WDX8F{-3RVn$C+>o!iSeR7AMG$i{#D>5d}NdAEn=ELTuCD%HzH6Fu3zKYLIa3vlj z0p^b&xBxGFN~k_;JCv<^06^pNLNvO9yn>J8u4D2t&?5*4QhtyB(nvOjZU4N2;P=2U z2#aX}n?fUQA}Gvb0lz{4?t$Cv;WRL0*jghG6{RVnN;F8MJv_|vglTWuhb~ZK1*I=V z9HXUVFbl0On|3OJPy9g;5`rPffNeak?CR|uy@)A@0{_4=%J5R6-8^Co zQjT);f)zbN;;LvL&oE}%z#^p3c+$os=te|JQnkDy!e-rDpjXVCIzfWQ`}jnoE1A+}@k7S24( zgER|Z3L>ISNGB;*@MpSb*c5<$jO`Wgbf+C>p@+ik3e!;vT zBWzBQ4^=2Jr(z0Djwn{bG)w{{-(vB&qA1OyD)r(nA0ppQQv{QTER*O_L@OZxr%fEo zC^&C9H4-E}q8Js<9+U$FPv#fgM%5G|12dE3kdrSw&xsm>4-13X;LS2_B0Y4F*?ti_ zn!*d2stsptJmaw82&3P=?JG(FuzIjVC20*>u#xi`G(ZNFAiIYn>cnl< zQ`QJCF_aM^jYljOk|88uBaLqMln7R8k~;A6J!`Tg|0X3oR3j_YB#JRZzoKiZH2%;o zK+}TM0#G{AMnTI1&7O~ErlKR7LMf2VG&T+)T0up|5C7gib59b4CYob6ho>G}qYw9^ z{IJndpsgvCjsd?SGD9mO*rh(I@F)PJY5I`Bj7EiUQZ%{-GN#n72*T7F&Pl8zCMkwZ z>P;X36-EY8~W*~1keEjCR8 z+n8@!Wbsv}qWpZS6kO64nxfa{!uz&B6dBV}D69)j0yjxPKc}J0w9O9R0Bj<7jUWFspASZVMd?58O#1pnJygit1r@zCZM9F;C&6EKhwWuUDg z&#D}ULp~A!0S+UE>|!|D!gTgE7u!KcXd*Y-pl)1pf!=LSi3Met5Vj0s5Vfs71bWV9D!2a>FSlWih7>AsAvV_AORvDY61^Hx9zesKz7?v!`&64>^l8KO*=_2U~7p zsFLp^?*T)E7FVk^PxvAe`Ed~MAvq>;DeR#X92Pa~)En>iYgEV^MWZQx1_URL+0+X; zNbfzCW8$i+EG89HH83r#25S@W+xP=0GDbcpWI7;KQijbhl5;ng!a?$IHhMDoh!yD^ zVF7$Si-5C8Y1qE4}+e;h=p$^yW;=0R=((h>k=R)TlPK;z1; zZDms_mQ(T;)>8#HQ*wg~#8nE0R4m$oz1Xjvh~q|Xq+h)^0K?8P`>>Cj^BA*23LrwY zFj$E~SS1WqKXa`Lqf~SewEXNN0q$YbBI2QRjg}3t(SkHcw}5RVFZV!hQ*_Y+Z*~fN zB2zlfF0Q0(G)^Xjk#cB~Kj+sTLXIHNS0~6VGVud1H&PXmW*;RuU0}mCRv65}Q8`{! zD+;;vG}2Vztu%B5SDG-LgZMsD3~>G?K>8PYnG-A{Br8(_+SH>i1VlgaaT|y2F(R<_ z4zhP0wDW4h0DF=R;o>L-g8y63kuNR6R&Px%(uUbA$YCj3LVlzi!(y11V&ovhhGR7Y z`*3bxvUid|U0sP`P^LZ(mpEEO3OP+iT3Q2#ZO+O?EbL(>q6bdlRG>MvG0mhzpr)uR zB`cakEV8vPlg}bjB39?ouBx`sT!eUw5Nu#AFSuA=@-9^p2nZd7B&I?a?c%M+Z$SMI zWlF&nKoCQe4LW5f`#?1!-Wm(pB6XeD28B=!m#`-WF$r7&Z#l04&jo8O@P{|6T|q?x z?n^tM?LY8!eM}2vu)2S$Qp9le<|;BCHPRs{6nCTKMF>TQM-cn;L_*kvW6kR@6Yxq@ z2;=5->>{PQ?6d$BApgW5g|BRt8TW%elB4~ww1Y&fmr1fI(1sPF&40=<;|dQ5r&u6I zc44;euK{o{%E~S%Y*K`R(sb=m4Z_>3FDSwV;GWSRc_eH^atYPz3++L(V+cWUky)e5 zgac2Qr}$uc(Ls*VHBZ;S1#j|_1+FFfMHrdV%xM|pV=AiRF(!j1b8by)!a7bRbd^GC zb*JgH^90+YxMl8vO5&fFks@FiPZU=1$FeYS5^Kfo7 zkcF4~BP}c@m!dEC!w@y+3nxQzs^_a1%%P7)*A{LI+(Dv)SeJc92|l?n^&$auQc#k} z0;>!(?6d>ZL;r(;Ik_21cT}{#6(wx^PvW}vE-HdP!Olp_mN|J+CF9&MW>E-x@PPre z_29HZvDzb`6W*i}QzR2;Jk&%AIlBBaC3qsCKSC}#f)v2jZqkNLBEpLybn8N+e1F#K z;Em`W1B%5wiC$eGq>=`Wqb0EmHsCTMFm-ojheJ?YYSCcFUk0{=hKP3)Qe!&RIl8a%Jlof?r!`MxLfJbuI zjA4~17qV{F2GVeYD1;~pghf1CB-}%AuK|FX-NPsR;;x05N1~JjU1Lg**}2x_hUkOT zR53uh$NvU9@X3hD*I&JeX6=uG;oNky)Z|GGI_#3z=SKQ(i4wN%om-5^k|o1JGM z&{92PO%w0)i)~Zh7cjLI9)6SfWLQOA%VQW%=-CH{Bu*6E^L#`EgFi#GY|z$d((tO+ zLT!9mtT!_&Fm)grokTtjxln98&8>)v2-xS@!b8-th6MV(n-C> zrSJADVqPZPO*9*t%9nyNA%v#mcupB2WxVxZW5td(mEfjaFet*a*jm=oRidZD!~98P z-Qr!B!WIJ5ID(Y@4Dm5e*ZRz@Y6qeV>FyopTW|sA*-U;Rurw_E@$_RaD`tlBr6=1>_6Y9$*Gl2uhY=qe z&I!QjM}x8P`fdwgCsw=|MS_$7z*b|3FyB@zAk!?^+`6&mgb1CY_=^-X3V$rcW&(S- z3lOkQ4L5+Pn-PGQ&!OxXk1}mkzpT%Zz-T4bJbaB z94VFohFMW?fko3-pJl{T0zfF08(w`Gml1?Og(d}Fws=%rLI3bn07PSvCR&0PUUyuO zLJmn}kwzYgWRh)VL=#P9;6_k^?U3|~YfrY4M0y1P@m79-VfYn9h{Z-^i~mw=!CqPr zVFuDw25#wPNjL&lz%5cpkXvkx0RhvKZPW!?b+)uKBt%#y5RxQc{ZgPpQnY9j03os2 z*kdx05t|fbx+J4(7?K53EB~~UUz3{Ni4#l7fwbjk4SmJkNFnWs(@aS`ITo5lrIwi_ngyRP3tUV|FLz28-6)5FPFtO$9g`O=YD8b3~Sb)FtE!2vp_PDvw zCR?0ICQLHLND;Mu`Go7E%_Rh3Zvjgb5-Ac;+*TX-7Jxu~XW2MqUH{kt>CRPT?PRYM zw&1wYLXi=a8Yv1WAu3h>*m7q(Zhm|bK{8ko8^Y(w^EjPe_GJj>(T@sUS;FubADW=1~?F(Dc-uSFxB0rad;zl zwUXkGPk#C4Z^x5M+$F@FJJ-Qx1=`4a=47?su;+nV0gY>%BM=pp3oNb?3eMWrE%WRRA{G0Q zUv^U#9PJM*X@N;<43dPM$xF?^!|L;utkDa4XKG{odr0uUP~ws1`n z5sLo0h07^y@E6RIR5AT%#sJ!4E*J^P{`z;Ftqc#1Zrn})em2LT1h6hNk(9p|!j;KxO;bTJ)yOKz86_X>q&Q~O*n{jt&m20DKf1)rdU69fj@bu% z=j*ChzY12cctIQWPzKOo=2&s^Q2`}#BL9O3>_^GLX>yKbBEziBYGA_2NMM(j zpQ&YzH{%dc)@mCG08S%ov#a!AdMt-97A$+U9i7~BqRReEta;fIata7Ij68~3CQ{>X zNK=%GEQd0~!zf&Uz{R%!K?1qUN)nL-fFN9LwruK}Zyds>;EFYPpepWJH#V}?zExwA z%})Y?;G-bePq%Fi9+#59S|NESFV2;&Lns1WP?EMMa)j=Qj3eD#D&Q-PHHdeu(_A3E zH@>I^(l^&y*)IJNGC{&AWqZnB*TzH%8LJLy3T&8>^wxxmT@tloTVD$)7`ZOoCPwwE zG1j8?Ly=*lbPbGHyo6U^aqTcpO=w*I2LCU$r`1Srhg4d}ytT87^`=iTfM(7Z^46S4>v zCMS9e{n}Dy-+=jQURo<;xKv{HhIP(#uCtJk2r0XUWVr!8&WVp3Q|62hiN85bU%k4~ zhwU$X`_;0b$(Nogb*oCawDXbF;$UqO+DO{Ov|Ej|=^-Hz&scWqXMYJKu!K6Bk10=| zH!YsG`tLfi-L#5fywAV9s44)h(tJ7`YdUpW*QpNDsEeIyzD#Wq(OjF-mN-4<{B!Z${M46@ zUCj4s^rI_1ZyRsR$7$Z+ueyBcRIhqip=#}-z}Nor48oo5bT1RJ%YMGOAE#wvue;xmt9OI{-O_j;eE9-z_`0jO@Oei(`5aHA z#SUKbiLbon>rQzkWxncbOaJ@jEf4w6i{8?nAHC^MkNVVimGMXNJgkvada#CG^)Y8X ze-CbZg}a*eyzjm5c|Ut&CtUcIe|>+66#L(2+}+CW>gJnYq~t??`qZy}+pW)M^Lf76 zmJYhz(~b5zAA98i=YEoI?)^(2_vq=zzWd(~|M=r1wJHWUs%=kpgo8i&_nvW=%%6SC z7a2O!dAVjJqosB2_gSql1#Fgkt;T$77XX!JB$;z&4>2)}vven;DT|jQ*fo4IrcE~H zX=-+Tb`^qh_kGhwC!_{%$LC=DXKxu~VT}fR0q9`1b! zV=vKkiF{HLLI1J|q8JmLQ4wV&K!~v~n^UG>LF!G41F|XflcTh#HMpDP^H(G!Xz?@=gO(7M93LpOso2mqgUq zbn_yOh9OU&*b1GYj%^@j?oeq`kpw6)D2<45grbcMk{3uLRtiNVP?;b(#3tA>kf8CC zWI+Z7lQ0IsB`e8ZZ2*cL5sBt>W&xlf0+f;(;tq}2Oihy&*O)LuQy&aT66v9oXW@~6 z=vg}RFx;q05ZM^2l$30#k_ibG;24UPqAQTmkZ48_Qs7V$(Lm-=mJL&kuft|)wla@# zU2~`rjQ{g|NfLatcOD5Q5;9>6O~Ew8niDF68+7qB!L+0cK?*gx1r)(BZ__%=>6+dFIv0v@ z-Zr4jF-L|*7f2VUezcgl;hSM}Fe_soI067s&^nvYo88izl~yU15gbTC5dO$I_o;0Z zR7yTW6Z4U%`{A37VmAh%seJ>aMkO6d8kaZXpL3%SqB2OH*qarzoXXal6J$67#0h0! zlnUCFDYQ`c6cUQM6Y|(nKtZTSBQYBBs(L!6oU@PZ5gfWIDisuq`x2k7wNPiVCbdbZ zaPuH%17OFY96{oXAJU$7XlbZ%3uQqPK0_$b(;E$%8hY{zx}`L0(+cju7;e%E#Q!KK zN+dv=_ax9EE&r!qltU0&WKQSe9!51EmXjfBlN``dSEHF)6GML}#}`|G8B+NWKO+H+ z;Uyc)T9w3C3a|wiH6$YuCP2YBL5m$bOEnhTiuV*JQxGH12rdfyAxUv2 zH2Y}P5k0O-LyD;%+>sm5^*InHDk_Gn>%o$W#7r2LAR3|(Fk1jz;6XB)j|ce}8p08; zBO>#Gw_hQYGgTA@Awcs z1)v1MLJ&$L5#QOhabl*9!KukpLvSG%2Gkf2?U8x@60 z7MUDbbPy;?#UvCPa>QVQ%Hs(D#Im$e_^>hkrpfraqDHA`>{cu zBe&-Q$DpXkaztMIiDxmPQZ{O!U$Rix6)L-=7=maK3(*k&(161ujzICmZIK&J@e7n6lYNiry-)t0gem7v?2i$2ym2v@oAvsgN!7& zLQxo>V;P#FwV5Ne$iX-eMHd4*NRUGjDyuk1TZ|sF!y1uV+W$)!ej$!+b5aMx9RQj; zLV*Aq0wspz4t8XbegPD&6gD>T9G0V0RA|mKmZ}* z!F?)n-t7UP>>`{(q9Gxn1aH9w39|_lLSy_`Ht|~qOidVP^DQwa>`x$|h zj@g=*^nsQwgF%NDBqI_U{)RjU5?so7T?`bh2x||u@PEpzo!rD0((xq8!OKs=Dh0O? zGwKoczy-RrR*<}*`zMr+o0S zA)-{F9B{$96z<&_5=ORN#U%eI__7K2z(1~`;P0^{-=l7s92BsO72Hv! zmWEU2&*LjVyW0w^HmUxI=FECNYj&lW;^1(Fmb zV=nDtI5dM=Ov1SsdzyFc|P-yQL)S4DsZBp1(0@s=^TZIgwaw32LaV<(IdUIq^ zQnp?u`PZ)Gzp+Ju000u8s7=CBY?2{Gd2Q7Kfgdw<8qrp}oVNZIhMD!>M~sy|D@l+YJNDkTl-iPVYb4sdTW}U6Oz>`!UpD#bAIT!p?kw#gET&d$S&X6+8$!s0z#^{*o%!Oa0FB)wPa#Lup)yl8}PajDXP9tB5$O zskNFo6PFBy&i^fFF9ZR-kh>PCJBth^$4lxLQVY0KV?uw_Nh7i1DriHZN;dgqlvCyj zfOV;rkgq+BBq&v@Bq|A`!q%MhB#WHF4kL3}rV2O;BdbZbu{1mBrPMOa5Gjje13EKy z3wn#Mx5&uwp$R8EtuHdq-2%8Rwt$c7xCneKA(&*e2)376vrpd zt^jj)ib#U7X|g=wk^*us^U~71 zi2QVVOu;b1T49@5PDlcTT*0XCh|IJaMurlv*Xb8~I|(==PeLH4j49eg0@8t&=%nEm z=dKl9W&f;GA;vj;D9p88$udjrxWl)VQao$NQKYW-)%nC71HjLRT2^w3p~xgmJ-~Nv z(PQ8eKw!P&v1tTP~hh&x}g*8QtFT!z^ zz}23{uoHPEIGSk)LnM=+e>lb-D8dMzDyT-o6^bEKAO%JaVxEj>FiRA%2+s&KEqibQ zCjS~i%=Z{_$fp$zfJ}+XnPdeMwejbXTjYzi$g&!Y9FJk>q6h*QdAHo{2S!f|4ix2b z!6r2+aLAj9aZ*!2l?79n!zAX&zV;U9P;ZJJs}$g7qdZ;R1V#Qr5ku5gr=7qpGYcFS zN^0bqHh?B$=vtUa%Gt@HaDrD10nm6JqQkOnVhd83XBW}AJ6k}`BO}R5VqCPg@6}EO*3O$0$X(TO1?tG69#W;|TS`)rPV^&~8sQI{4GBp>{1vsh{6Z3>g8v&+ z{wA`xkxEs!DoQ&w?02v2+v7yZ>u>)CJy`@=EG6~-f+LMQj1a1IuM>NqgN!01^A0J#&UH<`05&eAd zvC2d+tt2Fo{y-!^M>H5i%t#XI9K~|;^~*$h3RQ@Ral)pB%f&KAPkEwvCv#fN;*K_6 zJQY*MGp2D)2m`k!S*;-2dJQUBo5UjKEh%IA>+OmvoC~=yVoqrmL0Ux-oK&S1!Cjzl zEbIwC2FEw-RF3qOWQqO=8N{=o@~DC8Dw zd9s-fHQ>NN)nzkVPub1+0t)tiU6xfApjJb z)jLsA?Ob=~Dlid@Hg__Yuo8zabF;HHaRa~_or%Or#0inW8b2w2FNRGF09!&rit=Q7 zF8?S6f)uus1jMhCPUGMSHT2BXn9VBVs!Wu?h>*NwWzw)Ag<}-*k*d&!FowY%MQ$}^ z(KL%MlSZ_KqcWQDIBnr@;udkT2PS~43xhsv9pKE^M|@Q|BFQbMt{#G$5)DsndrH*h zw7NouM5Q-7k9L$4qU+>##I~#hlW1IXbs|TlBjkEX&1&Lkl>a;gG@TLSnCK^P6_)c< z91P=_5Hc3&VQyaodHKQ$GbLTV1~;ULku^E|)3A#Rwt~`XXQS%0jICu(U#&^2#+dN^ z;)o}%RC{HRz)toSvc|Kgy)fG|o{|?u0*l@9SLjm_*vf9lbCNx+@44gP>xO=0W;LFg z1)BfD3ictQyiF8@!d6JC6{lj^#&Kj6S4F2XHp@r?G@~_&yy(5cAzrp%9y}t1y`6Q_o1J0xg$+k!0o%gABr7d3lYY#sUJb0 zL@_78S(gX=k={y(5b?b0FhF+zlK4xCBg%>Q1Dtkn4gU~%2`+F4?9ed0nUfH~z=p%W z@w2$kgNgrJ5*}oY?3j`inX;DvwhA0SX)&$7Iuhn6BvjEF6>7mGa0TvT!j6dx31~sU zF+v?HJ2-KbjO!!?SrvxJz3M1~Me2^dQ1$PK8)5?z6m@f;Vh>~~+;<>;jA%mzH zj^6PJ^NWo(NQ@!76Pqx;t|7(I(aV zo2YUPkUGNH$fw$iNQoqh*wLzzNklQ}qM+y_m{26301J8w$^JtgTSGF9w4{_E1&blC zwjrh?ayg1Zp6Fmnk36oAIX11TNQ``mn!FJsF_M}L%8azgjvPw&SsCezDjEx#m=GMI zvzughNue+oz7z^YI?BJ?O8;9s%AZsiXd}w0WSXH23bX`EyF4PuL`e!; zOp5%va}mjq1Ut3dOvJQHz2r&3+$F-K%$<+|%&aFd`OLM{%W1JmnUqVEVakFy9;P`> z80yR(EX<#v&9npxw46xb3{I8#&EYJ`pqPnE2@moj&Xi%!Nm7}+y0_8$JhY6?+H+3Z zu+EOLONj&&oA@y29E$4HO3)O}=M)a>1QXRGPoY4|0MO2Jkr6pT3t<7old(_16wjiJ zO4>rQHVcolNR7tm$N`lxwERt|EC^2H50ofSMOsi5)XMNo!SIYwp@7fv1Pb0PrUcbZ z{zy&<87_|TP4m3C3N46Ih>-9o$p4OfH^wHXL4AT@GAmvfhAySeA%5lm!7-do-4NNJmQVxw$E6q~i#L^z+Qm5QVEv3C( z8q$dbG2rY=GBwjMT~jt~Q#XB6IE_;|ol`pXOYW>wBzQ$PJvKn+wu9aKWK zQZn7r;w)4}Maf0Y2`_C_NR8A;ebkFwN=dy`OwCj_rBn{p)N|QUMM_fOgwGuPQ|$B! z-W1i|{0UXvi6}kLJ7r7~)fmUX&t^N(0yWO&ESX0Q0u5?a^W4dnq`gxu8QGN6QYF@5 zQVC9N)9-9g<4jghg;bWb3;&?#pp>D~VJ%UXIMn-8nJC3pnAp(#R5;5-)1oX-K@`kd zJx`qo)$f7LFWpNTlUJfJmv-$U1-Q+gn3{HtN}|lyb?sMk9n+#5(!&%|F%j28bxbwE zO_)%CU*(Aq>OZhMOvOYpq2$bm#aFH3Qg3BTB5h2dz*yH*nTsXLgypDwjNhC8vQgC$D$9UZCG*eO_DXuhE zi6DhGC^?A;0Lq|@#PvzV-C0-sT1JUE4yzC;AOl2H%7};nDbQUlOiFg*$ai^53ETjUR!b#db0xsGf-P@KuoEaJnh1%HzVn8raNv!G!t=U}3Z5*MC5~Kr| z*M+LalDc$#%Kw@;h*Y$g)gs|=e2gvN0?=E-8Wz^L3K~GUV4JGpxQdtnXdnic0zLNB4E?QFcDU+9F$#Z%`URpK;(ji2&B-!A4hd8q*EBP z2}jy#HZeS7z~GUB)g0vnC4 z=?g^}jsK-p0O-pMJelUv;3HkksxKJ{2F#qE+1WNe;c`6;pz{q3q7OxCCZf7GYBsPl z^s1Za8n2tpgaH)MAP(H{v|O?vHl$`gBC`bfD9I{6O3KBxs>7Id;5wxvm}rGhyvT@v z4uSGTi(@IS8>>4+T&DGj1I7@I@s!O;-l+wYx&hnQ{g{*H+8%Bx&$zDSwc)t1-2`^L zEe6L%l3U!JPD*JgX+1C+3lLtE3nexZ!{sOwmN)KmX%g;eBT{PiWeoDr+VzdxA9m?P z2FLoWWqYmY!Ab(JW<;1ckp;S(F%uR8p53tO4?am=8a)*i#LAg=Pgev?p8R2v85EwC z>i@<4Nm}s=h*4WXTWV=ZT{4sFxVQ(tM%=4@S*eCDditN}b;pBOX?QygOpi%Vz zg6=H{1)!c5>t5!03AY1+8hJjkFh8{+iysMs8gXIOx(hNv9SSNhc0%mz6kE$FfV$YO zSEOf4A~cJH=$9Zoi=Zkc(GMOgmg*(nc_yv^!U-UVF2JeYDCph~F$#NN9>Phw&LgpR;pRalHGK4VTh7gg*K$v-|qzrLzi71-}jWwAdh5u}+ z+YUcGm+GLZutU`z@K=mE|6N@#1C%e*-QfiQFh-!^AO&NKA&q$P;H?ORSc-PxH`!a# zRQ3ymiLBf~2tv`GL`*Fo3%URP9@7CKnXs2w(+HVEh+9Dkwg9avb`3S*o#Z||TPUA* zU8F|aJ}$VU;YD&C;)JK5P&Y4P4z_SVNOny9nBXo?h{Q+$kt-yC1B+HD#M;1! zGGG_z0k%>Q9+~)Vw$K(uP7VLa3lkq1!x9tA@LqvqG>C&7KLK@_a0Qiw2>(@sIPwaP zCrUQTh!Hw&qNeZ}B}g3FafJzg*ne^!N;(zpsPH}yVF{?UdFqZra*Rf+G);H$LtmTG zI|2cmbXqJ7LNh|7WQuykMA0*k%q(#@O!TZ-;MVjubhCCyXqmyv6lZ6-M`ARI?=Tc zp`PLpn3xucOA&h?vD%0s8hg+na)Z0r@RcTU2v_kAqY@3~ppI`F8vm~wN2;e73Bis| z8VRc4lsr3)5HTD8=`ypJqA=z#ix`*2_s*f(z`#F^?`|V93Q*;m`*~aY3v!*r|BMIZ z=v^C^uYs>HX0{$v%9M6GzHb)8{T9vFno0o>$$z9MVUn_F!{d1F4PV-iVfw`HVA!~! z89$%wsK>UI%cnNps91etB7M_yIA0+jVv$5MEQNpQDY+XH#1{=XQ`>uesiG;T{dMx@ zFShMa1~_dxCaH)8+_n6e;O)oAnsG`gU0~tJElI!@xVa@fNxCFA{o=0C`_}V79NL0A zHDukbb(1heP)4mB1Vm==ZDbFDEv*$GXb(adp@b7sSpT7g7h;%HNGLHl(n#+GM^<36 zv9@4gJL#uTX#XTNTvo3E;GRZRIRpe>!yyNNf)`1Y(Of3Ec2P`u`RLwh8Eu$eUpy5+ z21`Pc;T1__&=r$dZnbh=daXEg+(DmB1*B_Heq~olRc`6f6r^C*B#e`}W=lmEjVGjP zFOoFZLnOhLpK8dFu?do9(a9wMbG-<_R#O=ifN+jxwv|gvgo|FNA$s?MjeuPt|0xdXJgbKI`KuCg4wUq>)9v-aQIb7VAN`%#`U( zAMU8#KwxoJnUMKLSEZFtjzr*DdS=vbE0&FRR<$poSdvAm4yxs|v=(qraIofw>3a?( z2>>T7K0E4bw%kM6R|!cq5yvjs#i4d7r8tE{jq0miOv*(&PvrL@=N&+#hg)cD%+N+1&9{nYaRjJl1j~HCS_`{ z{!_D?t+;e(l?$FaT3{b-rSvZ>k_y|oQY!Ed7ZHDytvzTyETuz(Ar-_wN*F|t%l`zS zUs$|_w3gDm5h&5(Mvd{0=k|P9Cw|-p>;E3vH)f<_N(=!T(soL#Y%OJemWAAr8J z1<4q0;~)C4S!n$-lg@1rxJkwt-P@@~qP->oQjmam(!&yu#A`r|=?<3=mY3R;Bx483 z&97iIt;fL$BT?cLO{fg zA-S<$OC-pcg=}Oc8mW&(m?IJ30HG*O%F-{Kry#W0?uIOTN$k{jD6GJ*d=Glde?Ag` zd$mqWEnFCSNTeCu+2a-x2?9fIV*i)sgk=*YOi~oXq6Crv$x&X!T5E;`1eNjTARDCC zp4`zu81hMHaM_VX+Q7O3)Nf{tB8j6U09Qb$zey&g07pn|fFQNzhZ*ewpneB&l*;b& zrJYFNK3bWMzUnfwm^8{&b^}&bHgPP6RL6aX%1=aY!WUCLF#(x#6$z!#3Y<}E3-AHf zc;J_S%zR`uGMOP!h;m2Z1TH&3A%z5{AT1L;q$ps~m+go}lhiz=0PRqYb$UcMRM|oa zgn^GL6Y!5I2x%w?h{-+&#Jx1#Cn0aCW`24S8i|->HCq|TUg}mZvg}b*lmr495QDmp zsFF&<>SwvC^cJ3QXF;&(BM`g88iN0XQ+@m)O9>H^xvki8hmUazDO%wV0m-B&NwH^e z>^UsMsM13i4NKkDnH7%=Z(ltsKs|5>6qXb%Fg*#8Ms9*0DoItEOX-?NUiv@B3F|MU#csN%1*T6M~#Y@|t(tUOIQ_Uemltd#^>SwtandWxgSaF1Kq<)WgIS!xh4!TF(Q6I+<> z6xL(I*WnW-!$nLWAB$JM1`hu=hZGh_raRpxxwfJxIqgUy`CL7=tXYt%jc_c55m%G~ zG_*Rcc%Je&07&2-SrLzDx+~wGN!Pqw2#*xFU|#cgm4p#jncT3!0#0(pSi6PuvQG3v?3KzDn{pkjU>th_V?p zi^ZZX+~ZjzF&$kDQVRN(DFIs`!<45h$M&EG00>}(aGe5KR5iz-q*7UGQbd`g%%sXx z4lZ)GTB|T4hM6F_N9rOa7KLRB#+G~Vl(SOPO^|{V6(vX;utO{viC1G&aTgF9r@{4Z zVG3kO0*w;qlS9#MUUvVQ%bC%0lEUECjZmU3V-kW}$!uaU2P2!Cwkns&6p>ANg(Q%= zcFZ}2WFo^oh+6E7(k3O9L0z?;SBiwExtJ(MthE-5_PIftBrqiXltN7x7n4pp_9WF- zEm?MisvC(IZ5RnGT*y#U(%L#A;(05(+wJZM-3HMYk%FAiQkn2j&z@-mZFlue5;^Tu zn%_f7_^jBDHb~}tR=ZYAKBJK&xboEzr!+|H6iWLMWS)M4&6E6By&&^ig8J6tqW`H* zkw%d)5!{(#u$I8Xx@_G5*kl;8@Pr>J0|cdR7cLnD$;(pYM+}*gj(>e>lE2i|AcakX zv;sSHx;ei5_4P3A&(lDV07Hgt6w##4?tE%&DG*P^BuL8^Z=okuq~Kht!=7?`5i!dQscca@8woCKO=jh(O}%p}CB6d{b|N2%DA z9wz?_`0$7lE{gd5(#t?ri#Up~1c_+q7-+;0k!?-jv;1x(X1Z`M^TCj!>g%Z%9SjZ{G6WNR&DI;9uj($W0uZYIj0bM~L%J&ciMyTJX zq=)*@1ig$zbnMilG|Nx`j$GIR=s-|N^b|O14K!uMFSJ=IzKFS<7?%_Pr2x$xL6Sup z1h^riVMzstK*oZ^Uu8g|B&E#|S=Ot$1VPjVG>u9CNKS3cMM7dzT7*`jdD?)u!rs+Q z5~xwWWEhP&1eF9*RY(O!l+8NwTN#no_-R4C@QI`tmSvO>UG0euwbUq{3dGUXZuI}o zL9A3=C_zT7B29c5G^)kbDCEz$%|$?*4o${L5X3!-O#p~m?@{7V)QS>r2_a&}T|6A@ z2x7#U;7^oRo-o{DL6&#SghvRFSGGjN70szlmK3gA5NhUTUP!J@2|G%k(_xj{p-*8j zo{|0AlSD~RL`}o))#7xa9Bze1Dk4pQ zjjs??JE$W75M3X^mIQGKU4`aE-bF7Vm5B_+_!QS?q9|2x2kJdYLD_^yu+b6SM62i< zSg2pcG@z1dEs{Yn)g`tkPac z>SGk1cdFiNWaVev-vQ}|L&V2aaEDcSTCQR0V}xc>gePF!gO;L4E4cqc^{LFw{N zXot9gi4;)TbddpjJY1k~Agi53qEOpRl+e5#-xkPR35mxi0vf(C4=Kn|Oqj<*phUz% zn+L_jy*dk^K^&e$)BR0_1oWA`DH9pUMsAP<3Bg4Yn1lfF2El5`SHz%nUDitC6^Bfj z+bO^nl!A%f8yQT2lo43Q8e@~B8YKxN00aSaR0hS?ETHXFpn(5`!jjD<6s*{0h5&&r zpHz}L?Q2F%+RzG`d=TsuaDjBuiNRLad3A}{rYw56Y{g>KVt#FvWgEw|ZL?@jGOixg zj>`Y-hNDCWnK~^cNg3Tn2bIljdI|~qWd=wEN+3CkZcN8P9H4noS;ID8P6!8YXr$J3 z1~^iTcJKx?Nm_XwY*8kGa}|I$scVr<2`R)J#cBi>{8sKghyb0LQWP&Pk%HS*<<_1T zdlX9QZW#|Zc=0m z_&p~?6$aTo$P^cb7Qs{tRWZ96=tUTD@+81o9*==;@$rc44_xEEQN4N6GO<=0&Il+8mng+%h@4%hrv`_Jzii9deBVVi#NuSA7nQMil!`K4$TL%OEFbPO zM{_wJ^n{4V9q-gBLo+AyFZTkWKU;_>i?Tio2Ssa)ML%>D9&Rxca`DiLGtYA$KL|r# z2uiE+LmRZkrG`cmbWBHx*?qIVwv_-$KqbpGK`Vex@AOXt^-sf|{|5CxxAaW+G^izj zPqP*87PTioHBCQt5FYhZTlH0AwOdIwXl(y=R(thkR`pjqG$MDjSex}zZ{t-DH2D3q zyRG$E!*yI&v|MAz6TUTFVH@^gBX(jd_F_YF@sv?f zZ}DDB2rmb;ITH_MTL@ueh&9hEW>>abN%p(lwJewQT(h%;XftZR)fS6#XumaQx3y!d zH9)VlY9DrFmvL*8HfWc2P0KS|b8~Q8GHq8#XahH6BX@GUGDUZFU*EEbBC>H`GxCgf zVUU%H5qB`}G;UA!g`_rw{4fx@^KX0fKfiWYbBAV!b9Gn9vUD?gXQqiNT1jgROlCJ; zuN!yFaTzstLR0s2M>A~K^=wNBY?J?V)FL=I6AwkRcL5BOa>w#>x6c%L*7Qz=xv|MD z^YHkX+Y7e@Z#`jYARvHkg22e1?-n01`!HEN+(I-A-$W?OMo&^06Ig0UP0cUq?rfTw zS7ro&G1-!$c`+V=6N2$sQf@&jr13>`cwy);@Rl=dO!xg|f!bC$4@qb=LCnB#H^v+U7G zZ(>chG@u`t)>LJeZq2Qza6GqInLe~znHq5i}R$z zNNT*8H^=#{=boHPG$%IXq-#3yIvp@amc3o6;kNg$Z+Uq`c)Q)QMuZe2FAl(9R8J73 z%4(pH{S9CKo1u8xE~baMb_Wwy50vs8A<4{pG^a&Uk1`!4Y+Bcp%nu$l=dZQV;s{2C zT7}+;PET+MMfhJ~09;CJs-^eR1#0T)lm4I{VMRGEBgi z)c;r6KlgF(d@%n!uFjepYnd=BJwK7`-IFMEo^jgde9}t~-0yu}0lwnTyw1=38NV{! z&z+aj{o_kd+QQee4vCgEG2!?9wJ|GhV)Ad= zMSnHkA)&`%Z>$s%?d9_K7~i&Ppi@D8-vj$5{0sWZuN-mCS`vj4-uB%~tID zEr8QX;gJv3w`OEaN6b>C2ByFW=I@xMv0ifkSYgfnLw@Pb=_iG>@P#KLX2d7iwv*S1 z0z`oT1qdc60HFVXL4pepE*!{^j6H@76;7l`5P-pl69Hu8_|YIjg#V-<#AvZ$0ssL- zvNWjRU#pH%{*gMUGNeb09ucYpKpw)E*gu zCROgN=u_vxBqTdN?6?%|!mJF#;uLwbAj*q!E+F|SWxyuS9yFWzY1o^60kfqG zw&2u;OC9?}`g*Wmww`xh-b^`mZr+FS=04lHGt$EwT@JOKl(F-~+qrl5{vCYyr2vw& zDqxEgO920y{w>_Xn2b$=q--H1rL|*3f@C%o08*fp`U+@=p;qic$d+~@LXRN{;5)DY zU*sFmJPH1BkRStvqDcy&5^Be%B!21dJbV7J$CkAuK=Gdh8JzEzBv_Mzz?uG$kv$+f zvd}>Xlfur!0)8O{p;8V!D@LL0k*T#-6r8W3q{bpK!K6@3h^({zF=&e816mYCS{a=eYUXeTKt zTKR7h7fBR~%zxs;v$)oT`ti9%3$SO+O@DN6PEZ*l6Gaje_-70A3V5#|`j#wd)2049 zG%5f32uh-jIYB(g(GFXrbqf}4amN-f0g#}b6v@!B04XHOinUGJ*d)+alqJs<6gf#i zM_DD{q`fswQg0;yiv7h@@(g6x*>sCdup|U$O*2Up^|hs>AQGt5l@51p<(@G|Bxs<_ z&QfnH*qCx^B_Lc1q97TYBS>O`fN> zSgww1B?z+T3i^*`lgC3@BHBn1xc4lz%osXhr{< zR+K5o^AJ}!fh997peBNfeXm$D5K6O^EdrlZ-~s|)=pQ8#*n*^JZ(K;%j%<-BiF%tN z-NDf#YDEe%IvkxnQnuKn^O}09l_di!dNcu73z%ZW)h%y&A%z0W$R>My^fLh|6taoH z{^Uc~z@Dg0fIxc^7^~j(+M|ecMAIbWz4pu`sKX#mq`lDh$k-CE)el;q(DN1Y(>ZuC zo_h!q6!QF|9hy6lk4$C~o8X0X29dxPie;XVkWP1L`V~t!IF!2$WePEIl%&gfC_6nIRd&mw|`|F9VTShh5TuqXW?B%99 zn3Es%Qek~l=Q`OL9&^SiKSKORn?!ZLI*BT9i26~QmVz($A!uX)Itc%Yyd;HR5NM$7 ziAhgd^dFi$&_W$@($ZGts*a2WZmX(OYwo9#gNceJTM!B9L!>#e zXN(Cl-JjBQy(FE*LLx1Ih_tXO^qh{M(K_ftfM5&A$!Ap}J>Z0lmpLq1bczIt371H? zs^uktUz?(dZ?F?mrgY97Z}dq%qa^_;nANNbNQ)qgQ>LU;sUtN?oRrXd*0Xx)dHH$Z z)=UDYg)j&Jt4oSgE2^>cO{pLxY+Fb23M3wNLUWORxqiG zh>8dv|B)+E&1qYrDoqeACV@Y7WJEwZt5~9i5t=Y6Wst+rLT>*-q>kJ}D>Rt`umtzE zk}0P)c;Tcj-BQk9GE#@HOh5n>LS1f-Q#BUhWOJ08t`0iWI^hKlbMAICu^Ek*!D-;* zAojNNB28)@Ik7w8eE0VTDh+`C}=Rg}5qZ*P`FdGY^mbkpNjOL6u1&|b41w==6#h#mDk7LXO zudriAi}^lAF!!uBX#wYTMwuHUHM7g;g0P()>m@4ohYt-2yRHQncXB zBO71!^21Yr>OOKs`U zLgj^`ZVH4lm0C`>6JV$8v1ehSAlos!`>LrOxL31CS zDB*4B=*~&iLq~>R1>fc&e#X6}0x9mOk}AL&kw<}?AV@@Yb`Z!|C<0t-sHQB29Vcz* zbV(TB>}CJrWf!17+X}320qQ1`@JwdEqrF1ba@@rd1V#6`4~aH!Go|ics9ySyUs3KM zpm?1;4k{K0i`t*U@9088(T|5jloc{{Rz3g7K8UU)2SjDZM=M+)+dW{#HBIA0SHCF9 ze*$o@hbYYa^& zh{nOl>%t&IY0w34)MYSx$>rfDD{6hw{3vQeSW9r6fo`aecObRv4D}V-QyiVs7 zsrn==_?U*l%;ba2OK0XQYl;pI<8V9rLnJcosL*0fXkvM0Wb>*?kYMcCz2ZYNFFCTRawMcmvj(9R+v?4eXn@Z5-E$LllWpbdeCLANh@tlm`VvPQzI>vYb}vOICu?cq8qB;lf@Ek;VcbSIT<~|oQ4SMRF(-m@fI!CVqqfQ;{469{&Te{v$Uo?$bp+*8^sjg# z2PI(Tr4nFs=B5lT#Do9Z!8-$|LxOWOyCimiOgFuRV#EwUVv!7zK-O-mya>$h zjzN@QJrSI=t7o+5K;%#z8ckMn$Vl(bTLbn!vG*n5QriMh>%W1 zo`5J-BTbmnWLiE&f+X!k#;93Rl@Mu*_iR+El4T(fYgE~9EF?mqY~t$7B{th`Wsna{ zXd={fEFq$2Kak>c+T%|eaWp_DEzsq5=HotF1X0p#zRrh=&VospVp?l4T9DO1251$r zgg%7mjx6%U!h%`ON2fr|Rm*W&B`aEP;ln4H zd2FIR?p2c>DR8dsBw{sAAg5j$2TZUk(sr!mKtn|23AAb`$Ve2V)DlqdM|ZZvL$;=C*D7VmAiE1E0d= zP(Q|E*~XOgYjjH};7nC@*=bqE2qm&HA!M&yy+n4$Co^bw_IBc~(BeO8@4zg>tP)2? zK@K~H7bSo%A&?hg%2mOJH#RM)b*#rW&PvG;GaH{{N1F#)6hKoFU}N3~9F3;E%!=Nk zg?s;ZYC2kLTX%(f&7^wJEOv*ld1QAxG_xTnF}@Z;dKJQ7YBveYB6!vCz&=&VepktM zQ!%7>Sobyw$#+zpkbD=0F(jZq{Uaxy$l-EVD3oBgUX=EPqV_mQpEPr$b|rR{a>7Dn zH@U5LPeKaRYK04cgWZ#&W;mM0=#}87N33b)YQepW>UKAX3YIE2VdKJV zesHx)NMneq`pl^W`GQpIH&9;&Yf4vUq9jxqNduqw1TCWqL)CrHqUD0`3csd_$0NcJ z6FZQw1kEO7^b|19B?NP8l9D(yg2Ck7MbR> z^3vj!HI51s29(^ZZ+}MvNtrmdFqq>qm-ZAS7()$Rxd-F&Fh!Y|IXNzw*p+!%1@lZR zo0(2M`Io0zmF31eN{!kw37GW8lAF?VMM*2u*_DeHbGw-eyA+o_tep2EE_2wEdk&v9 z&YruY;TlPqZ^NCHk|$efo#|qq8S&kSnUn;&orAKJ&l#fWSu5%JoeLVFZQ7$pIdT6rqn7su zr*%3!uDGKEnw0fMsJla!ej2DxwSLVoz!pN1+bNknYz;T;s0Bkt0&uUq8YQ}(6KigrW0e8Kf9nko1*18 zJofpnS9+gqBel!AZ(5tQV_UXoTeNB0wr{)WU>mo0o2B!{rdPXEm-&jXTJ{XPw!K!J zBAd6)M$*&%3jl7Xad%kVoWT)D41xL2v2aFUh{4l$Mslx`cIOG&{=4&S6nr2SdDgxalT`Ja8V zod+73V4S8axw^SyF=)JKENKdJ+;fFFynBwL`+Av$_@P_eyw%#cf%pcouX!XP3V6nl zH3bUBK@<3IX24}55MUJ4K^#T_65NEkMqwO8K^&wYdnbZ<7ovj2gJKXu_NGe;RzV!< z99)by2oOLMRv{8VnKh!o%K2|1D)>K?KujhiW_(G1E%^xN5tF`h5tQ zE;0s)*Z9r)@cC#`xqA0$Ot03{Si;{%sOP?(s9!j{I~I}B+S7zyq?3esj*qFl|Rp!O&t z3MRf{09_OifvBbn->O^_5Fr9epZ~@u_agwnH-yhyjwQ5U98jMjTAz7$i1rO42~-~e z?t4e0z(01X_0wh`nqNj*Cki4g0L=W(#R9+e9L)b|T_|=G008~UIfK?Uq$6O8DbkK1 z6hQXwswjd}MgCWq6u^4m6j3$`AOHX;AfZ44f&~&PT&Pe&k^}>#6ck8N;KCphq#R6` zAPE_J2^BCbkR*V@1WFtNkg_ES$po!zJ#;y8WRikgKw2zdaVJloKL-X?NReStpf!i? z1P}md#fnLzN+nt}Vb7)}gF;+-wCPW(1HCd83O1ohfe0)jusX16(6Mc&HidW=E>oTb zu-*;Z7NXGv0U&P73qWw;!#n{`y-PIf(1lIiCXL+Fr)0Kd%VIt((6QNtg$-uTE102P ztD3=%Cd#%oTB}>}LY0j4ZS94AF@M!>M~^#w=Nry0$boG zjyNhv&MFz2 zR3d&K{wNwphY5zrD48HZR+pg_U=Jx>wz9=Yt(X;4oBzmEm@Oa`@QXcUm}Sd9{}e!q zLU7t6MVI!pnUF1c6`+8j1#DuH1or>@(@LKI*kc%7p{;ahrE3Cc=BJh>`kWO1+~X&o zZMG8Ws)#1k=}4uNYKyAbA(km;W6~EJTZ3V$YgC5Kb=R*Z={nY6QqgD{L%t46=3Inb z8ZAYo(IwiYhe0cBwPg0%Eo|Semm80Wfm<56QvOnCg0RlS8cU>PgS*FC{6!nlLZh_jFSl>k%%Koic+YP4HVgklT86YWHF8?knA@K zA_z#bpD55|0to{D1yl1qK_w0J zkn+E5(y(HGCL~1xhVDs55?lO}XGf4;?+`>}{L@ka{}lAn^n(Ub*e?Lm^y)84oH~6F z0c=uf0Vx5I^-i|5lMt=Q`^fi%atnpb3OlXnlSHQXkeJLQB(N!fD-uGAe{3QFo48YK zjzS!$*ybp$QH|74vp@gx6y`rHtIr76gEM~Vk2rOqj96r7!V?0lD#MwMif(8Y4_e1A zl%Y=mP$(6E0bw~7IbvZV^DeB=FIx#wVz2aPmSPDnTLU5DLjF@2`WYk$3V8_fHnO~z zq-=}^30Ox2lYoIOuZ;s!VqSD6!w+_6Gak%Z$uw845N1V=z(JvBvi6((VTL}q5#$GZ z1{u|)g**lUPok(Jo1Oh6GNySUXvEW(vh0L1yLq7x35mz?K!rXPK_YOh5=5k6a)_P5 zp&@5!8SbDbgl|cUQe-I{^VIN;R|}>vhuI$H^yEuU$`DU7v5px9X+azTo7pmSATa?! z3z2{VQ%a(l?(_7Nf5^-GPm08j@S{+56+j!~K!S#{p$=<~0(gmuAV)fc&xEl{0@`zE z0c?RLo>VX)?LZVnX2qpntf@?G49!0VB^r=UA(ETyQ(na9FFc8c3*xJoyNHs~tzc?J z>;u@*{A7#0RIosJX+V+_rYG-C``y;sDE0HJ=p%@=os7Z7~!rb^v zI&n-0MC}DIA|fM+_g)16smq*6q9Bg11t1Bd&_?9i%i(bBcX3<8hA6VJVMstEY>!K4 zH~^Qh0^hfdy33H{Kt~uFCIrPt)Yx^BU_mYkMJEu+$w5duIsn9^V)j^*wftnJJ>8Tr zJRbj)W1PnnpC%wq3i-#Mnqt3_)D^je$zGqXC!8(Z1Caobfd9zX4zjeO&01t?X2M4& zI-!OPV_8#hp7NXM+{P_{9?c+ob{<7nD68Y$#qv-z%5p7UBGyaS7!thI zamriyJX`G6a!kePjk0~GYLot zImQuyByDKob>RS#d@)g&C=@A05@>j?2ck}iE=fp$V-aT=@}-WBmQc|%$R?(D3sOWT zdrgt5XrwAE@trGyYa$g*Ap)uCDdZk_hR83_bY)IVuO&+R2*z@&5Gf=OQCII%k0eD9 zQnZREZ8{nC+Pn}>%v1^t9CFm{cSu>@b&$RRa}xvGT6L8yQj197ZiVgFjiaSEDE6^b~S8I;VmsgO8S<73dkPqb`-?}Bs~*h znj-~TfN*mI2>~DlBL+B&qXn9?33t;J0=8d(p<1nB66d8q1$JQK@M4JfPJuCFYcx1o zFb-KzIRQXnXOjS$Fk%IOgC)2`Q7{U0<2k@132FlonqY%Dwt+sw6aipgniBw_APyB6 z0T)GM1#m^Xg<|jYMQ$`MI+0I3mQq%sDk~LuM%F5Y;ZsVLRB6UjR+0Y%zc46Fab=sp z5mx3?Jh264hg2^lG5?1`Ein+;QxHLRW<`-fLP0AiBvq^7cbV}jB(VhpVTS(`DjWm= zTvRkDgh;G`OT2_M)G>-o!yP@-dds36BLQ4Vgd9n98rD%){bm%eBveYVNB#mvl!YC0 z!HWstMXD$&_q7_r7%k8zeo7@-Ng!y$@krh#73szx*8xPAv_+rcV|8_3+PE9_1|BOk z66sYju69Dvw2YZ2R?+wzmlTL?(KGypi!RfBqgZ{mW<#@xY|k-{D$+yMI3_RDLW+hf zC4^>NQ5T++irrOd?G`n$bY1>fX{4BrtJIGIfnUky9f8O&$OiwAl(vZo7-;LbfFxOx zz&Bj3LQzf9QCH$Ntb+tVun7aAk{AL29bzH*ks?E6BH54$<^miVR~Tj^Q8Cga?iD6T zFa~WCAsV%r`qCJ@n9%v9-lMR_; zZv|kacw?mRRHR%pHV2Uf+90KGqdyvWrCgIaOxpjGnLs!GQfhZ~W5zRu2_raGAq8~u z3$1Whoswjs(F$myKcvtGnUVx;U?^n6{)Szj4ZPWcIIU{v36v@C@56`?rlVroz5T8dE$D6JXYuig1@Qm7>mfxGn-D43v@?5Xe#?s4_`DaP5MUHVH33!3 zd%X-}z3m~qgbmM%xawQA*r~qNySw7s zisTi(61%-rb4EBzOc}Yk?kP;{`@aaRz*I9x`rE$bmB0_IZxXzUq6@srI>4~I!5myf z(i>j-*})==G(gKQ8aKiyoWd!rp7X21#ngIv>%uZT!!%sOHhjZ447Cf`!a3Z-8JxcR z>%%2k!R^tr34s6);lDz>#7x}84J@-x9K}*R#Z+9yR(!=+Jj2FI#97?MUi`%dEM6ZB z#$;T^W_-qIoW^QQ!~W_Ujm7`97%YwqY%fX-#QbYD`8&NuM7z@KW#2o#>cPW093Occ zMw2nZ!&t~8ys^Q=#pPSKj+_+OTQ!=~9+S)-ImQrP6v+x$$Ji(zSy8>5>&YlO#%tWj zi*XX9%)Ld7Z=5V2YHP}We9B*3!aFO=s5`r=xLd@Rz3(ZryBxYHiUe9PBa>Ufj{CKW z3(H*`!wLAxx!k}BK#3$Ny9yY2@WCDW#%b6rOm1v7oR+z^%z$$Y!LwUTP`oT~ytNdw z7J~eI-|WruF~9g1#~N(M6!XT}48hD7#M^tnK3mS{Ji&)d%P;$|&tZboXSkH7uF#19 zh^I-tkr{{=30lAqQXu~c87;9up)Za`8hqNzrZF%F5nqy^1(HC!5upXiBOBm>V`hb{ zhDax!5;Dl)iqzIfAgir0EV7LRk3Lh6Tvt&J5A6A zyeH=K#G2d@B(c@ir3BYw$d@e1T&=g0oB-1^wF8k6cghJ@t;rcdyAmOf7uGAJP`0S? zJEfk!oz-HG-W9=S(SQDGj)(Wu&@zW53jmdbuRuX}| zH=zW8s{|t9)|w4RM!gWD%@LJN+77XK7*pB?aoXZ*wTpR#@ zsSvSJDW5tO38ds4VL?bCs(iwS1fk=kN!nW0r!%!0Qt%5?p4d52DYigUW|2L}VwiE_ z$M&=13W5LTwveqn(Pd;&29d&dmg*Z#UMOtx=BjHZxte7qg&QG-Kbw+dF2l>D^5v1e zD)xY?D^e+ya@B5*ssSKo|1haM!DBie=y5LMWP#?eT0wkL*Q`NOUVCJ)K_`5&6SQB$G%Cbvg4!E>|%Zru|nn?QJJ!yWsf>KbTU0^D+M|Z?%r)RP#qYSM@T{x zR}LF6P^dE_C`Y?tf&zwK4Qm%NiUe~CIyr`L`_ZLQbVEwDTH4XG^f(=%jBqgqT=A<3 z?-l<%f{|l@;f0F9g~!R~3W(A_#J5J#y@o+hb)5Jf*O3&VNfYI!)6_!jj0`vT z`_Z#KD^nl^wwyuk^A8mMckFl&;R6#Y&1cF3+h9wCQO5k4)EK<2|!$Xb~TPWNp% z<`R%VP-SOALG$}dhm-23bpleZAQ6#LAasZ()tf!ngPVP*WfG7BgN@ImL~w15Y0mpkuK#`ONXtH5p;48Aa(z$ zkRlUg7^qzyDx`8fq=G2SUg5_N{NlqBel0y&-Vp!L2AiKJ4IWhX!|8{J-5m}nc0@9n!W$QW4DU<(69XV!2AGFpg@3sqy!2~(CXhm zTL%kBDVSi&zg7ab{M#aB%O(i|fjs=TNnn5iT{-0G@aDly|Lpye0>I(H1SfHl`epB*l%-1%;IwBeNy2|gs(u96GLj%kpjLir$)U;^Jjj-c z>?s4R8Hp-jsM^R#;3k6vYVSvbc04GF7@bUD6EgB6tUoBpkf}$uHZcDvMWVJKuf>A^ zxbL*KD%#?w+Ai{{p@TxSh0Q%l`3C?a0q|~%HaKER&{l{npcPvx`=u2#1;SFGI0^ly zHiEVoDgp8&_=gNgNdbVu+LXfRAV60dh(e8Y?D3+G0Dwpd0HCU^08pKriB$kL(Nm`L zWOC`&OdD;8q>EA%Pd$h3JE&LmT9F_|TYV%`DO*UbjY1cfioj4O18hUVR$OXQ#{_N} zrLPsYkiZ@?}3^y%u+FzpuN;NIN{{}p8!M`FDfXO5qMVxRl$wnPo4(e9Jd^baTLdVas+^&EPwz+3qbTxJ{LzFY_5u8oXIDT00>VJ zkYp7|PREI@OvZ^q_u4dZJRHptIkoV@lUOGkB*Ym7ku26JUK86X&n5vNM2UUz@K5&? zeD4LSeR9P|fkY{iQeSKJ0BV=c)9*eUX{}J@Y{QaiTe~1vVU+PF&?9cRFZ-dcQmR1|L6#x?sJr!dF&TKFj9|fv%198CS(Qp z1-Ghl3zt!_07c}RLnQVPpG3tcvnonfLe;8Pgp7k5V#q;U@eu&bL{%0UpuzqTsh22) zR6!t5Q~u$`TkxoZ2_VHSs#qI^{DMb>AyWcEb{eS+@F)0^Rs6`4MMBNQ7C4>s2`6hL&l#7bt37_O9sEgS8K>k)HD(J? zSvg9{yeX?Y8Ko8!`N~Z2ClIK_#34W0C$cP65&opgK3$rSLok?;4;jfKdmJZDvZyzz z_!B+$kV1-jbda9)Cn^z~08c=$zY#laaSt+)kG+C!Wu0h?lFh*YM8HJcX2Zi9nsT;(eNxFLlJCy-c0HmU;|0HkI$m=OnS zw(uArL_v9y$pm+xfQZCFp|FsM9wd+u1!_hB2@yyFW($Cs#Z8BD0?EcGpnwFtc4suD zu}oqjfj!!6CmWIlUnT^C1nr!UHQEpbV4;xM!afcOP{_tQR--G*Eewr|HH5KHO2@JAt1Sz`(#B21ta09wD=+t2FhmA4IKMG66!%eH2Z4PR0wNED_~ zj6xtgBke~W>1B!nY!NIkEGqbPslfilw<#sr$`$Eg$tbkWHBt#frN$z+2xjUZIVpwb zx>tcPARR}SlpJ6>jJd+2bdx{#x3KVBvFXUPmQS`e5 z@aA7ET(RpsY{UB(cFY(l1U#dyXw4i?G~3a0?5 zohT5|-2zZ23y6qgBk!B@OeMS-@Z8VBSOKoTi9PH~gloak~}D)1oy z2{Ye|Z%-u&_Q527Ss)(j3Q)V^5Iq|RKpyNACvr__0}79W1a***iFI(Uc9tW_%%%R4 z0GRJ1NeG2Fiih>GA0!C3$rW2fhaAc@uj5q&6_3|EF_H_4RD{}EDn-SXbB!#AYXM|d zsWhXi!l@!{teTZKsi0hDl`SFvLWo0Fx0Ofck5M{13BdZYg?l6*2oHG(o>iZdf+7T% zB!NmUm0(9$qKJmChe$glF#8`m@AELUrz2t)&wSwW99aioL)$SQ<6h!pIWHlm16p$R3lCa>s;qnHwl$O@A3r!V9&WTLVb z6o?0s7pU-`L)!w~86cnviTG=?RI`aq`-nlag%oMRCV4|UGs58eHcNUhtWuldb0{f5 z3MsTHsPKx$8<|FgHwECKHqaOZdP1ex6<|uh(8H=IbQvDXmTFo*q|h3XxtIj#vZX?_ zrVtoy+K(?JDk6**APf?ckRhCUC>C2PJLx;GLceZlMBwX+gBzDx!Z9g0Dfk+sA87@P z+PGa+m z1$Y`GA5q1b1R%F0j5_&_l*Go{01xcQ5?+#up)eA*u#c6H3brK50^p*C@Ch$#HXi}P z@$jRDaInPxAS$c0iMEiIWD~cb{3nRhm90?-Qlkom`wBq037K*lPAmmiP>3Poq}r&J zfjJkcxRyZ?&b=9lA?uGEYB*^HhqNsFx%-7c~sM0D>6gMDxH+nKSu3#iRi5P&vns6(MTyZ>$3D3?1 ziC~hM0Ch|J;mcKIJ_iE{$xM=>;Y#s*%|LsJT(OBm>j>L)A*hkU!JN2`D7T`~&}gv} znenqsahP%wu)gsogp;lZ1qz2iI4x9@0JsRi1Q-e@9X%C=On5F)fQFJ&hxP%vaj=~JfH^Wf zl>#U_P-;7INP@`OoHq%^{Gp#O)s*6^qT7&{__+-#$`bgxrbGf5d%#4tIKZ{oB$22; z?sQ7nOA!DFl7>;3c!|GXxCuDDMv7rCB?OOwAh|wTi!XdA{8=&h!-@Yw(v{d6(sRiw zx(IaP#G=rmi$Mq~ay?Ep3#H%@6;cyP1dHy9!tP?LA6?hccq6tvw+q{kt*9}#1c2}V zgCCihllJ=+?%TP<43oEdAO3hfk0CTZ6P2^srhXHZHj}VmDT5cOv0pf+RC0;^sYThV z3`nHRxnYp^gFao&5KvK*1vM5S6O#7A"(t;mQ{v6qs87aVo9B)A2Ou`{3g!$}Oo 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
    1. 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 z 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

      -7*`qW|ke%WgkuklyS~SkfuT;pC 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

      T-bl~mLwg0o-b^dAN{tT`C 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

      lk% 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 &C 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%0Dvv_{*n6iuV;Z)wptZvSKyz7B)04w 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%0D}?|G>82Wtm6(MfPdI_8o(4Gh|yW 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%0AWGPk90Rbp*=Y_Qr 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 WnA9v{|7l$At zD~!m|O|(hg?xki1a&e0~^K=~<4cgM=bp$u7j@nYCQgiC%t&m)bG_eN@9Mjv4^aFy?U~r`^OAK zdDJC{Ub=FOOF*K#xS!p;6V7caME8RDup*ivu}8djDZMItmx9T-R4m#cg>RI%xx);K zx2L;9(8Jx*?j$okOgLk`n4MZ+C&46-3H!rf6r%%sJi7JT>m*$}BVbF^S-o90f zj{AECH`_WS+gA$>PbUB239F`8yFrsot|I!2r~BdiXmd0epuIhGqzH{ew04}$z>E;Z zVk?U)a@@2nAzeojXo423ZLr$K#1uDx)#<LOm0lWkCP-uenM**iKfF^80 zCWwMg7AizYA zNm>O6P;ll(g#iD843uE8001ff{GZBo^ zM0nv$B;!Oe_V~9Tf=%JVse?vSlsL>$fYc03nP30_rV{`_idFDIs2_cL_FO=6WlifK zwKfQ4+~Tnb?X?1;ab_EP0D^}F(rTd1vA+`rNb+x!gnupzADk{_%0IVBXF}(Ta5&LY zw+h&5rTc0-TLpfN9Di6UCo=8+?LFBli1vR{tjmj`pOVKOpqvGtAaX0VwFq?<4U!I5CB38aWY{Nl69i^2(^?_TZ+b>Y>dt-Ad<*N93(^( zaSJGwn$Jojfu!i8f3{$alwZYR3X=;qFK1$Hz5?#qVml9^vQ7#D1)YjL zf?BikAW1!hl*pm5(x?@8KoUwqS6WHH9{DCT>d#2sEMNS=qHF8 z6x64G`onanKzR(dfK3_al=g%O!4;Y_kY;^Zb}>I`U%wSgj&RW@#jx5Y|3%APF_BEudBg(^sjR@z|> zQc|FvX^TxRDx;Nu+G(Q|s84dQ6$wu3X_Hoh<7o?0%4kOdQf!d|0K&Gg#U3*Dnr@Q> zuDdD;TiRhNiC?%oa4Ee1F6i!pVA>0BcL29C2{PQV1#BYmZU^lZ;nrI6R@7^*C%o$< z>7bDR(j%3WR!B);6TdsUI&OouaIbcPf@s6?DGb`=mtG6Fx}9G_3Ux)se^MNArU=~P z9;75do$CWHy3g~1HX%a_S0bleYSRgl8YEZvvd&wZkQb7?gamUc{%yy-Yufz5ix$Oc|_NP!s*wn+-& z*q}Jj1OOvpCNqmc!YINa8_Yn;G^Y7W0A84x%!nftJ&D9BSf~zjrRGUdLP`LB7>OVy z00^T%p$5eP1*O0xH4-3L6QdZ3bszx=+E_;nV@Re*_$wUPP)BBfKo@O@BaK3e1S`P* zh{A^5q$g~;SVQUsCpk4pJ+S#nEAI23H<1E1s3XYi>|u-9>CIK1v&DZ1LM%Yq!#e;V z#Xsg09DC3S00trjDH3Ure{f+tSTT?utp+DX38@s+8Jkc#$t!{ws5xVsT~G@0$TD1# z6g8pb+x|g@()^+wWEfj>L}iPCl$yeGUS$~w;KWbv2 zRuGF-dV<=UKBtjYAw>$1qg|*zVx29lQk_6yq(*)s1p@^ko|J@KC4umdzwz=Tt&Gnr z3v!E5jV(^A<6}EmqXa=BkfQkm*IoW(qW8&9AyAphMw_Lqi;{(a{38)kK+328wN!K= zbcvtTD>kqMbqP~X|ZdfiM&@5HA1z~dk;d2ey1k}W5 z5C!~$n+8!&LCR;y0{GSJ)5gu?A*NRfCCJAMbNO0%Gld)-pL3z2P zMJ`#(awceXtW{O*&Wn&tcCCM5*`G*R`k|7Bn8X$uX^Bycp#!RvLs&VnG*hh6wv}c{ z0YJnmdbZO594!->h=db2W*R9(LK8DYKsLsKgpVYEOm+Ox9ZPsdDUa1iJtN2(!Gyw0 zFbpzEPR*GzQ9*+IFbZG^z?75-04qkuiBjGn5;E~J7-AyMKo}S%dIAYnD3KsxluH7{ zF$#JSM1x9J)mS+iofo!=A@%axH9Z8E@)bb4w;-gDhD#9q?ua`78Qrex`p7!BU0 zfefDf2!qZxk$4uWAgEO5)DE&LI&#ZY1u<4n7{xk*#A+bMfmC-)b4l@Dt#Hj{@gX>Lmw{4Ow>fQ3i{snGCr97wWZ z0Xh?oY?M)A$;)^Q^>tQpB%!}qg-m9XkO^pD0uq>jMp7TcG?$430rB!oI6{F9O(4OB zn(&wk4H7cYXhf)>sn;kB8;MLnLgg->R~Dd@4W8wz0Gd$$N7CjxuZ!dhs{~;TTIbst zBoIatxUm*yVGKZ7_qHJSgAdqDvx!^KD{`8uS{}=*ntKQ{P#;M)q_PH*b_~lFYG&2q zvX-^88KmS?0q!GzvE1Cs+9Jj)Ijs#cr;ubVxGAQUNy|b7MJWJutPN#5a6d3J_mMSt3KsAscOF9Wk z06;{LXcaEz%+>)&VnY=81TgBziIz?U3*bpG;V+VC$q0tU5iwI&25KTes zDA5=Kl^SAHybaqFsgSOz)JBIO;=@W7WxGI&kVt`jq{g|->D?G&3b?=~maLWNr8|a# zmar+eq|0q`MJc2}BS7g-jz}pM$4)Gz)F5sBSOonf%3R=!?^x_3xL{8TU{BD=l(3C= z25}>H?I=K^wtAvFQbXKiZ6e?XQnuh18j+K@@ViRH``XVePzo(Hk=|CUQao`JttEjl z>O-ETq}U=nC?XW8MJZk?Tw)O+9xk>RLJ8>q5B)}iGExpo5P^w4Vy=uT3PxcRj;dd< zAqqC(t_nb?0*kH?V-)gbt7yaiP{ZUzVTsVHGqeB^LMAejhhL^K3NAtl_ytNJVIm%* zVE9EHuz@uw!!aNO64vpk3Q!!nsxyYJgu>ycC`Sq;K_3mK83~5SD(mdj3Rt?rHSmi> z#%3a{1D0ChxoiuUgyanqAP8z=A_w9pJ_mPP1!~NO@E)R^KvD^T5FviT4;kWcJ|{x9 zYYRn1zoug(mg7LILzog^c?iQJ(`Uj!uP2gYSZ;xl`UsE41`j8teYi`09@2JuKkW?BY0Uik`Y=NH&UIKAP|772t&yjqpRR$Z)9^gxXRGFBunIK zO4G$6y40%%?INO-tD?^$kRVDcgR73}Eh273j7}*eV@##b4Ver|DJKEolu&_Dt0JN1 zzI6LA%lvL)!yW}EBw(HxV<~nGMU((8Bti-VL?Gr#J9aJfa1kQ}!YIDRK=A?>H=;ng zl6R_OI(r2Glwj8sfHfxn)llAo*;-XPCE&caQlGRyMLxnG$Uw{%LZ75S1GE4;>SY6b z)fPQfwe*R2I28@&2_in#R_4iDAfgn7M4wh-f^Ic%u)`!I=UE#DJ)Jr!~( z%`ahR6k)YOV!7}KZK6QxQ2Q?BRD5qJS_M`5?N@vyE+_(6{>NYoDAJaaJ-B68*i$(@ zO%!1kW_2ZH`-I?j)FDLH7XM^of0kzz;(`nXDjL=*mR2nYHeR8YK9aOO@8ZRfG$Ymz zkMPo4{!LpjaCBw) z$HkzQE$$8A+BQ{84{IIbcXc%2Dr9z9SH&dPb;H75Ba?cw0(vi&c}JHE?Xq^U_j|Jz z;>PcD`Db6l_d;4Xef5=Ti`4NBcSE$7eQES!tp$9Qmww$>aTV8UZ+CjRwnuZ<7Sm35 z#}|9?_kJ_~_AVr3emm-a)dF0=Hi4bie)Y28a93XM@?Y~eENrS4PvU5^Vttz>a9K)6 z`iFv}1%0=Vgweu<^;d(N*HYRrLn79EGxmnh55-h?gk$)J-SvX0w+%D|Fl~Z^DVKPG zI9znwRUQiIPC;OH?#Hw>jS4!DZDmz|ndJ|zdct@I! zM|*1pE}OL@Etat1@<$x*LW&TmzN}&uIwU#13@f4LmpWo&HR3&3 zi&PFs137a^9IZi!rJ)pnMDyk%^23r`!SE!YEQzH-km)b*rfpI~Jq5}Zxzv zBz)UT#I{ogkw(N%e!gkaY=IMCV|Ip{l3b%dsY9b@$&wZHX-;E0^xGbi10pN`xx1z2 zqpxC4X7hGvMA*vuqv4st%d|$stcLL1;z5{U!i@Le`Y2)Q-ntst~->V^I=` zF<6vXL_C?&b`qwkOCyR$wAc zJT;h*wE&XMiLsKOEH9T+W5FQ>u`AN6GxADwBmgKp08u@$(WR1E{i{d+qqNClTDrM! zOB{0X4Vq~kbs3_?c{eFgn{!nGYLfV9~w4!U%WfPry z!k3CQL+ymm1AquGq9bG*ymzXenj>)jAyf6_&pBZxH|IFg{3G(|GA-#n#=<~i3lGH& zby6Y{8^hlTf_!L9v73ugmaMfd?cOo1@cx1f+_{fFBEuZdkm8BCOG$DjD&r-6y&;7Y z?%^Qf!!(Za!pqnzIXt#FykY-35a7 zCp?w>_!S!vXF|f41mNEy@WPWizJ^wqTgO!8qW9z{;@cj?b_+t{yzmA?SE=%mfIum&?ERAhpnxs^QV9W&vL(8G9cKkor}CWdRBQBux2NAV5%!Lo)^- zn(%1Ci~@}o$O!eNPKr~XO5G^5rq-B+ zBG}qC?A*G1>%Q$<;4a{gZSxM+`Zwp-yh0IW&<+ib5D#ebUw0+4cXWl?)uawZJ&i($fcvITk+xbP!S%B+3+z8!Pt zzur8h2vk`+i7k5)v~w@;6Qz=02%FDjz47?K0@f%0vb5DMVL_HRH*d97ynyV~FDWJf zvXKPVMI;*lv9SgKeyq6?A8VT&cVI$f)J7K&5@cnWe?3*CQh8GRGet$4;PhBd=P8C9 zDXmOoTXWAj*J49DAqb;wi@g|{TsfAw)r^>ZmD!F$4oPH@M#AM7XN(<5S7}T>Ntb<4 zBF5K}dQFKJmVJezC0z;FVv7`Hv_hMFyeUDFM@Es^%28M)$eR?*xweHAt_@h`OT;~8 zk1a`TLDOda9Yv@{_K>%QE8q!q%bDA$Wzb2HLTBHHy|E|3om)uR4tu|}v(Xm+kdXwN z>yaWsZ8UL3p-lyVYE@KNiMoY=(+O3|sHOh@Q=q7%NFgePWc)))62o4)7IS3oG?9G? zxddsLfa)eisrE=Ag#rU*I#3V|iFz$Xg&HMQp)Rr}6rn>EsxDWBUKV7K6(zajTS=x1 zR%A)qyB58i#Ve%0{({6&VguJSmz7;ghVR1i0%@dB3imZJUD__p*S!=4@gx!$e;ia; zT#igun-G<#!UKNNFf2 zB-F8`CSIwXSk5=E=lxBD{el?rJa`xkx~qb2$%^iV7cvwQ$!&nCSOtl~qu9}qFF*hx z_Hw1S)gg>3WH|~&cKExr+^Bp1sxu5@5MaY43S@^Pv<(mrcf7gCFf?9?qCiGeHH@80 zihy|^SE^?~)v=IbU2@V|wg?w5LPm~jtRoDkhckbgA{p9=4|LG<~>j)bI3kP?%U zmuUr#_v=xYs&cRnLd=71N~4$jcNRFd1%oTH&RZC1!u}Ocu5V^{8aMWE|aMRDt@l zF{}*BJfYe;ZoZYN*TW#dT-Qs+Ofxb|<%>``Q&b7=l$!&BOkdY>n>uZ3GFzyVW9~G% z!4gq)gQ4tVl3BY}^yZHf3!G(uB_}L$kaJnlh-kqx1vx>FBU>nrfW~sQRY7xutDI_C zA$U{C-d3&n+-q6?5gJqy0xvIzjZ00HnOAk*G9?sghi+sD%7V14u=@FhLDI$%Qt$>Z zI2@vl9(uZ~(Di>1P2luIS+J>Ws+=F9?qvXwJc`(CC*1{!X_?}m`*O&-yxK}^a^jk; z1TAxwedmyhi`Fvk*1J$bFc-bpV0Aav2p=hBt!f_|i>>6DsEV_Zb7B;ghesUCcPv6=WOhAfAZ z-&`KjRrW+@CIw8Xg#%{bZ|1a*#k5^*M`@PhPD!^?l%Z}Vo8hR21);!gsAQ7#<(i~f zAfvFKnxp*xFFUW8NZDjfhg{ShtFc5QVzQ16`4^y=$WJ94!PXX(U@s{oAPHQM^z=3( zX-OM!Q2o&e7pCw_1ptdF8mUu@x3CH8bO&9CO8@{J%Mt-?Dgj#{6;+}aYboGIKzp7S zQJ|tZo*-+z8i_)$DN-kdAP!kM5mkmV0w`cBMhas{+n{M(r{~FoLk_VBcM@W@nY7F!N@-x=tPAy!ze*su zoA{Ck*qUE>OCa|k!;M>^6B4l~0ju&z%TU4^;*k6{1+aFraSl0_;HD&_LN?C%HXsB& zM6?y}jZkKiajvn)W-Jm)L2M>?4J#g`i*LN+A1{!=YN_EIF?d)qu@=mKjM+vKMezI# zE&bFzXvMM4W>owY3bDjKN0Goi5b~yHS=%c=DQcfK(;Mq3!BquN)MgtJm7D~JC2cA| zZbW`2-hV=2UGJI~JH_{#Hs5bs4?m4}Jw0e_?qbgGQkN za5dpEVNrwHqz)cfB>5s5tE}h z*3%&qhams46t|ZV&Cy;75Cqj>6=V{83ITR1!6L(Q5(xk^1_BWXaz!_GV>yvyR<{~R zmpPwfJggxq(pH5+fgi^44;#>QLm_Nn!5U?-Dl;-7n~@r(R}oymV*RlxX%PhfRMsMU zHx)pT92B930-*#k;WmL7GBZIDBO+!ER$${)VIx=(sR$TxW>`=ni;%Z&EL4k7GJ~V^ z7m}wHFL;3zF>t!&VUlrd1;r7O07x~Vd25s|pjRG%2zIRj5r)??b=XQ0lK>3ZaRbtN zEAfme@fyan5mRsv8FGl(^$W2kg|c#AF=G(1kp!UvclKZq8#jHx_AD{86XMo1{MC;c zF?@1pFH^A^6)`lX#dGBcMbZ-hcXKaya}*@;H8X<}rbmv3;&laie>>NJ1|ojrXn<2- zGkp>=QR51%wsRX|8}Zc?+a)m&319=LI1T8E%cxaJRYLw^W+$j%c*RElXOW8s!;`kS zR>&9^lqYXOVnYhFBfzMWeW5WFl}QD_F)?T)*`P4vz!72w2wZW4bP-NMQjBn+2_2;o z7S|kV#~P++ep5guoQD?M(H&yAgf1~sK%s}Ykpx-sXAxl>i+F_rKrX=6kYaLsQYLBh zXdh8iAkC4M1yBk>m>%B|XaJ&-vE&=(f{cbv=@`i$;l^*{O@#sU@MtB&)C^*#Kr2}#0kq}(4A;M-JXyw?%tTBC5Q3_MDGP+?KqM~g7ha%oKlb*OL10_56##350Q)0xFMsl5SRf4pbK}%^$ zJHirjSypYad)!$QWw|3~Nv4n?W_ytUFj^9=Fd*%al03R9qEZ005feco8|rZ>wZSG6 zVjL>MHj-!)W5O$BFf)G!AXP|qJ$H{W@)UwWcEK?$$Oi!bY;qG}lquFl2Bbi02Us;M z5vf%egzPaaHb-(zXG8)qVy!?S)?o{r01?)Ks)rK*35hPLF%g|Y6Rcny{SyG2uq>$3 zAJ7LkK|u;+;9R6o1{5M2W#Ah25KF{TstGY3L*rawlzgU03Z*b0!0Cx40jQ<7shUa( z+A<%hkvwT?rHuDc1v#Dngo305i#fSXHl#4~%C2I{8TdLRN*Ox}<&>eJj1@7k!E=_8 z5ektJmWYH*+CidWA|cPQ1u!ZUaETvYS{4D&2Ax6>1JVYq@H0|V98d;?EJ8LbLN;pB z3N7ZJs%jH}vZB(1Ysm*6ocbonx)4m^u(ENYvEm;8_L8f@fjF`Oqd`=d=S6D_q8^1s zU8bcjL#Gr9#D+HaARiG#CyR1%dg}#gRKDb2XG$d?XiRd78<_5{A5GoW#P#Ru3jkN2S97H^0e?fyi4L*UO6J zlv{CZ$cOyITJpRLg~(?-TlI@vkZgkga(rN9{K$tQ_ms;V;fwOSy&dI_CJbX`XkQ@8U0g*M6T_q= z^g9!#lwv$6-y@WPMK(Ez;RzDi{k8HIIHOI}$u#kGu1Pz=lm zFeeQq;p7>T(Tt!0o*)AWaiI;NQGfuT1lm^soN#z5(kh$L3hE&g&dP>T^Btn$|7w^95X|s zZTGRHq7#Dp)T|MQ@pB8UKprvzmu|WR5*QT16ab{K0lKDH*DyLuq4IkFwUQEHT?9rE?w}fn z@(_ae5Pk9x%7&r;L@_SsF%38o!vlPVd+#cE@{**B<>XK;+k3AL6)AXN^I5D z3}d#8+UcAnX?-KTBRF=NV@y~w4p1?Aqv9ZCLgy4GLPM7x-P)fOL9)&9hRxw@ zt--pjqBzQ9e64UX0T?UY1pt#-lhNX5pAxYwL7akPAEamzJ413;H&QsF-rWfYy$PryUc^%@=86x#D^Q0O?n&i_@B5NY@ol zk2gz&WC9;@EoJByklw-xut^l>(U&*6{C$b;d_p4s&;~spK|HY?Y4Q{nClt&n5Ux-X z7-tXv*H1ZpOQI|n6m(tqdI;k$7P?p@|1T~}Auc+WC0g!pfct-S6$20f3JfGz&|pD< z2NND-*wEoah!G`Dq*xFD#f23wR^-TW;l_?3MHT=;vE)dUDOIjy+0y09ksw_LVVFdu z1eh)rj6At=O3s5aQ3^dMj$k;6Mu`p_l~ZVf0tq-x0g#~Tzbyp<0I;iVfJ|;-`tX8f6 zbc6o|zSa0};R6AeCTO~Na^zqW3O`=GdE9|ekC&z%T>J3r3;hBmU*0@NsOQzMf0>@) zQjs7tj+~FMB?9*O^^bHP(S3j5R;q75pa3LLq>P|ZNsEX=E5O10Amqp>j^HDRwX#V0 z$0o1}D{CNI+PR1e%?SDjC*{6M;+MOGgKtIHIwYfj%t!-3!%fQCNV)>DQXmKv2g*wd z0FuBkxXFGgYbyXYQ46e#roif=R(?sM$y=bD;vT4GgsMi6aJ!I{f$-X}0C%heK+1Lo z;)2Gn$Q;O?G6-s=%`$%}g{>WNgHp%a#0<2dKg;wpwnG0@RL~F01k}+*x3b9p#YUNQ z$in$7Ja8gSH?_}GP(u}UR8mVdl|2Jn8c?ED$xHRrfhdG^R)$)2=pV8QAVnanNc_j1 zRtEZQpd4kh=hp&YGgL!iA^L|5x@00_F%SEK&Z-`f{RgY`TKT7)Ul+S5fwX9hEUsT| z31F*WSu1hc&NeI(*@1$MDq3u_{VBVDf|cUf)^g>FTD1mZu}s_ca`M=>%JK`lXu^39qgK8sula)gm2iNEggH{23PO$xz@0{~c|s+werEuaER z3eYx60(Ga>-Mt`-^R-xaz|xCrz%bb|Z|a8@f|>dXa{@Xjh@w||`=FH; z-&5?zKQDr-TLM2KqYqktA^=kr+Wd*iCw2bpiaXj-i{ATcf1bhbW)I?)u1*BNk`?M> z{}YHzoD@3b-3EaD%b)k8rawmws1>b%N?zo2Dd~O1asNvZuXtwv!U&ekBB@fL3iHQ8 zjHNJ!7;E9Z8d5_Ue&>BC0h;}==8_%KY(D>?5B&fr9`%54YCbd~OM=J}CW7RNA(UVf z>qn3zq=zO}e91S-zWYu}_7pgCc zqFA}JpNzEHv>l{VvKL|O%)umC{{5QIp`ruL)w3{WDUbkrLe?kN|U!!VFdVQZj*KGSWPHJe4#%lCzWlWQ3az@g^JThrRi=Y?oEc zB?%kFsUPO2oZ2kaIP-%@@qHvE^K2(I`&p_`^3$K>@x=|RhvLQh_5Hf$(J#yA+ zpj~80{3@Eg>Opj(8#SUsdxjo|1k{SFM9F|ideKldvpgp?rTGN95|0iFaCC+vlh3${Xz>sf0>`r1iq&UCBm zk?X8ps?)z3^_y0;qCzRc0fRWURA40tP${dQw00!_u~GHkSMsK-El3DaA(79HA_9by z%I;$B?8#E}1HKre1sR@m;bv?aZ zCqukdfY#g%Jc?!Dq~fapd$2d7DMA@sMxr*`_|+p$0?x?XIxdRXV=Y9y;v_XR7F?}M zG^EjG0Ftn;o27L?pXp&C;CjMv9c&EHVVo8xDy7b5Qe0qP%JB1o-*gubv6QB>NYq}wEbr)j-i zl_8QAudyY?4Mt0LlF&SjiI6Q>d?x@VIrK!<@e(A^4=JRAbO#IeR@YcAPL8QpZ*pXhUl1uQGx~=+-U2iUz_u_|@>&Aq z1lKRQ!!BC@SHK+93P+RdToTX_uo95K8)eBad1*{u`V|!;4TKb_+7m%Gaf^HCbuqHJ z3$_BBF_S@rgH_p}R+t6XzM(E%aix*}J8m)UWN)P0won2x^Ae=c){Da|ZrfOZb(=bF z;TMHbfdthyoG{?!Ld))<4>yv6m}MCoqs z9-$8l$D=}Zs%grerkhHzP$$)s)B8lkiglV!uShlsf(VLuog<>4=muk>7@H{JTjYKX zh-9-FxF_r8Qt+0tUBd;s@7p1hvkWP=Ah&wy-AWH4_sCn38amI&ObrV_5G3YBWRI?2 z;^quU)`D!D=O_V&83>*T<)l_@VY*%7QfwfjBhEp@gOc;C+Qb!rl1NEz-m=N$IKiU7 zr-u{&n1U3({OJb$O2F-av|=3p9R$#o?sNaR#psS@lZE~LS0&rTzgAuDzyHEsifM%u z+JGzi)`)D+GRUS0VtntH=veKL0*-|Bth@^tR#9*0jLk#;Y=V%B^RqhF^)qXgaJ8*+ z5d4#=^4N$>5QzkguY(7V!sihC#pD6tIy*uAq$nqdKe z%vcMFv5C6@y7vo~9SM9@&UHyA9qzHw{rXvxuQuJBSboiz-o(f)R*f z`55Tqu|OdSB{SKUQdo-$?7o|0i%rOtuNacR(2Qw8 zK{Wgyv-_jn6gPb zCBU+@A43pQQL+M=G-;y5Mm(8K!H@n6qh#`}5JNBiIu8}oP|UL@!3;RDie9w0Gr0}4 z!!Hst4g)KblPeutc(Z$%3@NG&%J>t|)2m<+Fw>zEj7d4iL7WO2EkgSru<#ZS)GoeI zonOee>Ou=BBnWnE1rUQWhX8^pu#6HZ1vN6m6v@H&OAjE}v`zSh!B``)xIQyf45;{p z)X^1$v@e~zjUX`pzXt(H3@}V$%Gk;xNwEW*aT7-9gTwv7E6Etm=e0+gnJ+eaFTq^AgyjHk};L<@Q2@B824xm%Wrlblx;V`I>L2TSN z79>VCO0b3)P5k!$Ybr@!K-Cxb~;fuJThA&DWsS9zR> ziw&GO3$7rOD|yJC(3;w42X71um-!Qm1Pk8Sk*)@#0ve6WNC$@>Cl59g*Ld7RHQnh z63zkJzr~W$J)6lURf!4Jij#@}hXBBd3I(-dh^AC6ep*b0|> zzfyqz3J)O&GFb~b@s`kDmh>YBfXGwx-xdk2ZmKmguXgQ8k$~R-tjs%c^ zv}hbUE1j%RjA1E^Bw#qvkT6r7FdEsGMSKV;G19zw4JxshBY6-5N&;Io6ZSKbD>T(m z1sA5w(9K)9&?p7&R1B@bk@ou*Hu9j>`3Dcoj%b@VoVXF*%NAuZKkEDnC&`MuP?o6J z7M;tCn+ub)AU{lkA^v(F`{7M4>LD;9QcaY_O`@#rYODXtL@Odz)o3xSxH#n?uH2$5joxX%_tH(D%*nC*}h0qs8Eb;8N(6PM>0_YH5$33HNImJ#;>?Nf=sse%iEsS zNZ?pXgL_)jbcl!Cmc<-eWQ*LAnOeHVFSFgs1So~M<)DK2GNsEvrAvS>3qn{SCMc~~ z)J@&=LfD2FB@+1DjpEWKLMQc@C&$5-{;*ZIQ4X_{0@1S7io(M9s#Wj+-fMyXiXeb7 z02oC3sF>#X)vBNdQm%j@Xb^cS;pr2@U5l6IbgK5n8R_WT;xTUV{MM8)7dB zPy+VirC;4vK6+G)*&;J(v-2xPciM?_vsC~=A?@7>9L*@-y`ZnsUK4An_z1n*6prQoIg;Ry7f3+_pvfj`Nx9T0FfYFXr&c~ec-A}faK*F3d;@8Lo!CXp7&6# zPKm!#nv{182}!#lC&82H5VOal;P_gK|MjkuxM7XZro=G_i!6weSW({rBnS*TtQbGD zO(g!|KV6aud%CQQAc}}pFS*iS6SiQ7CF3z>k18J6!LlCtlEqweiq!c3LTJ(duC{-G6 z9vYhjVTy>ZXvP^Qt>K)=VU~DL>uQLeC@)(csBz-Wgm~wF8s&JBWo7o|`(TJqMn!%O zXpS;s{b0E>+u&;6q;DQ#oC-33!XECmKPmfWz8abv6X?IpW(icoDK_R{Y0hVzMCDnW<1oGDN){m0J*lXU35kAaur8IC zwhvAo8kx`(d(xwFLh518;FM^(v8FKyCbCdwYQ8=dXYT7X&5u`6XTV-EgqR`$lfQ}Z zQuDycvjz&?9OEF8508$Si=JjIb>Sur<~geDL0Y=94wWx9s#11j@&K<$4s2R!Dtva} zO!jI~v7h&W3X-;&-(-&l;t$0>r-~r#y*8CqS!-&Rr@0pYZM>q*$)d@4I_AP|Zcj<- z19WcZ)F%eCYUu{G^kD3(Q*D*@Y_1jwpn>k#-f0^XqSJ27lz^ejMrqLQW-Ai!S*dL% zOK*y8uj_7V_nsg5eySbP?)xSzZ}RPdS`~b%t?uq?_%>&$<|^Pk#s5yV{WhW?Vj7?# z=lWK$jo$5n(C{R~tkjjC+I(=>=AqV3X`M!B^5&>#&dG^pMAP1n2zO3ZJY@rn8S##6 z6p!%*XKx^m<-zjrf^h6mi?Rn!@TvyI^J?+uuIoNBX^iTlFcv0<#_C>9aF?VkE4R|@ z4hbO7594I<*RF09cZn?5F;cA91fJ4_woNT}@t7w6FHk<`nu$8<-a50^=mzhIO481fL0S9hO^5Xle*s(5iD^@T3({xyg zF7Qd~ju7(9$*xv%bRw@(r(0oSrtyfnW<@t~5yzy_zHmyP6=B969gp?UE^((m58-b0 z$FAx9pqupaU~krEEUVat?)Co;b}+v5@>cUEiaP8zWTV}+*Vy| zr*eY7axp(|I6r%Rp6|8ts89BB+MODYs&&=n`g=ZW2}Wm^LNNtj^CVLFQt$dIyLwTv z@T)d_LYe#*cJ_jp`jjwTQyH@huQG1dnuE~%5U(uL9|+HPh)?rvQ9B6M9&^U$iL7z! zkRW}T$+T?}cB!X`H->#1pZxiG`^1<3M7?HlPdjo@k$fIkiGKff_1KB#50&WWpIMv! z^bMk@^^al?(mp7f2b~QXg2UH?{6~yWuC5okcSBN z&x!n(bE{zqfKX6iAi;tL4y-3_;4b{iUyTf%&2iA$Ak$2bj&Dl;mD9C zCrX4kG08!PDNlAx@-m1)kP2VIR7i6m%bX!``t0};Xwae>OB(grvu09`M4Lj57a&pn{!70U+!eb%MbS6p_MIOBEs9lUO^lEhu3wUy5>3X59O5 z?_Gt0v)a|$cQNC}jvr4&Yf)nV-J+EXe1%-Fa8Aw-Jr|T5_37Wfmo>MHfLbHa(u(K0 z&iEJf>YD>;*N!?i_hivhc}p3X_u%1y!4FQETAX(QoTpizjLnpJ$NOQi2tB7TszRYILDt2Kkp3Y9S89A%-WSsE}Op!Xe4e~+muj2$WmDU{*_=JnUBFWqnfPV)nPmnBHRPKI33}*6i+04PrT`YGkf%*$YSM9^Ru$5f47rpThIt0? z=BRxZb!mJiVRRlsEZO={kyrwn(W(^<+h~&;T}mQOoGOIgYQ3(Mlv!rs25kWzCXmun zyZsu}loDcvQ?~>ayV?Y~aug~-HCBXMoz`ke)tMzRTVbh`!UhP25-bJasr1GF?-`KsP@&5l z$*h{B*2`q^h@#2=$cm?{tI_6G*qIQ*JJrgYO?UFnAVc;hQ8R671%FhLhCZWK@vPoQoA$uTx6>?Tz18wLSgv@uJDmY|S4& zQQHN`iBsei%?~Qm|7*$s-=`G(J>+iEYZ`A{Czgabtalx`7rYo|k^-8qPyZ{x2B&g8 zV*LbE=$>aEMXKAwr&bk|i3AI*YSa4>hxtza@|{f5YGnp|V3RrEq+> zap34uC8?A21dBy`7*8Ct6r416o=xv9B)g;}h06Af!4 zI)#9dA?quc|4*)TOTJhUlajQV6hnBB;Or)tgNj}z8B&*7^6Y`d#M&95qDbmB>zXh$ z%^)>4zUC0pkI^JxQNkiYZN3O^C+j1Cg2PUNtZdpieX;U8YV+YmNCD&>_2Zel2M&aSr8=2R6_egf^4fj8UYean}UF#R-~=#y5wCJ za8&pm%0<8J$iDo8TL9fFQ>t8?0-5PnM8QnAnC0ehOE}%A)HNu4)n5VXLIIpT$);T! z>rpO96^x*3ss!OeNJxlTxmZQK2q{*pG^O6^G07zGF_@R;JI4vW1ez~RYs%^epzWp= zr3mSqXU2jQoFw47QIRio@0wY0inXFixr{0)e5d0^rLd2|USmWYGnA>v#CAQ)p(Omu z|LWG(mCo(12`l5NuOPUqB~=I&K|C4&DbcJLt%#rw+PEBR1|&!pn0`1~0Gm=~rZ8Tx zJeO8Pi>jwP7!sFBNb1@)7Rf#e*ve%TJi{fo61Gh7G5E+#Rn)kcIR+b5dPsEG+sQ~F z`UGI5_`FCq8%4zY`Pbzx6IG4i=g`f(qJ^{e5JfADr30;Snt4p7>>5hAjYb|tXsJ@+TL4-g|Mq4I z7%VS4JH`L>S}0R?YrNf9Uh0^;L%)?ad5Z#RN23xzBKw_QoC@47k~*CWVRu3Dj2FJx zWQqLYH*w}!snO!f(>s-tMu`lS@WlDK8cztVn?h>`YR;6?3|8V=$60FzrQ~y!w|Oe# zv!|)&Ip}2$7QvmOkgvw!ex`Yh=iL{I|F%vF2y#S_-tDUz-9kwbO~ffuFB|iE%g?>; zpAy<>9?}Q5eC^eCFijAzLyyX_ld;b;>RT=T*IzRKaoR_YWg*L(Pd*xn65d__zejzz zZMQexFB}q8#)L!80Bb~=z#NwbOFh^hnZgsiWP_j<)sl zArm!Pw=6_K;3HKSUQf*yJ^_Cb8KKh(NeL^h}pqa<1v|fd>~#8okskR(`k$RQ3nS=pxbO- zzZC=lE>uVW-~<_jS;QBL@Zfn7U!OruZTyWuB;0BVgn|X2G-Vra|F~594TSz(4zV;w z#DE5pwV-Zv3F8Fe`@G3gtrSnGU}6bU`y|AD=}!*k-jC2=1foO-ju`1E9dK2M9WDeP z9tyPB$3-#J=LsAG7Qh#JkPABB*Zo^g6x0Y}%>ud&0-}rc?b8{~;X(XhwlyJC+)@+H zp2)P-4K_w6_MS#yA#)&|A9kMBtzRY%SBAOTC90n`GTozT(Ly#hnB?UDO1UTl${=J)e zNPwpCg(5je1Jz(b#Gtsr2JcP8v0dK+iIzHP#BektLG0se|BVvS^~W8h+r6`0NGtAfgSKwS4`f@iHPH45a5s~Qc+QdD6U4g+yy;q#+A56 zWjLhm7)VXV;maM4g3+QxB1T*d(@0!Os-2KjO68_$3K^xuek~YRG8#hsWEi59t)K;k zERTxyP}^MK1m@bbEyfKhKqFFKU&0ycK?NKd)*ohJ3F^&YoMQY5Uu|HcT{=$jh0Bnc zR`EmxUpkWx!OdC>BxK-6jp)|NiI0<=iBkIGUACANFP0PQAPH##VMLlBN1z3XOo?R* zOdhS_>A6j*lm=}wM7fBjj=9@p@dZm@S^@+F03rDV1quKK04x9i006KAodN&|{{RaJ z6zFcC!Gj1BDqP6$puL6=BTAe|QDM7@7b|Mq$g!ixk03*e97(dI$&)Bks$9vkrOTHv zV;(H%k*3U>ICJXU$@65Zl0SP2eHpYs(U-S|wtSfK*UF>=ZAo;hw5mX+R&h#ASubl> zhPASa9osV_*|TWVnzU(DQNwddEc9VZ+em*?QvxO3~? z&AYenoSjjg-Z}iYUfRZ6y4JWnxpS7cQMwI1GPBC0R6l06t}=K?)m}&Z-BqA{2qviDf($mO)NK$p1Rz5b z!uC^z4hn@Kg3V=EQF#HbL=$&1`C<@tzNE+7fD*Adk%}hOgS}CR=UxlmcrDhVm@Z->25emYSE_xndqR5IxWhVs2^<_lB+##|HLY(lnz>eWV2Ev z8K(5{#VeRH{hF#+Aku2Ab9d_1SgvCg%Tckm=EjOq$5sSuwNEmuRi?>0JCKX^n5wEm z$v)&_vJizfF1G9%q^+^+v@5Sz!s=BoNB0U9mPz|6wC=nBb2dEV<&bKmA33;uX%b(g^mELdn{~ZzEd4VTYqH)^?cu#EC zeI!nY`|V`o62bhE7`@2V>Y#A4m4}xo=IK#(#s~4HbbIM1olBSGqm~WPreTO zceAUWTbQdKSNnpHS3Wk%5N*wn@U2k3knkN1hy3n9YU?(`Ezx#Z@6789WM_oOl=kWN z7Qj77rAtJ8^(*1ckm)Wz`{PUcYInbZ zM1DG%TZ14Nx`agOd&apJc%s!QrAdT-3@Szb<}<#u46q^+9AR%7 z;~fX8@P$T8p+HIq5gCRAX?U?A3?YI+kKLq)X~|Ln|DLBH3gTp4MDz%H8j?g5QprBD zYe^I}qB9WQN-a1v2@TcaiY)qsisI|Y3Dvg4GRBM}iL)Z?bZExSs4-7d4B!lTg1dHA zsC8DE;z|;=MT%fhO#=bqUYgj(k+?7?dMt}de#XWxolJzgffyt?XC5yKWQ;NC<4_=1 z!bTRdHKxf*_*iEbPk!<&f$2~p8P%K7TuYPVIpw4TDVIbUQI-qQR%eX(M#~XOA*%%D zl?Fl?Q{wWAdBU3|tTq)RiSnL&n3lR1lH+|U*#%WIj*n6Y8iGZAtdT`uN7 z5qXG?1Q(-$eT#{?6p0IW84^>1&}qT^TTHx^|CoFp1f0|~*`%O`$vG;HLr$uYwgB3o zaYlrp5;S1aoB+l1-R1Ck{~l7WrFbdn`^RCB-42x)&M!R8r3Ct1-vKC z@-iXHB=UDR(WArs8Ai`I)F3>?rbvFuyH<^bX9eZdM3>4Ni6+EWQ8Xz;g1Qo_GOrB_ zxt3L^z`CD*?C z^)gZw$UV+7*uNU~u!x;qVHdL4y&Nc*w%F8Ovzpk-TK2LH`UhqOv)Rsi_OqZ3?VChP z+R~c#w5Uz3YFEqJ)(T{mRWu-+1X7;a|GM_JAPKCK2q_TF;`X<2oCsYJ@`}>h!?v4U z2XL2L+Q~BaxzLTSbYY{=kk*hRSD3DLx69ofI+rg4h{zebOWyLDcd2PR%tr-cg^$eP zyzq4i8RARd`r7xt_|0!$eY+5U=(lf9{jY#Wm)C}@cfbfvu!1e7TbH9 z9!ihP!)4SaU?KnrGg;1zmNcvR|FmUh7n@ZAgrU^=&6RR9liQVqf!x{0DL!zZSgU7j z{ke>Xj>()olIXt_8qXshZb$k&DM~~7(sgO{f&+}{*ECrmi(ZJPDKcugJo-1Kw(KoC z9oj9hy0oc&b9k6rq+ibK|V*1@+iZRIVJD!Hnu&t3=PSHg<24O%e_&Tb8`V zC9^9x&G`m2*hX6>Ok7Q2#9I2<;67zx?g`OMal1F)PRXea^69MHSk}|7Z?w;HZd{JS zJjA{Uub;ec_!c_e>5lKZjrBThdt?*H47XV7t#I9FK{E_bQozp=fOg%xBM4ASzDttp zigX-c@oxCiLLQQhYi8mM{~GvSf}oNzOhk6JF3H6uqVoLJTsI^)TF(7;bCIid93Ywb zKs1q?jPqsZ3Ng7!lwN>%GaVvKfBHzAUI3Ig{Ul6Jx79b>^O1bq=L_1pOU4A5$i7^R zU{AZ+*Zv%%AH?k-`MN~r?DmesJt1h%Jf}RH3uIc8AYR=-U-|i1_{On_;}MR4*3RYi1Nce~#;S zBXxnyz5una3!8IafYKl9_6s?ENeu3r(QCx`dqI9f^jvq4R35&M*GR-ag4JKI1mS1_ ze!GPKd5v(tD!x}p|MFWTHi4?;fXZ=9+E*?8_kcOE ze-6@tzAuccy?X;e&0E(-A6qI~!$FZBo#$oFUnX%`4M zZ4pTl6)6@A*^d6m5Yb0^c=wSmagn{Tk2hg=Nh6X7f|45vdP~D}@dgALcV=z}kpq!; z9Ve3u|FL&c*N_(~&Uh<+=fk`tkTUYQa+Sx94v5Tf{5=SUl4Xcc2X7ePOk!ISQ%h(%MCo*7ydR{(=a5v@rVgZY|;M34y~1+*y;O<9?jafS*aj8>7F z%)klo4TR+Nmi$ z|B;&&L52SZoM(lVcbO7x*_pceo{sb+$@vl8$ujDx5Jo8{)43TaC{zJsfGRnkPEwsD zA$NUtmQ@j+xDjs(Iv3>07tA>n5ejOKlZn~*5&}9K4uYNxa-TX@pYrlJk%*5)Vf*XjhFUVSr5vpZfKn=2#JMNh=0N6^8?&GfEO;iV`vEIHoyxJRx^1 zdJvUYYD3BsZMt$trx$aI8x|T7c{*u8bEoQudJ7Vf97>_I(te~Cl6qGFgW4c||GJWw zX_rQ`s6x@GA)$RL2ckMxpa?;LS6UH?2BcMY5OKM5WK6IM5>1~HhadJ?zy zq$^>e52~dr(W$|At63qbiMk-TDq+8hrLp01K+=#rNvUm?6$VIx$m)i6p=amFt0P&H zbHS>xVXbI^t&MnA#2Op6%8whtm2)=`7a6R1VXh@{dg7|9#wZtH36jDZuOjiPr^JWN z>XSQhuY94B+KLj^N^X9p} zsVos{#S4aACF3BD**_bS}{m_uCMX2L7Eo?NSQ8+5LlsN3skgX0D*77BIJM83v>WCMB8nCr zD-z-$5O9|cYvzBU@u@pF5ihwrGb?@{5w|Y^ z2}%J4FX5pgJC_RLmB(nZjr(_eYh}Ea2nrFnFcA(NF}SBI5V{Kzy~}eRD;EuEkjs^$ zf5x~#W4U3wbDx_(u~!klixQClX2>fL54%}JyNc_{5vNzZu^UYQ|M?n}*1YtI6K?jr zY=^Ag>m&*qwyauuf$6qnQLv925s8;;tvQ6Om%Tt^q9n0|&LOf*`=b!SzX)-YMcEQT z>k+9d5(fOepJlrfLB0`Dwy=S_3qpepdl%~~oJnH25<#HyTVD5w7t!ac-pRH}Nx=&8 zz`ya66_S72FVIyMF6y#fLZ$9b7q5n0Mv+n4l{b!OFV0v5hVq5$mcJJ`BWF zMxbHL#GV1d_M5NLwyn7#!hYt&39A=AJ5lz!Y{v1oh$|2*{|t)m35|W&6Lp*^WegHX zTojkrCwYBv0MPB#>y0d z$)xqJGEs)dsGfJXm46DZLgBi(8XJ9y%Q&0K_vLb$RC_Z_#42RVbb-ei>=DS!5!Boh z;rVf@{2H?ihL>BvGPB6`h!X%@bY!xZy_XiGm~rkW&B?42qbx7*tjyV0M*Vnd*}OYt zDihT^&q}eH-Hazax*2)bpM(ko-^{bc44EU;tvEr>n&FihSI_qM5w;4@5s_sG%^O*G zw<)L?AYB(0J+UxR9BbJU3;i5@2F-Acks2Y89&)4&|Iww@!-xZn6F{J^HHr|#cFiLJ zg)gB5ib)cArNfu8&y<459FcWjqS41^#!Au8*kaSS1=Jj-)V1Tkl$<2z?3UsjP|nE{ zT5VndK-7qZi$>SeSy9%o!PPOb3Jd`WE?7ob9hWj8(PRPDc52T%oLaPtiJ%JCB@waD z=GLc$*lRb?X(7Z0fz*DT7JQ8@rE#X4vBA2Q)71ml=sBOon8jam*H%$yV=awBtwJsx z#dl%YW8v7nLD+nuTqGga4Ur8FEZIZxu5g!_7IGJK>35TTN)5&;n7tcVUEIf_*De9u zIYGLuHxSo*&k3>848hv!b`#0@*%D#hH=*4c|Bl`I56Ue<0)J+li_`n@a5!@Xx z@F)^oFw*Q7U+3*1fg9XGBigZX-s4?+X0aJ767?++iY=;g zmv8;OTyDpq_)QXp*${+SXCMmM3IWlUyc526;f@n($ZCW7{m7S*;t)3B#TnV2ycfRr z%?%DiH9jA*cxG%?%V3Nk-W!w8Ez1tsR|!yPixzJ#o)R07B%_DAe?8*qs%R-8nIs;{ zc5&kj4C5`D5@gI=%I!B;juJT+=4bKXuMv6`Nr+op5VLINSFGtNym)Q>!%a*UsJ;;skm&Q;iR>H`^>^r1x)O3C zd{hnA2*K7}O-JN9C4MdwWUd&xu47tC(<_k#%TAaj2bB)K5)?`39+GNf%G{Oy9Q7>F z0z1FMY0M45#X=G7u(Q&%Nb4WL0TSVArT!&a;CJmHg1`RayK&*kNW{)QC94L3!(2IK zSkk$U>$E%)0J^)_((gUN?Jtx>>wQ}Ho)YoS5+1G)6K@dh{onBFsj8jF=q;9Zb{0u4 zwg+zBrjBo4!rOSO5syAP4BwX%|H|4Ij}xUXi<*rV%gBy7UXp)Zz!JM$8?Ru={=_43 z>|)U;FE8CfQSrut?(|j23{mt$;qIHe>w#VozmW59lkpz0^e7>hE>X%J5|Ks=en7M2 z3^4(U0rpwnE+tD*i5_4}7LoXJ&r-9?`@JmzkekIxp0Q9_(_sN0u@mvva ztQ+eF^?8BT8qcRgK^1r3cm>!JUhlMd!FZM}5_e~mieCT`j}Sx!`5uAz1F`wxEPJS> z`dOL!Uy|C!{V5fPFQ*6ldmhY;T(X7aexl(Q%cFz&i|F6ZZ4=_C5?FsqEo30qKKJ_TC7Hr=Vv|pYF(RD)$=J*b2 zmv0_DkH#lamF&p-x{qT30ieJ@f&~p8M3_+FLWT_;K7<%i;zWuSElL#l5XeQ29X%rO zcrif8g&RqpJQ%Pe?ltzN~NHDpz-3%N=>YV~VZvSrPhO)@dAMTWU6>naG zc*9!!o09Kf!i5bFq>B-uUAqw*!~FZ$p-+Sn4oW#pGcZKSIG-}kTy}40(xtBw-E3Ml z%CQFVc9z?^qHL11|C^ru3VXHIwKBI1T-$s1aNpqP9r*eylCk9B$ytu>BP^TYu zeqH-^?%f%t_AV6(#p*N5H&hN@ruy);NwRMrUw%XI()mWGnDi)7+X(;mF9;+6=POEq zsU%Q~z^xQyutCExbMUA0ESj*O3KhDrAowCA%{~sV%g!*$I2!T80)R+s71jpx@Gb($ zxT-}HT^evk(>5fFw$1jNsz!qNg9yiu;_}hP^^B}29D+hDNSu(=kt&mhphU7tvt+b# zAuP$-iOIzd0wTjK$0Sorir53d%c+Drj7`WW8igP&4m%2y>4fYE&z~SXvrIq#R83Fx zenQP6AB+6*{~`Sfuxmg>7rN;&+8zbeDmN>gFA7X$8gEnLE@f!Th{RO%DN-5r)GRd{ zT-CT#LlRUbP0eDZBPCHX@E|9Z`i-qvUj^2?U$uK|*cpvI3t2#wm1{gcgN4?*Xs7+N z)dHA339srJ!>=n*v$B?2XeFbxs9C)$wV&ZtXcC#8eODR1@ znM{EXDmlxeT8=AZs#1ozwDEwjtblTJrU=1?3Ql;Tpr4aDWuwKd*{X0k%TK1IV+sP& zL8U7C|7fePerRQ^J!<#Vijsb)WUU+WTE42czNj;>3n;s|MmZY0r7a^3(xAAlVs>qw z3+VLMp~E}7B5l!L?P?O^2R9=@p}P(jUhk(|M0d^pyMVFEYNO_7n14Ci4xmEB;aA zvVVR3Q~vv){<+IvNHoE?`zh{EoB5th5@(*R&96$#O5pwq6DvwlN_`!P;6QRxu)G9t z|0cWY3w0XuzTY{}AtXG}QruUn(3~whD?y=Aj1saKE=hv&!dDGD!a=Z1#Ahfo;SDvo zsS6G#h&JM0dN^`6e7&x5Jt9aP|nj8_0Zw!x`co-ilEu>-{0pYm{075wSq>q0rj0fdX#DNtOkQ4cp4h>}xLjLf0 zoQmH5{sEK=>P{k4oX8{(d5~^F4km8An(;uXsy3ockq!}sL*gVcL2lBOo5ZApVmXmn z7Dh%w5>hQ+xl3T3vT`2k&t_W5OJXL(m%=LM^NtBbS(as#wj`3yl6f5-4N+<+|0Co@ z_(-;BPP1BxDji>z84(noQbvQ5n+@&tl4p9eJq}FTQS_J)N5-p;+ZjnVU(ze1wL>hS ziwnIVqD%7G=uqD&C|pA3C~yX7FaoO})6SL~gGg#V<*H{Cv&A-dzHtf<;Q~U2`4lp2 zqN7wiX-btcPJ+ylBpG$3huS$VmDZFcBkc}BZ{#2MAd)OBy+}P_I-@jIL`E~UsfDxx z)TA1+sYcBUQh}Alr{*PA#v%9u`Kmu`Wut4dd z4MCQ+$Ry0>BEuornnpRrRb6{l#@Rl_taqOLZD@QOU8VFELnJ{ib+!8*vYd0f!SyCw zr8yg}>gbZ)1C4mo+Re4nGPx{b?9qn$U1Cl*v}YxVeOq{01=%HB;i6$NyI4xr#z-M5 zl8S!GLJInJg~2k(Z4V=&Ck2~EybUs8cBwnyz0S75Z#*U&If<$dm$*2Ft=v4NvPyNC zc$X9;V7{(}&>3C$vD^(xOGL-h9QPQi4?%G<&1jkk$1BL}gDzj@|MX*?X!y4?b+U`K z!eJyqVmhfjnuo0#t&-tV%BxA&6t!k!mw=MY;hYX4$g<5Dg)}_#^_XV~yQLz3`MX+f z5R2s!Ws;f5w(E0j{Mb_-AnA*%nCr@!0XfCv^7xTFQ6!#$Tb77v2eis8Kr0&Z;I_Ep zwyN=3Ml!_b?5#E?b*^ldByGwGlju6ACJC&M1+5B06MLM)Fh3f;wrY)t`1HEF zGRgW+ytcE^6iwh{H=A(FHa0f}GoNQJJ3RXAO#SkrH4h?tX6*8wv*{F}S{G&2p(LYL zWNPlhoST#iK|m)1OFhJhd#Q10Ul%99fw&TeZftSv+RELP|7hF0CJQ9fU%U)nstvRy z*3JsVX+7-%dehqmhe<079=3T$DBBo^BZUb=<9z*DL)0le)LkFeQ}KM zk=I}C;>(Y{d&`pglK?;Z*OvubfA!GgO_{J4shX#Wz9qwa`qU1mY2#vlH5odk z_CsQHUR&S&@3+dj%Ch?VGutq>m^9Mp9Do`Q`BRO@us`g=F9M-H;s~RIV3_`!7WNxH z=rO<}!7vHbK!o7GiLkOt!;}lup9s4crFtXf5W)HIi`2=J@7usWNOyY69{}+ zua2n-i8~4A5<-PgLY{y-pyR=|(7~7Z!82sT|Czu$Y9kih3lx+XL)r_dx5Go7n~x%V zCEMU9(%{25T0kjdB3LOpt64*>$ecQC!>stZK%7FCfW+OyHI>S`x`9IVi;qcc!G=?) zSYx2P%M35{6w?!uFFK>JJFP}Mzsduap1DzB55H1x&L z0LGAr3eX`%lN*YN%M27c#!$(`sZcRXgos2m5~iS>su@O**_ggkH~(vkbIY)-r>V7Vs=o5ex8E{bc25+sgGC;t1v{LR(~r zNKhe$TSqzc6a$RKt1u~;pbQvU$W*Bg|FBVj2JDV?APzm7H_yAiQ_)BVAtZzBj%*a1 zSv1D>14W78x0V0+iJes_e7*5;` z05k|rD+sTY36spVK7$E&Fbib)inO#QMtU!Y>WW$$Nttj;p72N-I}0pJ2&+^L%&Z)E zghz0jiHJPFsp!k8;L6rh!?UnV|KgBMf~ZZW;V&u#Bpf-%h;Ylo;7Eu7!S?Ek)wE5( zlnKd98C2`d(l8dsOd*u;H19-9j{(i@NKH4yl$o^7%)m~b*iOmQjrZ(`_dHFOkWYoc z&GiHn?Q1^5g3P_*Ook*Y8@Uk1yq5;bOf))AL))MKT+eVMz@#)aXG;LO)X#{3O|59o ztC^5zGEji|9<8#_S6QqkgqD9S&z6ge=KMnu;>iiUQ0@9qM2pcs`p*TeQ9$X8Q!&xg zV^9v+$LcITSDXmK^F-++&C_7bK>Qxx0?o*)&m0Ao5v9tOszQ#yDJpF$*h-2-TnS%G z4sbyo2USD~oY7+=kR5SB|6x2N3nf!=dC{8Czdu?_9!!b}Ia4Xs(}BoPz(9#Nl?iY- z$+kc^2jRRg%Tocpq0abBhl|Q&)WbH6(mg%HM5WYARUrQvIftlIf^f}&pw5a2g=CS% ztgMLkWX`M*Pm9=4h?vx$xKH}hQX;*YMzxVR#XydL0*i=FBuP<>i&ab&R@8Y_hQLvT z*v(=JRpOvb37pl9f*ySADR^T|%GwP;g~J~uCxtjxihvLtvD7jf)^Y8|VyeGXdDaWf zPja=hE?S##^`z%J&Tl(Hnn>4T0)&uIPj=~EHH``5G1-||rm}U3we?qelf0@8 zO|b>YU!=q@(~~R&KdbPNkuX}oiBPQJ*^|Ilx8;tl&DFs@o!pDs7{w37eO$uoQ-iSE zJjBu%3*2j+pxt=Fy)x3f9nkBb+lS-1?f}%r7>P?^S_^bPxb0WTom}kz5U?4n%?KGW ziIeB#PPxTg|7ucFX|q~3t*WDtUB%mt(xs82a1*Bl%HbtgKTVr4RNmQ5PV3#I$|Vy7 zn+RNex;ecFHJc7#Jl@ePHu>0`1T0^(0$#_h*tWWp*`YZHc^Hqa2&lx~iiF+RRX~dM zj{SAjj>rVw1(*mt2s^>w{FPd=w28beJQpd_1y<40*j!9;o@J|EV^uo^=HL$YV7{q| z%dH3zmI{THi%+f8E&DYCE7wSrEF?j;2vgjh3Qb9@oML_2yja#ft>9!!#P#i-7b>PA z87hr*+LWXT?UjizYSD(E&io0o8Q!i8_J|(7AUypvDZUa3D$n_9)t4BJ1h&^{#h{m{ z$qz>3|1@U2m>}V{u-~o_V-VIrEl$wl0IPO%stB%O⋙%q~aBRij7z%2~dDG#*{dH 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 `euCK4|e=+ZOJadd9OTSr~(SC`Y_L+2w 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�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⧁RSPpX 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]Pscb#Oe9i;><&G&JY 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

      n7!upVY|$2K$R=&|=xn`)kI6=D+4fiYxIFY| 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

      aUhN{Hud>;fW!h&fj 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

      hPt_pI(cO9kRzeN3Hv_97?I} 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

      COGd#W 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

      ~WI(XG7F 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�&h{|tZSh<)k$sh-CUWj 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⋘@br|E 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

      DQg?F;N*BHk!)WWuTrMI(im9{p8x*-f( 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

      gU^avfpyEBayU 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 z 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[nj=-W`#?`zh@aOY!-~P<$f)C6Mu? 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


      ucR34z&M(udf_?-bDR@ zuiM2mBIP}we)Q~d^&Uj^d~{^|64iTL-22^;_Rxf}Z3b+BBX6UVpiZQ=ncjvkv}&C4g%-yV~p-aaOYx>Pz)NXh3Yhohp7%AIEhfFMwl0t>~ey(o`A?oB^SOIMTCOy z_i!M=3f!jyOx(RJfe6jLES-(6I5dA_h(H8Cf`tUK!9)2rpchCW2`o&^iPiuIw+w_E zqkGR_;pQbh>gXYFH0*?&Rzs6iyXua`pgxK`nB2!&C2T*fLB?1pcpU@|1nCi=i%5t! z9-4uJdXpE`bB4&a?jmY*(_}Og2U5zQQs01OY=FJ7WL`U(fg4SlM5O)%dlRTwv16Z$ z2Y4T`uX!?2kAoFy6#mV+E;K#QdD2N_f@WL*{y%jg=#p@zSl+y-|F_sW5|ZA=Ja zL7ZeGG7!ePF>2{FX@nYbnd#pv9{4d@_KksE7q6zZ$vo!?{A6T_IS0Og?6EP z3VbPtTDn2I-d{SVf?4M>dnSYf<&c)L8|G|~D<~Ws=L|w`fEG(9Gf2xUXn3R($O=PS zAT_EFz_T_+-UN=xcCAu$or+&{)6nAPp+r5($b*^f^Q~6`iwvByO~4x`aM7W_yQdUcccIQ6gMyM6 zR;_-~N%s9{5bz ziR8hJV&i_NN$N|+ha+Obi=v_ZpL)(#z0Lny zzqR@|@ay+ij^OG)sc&@4f3M&Ei~7d4>=6Ety}My*2aHWwm$uukLL%fcV3IF`CGSjg1_-?tJ(D*thP6Wc#+}5B?qM zuf10fz-;WEPEVU~y4yd_w0GqL_YVKTznevjvYz&BnSA!1Wc!x1wSVyCYZ6(%bzM*~ zw03uw6@iA^J|y*~$lqr~U9T*iuTSQ!bQ`OjwBEt%& zF~)LZD~QyvkPT5g9+u?oGPh#6K4C#~->IXS99NYzydg)9tNMaR+1L#S537M%L1dT5YSw}y`=}JP6;%-pumx(M&SN28VW_+Z6V(js;gtg#McHD zswvjy?eLF49{`teJvNUEBMZxBMJ`x&$9NfxYcC$qthX)bGh%0=kD7 z^rP-L<*yK)a}zF`o5aKSlBr)DHWxZ5=*u-sUH4<{DFBLj*%;RAUQwF2H1>EaqThX` z)26#k<$taAbN1`FoJXBH8((qSb!_ddo+Jt=&`g=kWYy<9XJZF96-_Y%!V_dZ+ZLHeq`@b6UC5obn6RD~YzX6x@)zzh-plcict>AoLnA z4?4N)cgFw`8TRKQuve(1TOXX=5YXqFt?V#41LeYCZj{N{^`77C2w_L{tRqObLf z+Jl1|k_4~Em3{LDQNaspa*MdzX~>6CE-VtlSq1K(0xllB1A;H76!ELK`S>?{`3VJz z8~uZeQp5Y-SAYk|8CPeMG0~c<9(f#Z{TtqG5Nhl=qV#ezIV%F=v=n9vU0t+i0Kfh7 z?M@(=M+XENe26)7T9|lM67fW%J%Fu#0N8ov9}-tob!*2=(iZ%^F!GF55nb!uUV!i2 z+rVq!eQS{HylO)*J|y|It=iy1@SPs=$v8JZrt?xGp9@Qf% ze`j^S>5d1VoUSg#xVC|wlNH|mXT_h}A-6-CF?1t>pLF`~glx_kQmNvi#CE*nV9edLWO*%gWN0{C87!~u4Ab@< z3-|qeilkyr5}0j2Yg%QFq_8H5>@JO6B0klDE|;I55!L=C-FR!`Z3#4+B9_7v9P;}S zN`|5kLMtasv4^-$qz(MCjB@k2RQ7WBiWaeRKg)DtSxpk~$tbF~8 z9uv2d>Qeam^NDkz&wmad(6tjHWpK&D2|gN6K%iqI>;-x(kLb}mGldm=sdomGTz4!M zO@)oq=GND3Rq4G;gSjm!^cKy0`-YXVb!ESph#2gOxhQT@{I3(+rD3hFXyrw7sm8nah6U)#N3wjfKeWt7Vy6GTd1-Y;@s6ow|Fq7aO%~|`>$G5 z+a>Wl)V)tZf-&8YSpf6Ia&9x!DJ2R6YOA-o;05lu=lmw*`H4AY9i4QW^8=4}&oPERF(?60O?ns`7kV=ayiY-MOnF*V$u_cpL%;O{e((JQKjQ@_k&X~ zUXGyutWDzQ(1-BFmQ9UNJ6?#AN6LtbJNkBey67|aH0SSb$j2(Yk~Qubl`0;h&%#rc z_1&|Q+dcTcsU&ONcFS>8dBwzPpJ32~%lq~1*#YPA?K3^l?;nl4C~9XqEqc!R)#tfN z`K%xvZ;O0=Fd-+g#Ki0NNiI;>$%S&5UdEsGO0*=k+xIf%r~YMY;UA(?cd9wY>tBB{ zWHC`xtv`Agr!*MFwCp|g{-iS%ehWiEBp5q7fO-#uiJ#y5(&`q?b9_^{Bpl{va-(yB zitu?2_57`k!GolmzrKnnaJ^GiZ+q5a^T6ML_PzZFhxy7O#h8F=z8zF+OHFSM?nBGpx!T~{hcqw!xV^T%^DUs$r1Mj8o8$A( zpMtttHG}q_Ij$bHh4p~CKf51AjRDYb#vjs-ageo*Y<-n>mNI;j^7`fyS*?G3(JRCL z=N9`Nsa{oTRf^?T+bDX~QO);3Em;qlpL%@klZ*e-uZi)KFaQf0y` z>q^nX=xz-*y{9AGYsJ}Mu*98X|I8PZ5HY}?VM%pnNvStR4G01san94e>Hs5@A1!uE z7gyfi9hsSFv;REyj79TF(W{3menDfa*<-f?bO;hQx4*lsti9OnR~4bPqXK)(sh)P9 z-nyL`x?{>sxBU04dFG)$BWk9%F?FD-Ui zrB>OsK-tY#*&{{gLs-(bZBlS$l4(NH>-?lkDc3K*O}xT>Ed&uAHi{2KC`TQii>Sq4 zTULq{(~C*L#}_Ci+vz3x;#0$wGE?-@4e{CRN;lf|a*u=Z+k8D|@^QMfzF%9u%Dr!jXKdVZznlWGwow_O zZeK&4LoS$}vEZxQit42xlzVAX3ME>pI0z{yQ{kAXFpOYmwk^9;_f^D&BdT0oOP{6q zWMPbNl8C1^aOi7%a*og^Y+0KiQj~*Hn^pDoiPf-;w6xJ&CU2m4p_56u0q(hvWOE(f z+7*x3T5oGiLLy4o0y)1L7ZKE)tilz=U4P4;zfviYkMrGsYxgRglB(L6on7_NBTq9T z($*&Al-bnacRF{Fp&`Egn^ur$b)jFjbRHjbZDX zSwm{@XSZTvO~tBnk`vFSKyoh6<$tfq%7rLB-M$h$X8%DYGGNXTFgnd$t1+Q(yhYZ1 zGxTr2TaNg_u1)nN^PncPOf_Q#QFJFFqui*dvM^&frDzn9GS_|yx>wZ5QQWLr++ttc z7E#<@SlroB+_h5NZDde=uc&XV=-x`fe7o9NTp~h9l?3n$ZHL1E{sH+?eEH?K{NbEC z;bhf!o`aul!PA~S8@d5`nZ(o4%*mLIEI(!%!6&?($TT z6$xk_34e)i2$dWw-P*fqwM?qE`4~kirR@mY<;#3Jmo1FrMFpv(w1ujW%$&BEJ3bbE z(sjxyx~w0Lb0{LrbW)?N#wlCk$`1Nux92#gR>ZW&iL5%DZd3}N;?E8WI;r!cRdFRp z$2G#EWfm3Uhm?||V5w^d94?(SI@)(?g6~w%tMV6Q$EF&eMdrV0hG=4Ix0@hpcmZUp z;*(@q*5I3nbF2>|d03BbEh-nNZfa{>uK5;*Xz4UB6xWuI4X<)Yc-ZDDL}@uxXUtZp zhP(-p@6*1?p*m7$!OoFq0nQ6_BRs41wM{y^q;`Kr?X&@^m_-AGYzOBczk1Jf>aP07 zK7V`v=f1f^W#OX z4Ra(1PjL{%Kw9n@urvw8M*}v*gIMo__#21pG6p#B59AXed?%2t3I4@Ik*G~d2-yuL zFI+c*$SDLKEYxZP#*d@b!@wg=;f9TU(r7qds!yeH#1jeQHwB-^_v0oT0uCS#wsx&i14jMQj;jYNh%ssFt7Mg*EdIAvHKw5UvIMw?2Jv^wSgi3|< z$M*Fk+rFsrOkjd_V=?X;Hi+fK6JV8RscsRm%>jf^FiH(F7N+(jKw3;E<2C-4f2-H$J;<@#3@8^7I;b&8 z4&3gq54+(&ugUT+7UoF=w**c=d8XNraPtjNEtw%>;AR^jtDJG(J=nDpm@}CnBjFHQ zi091sfYhQR>gmWNr5aLrdkn%i4iUP*owNa|o`9IU!C+q@)&r+9zy?Sxhh&8UD@jjh zVjya?@JtL`8d#D;L6l~u2Qr4-xdAI1tk2vGwcFx5=k?M>c4pwBd4{I-73dXl(TuP z&B~Q^lPeD7f`U5%D}7Q>$Tez13_Pr4COYsGqymh}T?e;24X^=_ii_)?d0q}WLB2FB z-2BT5w)r(}X9nw~CI6nmo zJL_Bdv1jFgE483`F6#FqAj+LnzVAjd4n_}vT`@5I4Ukdr+U5Oxt z^Kci`3kT$g;~q?p1al*RKGD8BXm~nIJMBPx*`2xgS$f)P@3}o1Zgn1xcY59FJnioM z?B&lF_82f9ep-(_JpdNXFM%A9ZzKsTOippmN@cx^5G^eCG|%!LJ|xyztCRt(-v}~o zgc)_g4EF|~k>j;FWK+DGp}Q1@-hk>MM>#PNGtxX+5>}ZSRw01ipP$M5_33X(xbef^ zk}z?CED4)op^8)FAKYr*^B3+}i*N;lNzz3AzkOC{Mox25yX3q4>~OYUia2PvF{|-#w0x!!!Ek63bI6^c^j~WZL;qvVfmO}vf8!KW`91#k zpabha)3*Ho5p?)ZSGsiny3+N>CNBQB6J7rZ+}6JeYI^ezi8%UyxX<-3oSg8_`&@Z{ z-RHX5|KUFxw-f)VaoaNgzjBA){9ifFMW*`y`1q^lVEKnAv)G!mWn`d?T(#M(ZCU<{ zP+VQcoXPfA&w)&oIklZpe~2>5S?^y&c{sl|vpx=HVKqH7W60%f{W#Ow0R`?I`9qYq zN*QHct=lqD)~5VpQCQW|6fZ3qIhK`6p@| zQb5<}4m$U)?>&WRt5FPdb0_%^$vu4WSKiSpYKdcFw?;WCqd5oO|EL^3sI<%)sA7nNrU7 zlv#uD_O_=A1_oH@d_xvpC~_7{j3mk8i|94>@Vuew8hd~>dJ83(D*R>5H&sA#s)tc+5byTc6XHM*{HjDKz$7;$?07b-xjb>_Lhs+5 z4gsnvI4_$aV~eWFB%xv=J?+&uOSVV_3}+XUj4jaTK#o8-X-o!qpYpF$HGiVpCC|)a zfLEk^?ad_cx?}wcrGK7XndokVr4aGXy>Cih!WPlretgc&e)?vI9?OEiQhG*`%{I&- z?pD01{ErCda>Hfh4)Nqfgx!rT8#;*61y+&LJnQN6ZrSs#<|7(~ z-0R}qW=GG%DLlenL?1mLdvTqDS7jrPEsN|8i+*ChGXu$^->75?gGdfp$(oYO3J z!}imO2-OBbH*Q=o!(3M`K43^s1OYkKZ%g302y8~AfliuJz&np5L)cw2O883 z5P3xU`pOGPkSK;)9Jo@!^g%`@3le(^m%^!{y zqO)9P<{sR>R+28FqZE;{zI%?avQVSlZZz?nGP_`g`L4>SA3}5sdL=5ont#PFWxbmY zf50uI>H5`p``$e7)}swDyb}<5Iumw!p91=uP3M9pF09Vm?BHe*QDL<# zL=rNs@|CX&6mbg#%(Jt#Ztp>7yCsSQs;`v1;s1VOnH#qqqd@5_V*r|0x!w$dx7M0< zCk$I&bmfm@t$sComsVnWnJ(>9pmYczfS9S^9ObF^;^(-r6EqUX3qKh zPtJXiSWGi&bC_$mkq{vC`n_SN%-jQdDH8ch7lIPboAnOVgLHj>NzEH~uN{5}g(6~0 zS>>CC5IiF2QNrsc`sUojtYPcdb0h9H?0KW-2Rrx^uXigI|&&IGLDh&D_Ryt|&_ zvcreo3#Caz%6R!`;CPGIM{Z>|>XZ5xhyab-qA4-Ltahpy`yAGI$;nHw>N2InM38wq?_95v9F zqrFw)DZ;cg#-A8`vzo?D!gghxVMtC~Cc{8xZFVBQ_2FAyf|JipptmMiopG&_v_>=e^qdCPxgP;v=IGNnDZQob^| zX28YXt3q0>I{M&d;wnI5XTA~*1HGA!h^#@9^&*=oe;CF#BP<~?4W3yVy*XSL!hpxF`0K8b z)_-4V=>7E$ue`dJ^Fpav^M0=e{ne|VMBa4@c5S++M?QP{tXb<&Gw8a<+RN%t57Ls# zo&xK71_hr-e_#8ajFMA2eXsjqwaR4?8}9VqPeX>cyY?@IX}siP3md(w8Jw5z^h%U1 zbll>T+YOhGuhH2Zzonw~NuVPUmFbSBS6oc8rfsiR`@ZY(qPc2`C~ZT_d>705bmfzT zGqWj$YRnzpwA$0P7Hf*cMOB{7`|)6KsaM2O?+-F^CIm!4G_>lezM6F+2iq~wWXmo`p0R-xpJ(CROjulGL4>1V^eLZyTzr|mcShjnXL`-wTGOYgH)DWs%*Ag3@MZtk zEHOqtK|?i{sST;3ldfrv_!4zvHw_|?zOnBOu5yMW7{a4Pzs0h=CGaoDCZXckRATMp zJ+9aQ`$^u%Z!UA!QldPAWZPruk5B!SQv$v#hu4QHRSw5P3K;f;)gHISE7uYf;O7gG z2}aBDD#IAn%>-Sx#0m(D^>GyXjcFVz`BdLkHX>LMkd_HOM@o7AF(>w>$xOUR=An6>U z=|+pm?Z?R->?u!FQo8L@S`hfY(V(_=>w(&!p<4akg4B^(ud#6DX+!1NWBsWVulcu3 zOJW8S$Ej=VY0p*C7Ja=|mQNYCM;Tv-8@wz?+cfmrNnzYQR(ZFa_Cd_+Gy7Glz39S9 z;OcRbT#dWOGr+|XEpRURkew<~(F|?DH!Ym(VG!L*&^8~95!^m*;nw)Rc z#6svWT&I&I+&$c#p~dIDog(G1dC4I zIA=GnDgG6ZOpWK&kGjTs^X~0Pe`P0`F>{&Q>VDf1X7+yD5c5_tb#C-SvAdm%pyWt2 zkr7jazPfS2-qHJA?zcsZYsBq_Tk7oMIy6|dibqLE)Wv@{i z#VN2ldMM?SsdM>oevO|;T~an>Wp>MOdS`fXTVZieO7W9>#U%FZCY5aL@QqlZlJok& zXkp2CN6F+$$U0(|{{foI)K z(X0;ba%OAW8nxe)^yiv@=a2ZH@Be^jE;4w|AzFdi;1aB~b=)6Yvq_HtWR6_72kVrT z-6gx^HzB9xMFgI`c`2Swc~v>FWRx^qO-#Iqd19oZfyq}8dhLM+6aT9u=WXWV8IE}m zVc1M%X1~0UL=_o4>-kGCoM@EGpX+<9eh3R=_q^mVe`h*@=SY@W1g03VRT&4?bNa4b z&JUwYVg@Ti3C!>ANi9MatYye)iPBDK zwH$~jIW2)zS_qS6J-EeY%{s;z!NwFCA*8mC)0R#UHS(-Kvvu{@FtU89{*g~09lU7$ z^=U)<*SyXz+Equ2_x%zs`8l8?5J!T-Jw7N_!xFei#3J+|nci&}4Vl&=l~4-B60xO7t|mtHCT7Q`IX{<~I;P!V%2ww`ywwV;kE ztBHxjuff2+fx?~@p-}6f+RS8FMb`*d$-ozlXAKor4uhpOLt4&uPuscnoQ$Wttaet1{2E zCF`FAY;)SiKk_cUb)|`{Yo#f$% z!oZWYeHPLOQ4K5Gt-|^uqHXEcjYviEl;WBM^a_+{d&Y-lQt1Ah7TY0z5kSLmbL;+= zZ;7e?!-T3nd#|QHL|LO>$fFhyy@%=h`u!5g3J>r1$1}ukrKsjg3bq0zt1smfAW1<7T zsR3uPddsrR{S!3N`#101Vjj3m$(Hj+rCdUh7vO2n?7?(M2<<%>I)~~`2~}4#^+a_4 z)FgtPG;$9Qu_Ym-_F&}0PGjqcsh^W>gpJ%P-UHjepyVw5Vdu;xKVUC&OnESlW>-=OBpfhPGUR#L4G@Q?qoE-!A zC?GM$kSBrQ3tE$=*iisN7yg7>U?B`tQ}2)AVxHi|V6Ye-Zj74-Oy;tmaH=cGr(;Imy|!DARVYSP*hI(KcVgcZgCLb4u%`+{Fv zVZj>~Fji04ChHUf8cI6}zJrG|U?{FrL3EDc{KAt9!LzhUV2ef=ht9%H;G2zzp$UW}4o)pNb@&86{s#6*aHRkT&3{H$ z$n}aLeWdCMlEjl663BM^+0ieYJ=6wqBLtoqOe#Wv8vsFIJUo95p@v($Jc+OZk`;v6 zyT<@{hCB!Xa~;Dugx>_Ry=5T4wD7B|g0rTW3&<`W!qB+PDYPj_^@g!~^IaiWL;<>B zxv7JPb5g){bfz>XSW(JZ@~NT<*tE+4qdwj~)1}v?$ht2Z6g-Z&34$#)F0BTG)sEp@ zc!Xg0s3c+Z+AkotJjro9DU5paDP)sRXiB_s^MU1>H90a&a5mx>?3fLp%YP6x3ctm4 zw3C2`_r8I>rkd(vg_#l%!)|la!NYc;yi)tw3}EDXKuKvk-hMGlmMT z(d`Hv`xu~LUZG%i5R4~;oTZUc6%E9T;U27Grl}i-$CE}lxUwhQA{BhaV~>Ao`jh;O zA=TCg`6XVfnE*?e0RbNO`!hVXYyYqtF<1yoC76zk)Ce5Io3op8*5U?15M} zPV)s%MfYKTAuWN3#bDYNijtV(Kn-^O>XW2eLDxg9f$&W5T1eu+Sr5u`?V~*h*?8NxAWEr!=g^b?zOVLA zRhUlB`u~PQ0}vYQ`|oWFmcRDZQ2&C^f5H~BDQo{0wz!=KaOnRC3;(Ms{1=D*+iZUL zWan=b9rE9z=)bh)gsy|km+zAB@BR-cy5+w^(aV2rt^L0Y3;)HT|EH?3&Ht_{Tu})k zPNIwc53^a>njNZr)2w*H4h_rg<;dlB?llSt?PScl`OZEQd&``er;LtOFI5dcJ z1-kTyLu;J$k{|#M9riB{{RN3}c%_np)BG~)G$WSThn>0E%-3{z1Rv%1ix5HSLtTvuB>u`Xa$%u&N>yt9cn3rWQYAl#a5i#} z-k^O49|pN7o=!spmrsBagU(=1f8v$A9AoILyB?at=icZ#P#-1~7A@-DqSe*f$$3jl z9gaX#sGiepr>cE*LfsFb28Fr)EF@yn)iIRj&H`!O(})g7ec!QHNk8AC1s&!>ixt2U z_&85*TRR?-^fNBd!*De_h))xbGd8l6-U&=fGP0YNheDuZEXf_{!UE~jEeyD=Acr8I zhdFtiavgpyEqq`&zRt@dd?hY0>qjYMfC+=Q)Y3NJec)Jxyyn_)K)`33GRa1zr7)M) z17vd{EHlnlrxGqm!VoRFwH4gi(49euS&DFIX#&pti$goY3KX#=-b<>Q}Q!H zE^5XejXh>B-^PG0FefD zKpo8=e1BghoccGBexE$|L6#4>?YY4N?Yg9S@Y2pIcrlv_C3kg%_in&p7fT-qTdaCr zew!k4f3(1Dyyw@&SvVR8aA~=_m(JfqF`-uvS=N7_QPr!bXDq)`{QU)2F4X$<`{e@g z@m?IU|J_iqRuNQaE)Fo+kfosr_|%@b5Bi{+)KIqi`4Nfx7R+wH!qLqlmzi3zfonW?LWBtb!oQvqH2RIUBU{r5w+Z?Dtb6nby2$antg&cUU?FLJTx zs_oclAxyktq@(fyI1Ffu8B#J@3G$jzPFv1pvK9^(^aUh_i8e)q`YFohqQ?$5mz-*NQU_6#XYs)tU6`!$lCAj zwMG|%{Dv*eh7F<%b?WfCJA<0~&CT=moN5B<3o^Q`Jo8V!M7qlEnBD2{o@Uw$gSisDjZ|GtK1cgh8tH8n`rK4?3j6enc6)^zrYU!O>@p6dcBG7!lZ>tGvS!+M zM14&Yt#@s6o=WXr%`%O1x?!7lH`@fPi0M#d9|W;!IuR50@LobkQBRupRO(;&^zJ;n z@8BjTBPq@vX65AgXw4BUCM*%M?byDVEJQaxu~$37ny&^v9BOC@`*m^6 z#aQ-7sdi#hVi;R3tA5bzMR)7nr%8ufE~_iTufL?cbU*NX<+s)))b?Cj>jNS`f4Q?& zynXQq17+?gsq1XJeemn8k>cud_Xpo17P(`7`mV>s9K*#9?Z-4Xf+HxiF#|MGCm^G) z6eO|3P_Ng?`9q6TmOcNGHYsn~?5=WNNw+b-7v8qP1tHgYttaS~KOy%5Tp7n-O!;}B zp|1+AjCaRP$J{wB*)kxsf3fD9jal*eW^z!Dkx||v`=YDC_WI&U$JK_O{i)!C#UuUG#9+ zzD>2^DyX^h&BAw*XG%NNy?zj@&V9uAkK zx44!OChH%@-R@F^0=})jEkieMI!7um+3i%w^tMK5NnwfG?&LN`DrrQ)W0a)BqRzkB z`4ZDvX*^ob)ZW>0>Hp?pzi%lU7V+S<62*3)X?2vKlix?*$cIu<{!8BDtuYYbqzW2a za5*+tB{s({HZvkNqb$}g11onHle`~8#2BZoflWk6XFK1_(1;;zkINmAD$coCBo&{* z7$0XB@1`1`78@VaAAi3*K6yVr@^XSVETPaOzSTMI1tP9}DWR@C;qiV#6C&}qdV-!> z;!mf{_Fn7J-l{?e!x(xBYS;Bt70;ne33u4o$9=iRXk~|H&e5P_4*?tYN1M+$gI(- z$H6?9mGUg_Th_gw(}V^<_4AsN3lGwl?#m4d$}P}94&*7G`+GTF$mU{|#td`ryohd6 zOF!thh_2B}$;!TvK;vlAeLm%W%66JOl{m2TbzZh3GY!t04xt*oFY9OtJ@|vAiO)^n zXM6q_Q6||+*^f#2=A1I9k#rK1;oh9wE1fcyn=+AGFezP7p#l1bLoekPuDmE*TP|Eb zFC;J(tuJd2m_FKB4jn>jINv-j_Bt_JQx5!z3<8ws zb3RVjd1nSwETBZo=CD2Dg4dUbv}`a{h4Vs0Ir_u6i@Z2hPIzuYAj&EW;h6 zX-QKReu7Ibfb=n51fGhd)4bxzSz?=3G9Gqejl87*=&w5w@>=s8cQftO+cHM|NCODJiL%EkWALnpUT!GixavYyVNAakblk5{=~&skyNpBf?Oc zb=iP^A)ZZ|H;1-L<^-iIoxz*jagn}KYsz{aAzl(V78w0YBe%3An8}E~%G4Dn2CNn5 z>x|^CtEsBoLMt!RbLAA3;htKLJv}&l`o7lm8PabnJYC?_*}fm7fBN*sNQy#SgIj+- zQk7{yvkMG z(rkU(hvAW)kgh%M8Zo8M_yvtaJpc6-pt;@_(If^}ro(*`s4GGJRJw-qVj%UjHY9Q2 zZfbWtZ}Ssi4pq7~Rf>{Fhs=37<^JHM6L0U<4G99C5yy}}!Z@ma&#oUQF<4_=`A)ilm#UDEXkA|9qDH%LMf zxx=S<%Y-tJbA6FfMjaHH>0{)jEi&p7Mfb$Xwtlh`xg`?{ViDSV5qjA|Ly^Au9}c}7 zKrSlRFa8gQmg(x3yVj4;k(Os2P?j4|wHT27*`HxIpxHH`wKgD@IFL4n0K&u!gg+eG zM5|xtC$eN5X}N|>Y6R=*!1(~7Id#yvU`VrT@Zlmne~Up?ACwl+(f!yn%d8*9QcR*+KA| zjes6Kqy&Pq3-_x~5!JI2-NXzCf`}eX^h-^T*#J;c3vwGXn9Az*KpLcYthOvdI{{E? z-JF6{&@ClaUpKJ2FpOOo+J=EX4JN-%MWlj9C{qy$dy+m|yFf6a`Zu)tx2_E)1(Ql) z|A^8yD5%Y~DMB#$-WtTllaxVcN@Z|IGyg0Z&?mu4g_^;xR|aCQ|Cjycih(k;!ea(0z+nE&tg`UXokHc!E#g4{PYW z0{X!cI&ma`0mKcVDRz?G)@E0m0%WXHpw{vAptz$M9{ zHdIrmiA%;hGs^X^WQ4CE$DrzC&_RbkuJpt>RA&Q+cf0Za6CZIm(n-Fb0f6NA*F0|! z;-E##X@t!*q!NfGW1u41uMC5iS&kPaj^T-z75YZlUC>yXk1t@_ ze?r^qV%=~a%pY&MGGz1WI%KJERwNXrg9S_7fv$CL>Js3*>~LM|E4lhtHovkIrbQKx z)3}wH@;rCWb?HrevI5>IM2{oc*#SJlV&NM9`piw?zsNKOHcSpt#=*pO1`SeH-gNEK zHw^ASgBs|XHLT=Op;l9LMK5-t47(sX9Q01m2A4bhE^0?I5n4Yvz)uC#mZv6HDczl0)%>R=+t@@Wct&#Nx7{fCx_+Rwt|1yU654H~a z@38fMjN$$78qEJ|fcd{A*T5d$|AP((;7{J;{%>Rhf$Ry(I z!lGhaNoiSmMP*fWO|-HiHBe$^R<%JTC5c`|*=SrU%FVC+8(5dX4UNYqCT_FXn6$Q< zSfL<2!z+Jg@JeXJ>`YpcP$qUlG{vyDA3h$Rl!9r6tY&01^lfa!Xuu z)or6KY9ty7g3=dgG;#5PFY%i+>L@{4b&meb;C(XqGlN$t$K(c5%I+tT^2Gl=gJ)zP zSF1!PU=&D((y6GP`7?uOfEjV7~z)y;%IGkB~ZAh{k! zg;Tsx{tC?Cq3KX{k-?(o1{$0-PGBj|u^R_^g>pXZdRqASRAQgYWCX7T5{F7E><3}{ z3e8B4WUx5ufpY^Gq*VVrFk${VZi0;dc!@vK+f3l0tO|kJpq`F{Qm?pGZ^@HPJv;(`Itxq(%XW{OX)r`@wdQ;ICLSL z3={{#w|vaI^~E>N%!=u_03`-)G}I=N6SnYjzSn~1%;i+epo33*E2J~5XtN4h75p0E zH+PO-x_dV*wg^RHPn;j5%qYC##msEW{LpZ82_NYL2g9iDgPjTf&`lz1C&dTVSr>M) z!V)7sioQIV4zy-A?DxqN=?5qk6V(eTsnB?X1lcae(%6U6(*?Zn_s8^^d!{xTu;m%P zH;>V#2dp8#OlMFrp!c8*EBW7y_Mwn{@5!OwYA>3#2Z|NuBALq<}U$OZK2Wqt-=Qry}Wm? z=HwV#VTg2%N{wT-tq)U@O3k%0S0jL&kCgo_z+mHL71;e>p!+#d_5vdpkb?%-9ncRj z9%@B~NUK4wXZ5X`RSk~Tr0FMrdv8v%#(UUx%amlk@cXCR<)u$|_&zn==s&Ob+INYu zbdqc5_9>bJcX(TV`vP+F$)Z5B#eK?fi-(x`s9+)SC8hL~ARb^_?{dU!i-=_J^H$0G z?^Gw!2S)|{)_nJ#d=vKn1FXyb0@kEl{u{9$L;N=rFTXz9in~s6zAdZkAuZ>ihN*?} zWpkbH;9{Eb6tWq^SZJOiRjX=An}QZpRto2cDtX;WazYa9rlHrX>U!IfkL#edqS{Nl?i|2~`zxv^fQ z`@Uxk_jw_>>#ic}8?gb+Thv-o5s`Xs7nbm`%fH<83h|^5G zLn2%aiH_W?%yWo#iRPL69>Hbnn^)C4XPT0e`!E0cP_3SE+?2u%h|_9-IBhhQN~UVh zMK{`|Eb5I)4z_>IE#0M|_lYg5YgDZzPX%UgjL1KI6$$=HxXufarSZ59p>iJnz`Z~2 za0wP5q%}ry$Mz+`^cfdUeBgseIQmt{W3CNx*7MNp36~;$_5)hjd*@Q=t_8jH6Z;wD z58t~cdNlga3<$EskREbT0*(yDLy;-1<4->wSs9N0=(wa4o)s7U%fKGE_ner>JR8na zU`ruDLJ1QcbQ!!Btq#5?oWJc|&i!zh!h%u9cxavt9yz)ncrQKQ!`p{MzT)o2&57Vy z@9GG1KE0H-`ImexHPI2Zo8>a-_l{wz_n1P0G^8lq5`a>dbzT)Ybs3mpLi=2Z!)?N(WRy_TVd}pG zFfA%riW`K04;l6R%t5g;YM=zN1pt9{GTPSOX)3)!bnm)SXP)EbmOc}~I~WG-u)Z5~ z%}1(WaY@||Z@$uYb{6v)o|)&@K8c{fzrU1lJ07h1G2~THy++8mMM3*O^K&>JLrPj9b03TDlzOeP2{rfA!AkmUa|Xmu~z??&bV=O);|L92{)>G2KTX z6ZzI-?12!kmk6tvB*!UtK&zO(cB12N3Xy5osp|INk2QXJiRg!vo9}TGTZF- zV2PcLpmE_-$hLj`z$G}AvzT&@v}hkhk3TfJj_L5bAyO-?<|1t8|2hm9F66Y3F>dQv z?6Cr2Zy(v}vaC-3y!N%q^&;`zofw8i3HR0lIGMZSBgxloR;|3{N$yszoxO|f4_e#Y zk1VafuRf-bY|*$u<@R)Ggp z|6aNt&*=QTG)iOp0cvS46{Fx(24ef6AMIZ9zN{%6Pwhr_q&`Vz6(sTAwHupk|1@fv zWDAJX6JP`(OU2^>Wlr3b-_+;Am-EXDgB<)r#AaS9Ci_*W4tKi52l`j#XO7$h`HDR5 zfp2%eP~`BRm(Dw_=a748%sc3m?eVZ7p$|k#FzXMST5Gh1gi(c{*W7+fwfzwAg)e!y zE_QxxcGX@_P%8C4SeLr!BqnhcRkCVFzLM(vc3mJk;#xroyH!84Ne|RF4w~Ahl#NgR zv>;#E1SWY*Jg*8iRASq&3ko=QqzcelcGs|&ovqFH?_9ltkMte`Wik4GIfwHdoJDl4 zFxx&LJ@QL_T8-VU>+al9vV1@Ba~mv-iy(?GUUQf0qm>*-Is^AYrOTtUZr*;+jk8n z4iz$T{>tNWrsf<@MDn0DB-1afI5o_g*q3!5$?p6>ogutXIDE`Fyb3sNa}E=54i}8I zxyEQJ#TxW7ppUZ|r?QyoE~ap}d5+4Gye4#O@^Dv>W7BhMEs%OAUx;38$K zF+1}VnpdNKIoVPh&=?~k<%#^XW}>vJF>~Aqg(d5`uxR|Em84gMhoch0K2RnnN}I^< zkUm16NBJ|oLw|G(f+2Do8k;%rC_G0tYF{R1NhXd_CIKOn14v99=iJs+&)D~4$~%vv;IlNu}LM>No6BR z75hn5h~yfnizIWSBxAK?Q^#cA$YkTnWWWAo!`_Lh>)W znGB_%;Nbj45X470L@Em6Ya*7(|H+1br7FzaDfs=gk`KVzr9*NWL1ImyYc@*Mx#1*V zWrHDp4Z<$8qN=S7!H$wL#|~2TakoeJV$LNLj>QzbcOIx z+t4Xa;zCBFH{*VQIk&XJ(J9+%hQ8gB)vq#X&Sjp0TOmBYT9#r8kIutLhEls1k*|r< zf?{nB40(X?4mp)ewu7tu>y#_@!k|%yGv}0^<$Qci%1ge2UZ&(9QpuZV@uN%$ks6?X z6Q}I*oF3p^r# zz8s(&4V)Ry!(bp-$4#~XJ$RLkNMjmPDHreW4R*IQCe?H%nol$VdbwKmN{eM_U{e>O zF$#1qXe)w)tmBVI%?PDCqAH0HEvlF9rr_o@R)84ZLvLQ~vqUUBJ}rIeT7{)>o*%u$qw z+*#ozJIdF((s}d2)x)1?82I^_HI*96A|wsM62P$KZ6x_LRFNuUX%;Gn=E^j@v8XOW z6Q0FNOFtvSCT#rRv$_m#lai=7@123j*Ziie2Nw~-oPk3mpcke#X}MWjBPepi+8=B*Mn_vM}Ed8lMH85t$(Uz-6U zb<#MT?sLOSe&tJXEluU+&(=m;+(u%`7w2U^`b(55NUqS7<4{*uZH1=7I1vz9Fc-h5 zw_qr@@gHzfo);{?LyLOl>DH{qi z1dNM!ie4vbhGv!0=L_&l^VygDuq<~)RK5eX=(2QCqZFrI8dlqusRf>mb87e-yF4o@ zIqu>YV}?L!n>l$K`R@kb?!tC*kB&dTG)w_3$)a}m6=M9n-tJLiZZ=@T| z=ar4nG$5@n!yD&rW(Bw4XuLzN)B3=G2{>N583WU9F?7s>d;0 z1>Mhf47olHzI6?vfgY6W0$&Dzb-|EI*HAVdD#!%m2);&+_j3qmC?Qz94MZ>ijR_qX zhbLHI8g6+E5wn2VHICU~VQN1iwsSBs! z2tP-X=+M5j0XQuzi3)N#70iT#h_FKK2onrwm>mk*iW;9wy#R}lO^ICtz%e+ZZgl$+?GdaJ@i2;O|ueh zW`OWuQ{k~W(9H1!!W>1OgoYm$Oj$OLRR@C`<%lro$*+kNb{Hr?pBXSvOe35fVAhy% zJM`oqW)0*KJi%8$L|kl8K(4kEhTEZtqzG^>fN0_Ymw8Md3x3}(ID9PJE&F(?j`FD z#xg$S5z4tatK3lY_wuwcEXTE z(0oHZwCU%Z9TxIlZj2EHU48Rbh+^woFjQ1wY04792tw`_zD<{h{}2QM;je{35S6Lf zM9f>(~`W5LMVAQHVI~eBFa!8YIZyL(v6s!gcWN~3MIp@fFOdFFboC!Go|AlzYMP{ihrxQ`u*6cjZsJ zc9nlZmevM@8c#HI7Q$YRPwot!Q2iHXeI3Y0--7OgqXBG6Pfrh+a*RNbT0oBRnj$wh z_usa)tgP%`9cf=xRn^&E?;CBZ)(>Hk8mU;n)% z$oZd3f>&dffh9p8CH;?Wt&;IZEq5KLerOjE^a~09Qmy}D)-HcVr2n_ckH?Q6=jZ2_ zm6iRI`~Y?XqyAQ{yARU-s(w7~dzUxxzF_3&*}&_6W7bWtj{h+0h5yrN;L_e1fUW<{ zw*K|&H}H1-|N93pYe=}!C4gBonCmkoCUR-nt1_9GGsHv_XUC8vF~Rfx#jI;V0#3CloCHg+8!N6X>xirNGJxYOm zw3y3-il=46DL-z+vj)`mk%^i#OI!+zN=zUr;ZH9((BhfQm-0E>hBsH;O_hzf!;0x0 zWQdeb)uO)a7##%`iP9`|@Tpy>Gx_yvZA`-Y_0uUL1FA54(m6p@83QacUA=ki{fn)! zLfN{yH=RTKhf!+SJ~$bpkdD7p?V(joG^K!50o~KB;auYQA($x{e&2D>8B%R#6OcA z0h6k}v@xB`KSOy6vVw=>-p#-@s%KH*pEqMrAYv|@5*0zg?1b>a5}nBr9S%b}^!TSL z&ld86U{g)mYu*jVm8;=oucKBYQY6|<)f(CKHo!(O>fT@)#>W1KM!_QmF#G`~md;R% zpb`y{LyvHNzJdZ#8L56|_ZA^hE`^f6Z?vT1sB}^bxvJTy;<;%$qjCWgA9Ich`)Wu{ z5~px_Y)&a?cG4dsi=Yb2;>gP>r?ags#YH+-N|Qvo$y8R_(|yr-%gJK3$we8iiY-8i zvzKyE=~37cf{5D@IFyKtP8kaMQ#cGH%`$Q<_}q707N5lE?)Mj1ef8Y9{|dZXg(6FRv4v9NCX{A8 zVZOALy&(MqTk{!w(ogwOJCCm@i-Kg4oZo3FtEd zw8;7^DhxJprLMo(@srDOZwF7;Lhpl7d;HUUTO3z7k~S+}nGjyqQdn)ybGPz%US5qYTbr_ur-^6EG5sD+%u!BgHq3DZA0(Pgc5hTjGZ9;vcIoF6o@^4l zi|@-@k_SUka?7ks*)Vr}P<@Xxq9ru_==nn8yPIFO*d-{83@PtFiA#9t(eksSNOPBCd$z80mV@e7c~nE9cLWweEnu4ko49 z7{}T63@ZgWd-89I!Jx{{JVXW>bcf5m<>@r+T9~`E+~QHLcl0wELyx1G4{#JIVg0xz zPoDkoONby1)w=h`u>)6a?}S#Xwu_&{i7A!RUWTfr3pd3BCmQr^ISG7$GYl4MvGjFP zL&AB~^wwHiOd@(iyschIp7rX?FBym9x^(0G>dV;4MbsreG;suQ+oCQI!wTQiQa>|t zQ_#g}2r++3O^PJGtSB|Ap>UFx`h1&zOblG9M7Rj9sseGr7s1}pAZ6KC%6DyPf7K*%q5LRT0~TnUK+mn)?? zI?m*^Sn!B7o#(xwBg!l7@mAmHxtxL{%qEJA*QRZp`mNQ~f>nX{krDHVe>GQ$VW zG{)`6e2U0xtK>(e!|3AsK!j_FQs55tFp7+PxP+RrO}kF?&`b&C;4bXz=_CXFvr>Bb z%QwYbCVjJPGc(V5=M9+kCKEHtC$+F08k}Lldh>bL+-vNuR)$jnmRstHr8rx@Yqe`o z#j?$(l^+1Aq&B2dme|+MjW@W;-%>??5e1qH&Be|#V!@Yk_GOjK47sf6>Oge0HO$ku zjG8Y&?iSW6j++fUE2S%ZwOtJYcDslkv|ywv>iCX2=FP@V!<(e|pVA5}4NE8@4v-2fVj@BCU;E*=)WK5p?t`U7oz5520Z!bDn#?lJJ#Fyh1|o`eosHi|0nl zZRB>B1Zm8dU(aUay3{Y`Ct@24$624VGm2AYSzJU$a$$Z@m~>LV){1_T#WE|j)K^{qQR0BqYK>6d z7vn4(B#4mr;hV`r_HAhq>8nC(SbXDni1!i|K+>o7`I0gCS zrO25{O4c`N6cFd>m+YRb1PDEfenPv^hLV(9dgENFwy{_~X zEbF+jP^+Nb8Kg}G;&eRIW?&x<7{r`137bv`FN;HCtP$LeJ*faG^-YRpMZ zFE`h~7izU_lnzG)%@(_NA2u6axZg4<+RgQXU&|ivm@wh>TbxMVzDddX+L-o-z}qad zmKlF{H!(!xJ z1tF2q?r~3k(cpsvp)*b3m926Wlc)cp-nx+B3m%uL#Qe*md*R1BE;4*9zAyj!dyhD>{ZA)dkU!Hmbt?#? zw6p=1>>*YR90qR3&bCm0UVQXHJ(Skp;<8s5QBD|hdsyc}7zIM-5+e(e(UJ>6CSnx+ z`9U}rID)h}eAJVM{S1q$zHks{1W9{E@Z?0uTn(4mh`5f3RJw{)Qi|N?j$rPM1ZO^? z-3`C(9NA0!NUtPvdppuCBb?PHh=e{Q_GT0^HqbaMYOOqqAuL)e+TX+`+SdQ3OMA3& zmZ@G&)cu@rfZ}2pUHoEW8j0vVq(bv(V_cLUoVCP+tHn~6#Ga}?^rDWvM;vUikBW4# zdgvb=A{9sGX#4;i7yT_RPs77$AuiiQ4I%8m$q-l4PLk&k7ptLBH}Bt+9T&P3pJEcP z^IQ`-ee1nnNO*g^ID>iHS^T5tnmRiMN8b|gv5)!?vF&H7Lpf?TUqJ7~y%gILiTu1B z&Jwk0lcF0nX$V2Db1pO!r6Od%M#ZV$Szls)e&u#gb^OvuqIYz%mA&pee?(t-@EutE ziPVF_wxoe}^>5CcJ*S?2ym7zwQ|zl_4o0-00Z7F3t;ju}?VMDSgJ9#4B+XMT-UUs& zio}xG$XnHE{sxRTaPUIA@$;MzF6l__b0wnbJ1i}ClqJCB>S<{XX?<;2A*NItdr*Z) z5}Xf&4nR=XK)c&h5KJkuOA*&c-$oeJ(@Ea%v5?foQ<>S;FmGHCcuCa$byvt?}j= z&V%Z0KrPYfvrV}#)x9kI3+VhqpDt_E=4ve5D_jh49E*#H3J6?}qom%5yM3$B(4=S$ z9@53R zUF1z%P7-s&GNA@M@0|ClTv1+`fEKaz*(}(&_3BgsR zfvTk+(Pbgh7ak1AGCr4LwWX3J?uR9~B*bu;{(jjctek|=_v&JCnqzqv_XGa@*xP0) z7S3fyn2OF(U!UmG@u70pp;B@~&-#&yjQxtb-SQglO3UhUOU(+t*ot?k;v9Q-H?vBQ zJgjFtML=MY89(VGjVi~yd(JDRK4$ln&F+WA+hEMp8*Y?8?5K=0vr9NMdl>7oET#5< zF2RQ{pTo4^iBWu3M@3qmmZ*eZB{TSOMFyFfW7*2RM>3VFBd~Xcb-9!Cc-IC~y*p z+$9N$LD%i)Wp7JM7!fsmlB(Yt3zcOs@)^~f&6R)rU0pk?;;198NmKP=%stWxINE6D zS_MhwW`5(Zf2E%LgT$9*RfR1-mu8%V?zYAY?=peTlC{sx$~4bDjyySk5uz&|Bh@MY zM7){H{Q1pQkl(GQi0@^^Ube$d<^wlGC%2ANRC<%^Up3pSK?3kb$wG zKibI6FB<$-pYghulI_#SvAj6`-V*+i7iRYFIXYQCX)i=1n7Zf8+Pu0adSrTevQujlg;sJn*h9PG!* z#_KT8!n*o|<0k9K=2o9fk4G44cFEieTU^cTUwyth4)o}{S6F(;5#8IQJ-Y&Jz4<*+ zojpNeJ)n2Bby)1HguHY^(N#FgTK3a<+emU1`Kf6Ak z_pLBp^gr({61TwJxYqwVx1Xk?UvjPgN+KRzkFP)Izic+36g*H6RXh55K! z`hm}1bC;fLQsbB{)&{NC2H&+l;c*+hdM($qAfRSCh}d+{-U1&JFyvG^WUz*J|A}`; z4%ecFZ6}5vS`1ml4c}uOvL)>gndsNPr+qbZIQ)HUq{T?|waD1Sp=#W4ghhXH*Ffr; zR$M*FM*Gl%;89<#Fsv2{avF45+&1XvD30|Zi_};N${>sZT&COIfgTTB9!o1=G=m$X zb5l%e(oZ|bLd-)Of{{;MIjb|%TN8oU$GBjwR=!08Lk6>URNLfF(>}LkBa?|}l>Tzs zg&GYNTeZyarGm*8rHR98D3U72ewkg67(4mk#|biqUfkWGv171Da4 zH**T|df$U4^J3`O(6q zz@kW?ql9&+Nf>TbBsE%YWJVN+Ov6k2nUB1^i; z#kM8Yb8C9rLs*tXJXxu?V2dO)qkev?^myyaZ-R2qwvq!^?(voe#RTirwidf#J$Oej z^o>E$TH^$(iN{t_*UphJE3wY5W9Y84$1bnx?!EP0Co4|354+Ai&$;Nm!hzDq!Ic1y z)vRl~m7IH6tKCNGy|AKPF@yc++{`h#4m0+J77nVuOQdUV zz#Qf!AJ(rQ))gH#P$Z6i*!-51^qdDw;05nN!D&4tlqm2|?xWG(n(WjIki(gg&h z3mQP_T{@^VDT)|Sii&dL`mMFbfA4c%ob%#rJ^&fx88Gr(bI$v^0lTlgw`oiS;OINQ zA^`Cdp&l>6Kk2BC)OMW5_RF|ZKc>N@LL`2<9&GvpYC}b(H@+}~zBn8MQ}A2Z54nd&D4?Tt=H$pTTk6d zB*aBbsx5WOx}ZB)abTk+)Bvd|fSgkerC%r>!!fcnz$)dQ?9=!}8X$CvnLr(Uv+WvH}Y`|9!jkPrpn=03{BZ6l|^Bq`B}_t&otUp*g_ zKG&#a9xPR|VEf*viUr7DaKSa>Al#@C^!0#DJD0wC7Ii&HR`$z#5UTomChl1a9V*CS!?cQp^AsclFZrSG z7UV!@oc)1|R7EqS@q60&WTw}&fBlOz$O_%h@hm{0rR4X9_ulQ6(U!s1b1Fd@8<_h7N&1j!(crW6SZ>$coA7w}^PEJrEULJaPntpoyoU z1(DI>2+5IE?)GZhp7>tJO_2DddmA zLJBvfYXloF+59Xt>O30nA{2J$j`(RYurgCexDkqnB$?SeK?4L>bt?R6cXcMKH zo38fbZnQzhU#jj-9BfWTU4HfQq16RSKaR-6{mJ#mmxU6~hVd(SURo`ISv$k^$}}k) zHj4obDyGl6>CRa-Z|?;iO7@4UKe3G>XC+Yc^A^wC5P-F?EIC}Fc8yC)c7MK+m{b?^ zAw`8k^HwVQh;9p~m45QXLYHiF=t16@6E>w>CVop)ej^v@V5Q@FJ6o1+?_^HtJRQutMc1cy#pb<7 z4cgzwTsr8OiZJvR*)D#1(6#?E-}{A9@1?KZ-w%Fzzc`(L`t{{`Th7<6i<3)40)*6G zl}j#EN9?PUt}`Ie=!zY_J~SK4d&A;Z=X(i}v2r+oid8un+(;KY8WzsE)I2QGzAxP< zc8~qrsLTS@=dq;?uPZOEpX`5|ys8WTK6U+IwR&QK_wM&0UpX_^w+5G0KU|EMy;5<@ zw$r%lITva+et+bKUEck-c8}lPo)s_jPlXVJX7r?^N_@P5pFTIV)*bH03LuKZa}ggpDtog954K|s*^ z{;sgL2c*KfTwzyG)KaIhp9W*x2&Rn=*t6!NC*u2QqJpnISl~&0)NQo5w2OYcSgJsw zfV&w1IR0()>dbnxoM}yq+LE^y5+O4MhIEYD3`4N$Q;~uVIJ4{B>PpL-)<264-<8)E{ zR&=Smlq(!-qEmWt04`jQNec~U!Vr#}GF(9=m^#^|6`!(@t z<7$a2?FK*fZt6G-aaBx0PREF%W{0-A->58ujRYrAyN-@>gWVo z%P&jg)+O?dxP-oF$^X{d<@l-2e}f=pu%A|zC9Q(LDjbkZypY`>#dp^pg`Fwul$WRX zXb~XW zm6@CDT!n3`G(;PXDC`1rLQnu%%RS3MB{AtZ|6sDYD(m5qdHWwnPhCl}-$ctf>$%qY z;Al82K@`y9nbjaS{uJZLctaWxSRZM;|1@CDkdtHnqADR-tnOv4)sVqSvwF|d7m}k( z1)lSkC12{?Rhbs2^8-UlwJklbkJ@_Hx0yY=Tkn;{xS~H7*d~{^t2tP`QVOqc?|5kL z5qalwkG7fVz#FRBh|rZM$aZV-W18&rOZrXgZJkMd2mX=BcUfVB9dkuHUag;njwEO^ zUHJCAe4r!p@up1g1jYh-f0-SQ%y&QNyS(snT_Gqyz*pFEUaTU_!Q0Lvv2e!ZI{9m+7+OH0TI{;FhWa2ZiV4eL`yf6#%jYvH0 z1K|(y_1DR}mC-js(VIQMS%eCrm?i*CCzle`fx57QS`quSDI=VkFv}w0iFGW#R60}Rfwu6DLgHT1VRj9Fzt22`iiT~kCyz?i>Mf^|g|18hnoqqJoh_*eiWZby0 z6Rr6!9_JLd+()CE7{U7ek=DvaHUpWDW;StE&k4jgbDjJgp#&>KT$+ib;JZ0jchXdh zWcRi*I-mCozZMZx?-c0Y&DE>JaU-dS26Ms6Ha!2mzRIC=guo|H- z`TXhWs=wKJ_q6)0*iv$P%_lFE_fqF6dg#5n76}5ZrvvLcbx5AQm#c_q%KP$SHwE6r z7qud}%{M$wwxnfQfg+-(ykmvfk<_xoim{D9BXz5x=;BKvhXx{(g&v!aZroe{y)z+h z7ijl}dCj)U`=RC4z~c5lmULglwe2seew8#`Ii;@`-WYxqy3)3407K0l`j$JKy4L(? zb$fW|a{OSuN(pb;$L7mS+qD;Z%W3u0?CjO`KN#ez^If-vv$UK)CtvUUR*!h~Yo~<% z$7t%Gv%!TQ-zF~zUtV1RtZmqDKL%Q3JJHx+CoILT?L|A5M)(qJQJtin164~Q^};{i za7Cc}>2Xw``{8L3;k?0uT~f}^vr!RvooqZbE`s#)DI|DSL;6B;zN_c8yny|+i*Vcl=OSGBrJXbi3Z@41fx!+XPJ=XHfSG^-v zqZ)Z*==z--n6=xK>9;9%O)%y=-2RS{Z)T~R6zFe&k(Z_8fEJoqH(Hx^B)rU#I!J2( zL6NGU6K{>6(xON^W1UnGBf~H*O8J5AJ1wmz%pm0N&nOw>FvOUL4EQ8pYo?=G17G#= zoIMFriqR3B2Ggy9wFh9`LvT&2SdJK7PT?4%GVqU<@Q1<=BadOuu72q|w1TJ3%{;E6 z)4?4;7YiK<@$!)CITyaC#AGvhp5Iarr~njMZhq0Ou5pkwheKz0&Alw2l(S9nr`;HK zUo{^&x9v@ggbiHH$L9@;#^@Q%6Jd(77(FBs2Nt%0#G_=jJci{w)=&&gK$_`ks#FY; zJ_j=%%)!gc{GKJqz!YZY>)sH~Vvz=q0V9HtSpXj1$7!_MRY6Jk^cYDu@!|NSsmSsZ za7RnZyymlQlruQ(csz*hSw7 zI`p;YvMj9soe}=d@@VL6mE2kV7#2|mjs~k|Do2%%o=%di&!%>fq}I#;QYWDL)Jv}hI28UW$Z(`|SDOw>M^cQ3`#Yz5Nhv(nnI3JB(~ zm{AW`E9U zq>M=1TwBi4fJs>!b3nC@)qGiARNP2_)bOxX{4iBkcD~(G;y^eHi*NQ!W`5#SS{VV) z(Zxoa&sd7Z_()N|h%s3A$k#MrSfao0RI1%jBj3GypK&1ltxl>?LdFk0-8gG)BuXnv z<05uaJr{RYa-Nx6KJ5OxmkI|!=mUAs`D~`0Yzzij*)>jp(xO5U#t&umi$b|HWbbkCrQQr zT)~jPCO=wn<+(@m^E_aS+OLNicC6aUEpLKaGD=(Y>;jEKFB!A99-cOv*|nPcKesAq z%{**T>20+QwYT`y>hzh?!S3nDRXN6-5wuT(2?+>BWb0>TezbS7hmI6@{znl+Oac1pwm7s=SOU( z*|^Z@U2x-vuL34pzXN;08FO1H zLOOpqkhV#g%2L{`7^nWx*WZc`Td7Pn`BdyeJE+yiEBe>9>xXUz?MftP#+P#82|a<0 zZ_Jv$EH9!w-+k<^SZjdO_YC%xf07A6@Ul-or6k5m znh8F@us*>sjYaXwdg+3|kTt(NaiNKz^bGn8D=J5%dZZvBYw0Hom zmMLbRQsm%{Sp0+dfSjwzItG;%42!;)Ze?xWHr+FGgW$8PTD9zK?8e_v{r9A3GkyAv zZC!<{II{>;%4>j~E2+D8dMD>1PlxI>YLHj)Z;%)$#tUjGNpp*XmJV|PT}2EyiUCwG z&{WcE;~JF}0qpMx9WjA=7WQY(^l?Yg;2K}(H!(aar*c`R-a{1U5&*%X9Ou)#)=kd! zny>ftnO$pXy8{!)*&N;SNx#P*v(P2NQfo zO96v^R0Cs}L68a5l8{_5_n_wKt82E1hvg`}rmO>u%M$FuWqB&FzSEaAh*>Mi`}rssi4-%Y6W0kEDMS>cL&N4TYJh>4MwV~g_%{qw3?ulMWmHIjGGs9k%J4i*Uvb# zGuSOU`ohLpAK#^TS~tL3_BPmP^k&-PU5Vg<^K45bgur0@U4tqT4)d5p$XnP-A((ch%&xLnXBt^KD?5M$}Nz<)pND_8_U~_ zWdu`4g(fpcKKcypn7Q8{TgrxPcKFP_u-Vtpy2Zh;vrlz+j%J|QXX##ews@<2m?4)e z#keY={Lnk?gr6*dVd?#J%f_07`eEKOIKJ&A#r{EM}1p z)T+@p z!%;;szwBL#%O%CqAHXU0(7SbCJxRN!)o+kzZ_gZ#9M2EQy}uVt97*?lPe6S`ARx+^ z6J?)obw=J6UsrjqJImcV`W`?0d}3Si;j98b4t+xGxqhYZg4mzB_U7xs;H!<{ zug#;W=e>WWAO&FMh9a|Jk_uXY1CV?ZZOF!qE1-c*)Fz9 zhcXlGa8Y{S*WV=4&gh}0@lQ45Gx*m{Gh#hrQ^1*QfDjzK7Yr#3&^zlLCV=D1X#k3n zrF2n{t3I|z@XXS;RVGgiiaZ;`X)E;Do#`M>25HHx8dSY~6DCM$_hD50iIb6yp5jb; zxW*SP`XDj!y>4fKp1A?C&Z3D|ogP%I+FnppzI#W^C1pPJA-RBNfD2@i7Qn<4Ej1B z<$&WUS66t}ok>HffWM!9^+7fbf(c>0C%|QE>IOPe2xo*n2~gM#UqfGL0k2BfIb9~G zhRp!Tgx9c;NBsnvo!{E=C>>(9I;C|$lQvb9S2&c%0u@xq?B0XYvvZDW(jc3047Z|Y z70ywocJ!JqMH%6tP*y$~zg3hSe_AixF-nglJu^}tV37|)mcdzr@lacHcl>HRD@XV| z6Usg(9ztBIVx*0RBceh;Dke|?%X2qcIMF_(pj7XtJ204RmOtUT3M_)QUnpA?KOh-eY0Yi;W^T zFcPvSr8P_=$<3nDda0aWqd|<$jW`iM<*r(FmTOU1y9*^}Nn`{=XEgDRt+kJ71cl?S zFqrkFzS~nKX4@q?laph7Uj92{Iv^tR9Oo`T3Xeq>q20~(!B!@`z|Jy~%m$)_%4+EG z8esU!|BX$QG_++_L6zl*CB&0y2(DwS=UvuBd1Q@pz$}rt!@d@oDIak1Oj-blm8;G( zk|n~ZK%L$UMpxS)H!>GRb_wUJIp{nlDGk3=R;W&Au2;8Gc?+lTZt_-u%I4*~S^Z%e zOPT26G8N;EF9M<0nk7O$m~9YVZ9&yXXyFQtUFbY*74kH6RBJRL|1F zxC&f$ZqjBDXV~baiiv8PN9hecc!Ih;i`BfqF*`Q()v{)ybzp*{o&jWLDm-!Iovxp> zDO$R4y)C3v{ToWY=lx|U^gYCb$pSaDHVd<4!M1e4)XpZ z-DITMfSX&i8NG@e1(=rjt)KRm9O8fxMoF$HVgNYD+97-?z?CAuLgMGJ1s5uO{F68P)zdCWocL{Aq0d?!&>wRrOMRq%JR&}By#*|{%8Z4VQySEFb#bj7vnykO4UJ_La`TLc@8;5>_9 zN%4V5g_VK}cq5tVa-yl+(UiA@`tkO`N@8noNL${I=+DEy_d@4x8QNQS0FX4;aihAEh&1-lI2)9+_|Jk~NVA_MJ+YCNn2B za!TMLm~bWn^|et?GbI5A9}E`z*iIVjVGsb%4+zPI4giS#P0*TpMxPcI~F;|ES0feZC#izWcCi zH!3PBE-o%DE$zQ~neOiH@RptMe=2f&KK)Zlkk|M5pQKFb;Ft1|gSzpr&nAh_r-`JD z%&VoNzP`TE(b0v4h1VUFN}LY( zZjCqzL~^4|KbfksArHPDUbI2bxhAE35ZG8@2zaQG2OCYp7ZC~b!M={CVHR`rJ7m{N zEI>Osl|50{bw}KjoSG#JR6vbx7Kfc62Msi-z2g|PFq`Rl6tdKfB5}Rcc2M_Sz=K3y zY$;XJvUDRs#JspIhN~5tv1@5;^=b~&clf!YaSf5H`hrP#x$WZOeP6UtP=oFZ=Fc0{ zT??h}Uykn!x)ZSjU^23e-}iH|WXWWd43fgD7@-fXlagu4$7YBPz9wW$-&$hSDoEDn6yYS7ZV2E!jQOZJbaO76d;5(11x?Xj5EH zVqmXAPLj{`Vs`RoO-ES@VBI}C^%gLXH#GoRlbfc^8=940D*j74%abs8Yibk6z45ky6LEJHw=CAOq%N;-;!p-Tu_*x8L&Mvp z2P*vH-=y$YQosuBuF)S(oj}7A{o&n7G z(=av=_GG5OfuF7M*SJ#dgpuxSF7Sc;pS>5%U#jA_ZWot7eM|b9?C2B{IKFQtF>_V~ zMp5JaUNb+eItD$h>hUG*h2;p@R$x3~o9F6&V>jZ}d*bUZ@Z_%p;)z2i@eO@y#UYOT z;@7tc-K#1`cU_DW_97ZA?Hg9*iTHOy_sT>r7F~P7xVCMIqX4I!4{rbA*^InMJ&rP0 zkoeiQdF!iw!*y?kKZk}lHGc-d*SaSWz&bN6*lzvBL&5O9#KL7YS?)eXvY=m|VPI<0 zLLmQIB+7`e02#tjx4|P@($@qZWxs&Rp`uV>R8&{vI;eCeA`~E2A3*H{_{K!kQ6f3w zF_{(}$T{w+MFH|6{57MfX*i9?##S+ldc0l})*{oE;od2eHQ`REhfB&watJap564de}lQ^V!bsmX}RDrj05QcP= zj?z-ABrog+t`H-E+PRyA0oaKsqe8{kL@Xy&p7i5Pmo-0=7c7modF9$jwIotv8gA{#&wpm@}z=lWj1NCpHj zk8mfwpJCF6iQl-7GIv6Uo@AHL_3_s3xh}qz1AuTb$`sZ^8#K!}S4ADUEuMTHHu`IF z4qI9fUK7D7vbnQiQRvi?@cRFu<&A;sWRhy4@USVR@n2K=?@6YieRFr@LrwV`U$2B%i<;6UA zQTn8cy40z+1!EL}&r?hj-H?@(*(5`$ zJr;rUef$b(n*MNGzDQa)BL17Os)vTm^70P8w5iu(Zd7t-<%-PrusG)>k!LCD^hM0S zlZ*}Xd{9pUVoP|~1iuMMkJFh;Y~~xtg}A%KVtoT&KH1Lb5PxjoMdkPCTeZ;Uk;$ug zwriOJ68evyC`J4FRjgb*@siwGlyd(;Ev`#V!|7%rY=1}YDW|kNxwa0FvKmzve!ju* zc}G%A!a4p**ar3OMZ(v>_84HlDZK7KCWh(ulNqhG&10BAd2-DbG=fVunfv0P2t zx_BnXmX+ER&?>EHJcFaI3Fy4{{q}5@ZliTKyEBlrR?nFY;0!Z6NaqHsP0$Idkh}ic zn=}OC@<72d?WsM{z(-|pa!DQ&DL$;On{3A*0;8s&J32BKb0`hQORi7*1`mM?FQ+ln z)09xqXA@gLIqQ1KU(w2V_6Jw@A%cwc*%g*jUg7G~kUo_0b`38n*~P^&2-=SxK?6N;@r5c_G};vD7ipTu^KoNhf$ za_Yu9rTmEav0k~!+-N&qVEIPoOu2FFO0Xj3`ANrB%9cH6EONVOpVj8q*k0)V;MA}* zFRSul>0xM1XzeGQ!=u--G6CugMR|JUe{TH9$SmkcHtCj?F6WRwdaJgxwHrowU9=G> zN>eGv_H3N^*w&Y!O!dq4j9`w*KEF~1z$RpY;dd2DWWglMYosEiMi$IR;TTB4f^AvD z(kk%1Lxs}^W2wo5@=c@=!SK)=}n~)5_@uc#>3I&jUBQSE2B+Mo`kSVMs!Nro`it0qwH6RWX6}+2x!v`qp z6T^-oT`46o0l?No5IYuPi2=TC1feiMJ}ks)7tS&T)RP3Y2`7*o0x$F~pvfc=1c77+ z07)Rg))>$m_h>$nNgAIdiGkLeBF_x(jq%)OTX99I!grO11S&Oh6M36KV zs!zmSTT7{M2l8N{T_r!T2#GqX(!C0I^1Zl29Nwz4$xsKrtIo z`C=S10rX8FjWHyx0tRNSN!m~VEuAGPqhd&=6H@?Gn;6SxLUWZgq?aT~hU2YKQ1TxT zl4RIK5~_wE*_MGLdTC7YX-UMaCCN0VDIl5%(ZfJ=e1I&7#9};9l~i1br%jRsUn78Y z*1%5Hq=yLUaR;KXiA;^aD_CHpNAg;3E{7xwhy$PgNCCvRmMR^Wqqz$g#zHkD!Qp`a z71neBB;5fE>E~af13o^!|H9h;BdLXjh5Zk|K_}?HZE}zPVj9zbG3`HXawIdaSmLsD z%8F9ziqyYg?JCKRPx2e&zc(-X3u~4nSS$ZGta()Zo7e6){JTmntaXQkY>)nhYzYYo zB*j5tVc|cDgQlh?617E=6bEg)F_HHM@lPJMec zgSi#mKd@FvpUjXQp{hhvQCZ21w&N@z(Hf_nHf=#(VS7MuIgx7CZC$WOHjy zP;1A;mtW}DA96ov`jM?f!QYXfLYlLMdJX5b>*CX3l6 z64u^a=ehhyOp*8F2)$H6PaP|2XW~#Tl1%7k+-M-{0pC zYAQdr=r+laqlx-jhk9{kIj2Tf2Jyir^5EP3w&nW~{1|XB&{GF}2j<{}3Rw3W!=Kj@9q0>U{!`DW;P3v4MU$w~icx*-X-r3Uh|B!oXWB zSd~qe8BA`=$S?D%*LC(H?fr0jo|m+SM_wka6ucs<+0i3E`-v|+Kc^_X29=eU7N3^q zRwj~~o7-fQSCHNd&nwKR>8vc0*kCOvo}OaOEdd~K1rJOIme{=87%6PLg?Vl`<>M4_ zya0BMuEoc>-`!v_FqIJ=`ymlsK$_^G5HEJz@}wY6KxqmsIHc}gR+<4Ke2_mrUSchc zK~<%PcU1~~Hs4W={Zy5B=s9$clAn<8j-@E`dd8Q{Bo25>LFZYVn;h#1S`$P&Cxr&S z$d9X+#jh6ak-ExTZY^O2@bn4Q&UrXi;SYfFYa*-x5xG13FB6v}Jt~SV*1J&YINupLOj#)i;+J$R(4r{m z)0l7i5dNy|e)7?*%{^(3KK{$Dfd;R7l^_%yJ-nVgn72k_J!F99_H( zPuVtnbGE*J>SkU+6!Ln~sq|XK|7zzU96oF{z4h)FV}>8wBESIbW!z#zCf$HNk<;RQ zVG6^^6E5(vU>x=czM>-Y_S5P9qhG|y^Oxs`n<}qm5u(0QMqpnUE`x#_su+P5r5eI~ngl{m02LE9!7&5!9DJ8Fs4t$tcMuhNp7A zT(rfAC_0-`qL*7ATy08Fx?79#t_cVGwnWVPC$n9(x-XV{C3zK9AfaSfte_GSn8sd6 z5ebv`&J&0q(!BN4VhAgwG%e@g#d}~D{DwClY2U!N!dO$SZ2&!t)pO>f{2=^Bwz)Cc zx*Vf_B>Y;@Z$dOIik*A?42RxGOJS8s;Q3vx^Yq*;a;=$~|M*z<3F0ux)oYX5@Z{A8 zIPt={=q8uYRmG7%;pv%tlpmQ6bzfOEA7!2UyNEd|qHX5Wv*p%rfCGm|9ey_Fyy#>< z^Ln1`#P%(BU^bIWQ}|gh%qUl`H}y(Zr@pJ%PM$95t-C*b+{LOYZ?#;IhqKw(C*XPh zhuPFce2ub?Qa=FZGd4c3g!A+3L+?5f+}5108ym%GWrh~)4Y_AM;)+PO{(;;$+q<@& zmdM=8%71&;$wZw_(I zOiYwaIg>3eOva5e5kOUxUCyDGc?A!VeC;8dtk>h2Q3PEYN3?{vbMlyD8Es_g^Dmw! zgZ#jS7Wy6lxcj?1Y$2mI`K_c&*9s9s55v~Bton|q&o=Ma7A(r7oommz>~};LS|Tnd zVIOXwZOB-WPR()7oURHt73Lz!aP&#WYOjE$GiiZr>FL{L_XPE zcd(*|=5B#xJ(dW;l3KAYU);?jdqpYw+MeI{qGyk?Tb+0-YEy5_h-ZanWH#bEm5He%5>}Op#Apm`}c00e!6i!apTpoHt`{2;jKS^f^Gw^?O$Mp zyw*Th&ImNud}5fp*U7+Vy{w7E5UF!V>YUtup%cj{^)Vr&?r9&>fn@v*FDJGqivyxG zQi;b~PM?=+2H$7;CYh_;=3H1DlGpJ|vFpCA0%Wb$;*w5D9NXf%p*VbFfQr78O$w6a z+k<1hb(hU#rrr~#aLcv9rr5PH39%-RqbEw1e4?hle`8!OJPm_rWP(UKYnXb~3E1B^ zsf^JJp?KJ&B{`P8VKQo{NAN<=ng6%>>IHoy8i z&(Qv+&-wSLH&T<0?rd8c*F5cV&=ZShws&GNhc*!&$&o6QLRQ?o4n+oc?{ZzZe6oss zveaK$becr{@$;V$Eefm*U|{RdJd%IoYNd<;IP%RG~L@7omB z%T3dW?`YO(?|`TsC=S`j0;CvS#@^n2a6snM+3 za?Y`VBMbf6CMUD>&?ObW)L4}f0p=gWRr^;#9p@kaDtg^$zRAn}7?i*9He++ZN2b&T zpltHYP`3PfqBMSoxBEFB+zMWjCP!4#@2iEQGRe z1J-nzdKPKn_~RnNYlJNF7Y~JASp#TI9%@}Xb?9Z9?p_8oMbFWcnE)<2uhhv#NS7I2 z*9K63DU$Z0-FVA6gnR`3gQ!zS6p)VAzlja0p_0Pv%D7JY$0{$!uF=*C2gzvy9=y(l zDfyOiL4~Ma3cZ=Tvj4U@()O+fP+_W9mzJkv;xSlLTv}^eK&9=0UtTPec22tVOMn@3 z-6)JVnBFFm4#a`k=zAlN_AH10QGnOv$`QU7C@dqFg{cy;zs$`v|vMSK;Cg!eqd zere!l3nQ}=?lsfq6*sbcD5&mF(Sem3ly3D6BSR>Twuf3BvcIbcO%O!Zwu^L^(ml%w zM@oek=!z8!d7-L}%mWBs{Qf17NUY zU%(sMj%Qo#A(UUAWD+?hCBb)tsuADm5)GWCyShN*mkwX|>>px9bAw_;vaNM7?6oIUToX7;~ydpUoJ zl!T)|Lzor-+%w_PVwJGF-N~hT>5`t zr}!5~0T%zlQ5)00IBI}FGg#UD2SCUfkdQh zTi-YT5~kl`U;Jbq3*UYxC;-0jO8wiz(nGJ2I?x+9G|8m z2Qy12X{e`sXAzMc($KVW={LKj)iE?CO+XpoydlR$d!YS4sEU3s8D)iwY<+zCvZz{L z!u}c=gR?X``d4=5<|~sbjG89(E@(N_3Q25 z^Da4O7RHl8CV{bkK;|q%08(RMTNfd+GqLFV??c)Fsn9;5Td@!hA9UIVelb14UgWee zC7R>3@R6eBmVh?3LZfTUs1)Y5;XS%?EcFty{U#7K1AmhDIDu7I{XUItUMZN-v$`x& znyvcDV-1QY<%+!d)fLAkp7=_l?}Os1+fD|w)#GVhg*C&ao`tpjO%#Ps*W%nt@in&0 z?}J*{gt&~3Ocg)*b8wYyJsWS08%~Jfh{rxNWE0|k2pJN|NHFaRE{QXp@Q4FbJM(@> z9iLxzG?0tB;v~};D1FCPZpebKi>%?&eAG`Hc5lBU3cno?+@jsSt8nX5T-e?^IZ+Ta zDDRcEqZ;fCLI|PUa+lv2+F!J-&d5*n=36Y>Z5V!Md7!fcXLTvgk-NcX2-c%S4nB$& zaV*JGbJL8aymwxh6cI33H&J2RPI!%K7j^5~B2bb3R<2ODyk*qnY@J;&vu~X{b^1~; z&*N7gKVu!Pnz{Js!SCXwSX{l(@~!9Z+EzUJIonrbXX@MX*_fuV15uufoOaQ*?}~tP z;lI9zyqoUeYa$9rSfx{pE#CJ}VV@}i%iK!tFv)2-FWR~%KhY_;|FJM@w}{GTXV8ZI zMyLJU;ln`xqrI7;o~ocvCh3$|uGKs~KjDyM8a&mG57-&<;}d}Yu^uq`IyJ}rp!a2) zaT2u?^OJ+%st+g7sFL!F0s#8n&#fM0VSNzW^_^e)J=9!(&cDxl-OS8iD>?F^OZC=! z(0s>si1@ub?O0q<))Qbv2I$P;A-YzYpos_09sR$_fZnXwx(DP~2xKb4`vp6GU#Gom z*f@&+5)VaUOdF$;NwmN@CzYF?23xUYjD!k?Iw)9^y-z$AaJKT3VX^C5wXl<(Gdi#9 zv}%EM!+!S)j-K(x>s}5(Jd$#dfmD98YVY&V)W96^Lhp^R*#H?Mgb>vR(-u4-OD?eH zW9_uot|Lf2{&FWra2a;>-RdFTcLO?>Nw>Za=cd+S>;MqcupWeEGVz`fAJ6*ztNM=+ zQQbeT@v+tn8}qJRJoIOuK~FG)vkqEoNN2Q+m56JS zbKKY-%WC#=kpOm%*2nwh_KCU*hri_&)7V#@xS99;Q9s&@<|y6UnH}+Eu%CN_SfED5 zqwqpx!pGCUP?dj2aePT5;6X-_>x$s!jQ({`(I(*8Se4po-t{BNB;^k_STwo8R0Iu! zO{ybNflJMKw@1!6XIbUOq!8)ZC1n zxyAwjc8F|=D=*KeHlzZl6?1iEdCEluo&~JhZEGs?7}vK92PxI>T?kvL9Ro5X`X6*1}t7n$ycTk@}dBunv8qT%V%enR!0QMQp5EJiGA*`Gg?YzzbKiG%1%2SJ+GU~zw@Hpc5(h&OM4GqC}?E}&vvDDp5MhS zTsc{MBD3;M(WdY9{MB_(OJ{y)gG|z>;hs)p*Q?fp<(s+#AT9d%#jyisWu{gA5!{R5 z*U=%0^F`W6ak$U#=reW5KM*zUD}Ei(dU*L4J9nqctLVG>$yN}|OWVVgZ^?8R#<5$T zY<(~E7|bq`7d=1xV)G=7v=F1mpE_!WH}|(abn|MGTk*&Y&hKFK_0}xhV0sq#rUH8R z&K>qmq}`X-6ZfSOZ`EyZeeM{LyjGv&VtAWpCD&6SLh0gO`A~{ohw=6-7d0^^Ts_+n%@q1nF;>N9W;D-R1`Gk zhWffR8FC<CD0%gz zJL%0TF0PpMIcR8yy)})d)!EY&ejzEZtX1AmmDVFVp-Km0zBzm|&FlH+$fHsln_*+5 z#m`H3=l9b53{`XQGW)2lvo}7g9runW{z8B!te{`)ciM+y=giCq^*&j3>13h8{U;;i zeP!w~{=Q4YHC)WMmpC)E3Re*Etx-Nfa7Asyq~Dcs3ALM_$Z2anZa`^Tqxg7YnQzMH zF?l)0k$?Lns2l2K8Vq7U4Grb7Jg7CqMaP>Rw=1X@!KSQmn<)<2HXhTy=#G@0?`{}*p>6&3~mwrfuULrDxscju4- zA`aa!bf<`bpr9Zj4btGy0}L>9cStBLQX(QqcZW)-l){?l`M<||yzBec+Fi3f8?yz+ zbzkT2ynZb90Z50EtVlwA3C@{sD{UU>!0N#_SK>%%0eYI$kmNXFl_**D3)cj9_VqL&|!e`y+Y0RZ(b}=bQ^pUIlAFBJ4;-9WwUGRGa z`#ee8W88C5l1q6<-|!kU;G0LNNUD2U_{?{wYRGc@OB}mpjZ?#z&AS+NDBH6@R`!sO znJ=R}d5d4T{k;RYixA1d0c7wD>?VzjCm5~_AOnc(+$LA=<6bBf&PQvN34l1pUl1v!MEt6c_!K2{zb)kSYd|pE zTWnhX@RZBZDdJg5>7tIL4Z#S8Ohm9O0TXdK326*o z?dElnDWpN2DcKx}A2Z3A2u z3Dp;e-Vuu*U!%IYlNgCgZ1{WwzJpAv>`l}*O6XKcM6uIoE4s3U0d`~(Ae(3llnNEHXUC)Wu8P2LnPlm?zWvC)4@A7_Lud znoDN6NM@r?;gC(?vPj|aPvOf-5ok{lnoD8H0&)OAOsgr9u_;Ulh#9`q35BYmff9(+ zVH{Af9>ma-!h+A!_9=8nK%K0#VKfl63Z_Q_Y3hMW0I1~=aF`8ZKap;af(W*Q>=5bP z7GPT#fgYMv4c`=M0$D?$HuX@aIU*qdfl?0<5hSAWW2_i!@CZ+;v(~fUDGwdgz8SS8%iF7d}FkTZV zHUYIb%EBjX7Z^dt98t_1k%c`3&IYo_p|(9+auzkb_lA6hzXhZVJ}@91>^+~NK9Z@*+4<~ z2u_hzI{~$yBT`+>eKSmCM*)@u5E#@KntFm}_cH8zfQ0+G@X%b;#0?|?4Ww|(u|$Ht z;z00;d_lK=wE7lo`Tra!a5=Roh&?VHP64vZ!akrcu}6X8Wm9P;Km>7Egh0^{KUgv@ z_c#APL43*T5kO#8UzC6Zk8W=^NB8AS9j0M?yLSnM=rRZ;^2zq9&Rf6tXKvZQ@{=b#6<^PrMC0Bp`->tEw zrR9ID`2T;tm+)!de<$_-@V&I5|A_IKB4^nnX1M-M>i^ku{SV*!PfY)J&-H&pe2drZ z$~PQKH=O==$~W-;KI4k7j5|9!BmeD-pS@GbpAh;`1okv{N?!noXgk# zi}l6l^6jI`gVX;6D`!KoFO_ zL1z4_t3BS3&z->-+OWZ%I7KTT27-P7fb<>leK z$FLfDV&9X<$oaa@8#x)p&Zp0^3m~=!reRq{x9oA6yWCYW5Gi~9m=7j~_xx6w29!~^ z_#ijcj_IeutpRM`)*t?x$aeP#5=-R>^ctMj^@ zPply!t+ z_l%1^3u}Xcq`7*A0cD3u4#9|ZZoT-9v6%ck>Cz%(=XAAPfh?gj_stO zoGF^NjhiC+FA9r-ZlP(C$qZ{x0xU#~K#&T{a{Dy#w)Dz3-(nJEE zxNHZS*lg+q)%1We@GVTXNgCNimO&baR=HaW)LZtT5PC9SRYwG3tga_)7pQLN;W(&j zd@J5r-V~zrvaH$8kg=pi(~+^bRp1#(;Tz)cm$)`a3L~!lx}Y<^L;Q)%!-g*kDnS~J)c6h5h=@F_k-LyLjQT*TbB{Pj`DdhJme4eSa{4(D2SY#uUIz8Fuq+_v$$j=6m^^@mmaR_62U z_U#W;PB9_j>rf$o-L2ov?T!7?$BUNd zc~`Eyceg6;TYZ(ta}4Aa`8NE?rSvpkUdTn%q?t!YiASsd+=z!+p1`=1e!KGZf()S|%dwUuV^M+a3@W=%3P(9y~FL~dal?A3a zqUexQg$%#SRcmtYKGKkOlW{HlYfO<~(Lx zh8WZUxH`&Y$QBqZY>t3Z4x6UFPGIoVQB%W16o6Pp&EFydg<1DBLV%|!`E&v$P8=6(<^jvodRTs zY4^5zwj$@LwA+!9B!W}KtaSY>?Tq{+ z6b7o!#)-@shGDU;Cd9X=)gULKKCeyMbmWX9;NvSk47eXC9Ja@!^D)Y zkMmE6Q@P$?9O?$LNq`iBw7i*WQEUwyV5zd1ytXcXlk$Yycgm=D{JhrWC0>3xu>Cuk z+5I^0>E3?4tnBNg@uRTQ;JHP+yV2yIrpH8s7vy&pI{n83f+g}d0(bB7GJK9-Zpyz; zxXYnt`8oBwbqQEtSC4xBOO%LYk*e^X+Rer1q%O%~iFfU~A#GE|gUuEEiTg%Xa?{o0 z*s3>oAM4I!e|^*HQ!D!BfH#_9sz^<`I{ilYz`U+wrsldOBqM8ykWB1jDjC~66Jj2U zKw|7Ro8yvhi=zj&6el26Awp9MUTh;{;a5}YRLCia1{Z2CuO1}zwUzLm+v7N?7onh% zVe;QwOVEh#5oNh=$Wr#HVoqXXXc@V>InJnD3>gR-hFhPqI<9AXPL{L~>?P&KI15)|hDh+0en7;Fe-%5ez@amH^s2p&I+)Btk|D`*y?@%aznFUGz zK|Pr}qnLtuiT!C(CK$6gNY)NKsC{}v<28XWGV1|FYTnZpjhlZRjsn%!Y(EUSJozvf z*eLb%V(ew`Y5ouSU3JlbbE?&!<@)dT%|2az?aceNpZuaZg3LXeD)?CieGmCSARp;k zAAoFC&z%JDhn+qo4Vmak^6`&7=n#kb!v2x^g#@!Sa}<9uI}8x@?4>fqO=G@BVn0um zJcX}E6Ey)$FR%~d!*&Bk3N(4ze!%j)c+~**>1;{7+wKREe{2-tVqP@UyhPCrAsg&O zKg%4@9QvS3Hcr!>QE4hLO-FM6d2`}5NbAynGE^9 z7HBTXoCpDM9!t{^0rGpf>M3u+7w&{(SJ~8+o~VZ_>W3>jPHKtFGN2TLK8tBhi2eoQu?a00nE_^BMAk| zpzwqZ;|6RwD>s_sTwVfky1{3@p>%=w&5wf z&esviAOGROvon@k(HaELy`m}j&@#7kU5H#Jxp6VCiehMPuLDSsW|fLMNgP^`Pyh+) zVHJithKN6IR>_CT|1}+D-JOI1^MtB0>f4~0j|GmPC?CRPgi3j$+ryi1qd`mR)aaD01UDM~%&^YrVn zm0j7MT|Jjwdy!pFpOb(Caw0%1p1{VeoccMSG6Jg81JR{`FdStu)q@0kfVD7?a%fIj z1(5v+JLaFQfB-Z05U~Itx)Z=$7{q!a*BSw-X$M)Ma?32h%fnD@`)oP@h_0R#NdXz1 z09gYd2}fY-RZsykuV5mtt|vctFF(N(_?ezq3I$ET;lBV*#N{Wh=5w<_Eki-06F_4G zwg3eknIO`$$3fkoOaI&$@~qKNUVES*nrw+4OdE=$r2t!?psXWA=+HcCRAD0O2A7C} zs^HmgG?a55fBytoPe82ep%R`@6$Hc_0R>kA1t%b!2%I$v3>ksa+UMQJ!{m4d9+7X^ z0ln>6s9Xv1mP>kOvi@p{sNFS;1175h5%6 zX#!EKI{`8D1U+&CviCq)5S35d3Qb2KTJ_~s0Y#>$8_+BcM2oBVL|h|CQ7N2VLyLqc z)RTsc;AjyL>wlp1;#CXq27R%$J&0%@h$qZN*eXr6YQDzRu)CF{F_fTDWp@I~bUmT8 z0Q}DaCG>z;akV1zM9geZB%mHoo-5QBjpBd@Y!D?J)C_^$c7=YBg95doW&nr@8cK(# znGUEi6#&o4)hzcwjgD#((ACqGg&uMc!+I$FD0I5Lfn=Y&M;59$QN?`)HpK5Li!~dr zf;0e-%?hBHC&WUo!MLMJsy@$H4kVz}O520y2!QN3APpli*AXaj6+|2WM0i4wp;b&M zFs`FD(G$pm%89egmO>XaWD$d`Q4nZAMIHVB81Ta{Yyxb+2v9URIXN{oH5CIDGc`3c zJryG(BON^#H77MIpBRgfEI%!rpPh=0jg6gKfL~CELqL*KSWZX;A&8I`6BCn^mXVf` z!+*%`*pkZFG2hXryKm1eq0B9<%`KzHFQ>&LXT)>QQa}O4chCHu0`is-4W$t+iOP%H zs*mZFoT)XvDYX50kv4*gCPHd93P?q6B}X0&7e3{O{Aw;D+7J0PJUFzU@oPO3&E-S1?d#`TKinWs|d zhf$*g2Ri;8=GHDX?G6@r?Rgxx@(4SP3C)LvDwbMRpU{+9>Ure&TSYoF%vevZn_U&*p znz(P;B|mj4E*E%(Fiumlxl)S2RTs5}12LFZuS5{k8UW*@Vtf;Q9t#4>* zYQi6tj4#mrM_KnYJZ>8yID50(=@){Id%9SK4fz8%i`iv@7M4Bb3aCw zj#gIi-uaW+t)Hu_Yn$KB_Kz zIMje2Fl1AXW72Fa9!}*msI1?EB-GwOgy_nq0nA+Ki_6-V)s0oj%pnXK7`1Kiyv% zeN(s69SSC4(P^t+>yN3r9x6?>TY9WQt(~XS-ncc2k$Aj3)_!V2FuOSp-sx%D`%-RH zW&5$C+Qwq?w2aNPhIb>&W<)l^Yy#C{$8D*9=!R4^FF_c4%>i) zLTF{u!K8%?rH>u8XtSaUwRh@JA>I5Yf+4}=+#KJD8BU=t_+vLKyv#JYjKZY zV!(LBb>@1k53%8-6yizt6uu%clFj~g{|2np8-;ESX-`0Bco>z8u2o^2LXF(suB z+)u;lQU;_IM2SCC$*?A<-_1aApHBhq@imQ!kNiaR7(vbfiIS7Z4KPq2h79MydNyjp zKu5#Q*%s_KE+#p*b1Yyry5lOV?u?zDTdIZa8!u_O;`5+t z6Z?6Ts?suHwbXQYS1N1mPIcpUqPA@-v7;5TWnZ;3kK(;RTUnLyMV4`42tnnKchO3( zTnr-DtKj~6{5VpHPh5XUB}Vurra+%{IFAQD3r$P`v;8RzZAeb@TJPe>QZ?q1jSx))TBgI#>1NpeC z>zPQcTj%?+roAt-<)xDGm#UdP;l%G>4{RSaOzFArexd;v^EBvVEjaE8##&{c3;7Vgc?@9$XA4 zjyK<(G>)g{I&p5uE?viD`pN>}>#sSMyFA@bYk%jZbpB3{)UH;I_oq!&#rL21uSK3u zvQ!E`0qR#hDhX`6oBZbG*Y25L^*#BSK|ljzW$37(dcg~-8I)HOc->B-GoZUW;W@Ca zDf-Nx_UFf@l}h!8qJ|(a+Zu+WK7nGIa4;$3r zjYEZUc<1pc-U#)})wk&h)PH#m^?t>YoBIeP&CZgsE6G!B!s&7Ng@)!WwEwYjzu!T} zTKWyoQKxX0x?g7nD|p@sQcn{aqyAud5+l?3hdYv3k~4cQ_(ch;4x5M3p~4aUh&i#OP`Rv&5Y(ITYJgCYUB|$sFfA395!d&uFO`1SWvj#1f6y%S4LUkO zow_gQi8Hs)9GPoJd|%_FS!)5nz)e@#5g4-#@i?hw(4_dP6lWsTVgbyanaWBRcfEnG z824NG4CGiH&E8YVpbR`0x+S-=S;LjAj=PVtx-?W#ud^7&nvHHGckH0%6`!Lw_iX&@ z{qx)=j+}QF6KRAHk{QBoe1t6vQ_|VP36^1clqThTr^;GR*L!IoV{Ra!3mi-=6-sPf zYM4POYsKMCuboUF%FB~j;;H1#3{mCN;U(5PmlSI!t}=iA>UMd;uj&SOE#hCCkaGVa z{By^>Qg?)Fp2`KHLv9fQz z$aiU)+5&Z_ig@$o1oO%FD8bPm8IXsi)qe=nOi2-WIry^UX%oS(L*<$sC6e7^)0Knz z3ps7U>EOB+wx}9Opsd4u+|O3$=Db=uG$dz2v;OePK{xX5WCyIb?_g~6QKq1l&&khs z_dlkrRa-5Uz&$&rX{Im?Tk!83B^fL4OGJk6lGzDBy;+5L_LO{e_-+s006U1a>vT%L z684TZtG6=y+h-e!>(#ku3L|9t`J}pAJp#J5%dUf02liBfZpJujnP|dJl~mrop`b#t zy7mWC%Wkf@s$NQ;ehIS4^}68PS>k7$4dN@mCDbx=rs{dHFc@{n-;w4Euy-rDF8@{+ z{4<*}iqXh}N;E{vw3Z`harH|6_Q*|tWBM@MLr|Z-!dwmaB6U8EK-%XSC6+BqtQ<}j zrT4D%6argxr;`~q6MP<=8xg$v^|$*ZQSWpvYJ_kYdEhf=)>y4^gH=eYXkxfgVa+|c z4Gr9QGWqfGms_8xy9T~{&FO3VFw;0nh(D9}C=juFmoL+z>i^h4;O0uk&1!Lf9V%Z0 z<>nl@XZhgqR(A3BTH9r<<|}*MZwY-oFSvbZ3|RGk2g9yy;PabKf8?*;O+R^JJdsf~qCo>AgLneegW6b7u-$c|E`?XSY5rEf_RX6wRF33QR!Kg7bR zx95d>$R7|7 z2$?s;KTLSQd_}joHu`IJ;)4Hi&1-NWZik}c^-q}{7Q=o)|7RRS&JudYq1-LX_1i2V z>OsF8g6v)et(k?XYz3{|20Q?1)kSiU)r!q2cx5o?Lk-wWFH(R0uRC!gGt|tc1;|?+K%Z2Wt#mTZ6}X5UzjD zZQw$?!5d*dOCz}(VLkiG);v@b^NQ)&D@XGv(*{O6OcZ{$P?v+>xsAi=Jn9({4N+gz z3%_VTI(8cIXlAPL!1HKrgJ^%5m`L-Oqh7{PKXxxnOafo<+ZzLBG+k_pOl+EYYzCg_ z=VPAv97E6;gZ&TDuOXTz^It^&yg^*$Y+Nm#=+~gHri*Vjk8kyhH{FeHYm0w78{b7o ziJbubN@ozt1oG7tNCh_ZR;<60a?0Le= z-o#3cq!quUT^IJX^2B#8Nqgr>M;PVpA=-+m&t1~w{NrTW z({x|}O$%E23ivwM@+ViCN*0`u-_);HNX-E#N@c2J2v-h+t2;uT`Es>80@VuAfq+Nt z9ARx?Y5K4@U5iW|*-W0aM58b=6La{iy@E0TooYn#vZOGZzTOtLApiUHX}6L`0T zgbW-&>Eq^14e&R{*gVJrgV>(MX2!Z?7W!x6+Gz~3;DHtJz;?;73S>kUe1jUG0Y+Ra zLR;4`>XbRE4)STP&~-w2?TttS6x>jmE#D&hxlHy*d)iPeO<63wA~yRj96F04OOU{v zv`Fq78DBT}0z-3Dr9|J~T+nvIxPqR;H9%QA7px!Vun*g?M_H-gWobV7!#~4v6=TU} zTxqn8B-O$cPA4U%`XpB_FxpKzKP6CpoC=sM?*2I`zvo$bviWc6@@WH7;SBr%!*B)q zw4hkH8ZN(fIRCs+^32%y4jk%cfm2hwzYgO|7`&rOiQRRDYB=T&W)-~gE0Et$lbcUv z?0_3tq_YOV**o%06pPx2L%u8LXaMt6y^Pe>AYGbyE5qDcmsg|PL(ewr?$ryD9LkAkbRsI2l^(LuZ0I7Oan!BO_Ndxivw=o1`u0L2&?*JIP%w*x zH6Y2yZ_FFH7V0;Ti0Kdwe>xh44jM(QQo-?XvsE%#!A8w0vSm-G!f1RWar14CX5*_y z28(9(Wa#DuF}q;n@G?4AqksFPOB+nviW1UB_oMVJZ$@jEWN(E21)Mt z67GE9{PJb%N7b@h7thI`T_v_fl4~xsEFO_Lgf>2?YAic2s#xeu zV|@K<7=9ZCBYN31x?jKTNl0bY(K-93bAh3Y@g0o*t&Ri8_lT@p-8V5^I$_l#*-*39>It`w(}nxL z?)F3xzdk>p87HxUG4)^-d&u3py8L=QoN0)lJ_J%23DH+uKDMp0s7U*bkVB!d-tUOzcSIVpv0@r<7Mziab}E_3*Oa z@R4+@@ezhW2K&HD@~hCuzJK6AwM?$Dx64>q6{)Qc4&Mz#}R69%L~?@8WPTn2{MnwTZuHk%s$>nPdd?ORMU?{QYo8*5Q-5atTlr@{hks6 z0}VnS_J^mKV{SiDgya9F;m7N(K||-(0|V7}(OzS5?mUL~z8FzXDUs2s*i23DM*VDq zYxcpTg@TU8K5q3h);o`Y?~Ow|7(KDl-&70$7T&hq>F-`cETfAAbZW ziH*IyZ69Y-#-WRKelUCM!I*04WU4mj$A z1=9k7_(JpF_*PxCWikgJeWj5DcdH}3vGC22&GLgV+wl3Rl?lR@!+j<*X)w9uZ zvDLr1v^Qj{@7k8h=(}LSj3n1%8A7WRENiu5YjBp2wAXEP z@#IgEmBN>ao~+x1t#dq?;_Bj{zFtSv(ugZ;ytLV1EL@Yx+c0g|Q2DqPM7ilt*%#T6 zptHPbi+M%N5htiXv!E29){~C(*Z_p`STAqcUT@*u*NzI?PPYH<7v^odb#1#ZZ$G)- z_GH<4rm*8}yYnJ=$1iUuAUHixW{Vf>r_OV?nAg`$uEnZrC*~$^H?C_pVfkMdHp^a$ z!d{}t7WBf`!5<#8C9L7bE~B}JW7#iM*e|x-FAd%=SJ=x?5X>-3dq26i6O>w^aL{af z&>DQumUqx$yIn;-d^`o0C&&bbZn_=sbp{^}YK7GY<5dHmd zHt*Yf*SE#xZyw~|3_q8OTHL)k*lYa$Z8z`xe%JRyy@OR2ny@ltjcx7y;P2mpf1Kz2 zxa|7z^!huB@`t|Ik1My`neiV4AxA{{M|X>)p$nj14*f&t& z5FvUZ&H7X6{!jSp(?;(=?`^+&TQ)KMpL#bxQFY(dy5T?70uWM%uegr3o_sS{`DJ_a zYgFNv=CQA+l7Fc0@1N-tkXygqSAIVU*>?K|uOA?GpO+o7KxhTp$+(S zQEYc-HgLh%)ACLan(7E+<1@FRU z-Jidq8L*=r4Ee`}9iMlNxj8?=yRdK0)0%2B_JV78w8t})0VBJmDe*bg}4Nvfw3v7n9!l2q{IlMp~+ z(FK_!T_5%uTo>U4O<_ZT(+^R-$^=A0X z8iP!c%Au(&GzB?c?xiJAHBhZCL^)|7#M0!wtDecif6}4hXkXD|Jm~a_OmM;b^y8bi zX+}8V{{3fquX^Mqx{O)GIMpx;E}T?6EfJ@v8x`tAVtvsA$bp_(?&VM^L9Ox@n7pGO z7Jf^m?K@mmna0N$!|{Idb19otI@>+7%BhJwTWGqm<>Qw0FcUA8765w+qA$F__@h*) zsY%Lo*@LGhFDzuDe@%P_1-7h4b45~U&05Fn@>}G!J^XFu`OsThSv>^d$VQmblg{aG zHZ47@ZxO&2#fbKnTJ}7hzTNF5<~YIwUqkyUTl=)@M4d7;90ug`o<;M zgaLc?ugCV`#2EWDIJvF)SxFzPjtSRC^oA!UoS5D4GAxeO?b)ic zPelx!1Cy5TJM#JOU4n=$v*c~>zrTttp+u*Rw&7bi7s zkv*prri8jg56-SVCjb469jtp})MyxM?bp5N3iWK<4tiURx2jjU(LT?8{@E(lf4d=^ zi$n-t*ZU{rxnhT!F4&);54wi2{^g#rPrKKIqJeZh&<${d1AjM4<>LuF)jTR>-)TMCy2!}@GLIQ|7REfZ#TDm z-bd(XA4XpMy!~`hkeBXG?AfS9nI=*H->%ZY=`H&EjH4}(zyK>|&EGpzp0lFdtwl>3 zQ#(`(!(b+~MD&>?SpFAI0PvZZ?nZHvM%*oyG{QeSO}93cc>n!}0N$|BSZ}3nG#&8S zZ0IP!M@iwd;5G18Gw~I2y{k1;|2bzEI~Z|C1!F(%&Bf1V>Q0oxGYNSn=)m@!+_%FY ztLzF>S%<0nb);xxQ$ zuHGxjizo#+&9)@l)1ZQOr+T&lQ2#{A8wpF=NG=&8V5>UrKobEO=c?2IUKc~U#LvP{ zaa*?*Gb8UOML3HcZpqf)D0aGA_Y;MTW$_zSjHFOdp=XHLWJD}9lIhsP7QxY!5|3V~ zflyp}F+4)5j+*^p4_xMO4mV0C5k}b&SPs0mx2a(iEmM%8R=p)P=&Bg#nBwenr6~Hb zKsMO+N%$ofjGdD(>ARSH@^PRO4Lt%FoxPEHOEO$F1eU@Y+7B~!aZ>$7pz!jETH+{d zgN{U8Ivh4Y#PERVbbC`iMUoW78yhxa=ooRZx|YOMp|*!?)O&9Kn(Le~T4Q^yoAv1X zljIyGa4B8NW9(Bd@2h=TEFw%uO^=0IMo?oiTVhPisA`VlK=z!Fs$=9AljN0~6=!D4 zIgNCD1pLtKCGGti^FArYFpq<}bve_P4vBbl&Id^v!CUN`K1`M+Zkw|Luk&($Gb!tU z9)0p6_f<-&v4q5ag9{F$omy&AM>*hs&9vI%q(ZT&gnL|Omf0mHt;q-bmRH0Q%fe@E zcO!+tjmIYAAB*x~KHp@|znV3E{rw`0`G8w7W%ir@?KbS+8V#9fl<0SF>3iH8$nq^6 zPWV&*6Ja7lb*h*H3_tfBK1u;O9F@E^A)yho=AYWNabocvAXczSgRQLjJpHxzpZ*n= zk8$eF&KbBhu)Ck4p_xWyx^HA>ZHK2h6>I5JmOt@!X3RaEuC`~roNJ4cHHZfUNNKJV znx|JBkD6J(+)&h>BDl^g8D-tiJ>Ijq9&1>tw>3+j#p*yBoIm?670|QCXXF6(R;vd3 zOniONqn0L&yxZHBY;jeG?s2Y+v#v>)(31y%>)?fj_Z4Ser}g$WcSuvnt!m>et_w_` zT0c4%-{^HT#c2p3J6;4wb)TA~>yxdwaQ#`;Q%g?`QSFO5c*#SL`u)XSJNXo0ec!TlN29t3 zk1bK3XrF~)u>3%ik?(+hv?$p9 z&FH~o!V(8RUY~UDr?ztt(>8PL()4%zF$bH2H=|Dk7+I)7%gm$INu_~RK{lh5j8&#C z_U(#FPYdq1#o4uZf3K}QI|TX8vjJCjL!wVUdo!4mms@WIs7|F8S#Pn2wY)?15guX` zxr5qn##x?RyQ4L*JKluXCN{jAq+hb52ERIJMARrntc7IuVe44af_);+Xe#DO0q9Su1gib!)Q09@Vc%@QASl^N%ZJ&y$~0O@NP z8iv`KlQnSLocD@1Sd#7g(4KwC6rgdj+(VMsZ%y)8E!dyfdWF>d^9sbDxz;gIVc&87 zjVNiX!1HdwvA*Q;N_LLiysS=id8gLGeF6=flLV~0|IUpUB3(o1hvr)Xr?*AV-@Z)g zAvbR2w-Th#R@%8+`|+i;*j=nN6HH9v9^uiQaT!JUVY8c<0NofBy%T`N2}-UJdl(v- zhHS~$fMJ^e;Op1w7vlKuvBCFwU2&D<~h6hL=(HJ{8oYj_@VNFl#pE4qjll3!Bce)RMLCk6&TiJMJo7b-I(@8PmLjqwb%*5SEWD z^zrVoXOKHe=CU5)_wBeNb;?S3E}(!v25W^!jMOYx^n_Zy)v8i4cjFi`>dctL-n{AT z5do{gs0Rf)YP+>?{q1TcS)mF0Dqjo2`|sW}@Fpc=$l+pZF&aoQb_zX1P^Ha=9@fj! z%28aNzjHs=++c`K-pqB!fflqhJLRe`lcU{m{QTa${&+@gmgT_!wj6>jBkd{2YB@Ur zbc#T=#aY}D9rkw#1!La2$yXhm2-Ze^2y?=Q?_)~@M-J8{c<*XU3EdSK<*3-qZ4B?P zBh^k>WqOVaucT@Xa01v#GOIH66EZdMwbitw-E?p3dFEt0&TT!Z*>UZ z4TIKNBd5G~yayaoB?UAD{rMz)uPRFiB#-yA$omQI$6*C6N8MbsDVbn5lfA-dE6t3z zskZ!#gl)7_IhsT=6iX7Zr6Wn{{IJExS$9*I`-dx7%aP9!YGjZuzFC%UTFk>vSm(!m zoScn?sm#HKf+Xf;LL*JAO~_e5ODj^bYX~g0nv2bfY+Xn%nl2BwPqQ66%#x)^fB+w& zTT*1e=k@QB+rs$15qAOKV+CVfV<);SU?i2F5W=zI%&}tl0d+|!qhfe0%;n37Y^+oX zR{CMCY&zmmIE=8(ND9h?jWJ4D&B%#c{!k^oi zh5ViAbTMlo;w;uMy=Cz=U67JrlWzG6e=j$WNi?sfn7s*;n*B>`7VsPZ3EIOX$g{n=YF?J5w%af&FNar(v<}G8d1TsYJg& z7>f8l8>;gVYJvmi+E|vB!19>m)47TBw_ay*$I`8u8{-rYWuRt{E$jYTru$ho#8~>j zpRMx4Ga4z90IODyg%pZ~dNwOhvi3?T7zKre#;)a?C9Bp~R`uwGaNvA3ABDoMX4gII z`d?P3nE56O>wzHaAshI68{(cC&TfX6Btu>?@l>w2hOG_08hnrG@FGYur*8o9$w~&8n`gJB@9@ zs*Tw%o2^9Kp@+6bh-I>H+r5v=?@DZwJZu-({FH&zr^p9+x2MT!)ptERJ)vBJalU4 z&G-pmH2AV1Jm_RFeoJ@RDOv1xs6RQ|xFc#=QhPZ;z9xK0K2Z#-*vh~- zuyGr=;b;jk50g*y(%GCdW41itUr*uPxeE*Iksj#ZvD<#6v1o8 z^k^m(4)G@59j>7>=8`1WW_h$59Acl(iaAQV zU{J1U6wJ0 zHikbwQs?vpah6B9u`#tJg+Fd%=&X&xHUKKZ_=P38*wK&aZ3=t32;N-)1-7aBl)9rW+XO9!MGj{Ldryw4iQqwVct z`glmsIl;t>EN>I}rtpO+&A9AlFr)sf{OD=6N56DoYZ7~V6n&NhwjdVt6L#n}(fy@M zo`Qt6JeHm7#Qm)_LwS4l!gv!b=CEpxe&_V-K_C6(m$4bIy+ZF{g$|Cx*2C6d=0^UK z`R^ZlG{3vkWg{C8xU&IOvK3$d{ID1JfxY;CP7quA;(M=J^M~IDJzbB=YWB&2QtRwF zxa`o43tJhMq*+%5lD6!r?ZVWKoPFv?u*b#w)Z=oI5=aQv!w$@#u6NOSnZgeYj{!8@Vz0Kn4{P5*WiBN%wtS-r^%fwxrh5( zpT7UO=2e&kb5WBQM*99;?wbyJo*4rj+We~X0@s%y6s7t;Ge^$n4gz)zg7#6HLc+5N zoo8$jr(?-pdM8>ecd!Qm5}d3Z`Q)r(oJ`&8Vgf%ZXA9^bgXGYTji~`O`&X^M9Va|e zB(v89CC+k%Ue+fl?cbLx*}mlTo7_v7&n@iAxzwpr{3H;TlK-iJ2{}LJDO3WP&uFFwkC1ib_FA}mpi}uve1N|s4j=;+^0SC2o`ze^(CCblLiW4zLqJLbwD)+NK z@aMxAI;;1%HQYq}XL%VIN;@T(oo*?}gIHCrcCdJF#YKaIG=ux=J)W6~E_%Z;gW@Cl zp@Ihbm8`v=a}Dk;yf^GF5>li5f5PbhX!_~A4hNHZUpbu9iF3K{3dnx=8R%OE4*dCi z<$0$Z_D^NawxgT>r)I8lTuisltfev0!pPU4G zCHcNb#JnOWh$OnP{44Y@|G4rjn6UsWFi5L1$bj!V+t)z6$bOnWy>~h z-VY}X6Ot@x@}$WCDp#^>>GCDam@;S5tZDNm&YBDg%(NgRiOVEECggOHXjtW{TKS)+Pm+;y+2H>tC6q(R2#VFUZ zAv!$gn|AE1TDBuW|q~dmP;l%T*QNcFSTs4H)_%iqb(!o3<2&-XCD+FN@ z(((=`Ofv7FMkffVm}5|Fo)s$D86#p%Kn=A{-o*g&D6-kSCku?%dgGJ5Gp| zL3P`;N5`Fu@EW+;ZlmkoUVLoEc~MH~0F6yL`6QGHonsDcS7n9U zXuMe=&q4D&|768Euu(DMXdp4LUuNDhFyC|8JZ8l>@+|luHrs)f(Kwu0u-tQ7HuhMa z2<_>hhPRC+U|R}(#^FLEMlqCOYkCOch#t~Lk$~9n#(+E)B?MM*92O^%SM&KMPn;%U z$-p?&ZE7WUn>KppIcd_x0C?hQWKpZcttSwk;W1#uIQwP#-bfzi30z6DGVmw^bzZ|I zr?>u)(U!rDV}wXuCiv_~uC4W~Xbk%H;HAz!IzgmtLWiM-!j)^?ujW_;pNQ9jIIf}y zZFx|08QB}Ho!ebC;Tk%}1NYIW+^I zZdh({!kIJew+vV@&#feZBahi?cQ#McT4%KoI6{!U^Ep1>nk#m09iI4hJZE-R-WzcZ zG~M$c8=s=Wk~DeZKe#6OIedxa&^$7m^D@ndscrMOS8Xd-%tDvcAiA}&esUM}-rP@GBI&)`*;7g|+a|hjl3z zw~%!C@8MUkZnVVzMl6$E3n21a@-&Z|GjuZ zRNCi={@WiebD0$P!DIp(D}d{S!V?P+1%J9cCQSMVz-2PCnJ96dGovZZX*$UW;Ls2? zvuP3`xJjGd{3bY~iOg}5vn9OTU;fIeOJ#<$o!_jCJL4%&C!tD`^IT^3vUtyZ@)Mlu z{O2*xslRjrRDbO3Cqfgd(1kLzp$>g0L=jTZiLy_i>?0^eJ$BHDaS|1qwjH78#! zD_r9$*SUhUt#%a>TOpR$yVB&Xbp0z}11ngo^0lpM)oWpG+ z(X!UGw*4(|gNsnyB2~9Y;w@=?E8OKWx4F|K?oo|VcC+gw=<-y$JEHDo zt*hPflDE7@AkOw0L<6?($oP$ zk>&*S8Bw25^9P@d<^(kM6bvrY2%<5FW@pX=X}|JD~r0=_GOUwRJF z%q(!uq(afCGLBy*L5RcZa8+t-5+jW3Qq9!y^rYz-=a2+`Zo_fN76T5@Ok`l1g=RvG zJWVNkW`zu^GBrm`;u9x@%WX~ZNI{bok=S^dFm6(PP*)PnFl0T!1O4cfAq%lIwVcrsb4<}K0kcTO%*_O4k%oDUREeswpj6_q zBs`3QoiRxwZb1+>^`Rj_Rv3kIjDt@lvVbcEwx7h0o>cs&(j37x8S?V7h&X##Q*%IfI1VtwB|BbVB;I|QD$dXv#HrJ5N z5uNO96t4Rz7gR{O-d#utZZir=xW;J&xyXdf`;b)o^{DkC8)REjkcYfCEB~GFI1*gk z=MMCwuPEwf^)QQ>-n3docx_5!$16)@qZ&PFzzv#2haV63{~SG0Mh95sEP-@L#cWN& zVX#)S;f>0`!Lnx+tw9jkna<91H=6luck&R{j2&PiaG-BXf6JLXvS9%y!-pdFVztsy z*7V)Qs%E((-Ps;YGi-d_QdC-clXu6M$&tNsz>6K(Dsnq=%j0E7CsEn5NGzHY4I7IQ zjRn+Z8M-uQ9Hilk18%1&&IpQY8IgyvClYwF5Kec7|Bw1JHFTnj7)0@yCyC0U{u7if zCM(_3)MIv2C$s@?S=qBpW>ogFjnqtW4x-#acs35pJS6cz$L6p;at$M}o#-Vo(R7BB z^PP(%W&^Rn-iNP|D;?c36Y=r%5#*71DEK<2qaFH2=5m0tJOB~?Ao?rDRWG9z<{%X_ zxJ=?Ffn;V?q~UpiNbdLH z=+k^~5afNx3zA3-cEt>$1bifc)=YqB6jGRk|BgPX%!nY)ceq8itcf{T822GWpoCyU zY>L?+$YC&{4-Si&IDlZVn!ofP5EkB@DT-J8UzB+WHqeFr@rFo<251<_NMv8_dJZ132*?%!(D?lm%NdvjB%&hvgb~aH`<<2heH8o&pxbN(NPxwNU}6;XoPESf zLikBFXpi%V1#^^y1JWONyxF~6MykQaDZ-fwVg=N6#FUgoBKe*7#f^D92b{r2DBeeR z6poTX8$!4UMO+_>Y)>Wj1z$`_N0eT3#LROXPDh-~3gsZ@wFpOK12pOkHV~ky2$I== zn&w1ZN2mwrZ3<{?<3O-TI#La9s0rp&|A(C&$W_={N5l+8_y&ReqGkYJ{AmX;lEjRB z1rUY~tleRn5t{e?3O({+5-?3ioQ)}7i9;r%_!VL~v0Q|`1pGLnMnMIc97tYH+KOn00`S}Y7Ua!TZ7WnploS3U*Pox`?m zMw);nS}cs6`3Hck$j!lHQ+`LvxJ5mV#67Bvg6ty%I;TnSA zt;{67m;_m*A~X6+i1>!MXoQssgn(clR#4!NBoKmtNLDmRulQzCf(W?8rmZy5Vd#-& zY=>u{8%73Xo@oYO^dP$!VG_MY4T@YF>R?%Vr(yg+cp4hjw4)H{Oje9%$Gzi4SPQnS z24ZZBYhK~y?4?WE<7@OLxd`SL&I%f?pc>MO0lLj|Xi#eA%oi4;9a@J)M&_&Z;SgD7 zg<>WlYUVhpl>;oIA{t3&w!~+~L}+5wXmV6(?$JCji}vkYbNmf|bRzJOUCG1`P@~sRyHs*3LP6lph zb$CYOT!+e>WB6SrRc54z1{7DFU;2HJ#i&Gyvc!qPM2cS3igJ_=aau`?!ylFi0wqKu zEm9-x&;yas3@KX}l?y2q860WRM0An?6_Iavo4=KkjndFWbP;*##lDT{7wOQmf$JNE zlB{v5vz`&Z1)GgY|J$~L>n6pJ6rskZnbKD*Ym^z15Z!C1#ad_RYu@lH{*@dDIRU%* zYe_IsLg*VI5iE9SkOiU9AFYSOrqUfv>=-Eo2c^=yxl&DTn|`#bN$ABR8BnoyhJD16 zBb|oHjSIMjPz4R!#g&}L$?R{2%&Q`kR%y&j)R?UTg=Z2iiiV_Y0hVM?7=MA46);}Y zdQ{KC>P!G_P!!Xxu0*cB#I80~ufi0J0cq5N)i;jqM@_9R{p|g;gwUFw(c|g?cElx;lfnj;?mw;?Mf8D1UxR}PC$@=5!F5Q|g?8Yulp>9QSRYXQE zE?B9NG`qipU_%2TYFHJcCdor23u_sEPjtgPCbOVWl+D zFaDl{`ZCk1nGW8>lP<&oh*j^Jh2L#)ug9qFO0e$gt}RWF?@gJnOpPV=qJ#!Vh5Pys z{Em#@DMXA-MW|)PcFGg~Mic!qFG>*a|A+(vZDIkp(*gg_DV_wKL6rkPu z12JgM|E*ZDO9;t_!Isi2l^fv=029g(X3?Iao%daHeHZY7~(zF3}Ao*bR-yvmJ&LB#_H; zC&H153DqRCBG9Kj>>!aa!q8F5PVoXg$Huy>6WkDz*-UG2#xTdIMvZCXUT zWzx1%0TJn16xSp)E0TjL(!7Y{b0Bdw$OakTQV+M!5A$u%60zWp9|kKFSR9=bfNA9w z|K8zQ0N1Psf4mG?Qjf4shCC;8s(wViZNzS9@jAENqIMzap`)eh-kEqF)Pmu%(1mAY zgNXpCW7Nz_noi;zhHL2Db=*bX*~NDDa}_ScUUW1J+TGdUXfY=0gG)+#$w=@%KYXy;EsmOP1u!$9}t5e z*g`S1z$@!QLKMRcFaR+S!!68mLU;f%=mH>wH3DzIFrf7?)B-~IK`{uzEqFBp2tqK_ z!7UKO1MCpmAqYoX*}%9nU396Y7?0_UgB5^A)IsU$5b)W&%tx#RQBOwbuyf+s|6M~z zNjQsh)ta*e5AjV{uuY|NLV?Av^dOnZpn6IQ2a#bm>f^K2##japHwuKXh{Otkg>0bq zhFpn7+@FD>ir^&S4Qj=6B#O#>1vri{xRB9#I3ccJWOjhGnb>xCctl<3lSrI~NMyxT zgv|vmPMI1}30sC&G{;07%-}?iu)sDrbj^aipieV|9=+i`%l1MT*d2mS%_sztEe7L+ zXQ>nial#owNI)^<073`?SH}TYBZOTO10a|LAmli|Oh!7LMl z93TV_9P@Z8H$Q49V8|m<_l8eIa*nX zxCw6z*~*%ru(0GI0d(^H$zbLgms6xj)QW=PMJWo$Y20Gzu?k%n-jZU|ZPWQ=N2PBV zIxz}$nB`WUNmnwCl@lmgGJAQ3{|;rK#d>`CZZiw? z#0Hd?x%QknTv}UFyT|h=24ldvB=-hgriGn-$bn?wuP0Wc7Q2bf~8XX3E8h*qKn{16Tm+=jA`4Tl8Uv&RO( zcl1k-yIB-Qr$<({C&{*VyVceNX|I%NBh>#H?VT3b+5(VuZPR#|9FJ{Irl9$^<)KTVBwOU zVW+T)p4cd*I(n|GO0P`19y#a^{e|QdrcwE;(1GvF47lRv^Vgt7L0!K@{7{>hJ@78a<){FV$ z3&?(tyL|pC`_@R=YdcpN!B&VU{LH_I0?BAQIarOmo!ShZ0>r#=R?dNAz+m1vDhw1J zWFRjJgCqj8&8v1W;X*3&vQ@Ogzz9Wo^CCJFGH(Kd3G<9#bi!a`HgF^vI4~y<+c|mT zRGvF`&1Xu7*XCgxH%}e|CmgNdba>DTM+;Gs9+bCm|0y_ZMW4bvcW@~K3-f-!IhchUHx_1peZOCBU#k2;&$-8#b90RIK=N%-P z?PyDg66b-dsMu$kFLOp=>kNISR4i$hB+Tr>)@SYyp1!^1{*Y%5Xyl1n zNB(fY^5FfJ465;TsNW^47Mkxf!Q$%ar=ae`X1N9(WFUYDC7h7L3N5@4!wfatki!l= z{E$Ni3ed0sBa%1~#S~RcVuBAx1QEsq${{U=!5XT&K+>yr~9h`s)2ORprife*A zNQffUOY)^Cgm8$8vOub)8r+x!>zZovI>?ADe~9uaAcb^*3ZcMMYOO6*D$)rd+OnX? zGM9_ONFn$#f=czCio%KszJ&70DXUygh?4#!Qz$30R5OZdtk`czzAWGiQ9-}7;GifD zd|ntm7VNOYgE+{G!-EDxn3e?|pq;J`Kj3J(vQX)scOo<9)`{fc?|Cl~KlZrrVZA(mtaFr9LKz)3Q#)u`JnBs~f z6wzWBU(A@}jxDqifQLmMndFj9J{jedRbH889Fs7I!Iov7ndX{pz8U9-J>Hq;o;}3a zXACzEn&=rp&Kc>Xm0p@@rYDdG9HE+?n(C^pzS^Opwca{opt+84=&!}T@Mx^fJ{#?{ z)n1$Jw%ty7?6~FD(Ce?mo;&Wc-`<<=zWx3i@W9{3n{dMG=KAi!xz=0o#vOkg^2jA` zT=B}qK78xMEhn1s$vyuZ^w32gUF6M8CmM6DH9wu_&PjhA_Sj{geQnll_c-;USHGQO z*J=M9_~3;fzI5J=pE!4-cR!wD|KEv!9{T8|7oGX)WlTQk<*ldD`RTp?9{ljr-k$sp zvG-Z~@?q>={Px{{AO4lqpZ~)1drqJJ4%v^N|Ni~|A42&PU;ymLGyDxOL;C~Z0vXuA z;UO@81>D&IA^5QyIS_*x)ZpwYI6nz`jDj7UkODVYLKB{Fa3Un%2Rjx*6$XHWD3sw0 zX~?t}ZjXf=bD;`jSVJHF5QuQQVfAvDu^o!Ahe1^05}D|rArkS36pLa7lh{NnUh#)d zWL^<1Hbn?l5sP6I;|8^OJT6wuiwFec=#n5Mlby(IPCypR>_ml8N#u@ma^uK^uogd> zgkDc^(;ioLrUwBjR)ow^{}iZDFtdHBk;@^Hj*_sf8J5v_XOto)HMGXig~VYclS$i_ zGRLmiiDXnThfbE$7#-1MIgZqkrl>?Em6!u59I4l6M)Hx3;AnJrfyCI%Bs^+qF|-?-XD> zJ-5#ZOkhh%5RwoQ|3w8gIUp}zib6{2iBu^W!Hz}{k_B2~r%+nJ2~J1?vVOowNIAd> zvgA@!0cx4Aq$v4DwO#7gA;`kNm0FGRvnVjgL0ITQFVw%C8<{ysU$CUQjcI! z3&*ZtRjZgPsS}nu6wq46PT;h_H7rn4Uj=EHv>gjgVP{j;;WT18%^y!C_q2#i1gSJR zhZ81%OI#LaBI3jg14cQ4*w7{+xXjB&h%%3PY)QK#;R{jZF`87}1g4e=?|IFMpPGzj zl}Y(QHgMUI|7@%jmm^6m1F&I^qx^-gPpQU84ttP_2skhExXVZk5`~JGqazya3Tw@B zjf2jEpb#~SLo`(w9Io2+VPevBHlIdtu{`{Xqm<$jQ<$Mh zHUhPkzs#da7RlwOSnC75xk!<c+q`LBu(l`;T=X>%byBMJ}Uw+Dfg{I^#7~y7DsO%Q{ z)oAkI%j)zZkaY$PHp zNwPfXV$n>s`rFNvuz(QL83&xi3C_L>v?I#TgLv5?V16|1#%#Lt6+j3^(D%Oi-EV#i zL3?MOUz#5WN{2w?9Ju^JW#pk41{jz#CHWVBSBb2dU;|Pc*-xUC8SjN;!`=4*M9@o%7Td5ut#wzL10OOjiXFv z|BPO=+n*9s10rOnFH+Mdu3gHKV7yRG}A9x`MbwdJIAHf|r&-EabBVW0(gTFEn zQ@Xe_PjNs~1aj@g`sE=W7WBg#ES6g19aEcUu$1np(fyV>?!L0GrZQdnn)l_f_uXaWWjg@`%r$j$fls?l07Az2iTN!;kd#n z4x%79YfM8iik zMf6T0l$LKRl8pS&uGJFo?50fpNUQ`)PK%*zE8@E{HitO^R;&ZOi7 z#=(wnz(x#7t|CWb!w8}*BBHQW9P#b8j3koaFL+|X?4%Go>l#cEvEnKN|3|AD%EAIF zP%b>|4;cd1x-TMVP*VU8pfn}$^y0iU<;J`WmNo(!#i9}QETMkD9Kc~59U$;5!WsQ! zBBErZUS|x+aCv~r3>_fx`f&{bXU)1|B2vo+7ty?!$qt{Qp2Vq4M#H?g%`D6d*6L*> zkr>SjS++tTWG^8! zr6pkLA%B1(;qC^z0+&#-BtViQ%|fwQ%>f-m2sSb#R179d@*t|=wqV1&s3a+>5h?Pq zv&;*$v=S-yF&9zt9Q*|-;UXbUVj*a7DO8cw%-DZww3aZxpdd&aGr70PqlN0-_PGOv02bfT+SGGr__v z#UeDj0y6>1Pg=$@Q!Yow5f%x>RLaUtq-sZOGe<1bT}~56eqbMkAQ}&;Gj}ta&P{4` zla5T1q8bD% zZWz-=sPjV7kbESwf6Q}uL<1?VAvi~7Dx!ctpDB!@Ai%QWqi9Gy<%T^!M5+cdGOu$y z8`MEds6gZ9Kr_T7g#>IA)c@r3K{u2`#V|s@WGXR9ZOEEJ5e!vJg zwcb3{ZO-W!%K}$Hj4p)20&*hZUP1`WVZZ(&P_%7G|7^`1M#>6SX`UV}eEYBk0VqHeyShb)}4j z=W4MUqF@|&V#2Zn$wJ~V%c@(ym0{5)T!SWu3P56ObXIfK0)_^t9J9OWD=9+?8#N zQ6SVLWD(E-NtP@`N>pDk>OPNP&*~vyHU)=~X0P^aY_?}uC{Y#F0Y*e3)HU!<c*RgNOmgg}I3;Sz2qFct*?PxPePiT(c_)6SN1PH)Ae!`0|KcxLvVR}gfB)BF z0$5|t_KNE0Pa#-?kw$_icz`YBgKejP|2LR~9khchhJqW@f=if%`}c$?CWT#OgNlqh-qYq3wMT-7>ZMMiJ7>FFLZgM z7>iMLif5#W&Gw437>ucOi?64OY4nN17>!kQjANvWF?3JEG>zlfgx45E+8AhU>WJl7 zkHv?M>$r@|xN`D%j|cfj`}k-6_>2izk(J1h4>@iCS#bn;ktbQq8aYG|`HLx8lWWM5 zFZq!Zd6Pq#j5?WaFd0lcR+LkDlt~#w>{xkES(RhiIa#@tP5F&cS(bD8e`vXuKRJ_i z8JOdTm+L2ee#)4S8JUk6NAGx@|0Fq>pLuVF*+T3Gs9x2YQN)RV8Jf4*d!)HSsCiR8 zq*A>YmbuxSyV;v31e`x)oZYxn;rN{6xsucQVzj57Ipm&S`IhCGpC5>x>v==+SwjT+ zJwdsj54!&TnSks$oI8Y|LD--XTB7$(q1RcQ8=9Fp$(bjbqi05;7doIZx{D&Zqf0t) zKH8$y8A?~0rK6Ob_nCOSR;FiKQB8V~QJSGE7OTB?oNsN)!^2bx7vLPDAvL%7FZZbqh?I`I}u;D4KrnDP`we^W8`{QARpzTaXm9FMAK1Z@OWJIAf04$qApu0jK zxo|d`X*j#Hi`tn0)ExMeuy=$CT3hz;<+M{Kyj2@#CJ#qmdumatFa*1{9|p2<DsQj%K@pN7yD(| zb|qgP1tc27kbYn*|2Ui^s9;d)Qb`&FPfDET1jYzF+^)z%bsgql`c()9B}ue|{IcXp z$b=)@&|V~EX=B?fM(*62q|;(WYUsoYOvz0IBMR`u3J7TnY=t73vL=%gBEg`*~bO@w<*ygZ^VT#zc`Rq}kzbv&<F8nS}+M>V-Jz!;v$U4Dk37P5oX5i0Xd?a039Jt#MKWEDU4!i3FHS) z0&29XD2QTI|1Kjl9DpdmVFR1bFaC?Yg?z!_WAh@Twn5HVg#_e)w=Y92GBzSXe(-X+41AJizz2|;&IPm z+Dm;P>aH?Q!g6C$xCg!^HiF0OBr=xbCBFSU?_(z_!o%oY?6@75o+KuY;z^jW1z}?D zB%PjFXk)~JrR{1&X|=%}yqtq4)TesX#qK^71Jw`096ruJ=;gc-@)mJ@lx}V*r0GUg z5GELRyv}MO+Cmo(koHcZB$~okmSrs3!o>o_oJzu=s@)CKowBq&DM;&{7Gn7tOWe%@ zQ^Jtk|I}Sbpv&%BnpG+qRb%^F@l*IYe7Pg9?8Bk49?Kpo-alTGr+>IA9d1|E5R-OrGI*O zc3!G`K0oX$=pPO%5`xjaVmS+@)UlIRjtVBV_#);<*I)QEsu` z;b;<0xdI z|G@U4EhL#>b}ievbnDUufcL82y?p!jwJ;&D;K76^ z+^mXGAV-fs6ACm(Mc@xB<_a=A2Q|q&2LdfKba)ONmC-goW|L=yN;Zd7Fn9LZTA=2E z=B)7axwGfd2?H&djQLUJLC2m4Mu|xUTS5!-elU<1`Qtd53@9^*;*v^9(zuOOlh^#C z^`f1lfP^kFo8;yQNmJ1&@aR(pM&?;KUM+dT-2y|qx4>UT*EGf%NR|o5l0y)M|3ncu zkdgMoVpKT+T{g^NH=II5xg?Nw;DjfTci=_n*=_jg#}J1D9hKi`<}ol?W$^h$V~sT0 zg=3C7?#N?SYV{a^TxAIfWRXU8g%m7U)MT3Up0EiwacDe)F`M z=1yz|2+n|HLS-3qIvslEaW_pM4@Fj-Q=m-}PQ{Tq=ACm6pS}tNtctOX|ATC%Wm3Tr zpA2pGYNPaNNv(M$g=n6aagyp}yX_tcZ@luF_2ax?5ovF}cje`7zy3xArIdwHIhB>m zG5~EgLq*o=HLV(S960k8YK~84I`o4)=3H|Qp#oWSjZzrXbPaeuMJxoK4Aj;bIN1Of zpmx~AD(XP3E{Y{ViOPJMqs~D(&~%+TgkeQ{j)SE+O?^nPr*6I&^q!-x=Ul7Ud^qD# z@__SUWITh%K!6!<+;P~memo#^6&tA2%}9H6rUOc0b55~4LCf(u6C5m6WxU1uqT5)C zc_y*oth}^+92NWWfL}Xy+MwZSml2!|Km2dze(B43=Rnr$c~Rwlk6^tEZg{1=-p*usC3i0A(*Ki9`rq_7+q7c*H|G$WSR0t#l$NymJ*DdQgObe%3I-j{OOYq(wcC> zzP>(*Z+BS|0`1`Ag!Aohdjl~Z@)&p!#sH6i!ZVKe=0iL+9WZ_jnBDQ(q^YSGAv)3H zUiiirHcn+Qg%-HqO>#m%s3j16^Q)ivs`0%jmgK12gD$X1$3bsoe)cRIv*<0 zFRNqSl$Hp^C`xgPdkGK~ujntnVR4InIieT6NJP&W@r#{H{~{Nu=)@?UagA(jV_$xt zH#f@hDh@b@`{p=DGU}0ZVeH%(_h>IO;<1NK6qxGQ|Waj}_+3Ur{?>}NXH z883bslq>%vs6!tL(TMJ4q3A>?yc9~&tTa@j9POw_{{@=SY+Ce47|rNLKZ??ns&twm z#pX!&+0t+FYo#=;sZEI)(`3H1NF}A{NpA|&pbAxvIYs79fz;E5{&c8JZK_j!SX5sg zwMR)c=u)4G)vRjuMp4D(RC!d@eqME}WG$;%1=3ZohSe@>z2{iZ3fH&}HLb1u>WddhM%W59`pso-(jG8Z0^si`d9YHlB*LBx7;pSZ_jhvYhQK zODhY>%d!=;NSdi=hDWREM$Z4jORS-dCz=aa0{Vg zTL#ns5rZhSp%0DdL@RpHjBd1}9}Ve9|4Vw(l&-X;FWu-x2*eO=b~6y+j21cLlFp9& zL7z{J>Qt+G)dU6%pj9AfLSuT?w63+SZ;k6*)0zSQZ> z*~~_;t3eXzLF;3i<>L^jwHDkX>N53eBcCEFuMohZh9+x;S6thqwW3cd~*)m(M9jS z6&dh?YkcDz7tFy0l5mHMeB>mrcdsKZaY^=DD=P=&#S@wFj>~-J=l(bYLSFKm>wM>v zhIqGAKJk_ZNxv^gWXw741Uu6_|1e2k^$*^XZkywr=Ttv*BX$9AQ<$Raj`lgefgW@q z3SEyyALP*sd=A?P1~LW~i6IMO;D!VyC58Ec6Buj+s1L^ObMMHh^Bx%Os9Wl=mNvb2 z;g4S!+86%l1*Y+l3`Cd07qkAwC=!hetPcVi|ERX*3k?r@aQ)#Y|2f$0Me!jK-L%y_ z`+%9__rRdWz%G0H-3xrIz~r7VR+!a-7gdo6sfkto?I#hsjR}I*}CWUcAx90>=FeSaSfoT^#9Wg+HkwDnMf)ijsNl<_ZghLFb ze1=DFqwo*xFbM1L52P>%qp%L|kPNcM2re`X zmJE4l3X!*lZ8!*_cMNB!2!@6X@8AxahYQK@3-5q+jkpfBz;NfcIePRD|6l}_)qXR! zdP*Wr^XEj&5i8h$|9?1Wf2T1H{g(}dp&jF35pdUg;D9u2avXb78A7lovls>AuqVV9 z7)gLM*pLMEHysGEcGWNe4f8g~5-q}*jLVn=T7xrpCj=VvGOjonvC@qbkPYB4eAb8! z=`#;|Qa7e{9Jn|S*DwLU2o6r59oO(Ox0hf)D24N;4*&2A|4@C3&=39)4{SIHh2RhS zzzz+`XjEuuaQF}JfD6YEiudpf>Cg{`_7BG}2>aj<>~N5U@DBg55ASej=x~tlK!^X} z5AV zyTA_r;0`*;|A`9ciCqMW6CjF;Rf=NqeqR)SbEJx_b0NoZce6Jrfl(hfSQ!2%7<&>J zv2u4Y5g4sfk8sBv7N~&1=X=aSj}rimfng5P7%hQEe8x8z!iR%z5*X(|k8Qb^s}luK zXAZ7-j>Bh;vv_>OcOk?gj=gsuJrNkZ7#LB2jQ!Xq?N)gIC~t+}ll@Q#Md%NYm<#`~ z3%2kNls5{=P@9S-kz$B_gMg8K$dMj-42kd$VaN!{@Q6csXx&$6oX3fZ@R5U1kxW^f zg+>U;Fo@V0hC{iAg*KG%@DGHBk&HkJ**OUD(2;A1goB`z)j5b-S$bcWegNQ=qexd_ z85U#d|3zgfM`!tVENBrHFndiQ7z`REaybDcaeGJM1e$@37J3{F>X#F+dyN^Ga7UQP zcbF3pD~E}Uj42q7c@$8G5fcC{T!S^OV+B`p5$1@FkGYthDR}tjD}f=Q8Je2&Aenl{ zny4t_zo!{q? zV2YAW>XTAP3hU5);zyp~cb?v73jbgV7#W;+TAqbgmHV&`d5E9ehH^sm4|vg^|0#3= zdPD^3Mg}S+p{bw^=%UgXnUorrwI~=8+IJPICCR8IKp(-e%lnN9>ad#-H z|9if76en7XphjXk)wf!e5lc*hEWipx~mXT5`Na22=|%|$D6rO zX!x)X$snzTNQRA=l)*WL)puxDYMfcRrG=24g+lD z(h8^Bx2NYxesy}M|B$Epx~GLkl{4vw^tP3Ju}6h!s9)Jt0D3Q{I8KflC7~IjkV%u{T72%e?Tt^=8s*=l{@hmnT1|Aw{c z3m^HLY1p11Nsx&K5BpG^Sqi5rIS7Y%Xc&ovr67L&;0{bFr`j5Ng@&(PTWIh}lvbOE zL%47QJ5ivRB>ai6MWwLA#;~dAXBr_G%3&Mdcn-1{7?3#_7JG}icz3(lHG8R{wn!7J zIRTncF~RDhk~tL8XpH)3nz14=g8{nR*s`_gxY(dEgfTaDQ;P@z4zlZas>_Z$yO;7v zkD#g?BB8hjm#iRXvlKPBM2y--4jU!4nxe?4fBg5V|HqGl0f0_{!321Fz#|w` z;JJZU4JoWcZ-K!$Sb|Xyw7M67Ck#FRheNZ2Y)&wtCCGn!7sEWvbmEf)F-rx|W5T+J zj5T$&d(xAPoO7rI6^Xheim;fQMUnXkF+I zwlIc`kPh#F4p%%1=|F^sh6u>O4x@m!gqVky_zuTF2#971>@bPcN(hmd4!*E`bxef6 zV7-cfhSe#FnwJZ1SO{jg4!F>X`H6mCWUzsIs1KZ|hZ{~7%wX8D|8%P?bN*OVOW$tjyD9%UA)p{3*Dh7>c`G zIuaa26wF4yJj~n7&4f|R%M8xpylbBPiTgPLIST;d0{~G4!Chg^K!nX}q|Mz-&%^x9 z;*8Jv3~9|=6$R^+2q?G-Tgn#4dek(}^^DLochCCF&<$;9{7e-EYq0+?0qJZ7>^#uY z70+jM&M~&1;t<+1+)J?r)P4;9_W@b}O|J7A()mM$xSxwbwreO2rLY$9-ci!b6#pDeN*P z0}>oHV-@32-u>d zJ~5MCj4KhebHo!Mq~)J$DQgbsIH4W*V;pEs{~udkAkNZ3qrnq5(dEgaZNlnuen_K!5SW30z0oRcavi?@6IdT z=eqvq@3BQu-XjuT+XQtE++qadU^(-sn)4_Wgn2l};Sus61d472^57BUfbKo<;ct=> z^1$H{VIM9E4hpjw->8qsLJ&>iJDL6=5aBTi4?U|a#7u)^=(0TJ|V9~pxU9ODum?;yEx|Cm&AER?|~JaaZDUpF&?@4e>}v2qQ@xD)=~ zDmNhyOdj{v5cGI|Shq>%$yzqWYkp~jp>Pip%ilrau^Xgc5!8W;2xA2T#vUrtKzm~y zP5&Cje;sGD5+LgUozF6_?f`UsRa9I-v}NPnjk^=vrEw>?LvRW1(l`VS1gCL#cZbHE z;O_1Lf(1y>03pKg-dnR~)_XJcckf5l+IOEiYu&1I_MUq+i*c3W1aMpIVbk4`#PysE zg!Iy5Q1Cnz!`};_?pHywn2uX%-gA#rM@yk@a`KonTkj$N$Kj%z zBm+Zd3Vx6iGMUbqMu`*>gzf;cV@$o-i)bq_joTs0lSy&xDYcX^q;LLj zC&mgwr(YQN8$oR2-`7JmDp=uF?dhnwlhI2QIiS90f9OOpXe|3Q&yO=@9JoWJH3#2= zXE#dtLCCQy24qF!L(XulX8AX2tlUfCrs3T3q-G&j9(yVRx{wwIc?{Ka3n$llsnZOz0pjGyB%GjmNivbw zz5C*%PFuF9`FCvR(g3?>G5w|G07A|ft|#3~zWg+_VX^&Unnp&jc}WV*O*9^^SZ~gv zqlJV|ur5Q|T-1&?UCO4w<4&St3$8OTa#8#`58sfxW7XI!3{+y;Ir zQHB3>PO~bB2+rXwomKAeoOh;wyepj}?7Od6+ZFq;8XXe~UKeb?F3zjj+!&GiG$9n@ zST(T(++Q(bpT4W1$?#c$&1c0pzArCvj0&on0mVD{v^mn$!7cs2)N62o67w{$pF7fA zuY13xyXrD*m6CXI=Y-qC{SGreDZ+MBv;I9_>YJfI-l#znZrUrU=-}hJhN1KSRQYl? z84eg)@U_*$OGMF@9IT#}=bpD7lMt4o4fex;Ze@0~PdZ;e8cLgKq@9Mx4qVXMb+0nI5*$r5Sw?}y=y&0k1m!|t;kk=Gq~EDyo~Sjh<9NPkcPzspAjpnpPdR4 z@7)tV$r4kDGAT%g)+PkXTGJACDas3I#Yco6B_L;WO3U*oM0r^=@^>kzdoQKRHd!-U z@hN%fYNc@x9Wm*4DeJW_rR#{#~7VN~^eUYGu8j zJmyO8QneNEOdb!n)rOIBTFHB|PI}o2v~{Vus4wPx5u4&0)KznnK*`;ewG&zGnmbQh z&N=);B)mIG*9>1ScpR~NkqF^=XFueraC>B@HCO#ElxU@>0iz1?x0)`Pkq>|*ZZFFq zvM4KZpMgHBDT5EzjPYJ6eZx>HXA`YS?!Z?>f#RU7+r6|J&6h!+pRDvNS}S91r9!Yg zLFFAtn{?8vfN#`6BSJ(c>P#n1EI#?&E=Z?DV6~c>-;p^POjn+fTK#U+Q4gI=S4I7& zoG!|#Zkvc+b46-x^1Y+Mz_VIY#%jH*$%!G2(h{O7z*EUL2ZwQCq3wN3y&H;?xe?2{ zG-oT|?LaMVkU0W64szq$Bs;UxU;2Z3Yt7m8?9_j&Q|Ju<(I{|$DXApkq;zU?rku0m zW7g)|Ay34oT5E*;7r~I~w1=!pU1ygM0rG2ent80hq_obTky!H4n@ZzjoFk&QcLmnF z_AZ^tD-8jE7#Lc8M>(C75#JiI3TDj&y7-Q6FP#Os=fFl6q5M4Eo3s(#gU8B#iHLhQ zYwP{eDUC$YN+#%?j}9u_(s*tJ@3s9OGw%CbLka6L{5&Et-z7uCAUZ!jWpQB#K)@ozq zhq?f3^LNuf;U*!9`dI|Q!?f#63Y#AQ)I1h2fKg9U1w3uPZWl&@vWYM-sTq`VIl8vF zd5!Yjo;3I9ADFyDsA5BfC?(0iGTaa6C#h0Lu4vP0xp1(dl-rJ*rQ|9mEpM z?HzYd$bqFa@*NF{clObu`0H<+SB%WICk7cFTXH#^Er)%Y;+)yPeJsI=(AYUxFuiTf z*2?shc_E)1!+IJe7k!^@CkDW0deolibzzkuYm{Dy&8}9xV+nh$nA!X_bfu;m!gk!f zf!S8|xJwX`OLXuq%D*m`(<^qVnhh7bVKtuvIq_~wedxp=5FU)50R8yQB(u}|vr9u` z>~=RvgZJjBx_5*%%85nhubHoEHh)M5fgUZv#+QAM1p!2RI*Hue%W8+YyhK5(Kd(}F z<9sF6^Kbu@;lIijeg8ML*5U>3LE%H(YFv)KD^2~FGXKxxdyMIpKhG) z-`Xa#eTFYPG)Wu$ZA`b+ACEFoRxlKe9(U2dc;o%|%MXFZ zRJ+JZx=&5EMER~PjTv=Doh?lRx{{h_As!;;H4 z{kY*3-6F(j=6J!WJezd=%=kT^TDG9vV0)t&9SbmFS+vz%+kA}_<6v?(qO={7kZG+H z6upv;k7rg?xMHF81c{gVhzEa0(khf=0t)^S`lgy$iZxG+i%;rF8`dNW?!f~sUPvqY zOM~O21@fdJX>9H_kVSv+TndCUT!uz@Sd5(sCiHd-U;K$}==S|EF##{j4v)kUtM5zB z@WxOrqqT^f7_Cy7EX^`6gttUxL{YZKH{Gf>sdz+msrY?b37k4Lmo4afb>mvhFxyy<*?Nsh?8rR& z%h%+LIkt{Lo$Bo=D4p)X&PQXe$m4c@MjEf>h1kd4WXHX%N8K;wKa9xugpd2CjVIrY zdEQG0tx>jWFbXGKEXr*@>B`m)JOcOK>DfD))8TuSfVoFl3=Ndv?l+f*4mM&x|ON= z6`q2SH$KY1B-_2FVF?bh{bp2KY9vRwqk9UsSYMy9#6 z2y-CKfVAXp9FPY=m#@||XU}y1AEG{0&Q9wYdabuJi<~{p$sl-=grRu(#AoyAKKCKs z^-Z=jjeZb@%DcE34|i4EKT|6Nv}lk}hMqnET$SsPjfbFpgMhPqVRju~qC87^zpkFO z1!u;+Lp-~0P*jb>NOe6gc~y3lB5l0$UTFillkDIv`XHodN!@gLHs^&}fR37z;km$%nYRa}JWFwiM3yx9RuVGS>Zi!WXMdy*nh^(` zz#HN9^+wGmN`!Y|8V$L#-_ILOy1F+5x`5)NGbM9*Y4uGq(p&WN-FWlv&W1bj{npyIWwYOk@xPy|t&!(Hj`Xy*EK|QwrX95MKGEb!bv1Xl z@-R9t!S`97xZkq3DtZ<#CAZ+sD~Cdh5IK&uxWrqb_JrIF+GP-Jw!X;y<|Y0y4JLI z!ad7SuS0oLx$wUE1+RzRtsN^)y#h*A0oT$-2e8qsmYyxScmj0fVz|}%^!l_!G?zc< zY70RjM(Ikr?p!jvx@Mzq+n{xsGBV{!yx>(`fXbRn=`vCL;M-C09g2K$7RX`v+Z!=0 z^hrIm`+4E*H41l*%V&@Ya(g6P&Le(Aqz=`~dASsZ&Gy2f>zlq_TC~p7hRE?zmJ7#P%V%6Q&W8rI`fu7l&!>s2q8fKO5j8T{)#$A)F*3Er5&J|Eh1byxj& zHw|8wOJ231+p=*o@;XqzXP4={m=)r0Hm=uH6nlpb8nDM4klg9UJKl;W6c`I_b-@>( z$X{#wE*k~Y0mSoMH?@pWs#<{|M_L+3C7kGA`Fppf$x9LY2-}Spm-6$2bNk|I@ptlU zR)=QwStX4F+hjM@GE4lYU5sabq<{(Q4CreayI;I^5j$ZU>8ANJrfLk76jF7VecTnI z3za}!$SUV)pB5jc@w4tK8=-zc{nn|?GR^VAO?fXi|7VldiIGblK>LcLG<&gH40v0W zDNk#^jgtu$D!S9)hb}R1)eJ1>Kx}0*Gin49u64W6F{c>ln@hjr9- zq6ARbxd|Bc-`MDf1A`^rb|JHt1&e5U#vbYJS{ac^84(ALh2ot9Mowi~QTgBiS?2OS z%cEV7VrCEn; zC;WsT#RL<^sT01wZD^wj66@u$yiBp|ei=PDKAMuVJ(BmfK1M!L)Kes3w0=AnBC|CL zKT=UTISLD}L`eXnwI8tmIMUiv5au&GND~lXv?}L2)-OFg2-TA)D6M1Z+ zKHd>X27_sBl^KaxZ2k;XGL=7ZW#1e}Y)C^nQJ^?R4f<+baRR;6Lq}cb;9Hd4no0n^PRYftYLo?9kzO+NodMWmcmA zXZxl4p;Wq&daDmNR&6O~nW*xJFMal3Y|In&))U5-_9^W(BU(Ur_NnS;Y?yIS`!jt^ zK3L?pGE=$iNb}4O;9Pld9+mctQvwvn0mAXEOvs_6Kkg0n`R_Kom*biYz4PXW`ev`j zFM;RKPKVkDdkT+GM@2*?__?n$RnT9DdMroKu$k^^tq7w<3(=*RwWF1{blatf1wb!Y2Z+TEfMdG(ZW z^{e9Qx&7+**wvr4tG_2#{~oShP_F^&d}zQhcE~l7!Zot~HHzIes?RlA)HN{k8dQ0W zybeehzQ$O;#yq{odc4L)yTKv8!NtCL5V(nBy$0*w5Zc`k`P>kHcEiiOA+5Y2>$o9( zdqeTAhTzi;)#J?@G!IbX4LQ>-t>7))sT-xf2b>u|g?-Bub<1pbLqmK6l)Pmdzh(1L zay0g6ak)kNgk(^K44DWOr1oS{xZ{g*$K|5F%nrq!xE0FuBt4Bm^q|D|$3?@-)HI1< z_WjOT*?TuYwbzBq^kU`)@kQ}Sir|EyxY$SVzP(o_xug0Nrf=ZR^ zW$GxG%xgVJ)Ca*R!>1d;qzI-fFHE~c%*0^8u$z8cia)k{*QOg=QY_|U56-(#)`@Fq z5+cSMgc4Nu#P$!kK48>qSowgk>z)szxYkxs47UwdtZ9s6(f86>@G+8K`To;KXYc6N zP|sxF*t`eimroJ;NfE-5ZmPj3D2?Ing4eE%$jFa~C@;T|uR>9={ei9#E)X|SW;9iy z>yo$E#e!~?<9?nv&-{;WY(hWjfrts7It}ma(G92)az9|a31FMOZhHFxBN6df<#$UX zBy8MmVjcg6J?DE5N)}^qk3IMI!n4aUq`arqqshyx?TNZhxmBn zpot^}dhADjuzMC|j$$7`cE3j55OgzSj`9{n6P3I!ee325i{K&l@i_Y>2tjiO_^1NW zwmyY9yK`RJ?e50{#*eK4OgfM+og0zd;1u`6v9w)a{Bp(fGvHgi5{O zgYK8gLFxUg124D;k7lYZ6pKQGh2(f2=D1#?S?%FwIY^I2r{je~bHLAvhvh*pG#HW; zx*DXan#}{4&futRBEVw^Mq#4y6v+#=+VafV%F&7*Doe zg_JK}cSdj<2G%K8&G$}c^=98}ww*6gt9>mnZFl)H6wl_vx!di1`VWG)0z+v<8L$Si z`(9HxhoM0OJhO~z2kR$n9Bdj0NeqvAgIOMHc#f1$%>ANuIb%=Rvt}%Ac~p!uR8Cl{ zUlwiW627{Gd`TKki`Zd@q^$OGGoi;_Dx3EYP7Td&lZzZ#CJU@H_?HXrbW+YWn7~of z_o_97>=6z}=w-Ar#DoUHgyDMZX=0ydOHv;g=#qL*Mx@nZb@pB$g-DvRA%*y>an~~Z zL{d6ZN_gd7Y6Pnk*2uC%;+pa3MDSBdymi3f0YAQm+bkZwn0vertK29+8)3p4Uj_Kx zOU(>H)lE$ce-7MHSQ_f{Qc@^27G7MH*Y!x<<$g4AiwB2GB8IIhl<+uDXtf<fx2MH$=5*F!eNL>k2 z7vmC%97yu(k#K7Tp_Th25fYimg!|Ls`r^p8Xi3Q>a8eMUgcG1Jhu14<3>L{@krdMs zww(w{wYSi^V=9-6;H(C7Y(CS*bIN5~AxLFhSOFAJZBVifYtmDZE(jM)HO-r?xzgTx z8NvtA=Bo+f=Vmpc~p#=~sI<$U+$iSu2A+=e+H=&|Z z_+yS088jHITvZ%u6H_VdBU{-lu$uifqAWynYjifqr6yiT;vJJ?c3H}cN(kZ8<`f6c z_qJ!5;5N$<(`F(=x1yk)l-)P-l2tlRb*9=k;plW!BO@(nCcM&t20F}cj>ku zaBhd`#&E)ew}Js$`i<;_!0go<0Tj<)#^pILJPPN6rdmLdF9Vo}&<=sunTufVKJebW_?1 zij?lbF*q?mI?74T7_B^7!diQ|HjM)lQ42}zdCOo*p?IO(Nkk&+159Txc8KW{s<7z| z*yE#&eWFx?5WF=yI;#|qp8 zCwqJfmtF+HUEc_y_C+$!85;E61)aO24$7+Id64E449VC$Vo0q_|J%?Se*qu@%6?6z z3(Ws4a?3#YYl?Q076(SLFz~(&0#@%F!=*@~WipV;eBJ-#(jyT#vGl3bm0*o+Fi#4r zjul9+3U$>wivU%Jj-A^g@B7JJ@s}hCo1-nALI%Tgm!k6@!#{@epQYnx0qYZjPvHDcbm2GI2^;IkJ zGH-`SZZbbdQyiohe@*nE5KMk!tOCrH$wgvK3TL7Zag;U~!tQ-v>>j-e`kEq%$LK4` zC?xfsAPy1lwj_l<4!I7Ebf_~ZSig_T&C`4|5&0z{c#R~-Qz2O*6w3@%3<~XlZoEd6#v9&%Vz)B>^(cGG`*+jArbaEprCMZSyvYXgJ zbIjq6w%nWMZ)H1b!s(eSN}^-BinwigtXm7+y|5JQ+3Gttc(tvE;ka;M>^GQ@?7t(a z=4?MV;R@JhTli@}19RXGMkw2l;S$R1O4l$8lG6n}=(c@Eq=NXgL-&#BUNfy}vZ3_F z9-55M5MIIcAXw5&K%KS}c@GjLdTCM1DKtV$)dXX4I>av(8f9%q55!!+@?e)j8~h82 zhdO;dmd+dz+2c+m?LB;hBs?K4(G+2{lbhheZUItO42yKVJYw1w8W%6%NtY2jVzUyS ze&25y8^4pFO5X)kgNKt(0Z<{~G_#JTyt&(#CxXMma~=h}`4>*7Lc`{W{(HPA50|HJ z??@Ly*E|c+FwdmPx8`B$e8r^o_6lesizr!qy zW|To~nn`1pMQ5JHZj%kM%i(j#5p~Md3n(%QDmDu)whAkCc-5AJm3zch1SVGorc{Nd zRmJAiBsfRbhoBkgl^j<+&I}|WjP$03&>NqLM0^-7c;s`Dpge$P& zIHchbs>r3)CKC|FNgv4&BCC$T!`(P}i0N3?@eJ7UWvgjOxq(CqnENeG*?1~(h=T>F zsHp19;WYm@6oywQ=>MCKS17NPkQ!yMTW53I=ZZSz$$8}e7ZWDICFa2;j*(?9(dC|T z6~2j;{z;XAuQ<}G5^`%_$;dBnsH|E7w`KE2iG^yBX zphzss3U`Y`Z60yc_(sTxGzg()d7{@|8zH0C(O^L?V?pF2kU_HbAi<@NG40Uu3+};; zp~nLO%Mktx2EprRdkrgkL`(n{ApA9^aP-oN4KrTpV6)B^bj%fo=E}I`Yxxzu4=jGg zU>RCs{~ys*_A$9K=rxqmtK)KOGK=eTOY2`*_@5N~w>K!7)YNz(_63sHvS^T^!vPH( z1nwbW$yn=7^a+&_0}Q-MWI7_!^Kifr5@U@VjZW}~Q@&T>+%gci0behUTmr;GvJXR{ zNXo&h4)=kVKdDCYFPeO55TqdEuz|F-e-RN$Il7n@C7XF-Ti7D%ms3*s#dk zbE?>|C_2-sc(5pYu&VpBY6L_KR8*wZjnvdN-f3uR zYisN28|WJt8W|axn3|iJTUc3H+1lCL**id?P#0G>Pft&8A739|-++JsbfsXRb}F_( zD$ctQe2p+Xy>!C=%m<`K*%-EsX!b2&yJlAHFgE=d4#Qyf_ldM78LxSQ-8hZIG>gwH zoYp*(!6NH5QaSB&_{}5vt>XmklK&%rIOYmDq>DJ`Nx0>6T9tCyRdYGib3x${=T?Yo zr>IA%xOcUc!Tf20 z+jEe|Z<_bx65po{DVH>9k9;NX0yW=4HQyrbfFi@7;!mG~8G|R;L#MbSrud>~#Ny`o zg17i04*8?c1>)}nk{$(8{~3prdOE-p1SH8(dmG`%V^t2*XC6K8r+ zU2a)@X=!OuMMG(ILv3wsMGd^V4&DH7YHn`n>FEh=+Y4>qkM7uy?K(*9J)qDL&)u`1hnEk> zKc3ESe%(C${`vIh@85s_Z8!b@9)T|a6d(mNJPSJ%DVE{Jy(|k7j)Q^)Q^Y+$u*3(M zst#FGHz6ZNQxJHEQ8%F>y}`kED=iI1VB)eRsQL;UKqg^3-E;Z^@K`Fv z21%T!P%wK^&malHP-tk`qk}u#QO5LF?gOw)>VvpmH*+z91era70*GmO3$ zEynyk-x`1+a2R|%d`O9B39^g|BphXRc05dg{^-(^sSBU1h@iQg)v#-l4Fg-WWf zlZ?S1OF^#L_1zoQZ2*~gX1N>aY6H*vSW&r$r3*<_tx>1vb+6e`Uu2a<;$qhur;1W_ z8={9YcqD&puh63{R@CMiBR*xDWg_?!z|$poTIV?_W>?-4Q3hTa;o;UdzUQ9iv$&ft z44JuK&V69#_tRh^X$7b&4ueJsxrRSXtFxQ%TdOBJ3sh=X2Dba?+fjno6EucrXsbPF z)ix*^)$}&~A74zYw}O9Pb~x%|2V$)MijkgWGGWVq+y_f@b`^){tN%PI5boVOG5UDO zbEwW$qN~;uhNI#}mOP=b4YetLqfEaNdOU=J$1JpNrT{ zu^N1$m#eadi{JSvR^(P0^zQFZYtqKP{S6sZY4Vxch3! zk01kl9b9Gja1c+#z2*E>%?kiS?GGx+Ky4OSSKS`5_MiU1J^yux4QUZ_7n;-@+|`4) zt_YQBLh6@;8~ev;^UeaqEONL*I2PUk8q&rfk-uAno_h{*IBq7wYx|WDJ4ijUl(rLC zDuI{;;C|^Pz_Tnn11MZuxTU1hj^@dt360Q56)DCghy_QEC`!wxAZ7k0iR6)R#KMZe zC8v?Ukr(os#EK0iARJl<DyH5SZ{Z;Lt}w-5=9Z^R5qvYkc9Rx=j}uGo(#VS}`im~eMFI(7aM!tdwu z5M{=EkGs-5WYriKl96`2uheHcP}!oVT!e*d08TnnYza)caHpj)aGTA{;$kc2Wuld~ zzE{eW%2R`sff`}*S3HYc^aN?LVoJPMGL1#J+O+qF)GyXUm_<)X^r#1@k?czL`W}F9 zE?V?_d~rDO=ybJsr@+scKLA;h`Zql7pIYmSob1TWP+225nLjK`?Xo6W)=V()#a)u7 zBBdZ#c_krIU(*Zw8#baUB=t%u`M3+sd>;c2@phYn@YT99jLw;;+l4wj-+S9=1Mwh_>bqd`_hJ6g?`F5fiipA$(BRk{$hwd~?;@4hJ(dWgagw`@9wQtHs&r4Zz ztrdc^-_!%1my57|md!Id9*Ik$72XeGdO4YC*c=1k32k+DY8UUfpVvC)+8TUjFHCnb>>8RQRx_w1XCZ#kB}he;CmI zcUOchK5yi6`)+R^fKMukDBISE&*S{31sTqpZ%je`>z|Mfg3|9x$8?98jnI;1)zgq$Rlmf4eXBACuMlvy#f^C+YWA(Z7Q z6w>L&AQa4P5GKGJ#%3QX*cm34<;q*-d9)rTEfl{05H_n2u9y|RYa8BJ8Ls{mJ~~GGQpvMJNga zjEbj?n)XIuOG4q^N2DkMc#*)G?V@0zQRChSE=izVI4rIcl<`811f+(g2>FHkGDj*p zfv-{HJEP-ZAZ|!>k)m(9qOeq!6Yv@(W&)P!hGuq+Vr>r0wFg0PVpY2efs@8T-VBro?uhphlPjGX|n_&4CobP+$>C{{$?@ z92Dt>_I@DlsMBi>CSXhA6k#48>kDKXfL6jlmz^Lpjf95{&(kcX1p_E>AUaC}Xjl|C z(2ij42HZV^J!U0AG84U;6I<63bKOAX!3fDPCv-Rh6&#jPlteMc9@I2x;q>2np9Xb4s1JsYrY3x5Om9CyyxmA3E`pjWrP~_1rf7R| zg`{&K5FniSYuh{72tz6M6N9VbRk{Kj(p*4roSzQ>1&CHxq)DZM69^|OPT>ulQG5J^ zVoJ~{&JY^&4Jwj^taP2#euAXrW|g9ZY{w)Fc*KkL(dk(aF!OctWP!pbqRo?_)uc|V z5UgfltW|T2f@oLF(dX&}P_8ZL zY*9%UYT*wS=-n^qwJ_G~K;8;AEDQv4jDIzwLBEbgSH@~S zL7Fkdc=RrviYz8m#-i{C$gsLl$Gm40DV9)%GIwXWlQ}Ju7I=tYoyb=}YAVOa@_JCq zZod`xWdM#eFcUXRSF;PVUXY4dihXmK$}9bx;;Nug=J7vaP!c%IXQ8~sJMT!N6rO>+ zpn^>4`0pkx%t&l~nVt6eY zgnSi%S+zy>#Sn8gxDx(QI|IU;b@LypMp6J{w))qNnb*YGKt(h#Fj+B5V(MF;YpeXr zjwI_D!}FvxY8Hb1nof{*-(!vf^2V+W%N^AxYU-51&>F{@EoA5{ytekaTpV0H8!Wpr ziQKGQ+ANQJ4X$sls2$qG_-TP*=?~!cM;fJumx$CTIAUy*L1i`SN6APKYs-kHYqOYg z1sCd9;8kR7`3f&FO|2C*vzr*WG4DsN;jOGy_=*^N&j6@$qZ~R^Z~;R$3Avf9g-E%W z;KIH7YZaoVyWD{f0$CK&In;tBsiPgyI~xjt!(8^OTNp9+mEf~Vm>9}Xb}*)NO{JiD zVe4kzydNN#3_22A(L$7aB$+E~-a13ti4E_7uXUX86)D^jx)lHU~9}5#o}MgTexm-t!R&O z?5ITRZ0)Kd)bE5(!)HL9FfjCbvugwlb;<3T_p1s7LnSo2yxD5jg|WVT%j;6X%3ALj zh4!?*ob;^jXFvSv+p4Wt1whAeI@gu3$f3Nx@KLW}`yIf!Y;oj$~vsduV)DYzKOBrM2ITS`r4!3w0L~M3=1OPs= zR&ve2xqJJ6a`&xjlwx1!BY&)HLhYltsGRZ3b#&DRkYkLLFY5 z3hAawg1~*_-#$+(VJXLSvSL8ljY~rv$7r70Wdu zk3FEoDx&u2wZ{r&bnC_C!VxIM8X5ib9mpnI<%?IliU)RTps}6A2qR4b!@d~MiMZjJ z?1`q6;nuYZDRwBcNPY@=UXVX@D?3jU16l$7O!0nZFuQ-bdIWwly-opLjDxDH4hh$N zbP$7jPQlNeDgvR!7r**h!1ca6`O7MG%+KTBvfGPxI$~L8291l4q6?ZH@&!@*!pWQ4 z+dEEnOrUI457F5SB6(Y49WMc6%@2Tw>N%RsDO}tf=aJMAy-eILsPO=d<)sM90EcD6 zogT$zOL~`uRiW|$V+-5!luokqbu*>s3;4idhTgGBCv^h=C^FBG&I`+$_{-Jd1s*XKHn! z=yOZOx^w>c$i@2ifLHa7IwDGF_@5OPaIaE)>2B{ZN8C6lphoI^j!Sigk!>oJY+y{d z@V)bfsd%4m{z~O+73v>yLK{uIBwrC>Z^Wtefyil%XsE{k%&-XR35U5CEvsWf)hP-j zzArmLm7uXhX6O9^7{d@xz4r7}#J;LHSud%n^eZ%&Jo74SGuGWX~!i z*_?`aiO!#jow`M$m@(F^89?lAJ6rL^@14NhEam#KL`o>TqwE)!y@maGFYto#PQDTQ zKL1wcrqOU*{(_`feiG)F6qBa(*-^!n{u#=CuDYFG_KL#zg9)asDAxU#+%0w00hZ0G zs)~T+3Wn9MOC$2Au?E2INMPI(YFB$XF2+tjXpGZou}B=su!Vy|+2Qgx?+Xi5{COwY zWNkSRph5*zlYol2aU|7%lSyl;5(q{VitHRB_fe%rt3v{Zj5v3?Lq5;Wc(*o8XH{r&5hUp`$;`_*;_ za?tp?@U8+y{S`*xt@5xs))!yaT_db1mG}zmq(+wKJS1o6ufTB=tg0=)UVMX==JtYi zaN%TiKK<@^wCK8ndL2St{@3d)cCkg0g3EKU{99vp4lukZ{uH7->D68Jg88LAre1p* zj!M-RDS|~~gn=$v+Uj@;G?{QRQBMcU6~SXa0?}JmgOs-3F!lc2@?^tcOnu+{Jcow==fK`)0OfYy&5qu%`?@bK=E=Lr z&i7)8Cpdy*_6xbXU)0>JPIsuOtCgQ#{G0jLyF0(`B?QR$41H-A{E{W|D0P#HmxTVg z_D_RrcYS6H7H7xLi`ACOH%|GxE? znm_$g=yn3wioL*@hZqL;Vaj{TNTN>Dh2|8IrMXFi*;=oqF?d(pWUxeM7T)5>5G2E? zFPGUqKR%GVkNyI*x*@2FwHysx3QUaf%7{75*R^`x-zZRr5qK!l#`2}e(Wf5GH%(Fj z4*`GE((rg^*^kUyRqS`_!pQ}@WD)2tx@my-Lwt9te9JnXY69PKZq|NNL14NxTiZln)%j~`;TR-+MeWoFgoy_9iRAI*ViJFT;0&AK=T!DWBnIn*)_#vB{H>6+RtiUrP#ebid!QEr}KA zHZ4eP(E0ZCaSbPg>j-vW|58)izGYg`QsHD*kKp<22p=XAJ!+WdjDxoPdiHl}-}W}z zZvFZX-MI_J;J0({-I~#2_wTt_m#(Y50JkA@rlqTXghV5^VRD~8?kTvLMmMdbQGYyU zcpFu2Cxx+RJZ5ExDLvl)x%!N(0C4RoVcgmX(C5Tpi{YtrOkuJ;0i;5y|WH4xHX9 z-G>1|fZP@^aF;VXihZvU&Q8*R5$~B-Os2p$Iw66`A&&W8MZNQr;)`)%n_?(p4CyMVu}>(fnf+` zQZp@%7>tFOzXHkk7J!GN>}_35rmlCS)Wx#sr=FrrEv5A~DY}R$Y##{$LsHJAY-N*g z6H+H+&F14E&+YZ1gW0T8MkYQ~F2ih@`D}iM@FfpsGC{xy%CeS@6^7{v;OBY=X)DHb zsk}1}okgOj$*mo<~5;Dhua_Oc)HQ|fU3<$$u8GbVhf zX~RpAyi0{&8gIJsY+1CUELM%QX1W_kN1V{_wN~Yv4yFzXJ@+cbrsk~_^tjIks{n-K z4sdhvLP&-nRmkBqT4_}K2&&YP(yP+QZ-6o+ZG#uMutCDlU>RmS#UZFm5uS*+TqChk zEY{xh>mC7Lhjy#`5VfuJCr~EK94CR^ zqM0b!Nt1pF!$pD`B$CALOe9KR2{~YsV4gyNnJ?&_r_+isyWlN3Y|?*3X;WoZH{-8O z?xv-0Y$2>S6!i#yFQP{>di>pYP&&c)yhvfh#0F2RHo2rKlWkk~)c8xl25d(XO=a`D z)XsExb@vKM(X5?-e(n3m<~7E5w}b8x2&q`>%8+|iiLew_E|7NHXZ`mSL#Tt z5!I8l84q?DiCWbv+!RaZUv&NMKt5zJCXGH485#l~enK7&C9sU-od=9NV=1|9K$w1r zq(ya9EWt93U>Rp?GKW_@!9At4Vu!wp`=jxG`hvr(vwCo)3i#N4Ae(H(Tv1K=yA^9{ zDJf!kr1FSre0d)Kk_rf2(zQ_~Ur-ZdOU5Vrh6|F1YV(*4Y+-1+uBn!k;9mU%vEv zS5yxYMh5v!SWtOpgL15oYJ5l2{fap6&_v0;OpiIzvg%IIEFeLC0eB8#kavE$Ho%0( zX_%tC(gTBSvsR7>xaCz~gFoE8katHXDzbE?Pr~l$3(w*SY(6O4Gob%PmHXza+Ea3x zk=e#Uo;@`){rr{gPh`b+v6|}GARLPrjQd0nk=qL;3fN;p+Yb@|IN! z*YaPRkkSg8q~KSzH#+7dO3`33QJ6RzTWV43)o-D! zWquUV#+(vh*Z%@jK&-!0tD1YM(#t-%!m^-(2nk?$N0U#7{~*zH`Cy zBRb za9c*e11KEqJ(kl&m@qaCY`LofJ6K#qB*X}V2*YCNM3vY+-;+cr^skiY#E7#(Yf>sE zV@FwJGEjrPkOM<8%*LlOL+mpypm;Zw(7PsNLVyw|IMl?TBE`b0LkqdX|HzmVOsXg- z>BH^WI5oj0+z7;=0y&WbK9jR1l=H9Upfs1Oi5Ju{o2t2>TeDr-xt=pVB_pi63cAk| zMWoX)m9R1)47?_E#Eo#pcPx%0aE;NLxrB&~;;<>Dk~RUPz)UQ@U&O$PAgIVoi&*Q) zb^&vCot<4iE_KQ7$OtH8eNc1{G{F=5;`aQu6 zK9v~0oBX+)R0)byDOIt^!}y@d7=Q?BCh7A-IZ_xgQ?{k3MzcCK{~!Z1Yq~bds|NMp z$4`T@qdI^pyE2n7xz9tlkD#@e@U<}uOu{QQnOI1lygqXq2f~wxJe!HG*tfN)rkOxW zg;+Ie7zf|THzruK-!M69U^ECM3!o^5D|;zVBfG2&Mj{BqJDZ8L2q~jrv-Tv5kN8fs z+lXe+fmRc@YEVvU^hwLwvV2>qai|Hw`!$9*tNh&0yrc*RwGH-kPaHGCvm&T!a;FD4 zvP^3UAiJ}KQj0M&2+PvXfP~1*M70RT(Dw`|`SeF=yucK5G7beff>e&NFti{{NVzI0 zgG0E+o3rZlPVAgS0(47>gH6IvjC3jyjRI4Slpc>%lN%6*{}+@ewGt_Wa4V5ICLQCf zscOOP;w!EStd&awgG#JOSuF4(vEte;Zj2Q2daL46D<)7c?nnY9eK7Uf3FktH=_(El zYrs}|t$eBt=Ayyfx-dsg2nwv}sCVgRrB(yPO&F5x28;HoZ@Xt1Z~ z2-I@bIc3c7(yQXKFhH|ir7HbtRKW$Y4>=9FCJ})JV<4C44 zDG|t!fGP^1>D!wkJsyE$w`|!jgw&#aeUywNmouFg|5SXQSaVHanYC4Q*oWPdhz*yC zbtI8BoR0O_f*o0uO`nq0laB?LkWE>bb(@uyn3IiJn{}Ry-i%mEtJJ&+{2Ar%LSRq^^eAVl*heX&kd8z?T^iMl+F#3DZagbRhk*{D3TyJCGXf>{|*V=NUB_JDTpYIvkW;))qsYg_@{tF z-Ji0)a7s4|`KPMN5c-oRdXh8eZ4WLiD_*U8>O@=9} zCy}ZRLEg<^Da=&G_PAewYKs%B5T^p)3!&ekAUc!V-t{OeitvG*sNV2Z*mvZRj>E`x z;@t^h-}dduKcpA<-LI6$G100G!rBS7Vyk=2ul8zH+4)|Fyb3F|%2GDad$ zD+wS1bOqJa>aGd93PDo|eab6u#jaUB;ZiNctc&4>v@lBjFI)Ai1XwNWi>&tw0_YMC z4&E)3t5y=8Q+xH|;`*?1rL^lZ)u&q5|KdVpxxg#mGYK{p<6b<1AZRnS(5w35EZz7o zJoPJxU}8hfD`uTzc+IEadJR|2E|H)sA`ss!MnWg13cs?}6<(`dI;=DmtVrpwe42_+ z{bFw2&C{!o?3xrUsjd}D}^ zxaWM1iz0Oj(961g4#lBMGRL4c|FkPOdSky$bI);>wR)}zi4d}}n73>Sw;1ILCxZrt zD6;naGzWg?Zwu!Mt%xdv5QCuQj(9kpgFKdoEk*-R*OFdmG^;CHRkU-676sr_M&%ZJ zF|QgU;nf!Sh0=tO3H)_Sk+WqUJ+E47PrFM?mo%ve9>bFeKqh+)&%D0fD+>J$K#ACi zk4Po7+h5=~0=C97sf0^1ygl?%JtORD?#Myc`wikVGl;0W$AihVa60{5VW!~9Sn7zB zR5^5xkcAHD#Gb@Zn~J523wR2P2l$A&s=Vvl(}KJ_=FGf)^+mKC4hdz_@i(lJJy8oiMOJLBRDz?2fv7TsU&o?C3HtwUhxBuL7zlk(GxW(6zQty zEc7by%69OOV?hU|NDI8a8SiOw;BE}gO$}~P zNlXZQRw_cwz6d_=|IbTrAwO{U9&z|?i-VnSgH-6W=HGoPD1u@~c@i^D9BPU%G=Ws+ zAdf~!d`f;)j|CT~27h4feY&c^txiCle=q`4A5|%PQA9r9VEpYKAawE?^icE4z9BL+? z!MPJNVdz9|B=#!TSESa%zQ}SuYU*tH?k^vTd`pYrp2U(fUaSth+{V7WR&&@M@j^vJ z1BdXS`^>a(%q$D*CUo*G1`FiEy=i-ru^Y>FDvGl9ZI?VM%Ur#L2<(p-?1t^Q0%r8e zw#>{%i3CVV|4@EY$?kB0TKK|h_>DLveL^oCc!?*0_(_#5@K7kY(mn2R=lu3@Y)vA(tOi_2G3@1r5jE75R4_RCyO`xH^L*%l2VTi zcL_{qd>VE9F@t;?UDc0}LGp~!X*SMP|2!5wX}N+?Z5C+=`HGc?b(cqcuEpVq?KOZr5o?yya2rEU_b-wSD< z`YmsmNe#`DfQIKbNH--w$?}0zrBu2Cue4BM<1&d+MQ77$FM%4@Nq()gSXURGrTC99 zf%@c-2Z$rYg!wpN@SqQ2!fqsya3DbvVo7uyF(`pak^@9^Sj_k^A`^!i3mSY7G0B62 z2X8Qun7|-Kl?Q_`(E%~#fgnK)vUCZvWkriEQOdk&Fv$[rwN^74QVpazeOlX-M0 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

      vaWif9^AnaxXRwQ6VPhJM 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 z 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

      S?1iL}olM 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

      _jq>&bMerkZs08!@&OFV{m_a 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%0DipBOmN6_W|rhQ3DD@LDW?os<*# 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 E4=D5@*Z=?k diff --git a/assets/images/list-workspace.png b/assets/images/list-workspace.png deleted file mode 100644 index e43028d1e85b5e8ba1a7a36668113255d7750cee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 401315 zcmeFZi9b~T`#-D{l_DvWWkjXbgtD8dRO%fm5@jnwvSr_flT>z+3R$M2q-5V?ChJ&d zDm!H`GBPyAn9VHbcc$K-@Avb#@4w)F+&}Y}IcLr`=UlJrbzRTr^SU15FI_aAZ=F$|ZkaHxDmY5s`E8&uqkP zt-56M>@0UziLA9e<$M3!7L~mZWKV=kdp+25V*hTj`w2=8SMDx4uTf|?_WF$z0eZqS75oKd|0;=c6sRFWk7l75;Q;^ZJsfQ^(d%sI%fzT}{4k7Pg@?%td!LT2 zS9{O+%$&H1(Tg=)1P|lDn(vCgZfrg@az%UZtMUr{)`lN=yhO%L>$r$B9%+}idY|d9`s9Fz`5o@aVW`!&XCDee~2;g;R=$yW^8CEqnZGxgpth_u)&chwF1f z;}|NA`#Yr)tX93A&$J(Oc@^|)o6dzUr^$b2{9MbG|EZL*{f9rCwKl~PW_74L$>M(I zrt&kdj%sdmJ|3q;uOziRL*yrFji$vQws{mE1|;HK*1vu%@(^(~Q)6R_^=iiKtQ1~u zJm4UWB`@QT-XClkolx^~mITFFvD$aX1&u>`9o!yLo2;Z>TvR8>B8@FxxsR68Q z{hIQGay{!DnU5>DzIFP$wI((@5A#~|e%cz9i)fsCh{)5>h)c1ViI;QrYkj?gGud-u z-Hn(NpG7Q3zMW9+T-!1Dh?BN`(bHY@=oPQw49XW!JnmW+j8c@Itvvwo@t^tWP@~o410^06wB>B#GjjTtpa)=_Zm6s4 zv)+*Re)E2-ujdYJHG5{9zsAtQ$XvCz^YD$bNrjW2C*wj>)a3CO@g*Xi6YvDwaJD=r zLiDRQ2j9mP6+x$qii()g%kHIHU@w^bhwi>)n%~W|FXFQ#BRN86JhWHcC zX}9+5=sIyaZhKaAuSxgg9i8E~BrKB`OjA?}(-O}q_>2EK9sYQ@Q+>OM^=0pY4b`Vi zUzB)s$6PkhojUTV|7Wx zw2O^W;Mtebn>RAo!Pmwfeg61l=BfR=pUTw8NXp<_B8n21QqJv}-}W(HdCAdipPO`{ zjGT<_R@OEP>G8PKc>bPk=h3$;mUo{?t1DP*xzR((L-*I7U%QGDSE7qg>FhR4kLfya zOS(SO{^GEBHz&l4$s@q zU%zvNahQQ%Bqt;!WF-{-laz4DHKqIdv&e&TR}8EX@9z|i6;)W{KKx^y@$UB}<2T`^ zj4jD$D_?W^EpM-{+FNyJZ0DHCnE3IA7x}wPlS_5%KA!q`aq-32g`k9nHwG6XUx%lK z*RP&r9GY+1wSCK>Ej3~`F3-D4uNa=(U~;pS!ob#hJ7ro^+z3)FA>?$~(-R8>~>RIzT?-eLW^{i|+%&%D`S(HH%a z{#S{=uK)563<%7aSN_uUhU<~}_2|&i=CU)bcVZnBn2x@6dDy%YrB{4QC(N5HRyXri z_+I>C%o%zbMwy_gKz()p|qIU*2fGaekXXl*!v@6+fnY5ARC ze23}-uOi+c>fArt67b;m>A|>QaclACCa+AAO$zf%TpqZTyEKt{(qz@F&T7EIqGoi} zbqf^>y)UxPdL(aBur_+{H{j`R=$;qwkiJFk#f7pSuMDvan-XTp+TrAq+8=X1F5hMA zj@L&9vF>Kn4L7htZ9@yfuY^}=S7&|gZSR%HTSpKfjOO8tkm26{Un2Sr=4AQDK$9P$nMdtdlfQ|}R*Ye;>M=`zi z=hjM!H@ZiZyH{AOcaGj2{U-Y3$?GRKo}|Pmi)F8OUpKst^|0=tnUwyHe>QB9a!?+_ zYfdle4d!5urj}*h?3;Q&+t!|jJdYiWB)zUF0lM}u10$a z5b=h;ZXDcw{6LV+yqwSW+Jtd*$N3Lt6jFJZXDFO4;92vOqf>7@oV?axv6`^*dow!e z*-qoEsH~q^O{Z$^HZ56Sy*>1{m^FHN)UZO_|A{|y_DO(MKx$mo>CxA-Mx@4~FmLAw zzxXuxT3VRgpJ?(L|# z-Lb`Mm+yY{?Wg@}{AI3f=H8q8RX_cBK+oY@SI3Iqj?Pw+3BO;+Xt|T^=f5x1W91BY zlv8DO{rIXRt>l-jLV3;2-1Y`n3Z|G~4^*nYboPC7^XKbsmI7O$#CwHk`>E@;)#zJ` z?1$ODz8gm^ZCtIbG0*C%?^61``>*DJ3L1M5i)B;;dMzMysY&)R^y{OJ{h~w<6Mjs7uS01syN!Q*U{^bis}1=+OZ<&V4I#ZT1T^Sqt1f01r%qy%a{7Ep& zvkox~fl)U8u3trcrolQFRkn7n8+tg8{m=UPPH3OVNh_1{=b@#Qi@&R@Prz;8 zK=$uR6KKQ6yXUS2h=|DU6~5P;x7@P?U4O*mify2+xtW2BueZj{TfWY&8lm2Ih1U@= z3N?UMy{5d4h(^%Ek{E~`^ufMB`j>b`qqpFBa zDk>^Q{z`F);ct}WyMu@hCufIE7Q(s>nepCytrF8^4;z&T4 zPvFhaBR&CYe=qW%>zsBCaPjxJ8|dNdqawWSO=sVrKx0)^;Sc@K-{1Rm4fXinU-Aj~ z_pzV{gbVk;H8qaH|L5A!sYb%B2A4cSUA?ZI_V9*m2K@#?^O)XIqdzD7zjpoaPyW}b zw*Pgip4PGdKJ~wL{Xb8&4si81@%4s&G!XH>1NQI9|Go3y6OG`)Xa6r-{5ABSt&pV= zn~dQ9Gir!U5@+rS`L3eJX^Sh+5^^))-`W}IWB=bJv@Ro(+A}hvIoi!o}PZNzu;Jn=h*c7X9wTh0q^Xn z4zeo(tE>+(UQeHEFHy4dyA|gpQLU$%DIYUGdCz5?+uKDE6L~iymV$P#*|0k}K@b?b z_xVyQS^C`X6D;mIY~@h+5Z#Dajll+uM>LTeTeof$y{WSKLG;nBVl5}+H~il(|KGMj zy31sR#Fqk_=e(asQt{#MzZ@7M{~p8Ayz1*|wz8TzY}!<_ zL)`8`!+UCE(%|?mnI^<6<8rBYd-MOj-2b)R|4$v|aq6Eas^K9ve?Rn$%YE_77Fmsn z@SwP0jgo@nsav8tjw$QRRaq0ST(Dc7kAVqxN+ikQ){)dmQnGKu)*tv(@?G_>c77nNW-~I%KR5cB9Ys_KT3U{!PU3=ww__>{yZ~gIejFja($<+z-9;(k?5mq@=6q4oj}Lrf+>qGU%QH#sUu^ zcLF5&Ut~KcJnuuk+Y8TYz&=O&PwM7FFtYg&u^3ytBSoBij)`7CCdEf#7kl`1uX;nf z1thZ<%$f7reYM5dYe1#oBE4Dv316LS0Ue0thvmb`yr~5JxB9?OURV(t%fiP!ZTXDY zypr9Cm@UGbmcL=Ir{m}qCVSN~2wvSNzHJ$CPAU6` zV7vr-4tJ%4*mfR?4lmIHD+EXPLDu#B2kBG+-U106buu;wS*UG;N6X0R0~g)RS=~8U z^^2?Y(|983yI=7P-4p@*`S?k9M*uA+uucsYGd$xIsiE%5a6#0~g;PAp%!6V7bZT>Qv#~qhg$|qWZ4yReCA#^czVGjv2 zg}HT|A(1Z;9OV0+vw$20j6*VKd73HlIaq(ed(XX`9HhUXljCA^t;{L(_t7_J`L~ac z+S-t>;9+V=f0GydkeNMPUna5P>MgL3qed>x!D>9CXYgmtw$`7PpIlO`50t-QVq&zC z9+FO9in&-sidlckZvLaTtgBa5cA^|AQvyucS$Eg0FIf&JADnW?vdzH7mFFsOGM!7hRJN0|W1c_!>?N)G6tJ*5iW zjnhzHJ)_0=x!)5y?wHM_iBHZ2ePD){M#oiM?ER>&50v@O@TOjDge;!(n=bBoeGddv zv_IcdD8}aXy?SaS6;v=ckbZEsx-cmL$XMx8K$46Q1^tegr?za?@DIDOnWE7 zTpe=lMt)sTRwx*|B}mTcG=~fe>sV_c^t~j};Y)N}(A+Wo~EaemhCw!Pm&C(xkQrCsb{rNgKBSjDnpDG7NXb##5PAaS=> zk`o}*1B^JCEJPA!Hqa~}0tBe@`L02%V1G4b~lFxe=(2imf7qFv1VdR6b z=v$yt*koZ&o!h&7`ygnWUpjR2zDVS}y{7OnATRcS-E>qL1x%IM2h>Y;&hNKzfVO>y zJX1 zOE<00R}`?8#hlJT^FNW);rEo2!N47VQ2&G>C;OITIV`z?S0JZ-cjfm9()l6O#+w+G zAW41S9Mb~)Zm&wg=N3ohsU-0<-LR*I-8+GZFuSe6(c1b?b;EkuJ-h%(O-IN{DmyqW zyrUM$^p3DSAx|p>X7*j_IbE+BuUQ<79dY9|L)Z8z+0@vT|NSzaJ>H{$+I@Fl?DD?U zoj?|V-`(-g5X?4n_Cl`VT&^x&t-c3x$>I7|z4#n0vCNlg{p})&MZmkUta$VP|_VQy!2$Urxlvzqv!-K;3BQFzV{E^h| zcVC0+i-!qgaQpR3!xF5qw|I`|wilfn?FSjhxYW*A?mxoaGraN;CU*6gNuAU*ZuwYgFtXiU=Fqf(rK`+>#lfbu$-I7X{v?4ifVz21?|093*OWu=N z`zL+xsGqy0TBgP2;{9kZ^9)V{D2KcDwyRGccAOC-I$l)3NaQaT^FjQ2*TsN7PrH5x zCX!8(c$YJb`uW38UJ#-SY6-LiH(uiFUl4fN$lI-H-0yn#-=gQsqp?9;-&ta(ol?MY zG%bTh#`wPABe}p3aRK?evLA0aJK+9r>_i3#@-Re~hbv}%tC<8CDep2eV4%@{@EDnp zgWRc>r`;iajDIDyue}O9`ui6_0|&PIgOi5nvnTy=9U?JW{{EXkVN&H%+EAy;Bckn*Lfd`V3WPWorE&1=fEE4Yy8J&X?@^8`D`;r!WE3njmEv}#4( z*|X`^RCKwF0O$9Dru)$_3n1m({C$f*3V?o1eNY5Y7miGcxIR!GGsAmEC-a~jhNW}V z(AZ^8Vx$%tN#~>o$UGqsIlR8Cja@7$jvzXy*?pJ@Xk%9SxS-qpG@C`+Plu^2PUg;))+%E=^5P}PmI9c>msN6 z9qA&MdN>6EU1S1EfEV7^ZX$Aq8;b%TQ(+npsW5qR9-v4s2IAaZDYbmw`OSKJlre3Z zv)?)N{YwhBX5Q^wdZT9i(KyIV^z&+{+-oXEM3h5~~+#dnD4 zjfZ_0N?Sk{SBygX;k0eE9K9Ox2bVxIqXJCgcI-ogHXrjxfl=2AaEL!xz7{^~8TmKH zRf29{Qx(gJs;Hw6g!+D=sy$76KP=nCxo#0P&TzL@q>YkQP22A6fn8=_Kpd9&(r&Az zxb$=iEuJfGuxzHqBi$=rYJmeXv)PU z!V`=?&%=O!j2=P0_7_YD@9(#RT!0`GpT4;Nc!Z#ba|rTUY?e|468I@ZF@FFInH%c| ztQ>wubz0_MzyPCMeKjI>hMR!`EBGw_Cl<)G1N4~y&S3PILM`AsxWqkW2+TPX~+Hzi{( zvC6xBjJ@8gok^;^fEqu=n}k9T_E&34!2RuAyzz+8yO9A~{1(5v@%!bXgh{ju3V=Ac zoxRMtG$A$|h5HK}%wm6%C0Jh;up~KUePBTeR+3$C*9w;yX5=sEh8_}vJpO`R@K5$K z=cR|g<{-}^Mhv&I9t(lf2$SoJlO*jYr>5%zb$Mw9vHIdG{@W=q`SIybzgHG7a6~qr z6Rfc(X|;-=8s6z&I-*_wjuj(+Kqh&6a|-TERmZm!`Eyj4-ucQ+L^gYX=-8IWRuu6* zWUz1$U%MFsoln9k_BL3hZ8b;pO^ zvX_+g_lP!@bxz5@OMIV}xplLTxOVy)L-h@=>gGKfj1f}orBYZ-6RWiD_;XAfO-mZ^ zY76=5zpY3deMWjW93x|GNQ(Dtxa)=7KP>Qc;{OzbF&IwR+;xKUEF@dqP|yOfkzI^G zPf1FZY3|BFYJq=W70_V1!u5U=pq%g*C#L@g;hP2t-VysMhuD0s2LkwVcKiT*!Z7oj zTmcsNf?2hJF;-wcTjv=hf%6UwlYP48mWZXAxclemL#dJ|#_4_3))Q`*48N3@PTy0v zesAoTBY$yIWLaU!e36L_t%&?OH9kNd#gBJav|O2tK7#T7%-pkN(Ev8XaHl7L4qz6f zl|r5c5dkqMSV5#Jo589hfd9G6Y`W>+v<87yS`_$#Zi9D%A}vP=!`jg{`3bc$jsmeg zG}FUNqo%#-s(ikvLHT)F^RVEC(?bK7_od8%QBWE7sq^{f6Sr>}iYdO7bnIq)+hQD( ze#K7Q)9Ogz)2wxyuP-;Tv+uF#Dq}mXP~Vi%TD0n*^4ssP@eF87Yd{WjB=)(3^Ce&I zS3B7rrlR^EYxmpsaAD+sI>2N5Qo{LNyzDwWuZQP?xCP<#(?e+5VH<*Hk`w_QYYe*b zb33jJAuvR)Ac&qj)F#Z#qjJ(%c=sQQfW%QPp-jizG!*NN1@Pq5cr1y>o2oNDFBr87 zNBvfxY&P83J(E_?cQ4M0@(BP>H6|d>ocD1OLmlAm>X>vDeX-{E8U1O>t$lF_OEY>-AExC&9Pw{x(1l_#3^6VQ zgb_JJ>`#bNK*NOt1WVk6UToj26F()Ew#j$lSwVG5z;*+y`taK#S!TgV#Kc%Cz>{XW zp_X!6YcF#7OXX_M+0Pkr;)hT3%AcYS?Y#G;Gh9s3-gaUXb=8?Vb2>Fw^Rt#DXWk_1ylKJ;dnjN15&P}&q03V-Du7)cj^tXG;%NQ78xFD{f z+u;vY7Vp?9<$N7y`7dX{AU`akdqtSA;bl;Ac+5y7bJ^!a!d(F7=7fTDMuF# z=NYk)*r=NKWD#N!Wq0G~zWRPgyY9Fm%<5O&2jMPp*ms?&VPbncF*?`f?`|F1-V|fr z6q9ZswjZ{6XXaS-f)-)2Ej1REo3pBS??|Fag1k)=yTD$f1hN><;8k0zSovZ6K=ItqxL4?kQbP19E@m&4vdT+i=u+S=y|m|0UbTQE56De(5dqp7 z!5mKZ@xM$T*&m+H&#-ozR-;g>W?L>m25Abk|15s0VUYzrtws|+!>_fqo>VXa#31}p z1nV31Ztv`d0k5rO8}qLU7nd5?xrbakTG9eWP zT8erp&*;&bC8F2_2!w%*BP=yD069eOEzH0}9cq9UA7*S7qL(Sn|k&H6x+=Niwo zo}|kt@YI4ZAN`w{Y_|jm#%6dwl|J9Zg0WO{CTuM53K!;=7RBq=eQ3~Kz|1vRp1TcW zJU?IEk88MEo#dK#%u*im#-5#bRl?J^SQts_7#;3;l|Ha>=JVT$ljalgCpL?FD}C?K zY*$9+#Y`I>IEbL}$8pm!drN-3W#8zOJ0RGQIde!XJn&On>7wx_6mf^QDGFB5d6|@` z`+B_-q6O4b)e>m@X5eUf9Hf>CEDOv6k3MF=Da3Y^Ah1cnJpvCbr!kNeUy^noZjI5!z5DS<4)It8Xt(>sZ)tLFT54Kle zAc#R?GM11jXJ+vlvrbA77F8?E0!j7(eO;>=3}X4?Ki;?-3LeB9|N zP1CIF5whREXq5Mi;Ka~&?<4=!d~jc*1k;LF$@YCP7LPJsaR{|K6P7M>`$&3eWC;ff zA!k;mj6@}+?gQ1Yl3tR^9Rct1lk!}nw*Fez3|f~{#ahiYkH;%9n|u^)muEyM;>wJr zYm}xY(^%t}OA3}S&2#0nOT-GeLfy#H?R%33OzD9bZ7gB- zA12Yyr|#@$ad+`H?R6Y)EcoS52*t^g_6zZDF}C-?H`v1u^~|n_)jIn3}uHSmE9h?A49J}&T5{&n@gPFJmbT;#G6RSA_M`UApsH} z^yNq80XHyrq*IX1uZ_ZH{mu1Bmo$QzkIE;13p> zM#0`<5ge)d)cBf zy{%9Q0xG`w&IbZW)cq5{-x$OTKnJerUZpSdkre80!k@twN^j|WTyBV&FbXYVfles3 zr#b*&x)8GbNe|_D*b$SR#NzCgw3U}c5atHD=Kk1$@Jq6xuUKhX@ZSq47mPUv`JBpS zaVcYrkwQMMusB)pmVL?Q4X#vB^^9rn|1CZ6z}Cr^MWO@EuHX?DlPI6EOYVooD{BS` zMm2+yO{$JZ@?B1(Uqy=R|JuhM%N)z&FE!t~`GGz6`S@`+Zy3}0@$jRnv5&33Zzaa9 z*@tDte?iHSsn4cUkvw-u)H3(9bFc|6hxEp-RYGRB@R_Rb(YLwW5Bj4B2?H(P>lqz4 zLCA^a^M1X^h5~S@%kKY(6It{S1duaGaH<-wlrCyfwrMx^9j8lC)G*GESxF6jEU;~A zR2J5laE(4bsSsQ5gIlPSP+<>Qr}Y9CBQ;M2!$qS zB6?snaa!O$s0v_4(Q;9v_zIFZd2}A+9f!^dby=Yxd4O z(F6J|W}IJusH-DCSEZ1#9NwDR*m_X!FoFwJm1m$OlV;>J2~SE9UJ zQ`v3DgDnNlBK5Xpt;C{nkjy7AzmR0a15usjxii3r$WSg@nWyDU1Np zk$IY8_C2~#bP~X8uzTHw!21>m8@@awH6%XU)<6gF=ze#oNFj`0DK0AH)F$F+nNHdB zl2t)_wT=+(bwEKZ2Wc)!Sp9%h6NZ9^^?8N4JLlQ5Cw(^u{x+Z4K`Z|>_Ym*6XE?A0 z;$JG~isGXmZ3$Q3%vg5Kdn!L~7p(s|sqcjU(oMoom6kQvBinIOW?qD99Pmcn4T1}w zi`mbWCb?5cB9EUTxdW}2J+0es%r7(^pYD;uFx{aHeuZz0hE)x}IlXz!oDP+0uZU1Soc(mYZ4oK_SSq^fr>96MVPH%Lk}&79j0R>oFHL-1C(*I0PmBx zEABvqs`3*A9sb9GpV8%@VTI(g0D-+C^wC(Ryh03_;pNgp_=wKRm|t&+fM&{4myqS+ zE(*EVK+x14EZ{~QUypFfMhr$)?vVQ#L?NDB@}SmG;CiuHz>VqB5u5IT-SdY(P`FN{ zFH#G}z+}MJP3s(rr$zDs$#u&?lX@e@oAoY*M=Z|ttT}D;pu$4wgk&+o(U;<@ik}LY z+r96=;)x}e?tx@igVq60H@q0?3 zL0vWU&-)99i;+h!4LdGh0}4N_WuFMH2HCm1lS9Pvz5V<|>YX1fa0Jp|SmWUB;TkHM zc=!8?;HD(ZZ0x}B$V)YAT^#Viab(2Jt4pn^NfS4gI9Dh-uR8zj^&w_r73PYg|HszM z@Ic01imq;4mAb5yPKVd%8I1D~3i9Eb_tVHlH5ZLgTm9P99bzrA7sLfKhcMo<#P|>1 zsZON9x*7>&!4QL^k6JB150aOL89>RA05%g#Mh7=aTtudQdA9Sg5BF|)~q!d0&jWC>j$XXpZiGK4y_B$sc; zB=&RoE_kHeFelcUcPtO!%jEM}#BqpH#J*q_h0m69#(+p22cRs3sO?Y-##e7b%g3=h zPMbz$3tXg>zu`uu(BY_X!Pork#PI>S*e|ri%kw?Oe3Ml6w=V7zrTueHyHjI+M0@9! z@3%6ocbwgsXs|M(KUZY;5T2*^{Jb<{2h6y<{wtNMhS8~7KPm-O?E>yx@Q{Qh>7%?N zP|mwMay(0QMy5)SxH>Nn2ufRUg8fVJ3cOzq4?qr0=n5GO_wQh)#P|X*qP8?#3eE|O zuZ+WwA+>|>os%A!*8>&CI%7M>_~7fBw`fksPteu zU6e^@hdCv?T0SrqhoZ#H8bojt*r~Z;e3@WiyB-W8Q}rW;H%wnaE!TKsS*b@VU>JJo zSZRy;gd#$72}cM$@@YG1)a~GxDQ$PSSTJSU64>`9c*!jIrDqj9FB*UEEr1DhRB?5x zs+p6X?=(EGxM!|PQ#QzcIXXHeJdpi@$^Ljp78cQ_H!ahzGy2Gy&5j|rlimwRPPEQp zEj{sOoD@pXA3FW91x>kjWlteSJ-f+#*w3d_Xe3cWwDk&>vR_X&3LI9nvBvlEOB z1E-KAI30RHY|sfWHVQByQV;$HphV_EC2yIPmTH-3_zeYxKiK8S+iqvP5a6`tQ5v$K zgipO31wMn8P>HCI}MY%mi(cb^6IC_N5VviZVOj=y0T4KQKvMXWFBu6{6kFLk? zwniXP^SX;j+SYN;1#3R;YIYD`4#o}Q7b>S2x==U4ChlWjhSFMD_BfdxQvmflo~@U|tHC283?NPc5!>Ce^$WXW*$ z9IQzVxsWFq7bn&-pAXZBxM7yr zo4^(4t&UeBn0%lJS3v5v1>z*$X#b5yH12XKv zz^XNS*^V!Vm*agL27a(B`Qy{2;b7ZFfg8OPgN5kbjnI)>5N2F-K%Qlub(nRUB{uL0 zoM#O8F|2UXJ&YE{6$h9x5-M!Ogg>PHDK9dK{C}}A3OpK_(V_h0U(`=mA(#4TDB?Jk zc}^C0cr=VurQjF#7bhFxTLG@H;B9EGz)uEs^k>Kqj`$~Y9CFbruHGEC$=R;?`CH zOqQr;8cn2Ipwq@c@1>uKb*mpKz>-`byd%j)?+=DfraKR=V*ljcAAb-fd~>lOSeNPx zwGKea%=j!X``^Ta9R=P}k7i2ggQ*l}JlN0LuMa?Hk5gfEe*Y{Hn^LJEl%^`{1v4aOF(8%%HXIeHj#p0>SG0zyKnuT*!T}9R?a#4e;Ao7|8CW!4ZDUR$PZ|_6jk0KEM`5jPYZUoIXubXZcX= z0U%q>f&xg`K&PqU%!WWe{yQ#1hx>;LI=tY!KNOnW1P>Jlxd`H>n@)o8(C$BvU1XqG}Zb~?wXQ?*_!DTf_ z!jQx9{0StZGm4T*>a8=zENTyyOvkt=F8iOK2xU)^T#T$J)upthUyBD3oIAe7ZzuYJ z?hi{0qLh=NW_j(AHe|pl5}{#4Tx=tJo!{q`1Mn{yjYk)vZlu~uQ zr`a&j^2Q+hs)m=9xhHt21d0#M8wH)$e>Tn@qAvZT&r5X~@YB)K<6n_VU8=tG$K71{ zJIUq_0e27-LJw<7XtXS~-`b?jFQVS#_Wc!EI>IJ5`&rzKf>`&pq6nY99&2-<6n!(P zj-Xd+Ht6!7VgRyOG$CRm#e_*rd)7c65|&!I)b=LOz-Gjh5>eaO#l;2p^KIFm;1g~V`y>dsTjyWOAyu@zI>>*~}8 zoETL7g$2dYaNl-v&yxu6L(|$X(0^**o3mKErXFJ?{=knHWb-ZRvpm-N2>jdp z%W_B5e4NQYO26uv3$cXBAw2W=p#R#mTBo*|X35RpVxXk=ka~0JCmQjsWDFQ{$6gPn zl`Oz&Hh4S5QZpR}0ot{faT}EnjBux1YCU=0t1un}8*9fo!a^gQ0x+=)pguUms}(>Q z&t2HBG0Us(ArSQevJe;J|6O4*$-WqZ8~^mA?>H4pW;(&Can@MCDMS#mg(!s%_J6d( zWyMS)hj~rvWsz-fz)kX1UE+q6;i>+-AQqfm(pt(FFU1u`?LgEFEXG^_pFEZ8Y6BnzgWAjW?U3koTs(oc>WgbjRua14cFaWRslpIQBl zkPwB?TOecqlraPvh&!{~*t0Q|1dsnzTPq~X_Js;wCgrqoVuI@s-ig%k4u^Y0UBV*3 zw21gN28@?U!eH~|u96Iv)R1=~JXk`%2kVWyn52xpFc8GY$t&*WI-~#2#9}LttshRFu!x_ zi0Vim=hX-HY_+bK>jSODV!fGmb>$kP)tZHWkhJqQ3|JHUqB1Ssfi{?!3U{`u5M;Iw43WuESEXen}S+@B$fF5qn5nD3B~VfJ{3;8yqSH zh1|ITTSpcGBZ}=iiphTpRk3J&I>#L(fI>g&GWx~3+6~~{W9VoQ}lQf~xdtK{v)BZMDG3!{?QFRX;L* zP$D;)9afLwue4ugu784)jF^un-#bO{J!^0YBG>G43ZreiizN1?9*yl|W5T?dKhpB$$TPffq zmIp=lA1R>Uim-1jnR1BK3=vSsk)psq&z?apT|lad3JtKt5$h5d`ak{)0lWl!8G8=D z2V$UyWpkKnQ0Ri%mPlSgc`!rs?k)nXnD&XsI|EBI9|p~7^^>H$H8exf@-LOhuTpQO z^X=L}1C%p<5m>##bF`r~%Mv5EJ2{Wb@#=wh{L{5Zq5`g+Yd77ESyhHLvGhvDYmzIx zcRvs3rvAPnk&8UEc66&}_TGBTQOE7@HRX;-%lY@l!E@5n1|#xGakeublw3)}q0=OH zz9J@gb(;lBz@*i%JGA#Im&fbJmO_xBOHAq<5xired|AA9(#DwKoOV@E-Y;j!rMl)D zSgr%wbgUI!SbSX6jwtU$KMGgew0M{44`?Rtvuul62dVcw3nRsLwt9n0GOB}E^|r;d z19sTVvyOs1po&aU!0lf}q#Ccu1Iu1Oj_pDZjO2iE(Y8*sq7TejImt!bLDb?o3b)WpiBIDdVTv4wfCaBo z%!qVGL`D!xihY%L_4_WT-fpD9^q9E*9*k;g_9V%q*9smy3q`i$Urw6Xb*VkJciPV{ zUyvwUnADVv8MLE5cVORa6&bkdBz9Wq`;7Fw(y@+Hrp5=HH!pmaMPETbcj!EbiaehT zH2-vEcZ`TRO|0y-Hg%fAE>5h&GSR{F7tHA6E5Htfce%0u`SC*thI2_P&Zh)~!mXSy z5;cw9gP~s02p6P6HD>~sz(xuU0_D`sMaPel|?-TFf7v4%ibh z^PT|W74Qd8nA1j;mvm$`p?^_8_}dBK4u&Z82y{P=1|1=+BJ)yh4~-Dz)jzQX^x{Qi zN__tWFwu7s4{LNH9A*an=EeMoqGC(-@;R|ui~uTDaP^h@fmv8+07;7fo#P25gOn*{ zC^*|p$;7y)(_z7#2YF*|3uU#wGvrlYGgMl=z`F74{C2P)z0hHPlJVw*Rv5)>QNmSB zTC`m*F_KYRQj`&{u4S-1y)`Ct)lN2JyWJZcE-!S@i8ofFj1C>>&q$!Ed|=oIQmHNn?{_)JJCFcmdl-xGMtN5C88mW~7Ztlu~!t?l>@bb~b+HiqvfeW2iwnp}FJtDm`t z?y34|PbZEHQ5zE}iU_q5%< zo9&5g6#GN#C)G9zi}XwGdYe4whyeSr?%ReHu` z=^@O-zjIR(|BAD2Aj3YFj;ph1fRYR{YM%>sWJNfw^#KFG$o=swFH4AINJe)Z|7d%7 zVnzoiyK+Wj7)f~BHuI`iJ4E1|JL(I1?>mGAa3O;nDXcy!&^j(U^MyMPqEC?^CqGZE zZJ3}lg^O9V2iw)!@%}v;3pRa7ub=XEwB(yc-DCJEQevFvdnoqlO+QvO7Q8cVM|!h8 zyj2$~leeZ^nq7ZV=Tug-HA8Y!5aw{V(bKS^w%r!*j~tL0aFTkP6nB~bl?DHyMeCCJ zba9*C>{9lx*GkaP7+a*KZn30%_Ah&quopIF)dA@OH<)bpl#5-b4D6)4673FHWU?xt zz!5q%&jKZ}Ok&i$`wvA#1AmF3_G2B9N!lm?c&L z3@-64_YbfUx*XK7Cm@4=+qz>c(4_Dzq3DqZ3lJz`sYOJ@v?%V-1q%gI!H#@U1; za2tid&3fW7Ir0(_&NqD(yV+kf7T&21;zs6atiyId*8v}3h~T1U+y7<{5-3b zth<(0oeTkto_%bl46=ZkR=0e%0R|4JRjr3y-iDi+%#H*HhXvHw)Fay4ylW3h|>R*;0vky21MI@EN$0JZHTQBDeLVdWaL zywP*Fp9otKIXq2#3`)=~Ec)hQ>=1LTQujr!I1v5o9U1Aq!G#BWt7VvcMh63_+HX{#%cUM4LCkVZ?*mztX~xKh3@ zu~+9eHfI5cEI)*SgggW8#Vo_<2Txr=Yt@-fAhG({3(p~%DQ<5(x zVly1QlVah1Wy3c1R*^;IGcJjjeC^`gvrvp*JFzroW|W zy)LO~nohmy@~P9x)QlI73hem6$KiC+yG?sE7HKBMg=U+T+Xie0Y*1czAVqUN*&^ZH z2TV0M{Q{av7b27Wa@Z?sY)G3+%{q#w^rq%1@B&I$7tKH4=A_F1X65{spBM}K3X2J4`YMVWnQlNkKv$Vd3x8e-jt%m~Bm5%J0xrPWgMqX(J9^~dqs6s-ZJ%qW6Hn%{MBJordu zGU^Vl(6oScK)wez7A;aWkQyCy>)FmHtPhum@{ z^`PFIS$Zvra|{o#-gUoObT|&qqGs8qrp5IPf_wn=Tg?>|rcy3{RUT)s)NAJsd{GPX z%}ab^9E89lDUb*!t@$<4^Ex-R>F2Hsih=XV=8CirzE-7erI7z8zTDx;*mUl$@yc=Axz~X6A?uD)Jzr zd}q=ItWOeBYQz}h-HNlF+e({VGEFQ3pO%{>oykeCP|~RevnO3*QWy1agLZMQV7x2R zBi(yn&HXJ#&Zbe4M8TvD7l{M3uTB3S#@;)usf61e9(5EQ1VmI+N<>t~Mr;UDl2O#4 zC{a*B5uzZXAci8Lq>ZA4B1F^y6(K4pAVTOxAfdM?h=6oLLJx$HkY0a>nfu=F-uuq? zyz>tjOn5lw?6db;Yp=aeMCmFBXKagDY-FRVf0y&8-Sx|pfZ^O%s=utpcLDmS+SHQ> zI76kZKEUL;sC<5rSdpMSzzhv-JXrgg1N!rye|{-ZDEBW~q}5kwN+r(@ex`>Y3zeZI zbfml^H&~|HC6{8Y6oqG86^}1dX)`h+(eGyxhN^mJJ4+3tm1tCnr)Jv^i|eb&(l+aG|-q5xIKXeZ#|#!{(2EC(BKAT%gmi@FWEWv zrajNIMvXY?+YFa#qL}C5DFJ61M2`SVe-r|7n44#A8fgOw&~`L!x}%0-rqQ+N!V$to z7)G9zEf#8{SqdtsBNq8O25A#~nn=c;&0i04sQ-;P^ik>Qt1oFP{l%+4jnY3utU?Lz zhuSregB$nf0CIQZ(9a~7^?%;y$XBZ1yB3@?2UU$`Uj&iG%kp0XGc0NGNjODDZv1}h zZ{?~k%h4CWw26Fw(`)2ogZe z|0=(}M=m=~utFCNyaev=`ykEU3WM@%HYY~5EjDo}ogahhg1Zj=IUICOG?3^P<>i=jH>6L|D{*SQsXsCUad;J9~Fw0pQ&uLVhtUEIA=>rM{?1ismY+ zyK#UYg7|tr>VUG5`&3e@0*p)E`nx-04hG&lGNWQG5M>vJ>K1*Fi(LWl&V`Uat%85- zn%h0~r|SnG6mi!~=ePJXty?6%91-$g@D`GHQk)X>byC)pkW`3LrdKtW%s_paI1XJ= zzfNC1h_6WAO7JaMB^4dOaYCm zbqnc@YwcNeX^8# z_wWbmbl%}&Ln~U>!uRg;k)f?0#^TZpf>$34u**OH>%tc|xwdVVcq$yz+8b;CvW!_e zd+b*y!YwNT!t=U4$VZjp(z~fp`UF<5mey~&3oL)*5Z^3f*L`YgI(gMG|5SrdpN%*% z4!+4XojHK=JWqtPp(^N&(H>Y^$ujjIhsg(6+f9tMsRv0WPb6 z9U(w#ro6$T72t8^GVsCc&;RsnbgXgs^sik2ax=E}5xg5_68r-_yu0A5l30bCX(Qpl zkPu~h8>b}Ngc5KnEbnc+b-)_Odv*=xD|Q|Z5{uWU>v^ViCRsjw4vTNrDg5vw)-y$% zz7i*OY;?fz5^EeYVPM!;-1V3og$Yq(JO*4MkY2*Deg!-lhCioxVYEG;=px*J--a^T zby$8}FJQ@Q-PYd|T>2-}jll^QwGt9tQ3*}d)7vX3SLOA`+aJ9vcY9 zn*e&JgoR)Kvj4XN4Q9@wF($Q*o?3C%#`!byBiRdnx%bj^J88CDDv)s&a&lAK>y3s7 z!+I=wciP}`jOn96lfMs(5Ho@tg_>FwJO50~1x&xQtliy71{kANvjj3xoL*AsB^q(c z^{dWh(x85Ms^VeX10#3Z+%&$SM^g{*gUPR|ifn|>SCCfRU)LghZ}*)2%ueteyR-5T zVr$m%8T%^;O&84-PV%U|lx1(THf*JY%k#E-&39QaopCLm#B09jY*2nf&jxh8@|_78 zG_4QG|2X1}o>v3uDSTBO(VYeMsV&*1MCr4&M2jEAvug`^^wAmEom4}Tg?LMsaeovN zA1?0*=NGEPx8RFN8^=O$Tad8`zJMD|IDGKw43%1Wv55+~w$@dfu;wS@fuY?_L-*jo{*B|K3j6!!?U5O;RtcAFl@V0J;+ zYjmKVvC)NLEN;dgm~f!z;$GQl!z@J){?m~f(%QfWXI*|1u`_QxBj1oMwZkr1b9z%v zB8EfoEAFIZ>6WBl%=5aY4TJJ1Hyj7tW{Rh|HQ6Zf?%vJnDHNvD4-l03sTO$=a7-o{ zJCz%)4}xO2XI^e8`uakcowdPFw+^L;uxiDsxH%7U6g|Wu4mAIhNxKu*&-k+s>~c*; z%zkG^Md-$gMw=XQQE|ya*}u;E*_Zgv7_>gn{|AWlqIjD(7k)Bmd8^b|$MYA^mp|MV zeeM6UjsO4=fH9UMxycKJGmmdCp8XWQq?1!-5IgHy6wM)N@f4hrNqWRcC#2_+qoM!V z=yD%b!$~8sD&4wR<$ic`a`=MSXLoLXTpH!2>Cf2pt=2eY-jLK;S)B7im|!_@0;51< zT1&L8ctP@5-_x@(Nd5gglT8}hOA>Z@^gOrrjO#)@vsBKTmk4@!QAgdAAq^|2I_ozF zfA`Sa_Vf2`?#Ff-|FN&-1adg(L0i&U43GIl8agw00lgz`8I?H-&?3T{jMM@E;*;x2 zk-ge#Ut;Jn>JYoE?4>&%ka~q@F#|a{f^^eu_0=SC{aUJ*uH}FWw`DZqPA7i0rZFTQ z?~&rG#l_ZVXx5M{9n+cFuHE?Ae8%NR$VI8jQh0}3aRbDmLm8|X+1!QWwBhTI6=lmn zpUb(#T&7+`kw-$Qs_P=gzX*Uo=W@e)5OQmkNRi?2w(Z4O!VwH#eA~AI@B#|A0J7=b zn#+LU1`yXG+MOg#8?qElEAmxiHAPpsS!riWVtLW4;w(sf68&d&t*lw2A*1kCF``0|l5L#(D3%I9=+%vBiIo~XJ zvG4G5Ve;M&07N{pArQ={_M+%-W7|ZC{8J$k#WVE#h1bu;*+1~2 z?sA3h&__j*C1tlU#idtB$D4N>Vp@ac0&yd6p_F}~q_WSHyVFUH0(qVV^H#Z{qRB+L z6Co!cbMmNNewu?#Nj>b_OesJdZo@4JNWiniJxcwBWEo%=eL|%T3X4zwV6WlBO24!_!>BI;5NJNE9#G^}U7JdITJYo%^TJ2a&?1vX z68@Jxh7PnKET8=8|D#&$q{!u@|B@|msMbZt!n_2!IN@nUhn_(%Lubrv+c`LoRX=uw z4vg_-U{r~Vt^An=g(7=KftyhUeVrd*GbrQHLhH^{sBgP7*cw0hUCneX-;+J^rNO;c zq7L2n>u%sBSsP@a1^79_+6r(g+j5-pBGTt7CNF0a+8RvqZCIWvexBa}C~snBoqE`8 zO{wBqsPY4jx?mzKb^}<8pFPbq&#va27G&I0R}VK^t&#Us^Hfa4lE5t|9-Q*+)BOMv z3JFQSPwnnw&9k|J95Lk!MAM7wXN7A#mq7}s&PZ7gN)hzN!mr3&CHo>R8f}SPq4nus z-j9k(Cv(`6Xd0L*_bVMj4cLYZ1@{~b84jBqFC7e|NoH~@=2+RepINLOli-Tk0$O{D zRY-85>zNlx?%}s@eV*vwjNn}?&3rAnuK~Fz-S{Kh#IM&LDyYwtjKDeRJlBOq1>}g+ zdy*~iUta-ReJ4@9@rma{%py0BU-kXSpH}POdTs~VXz?9Da>)ScJ_a?d{Bvc4zD|13 z;{FQaOw?!^!uFFh{1xyD4mI5fjo0QaW)_Pbc9VbdpdRfe7&X#`oXYp;#k*s;4V*(^ zAKrr@vf09RjBJ386Goe)h6))35Kees%`lXqlyRV{kqE8f!H?8$Ws)JGJXVOI*bHL* zC5=lDnjYxH+BxmzAj$^jmCJ12IUqcCPGwHwmP2{g9{z-5FN>H?2%7Y13^7ic=vLwe z4epOfs}c{Z&gF`r*iBH-=;nyBi{6)0#L{P}QN1HNOOS6Uvz8lgsk00GG*>tVueB?G zn&}RTUJgUB_*}1`mdJR^pItF)RxCk%n96g#`sMsB4{JyMdXkGEOWeD*$Au|kr_@cN z443HSYXIIl6!d#)$kl*`^>{@w8Ou&X;$;Kma@kx3qGv;S5V&%_wz}?tGpS_DNX7Hd z(N9ZEkZ=pbj! z*ilhkTmYW{F1w}&quXWeH0Ukb*+l^`m}24lS5gO(6fnXkcx*K>+$H#K_UAOWfqMLN z%adI%Cl@{p{r9Vg5} zbE-s*C=j=!alyNPVOnTCU^r)6W@6-JwCpunlLwh}Lkw;|J(F z(R(R^5vzUO37gXzizyd5(+e}Ml8pXss;p9qAg7%&>&zsNQ>0mu_B-9}VGu+n^p*5VBk{dH@rPJxHx z-k5MwR%LluoBmXVH`;M5MVBa^A`bU9vbn__Fti{&YUhiwDpkIwjc!CYwXs)=ZqZFY zd>MAyCLqfSmGID0?e6a$w$>?0nf)95zFkk->xHQN`SeyV#8nQ_kTK4LSM6`;fmPlt zz#Q#=H^a>_K1>b1Wqrp_Pdqj`Kl9VK)EC7zVqX&oupvc9h4A|f^2NIgQaE^(jC1Rm zLYR>n?h`uomasvWI949TM+6=ku=_`=#Za|BB|X1t?T%&_$I_ZzkyXKE6R&*5%d^yQ z0G3tMAaM)HB%j}?J*mXfCbTxk`qna$!7%ns#uuAt5qLQ1Nw~Ko_SmO#gqqflGusUG^0r@brBPNgw=$nKC1o^z6!-p4 z(6r*#7!#+!?hQ?MH4$!tQmt#+w8PPG36?Ekgj9|iAf;T8id$+U8GDvgOf9vxmQJND z(!IWczDeCSXS;`LV5cN3_jr5!8nBq;-zDXWC@8J8tr zkI&hZspd;{ccN8CSqh-!a4weN8FLTAAEMXthMUe!4r%NR=Un-9VZ_s|0cK)~V~(~* zT(hMxJ*^1zE_)2ut_C*0gyd3u7H}D0>viF-{FQzOsps^Yv|5g6?%6+^30}4J+o{#4 zMBkK$30wcb1W!df(Wch$>(|ql9Ji`BKCwrK(DdR%Zxr0Uk~OKGVVM6|BaC~hyLk54 zuA5(bfXRdXp~C|^c*Lqn8&24Q9$nlB8e=9vi~E(GJ#Q7K7ntoI-(&Usz>^-gkRfKN5$E$vE(6G25;;=w1E~n`U84ezsk#k0 z_%d~dvQDPMf!QU5w^;a`bY*cFj9h|6j0pU^O7*e=#8XDPU~Mc@4H1KviYrx1=)yEz z1fHe6@7sAm!CO#fcyLjzmiJ~vqRr-+eM}X0r~ddqITxKZKP5exY$t)le$CEQ zX?Gn+UIUT?@L}ShD#UjPTs%1}^jBkI<3!-I#br+1xk&VS*1Cl$?&Q%j=Pd5GO%YbF zCkG-l-sK3p(9X67aKUmNS3Yypc3?eg%{}buIsC+Yu_(U9YFmI^PF-Tb3n9qnn88+3 ze_X$@bmx@zBm8BT`B2QJ4^K^ZCayZi-mYc()dKg)@L@iet((7wHpV?_*FA8PyHk}ifTSwO^4WIftf-idseG*BZ~^?& zJZ}8uABBZeL-lwP0&*3v5X3^8q_27^C*C6@e;_0tGUT{;Z?g&jN@-h$$>)Sjt*Q`{ z!R{@IRrro}nk^@=ON6R7T0s;+_sR}nI05yYTCVpRx1Y#tBB%}RLJQWDD%k+11Ml>( z%7o>yx!F{4KlpV#Pi>@W`@Q)1zLq0b5i1WDovqD(|0P00uzK@D>j%T?P+tEl4|Bk1 z_YTou4msTaF6fObeKZZ`ePzJNA=|yN$k0IX<_x-Fn;HB}+0i^j{%&$5k18HfgN6<` z!EJ)ARFk8&S~kz26`$XjK>txNH2*|h6*iMoYHDgkt`hbmu~W97aB+h!LJoIzg#!1) zan_KgXm^xo&v2T*HxqlNxZ_ev$ll?67vk^>fpV1rJTAviP;9_-fyHE+XgYGJzv?{$ zP@@SYtdr$*FzwbFC^%&?{Z)in>myf*02%=^i(rQesAE zb*hwKArR@NCPYYsCVIvdr44V(>m;l@GXP6jmfn9Je-Rxn|8S*oEy9Yq7G$)Xq-OI# zf#;W$RsoJ~zAcnr0y7M|G15-POQO(eBcW`1?VVZ5m`CH4>7MlrVAK4w7te z5=S-TQT^J3*xb}cb*s5Ml`5|Cq2+8Dn5%s6r7Nn z*x>ZuXPfIV_$9q(5(AohHV)Fx33H>0+-tiICzQq)HNm`Hi@HJjEbJ9jpD>1;x(=bp z-@hW5>3oLYwDmA6v!?oO1SS2*(xQYl10VK=x1?1~6nAQ&S8S6ix5p3-(SV2%F#rDX zlb#ZfS7h8+Smq4iJGg8DIXn`?y&TXSiv(gq^AN8n`mn3aeLAiXrYDGVA)RnA@q z@@(NY5B5Upf0M^G0u(HuzUjyP-@$^$V;pkbyCxW*#;Mytin5wu8NJZ_Vlw-f_ooa_&*?O>IL5TX|F%r zhrOk&uhk+SxrO^Nh&1Tk#jfq_<;`{9z=VsPX(m6zhOf zz7=`ry{$5PQp5SoP89fTj`4dyncdOmJ3vAx2q1B_+Fd^&H7@c-WT>#uJK6G|1jNJp zg>}`Eg-HTX7R+pAP$QCRo&b1i+3k7CxF1p#*=8^W086byQAA6}xsY!`_y;KvR@s+P zWrGUZflmBzMSLw|Bj8FLo^c`M?7u^Ju^v$o-j^AFVYMUE2pD*QWB5Nr;>KF7{f0X& zJ-TG2m#i(d<-e|Z>}K`2O_yPBd?If&;kY8(;OE<&1!zp=s>I{0gc$f9!#j2c{)-bd z?aQ~_CL$}MCXrj8mfAGdCWZ6sw=Aa>1lS2~_dU9R!R7^Bb0oeo7HXAJqvh%xoT!2> z=Xb)j5GrX8;jmHGUwcXaQ=u67vhN#?;S(yzMtoH*JA#?@1j(3-RFFEbS=A@>zikoX zT>EHc$j-sH{@%3_@y}(t01^Nu*H2Vdbi{9DeG=V0nOweceW!JqbfY=~zeK|-|BjVl z>Xz{_cZ{P4(9}P+Ye&}MbZOCSZCh{s6gR)G{HMU@Oxp9GtxjCtTJ6mF=@`r%8vR}K z!Mr&xuDeUU3cSJNUJj@@OjI7|41(qp3BorWRq_zI^ zW%NxHe(@xsT}5rzK*&F;-dwK`6N)L)x$H<^1RiIh8gkZ{O)~`c=>cv+F3wI*p05q6+WJ8Rum8YSfi=kCyDUY*nm8@B4>w8U22JrEM-+SZ0|MkH*HHV*z}F{R(DRj6`RD@ zUw9B_8{@8rX_--j5OpJ@X5GB)*9JyC;a6F=tOWHnq;&=!)I8fe=mwZGw|M*ewi2gH zCXnEgmqK|hQ8`6aew%R@eJ;f=B-8Z`vHXq?mX(!~&%TjVzFUtL6t$pHSM0pf93;xp zb=Svn5}F8bd7n-l$y&m%?1(R>(@hQV%$!LAmA`C~Fq7*}rt&YsRl|e6q)p% zeSl{%_Ns^CQO5P_S#2(t_(tv)-lnVPV2P@Z&N@#LIy_Vg>`e+d1m5_c)e490%gl%F zb^1@H00Y00R%hiDKrs(d6=HX30n2}7dg2~@rqFe4g5Mk zR4S1=U!Lp6vuil3K@vp<0ndM#R<*5a9G0thH*7Mv?qVsCy7zPG`fU4l?2LrLfZH6g zmdoI|hfkmV&v736;{FVoiYo&|+DIg3R1YB+H$icT8J5~WogzA9o5JmE73uz_)azedP6EsTfkZ?V2Pp-#P*e*)MPgS^LzxrotyeMVwMWEZ| zNdS%0F&s1<46U~e08b9*L-!7Tfjc0 zdpP4gqeivBWxSEM0}?@kKfbmO z`p4Y$O-q^BeM&ML-=KlI^X2hyx>R0(6x?ZZ0Tu#T`Z`;_dhEQ`W&Z2b9 z#Kt{{%ZDf_qAE_K5L7T62579B?a=m0%NO&>M5u~2poNkAx-01kRV+ZV<>p3`uT6Lr zdC-4^*5oDYFOnnhGH!}$$2O`Yv_Vgw$WM!3y!FYJajXnJSE|>mG z7|%C4Br83|sVaPJq?N(Fbmn!kp@GLPh=A#YT)oii>&oruDX>V7!aZ-1ohx%lv%W&a_u#y-6du-U*+#S8*!EgB3WD*DNa%_`0yv4|ksJm(i$ zc93!4p_L9N;0h{Xa<1O;-th7;0D(VF+W9>Cts&^Rfg~KUjl%tP#@8LgXX*jUT+}$k zEHS(lG7Jqff248D#xcK{rh}5cfjx#MqU4>CY>U~guT!?3n0?}9^}$eYg=Rf^I#RP{ zg`1$`q@(ZU)rzPZ`=&-q+1zh$&j2##n}7~ILO8EWTfM^pbFcRzl((LAKGhZ{o$ahs%_j`WvpSuXUy}*R^njrQLem38jI@P;P}adv+Pn7uC#be% zH9%u>%a}2MQWm<5>M!UbD_LaTb|vBtF~sERgC~>m^;WtI!-Yj3A7z%Fu@OO~PQ=VY zipRA&V@TNS8bx#G27d3(UXQeM8Ct==Sk5KQt5pD~-77iAHiHxfm=<;lW3XFt#Aal+ zgJX36sXWuD{OxfL37l0KK|fBJ-gssLtQ9l7b1LD=4g`C~>rL>r`6&1vu++yOoSUT! zN{&I$JZ`~HqrZ824;1-+Jh5kX&HN`|g6=+iHA~y+o@&+`H{qS@tHb*k;r`p7@Jz+i zARFdZJ@Bu1mf;>6Aa1Ad1Ppt)!JO*7d=ZK%lkqbXjL+F21Amo$xKad*1mgrF_>v7J zxfIz)hM8*4uWr57-Nk~BP<)H1J1DX#tw?%m_a8zMNSO}%mn9)^lKDn+NDB_s=NSm-I)&tw-PJfUIV|>A^ABE8TPT@oZBj z&G`QLQ<)ozoz@zKt@+(!Ch<%og}5}(WxYCeWGpYs_EEXOe$p zi#vM4zsC^4fIlrxOCa5>XW%i=;%jS&N&gXXbW;Uj!lmhEr#=TBV`5FQUVUKniH|ck zpRttJpQwqDeowM1NuYI!v&7e&ue% zBmazJHV;U;!BfAYy}Jr%y;GH$bsv85N{xY)GrL|4PrD%RjGo)E;az-}j9l*06$?=I z{-;~JE+apJcOE-!@b2y&_DIJ4kTpJ=jul+!I{7SP*x}S#FVil$;QY+?$EZtCLF3G- z9L0f4>iMBd-1Rr>APnaXFlMG@{hMjwPTc(Qqdt0HfMKH&@jG2oS6RA;CqnQXitkl# z)~b@ABLRrneT?m{#0%$a#3IGV8JTEfV4$hd&!>OVNLq6C%c@;JH(q(`Vp=0xo*8(` z;GhM>6cDM3M6DEsaDoDbkEX!64V8G`s-Ey1noKZIccy@+P~zk*84gq#sZvt%iz*8` zpPvB_Uv+w}Qa&|+6Y|XvXtX*7!B>Ma?unY%pwm@BK@h2xq|o&x0#l zd;=#AtX{pWu6p0T|M@NFK;GUh*rmLrPoCxlu`)@%Z@&3k_CSUtBzcH9MzK{y_rSb4pUt3?jX%QPs+`(TGeElI1#Zx!ANHqZS505&e@Re zadOWABw`)q*>~eEYx0nBz4bd-Diq?lbtx`M?sKEGat1_v<&l1b1*e@Tu||ajzV-nx zSl+)#HROjGoMO#ZRV=h*K`WH^6f>QJ{&#R5jd)CjdNVStn+6Aq!{Wlasyv~?Ku-jY z5Q^|qB`n2zD36<=Ypt5RMG--;Qh`bUAO3+Mi$M@Be_>8p{*t4B+hD`_TFPF(ujVcP z_f!OVjRZj^gB%dzM+ot!`9+M%AB8GMn@IT37JK(V%xNB={##(#JvesZ#99CU?^^u# zm6>d49#QaeI5RE&-PTRR}PO_*eH_gnqG+A*WHbs0vuB z?+fp>S|L|zjbc;cXQlJr;Dy>t#&|_Vr+GNu!VFuKbGdb3ve}umochAb>Pv1zm(f@M z+!-w=Y&ZfX{pH7~42l%&cJW?vMBPqRee%Em{{ITF$%5Z2we1UmFS|$e{uOZl{U%qh zYp%aZe;xz7HQ|8c>kF}%31<|V?@GK&eWs~3ko*1>JLQUDZR;qRiY}&E_3UFuB!+!~ znasBhQ>FKUx-yhiMzaw0Pp<@L!9Cm+mI<)h+2D`ZM2XhwpL2$`XZpq@}s@pzLs)=c{I+Rh3dI5kM!Yt2YGd@ zQqd$wv;D&}$uB=%lr6VG)P$?2pKbl$VNck*Z0{BYQIF0`EPXvJ$PFmwgF_HKAW%sGx<_O!?|-z0w^e|JD{w9DE^crNyF zAy^sHA%u>X2DMU;=_-2JiM>8M=D&{bc20f?KkH3jUPI`UIeR}MN_mW1@4T@E#Oeu- zLLQinAEu{7nMmm+hi2IuK04S6HU{^}4H-)`tr7WN?t6N+p2f89CS1x!_$$XP)AiG{ z5kv*(;t}n=9arZ(G_w+2f^U`KvLqt?Di%VEGJHXW*?q6Ri#4CX>O6i|psHcxme1e? z>iC*zXNuUESQ{d3qK7qAIH-oSRJ4IzG6GfFkfEAS8VqtZOWi3!Do0J=_^G!c)=uIh z5-8UfBILhApfD>1M;OQz{5HI}e!5B7#a6_%CQqC9{?F_bc^_Z8N!$fjbalco^|05A zCBzL@Zx7VB&TMzV$Ic9Fe@2SCxK`JYOHxjgAc}b{)%-M?Dni3KShDJl&EF*}_QAiB z)xn;8*ZhpP?9;P^l@*G(lr!jL;lc6XB-@W(bVp56#Vh49&E%qlbJQqLsWyB`$NgM=n$6^o;A7C-Shtoyi<^{t9ySC#^b8Ctb}&Hj6J zhb<6?&-AV&Ahp$eckKWEZtuHSrLU&tfh?*{TV!z8Ly=Y{r6Fl1Dr*T^WT`Y-Zw_;W zQ-;9sPp=n5k}Ew@(R%XN{A0RTyFt1>+F@uq2ch0P3RTcq&UwlbxcEh9PbGgljBBMB zg)77Z4s^K=G|1J9$^ssL$+yA}wSRrUhhruy9O(QirP{huQ;_Tg*b+O46lc1E=l8rs zDq>Yqz7u_+&HLz?TmL5;iN773uLOGhV!bCEJXMu>@bAuNir2`UC6d1E&)8_yPu~mL zQXjH=+oO)Ky?||D4Kzep>{w{_*A6M+t}tqbldQ zVJN;_=EkH0X$cT(9EjGu=JQiG@s&&^8m?l~Al!SZg`%<`UaxEzFGUXXJu_e+G_xdz z!h1%-OVd;>Fp_&HCnbe51g})_5poa`su&@PRm)0EMYz_X47hR#e8dLG93qMtohav) zrlf|_oJt{sH#GmPYX0wJ^5?6h$M^k~NOH}j-Z`BQs_!-cx+ty0tv{{0Af(cg{SrkT zIuqQ>Yt5LUe(`11%mvriC6PD0mQhsSiFBi{w)<27sc2c{;0NKo4J{U; zv9yZqL%)|k$C$0+%J$6}CW6k8!UeaKiI~K@KC|^~vA^Q!_3<@_Z%3|7k8R0zx45E_ zEHegNAl>)``%JmFl^o8f|CqfY3m;ne0*N@y%Q9+O$`dQwT@^o%eGHJc zL&itp)HzSYmr74w3RDo^2}0B0!wKOkNfKp>pNwn3hNNFQp{!Lch^O(AA65&~wIr1* zRLbul1&#Y=e#BQu*?8Gd23{~ZjH~e4f&V}8_}{qYzsm@aF3K*fzN2o3sA1_mL7Bu4 zor*mma+^I{Kb4n=VLQjLE4D(+TvwPbc$lO)6nA;n6%2IFUqrstRn&c?w`FdgAJ^?c z_$~FmX(p_rJFF^k5hTtuf7NouLL_7QRO%`HOQs2U+Pe;RE9BFaIhieLU_`K|eVKJ0 z%ygl89u`RPAzUP1-MF+4e)mS*vwPH^L^fo^#1cvjfdP+|oZxQ|RkfA7SyxeEDdH>~ z^@at7wO&=>yCe()oo4UZ0#!T`rQlRoj#2oAbPKeMHwuRYOA$RhE~#=rg)GBL-jl*b z(^{CmSO*e+txEqc0>}4*qNV-Fu*qpqm81>xd7c7C*G%hTBrwvPvP{@qYCh_O#B!z) z%Dz&Pp=y#-UUlr5&Huz}e-n9s;+U%kR+KDHr@j@^$nkV#ql0%T+N~nfL%w&zK*PGx zQhY+4i9^@T9%Cx-1hqzo7|xYJh&KnJkkWu>FV>dC?z%KIyvYi-eb-}xN`!{VJ;$%No;*;;f1jyCWAlqp3~^Hl{N6s z1t>O`Asj`la0=Bk2LY0y>xX}ysA)yY-xeVE7Bgu+&ZPfll0 zWNjF;*%UnEg8sh)p#MQc{_BRu-Q5I0BFL#RohLG8$K3` z!AkFl@c7=f4X*O&zVWgd_L_|)7S|Vood?`Z8CssHH}8}P5&JOnlCED7ZjSg@U1W4H z3q%$z2_OmCT zg)ngCUmt)jm=D{KFxDpb=Ke3M_?sJ6<*@%R9OInp31b$87J>pyB;>)|YqL&Qw(w}# zkv3<7QC6U<<GBWB6@9924 zPpP}dLn3w;7=MoTQuOLf$s}{j2hWR4KlSyb-y}{8L8h7x9q+$VRoFG z)V|~1Sb1UhM{1~mrfVWgmKLQcC(;_S;hf^u@d59fqC^|SSMOGHU()ZD#)z8FEVn4? zD#>!yFf0|<4Wmv075DM{m%l3R3=%&%O;++N=6dNE%*0*it;!u^y4VSu46xWs^cpC= zh3%p_6QDL{tL9reMe+y}4)9L-wFOD?6OiDtD8-%sQRdJt+pdrs>IU>RrTnC zIS9HjU*~T?`2USTah~@goH;U6gW8JPc?0pGDr9Kys@Y3zqk-4hSEiWk$B8o+aQh)# z)Ja|!nF_%ix^IJUtd8k)kkG8tU+pt*)kS)*Ly^eRagMA|`aSR(T6F*%x|W{rv5oYa zN370~pPO~C`}y#pAuvN8V0b3H`j3G>2>G%{nbDZyCv4CI{n|+`-{Fk~0{4oXDoL7o zx1r)SvwK=25v#CW>6+TF@H`Zh5z>Wlw{H2v_M=JSg*5zC0Wvp_9+IJ4aU(875hLT+ zD83UbMf_M`qZ+?OR5`-W578UFC(X(jMoSY+=t0s9V$S>Fic||5X|E2tpYR1YZUR;D zH~DUo#K6Oq(@qeju>(lt!GG<5#5TzskdhXXjg2%7_{Df6j>V6FGD&R&_c_J$3b;u1 z4(%Yqd>_g{Lm0rPxXj&D9tqpjo|-C;4#x4bIz3ghEuA{ZFqSQJ@ZLYl1IoQO7Oz6N zZ$0Y7*%^n~)4lB2D=X#)I_9lTS%E@aWSe4_tG3%zSdN!W-i8)!QOi{Z7B+M_M<7hI zc2uMg-36r<->6mX2f#OTRjDS!R{X4tS9fZuRGEJ+sCyt^ie3hKOFIj?pR71vll*mn zt9?1g?oo6eW}gOl12-WFytb>C%MkZQU9anOP_5}jtC#}2g`Rd-yAYIxC7>r%AabxL z1s~ycmJfxvjYohjqYbpn69GM-laCdu+~s3c_Vj%6wTr$t{z=(bgf(~_0L3($II9o= z!7I?u5>f2LDeRJ!J|V~I^<}yhi72z720O7F<5NOzL4bpM*`f8Tpy$c%_ayA#nC$a8 zUhcDi&Prd94B)$=do*0D+&GHyZtClaW^mF_rGM$RUxsooc;fw+k!B*>@WaWZ!6+B3 z{zffWkyY}%NNektT+vlrNWqNU#}c={o2>g7qDb@kAxBp&uV{8QIfK0>TE@xUfuYXd zoWeFJg;#!~_%m)UiGG;yzX{v_->b5&#lvgrvBfO+t=L@g#|EF<=ye5jM(T7?-R*!? zNkz}JN41hcxw!H7b!C$SK;|-9*x@0czUfP@r>ACGUhiZ*LQI$~buxVH&Rw6UWXkR| zAg}BWttil1U$enWyIz=w+c{@*=I+Dezr)S?J!F*jlzqJ{@WLxE;5m%3qJ;CfU>3dV za@TWM{c9<`>W;<2cIFUct#UZ)gA4V|Zn|su`wdrv(P)M9)RY!S!HB8rp&H_SAxp|# zHf{PRr7QBjmimge4Ns_nHmwfnDX|7|1~G~_#j3qOQv8yRjd4T9q@SJ88?8Pu=Xrwz zb>GGxxdMrMoAVdbs9Y6A@5)?kc=rLMLWIj3>YI4(lv)9qI9CVMc=b+e)|y^cR87lz zxGo~s*g=QOGK_bXT>pJwz1ixuOIR0^NM(}?-y(G*vQARW%9q=S@ExT1$43ZP;&iMgL|gJ?mzOxQ&uGs_u#@H^s;>=+{Gf zsERAMHwJv4Jp^?#HE_ta6)NZUq5Y6X-McR-hw+?%?K3;@m-st6bMKp<(+c1u-MRc@ z!)5C`SKc=JCbI5jNSfn^{PKBS@i*)%rFC8AIVG1FtkN%akw(}1s@}e=~EK9XH)`RgoChJIAb`4oYRe{E%&1wCr~^|4l9Z+j5(fxHz0N!Uw!aBnm^1!iW|` zwYxPLJ^~I_vZg|Z^z%0M!~V170~ysNo{WK+sAuwVo>ytzPI!)VU||Y$@{@J3L5LD% z$;x{c81l)bjQ6V8aG$hPwN`gGxKb7;HLr6=I4EaXpT2#yZ@3Ft=wGb`JR89Fw}-Ja zJrNb6-z;J+wECl&oYB0!b03!wu7z#Gr_ZWa?~c;y>M3=)E9j29W;R1k)jwDxgnSN} zEua5-0UTVnkS{?&N!C}uh^EcZz!*TkLjS;Scw)ElA4akL*J|Oa<`6OgqqG#7ptjZH z>W6Y463x2Z5xq98s`5!j)sf9(P|gzvq1&fNOW!7f;C zsM&~MZ?1#c7_h~dK~Al(%)>-~9-5vPoF{?xhYU~KIDV2kSC-Bf9=&TMc=dec!AyqT z!`S@JKL0*iWoXfR1IJT8=hNDq6&~7ukRtzpP2J4i@c88_65<%G(I!blO>2^3&pC|7 zHqbnKp1I}BhQEZXlpS5!mW*4xo=Kf2&QUK&e|u&B?T7x7Mc7Hq=>d)zwL`eQ$R?)K zG}6!8adt4$c<+L=Ya6N8-CM-XcB3CUqmZ!R95Jg_XQ596*fM17&-!)>B|vF74Z6|@ z*B899?U^^|RJZ7>lFN7tM+JX9=dAKm@7WJ-YV=cc`5Gm3fx5j&-FZ#hv{OXh9L`8F z8gpo)qXV^Q1Nxq09PX(0WqdJfx#yB!P42P~e))lkVe+j*U+sF3FMGO1dI~MOhkR?g zK#A2av#lXVn0UVpPp1CqwbfEvC;Gyd zbLOTzoeSyN7hmtVS3cM0^SqAiZnZ7Ei5(*NV%HjAp7yGtAqtH%>tl6H%FJCVw!g~E zA6;0`=1TSBlNHzB4E$l(?awkh=c1J)l(}u`%3vys~noue&7N;<`9yp(hPz zl}eVbc8xG(+%!6FfvQ1-?5M*H4xVEe~as zC6&8j{I7par^+}?>RyINP43scTcUWbn7D=bosf1W&X)3dSzHcYg)rzxir)# zOi}w04EnLNL3|FXFfYx6{!-w-bU|IhVGi+R8x_8;YQeKN73K1+YLTy8BXUCUGt_=4j zKM|S%f7!s-%(ojDPR2W_==~C*`P@BpvJ~87#Fz^IhL1okNErH?ph^One?s>dv&tSdHhnL|l z7N1?HKOKqRn6l-Z)+>bj<`S2Kwc0jc)#!T!gy?%=-R=`+C0FzJF}eSbvUiVXy8r*j zug(WKrBKdPt}Z#{Y)qw6mryC>u!SOroNd@xl2b%-MLF#%l^ABpab__>!zyNmIUlz< z+r}8*SMSf~^Zng^zu)`&eY^g0vzgnTuh;AOc-$ZN`~C5Fn$L5XQ-XI@ITRuLEsx-> zxr#@1(9tuB+kS8}U;m;GB%VX-Qsl0-2j22o=PfTn3&|(jQgYdXwTZ;o z;GroOT6Sg@136i7EKVs7<3Z93As&L`u0SW7H3KNI_V!lsw}_6T2|-v) zs+D|Km0(o-T2p5%7U~cQD?YyF71Qvj<8htvm>yb;l$&OERLk2AzxVGQK`O^Hj-=b>5D_p$)`B{JmAC2JQXf}J#5;pz z9U9DY$y~+2x!Ud4s zN4pAIzPC!aBiNgN2Ps!0*5)n}y+aDFju*+y?Jri~{KaAm7~~nLMvI?Ia*b0f+zoXD zsxz6WwMIRxvLHfq_f&xnjMzQOuT~8RVp1mi13Q$l5VFbO&pPTy zm;hs2w+?;1=fpva|7K$T!;fK7^e?8mH-dtp;nchg#uH&D)cL&vE0UY8$)V^Q`B=}R zDhN3^LKX)*&kllTV;P6>wGk&4v=V#sR8qUK)p(cdg5h>^5a+s33J^cObeq*V7`a{L zkY^yo0D}@AWLKio1<|K}E$`FSRqh>aT2SxiI)pwYk&}k+%l~A5wuLx?(^@P*)G?ON zb&lpK%FgR1E?X1E5ux!fr=s$v>c^OG{K5ouM6q!Q`kgO#qISB4m+849@x?a7&uYNk z|B@)Bu%5N zynHIj`gmQ$W*MuCL!h3uI!MZ$mYCqyKz|aLR`RcZ*1Gt zN||ZTLNoP(u`iBEQf$8YT)m!FycMJXz+Fs~{x!V^%FqwJ`YF)k}860~RIcw^8 zuJ4%`=qfY3cu!2h<#L5+j9C`FqUs~1l(?}RK@QcHSkGv_3%^h#amV}kfXWg_3oiN& zM6UaicC21OM{OFF=_gB3^?dxi9^rZyX zOEr(SE6jc6G^v=iQcc09eW}D9YpGjpD#(AbRIs26ij!1^=hkza2B*~=P_xEd-6t@% zndI1$9f75!1%q8ywHR8Ecq!_^1{`aU!IoD>lxtWM{%4GPpI9FEg1Vi%SE!-i+zM(RavK zOI@P@oc!FNiRm3!Ysb3xcYD2yzuz#=`Pfjp1+j20KE`CYScmoU$#ekxmNzFJN3H1r z=d9It0d<&s_=;70aMZtjfd9>l0e6mtP3+Qy3Oz5d@!7F9$B7%NwkCrtFXE3PB>M82 zuCB798s{BTNL5qhLc2}w?b#x(aaq8-&2<+OlYYn*IccuE6D{eucOsd-%znZR9|o#T zp*B?mlm5ZNbuhWpsnQTH4{&so@1ubNZr3sKPokCm5zqRoK2*<3(A0_0peboxm5#t3$hQ|{6@ZFuF1;9RN|ESORRl%= zrC9(BOU^dKRdwAVS@a|4F|&>Diw9bv<<}4rmb&<37d)3Gj%yGJPsi%}=gMXyzU9w) zIf`j4x2i*OBiNC5Ni%!Q(}Q#H`DWK5y}*Kgg;+gcvPl(XJt4Lb6%i{EIHb*H-pZcT z=~7SHS*0fY!P*?BQliv+7+e57fsa=Tgl>dySaWM3&u_>Xu>;sqci5x8KXcZTgVy(O z^$H^-mRo0~(p==CDvz&4#DhRY=gNFk#Y7KwvqQ$?e2UR(?mV(128*Y_m9~bFd(`|c z|A)-;--PY(VI819hNb3^S!{C-T>lqw2i-5OzrNY8P>^VI>992J9*@-5^4Z`qE1~UZ zKF@f~mDy6o%e43=TtGAxL#->C_V2+ZsV`64%!l>{aIoBZCk)Z~aOEbF&x5Rgh`{*E zH)bwi%!fYdvel&=62(7WCap-Dri=xxT&R6z&O8Yz zNjT~+znUxc$|FX?3=6dibc=SdHXZ*Wu9vkO;4IjoW+wvIHw(mW!69oh&zBFh#=KtB z-i|VNXjf*|FMQ~KZnHL&ZOeAyjm=;!EH1xHuS~+#`Pl5X zM^%QcpMHf5(SxC#H(@3~snw!tC)X$PU|tig8xs~ezC6`c<=EULw<#j4aLvfIn;D6$ zI+MjHl`b=m^XlC@r4u0f$wWo|%cN9%@VHXy!!(-aSJR+RnXE7Kn{EgSAquTgY__o$ zR0hq%o-5fJRLizo&)LNzc>2fDhU)kRmVujLPLnfxSkqX^Hwd)>sEOor@+;zwntwt? z07j@F({Y1h_f+@Hd)S{Mt#eH{oj3h@KY;oby>qBD7QN8WPyRfuW`_ncQlZrnS!E+= zfLh?%CsatDEO2c;fW`~NoRNLKOUG~V`~$BMj}n6}k$@!M>T zpTAY*s1~BMv`Q_^JC0m>%JEy>UB4#CXF(vLz-vA5I&K4PsA_KcXz@Q>w6Ezn4eLIC zfqljC!ly(~AiQtvyS0#kc4(jdY&bdcM!bt(pY^FUsDC}79xn^Z4Vt+q$D16Ue@G3S zmz&{QFeuAK4WhejKm<4tv|qc=(@a7H6N4FSbB3>ysG{jxSLJ}MSY2I{AX3ptnz~>K zJw_@#{UJ^kX7rh)Dc?Z#&I=F?0Hz6vqPG64r8#Di;7O**!Q9(6^QzN{h z!rx{2nlhR{WrkbH!KD|uAofKRB98#)Oiy}aZ^;7*5)9LMzs9+hpM{*L@I0t+O0LJW z5YF?YB1X%1V)qJrOW!Pw^R;NF2eKme6ZeUyc8WOV?kbDARRCrr(QF~R8>@MV4MEu@ zv7>n^nXM(0BMxTm4#M>wll_QK7~8E$h7VJ8pY5zi#3>}f?i=piyR~ubo^jT^HXph3 zu=+N!R>13Hz2F^ds}U{!kOGEHk~!!UB4c9~IS|SGArfoVG)($HN&wA;gnzEPSlsLy z^@>TSm$?=(z|(aavWE&U3)a46TGV157W@U(c+(GU7AJ1Hb&xGq`@Cu}QauFvDxHH> zXy5npDf0U8?Q^U0?$dGJcXx$9h~exHT-!KtjTex13tT+Fv{!jS*0D^oz)-FMV*G!P9ea zT?Ju^{j;TJswOdtU&aF^A0NpKcU>;LG~O#U^CqPZxdL`Fnjn252dj3R&Rm#^(S#xyIAOHP?Pu?8!Vs~lgx}wP^roH@@ zwL_F)rGr4Aj8UJg=9RL&?MO0An@lxLRBuGBy#;E^VLIYT!2!14at(-&Y5^>s2rFYi zvF+V1zX)*0YBc*YFk#dGUw&ZA9vmDefwNWejUVz-0w55<7X4&A-Tv7eSO200zK=TA zl`jx6yA}nH|1109{5ztHbp@&MR+Y4K1*=Pb|EcH^tR24&BGeAEUq^Nf`A&S`e6v%~ z81XMfQajrunFOV)d|!8A+F(rC!$wc*tcM-;dqto*42+=!zI)x??3Njx8dA@{Jl z0C=Gg*;SkJZ=mJ>%m4g896&($F+)IU&~(wndE)E?d!G%SLkec+#H=9Td~R}#3WtJfUXRXAML6L9j!gT*E^l-8X*+{GTespW zpq4a=169lU2>!IM(UoKxS(jnJU!2rUGsJw5JMC8JAp^xdgyt(-p)_hGHc zRpmamMFA|UAd@EtQGd5cLt)X_2qD<;xV_L<7sdj)ZkjazaYV{?D?&fhd66K0M%GmV zF1U;Nfz+}NULY;twi@{|&v^-*Lyw$&x4ZuL9>c2#dpHf4c!dZOqQ^XH*_f-8a_N|B zI)lcjk2Pbw?Z|81{HjEqmbdoZI+tTuED=`%slN{ySWDQ{n&@RM7~!A9$0$WqS{7Lo z`b6Kma%R|J^`j$6*ze8l?2Vw_1-kACs`KX0@{?@oN(*n_2RBX3p!zN%jPGl%{wGYY ziR!08)tlDuKaV=#{fX4tKNUbT+c+!g>j=^J4XYjWeS4Ys88~g$IvioG(>S-tETD#r zs`(P0MzVgbR!v{%pU_)hcD?}mT#0ju@A(Jq)+IpcFk3G$J`<+@8E>21X=hO^XA8KC zwMHeMYq`3@5H6zZnz+I|^rT|aj&0pU%7o*4u)ob{hhi9DDicdc>m;~2|s_I{D7 zhg4VY!+o|Q>e$@WSDPENvCJA8gH=YNK}|!OpK30sdJ<7*po|$MX+t~!(L^<4y0(!?b?Vr;$gh$3RL~Vt^KV58spG&@XLkLSN^C&SZ#TEPjX2l0^yXB~F;74*_WR_U-m)J5p7ysRLM zQy$2qMC6)wUv8P})A-Ysv{n%z^IG!kw3kh{a}ZEj?*QfunhtUg#?%_5XnE1i|EKDXW=6k7MX^McrxG&YVhI<# z=B2kvJ#CXBJ%S;+SiuCm<5Vx+E?Wx!3~fXLvvtTkNpM*Who9e(Z9Z zp3uxhp`Fa6!#RVVQ>r1sUoh#AN%5G#EE@u#7uLN2hFBzq(z30_8%c{bU3|W=UE~?v z30*R<)3K-qFM)QCg?waJQ0hNOY+=LEnQ}5OeuX!8)=_AEN^XK&BH?PEM)S@TY`Nxm z#`*&J;hW#>A$qH`u1IxnM4|VWiZ8d!h!H6!;G3vWOz`f~uft0iH9$$r7cH^Yi$I$+ z0;5`28C9hgF47m`X+%DAM)TAVq-ZT8Ts+1ngMl?G+y%w5o2U-+l`#~co?bLY~*W6QzY^E_x6>}uH=WaP8(-c_=#m`Cd6YST$r_+SnJS&0*i44tgMf9|Ac8q3~j9Zt5ofR=jm@ zZp25-sjJH`DR93eRelv}%+|m)liYGDB(eiCG}?R@n@(s5ZI}?VR}4}c{GP?$rF(Dj zXuZbZxwwa{gBINuzX{vVMrm&#)%h9WX|^S!AZn&K1GL^iVN)_G6qg*pRohx+1kTdFPylf!sQ`)&3 zu+*!7p2rYBNgGicBE)MfClnq?J)#UzXi92RrDCES4}Ep9HZ3Ad*`pd#Hg(Y^KhFlD zgtBh|8-XZLTm$Vx_(jzZezmhKj`BXi_74ZhCMN*X0znM0BGo0!@7-1)u>AIg zd$ic5SQSX}8NslVP4aD`&Ms&;%xHrEAyIJ4bUju zgz=LhYYR=~&MMmIRB#g}6H=N)=KuqWlik69K6C>NY=SxU07TTL$2GFbTo6+fWqxCY z{w`Xk$7NCeMxC+VoJh;m+{Lf;51i&yF7wJl>gC^FZeoj$t8~zlk?fRBZ>K{U#CE_I z@e7BB0`Fo*(;1-d>jr;O9%^YBj`u?HRFB}0bG%z!<8@TBZJq^e%!QaTFco7N>lYe-u0QT}LG$Bnx3Zzj zR4m>iMDlskv+Z)L-G^j>X9lvcVD2AAxe0}Fw7Dkl?jOsh{_h#hU24@ISMk3M2zI%gQGsD>_{6FvTB0i0Ln}TDZyvdIRpzQDb8R-1v zA47g^jZ~*^wlTMCldJ8aU}EjWQq9oyKcYy(x2JTDwu^r4X;n(IT%K{?e_Ya4o<1C@ ztkr(drTcMwj6a0ujnTB5zc0^=s3!ZQL{=sgnI%U}g&CSQUExJM6%S9rAETa}_|g0z zw0&$Id`io@e8oDflE2iwsl)O=Hwcf2h};hNz+ibnZT*erTvrdA@zOWtD9(m8F5D-P8lHOu#}_Iv z#Jh;K-d}!tVB|Y!8h^}Xu);)zH8bO=yE+L~I2NHj-`@xiWgow>K!3OI_X|Hag!{Fc zF?YuHno@A*`W3F5hW1{WY4E<^MZMW??kcfZw$uo;0CEw#=W0eb5~bge)ooJCLIhsg zH&gINXXLzAO*1=0p{2&4%gM;)U$t#s-k$NJ`jb=tQ@#D$lJ0-M=lDK0=%|Tsp zHdz)g(GpbhUZ#Ju$)$KgT0Q=Y7;m(UQSMdYI9T!EO#KBZ)A2sWt<+N+Fwor6e&}I{ zhFLoVy0zf?FF$XeYZvvi`D3MyE9sNLSh(W=TZ?)#`wLrdwWy)qdM8w>SN3RcML@?A zURC%(S%4c|UPPs;h5L8Vz|~ZY4ZNav1Y=b-a7c}&grIn5y+`VM<;_vwVoutj>Nofp z)lPeB7|wgn)KQ}`0Zp4O?Lq%yFt8#34f&5Ad7)O$V*oOtotb2s*U07mY_`xP{E>Cp zco*N-Qb|oqv$uP-%HEk|Es(w(=BD8Cz0TK6-9t}hWu}&mWZg)OOqoM+u)H9-8g(hs z2l5X~1?8&E0QO*2dlCr0!5H*emYB!J%TC29uhHLC@7xC@6mNy6N(sLTrRXt!Jl;BSx&K~EH!1n z?|n9TRL7B?czN_>iE0rFP*Hb^Txx6`=oHL?Cd7S%w#`~ z>Np~#QPd^lnq}{cRZqQDoPF zb5@iWf2y9IXckBE{EY$Ms_e3XqSS%y5_N^Y9B=?t_mcIwwZFn8Dc%2di?Rkf_s{j; zwGCUM?$Z{UqCUvofY(MW^=bY<$mcMg)ozT=BFDvXTq`ed_(e!OmakhEu|Rd1RB~Ie zo)^}v+H_m%LL#<8P2X)c!!`z?&g{6GOTsbsxpDmpePu{tG~@cs@)5eY#^tA;GKVWi zSTlJgm(e1{o@8TQq`p2HS?TN$c~vmu+ne!9>mA>9fCrvS+}M3t1U(ixv1G3@5F}Tf zkuv8NG{PGC`BO0R%W`uMSouHUt6pO75`2IgPP+pjoOc3|H*h@RD*D{#c%0N*(40Dd z7^5_3dJQkDZ3xODh&T)A7lj2AOQGYjg&7fSw+_)3BJEKj(U2W3kM42{dM&jxyBmc< zzv6dT;?t3cx;t3K(v7;bd1Z}N-WIS0f)tYg7_M=}U;*wXB${I|m?-?@K084M;ZC04v* zTZ3l3hp%!P7ZVpj3$9&&ygMOgh~t8%;IH`oQi=2B(>K)hn6_JGGka>nENa}Sl5l@{ zc*T`^@8#yJfdaU~mY(uz!|o5Z}i)B~AT23k&#B=g=Yk4OA1SsFcKm~8YUOT=Q_ z@E*lgVwF!)s)Zgl%RV(q9b(Nz8R})}WZiY|9>JjR6b%$Jm>z-)qBEVSl_RjySQRE{ktB zMFDi)`g1P)1|25Gz^taxq^u%82_m=Uqi z@k9gi*;GU@*RqsoY@K8g_VZI2xZ^sYjYlDD!sj?xQH8oq>Rbmo^oK$oo80OBy=CZ8 zosa3vzF!W}x7&4yIz#pXzV-Vp3xFzTb7oA9hKsq%c0x94x5bI)=Q8}!ZVD5h%cCE{ z_fRy@r`Be;dcL8xc|jZc8h~lmKN| z!xt|WM*(Ca;L}0#;!RHk@MLE8#*`FBD;p9ABE?8g+or1SvZ6QG@|EplgS(m%OcW@Q_{z7`Me2@ zkXq7H%q1G?b-cPCN@Xsg3(0x2b|9Bnha82SBamEdZl(Y=Na8%9s9ANgHB?HieoCDe zErCHf7``Z#8uG(KRSueDvqf*1AoUsFnbj8W26Dx;3u3dNcawB$tL2vlc$d%!QOKk# zfZF%o6o$9Blo0B(nA4OvuMf<%32|ujx1N}H6SVTpjt_CY5FJEKYF63i4$e``DDon~ z5ZUmFqe+C2Lx<}F)fMN1!^eLZ+}LI=*E$4vxqwa-tc$1@?H<-`UsuZeOR~U8I&XMq z`oXaZmBID+sj$JHEMdyU7gz>3hcASxVSD1*T5{eoB}j|M8?7_&E5C zNik{O`pi~qxLkb@^FBpF1F94I(jLvd&>^P31&%l2O&(CA-RQDTC|lbv`@^i?6j>9p z$h|fK9; z7anN$a<68jb9L5+CG_iDtn{eA!(Yd{DD*{L&iS&`=D#;|iB#Lq`tlO+HHl+ALhtq; zz)|~smMT<7GpEE%8|~rPJrWth3TA5)%W2*}E_M*ipxRu$n+-lW{qHRT8jPP7WQLD; zrn`aih>ja47`u|B$f!ryQC`a>B$*I^$PLE#MI?!bb_a-22Yl-%i$zhP%}be8w6-`b zGz@OUT-*2E>~YzoxAtorjlv#tZ1_Sb52FQ?E3vQEjJD~F$^0*I-Q<_J&X54eNrLsd z;`(11NV?m-mV_FobCvissf>>KJfQ7A>B{=)O_(9m=w51}IXBGEvCidr-IJku3sJ+! z{q0~WyhAl}VIH>Vl2ip{<}NWsf$q3TIVV)L)>P$s=qFW(lyi!ypID6kb==+{DNu_# zE%x&{){mX)T}2Yr#+(CWN+zlWN5xfRAV3YAf&A=H{*G5WkuXbWT;f<_Q1bya6we+T z`_`dCT|UV^6ZZ5r;4J}WdeDaQsmPr{xNVo=S<$l+&r`ASCe?>`5u6p34UWIH9);BaQ9W9t5kUPBFlB{EwwQZ$9PuD#@nqV#JXcog z>Y6JHst!Lv8c$kv>#!s2AxwLvcs!XG>3We$?Ay2~Qv3>gj!NYF3SIu`>qZ?D#q-AC z@haZan3fb#a|r>_6@Vm>pFDSj2b}!}Z2TET+ThrTfjqQ<-v^vPx%j|hbkMKG?`vQc zGCxr+4gV^~B}u%`D3#vv`O1;5RMDQz%gG-x3Wvn~OTCwAP~kuvGKgH55t$|*kw_xn zpD!;w{|%dAVl+37oVtYy&n5J1_KbGiJX8;ka8^B92drM{*w^PrHRDrDY8(z%B94pH zM~FY@UG8&TO=_Upnlw_6s!Y_(3!1Vd;vW8(l6oLw3PbWdBrqQw^q7{*v*8S{_yqfw zoj+t84KV4zD)F@?QY)+j=niGRS4C9&B4@e0*l=srE`3g8iut1@U z$~KY8ljCEW=#srI$k*{Jk~O0oO65D>N+kc6Kcc7Lmt}zeAyjUg9cr$_OJ@TBHkKGk zXv%AbGIplTN8>S!>M$`qy=6#N40q2DT2c^5wR4QcL{}Sq(Oz#{5RPWFmQbWM=PM z;k#m+*6{4kZt*3{jm1B^otIEA_;08J{wwez$fkM-2`VCNLc`z(Wtu9 zR6ZLp{=)my+6tWMKVPnSlg4qI{Yud*|3ZUyJqjp*rwUowfdK@q}&?$*G z*|c7s&hHd{|JdM=hG(;`>%7(R5FUnPvnqV~5DAQ}q8&9j1C7iGALq0(zkCwU_XzEk z$5;zym~FvD0ME0*Up|W6JCsM$wAo@u%mvRbQ$abPKpNIDqINm6OBR$OSoozrhcy6I zP4n07XZaNDT^EJAh}Aa+b)Kf<6|CO)-sK$4gKO%P2ZvKCfte$p)t46*(_wcQypytc zhE?Ed#zST$xvk1M{&VV!eYU7|dEAEgb6sbIige|MoWkW4Ll@beLR78e$Qn?O#$zuF zmdW(s=C(QfXbs=?jp!-R2iGI|x~B(Y);`UcwkVn&)+oHplb6)q(4sCS4WYd73K`w; zz+cs@UXj*^l8KWOWKG(qGUy-KM@0K&U@mjdv^vgVu9CXsf~hUOz%GWuw|q(1xJ6P6 z2j}WLb=@WmgNjsWn)22uo4ez_2Mu4TAxPA3x-p+KiFfHB8-!f-pt?;;1jl)@S#Hh- z5TQ-~X;00%%yY@-&`6H@Y!2Ym-_Mw}dC&rB$*qjJ+BDElUcL36a7b3XD(Px@|N37n z5gQQ9fjMJAGD5h7vR^P63^o_&7J-k`s%kfusHZhP5T!wfoI^9i6HFGZYi7$j$Lv3W zuUFL#x`OpaQy!Me99-C!E-wp+?_So^djsOtv3SG8;$>%^e1~5^Eg!Jhe8)d2Cq94Ygm&!P&eDC!jAxrjE&lYp2E;1rMXHaD4Gzm6CEu&=TgqnYd+xP~Ayla{4oVkpFRp&+V%ipS%J8d=bXQExR+f&th4 z*9at1#r_TpRzL0QQ*zAhb(w$hIN%bqul&}0e@B|n1aOXvab&keWcy4w1u-}S%octq zbn4+Yu|F_40`y-A!Rh%gX@1P75qqa4ujv!{1*tTl(!Wi$lXjs!cLC>g@teB;>-Zs{ zcl*cOd$3k#{cyVFUEpXGM&jmdfJh7fMhDlFITwb{n@qQTHhC*m7jIz1Y-l{moP+BZ zJBL+9P~UQ}Q)g4@FW_0g$=nYQVBdrWp>KgbrXzim|yC z40t)%2EBL;jTj)Z@bxn*5@u`pQaJ5xNxQ%vT)nOna7NL-3j=^kPzJp-uCfKU&s(bd za59W--Kf6YOYZHsMfzl;F+v&CL!=h^n3*qkC4$n*#|Ao-2d{C@@l_|D&WCMUYYSYj z)bg8|C+8L<49hD}LaLXG%q0RZ*yH8wqH3krjSG82qcI|Zdz4Eo^gd6n|0aCL`SoZB zC!!i!{e~Pv&rFyb<@2hw$e{_2X?7ZfqyfGsPs2fw=qULp#Bec6+gq%Du-8OOT@iEa zvihjT<<)N^sk;Q!BUAlT4m6Ve7O=yx&~x?UCxK}$>!|syu!zm&m$i2Fv;A95GxNwH zxI!mX&`g|NxddHRP~g(G7R`|SDgUT($Ay7yUoEk-WdP|6-a!Z40DrNq*mmqd*+z6i zTD?3~s_VC^|Ct3)zenV&#$^+WbNKLrtGvn4bbFVY2%|EtX@_hI(V(GC zX*2~CYndbbzPMVm>S{1!a)yLAC$Hgk@ z7b||zkN<5o5Uf7cLE=t~MH8_5)-NUHs2J&Cu;BhIh5`_NZ^ zW^Oi)&70S5y)oNB=jBB(O)ZfB=vw|iUIl6Qsfd8@ZvMFmH+GfDC&Bp0E zSCmSSX9w`NW@tzb3-b53`bQhzu&acYA-MBm7i!A_MVWyTmuK6%umU}3IR7za>jh~L zh2-%zYPz6nb7oceuiNytxDK0lepx(Pj9~$t7!9hDP<)D9Qm(KU{4al~{$x1|fXG+dbWIW&W2pRv_b}FcESB+FUw$zXzgVzK+ zI|_q0h~N+b2Inj#8@s+m2Z@H6k(cI%l254a*m*#QEqvhYt+0EBX8P zYW~|EM;~fY_l*Zb_1_M@rPdbR#3+lzInuu!w7fT;tF=5hG&R0XiQJq*St}lRR!GDE zC*jc|XV>8u*4J{N=&6SIfDaHKxX8nteFt|WNgNmc<6|x|M5E!tZ!MNwfOY;&C+?VH zS3CSvyuNi~iXpPMKZ-eCWz?IC<%o|Frc)g<4VRKztWiwGoZQ#ta%rS zI^<5!yj_nIoD?*bTa{5xS@SaD)#=psZtUNAUUC2KXhpHzkI#wypMLqWbn)+bndkec zcZP2{1n4ZNzDVgEzSDcO%{1)yHKnEG+x|XnO0MY(~(Y7VOE(<+J>v%~+l<^Jyr zaa1IFQs#NxW6s~T!^tORyHEZ&v9VI+={Dk?JW;HGuSj-{k4dZZNxbYP?rub4T+fyT ztTwY{5=ozHrkhk&jmq&0clz&O3O&uM^aY9U(MGGonZ4rfz2c+O4RpXOq5C!i*PH0& zbGLji|99=Mzw)&m{$>RBUjunIlYak)H_H_o>2Pd>=gK;}cLhm;*?xN_9Y3{|9SM zc~opm^FId^A@tA&sRm4|`uTRH-r<|QR3+h~W8>Ln`R=NsKc-UTV7%J)K@rjc=x}CBD%RLK6}KON(HkeX`8F z>(B<{i+}FFqWJVbJ?g*iz1rEG9cm6!R0Ny2pb=oOaAtqRddOR>3w0mGEm_}CDyVny zn2Kx5YyKHGlk(uN)_L{%lv=*GgOu8jmSYN@;lDGLyI%@@GSgnol^}YCE*D`et}yeZ zYMTC5SvBlekhvfW4xVjvhNS+e!@`-~5yxb#x4lhD!Yb@e0b^06?|WgYoQ$AQHS>uL2n2(@pKVF* z@hlMGd>kPZ^(C6t*~_GA6kOC~eGYye-z&=4oPBzxWEVQ-ZyZ1!{V z@Yo@CLbP9h%FY+ErN-L#&|PlNhQN@I+h0emDBCq$PJU|>P*x@AD-U++ zl7)MlA5reEkgBbjet6AENP!G8R9)-|QUyA_ZqHtPL5(_`$yG{t1?+vkaO)pRiszNK z6Yz>#_v_l6TRPaYi}~2#!f;NvlAL(>?^iE%254!F{-B>c_-rIu+9$GFdelgTU$U#f zT_Z5(St#~{b?fhU*oFS$dib>_k#qlPl^DFI(S6?|9QC)(4Wt$2!zVfrSno&ydB zj$A!jtX6XCKr1=n*>-OH`Ma@~{#H^9-x)-#9shgS;X8fA_PeS1{>C?9rQW=ICju9A z#4<`0Ko?BhAU;*1AWX-UZ%W__P9E3ZbPU{5pqqGU+C2HEzdxnv(9@G&4cE&g$Zz*~ z8lLhoi8fFjWEmq-j(ki#g-mhJ44ExC^Jh_ z?aSnYQG~BDtQRKt;)NcoM5hPdt{8JL95ayrDGZ5qxuI%Tnjjm}bbRHDU%ltL#C(yr zYR+Q6lw4`N&e}tDzT)`DDxPu=63!H}aV9=c$+!d#otdX+HQltpnMJX=cMXPeWf5-?ggEEK9MZ(6^BxsT8Lqu^-`IPCmgZm{FEM&3wK3&$ld`9qb5mitgpg-Ggjy=% zEDR2p1I|LQr$W?2VH-_pBx}m%ZL3_ggHgVIYJI1N`bIBdm$9i~e?d{M6?(BZ(Wlv% z>p%5yx#ZbU#CT<`_CrBlO0bFc>+@pAPeW45rT)h0$vrLqO+4wY`&!aP_=6?IW8%zD z(>8~|u-$mUXNh>>hMvh|Nus&bP36Q2bd$SY=udEHLW6t{T(Yy|nTcEf9YYC{h{npO zb<@p#(P0H2F*W>;8~2nyTWI{e75AkScpY zJpi=dGY4W9()Y5)mQajeaG6j^UcD zAToKMe(cJliu6H|#~XC!tK}APcbjoIW6y`XtRIdZ zp*$1;yXBDRio16lRai{WDeo5|nzp_XakCn2rwvXz2q^^SEZQa^7Iu$|_571eAiSdu z7ywP%qp(wz^jI|-{ldRtFY58L*fJj-DMWS*p``ha#+94tvP^fl!9E4!@Rdf&g%4>Bl|U0WVld20FdxQgCl*O01QZedofiPrg3)RW+x ze#mr-{m!7XDM^~I$&%Z|14-u;c7)$0>^C{!EL`_gR?JukvR6SnNLMT~;CFt9s+5f9 z#^Gl{H&?0s5xu}pJt0{S9HeoA+fe%*SDx-;x=xb$fp+Ax$4q;VdXhXu!nqBaQ@jnN|-O)#nN5?&?BSP+N)sEj7j#BIx{?qwI zLf*v7giEUOX$C)s(4MlP388J4H+G=~Mk){GJ(q@K+dVB>V_7&egxV|}?+{Zbxoacm z4)9h`f~RVV95B$x1QyxZOy3+=d??Eidzcqr(qSWH@Ikytu|~!wc<&|ICvw`7ME#{Q z6-eK4=RbcwylxV8{>|Qsk4n+@)WJj3y^A1)MXo_rmN8C4AkLTRAHvLDl{FeHEXsXu ziQ4Fle+KTsc++ASh;oT|u_^DVax;DA^2+!D&Vkm%dy_|tkNz*p-ZQMJwd)$)A_{K0 zYyqW<%2p9JA~lepD5xk=kzNHcDosj44+zL-S7T>a^)gFR_-u~nAMge2+ zh?H_#Ys!ihZKFB~jDXLSc$73q4?;^qc&~cf@g5uQs%`evLBF=@69yMv_+`a^dWPA! zvzh)v1j`(EXb54Cl*Z#P6pkvIXJKAYa>P^Ps&)47(06*kcYlu~A1e7K@lVdY^Fyeci@EiP zC8eCv<1$6=zHSvQLTJpG3~hw{i8-1o!`3ec8Bx+-w8A1`rJvQ)fvHsu_K5_`;z@*M z>U~G8^|KGhoR`0xyVtL6SkdOX(ViPP^L$H56n^c&RsqSl+$gs9M?tR~zUMomX@T${-o(AQVHqm2ld4h_M|#Ik2{(#CnO>|OnR-AKK;u3#c$IAe|i1RmFpSd>7D;z7IyMsio1yMiS%H% zjD0hGqiYhrm@f#}j=l;VhZ4U6rnL~Jo5*^WV+k@#4Ex)R!f83O?U-F*9?+#fM-(L} zY6A8=nTIzsoq@e#g+*H`&<4-_qc-?^qOqB=_2evBA7fK-!SH*!aar@5tv`+#jK7GH zL*fN>`r7JdqhXrqT3|2oS4>H?hV3Tzi45ZyzyU zWjOS=1&vCqjwV4n#~h8Wd+j>fXGrzNhRWR(Q@p6i&1fN#s|wA8fj5N>`~FOPICp+@ zA{1{Lxze)2p_YAN37WwXVK;p(0F8^dCFM|wvE)B}0fuZU)C+el4_wZ9Y*?sX`-h%{ zp8Q3B5m_*;?OT=c!S8*pDwDQ-Lxb^k2Okhrq~(>{4XFfA8cum@DoLRvL7%u4N{x{T zk23(dDRMScT{H=G_8>pj2kgf))jE?hu&P*)_E1KvK02VS>}!3sPr;AivkOt8r(d=y zd7E%YhzXBOH>$K`wjWPF?P-37*Kqk+`o&4ZxGh=mHxM2F!9r~tAC2ifpDui^J)`5i z?>hRW`x%ZPSn7LHHt*F7A{7draoQM2%|bEg>-=}Q`|kpeAPN9P=5qx1fASUpG=Mr^ zM7gU`;Us^~KIf_%e@7-w0f8Wybb({RHRh%>@nd};!Iekqb%EHj?%+l4fZoXXB zG3y)w2;$xcNPX39bb7KPJ}#IMUxl!0up2486tOQ;zo&p#;;J(w7WFoZn{exqsJEwo0fBtRCZ9^9;OR*j`z{MIAO*H)t>#={=<9zfUf= z9&7w?V;C)pS|AwfHhpnY;L-yk5f3HWM;&355{nY_2>oTk`>MhxB9$-gN>&?Hsi2+y zynV__r_a6od%EvmO~Cb%nd@AScm3%>AOx(us~L{Is4OQ0L)0D&to`GnJbquMkRtt& z#qVV03nFkgTQaI!wbRPVQWbBa7>+x-v<4zSY==4di^G%&p=}M8(c9z2MEX_y04uKy zD1~um)J{xctnJ>(PToj78Umt|?*#o2$Ocd5e^Gh*n2vKhciuNs@4jb&6fgiwOJwmv zy`9_+OJ$;qi9_^PgUZhg77qH;9NTVh#@Q}abzJH%UAFMXX`%2q3q?c#&DRhye^eUM zfb_S!++dkLqB9A`_hcA&_oXfYpx}ox>2XQNuMt2-@`;sA_KnZiGH$Ij?UZS{&-_mu z=znxZHDCUEn+k$JxdqS`R{s1j?QuQ%`P8NUX$x{8yU$zL00opH1Ybt1jJuppc-FK#_0wcqjXv##c4=|9 z#Wh(odE7Sr_-X|zI_Wuu!mf!s2U z>r{CWA)xWJPTn?3IJ0-3fZ|@a*wMCY?MkG4q`jF7T(cu@iwm!VUPmYN%e%%5=+hqLJ`Qz#~-f#Ym5Yo@+WVaQ;9_FvVkslVQCAWjp>JqWp zod&-_|48$EQ#26UHBr;2G3*pF@85c+cQ;6-Vmoc@br5zn-`$yEv}*XiC$l{$T`{+j z)hDVJM&mNn7kN9YXI2fUkK1irPkyK=46^qm8c^^cpEEX2`avg89oPO_C=1!o|IXL= zg7FG=4exKUcHHnl=V3;)yhUqOs5YEWF*-SWTwp0G{YmW13o-R)h8KCyCZ1;N@dHvT z@_WhX2KvB^xf)VGg+Xo&Rob6w;jLmj*qojW!9thcT8l+6JRyS>I zR9U)xyq*MTNq=^OxmTokqn`4!6Kw|KAtMq9fvIaHAvtuF$NerXRq3B|>cQ(6J+wIc zMin~$H2wloHi2}w_me7G9FCY%eirNrO4g3E1Rz74r;QQoArlZ5$?)p|OvTQIWhlir)Qh2GtmLVaA#p z^A=sepL&RJ)4GLW-Pe)3=>cidcNcfe9{+ZCA}pD+^;XwthPHD?Vo%++ltX%r9AmPQ zeZ;a`tZA3V$o7p0=~3t=(&uWL8Vt9K`qbugBCNNEBYA_B>baqR3#B<4Cht|0PKVtB z;sBw>R}sy#?_2V|3b_eSK9z5vQ`b(X_%6M=-*zL_5l{B7eui-0K%MsX%1qAHV_P;1 z6?JE1%k^2&@Prt#qj*QET8!MMQjZttqUnjOrxON)_xp&WC`(yXF7M9rZfkUqK^dg7s~&{9|`WM|T{dm_k~p#eFtr;bwrorgH`pSbq+#^>uUFx+DY zUr=!mcq#>7{gMAz=jqa~w=({^;}){kygRzfGBHltg3tZ^^2tqnp=pm@QR-D=MtjfR zrB`alBoE%in>s0620zyt7e?wy&FH(EnT^=Bz4Mfl6P`INFY8BcUR*n;qO;R5tDDRd zgi*O4FpwHZGMM#YKX)u6zCcQIUg&qo7K$V*1-q<9*I z58hR0jG&6fT*Bb+Du;mr8QLtS(*&lU5Ycf+Abf)XuNYJjkY&dMcqGuR=;KUldQWNl z55C2kiObw`i>}WIPSd``epFynkwO<(Kv->@uPrcn)7MZk_=7Je5!4SHE;t98{f_((>8q=qpE@ z69~kNvzaf+CC!+XtUk`ADeWCsxppqELSM(v_1!=U=Fs{En!Yr6 z_vNw&+OBw?fNUN9f>;2$A#*;-3G+pMggmC`Cf1Kesq{R(?>nEbaMbU(cK4yzi& zj)<_jRUclikZHGpmi6fYf>Y`D%J+`Q=`;CzrR=R;0&ZoXM&C^=E}8qB7BlK7$GpB? zon!s%^ID&)Eh4hhdPoPu;W5U#7YiKo>S{>H^$1F}?CNs%&KvE|*H6iMRo=4;iyrEV zURO}BnGE)=YeKFwreoQ=mUgc@vxiGQ(z%=9k%*v!RGra#_M_oriOS#w2f4oQ zTaRn(-F+pVQe56-I_lQ#Er7u0BNOOE(yq_@a#Ag$tN1monv_@4F!|yvy!QcRI#%&i z%|vKG9pkxq0|t__ZtdV}^ZA+`Wi ze5%pk_AyEV0KW(lz-5Z-ONd8K9A#-_Og5yXYAYJ76BNz`nptG$Q|a$wHGHUVhf!(p zis^h&5OU{LakdjmN@q4ZS&q9As}Xe@XX=EI@*^t|`^Q2bU1Vt!*n{8iIR#1~aXUY9 z^Is3O6z>G-=&RAF?0&QOR#SbcBWsqA&CyT$CEnHS)%%Ea*OP=9Y2Ys%CzR~_ zja_V8BH7t>lpkjM`>^M>N_F6FA;UK{7T)!4Z)kK4u*Ms`cF7{9j^q{4 zT)HoEdYsWG(i-KlMXdOn} z9xbHfoLo@gs$tqpvCFVSWLsg1nPSApEI)P;<+N%<-uoKHqzXjm#P(=g(eC_alQVBN zQ#Gtd;cv=m)Hg+azFuA6cJZG!+28ll+wHexcz<;!z2Awwx9j>q6yc@DyK!9v=a}n; zOG=bMr0EZSU&)ZCdtJXbV45_Zf+j!h@KB%WL|1c*i`E?gPQve=s%YM`y1`qpd1u^F z+)I;Pls`H(A;mo+d~mZTsa7nPjePZ2&J@gUeE%PpVB+BbDTb>u7LNutE{K@mhyEdv zHy2nEw;2*)w^C(xreSwf+mEoSk})F^%i>T4ZKdtC8gz$Qk8ZL&3IboaB7!r(Nwkcz z2M2u=bOPOIS6=v8(KvwQEEZVz5PXf3=)YU@z0_5xa~QqfjeaHuBtcnVzJ%{~OEdA^ z_R~Yq$YqQ6VVf(*S|%4kY_{@-y{T~8vJJ!kXh zAe^=QH)@zF$FSCH=E;suk8agcn-kahp5Nll)~f~QeyV;8g=l!Q_;d8sT)RqBtVlF6*`olk>il;-d)x=_O*x-oq{*_P`_(7QCVbJ2D!4Za8nILunir-gsns zo%Hy4_k3sl-pQR8D<@mSmQ(MW$73Jl-^{s^U!*OAi%r z%a$$)m+Is-PSc>v&dlF6H#H*Ht8PLyuNs4GU4(Xu*&p3^Vklpj5599rM&Y~Ln-E9d zwEQl5!DZ*Wx_N?&@5u4nI^%A=S3_5wuY9?BmN)$7>1q=DV za=txTv6@+55Cz%b)x2@=ao!+lph*>^%gs#T^xmVd51oKzobes?J@z<;Bk4Is-Uy2fHz;ys&n6r&j z!HvXb4_Ej{-XmYj(SDJ?OW&aebsVddHZ#5uDoARN(qhdVjR=$9`r6Hkhg|8Z@)i*<0&o>0J&hsB5opG!|2COz;m8&M_Kh0rhUGFmA zBo%>>^#@;YNzsn(rB^8OyKBHzy%{7htI?mAF`Pl9m6t$OR~&OK$PO{>5u6frZIF}9D!^hbm*ejkOJ%WHzC1OIYd3A!_PoH9>paJv|B8P@{Q=I~SZ!JHkM;M8pu z4r`vIz#ojgR!TyL&#P`O33fr{dC@Dfsa(zOrA9-+j$zF7ROS4-i#?VZd}W*5J_%Vm zWnyCD!4=V2q7J(RT@P7M-d)`;>=#eTSB^jaw==At_=0n@Jy$h1P#CI)FB7uZhu=S) z{E~5QM6bI=22hF_3Pn1$uUM$V<9}Gl8C=K#AmJYC^z%#jhf@gSEY4ErBns_$C2AN zKtC3Q`!4XOPng$93c0rZwfFA3ZT#IcGj)dV7iPU^Uy}OcmD3b}n!I$gxU?O!c7AJA z5gYM^IP_joYsRD_;2xglMV`@$)e0Ge-E(8!6p-b{YqbR8grKHDM!a|j` z!1OTUKNXfcis4Dh>(9fmr%6V1-IiDn&N|a~4DD6Z&8B>JakRl!1x*$%E&Cdv8!6?v z6QcqWDftK4!r?9q??@~RCchk(7KvD}Y*^(v1&q=tTamUG&ocNY8)avEX8Kmt_uS@xw>smh9C^zg*h9kCn+t+Nj-Z6CLdOoMSs{%M*(oI`K6sz)y@-XgFEF{>rZawJ| z^f7ocjB=o(J;8P+`o9;j|6fw%o1!k?-ljbV3ckM@co~S>A35VZq@aA|MOMOgR?!bd z4b^Dq_hcFT)?nwn@Dl--XnFiIIsWXXtt^R&90rK2Ja;g9ge12!Fzn%t@EUw1danw* znd1II3Khr2$Tn1srphI<74VM@m*7K*FBk>B zAy*?J$oZ6kRrd6^)m`{gX`bytK1OdOCQNrdn4i!9S&v$ANCA+|ooyzx?16*SfsWG} z_2{g?K@GDly=%@97ee}AtQBei*obi`&wK6XRLy{vPD%NZ2!98k82s`b2(n|-Y{al} zTK>(qF+U8OyojcZML?yGXiYZ#>v-7m)3i1xKd4;sZDQrz1ma@0P5R16d$NfbM9|81 zbZ4t{Ba-kIi>0ryf+M=4A3OST4^vDOw;dy*f+;JDZQb+Ew|$xx+5YRjx^EnoklPgL z^pMSDE^&sHq^#s{?t{RSznRu5^nNkG46_bh!ama8#eFp&)Z_R6*zfy2$;JOgm7#>e z_t9WH&VG2pek<{KpZ&%+e3ENygRN<2kn{|e}`F)KqrK|rEo@80zOT0_ChrrFGoPF(Uii^DLk~fiNm6*yT_H66a59NF5+9%t zFi~6_r069`$3GX19b_qqLWG=LtQs7{W&+fA!cGu4*1n$ZX0?z_&Ee6tMDbVclH5Pu z%fK|oTpEpJyTyg0^~AxrX0&_2qkszKsE4BSJelQ#<$Z=;_!+M@Pu)JbRSP+t%hv-d zT(|#lvubF#eAFKhIwaX|G?(=qjz3?Z)1Yrf^TJ=r(cfB#bo})TolH()~$6}?qn<79jaCTV1WEQ-O^;ohuneaTT zpLof5CTyj2DfYb08Y*tc zLfG(nrin1(04ShCMM_Z!G-H?Rx22>}Q56Sk@4H~1nU#ugBO`mJuO)FQpY@7sLdJy} zn$Bwhoz>vEc5hxey#FQZMbg`0!V#7l=Snj@#{8_fpIW9BI;eX8^%v4|vl|lTM*OlL zk7&oY$M)LNSesF-0ACGrqvcA;Xwtg{LO%GI0w{#F>3Ds@F^jIL5;d7q)Oi?%h128r zHPq8_d8x6<`V#9C^wHRf`gS<5&uR$C!Wgk~2w< zv#M9f3|2C26fS>B$@=0XH@T%;RX*X*h?4S0*#_RX^h=PZ{V43-R)G31uAKXt$N0$& zIu%3$mxr?=3WoY%3?Q~JE#@&NL5ymxGagZE;1&p z$ho;*m@cb1IIFiM(kcY_Gq7lWfT6YLqye}8Vz;JNJX(4QY6VE{EC04gXS$wG6V)VL zb&vjnj-=}KQyP&J*)HcWY-7MK%>|o3{)mf?z5sF%?9j}MSNYr7Y>(hM{$o&M1zYK3 z%8t+Zj~a@F{~kFt9Gm1KYk0L=Kmw+Q;I!GG6OIobcNrk4!-pZ zm+zPv%BnoL+{BHa^@@Ze7{CsUYefs6)AS63P|1>g9~8@j&~2zUkF%m+jjBqU!9&#m z&>Z{xS)`k$OLE~Yb_^JTm3KTz9CBsLfUa74R)G8Vk|r#93Drp$=sF+CEWuAgjmsK- z9HEpdA}!`+mvfNm9f{5-IZ~FVvYK;n0&A^ z&|bBfJm{BA>{Q8eS4~s!WMRGJiLzU~r3L9B)t;;RbW7NqVvV|pi#@-#7e}xX(MD}8 z=B%(=qs)-Zp#lNl(*a;^!V^1%ykRjq(b_BJcAb+sri#@!uYVK?`xbQea80*ms&EC?_H0*Dm@}AogetE{RlybnB4CP%MbGIdN(_G|Q_Zq7TtqTU3*xu{=zaRU(e2}3O|OXA*r_rhrL*hi+)w`WJ` zsM#7HkO24!_6y=?+r!j9$tAh+cVOThw}454j~tgN>FK?!F9w4h|J)RXM((Zbddq(| z5!v3pspeT`lu==UWR#kB_cevpwX5EZoIG7~vM*%2no>44_omOLa{Y(dW4D)vn}^0; z&o{Y^;rpS+)lgmD0!c$1hTQGC6fcCHaBj2;;d$05z9lI(((ub~Adx!*UBHgQ_JnAu zy|ojZ!ho(qO2?6sq;jXm#+h%~UFr?Kx5_XxN&eJ!ykq!<#9)gE=JI+lb6I}98xk?4 zO34%8tcK`C%$3Q$9_CUk8}^cB8dueG`kjxNn;5Hma-^;^N6-Z{lwAnD33^JbC-S45 z6RK%bowtfRI_gFsdaxw=7KB}Pe~pTf@Rp;np?{x{2)M>wE@YPp?N(u0eJeF)tgt?m z8Vo?2A|BMO6X@9JkvXt)_Hb^~u1W67&m=ZkpnKe0Bed~&{Z@@4@5x!uSk-i`zAe9u zfbk!*gy7jsF%7Mtkx!2B)=!j$J}$R#1Ws@&=g>%s1DFrYg}#WdoVlm~)7JZMBl`0w zb`3PUvJy0S8>ONR6XW~a&9Lyr_aS_*AdL#Qr6b=zy*njFTUa{=#>6FR9m~?Bst1h5 zD_hILVr;$C-St#x7HSt@DkV89r-bV80xD5!>y zW(X+Gl=V7>5BhMuBRTmoF|7wQ)iX6;_X5+q-opOo}sS zjZRR;+vA(T9Kcy3Gtnw7hJ5E+Mf;q-cXIvOQs8%4GsteFMQKcD_;qMU)3lUl8bBzA zZN`wcnc7*{tshpD&z>tQq22%{^e7+hRr4&z+6S$uD%Ei%a*4%Z_VhCLm%;K~Qa~5n zW^xFlj@~&jp{1i11_atF6d9btu9}`68ZK{ImkdkOURt(!NpeAk>95Sfn3obGIH?#N z4Gqq^eEs9q$n6>mL&*13GFzj}URg)6;ZaT+Lu59xie3ab$E%mc6w`0AFe6kpUqtzrE zm5*B=AX%xFIR4r}pe37bhg)@?bi4NrZA-V`o5pZp$6wf-lw=GyKajasocAQ6ApgL@9!fmG1a5 zIyRf?#zWdWRD;K6!kVT$DDZMfp;iR*bh~vWgUTlLeb{}x(y+O5Hj*c~gH0xe{5=p^ zi%tAxBs1&eF3*TP=SZY|!s8X^j5bpfhK63g#(gU{wk2TKSbEA-LdnvfAh<-BaIRGE z`{W6`g=h=K7)Pn_B&eLby0Qyh0v`&9;@Q%bLb~6Ts?wJ8B0Z z{J%=hAI56`IOJARP+F7vSI$>t!f)>{(et&wD*awmLlXMWEP(xfrH`r=r2m@i4m)8n zk>f4D=O`3&Tnwecs!|19g@7o1Jv}t+mZhTK+>O|$E-1)0?yNvv+i0qm0iB9F;xbeQ zfpG?J==L2Rp}U(|jKf%YCU5r1tONI17~U_aT=&ToHXF{haS3(Mr>91{#E%Nun|7TR zo2;X9N)p3{R%$;Tydi0$?pdOL+hTW;@@t1ZvAtg+Zp3s%&3chok^%~3mrrLEcQ*3wh zlXoMx*oEh&PaCuhRW2^Aw%4x&!}TNB_1QFFjjXO~^HcI*Ae-2tBS(TzWGQ2$ty>zt zDQAn2T8wB#-Zi_hZ07#D?kvfqlQ14<@JW-*-;gE7;#;#Ou7n=%(^o3r17 z_!Wi97RtAm-&$+G5b39~=(1vqZHiBW~zd058gp~WtCo0ga5Jmgp~0@^Z(~&@^YTsV+fMb6ok1G z4XJJ71$xPF>r&Cc^KR`YMhF#=a5$ehSs6FdClAtOc?QAV7FtJ}$nLYki}xdGLxTr2 z1?x7>zZimfQ*q4IL2}XMc~sI})tv*t?pQKjX5)A3Caqu`r0M;&FCWvtr{15>4asg- z4RomkhjbL5%Vo}#f_{p8Uu^SSIVC;ltLbcirJ!Z0_|8j|;6>-`uGH88LiW$r^IMKV zlx&JFwz1mLI`@to7l}n|F*u!b2AT2=NCx@Wp(#LhCDYl#=Kp2!*Z%E zR!Mw*%1S#wy7d1BGjRM=emQBCf7!!;s|Ssb5&Ea^>$T)psPKL$Dt@0-ck4}ccT-J< zOjflF0LDBG=j?Dd+V$(wI^nn*vGR9x+q6)eABPkT=qnrP*oR!auQz_f-7IdXy=)>| zCPoXjaihi}v%I$+S6PzibIr<32v5h|J*;-*q}2S2r2dh2qOEpQapx;goTnc^=R$bs z%=!{3FE$`?VnCHy(N1* zA-UPB5qgVlfKa^^#yMruWOyUCof5B@K6}!ZCjxQYk&S!^3|s6oDB3OXrmN1-z%TCX-cez7iwfw9n_jbk9J% zAVMmN+icG`&0nF8J zIy5VJO~IBK04QpF$_5@XvX3z66S-V5rsxEs|Bm4|UOTq6;GU!tN+i9T?5@i`gw=5` zE-LO!GM2GVw#CV38}d7ZxrElP&1xmf;kQcrBvVXm0j-_g?9oF{;JS_&WZ!C?yi`CE z`%>M~2UXsij6LALIjsEu!4L*>{)KbT$={F;7s?V7%DGrs@x@48P*&(A_Gpe{-=mw1 zn)8V*MOdi+mKAi&en4u zjd#~gmSK++_ZH7h8hS^#0X{a`)6yaRiskzAdi_Ah-SqlrjKIaSkBk%mX>p zt->c_K369%eYmNJgd;*^1Et`9;0I%i@64-VO~lx40cJryfx*f%6+fg=Se>2ae29*e zw(SPaqRjCR_zx6F63HOi(*3HJR+hxg46E{0XkL>C#@@QkyxlW&{zWlH?&;V}+l}r! z=$Gxrf;x=ab5WCR?!M=%_HPqVrrK~fqvl8Icy0*!=&R5+V!O+Yo$ls&N5WSNU=1;) zn7~D44CKyZjw_Z%%R7N!t4}RxtZP)i9X$A}iqdY1OSApFqtEwZ5NW$;K7FXb;?#fQ zcL$%UkADB)`TPau6WJ3InP~W4eM@{xqE_XyR-p7<*{D95ndwx=HaAt0QovW{LW-0X-D4v$b3=8MZu{Yq)c#r7z@${EkC37^ghg?3<&#b~v`z zk$PFy4E&*Yy#l>`j;&Kn*TP!L7>MCQc*N+qYwz`7V!%8CEL}kFkYrxj<%G=6rkfDo>@9*UZy{ybR46F zh{>7-GJzzE08cF9?F%-_0-!5%%86xFyKA1(Z$Lg7x~EP&`&;VZ-?GaovAs_+#(W1v z{25o;feTiHj~+M+sO%Znarv|Ex>EiJn_4+K3M;Lu;+-ZH5<+6p7LCji)U4S?_u&jr zF)HpS>4=rQ@&@`dyyGS8XkX}{YFZWQm+Ajw;^rh3e^t2d`8vu|HBF9x0Y9WvOK}F?*8_33 z%iG=Oq_FkqPLpAL+5Pr=>fpfeID|J1AFu1ve~SSxTkn_-$lmn z)~@mYSwjT>2GIgZ8Co!(F$ooycL5um(B$Z)D2+SK1;#{FvAfw+=+`RubXP!C?Cbfh zF2xZjq`92P=vYtup^W`Oji}V=)#GkQ%f-c>YQmcRzIu}gjn{o znO8}!TZERl83j=n)BwZWb*>6a$1lcxI*+L(Xkw58KJvb5joEHx2|Y%xJ%{crn7UU?yJqHZ_kx}NU=`T!ga|FQjhQf^pV~%nJ4Ghg2rX2Ll zfB&FDEY$qdITMAeTZn#p+HaU-f=|#3@44(0#Mu(}oHhy4hiE?M(k0BigOAdzXfe+I zw^{9XA~~gcnL2$N#tX5oW;GC`r!_nr)nR+{%x^dusHFNp6j7&b-gWRsM|+aY>?q)r za}GP{ABWnnlxl8>S{Ui)?h^-$a;(RBrkQ40+|JhIimI%qa(yW;Smh6;_tLMF@c&8o zHiG3ntFlHf_a0VGw<~mq%t*LprSe=#%3ZU2E{5zoy>{_`mKXo`Cx;F{0rFxR+dBh7 z%U$0D$2dl7+=(?gKlQ*i%K;P`cH)^M;(#GSN+;$B!p8o6~Of|mMb$nb-L_LN^o zkoxkC76l?vCOnJgAsjIsJ3`mb442SvBPz-YH3OD|7z1KOm7Yplhz)mRDOW_+@83Sr z%V#zJK-cPz^gl>~Y7(j%q$?CI$}0KY@h12zFR7H3p6MSN&y;j}L_`uXVqmsI3vt6O zL=h2j@R_$rxL}xP`ZXMZ81Mc=k?$q1=Z<`stciRC&EopQEL&hV8I$&ZVH5mT0+`D7 zF(Xg?GK&ig@6*LaSza(~XhDC=sOX=*p->`(-={35NN<}mN$;uB(K%o`6TjS-FAycK zDJ`!!F3P3Av&!EY_?e0>QGaLFMsv}!o+JW3OU-QoD#G?GeyEyLlg)DKIpBK% zXn0^z8`?P@`r@CIg7dDem)@@)DiIjY{I>q>&A05!th}0I`A9c9%AAaHcR#QG9j!Fy zuBxaRtED~VU1B$sljQX32a(;Iw;$8f?h~yjLGQAEyvl|ns_7{y2;mz3BU zMMI^@iELI74+-&WvxZlQui0L#9t=jvR%)q5y9R}@{E3)9wM%afNrVi#(-V~Xcu`S_ zjzOVzy|Hv%;0WeF?=}a5~1k0N?ltlRXLFKj6YFh{Eq{4|q z(|%J=r))PeRLk$GWdT9d7lbdU*BeTr$R~5gzzc+!7G-JF2?L$wM*=an%MuAL3f;UF zz-rrh91ot8h)u%K9Fntdr0*OhJPxXaAeP>BtJ^%CpcpO88htUiC8z*ZGnEW{HZb?T zG~1ppdLltEsZP|}i5unSz4X%E&=2QolAhu@n^?3Wf$Ev5RM7N}@U#?@_d9{04dy-L z{^*6PFD?156YI4<+T_}Lx&~Q$dqcf8vMhmEv3OasY>M$e3JL&B)BkT{9CtZN>@_y9A%tLyQocz`uP*(A18wGm(9QDwR9?ZH)?LQ_LaGm9mvFt9A^`^9lbx3nDd&L9&j z%pp94&!95<@N(jbameLL73#rsTq>-DNgvqV0)lf+!o~I+5d4Qd;J@8(-|ETvQ`k4vcQ}1rou`glN^z#R9Gq*7 z6xcJvw~QNqlW4f4G#&Y-JVNR64}@s=HwYZ07{4MkZlwa>>XOfuOga%K@yq|OFm z17x6%r@bA+%-AP4-j@X!oaWla)sZEj6NEmaPL(oXqX6DxcN}UQ^)FxG|27T*;VJh4 zZOWdIZ{Hg(%Y0A&Hr=6!s#fqU-eeqk-;I}AH6Pvr}27UVR(-i+2|C=B{6ivv%EIqQBB_rSdd zqCE!sFc9|sUv{(ozwBnBgQAbKZPyJ`V}E;V0Q0O0TePmp)pyQvi~$1+8+m0@KPg6b zr+rT8qDBJm;1gn;@+6VqTA)EEE0e!Q#A_;I>os#|Pn{<02VK!H!H&E)4~rAjn@Z|) zZ0+Df2Ryo7pQNlbtcJSDehU2uw}`Xy+am;hT_P;dnk37XKm{I(Im&2o*|p- zPU@hagqdqu>$jrqN2q;xy9a&5!~&fQMi+P29(;rD6{t0k>}6|siMIZ5fP{i-AHR!+ zJ_gdarVhJ1xk)VNrYjaZUlVAz2e9mKN&F!_i9voQsMSdv&(BMke{ zj{H2p%<4oE=C3KzSU)WG1kRMUBqhFE*ti4>nydZ{z2r9FJmhSs1FI2Z7WE!hY$#9s zq@drHQw!uQsHU+s2|%`rLoYPzzdW5~&D>3r!z6rU57e>hQ(@zOSwO9W`#@rUuFv(# z4k()agJV^}5r3;6keRekAK;)?$}JmF>cKMckXkvtgSCGMng*t6`s9(kWQ5x87>C+&^u89RN}WU1Xbrimj>JnUvUd`2 z&!7XR`ZOzqEUis8Fs6cCB+@4XwV>TsKnfiXjd_cSL3 z?;w?x+Apdm{ci_4u<>3nXNUi_AAO7joRV#Ev>>3UN}^$xd?!#WZj)O z1lqwRG5_iOZ_Pken^B_*B5_ApHRU{BU2K&U@9T)5d%!p7p8cLec`D}~2t2yXZF_VA zA1c~?X^#j>>bEJ~*a?>x=~@N#^@itLEadU5;-xry+z6?jb<~WnqLiYsA95kW{|`@M zy6Pbbw^}V^OqC{ekXdAk%7?g>(FscUETBQ{9_D-X#M=JBr?Ypy;}}!XhD=WENy!t} z{v7yRuH{x+T9a*cPw~-Zn9v@5zISr}J+uE$507(Rxj%gGPgSLep_5q$(0JM%jIis+B=9)+hd%RU)B(ZsZ zd_%R(5lH28Ym`I}j>*kX#YpF@%Mkt&u&EcxY?iy(cq}vmazzHZR;A{%_xXph5uhd0 z)x^p9nSFJbLWI|E@s}H?_Xe-iUqZ#adfalqAdK`<-GOkE=nMW)9y29bM z)aYEf2rJqII=hpH@9}90I`)hW@Ln+iV=ZB7ff~d=^>Rj1ni~tF4@9-xXm2C5#wKbt zxL)qRvn(A}t<5haYXHYgy;m4)O%nHw^itcIH6iMkl$X-td*zl2-G|%d(W&Md5%^=< zm$T{snJ*(N1CXg-y>@FE7Xk1eLQ8Mdn}U6elG5JTIDhi0;fewZse7-BJS|R(K{z++ zXoSq}H#Uw$TE5n^Gyi1=tY592CHT`;BX#>@{b+E)X<47zD|Ix0WG}55zn#N*4GV-? zhvC{1CjXDmOLSR+EZa$gTw=i1{z^U{>GOkX)G&-_H))Bg{5ZywZCzIF>AN7_a} zL;)3oBWTNHDshOZllefvL?Rm4pBhGb zaLrp|#aAqGNG_S+5zl(b5`_@=JT>bmuLejS1E{p?pSGSfHAIZWBO4}`>_0s;^Kc(U zafs1>G5Y@($M;WwuRZNuY4(sypWg<6#!uMttl0_8qp6Jf+y{b9t&ub7>=>RfMVUV#8_66pO?Mb?PzIe%7Ly=enj+W`@{V z1@DXDM4#p0NYP|}rsSNYgEWi$s?V>wy8 z72?}WT$~1$?gz~uQA1oCC?R=(FbLNvP&Ydtv z(I3C_aM@L{zocj{K1W9*Aj=PQaOUmWVBiF48qKB6T)x6nymX5430OCRnKG{e4=A8F za2z8TKlDk=l&4m58~5F)6)w*_rJ+UPpXe}8X1=t7w;|l135p~}E!xcBbkK5l)|i<# zGZAwUIyH(#FX*t`;qq_qgb)4T7dJj;G?1ru6OE9Rh22{Y);&dX8wgs<4HO*{#6GqE zIllj|P!)&z=?1{nIrjf?>1_^LNBy-gFkbU|UTR9 z2rT9jq+<1*6NvxXrT}vDy~23l4+KZ=j*jrB_`Ht?@LGX>?d=cd^1A%OITum@^$A<> zmsWG5#qV>ggiN~+_;qZDdOSAj|jUXOJ!uy{a;U=YWU4C ztZ~3)#QAQqbnVF!J(J>U|L}=H-C*q;%K+tH5rP4Fyc`Ko8ik zY>X1G4|pd%WcQ?-J?S)Ts`rTfco+CI-XZ$}{z>!HgyJvTgyXfBGj2A|eH(qEWHwlh z{4*--Z51JI54>tek>_|&@m6yKenM^^j1pNNbG3Uq0=;rOTL^rfUCzEVypmycM-+C;9G?;zP6dl*p~5 zHzPf13kI!YNw5?6lZxs0w1c)euqO}c{Q_t6`jg%9 z7yExc|LlCg&hmh%*Ap8K@7y)DW6LSO3*O3h$yxVzyFc}s@PAtq%({9z`_Y--pKsWi zs&!R&k8+QgpEym5=7EvAs;a0KHxGdq$BR>?ESRxdOKRf@oUzGtm_B~wVvYAXDRQ5| zD^RJWLq9*3xN1Y`H!m45pNXB_a6j`DWqN5}Kz1OuD>?it=t{cMMU@T(`?YZ)($&;c zPFju9aV4`C?_Lha+se~;8SV~|G3-vKVfsN-@b?ROUv$)8q06}jU?1VRhEVWY?g6Dj z^#&xs$bAS=id!_>51p%%t@h|amz}Z1ZGcj_^tmmnYgP~QsW=}pSBF}eEe4?$R?P8> zrIUm!#HXkg3SKsVr$8Lmeh=qw{8qeK-alhC^K6_UPgXGp&-6e7f$w(8g9xI--0ewt zaN<{@*rC`-oP?QLd1XdgT)9#QUG|t%f20Cgd({J#C}0FD4x@350ayVuZt@{VEdw7T zx~U>jD#lAbVlbjf%$j)!S}rAfpbY`POpug{7u(o6;lD}>U}(XWMIg0|-{3?;msj3X z7OkD2YlA!}X-pBq(Kr3DKC^Vm@ScA3rf-0+SD?1#A^Vd}Pv^3(Wo=s3tv-zr#QtTl z<5NxefpWS7PO&HIqF2qzYsRlC(9$^RJc8ZuxlrMJB=}QFm~i!v09DwgtPY3OE3Efl zqgq#pVUV0V2v{_9LIgXm4;}VOBJQ2DJvU~%+0=GRtbs?Bglo4cVZ}zvYNK~Qc)w@5 zPXZ%PXI$J&XK`_RN)i2^~~r&%F2!Y8y|zL4L4gaERzM}gnKn~~1kLUbm>a`GW`Z4cpBUL$hz0hlI}HqfXM^1 zxK&=(R+2j38Nf!ee&hWHL4R7C0O@M2nSAPz<~E&0l#-XSPHHa*a2r}9D8Ngt$N|Ut zw1l0@F3*_C#py2tz}})=zV%u6j^C&~vt6O*v%#+1LUi!*)2h#f@aRv+ZO_Xs0b4n* zjHt*B!fwjsq$6cUfc~_|C%^$+zsZ$CIaeu4RyZ|-+#sCd$GkCGn+Q?tprM!!Gg%J| z_RIMK()7xV?6VHCbr_2reppOwoMcjYb((NlWjJQDZaZ)a@!~+)#~v|}m>|ufEK>@| z!d$P5CDEe0@I=AvHmA6W*%0npWe*~;9SYXS?Of-Zlk!jh`Ax^g11hlc&d7V<`$xQ+ za8flFU*%A=cu#*~Hcm-LGR}y*1JYEG@KKL{O|Z$R&+xvd zA*tQFljF&nUk*%r>MUnj5Vj#I@C8MUT`dfKq=D?@g@uaNg{`+kIu=F<&+XzG-?ye! z&<{;y1uJP8>SOq=3Hx)4gm!U4_BYmLwJe7*gT-rc{l22d%mZ0i(&#c3@X-=oww{~V zH`co|iGUFXooFb(5yP|k;XSWGxy|<+od>5oX^}^UNF$50AApB{cQHe{5aL8cj;P?h zC@Ude(WA4s#EA*Qw>bENEmMh{y5kfPjWYJ_fP9I8?irU46642bhXB2r=wr#tGnF@2 zX8*)jO1^~4+lz71ba6$=NJ=P{b9k7}m(L=V*Z0i3)85tIT-nwU zNc4*gg!*=$9XdHs+|S$Pmo`&n8$@|Z+~RE^xeaoy?{r-A?7VfI*n<+T1TL#po$m7I z6@qTfg2nlsq=jmWBCEl1m2h5bANJnt1+*LJmc!a`n&;=C(L7IXwxRHIWU8v&AL8;k z?ts#kTm$^bP2ZxmnxWiDkP<<+1Zs6#pLGs=C__c}qYL(}Zm4V}N*kQxlo)$4F?t~l zuuA&+_^WpE)t)7!b!?<-#nR_S3YL=1`Yx!CSsS6C4ff;THLh*z*lh`xN}&rYi};1o z9%m*8)>NQId4H{8^&3*QG!pfQD z0H4c73@abR_N$s7?h4Nc4D?NzbWB4SDN}jMw!;Hi8L_A4q6o8&y@UXvF-twkpg3Xv z_FCFy9p-sarl_MNpkMTD{{HGPxJWRVbm{miZ@XN$)?2#k9`n_{W zyH$v3?(efdO@jZcG5 zYyULC2%h$NM91-=6iipwGdM89QK%x{j*)Jidfci0NMbe|L7in-O)_-w)5tmml9ovX zCt?M0#Ga?^(BIcq?(<|{df<{z(CGf~S(;JXmZH&{C|05o=6o=DhK$QckBQ}cKVRL` z>ocYe&;DW23IWG(EMmc{2C46gx;hU~H#(nCDLbT)N z(Z}y@1P65d+>^1x(ZMumA;Ms6d;g;)gMl5j?VLk(3Oz!=c%~_ZfY_UUJxl!-`}<41 z5=tA$L;h2>N6sl*L4-t{G3gjc7>c@3paz8uTvK0M=(IA9p!=$cfMYK^GMOkKu_MSP z7!YFeVeu%x2`XGs)!{cOuPKtpPX4G5bmG!VD4L2Lurd}CMp{rb%Abd_VCAw@DBr(W zz67JtX2T_XT!9Qrkur?tpGrF~>&kmXZuR%+~Vz?@wF zn9m$cUte$E7_w5gF*Q=J(Oo%Evk7Yroe2y%#D{HX_fZy;ZI&M=bRrh8s+3nOL4 zJC4~&StZt;J)=RUF^`#tnO0qu0-Qa&jmfFUe^j=J4*THWwYJ^b>^H$ywL@H=RV%c$ zo>IRRJ!p@H-6{B0USdD}f~6&V( z_QllGhrGb8J4gN_A!JlpycNvEG%9%~piuxeZlc0iERz^oY<0LtHS38YXn0{*J=RNE(e z(P#Tm!g3kXel>`MKRaW!U1wiy{_Z9V`m5#3br!w@K3SZMgKMrAqdJWq?o|2|n3?Qr zw(I=nMKwsj?04Z_H!u4}&~u7b1u0OP(+0*DEDdvv>Z-(@9Bl&yf_pv}snjridmGM4 zn>?|^ZVNZmgfz<3u|<%qhoKkA;t@bTEO~cA+g-pI$&)gZ=_Hr7qgpZ|7z}wEP#lS& z5YnuJtSP|)Ed0oe6^-b~KToQmRo*%|$v)Dg)wcQz%-Q@=)=DQjyEZ(_Jxpv}Tnw3) zI*v93C-%srXt|p@MIZ5!)Si7h3o)OId&0#XSaT`ashPh5CZdG1$0-v|I%EU}TMQhr z4LmWSi@>uaE!acl3qtTG4b)0!qPIDN_#6z;mi-{3EHWCf<4}5)X`6*vKsSTGsMHG~I z#7kz8ayr3LE;f_Xigje;i~_0z_`d!I8E>fw9x1x5fud(DUzhXbB$>ttBM($Bm-+dK zxg4`o(D``G$_ke!d(wj?4#-+{guOj9St({BV?A#-5IV6wV{CdcXcj;m!#zG!^#yJC zO$_}oWS}a5fLll9&kN-5W6m|Ko>&^}dbc!C^X^`^qs$mJf2}|9;IH})Y!w0}(XoLZ z9N0=zuwE(sQkHu}tMtkUUzKuH;?p|JkD7aN4Xm~N6_whg)uPMy;|xeEWyXP9(mM+! z7tZ)~1qbh^F0J(*5HI?zQLg5!-wq zl&e^=C5Td|RI6m2LwptGu49LSVFwd~v1ki`h}w^?oGc&fse;)A@kG8WtkkDQ0SdjA08G(!(IY)aa^s}oa`|{`o~W~gQBXIm;225- zsDviC+tFEXDg+ai;)SNHTrJZ8=@8E@F#`Zu(=Rm^(H+A(t{a#@%z0&|H`lC=_2u*hLBUZIC)!K2Ht ze31MOq9gG;P~vUmE%yq*iQgP(U@(is6uX{Tx`L9W;V|v9;nMKYI1!nbsKi*O&$I+6 zf_yf_bAAETaf^M4emFmTOKiVyx-_-E?TCAxy0i5I+Q_#eCp&eu(fJtg9a;vip5PC& z?tF{EKe{ts*tV^-iS$?6XWx~uIx{yel?cTbCKo~}R^cz`{u;%?$zMvZWAz2+2+0!mCBKF*n<1gm9~+*{ z0A?#bo!4itL8NbnJm`1yx(+&p3ObL46RU;;JKGo9=m)p~h56H5L*AD_CQ4j!vl+;c z$76N>Sq1|k)vg$UYDYjI+l0wF@guXhQYeP}?JM}~ZlKl|+{d7SJSo5J*N8|c2L6fk zS#Si{^I55sZudBK031_ z!c4`77hVFw@PiPxq#_TgPm9J358QPiWlj)9v|$c+dO}Jtf)M6>_+2xGx!Rt`J>w>3 zM}v0c+?l_HT3Sm@@bR$zsIH!I^!`ZgMDH5C;NJr-1X3o*yxe}@8?N>?P1#Fr=fwLXYusdu)Y_C1 z+Z?=uH$4+D_eO-Dm5%2{bXsjD=g@CuTCZ9)l%srp7~Kynl7>LPKpzaZy0@?x#j?5d zJW-G2aN>Ne^zGQRMIhJ4J0E15DPe@ooEUF=(`GxIs!*A>{B$Nm$>R%Dstc=zE)Vdh ziiPgRhRgk1?y~BlGcujhElb*KhD;uuKGx3Nnm(5};LC2QY=T*PA^%?Jj7i4TiQ9I@ zq?t6il273+m{%~6SgB8@aS*yT)8oOsl$tjSUi{p!2RXcd>-E2V_m*o{q}8)5)b8xW zekluxQGQ3ow8jqbkWQ;!#ZKFkOU`z-h;X(H3aD)rc`~gc=v)3shzpOLFcrdny;%}n7!Bc%PbNO>IhK9=XZWgh| zb6K}TA3G_<*0e0oyGEv5A`Gh|gqM)Xh+-xK?pu`b8oEwvE z8;*FfHP3>dq-RY3D(3+H4iGPXT@6s)m5(lU7ZaT1H+xhh?iiQ}w zqG88@fKb`q-PFJy;_5Z8**s|Se1wYUE}*K-@7EaJ-o{aqpp;7}9v3nF%G)DHN8Orp z+Qx*vjhB9j3yLs5Le;FCV6E)$YI|Hh(i0Iy2<%QiOr0i}dXD%;Am{ISaSOLPOugqy zmvXBR-{B8~IY*dUbH1`jK{ngjFk-8b~3 zd9Hi7PWaX6#MS~b0I)pgLqj&qsy(WE>t{CAe=LI=)TC~ymU2C1Y0P3iVJh`~rg|J| zfIb~EUXrzU>COBXCqsf>KwTjQnZFRc199^4oUxESv~Q`CV5F0w$Osi7u`*#+{5eES zfAIX?qxksTlN2Ox45$H4URbFpN|~$QdZNB%>%czs89&*RAWy7U z@O?FtH}g#WsDW~J)w0QQly;)Q29C<{6qN#bB}%ciXplZL!|@F8PwNSIrAF!i8QIDM zN?xI)fQ@AtApHBIw;bvR{{DCFgCS}Q=Q>9iYZ`kb_K^5R1pHU^l)HsK^OvuYm*#!X z2_;K*=9aZN69d83SMMCDuGf6~N;X#{GB&Vid$S<~dbrN5EsGQCC=8x&dL{Z6)w_d; zi99(U%NKq+rnBm+WjOb%k;cusvsQi9Ej=bhO5R6hjsg&llJe%tL;r$KXIe?1RQTo) z&VlnB9$yWq9+qVckN<>efqOy_CgOI&R-IuRD@^ngf(oY70bShSZZS<raoVAQ>ma$&Gf}V7NfQ*w0_D*nxxt{V73au@S3=StY?YAWZ zmejU6y9;=}PUc2llnwEP--ibO%|lNIXwN#$je;Wx*X@uHZSf9dR$AI0kj|4E)zWLN zU${RSs9IpD@EliaaR2;*mpMr^vHze2E{g^y^Q)5Qlm4MA9^}DQ!=YEjNZW zx6v6Jaii8%t|>j#F{6?>O@NMIt{L{ZKery!J{?|)ma!~QQa@L%oqTVCB0fAD7&I)j z5$x3(+x(Z4-;(QP2tb|<)$* z`HZfs8&5Ji8<lZJcP%BNG3wyD^D8i^F|6%`(J_?|J{dU2?5?>rE`iM?jUq0`AHQu z2y@1AVpXqN`+@XlpR}G;6j!Z}#5e=)5V9uel z!YCC)klN}iQ%$GkwD|3liZQ3&Rbe~HuY*_G1jO~ASh2H;lF<2kA=d}8x5c^7C zOuBLD3a3BYwX|lgGA(Gf&+9|M)~&U!af9h?6Ut=?omPZwd~EMa7T06|IZWEahKHf! zkozNRue{-SJ*;k4&hw~`N;6<&*k_WmEIpRrJXeQHg9KM8Gb%*W3)o$h*ruuQclLjz z*jJ^g7}`dzf&zI-w%5#kRjWT+A2d22<73Akh@u}J82`l4`J=$!Q+_Y1b?nnE)jF$E z=zMRn7NmjeGl29M;fBT_d2Kmd`khSMmXAabe8NF8RRBP5u&bZ-_7hcq#r%(<$D8pt zE&f9b;6KA&V;@%Q|KrX~QjJr^P~?mr zH@}>t&B`+(@8n=Ia_p>Led^o53Dkd*3elEf03}kSD?Os+v=lm`V z;*aIN6bT8W{VA^*=lKM36GX_#gl{lK#ax4!42UXc1DGMJCFjVJPAlrN2{N%4Hstw$ z8{$XLR9h{`4I@h*jK@zXfx&xRjvXSlc<`dF@-u^KYfZ->_8+|>c4hvSpr%_B}H z1k>)*8TJChcz~tA9}vxj-%fF^vl@iFkpT~sYPv4H3??Po7zqhN_v1N7JschOx<)I_ zdVV^tUhpLu1`ET+5E;MHvLe9%?n<(i-6(oR{~15;h3O=BOcU@8=Ugkkqz{a?!a*cj zby>;+wGAtiS}&#UW*F&+%W7^m|Ek#0*1FyZDELwO@$UoOltNbHb#2Rima2oYqN>kT z{yDB`HKCEnJt?%Zwu?@XlJvo-ZK11PPGw>coH6N0*bQ-4wo)SrrU$LW6>OhWK6KWxG<@33sU4?@v<7z920J5!t;mWPb>8cS=RR>-jr;Z7wrJrnT@?L>p~E%0sFBNL8oA%7oj z`Y_9~C_A+&M)AvxMW|LO2Ya9frVgLK-$P=-O=S+3@4wfu9n?CaMq2 zyhf8rdT?|0)n$$450WVUFS;q!s5{4Tx~Qd`>||nCnq3Vyej3Pt)*L&*h=3iVz0Q;O z`4I+ZVfflwkc#kU7eMLby0%#L+eX?*`n_sIMMw0U>)20urxUYBnD(H&#O-+~%Y8Cb zwPgkjE=%a840yL$aJw?zI;{nlWa6_KIo~$zvi0QwlrXHSuwenQrGRve&5)0$1_|I3|~ph&&4#R=|K5e%gVo34H zieK#yUE4aJ!E*hZe-l-HN2h?2;@`s`4KWhjVi7=aSN>}J3S|w{Ko5;~g`+3R)W@Bz zu@g6B<;MJ^nDE(cowlF+Iq!)d(B8cV5k#UlY4Q1$-@N?%Wa}hl#B{w|-S-G+h0Qtr zd#>aRyuDg?rb<#}7F5zPO45F!d5rPp?mHJVPs8(_cJcIIt%0fInonC>Z^dZI%&#gs z|1Wtg_#R<{{gke_bjkagIsbnTcdQ+w$)>pw5=Of0r!HZ;RC2?!+oLKPB@xQ0`(lh*q^{Jj*e~#pA#C+f+22bTKzUA2WlC-x|x9q#UYFizjro_xK4JGtd<-5^mLe9V_|CuRXMIC%uWe>tWHIh86@+U4Ny;E0BvUM4;R zo0&VYVaHt0!@pVfer#v*gyS4{PwATjv5QI(!Kv@*6iM|n57)*<1PFiABVDM}Ve@Zv zf1v;g^CoK5LLISsNd0;>I5Y9S)bT_ukoBIdx(nU@@rr8n{np*4xjUmZTK%gQT{tI< zDfC2IkH;#64dnT%(E+-m6T$jZp|)&c)iG3h?-__y%u?;YLnHOKHA}k&SOv3>X<9hV zjKkF`o!o+vzsd)e29%DTy$^39nRC0#gCC2ihdM5%_nzD-^nM)5?+u(bE_*mW8)7X#98&Nr0#Si2~W%Kk6 zfx-4tI^jLUb#Wm$;hyaj$A=3#iucUZ_01Rtms*~nrl&p${)*ynbK=R^Ex4x7g{$Zk z#p8}{yR!D3eQ=#DTB_+7mX7!Kk2+tE{I>HO32hAgXaL_b%--_v^|_mifY%{Ly9p## zx74cz+u^-JRp=MHwQHRXmHcQsKjgo=kLV?i{;Gn>!CxvwCg!BTwb2*B(&f7bUP|JF zv8NYF>P^EW8aL3g%a#C}_Xi=C=QL#~`t(pp+c-DLT<>v6@8;;Uab?~95(&E!-bQmhRQFp%DeU|*$&u*I^#n-2yT}WsE=A7MJ4Wh#Kpslr<-904`hgNNIUKT#$ zaF=1YfMdF9b9Q`5H!g9x=k)BqooO(Av_d_KdBaE~VKlfc$ui_ca?| zDEWLp_h5Uy=P+T$2W;VqE}AVjas+DA^*{S@DX#lis0^LZz)_o$>qCGXTL=> zh~pO^pz&?e1pe7o7@oSzk$ac0?Om6_tHT~oDOoYu`Bim3;h zr&VCVRXSpzX7p#LFj#bCB^*>mm~l#(D;Jye}YL#G_-`a7&i*HmKj7Q0v2`L@>b ze2su?oEoPIF%7jm9vkztB9x#Bz_OH%uiOW&Iw?lnmE`YN z@;%M$Pxr@$i0;96$&7uu3FfgEszK@T*T}7&%06n+<=G#Ui-o|k$)%&1UEQwZIeR-6 zP(Xnn_6R6SITwV&1kGH)vZd2%i4E6ol+8)RS_wA4f!!AP$pLIHd1A70o6A5UJUmGK zbgZwBtFr!h(jlL=RRMeCmfCT6dQ%)9xQw59sEtt-zpfL;V3_>tZ4X~3g+UB!Y?NI8D@y8>F?^ zA!*(@w0`&N_TwN(ZlAXRS=2NPYKB(d-MewXxD6LS#kSKQ99!AXw&2fXy5~`{*BW_z z`eAl$N1@NQ&~QWMzMk>#S@*=-gHPLq$MQlh^RKB}C=0HHd!QvxjQY0ESpqq2(ViCm z+d-f8=QKn8{o$V23O%5AVN`ThIQdwHo@key8J>7-;Fwl&;KNK9?_2TVv{c?|BdBGj z!+w}vNq7zbl}_hc7P==k_W?J-Cg4Ou-OxS*!8ij?yFl&6!wby1*_CNMlE~eC`du($ zM0GzG)=tuTX8Uxf&hGM!#`)67pLuQ6*Yq92sXg}=KBoP&nr@qgEV^usj(Jnz5x7yO zwqeTSb2O1MRnDrtaSD&7UoQ)8$qdNQs}-}J)G@Abt5|+(6YL#`s&2<<1P(FtV}RlM z+n0Z@dIh+eObRHf(_-FdF5PW)0Dn5``kBw9#7wE9Ua1A@Dsj?F+w_4}V?rnDj?s39 zYjMat(uYQnFO5o}9T*D(RZ=d$WdnT8VQv0S!Gdv@^RUMR>#}uo!`dg7o~0w?BSV^l z5GyVK-oqbf7jpJJIrWo6%l(%6VFqGr)qFV$)~ptB>itk=4J1K2y5P zorV+$KM*n1i=Wn;4XK+C-vTfiqK!6kR!-+kQDQBz+l*WcAQO&Ok392;R@l(ENVH(0 z)9PLXqQh(Eg{PH)Ek^zi9|1%J!;$>@_&XYmS>1Ptn4*!gfI(z$ME_FTLdc@)yreV6 zMerpz49!%#IwJT4TgI+)aAh1Z@@oViSaNIYu!l=tn3dTMH##bwvfO2FY0>2Q)YA!_ zL)kLRYA$T7gNZYEWvJhTG?}VV_?hAn7#H6J*S}Eb zT9wAKUoM%<=g;^tbWFEpP6t|kZ0l!2KW8)5XnDC6?Ml91xBl{K!;oszJ@>MczaIrw z`hs0%{$VAt4aG^xf~&k3QLFc};A;I+O#BTg=RzpOtV%OicVvLQlKN*udVL|q@_bbh zj`QxxB&Yy;Cx#&}1EAYPK!D16dE2?U^|tCinpFU`?6VH@Y-fJ-nwgmRTK3XUff{zK zLs!`A4Lfc%n!X!xuIAJANF1d(){*Nwf9u;s(O`t{$n5l$>Fg(ZTMKK!7i9jR7hZsK zm}2kbug$KNG-|QVcpzhRJ1Hm|Yp^^1)FtY%KUe_nh9zpnZGO7K=UM}++cQZYHIrz;?f-Ag51!Nsq{ z>IJ_mafZfibXJm5!hkY-@-m+2Z9`jccBlPcHmL{Z&Hqm0@_*@^9w=~Mth;>+-1@I6 zy}|$SDSaBj9W+AH)TcE3gsEh(qRkNUIQkgDFp@Fpl6ceGp(731Pt zSuONptJ9{?#0v}0K_$r~XQ_}wbJ^qt!W1LE_gH4dd)?Hr|D|sMnYs1uN1}S}g5Xid z04McwU0l(nCJXRR<+IwciVbXi#(2sBOBaeG-@BI$@{*I1>yfem21dY(uE-6i4RH)R zGKlD!sf>WTGfn-@U($g7m3h>HvZ0}0bG^_^&aFwH?^PgjfkdaCM00D0v=*=?UOb{L zJ$QGgaQ@ME^{cD;C?T~eGjUscZSDZ4occW^&>H5Hs7X%fHV^^2CwRNH2v)WIMLhQV zXxTm8E|tkkG<_}$r&n-~nz8g|1KuGMTqkSd?PZTsj^sys)z4|x`s`xr962Hn6TI`? zI-7y?G;ey>dq^wapbvUh{?n3>S|nsU33PJO_%7df#3_8)N5Eqml;Lts^^`L}HC)1~#eCtM4X}*zgln+Z zXLVE6==}Ayv9#`i2?GmUd|#neO$#pv@6l_S{8l+AjC`gn@vkbnS~A70(`s&l%j&}$ z4J`K_5SgXL)wJeb$KvYz+Kf1L!{LT#4-m@tRnu=l1Pjv(`@J5A~FEF)nDMfX$%MUAY+ zlpd;>9%4k#TRls%o+l}z8u&(r(}yF3-$jH5N(PBWDhpR1t2=DG_s;eG@k-Sy?^N8q z5b>Ms2DtQB$dxb#F%M*j>rKJP6;9t)Y4@2*dFvtwUd6t|q`gBKFPtjb`qrq~>YzfO zD&iA-I$QgdD`~BYa5-NZwjrLCOrPE@ApJSA&dUZ$JNK>WTc!pd|5%B=iR!b6)m0BM zXqxkNYplUl6yLgKpk7exS5cot0CH~dbg_0!Py^Co6@&;+7U6Prn4oic*R$A-utNsK zO?nz-!@!_w>f2Q!3m6XszixwJ2EhY7z`xm{_fQ*g#89|z;qlk;Z*vn#ofq;*?E~U5 zRkw84%?8VlIuxBfT`wlqdYIV7)-Q=t9tB=uKwoH`sE_h)HBjL=S@MsiIF%t?S3$5k zOZO2bvf>reWPBi&KL(1OmP6?mf%fIzsMz9$n`!2EFGrdQ;R}zrKx24xHU} zr9Bg$3-wh~Np|=%)xcEdALByrdFQ#L#yMwh?enlsz%AXsTU<3xe>&th!l?n~;vU$i?kHXcRJ$ao zrX{e60lb-&LUy3xPM6Xuzg4qEoGtIv{s`sU#_wz=hZyW9e%=^$;>3ER z9{9&fILQ~l0dBnvb8r9h!SPNlbXI>kG+VdN*T8+)>%(|eNJVd^)0@ItkBzw`Mka^c z&fwSg1mC4)ZE|XzL#)j7WX6u=1Z4-JA*bES_8t!9Q!l}q8*N)ehZvBbRRD6&xvH;c z@-7w1_y*`mZpalC`P+U#r$H6=&Kr5awEL>g-v`oCB2x%n)P$qo&eiPL@1;BfJ&!#e zcsITI+$7KlqdTo&imzn!x41m@o5;5^pVm}S)Z^ejhTiUN56sfk1jf~kiEmDDSM*rP z#H}9YK=2RT5MOSBS?6TBF%Y0AbwD-@!14!=4P^8$o{rVO6NbqoYM~+R%p;-VSCF>X zraIdVur!j>A6%0xacMyGJj8rHyEl56zMqY>2d`1@nbgUQS>GZyzcMR%N}72`A0^Lr zM=f_A=^8V9g_d4>Opa|@fVKFg);llmJ^HCE5}+2(f>f6VSWP^YE?UaDZxasN7g=c^ z8A&vK{*~!&s;8p~+bE?M8ug}%cJ(7{KKLn3@}PLTWhB!tX$c)hvcU9}L@%sTa_g zZ5MYqdOR4}__#~KevIIdhCAL)PNsl@`zZZU+8e2iVja3m+Us%0F)abxgcGH0-u2Qe zPSe)m;6wb{aiTXq5-pV58W zaqfjjY025EsTIP6F@JDQyNZOiDP&`QYKOQj98UOTh z8@@T<)i`0u_u^Y*0g&~CUlYCotE>s0>t|`9_r!_l#c$uXTa$0o_4bFmx1;Y=zl*Lr zba38Ne@V+y{q#mXM|eP;;ITrW&L+LlFUe4ydB-U_jsoI`o4Qt{Bcrc!)W~k^shL9> zGZ!+6ap5aye(PfqY&8Gt0?An!?*>#Pufk;h1yv(7yHr3A!N%%Aa?ykmk8H+Dxt=QGfJr0USTLnaiW%$CfDH#p#&2 zOLIQwI^UzX^FB)rRA6JCwop9p%B)sCk3Mahp?7xeevN&U2GKU!fN=}KNXnXg#7^Ts zEfWg%E*Ot5_nd-qdoPX z=@eXF1MO@8SB_tEy;Cza>4zIVProgQd*;gpq$Cb4`EU*xI)Q7Zc3VGqb{8&fLj*Z0 zLWO4vnzV#bISXlWwHo%1J%UHDz^;VGzg~vJBf?MDSdkTXO6pSXdj}! zTMw)s0X`Y=G5oi|y3_MF+$@#`a7Dlx^3i#B@7B4?pAd+-d)F$BPSG_oX<31A>!!}g zx_1P_P;)>vBh}=Pdzp3bU)U##)~f}qYNN+9mvUoa*5JJ^@CsC{J^l6pKJR++quZ5@cq59{g-Xrb_ElU|u0|^U+3LVXwjvvw{ z;izlsj~M;WDC@j>&y(fSt-uH?@ry<5*{p!r;{yiW`tmskw_lbJ;R;92eyWN7Pns^D z|04Q>(5{guV&;B`x=%uKhMTR~F`RyhsQB?u^56xJWbGS*zMqUm;#ZH-%8hmFTc!jkd zORL~7>LiP*=x@9b%R9~Ke#=yV{8r&nY6#7=ypedBZNTZD?a%(YddNU9JT!AvV={2)<&^vMg?8Tyc^!vB|ML`YuXAeLIp5C>=iAB8VVwHA=yr3C6~Zo{-R!j9ftQs$C)J z5?1{2^WiDZ?H8*+#)&_l@UU;)ZQ*_}IVosb{Xy3SXpQg_kTi(qtfz-w$@78JC!Pbw zmw&F8n(%|B`*WW{pJjn`!F?`D%NOgrt)F{0|DJida6Zsm&~{)uMzJYs>V0hSw$PaG z5x&w_2lsiA>#f)364*!Zy@ewx&8|&HV;fdLNd`p3(>fa7z{OFDcMw8eV#al zBViLZzY@$LV)-pS>_$EiTI zpfL}B9}M-ioqBYNVpEWxs-13Wz$BgCPO;RA40JyW%&j`#zOuYP%wbWVxNon`W7jB7 z7`Y_Iot$-IA1coA;n>$5|9{wf)2JrzZ|}R-3RM|Y6p$fNsZt9vhzJ-6T3V@pDbcD7 zGJ}!|mJkra5Qr8fB1%v!gG{xyq6P>Qks*)>Aw&!W6~Z7xNCJr@kPskbBFTNx`<#27 z^{o4x!}Ica)_KXBkSo`3*!#Ob`@26T%9<~J=NTYn;yuA=TKSyps(O?d%!A}^g%&<+ zzu{-Y+ z7~h)7-X2v-AfXQ(Mqyl?S7hgd%3j{QMgaE$UmC!XPul@?hh&j2tUio~5pwIkamc0y6W#VZ}CLd~olDFNNh1+&&P0 zwc+KL=e_McPN@&AOewv8pZV~oTPv2!!dak>1x*y@E|$q9JtrG(W5akiZs3he-wgve z-61nEQG5a0;Hm8!s6Z;4ap|JjkV!=kR;W>F)w2j~c~O~Wv`Jlg!WX=J1Duf7?F5}} z#?YJ4lv!-1T-6^LwcbL&!q&cjbJMAb(!Er~xipac&BP(2dB0ZsrGTG0M+gA{BBTar z0l(`1QbiSR@OpIP(8=X%FJMMU8nkN0+Tv6LeN3&)Pdi^g7^!6rRJpYU#$~Fh^v(Vu z8s6_RRV%2zPV~joG;EYMaeEtWB)x54cJ0qzrpIf|;KMYYPw_Wnk%jvUr(Io|l1EhF5>H zcUR-Z?PB+oxbXe~pJZAR$ zN|aIqmKR|?)|r<99tYI$Dft)EF=&7o{bZEiU1t)rA=;Yq%DV^t|M13GqYQHV$>Xbn zdGE4!D;_G#ydznU<{ynLm^4CTrtOK()z2H3Kl2C0O;sa{m$kU&^+12 z!l-74Gv8rBQ}(Jm{jTaaxHi%9jea=-R=Ii#7;T-o0>|){H^z?2A6B*XOH}!yer@NN zuOajknZC{l7Fc*3hkx{p?*HQpf%SoR>Xey^r$YPfeY2jQ=pGCi&zl+Tpu?!CY%#XUD6c0q@m67O>kBhw1gXe@Nqd zy_WWi622_`R0-=B6-lw48^J~1iYK?bw+s&+&*sy~y@^>5t-?ZaZ~KQSBda22Fz>#< zR`5;==d<|lY(5vf|CQi!Eh?F_%9?7o1XN53wc(_j)hp| zYdQ-j*ZfxNPzPk_5n@G5lgT%s6#kdP0y)R|{JFcT$c( zSFM;f<|7V}MClpMIjx5le-8M3tTb2Fea*FXKL?s+=KG;^LUr+i$D><$l#C(sBCzL7 zuJc9}1BeG!Kk$Lt{X5KYG{ge(MGj;t4jp}e*~u+hXgzo|BG?i7$QCe0aF+O-qd_4cOWw6 zwxnf@_|pC00n(T-?aN9ld!#?THoGuL3*Eb!;+<<0fJ%RCTtfXc5r=p=jt#>=z4g5@ znW>ZC;puk1OSB6C4M)P-JKskVf!>USaL|Q+q0hhG^7`5e?O>aU;S)cv=>qtkPHX#p zBM?xa=)Rx6g895Vp?ouXg!drPvA-Y4!B=2P6a;7H#NO{1{ws- zwy!lnx|q)&L7`Fs=U(0zZqu}8S2f*pozfZQbrKC&H*FYw%s)It-2dSr%CnnTvp4(5 z-|_{`{@6pX|IFh+X4hGpcab@!=7{pra?(?Z1v_1eQc{`Q5O$;lMNeJ z;~Phe$BIm9+-e3)?SlL`_*Dcmu{C$QJi4ZEcV{83$^LsqP8ktMkik_SfamtUrde+o z5MS;XFU_b-^ZDmkwh5TextJd~I7(<1s}8&}wH*5CecV&D;|J&u!8L`L)w=lz!F?Xw z2oPx-PN^qK&thDy#}6CcAVeokP3L>S>}95ALM?VH#=GOFbcKNdxdn>F)3nn0>78waYjCKi~__&kvXl@Mpr!REug=u zCIVd?Ks+Qw?E^o89gl>s^YH<&7l@mob%6cnu@zt77dOEsAF_m)CZ9fWw5Ljkc#*A0 zu5R{vaUm|3xH{9Am|zlX_|VvznQbKWb?HCc|EIg7Y2$p(qW#h~>Blf;*zcesHuXUU z2&(?llcMHq}0IeE!#IdLowpr0;BX#&(|o#1udA z2lWgR%wPfOk17)s-eGr>NuT6Ke)R)f0uog?iIVjoAVXf1wkIUN59&AG^}w} zV4O7;>%E)+cK&&vVY0Z0Ro3pMjX57=FX4roEa8a#=PMK5aH126uw^VA=C_{1-od%=(h_MZx*mxOjI5>nDz`e^@*I?p9L~LP#9k z|AWQ8ucv+XKDfK@qw08l?C|NLim!EUeeqy#PyX$*rsyZAvA=%4dFgm}(HGBO#NCAq z^R;v0km1DP29)${Yn;4>(@IFHkp_{ILdfvp_Z+R3-qE0w5~)DuIxlqH@(LMeaOQqN zCqzS(F2kE~S#Crty5YHMQv2iPR^=VX#`uXJG2-{+5hQqMw;_1AedDe~mMCz%1$BFZ zv{bNHZ7baCQk&cC8fnsEUTDI#u5cnQF}Z>h%x$+Zx!3Y=p{_H#^P0 z^tU)t_H`-tf|ZWF=2hCpE?beDN=+*wF3!x0uJ$iSqDW?H;^{Jh)Dvi*2LyL6pilu- z2P@juEj~96I&6CSdS~(H=feN*f28zmaR=5NqN1sIwD`B;d*fN1>2Cr+#tehl+DH@p zq;2*E``U^NiBa5#{j~S_+Y3i$X69U_e7J;ihEh)NQ!&A@9#d{BAAv(^abnfC~=L=`wQn@-CDggfdyCX_O(F1*p;j6l6B9}Z!)e! z$jTh|4m}i{@gj?xJ637#u~6^YTQ0B<#Xt>Gk~lSMjtQ=!Qk~U69w=PoMyRC z8}=(kpS1}>@m&t20<>8-3(GogS7DUa6)|#;N!SI}t7WjIWVh+^Tom9BBhRqUlo5q- zlN(b9xwzAo!rFz%{`40L4bU!vx+F8t_r5p!U%cdhfAobvcBKHol46Q!h*`MNG3DQX z*w7K43jKPglY5i{doKEi6`e~w+ej(}(vbco&84&jXpdTUZm6eW!6&OjS9CI5G&d`4 z(akZB_Onf*lrA=ZH;4?QsC+vH)8D$Xhf*)#T<>pcAimO|=9~ou%55m;X)lw+SV!K6T52^_gHgWGaOc2>fvs=MkIEYDmc!bmIPCaspr#Hz@?eeCRz|8B~#6oV)(XdqNjyV zimTuJJtFH_*i(?b^Yv3>y(_yA*a%F zgUXqYR8vFVd2VotpU?vENuUh}zes-s_#}+G7@`}c_V)10@zgmfEtPy9!%|sbqFA7y%#pW1Ecg+D}OIP?b6*;v7Pxh$b zLOJDPO9Neem}2;S)2hC_aM0@JPMx!OGq|Rl&oY6%i)sDS<8+&YBs&KTy&vZpoTT=8 z=2R^NpS@=h?Ch|Zjg>Y9)m580HZmdMH} zd?WxGA9|zl{cn%<;?M2UK1DpeO65ZHv23BQG?x`v$&nt+yKV@^h3Hv_g^}7Jtg?)6eyWxuD;FXs+M#kJ zggy$880eVJOtFm^qgo;`aP^tX5YJ=m^=y2HO`)})i`!*?(RNN_J>^q0{w~%ry2aCu z%D}wcIe~XJSh2PY=<)MhZlAZoZI>E`f-iR8^714L5t(laGkmSa^`P7NU_$qdpAfrmLW@CDM@ zdA9RW?9b$y)&%yvVj+dO62MQhlwC0$j$#&)(|00ZgUP|{rE(!+q-Z2knrLtASDO?i za>?P?;fKN|gS&S)#X1h2>*sXT6n5}f=$LZxsvDHC_KldYo!pjy#jyM` zD1KtL8HRLpC0?|!y}BB~`3)yK8?SlhjQhi@nG3BZj+D6Pu3;G3)ky*#sxTil?-1_6 zy{5+PgAPoSju+X2yLa1>?1YcMi$ZQcPBKehvqyMTkT$sgkt>L=w3O-F6)R~$_RjjB zA!;=d)4MaB1Iwh+Q{U@w`xblM?ph)$V|*a$z(zLrI-UodfI9hxjVti~drb2mxBku) z$(CU9hEeN1su$;+_B-ux0@3f@8ZBk*#GefAJ&f8s*7h9c$T7~U#~USz3i4fOn>~@q z1jy5;Zbnf0Ze0psjj+woYPemBeLiGB3r{nuT_x(&YIr|Z`UM3a5*jcPlbpoJb-^jVLZ8xa4soOrAUu#6!J2WxJ&QrYsAZxW02<-SSdt|$+ zkCgnlp6wrS0|?16X%&*bhTeOE`;*myyoHA9Y`g4tExA_$pcQ7Qp@8bvuAh$s>Uc#W=LcIiQh*^k2q#Jj zHv|BT8YMSU=E1Q~mhHsrz(^@>2-{jeLPAUc#k)CX-p3~d^@>6p3*Rv;%bZ7lzQ|qr z6Bv;6-i`5JhO__v>K77r$(b?|`Y8ykT60BM1%P?0>J1eQySK-RBJ<%T^{*XWQ&nTD zyimbZZ`9Oa>F8~f28dIVbQi%}O*F3#rnjU|3yq+5?o{f?l4@$F4a>Y8Tp8@Am6w-T zl29+UQ+6HAbZevHRN3Oy>LflOkmv1^}k=H-i<5-{2_n>S>_`cou(+$)RrM5d#LI>arD#9S8ctM(2TUD|> z%;!+$Zv>FPJF^tRB)2MQIh9lt4LPY!XFZwH7%42%MJ}spz5x~$;zf_Ikm;9-8Ynxe z_g0#cm7<*{Z8XZm#5`5Ar@vv4VQP{*{<)2}soO@flFl0P&|e*NN@Bze;%DQM-B2$f zz~QG@c*X=9R5}IAZt=&2+`B3lprtC4&7|>-@`0RX-3dlRgakA7w!Iuetonko?Hp&N}UH*goWQUtr3 z5|{QR`Hd&TE#z}`NlxHD(TaPM}H?H`hgu$6SDWGs3D^|W&)5zsDIIv9; z1@$0qN6X=HAI_X@OLY3$&95ePYu3G{_KU^Y1p-b27PyqQV}C26M3K(*bD@zAGty@V zCIx-B;@@zuUyf-|)e6GrVgz7>BV?=i?o#NYlC}#dMe?@gW@!_R<@_D~dwxwXstrW) ztGA{tCtA2~2$y^O-fjjTQcO}McLL``h~xf-ZW*>ZVR;0c7H~tL?Fxg-F2``VxfElF zD5}|%;95rgpo4IPCi3ttVk2ybhlQ31a5k(Npo17^wytpZdz%H*;}s@l|5zb}LFhiT z-mW<4hxq=MRNqWDBq{J;^;~F*p7Bh{u^~H#KaGGO?fx;VC*EPPFjQm;g1JJk%4Wwi ze=bivMRE4VHH1-$@@C{dS9r#q-;~rI9g`~WYKxs zr4E16@+usXb&m$}t!15`rr?X3ii-nb?Sl>}i8q4YP^<{8l4PwMJyX zrUrmggjmgEEemk!Lm26awpZFuPsnnC3d7S*B30{1haEO$UfJ2KlMmp1(grKRtnlFMxG%~)_Oo=mJ% zNNzQ8BbcLyBnv!Ww7R$q#B9Px)s++{w(yf=rAzpXk2aZG+Nh_#daeQ{&?rK-91Zgz zZ+%<8NPv0L(~sEt`e9N&-~F~e?Z6+VK7}|O&gfN&YO_b$HP6*m+f3QEBLCPHFRyRm zriBQ97GTdwd3%9hD^qn58_d+J$$vI4Au2XZo1`LCUrhIqmBLBYZ~kKKtS2L*n3cO~ zt?lqs3A9ULa_#(j1fk;3$?jX)G+T!H%Yl&Np2{Ym&%5`w?T}quK0G=yn|rlL91J=+ zzB|utN#CmPXF0Qbws(OV=;6~i6OPXz1m>r-$k`L8Fn(ZXWHvChJMeu-Iv?q%4wrE8 zWK%S~WP*=YE1KF5tvoDRwZ+T3nNy?y#e%Cxm(?Aq1KjX@zdZt;kTdR9?UaZ$FZdcc zLKPTIX41H~2rJEoB9)$rUxoA6)j%^SOD(V&+Ow30r69@Haj8SwKD1;y0EY!|Nq|%@ zH%#-PvKD`g)^o)=RDGGexTy}S9>qvdp=y=}rH!D?uSY1_DgW!tlyc2|LERk~?ZG<~ z?Tb!ao5W)A;_)9&SMe7icim2#!gXv|ond4k3!LZJ<}swRP)X0fTa1Nb7If!`J8PA)|E+;c>Ss1 zy3;RQE?JF~6L23vSM33nsV%WNt%)L;`0KpNkVF1g?z6;J+CgP^XG^>`{2C{~!{Up|a-T%^X!sLX| zj0N&4*}a_q-wTFoibBze8?m1OMzcUFt@p;3`nIX``L&}yM}lV2HNV5I{C3U;RB0j_H1uQ)4|^DNyR<4LNfenf zGRgpO4SuA9Us5)JYizqhtI1~9FZVA}x=lo)&0}ursZo#RyIVmp=Xi7~a;2TnrkzKH zl@l(gU$U-$p|sJwB`-6ZwD-y7s!Q5A&qYjz)I`J8$_7#y>pDm@b^klw%yt3>R)(vA zEYl7nsLsYFH&{45;JNqR>YJuBP9@f@g)}AQ?iT102fLk1 zIoiOX88x*Bv`OB~VBH>9y7ct_ea9T2Ev}sLs7yMTS@i3vJ;(z(W1i0fiu{K2YrQ`a zPKrccGCk-flyv4dsY7Sw$1b9aeZ;gjMAQ z@hZT+D_RPa^ZoKIe&1^;WHli}>ZvHeSji$hHH1tp(^FHW#St{6TErpx)yj3rQsBIQ zgb8mh&|gyt;^X1YZ|X{$iVr!$D}66&ICFtH z8`b4Z!1Q6MEQT8s{gs^#W%(|Dk_ebSM8_)Mc)Ca&5*TTL(PxuAY-RPiml-jpm9t?! z{S1WAQ2Rxu1$4%6$Gz>tgSUc10iA`_{DZTADSgI?^tfv;vfv}ZNm3jw6q6}YfztLL z_b>xoA4G#K8kuG1L&(duK^w%^5~q!nnD7!)i>)>&0I4u83zo)|&2WK18>sIw@2&T+ z)Tgzd@R+Io)pCO74fwef@2~Cjlp;vV35?3qHDI&ZA|>;}iVU%t2u-1c<^#JXChnymSXKgYV)aftQ^00Hw;&L><() zRXKBIO7&QO@XI&YgBU>asp$P(-`6mE_yxK6<05C`RP|CHu7LeZJ{)_wuDu0~xM~PT z+)iO_!2TwU=9By`;6#xyimFx&`0u?a5*nu6DvYY=Y?3DwDstL7_J>W{ zVZD5NN5}tyohmFKs}s@1#edl)c3<|3^8W{uu!=5%*D-kC>K~?$BFHW8Hv^L~a|2y% z)l_C`fu%jUEyTU1v-PwL@9#<+x1@1{^?R!>-m2WezczMeP>?cLLtlfonf@x9nBSBn+QKlI{ zN#L+<#L@}DWH~c~KRl^jiTX^DyO!bDYwr7Flwd7!5+Jn5%l)ege=RV6#l)a*eenxM zz9o3$8*t?qdcKV?@-jvnBTxAmZ_b{XSLiK%5=Hsx784K-ewd#m0F(&onK zL*^Me@wb!3d)af)xlEf{xu_Y+Fedf7x%E0)> z{l)~Enlu@SdjdP0{K~1!))tCyu*eeEB3ryh1YM%X&s@(fu>pyn@2LI*xJ*j5G+=rO zS%t^Uo&D4=2Btn|O5vJiEt`o^t16YOZlmONUQ*h}uhTJNKp=QSMH5- z6w$H9y2uEeYGHn^TNao2jN=gFgxKsKT&Y|NiV+}8)+DiE)|Z5L=As`zkCnPYY&6Q{ z0|(lIgCl!OQumPC0+K*LEsD{V!9c$OcQvL0{!?I}2xs~sX#3<6DhJZQC^d>J^Nnni#jTeTFCo9QXR_0r+!c$gR zMhH`*DjA9E6O6DmuhYdD3P)2#jab_a>klCz{WczP+UW&J&usXnp@Nev(YZ^@=>4_x zPHD@tgHO9lm|W?s^T~<}QOO%=A`;rIt!|Zpd=_i4Q**OoK_F@l&Ta}u6#-6@*))jI zzMJ5A)%a;h8RBw(B1-E3Q-#QZyBi|jXZP{e+bge|rYpFwe6Wkpj97)4Z8T zt`t|SmaYwx$axYGp~g1=!z5-ziKs&ESRfo)0X_SC=t0vmDtp#$-g^1o!5mDYovqgd?-c}3uL=Vr1T`cLRE61=z76) z8M4%9m#2ub;0(-}_|9W8yNE7Q-JYd&DWoXua4L3P*75;2n#>KVwb=@l@^td50HLbPJf)^+mbA+>f@T&Y z*AA{XV?4NXO;I1`Vp$k~@Yca)$MW_kJMD}%j&frmH5u7w%|*?)-9>Ii76q{)<~v_s z%+jL-M)P5bDwOA%h9W4Bsy5qeEx1>W{|qg6YAc@bcMw{mq=n= zgfbEqBAX{;wv(Jwf4vhCe0VV?EuWVVIKr5ZkKsD~Yz2&^%pC(E+?q=vk74qT2)H0z zoJpMkW=(*-$J2UHhM8{KW?8x5+>c3|I-lwkz9{GaF-x;kz{gYAynsc_T)Bd5B ziE3(Z7pL^`swS{6ZLp`q3GPZd!%U0BNrkws2@XR9{#iP^6i+N|DY5KVnnKA=C7^| zkT8#0<$13?nnNGlplR%fa92*U$Sy`vCs$Bgmo|GS%|0Ij``t5blaC4Xw>30#O-zI# zqPIm�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⪙S|yy={R+Lx&#aP=<;N9C^zzu{nS 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 a1%A{oN%+d$=*%3z00f?{elF{r5}E)Wy@MP8 diff --git a/assets/images/ph-readme.png b/assets/images/ph-readme.png deleted file mode 100644 index 9c38620ce69adb8bbcb67a45f6be085eba15ce2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185319 zcmbrlcUTkK_x4Rk1q6{2I)W&@8xTS-A|1g{q)F&K5K8DpkP@17=}46((mN_7bd+8N z3B4!u=6T{d=ld(~`~3G@*IW?DWG1s_&tB{Ptb0f6YCog6!*~Y|50B!xn(_-gJQ86% zJbc7065M}aeLF#T1mo4ul@$zp@po@-XV^>|FOhX^On^>6J{7NCG(9nHd^jqKY}}n8 zN76?T(tROeCU}S+c5}#e@h+?9k&Z{+pyeAlwOU9|H-#zJYY(jO0uzFxJ8~H?&(5zg zW!Ye|4IW*5Vwm%*dP(*~sLFiqDm(C_wwK|{F1f2Rzr4EBIj5?Q(>edHzZ!lvS=nlN zGNYjXwPkDd-JC7CQOcg@KaEFAG9`Tc^Xt!6R}KIGHsN!fot?YmJN3+6S@r+EgEo~r zEIGXQ_i;8p*4YfwwPBD)MQ_esaXXhc;&I{YNfQ!#h7~|Gp5{s~8io18`j*nrD zfvbJ@m{?dE%FB5?nKv%2tgU}xB5Pg~t<7zzlV4yh7WE{)|BN}dzUimm zjz@<)ghO`X{6D^Rb$)Hk*BRrT=&U{`(sK=aPZ4K0o25GT1)ObzGdB zK>@^(e*$L8NyRUWH*l-ZyTQZ^_!*x>rZa)U<^KKqjh{YQ;@%Fn?A!PNwet0qoS%~X z?71uUvHk`%Ba zK&gDP9O7VM8$kMmaEGb6|N0tH**@RsGC1%JlfWjIyY@UV1T?dLUR3OSO9a|c@2GT@ zBjvTtwWlHrz0##0D}ivM9m#E`WdG|nN?#8D8420BVIpy~G=QzS(0c-OkAy3G=hX=> zbHy>jM2)>58BolnwidtZm>M~kfaVcEGrA1@d!Se-+%|6x5L_ zL2elcx->D#g{HF9Kc6GDD&wrs?28p?xzC(l%aF8gLdH!>$vX7gz9@qE@(tv2+Y=OE9H06KI?v$72wpx8Q)9VBgrc`C2Q@#+B z|9QH$L_o{0)%ZkB2bNKUB@4}Xt_8j#(RP~2B-Y$9c8`yuDO^Qt0tSx!B|0})P!0w3 zVrp^IraIIF`Gy3MU>*A>;mF(Z5uuqb9lBP^A--$)sxTyd>RXYRCGoq@H50#w-ct?> zF`dI?5k*T12zA!_%0In`yKeZXSr`R&4~f_Di*s51FiDF!M?#-~c?6a)D=e`bVQ7bw zw{xTq&wKdPXle*C%3Jkg5iaK2N6O~gC5?h%5U=}9N;cnlQ=OtOMK*+$9{cSX_+yIrqMMnq=Za z#7}sUs#P)BENCg&(eqDKT4F4-R|){6?%gKdDiz4{RapY6TN$6_`A=t7J{z! zW*fortI-_wq#}}suUQW?WR7g%>fLIn?=U8qwl!=Th<=jit7#1`22bhIS9$!vSZ_Wv zO0p~hva@W2?WNv&h1d}FrTGF4Aouw*DTsQU&D`DhS~!Xdp6vfLQg{16%O>|5EI2;z zK9;>pyMhj^aXIwmC_I;IWs=E{vIz8%Z|fp=qexO)E(8f((Cl^BWVlbmpMC5h#syF^n3BY6 zj;H@70ywgg&>@=9R=GF1_2U_vS-eH)ErmG_ABJYhJ}0(Do@d!|Yn&FhA7no!$7jro z0J9wah@n4)WKXHz$Hp&4J^z$1CV?%@2km_Khdb`Pi`S_1Rq1OK?vk#;{T^EJuoxx1Jr zz33)g^~p%!{qfX(rqZaWU(mQe`Q$3@5*?K|_9yXE;D+Ks-0GlM zajwnu*OwpBG`|S`p2;hzS*g&*iXME_a=u6GfG&eR7maq7s|Hf+a;UggdJ{8!Qutf_ zfqQM%zkad)P$qdqaEi@m5RxDr>+cHGY-8wp{|hZS&9rB3)bc3CeBG!)*Yttc!Z1F!I^e48148#Apn4?4L;^_TVQp)RZFYJvwMdGfti^kl%rpjwBB;}` z#G3bGQIFLZN7RA0YIO6`>X(}yD6?IMo_K{U%R!9o_C}QlUl!1tFtc!y2wv}BjknJi z03@)P5An&-j)X2AG&f;`#_x743AYsR=j=C$K%K?!wJ{Bc`-@-oC_ZPF2=|=Z%2X;E zWx2M=Yu|`JHxrhn-;(AO##cT_jd9@;c>_UWW>z*RuqCdTHg^#G+mcXD>hgcWTNM=b zBRn@MeT#t78x#ICvf;Rwi$b;n@2858fUc?ME&WXWw1N zu*`|b9;>#THeQ*wL+8iq8yhuhAMEaS%+tzfg#09g??)}Zr7K=D6V`r3bD)7?Ea$XI zAL0MD~)_9!ZkB3_e-OJTvo%K!-?Jz5^sH;?ba)ND5 z>Vvy?N4%=!$4xz3wOi7-ScTCtKcAr~rk@IxUcag%oQZ#E=wbsTA1-{4|*#) zeWTZllOerGp8@xko@hQKWAC&jm_3;5_#N2w6A{X~-O9V@cU3*S`eY_uR5++yi|6s0 zjK``Pu%vh|HNJqutvCzWRIe??X2PRrGN**np0{vqENip!uP1XXKeZv(8DwZH;pOn! zSVlMDE;#n;pld1UW;$5rtO?ehDrtcWE4nhFe{Bwr^C|MuyD#G5nHB=Gr&}4>o=VN* zm$tpC7=tYl3?#<1j@ebw^wJK-qG`X0>0I(B$$H|AN)9C3-O4Ri8}&q(s`NU*_cfM? zFMN2dHe23+Bp+SrogL5etBykVz_sTM%dps*KM4++T|p$I1V~#IRn~a(1oC!oCLcuz z0g*+(OoCpC&#RG0BtnHw|F3neFB`h&CYEStosM2IS6 z99cT+en(&rws#0u4j3f_yOs{Pcnq)Weg4N@L!K#0js4nZ+_sATAFz+zmM;Ogv&=@A@ z3A%}(B>9=+n?wadEJD0CVHYHV#AO*1U2lF9%DT%4#BgF0f%2K-vaDZ~6}5ZtDx9GC zfG+yPW-dg^r*-L<>+NPYAN9e&+@s8<7ll#UaPv4?F~9ZiMNc9f9 z#Q5}g-krM;PW@H^-|{HC;ZKWkdDGgK{HZ!GS)=BA$-ZkkSgw1uy)`Dc^4qdE{OL>b zLW)m@m@vzVsL%ctk?fX@@SZ_UGsPiWR@1{*uyGQ=$OE?s9Zd-r`KPoxA)Vk=DbiMl z@MiOzx%}Ohh|ezHhg#RNc z%p}2V+VR>u`$Q4+Xw^*mXN{qDY2%J<0AWil@qXJLn8`b=wsN-)VB;q78wE4jqpD-w zZ^HD5E3jbSgtwo`|2)I0jc+dsQ(mepNce(}x)(^*WR_467h`R=;TMB)>zyXAa7*)5qw-z`0=Bdq#%W?J~FJZ{Z4^s_@Mk!obK zwt7YWugmy)Y89CFll#K)Xihy`ks+8QQ3;tDn-bv!Fv-r2i++EoSfUQ=c4n)cgm1>TU*$?9NS!x5*ypU_EWQWX#XjsN>ReGoh%OBhAmH?kIQdQ^@P8FI?_{V)q4q6ZhMHSs;$W9F?q4>HCc7BCiEo9btKuX7L_r#C=S5s6YuA0@&?Np z0No5O?t*YyTG0S~*Op8IaslSYv??LSK>?+{3e5Ty(%kwWr9=>wZVH_bwPUh)_tSYO zh`ihK+YIA$9?Zthqndak&-iTTOM_xtQ1(clrty{|=bw5{JqBzL>k8(p_R)3 zX7$es;jlVJ>knT%4Ki;l#E(<3_RRmQ;;RX%fCEI&3=YT4OD8o)M3EN_>N|fFX&zP2 z)fZAWaoi#8(7*Wpt|k8*UdmD+EWP@ze5s)6pHzd}M%H_$kNtlM}0=Ry5b zg#KsC_IgVO`0suG{y0uhN&hVn{(HAS``a!4TT%V5Bk$b(=VtubAz4IN`1?_PU|`^E z>9oVsAPI-TF)fq-oNDTEJ5NB*-)G)p0IayStkGpg-^&bHk{p<7Dbp`VMi5 z;lEe`%A^aNR5)45a12jr7fDA08RHru`_*P`pQU^lyA0pszH)q>)PDPsw*P9IM4|AwVJp2N?=Df?m#56dDd40ViEf4CJ z491}a=YY9Jmseoc_~7ev48IOif}OJQsjLGJlcJ`nP}SV`pi=D|6G2Lw2Lfw~>`{Y^ zO$sqc)7y7b!uQ%m=pQI*YHHHNFLm?{{%4RH{ugWb!JCWW3pWL!!Ap6vftN8Z2v?_6 z+?5;B+g?KINf2A2)-`m>c!*OSnUe_(tnx#7_GN$MZH9{ra}FXBSmOl+p`63Tpd<0J z(8^bIf?TePVMWzboyvIK&P#2@w@5ZD0>w{$ z2@<$H>cdPK8V2Gb7ykXgqs)9lW$DPRL4h?}=rr~y4Awxh)%R>O!ztB}b(<6iJccy( zZ;M39MXAAWxG1p((lvJW64fI4c|9%}ic9(yTsfC7S&wB-GI7{I%BMKqQYG%vr!;eM z=r_q+8m1cxWHN=cvQni$9;DU2pY-nbeQAq$rSY)6sjYK5#uZt8(rwGq*2>UT^JH-$ zy?IJJvsnMH_1O@+H_4B6yxTX9oE815&GM{&nUekUh-I^e{?Mt56PfEb`WkzO(hq~M zxp+H0WNT?5i$QFeul5o;NTbtmD36T%Y;Q%Hom{@%j|_4f9YWp&n7oJ+iKI7;zD+Gf zMQQCjy^R-?%zm$QtyhAM2#|0dcg@46N*T>z@&*5TB%|b*Hy!-Er;s0&3gCPYa^Q=J zSGl+Bi&4MJum|;|jpYzw?BZIn=PwSNkz-AN39c&p4yZhhIx=-J$H3LT2pDFbKe*Oz z^-X;yO{GdzVM^q~T*?GMJ)9GJR7wzuRNjBOqtKm?m{#m|&u)0*ROS5F)R6+iac=p` z`gqTVe`^H4H{_P0G+QbHizE!$$Dd1GSnpm$nXl5ywOi4Q58B)V3|>c!K&R+EhKo{( z+dH}z~~ixZS(Y)hPq?5sc5v*n_f9D=v#;+LKa7Yw;BxHH>T zCB2&TuCxa6ij6e9>RnsaUuSt^N7TFLF-20%kbBQ6G<-u~gd#A{sbv04KDY~3O@ad_ zxOrAPp<9NO(jBnxzE$v69N`IwT}fv_z-txmp&2NXF=M;t>s)F+hsz31r0^@k5_Dzm z#HUV1VZZxK3eX3_ekj3@wzjsPo#>V1gz`+d^vVrB!)jx>zWCfJiTe@Kr6QPC7E7)I z=!5rjbu4J!CRahoh-M_$SUDA~;G-;6RCjq3EEmeT2@uZ{WG^>8$l14bOa}7e4WUeZ zadZ#|bEaDZp(2RorCNrF~O-kUV22 zXGc6+DW~wII@rj4L0k0>*v*szKm5piYL9fIQ>|V77c+)ONn+msh}`7&yw>~0Z>|#7E+tE@Y>7M zV!LOm>Q$YcjBKkp+-;(VzIxQPhT(rk6(7(+699}L{RC1n+D0>T(p?l$q8$)1IQqLF z-Z8)@=u=91`q@<#2fbue#ANh8kVU!=e^1YYR{N9R6va{~?p9!Khu)7tG(k;n6R1Qo zFnnG6S(d|||2diNgOA=q^tlQHL>g_(8?#z0K&^t^_QK(5O`0w1?zBOHN&U#n`h}v{ z`6w9N!7tU2{3ZlA_B3CvFAs$71lzDnmUs053@0q={d7NhaC$$#g)NTzUU>dkrAJ}V zhN@r5ifkG$vX2AI+b9|D>7~%lA0|>-`J-#mdEZxs7;Rh%I?=44g=3nLA}cN}yAZ_} z5-A-CZni6_5h9qFJ0oUovIH3ETW8hYXG~QOcdaEY4n$P_LcvLj?eD~Dg1ZjClFfR3 z$e;`JUNP+*^~1=R9u!Bhw30Mnr*S&IBJ`j9ua8F=qC(lLf|O*XL#L;T-)h3H`I{E? zY-K!Y2g7@hc@saOB`ZqpRi&qcTEoH*d>PglH&p8Ng;jcUx;KZ6LLY?C_q89_#uke@ zJkWk6UM;-C_JLSvQ1sn@i}vbF?0`Dc_s%GeoNbj>-vAeh^^&a@(4usBaboUuYMKzExc+Z>fu0S9DJ1{ZU*RTkK z?kJS3miG4P(-!+)HXi(4*9>duPpWcBKaL3A8$KK z?D6D1Qd1Kx8Y6iZ(rz_{i$g;Rwd_B=l*j3XT&v~y{xa;?WdXTOhfa(J z1!aaqZbx728nXNr4kxV_7}w&8B^l9=8%gFnfR7^7mI&4Q9s%lUsr|?oAMh?d7l!TR zrR)E$LKp4BR;%L=eBm~ekz*d&GdalvA-+^y3ooW%?Y|^sqe!nOHD$**MtV4eQP#Uw z5%@^<4p=g_W6G5%ce z;=RmV!b^My8l~0#$9e6AT9d!)$-G>qEv)Pt}O99IGb!t-C0-Im0Zz-g+t;+ zPtvka$MHw4ehs0)9;7APfV@;(CY0$g3xS1p*b^dMoQ1cn0nrpWaHzgjvuZ}>omz}o!p!&C zeywO*ZclTof?+6-44R!Y(Z>_cvsxvr$@5Qu`&_goVDB&T#`cDe{!|C@nY9)F1l7>9 z*GvL^)=-jl^}<-v?xVy;>c*{~_YK3kETjwx|5Z4omba2e-7g4I@e}sM?JE%K-Gq>K zijE;Z63#{Su&LMANu%(A?;|R-TdVr1q$}QH<>E&Shff#wiKFNt9lDJb;kITUF0@UvqG~V$9-Y}e^j)>##{nKt*>uLL*yjMG9)xKaCM*ibccnEK+2*> zud|lYc}$%q8ZBr4QW4aa3QXlLygBw5A*)elkAKdVl2u+`$t!1H^4O*OAV7#-t^UE@ z2Vm4-U&~{mxGx?#4>v37ZQA`f>F&dJ&DT<&%~8%gc6&*TO1Sc9?V$FfRj#LZ*G9`u zkKF1rDyj#N&))`M_N@$|;Y{Hzvt^XUCL+N^MS{bM5(&BCC`AEYXQ%RiZs4 zqn{mc;rri$`|l{{XVvpPZCWhaD;Yig9BjcSj1cp-ckbSlXA+aOCt>?4&yPR~eUoA< zN)J_b;EE~R2jI=vuIFHNcPXMd-g~`$U;$sNdZ%mrl$7zvstI0{x{P=Is+N5$DE`6Y zyK363Mfx2p9tw;f6gMQ@hT@1LCn79rj(B6+oaeG(jL+ud-Yz1XMov^pJAVv&J|{;z zOV=uOUHCSLO68<`Z@@S~ZIyOl4;jh$@mK#TQIkj(ZKZRclZ%p<$c{qj1v*9sq1jG^ zg1Ode%_d?-nNi5~U9$(z zc0*$`%I=n^n2u|SyaJoP9#KY4zYi~;Lqlu0Xs;MiKOw$~116`cd-9GNYZE?dntuSM zLcXHTFU)<*Cp!}R&aHipQ)ts$=%|%WxXy>O*)M-@VpQ79qISMan?vqK{ia=i&J|o# zR_WUA1?1bSehWjMHAH?kt$u9Q=IrhK3% z9Jl;i3Y(I$JEz>{{n)+Yl-f8nSYs=FD(WI(?!Cod5S8 zfBBmDt48NqCb#wJFaLIk@4p`I=uS zQYXI>jYiMbt^o6$KZbAjicFGx#P$5!?##=d6fQ_CxPSBLWXwVXqvp9HmuCOMk%hqx z9@Zta-=`{U$yto~Myg^buFG#MWBI2;EmvU1g1hIuh%7{O0tg!whd@|EI3bTlrw|3L zI#ReBxO3kk^w*zJ!`1x>sS!`E5Rzo~`t`3ESkV_>E<(EbNyjH*Ayt3$yrc*q>)ul~ z|6LJjpZ$f;wH93>zb)(WgQRgi=(IEp=@)sNO~7jR_0@lD0#9os1yrH&u@9nZV_*SP ztmk)yb2({Do82EUO*gvCr=`9{v&jX420d{m1Pu*VXU~AK7eI1NoK=8Y@sCx&u?6Hv zI1q79R*gdghBQ7F0{4Wuj^i5&6!ZZJ&>#*zP^4mftq3=}9d22tEMk zuS@E$Q#B}lTU7>MV^DQ2h?DN^TWb{u)-+Oqm$1`x5So?}@XZD=7DH8BOr8<};u^B@ zwX>)ili$^4NTE{*6^TEPWF;Vm4;YQkME4c=>Cp#{cAOE3v}Op4it z9OcPltbkPYevKj7oX?YKH*%N!9fT~?H~6~{pqSWrV@`HloYfQIw36w}H!m$GQ;?-` zcqiKi>)O-45}=#oaqm%?Gi!8AHA}T2QhJe8;(o=JM19--15NV2S1&g!EhM`@N~tXy z9(hGVhwYR57v0b)!hdBVlkcqwQY$5+YyWI>*XJqP`-Usx6~nOyv51HKu?NV~c3e-A zuG%G<6u@cdgqQj{7b+h~O5RtikU{@4Xk3z0L_zV{wP*#y#q}cv4((Xz!yt^!?k@=} z3UAQjZz3SoIaXn6!gY^n>}fSpJT5cfZIT3?3Z9YysCqy+BDU0sMsJ?GT800Vod{JJ zg=M$+t;IN}FZ36+idCOZq-Zobg(ChXH90VbBI(Zt6}p zh>$c;LG{!-Me8v);nqCE`pZ%d^dnUJT&N$9TMZHUoV;p}L3h4euk5v1_e}dHNNm3- z(!Tn~`B~gUOWl2Kn|)ZEPdHK#sj|;8L;+epq8cS+rF`SJjPj*&+mT-Gm5*d&Sg)t(=+h93jaX*fk76Yqx4uN@uN-Z?H zHWGy6mTAtf_<;3=9OkshAcRiSQjmXRmGLKd;VqK6Z*M8*b8wEL-p&cJ8uR*4#MuOw z4$Y4tbL`6w?QBWC8Ilwhw(XDfS7Ri#+|-<$Nl4E(c(QP`bkSKPjL9#_(6K0=<)!vm zpKoz{gTOQ-is1c8%_JYS(?p3gr{E8^bNiR^W3{6uOp9AO%_ME_eFJ#yJ|t_G81r

      rjevd&_&*+hyi{n;=a%k=|A>?1fysnZvOf4bK&v+&66`%W!P7+0=nkFpN zp!@H`k3A*}(6F!nbQBy2k^J4=NKwa*TMj_a>#=aXNaHrqj6(u7DO+Y#UAkXpdg242 zQ-%aRZJ~nSAzP9=^rn*bk-@n1lA|yZ1i(V+y9X=4&kcA}op+-Q@89aw7j|h;<~7lh z|LIpyQu&@m5LYYIzJ+S=;q@8TK6wG5LRo5ZS`@$hzI&{aB_(sY`C+hvQkW(gIJyR2 zAQ62($eubC3r(-h5HFfEdOzYzn)=d({dHMiUvUNtfVR)DLg!op?dfRxEc;jPhuKdP z3Bjm~Gf~`NJpZH^ag=|>x)FDYB)AtziwF?ZtE-E=m-O+N?tP2)=;Y>8q}!5e zdAm)^G%G+JSZB}0wO1;;U1uvHAvFpg4MGH7b{GmOF|?s4P5HRon7igy8yMDBatFOW zG;3u+Q@=P~4rhwlr4c*P+tkQ5)9k@0N=6<0f|8}nj&n6EETThxY%v&&=Ei$I`8O|1 zuWe9~*<$h&c3@UW1?GI0y3nA1Ra>yVL~p#>5?r?PEbpYd9hj5wdva&0PoPNBMc`YVQj41=UylDQs3iyisl7 z+q`D)-F7`$gqz*job5orm=guH@1w$_(8{I)*cCn9Gth&=@t!d6YOiLx1(%5vg|;K+ z1kW6Mi3(|1q)8Ph3ep-iqh-RHQ;h*2>8pKuZkrj_$91MF$mZU9$SFJh`0RGv4fRAr zOlH6wL$IM=Tn!g)X6$M6sAf5C&_?_7@)w_({$5}7giNR9r)FU#snSDbJsJ!}q_qES zOl05fO9)_uNsrR|UUxrlZU4h~RD@pL`8x288{X{uOOh#l(zGi^I<)O^B2xkAfw*^V zj|Dsai`KZ~+ z=-tjM`8x$4QJ?NFX32cVe0pZN>$@&M`DRNgXCZa7AelaI;(Ri;-M4Hgi{-H)M|*QE zhmxR7ZUFYVj|eVADW3(4>Q~f-r#=-Dpl_pz|C-vJhDEyU9=*cwrligKLpy8Tpv1vM zNMU5ojM0a4#y^yTOwaX>fv)TfUo3#!&BpW$L z18oCFZPtiJL8gPCtls-PW;0OJJC)BEL(M@=t{0mg1;Nvcb1EZYvmPmAnDu= zcrS>bCl8Vii$bJWxGFC+^wm!kEh@#zSzzg1UH z&9u^d|2;9E#EYUepN42tilp>6gr3q%i3ExI={W|ko>&6f08qhBJVB}IF7pIj$-no3U{j7JCqjA73~7_81} zyFak6WUbDGFYa?iA9017N#|ACj8tuwPzYNMSk9H3Lz#-i()DrZgWQB20=u_ZuOP9} zm<5d5nJlLm$bH2^OEv>P{ z-;JogUyM28VYzA~tB|!bFIksrbwKws{>B{-uSLUOs+#_TJDMvo1Nh4s)GFs@sy@H9 zg7X6>NIdHDe;2*H+bxUHRBOP$QAWLB(sgZ!CBK>w0Or@qIiP=Yr{7&IcZzYjeC-U_ zv@s96#OOIwtZ6L?h+g-Gb`ra!|8yF25;wc4opRsXYV9=XNxn5DwufBMhS&)q8=QJo zTO};`0B@HLC%oB78IE!!pwlOUWIIzssxaowONl@EdYBELk=C0$f2Kvh-`ni04k_Tx|Qm zm_sAZebHAHlAq1@eBR-N6y89#4B(XDw&C`49k0*XrcH0q@0j{XF;Ega?(G=vI^rVX z@?C2#6~~;$s?UDMC7B~@&4&_uL)Z!L_I=Vejxx-LAS-UKq*|$07~T2XXJFt%ENPRC zGr}lv=qbw%G90BC{^Y%#n(CeWOW6CvL&!Uvai;g?`PEaB8A*Ty+@3fb3ufxURjw~h zu+x|e?LxH$lGQK3uG0O>F#xRtm1}XRIPiseD-JOgTIPiXjm7)PDqEV@H{ zy@}5sWJ}XaWdE#Gq-oK2W?06lqc&-OSaIWNja-lHw&55hkcqm_Msh=_PmjA%QaU6Yoyint0^_!X7Ti3Co@heUTUP_zbmYK$<0Pq;1NOqce2AE^TVeQw8?XE%5~wkZY>*q4k*)L9T@HHNfSjLZGDQy5pUj;vz~*YTs2P~gMZ-neNZW%n*??Ft9nptoLlmUy{|76UH67Y~KN^RIMjF)Gz$e>}s&L@K(`A$9Zx@7d*PkZ2u~G)l zc{d^DjJjpy(p%Z%2mdT|*dn$uQ-s~$ZOE!$Y%Vg2t#^7^Q^CSK{V!XoevD&Q*-wb@ z(QTbOZO&W)YkU^}_8$L>!r;d8{s;WObLYRn=O64-DU#()j8vkOv6lGh3psVO{lZ7} zK)8;@{l|w<`p!e*tLqK9yql}w>x92v|1Wm)=P0Jqz^V|;R8wcep~P(_k)>m;C0H+z z11WSfCS()LW5?n`J+`~{;3TrbIT z=^*mejvAD$duA&aWfaB{}{W=V4F= zsEA_<5N*9M{xMD*efzromz$giD44A`>LL8ZAUy+?)>O^r%E`y$O<{xE_i=_2mw#eEa)R>WvJBW% zV&jDo_72`sB&ikd#4vT$3bTHBCX2n-2HSdfGof>n@@H60QvwRD(6_^s97DeJy}5Vi z8@OG7(?SA{d#~~dAbB)bCX1nfl36m5VUVk6pe*4R+XvA|d*$ibSz~FOw<5b(j(p#ym6!s=Z4nkSNsN@|SSqD|faeynN5ET~ComqjJG2Ol9V)EILy$1%VEn ziwSCj-n`zrBj-WNGBfdAJ2vJ#t#0bd>IW773E11VM3b<$fdt;@M=|v8+@3z4aBrQDT$5(D04IiZMB1{2#RzDsrk|4wYX4cscDE>-&P?FXDqA%;S71eeR zPEThBsvSsOV{G%+d5&f!oMn~IF>tI(I z3UK&2t2~RS{^YJpF{W%>jQT`K%=<^R`ZSL!``*X;oDl|>kM*r|HP1FJ>Qj*z(58P8 z&$vZF*6+A7b(1*Kz3)dp44Zs55cPL<64R14`$S#`jTBO5VvEOasC&muml|#UQPt2Y zJg@BGH>4OrJRkjlTgx{&OBXqY*T~pWl-zG<+d=2m-jEB&!`Qo`d~r^wPR)3;C=SH7iPWgRvG>!YhP6sm40Y!>x% zczL_$IGCyuHD*NupTs0SU z@Sz)snrMmb-&um!i|r!auRlXoVKON#5<9XwECG|n<4&95rU!euoT-oK!ld;YgK@6x zF^9G|X#+ZBn5)(8R0io*9=;1Wg2S$AnH705*wMMkTIdvDYl~bIl*+;x;H2d7+|0dy zUQRWcV`Sz*Mf3vWIIlT$>M`|QKv#o_qN+IZM88y9K#m5>LKzAow<@xHg#_NPj=D$3 z8O+(rxhR#kuh6SA1o`StR=#BTw5ndTOIG%0A`v|uC{99%BUErudQkA45%DM7Qny{g zfV}EQc(ymm>9$`)Ba^_9N0N65A=K~%+>$%oN*E4%6%`O+-VGqxt?TC0`BlXutnxiD zy*=2s-L3t_!;y5UUJm(O?yp8VCSa8^^X4*M94L;L<}S9e7@&#e=mrwtiX~>US}r;j z1EHT!3~KuO`}y5kMq|dYOegPj<;^_|Q)4(3&)ScJ3}C@w$G>sbtU`KtZzOHdxTZbB zUszn}mA;^}Qya+r!-=jA{zFLRM|CC8{^MomL3bVGM`GDrZlA#oWwV1{VBo zG^s|m?5)r03lcJrrGf?V)_^+Gt<}&@2q;cv{rEzvh={Z*)BEGRgSf{Azxb) z3RDv_J~71;wZ)n-ubOWtRrjs<*X>WsFTIKm3H?$}uj(4#VS?7@z0=5fkiD+JCLlcm z?HnvwW2Pgnwh;O*;rDB-n0}-2{vycVv3*sdScM8~1_|e1DXbQYX2AqT+j+DgKaiXH zm^LvUti69;k=y(Te)>p&?RM5Gs-b8HjDE3;O!)kca?Q^9kpK!j_h*&S4-)xYOk349 z*DnK?@B1AbKd191YlJp~a~2|g=u}6Bd=WEl^VgE#t7qPDe1Rh~E{ei;i`_Ym%P~p$ zi*mfY@Mb(uytWcNA;6UK4rB)w7`0XQJug9C?EW+9>tGxx3_@&7rEa5P~nbo%!nK;88^Gl(? zlqC9x!zA9g)w>1uQ>H&FJ7C%0bZd-vRH{j>C50Fhh|ts!dZGCo^0!4QAbF}y>j@j? zHDWmyiKBe;deX=#Z3iB{wM}dL;tt_A=`MuP9659HC%ib9{;%^CoWypc?w)UXICc|t zb$`pidroj)qUcvAE-|dKq42l7%y|~j_I$T5vn>#DQecx((VJJ$Qel`!!n%a5A77eU zc3NvR2)CKe@gfzQ?&wa=I-C?%aJ7ks3umK=@&YkP`G=L?9AP zGcXt1jjm*Vz9r7b7Jh*f8ugACg1+#^p{&4z`cnFhP+4WU^|dxVJRH%t}Ag;yeTkmWx@;-^L3(5R8 z-HBcZcSi}8?nWLSC;PbBm?r&rAs82fd>UoO-@oCL6dO9z`{MCm%Ye^MICEes4v;1; zgn!N$_61w10B?mUKW2BV+`M+MT-1dfjdO(PY9@)gP@#U>rvtrp3Nt8FY$jufa;_#x z4smjk2iI>kTo4jMx8iAB4-NRHy$r zvlX#cW~#DEWf2=e*tb7*u1QV)&xx+ZlY>eN-`iiQ`ry`6kLsR@DEHJE!7mc$lZ{~C zHEUpLiCi)*Xdv+hkW}mR2`rjT;q~qG8v<>)6sFML{ zHxmIRmgZ+=xLnFDxBsN}mzI^^&l?`#Wv$!K4%Y^_-nuW>oi#(MlftXbiHQkX*N&Cn zT7Gk}r`&$3h(+W6J@A5|fy4mEwEeMRFXXvdaMkM1${?jn5aGS9ldp$WLHDLB)XLnI zCMQEh1nAVk>VB?}dZ~|QZ2WB=m07>5QeS}dJt-4o8z1KdV7d4dV2d8k)#dFQZePx6 z+r*uH;s!em0v6ZJ(3RcGH#BAR8xfc+kJ5vBN4~f&N5bDZvK2dX+Dm)`l~k~5%CSir z_-YGN>=ukNRJ6iex=Q@RLCG{ujFEy!ROv05wc=`>o5UsUi*HgEENg@_e>Z>PPTxVD*b?<6mS<_ zcb&uc<6|_3z0X|IQNCxtY|iC_jS_ukz>00rG8Q&s3X+Y<&iukS@@<1G30`W_26{wC&R(QWfnevyXPWemBljQ}|YI ztS={;+#6&{_kgY9H{P}+)7u#d5A$o{&8Zo{)t+7UuU;VQ29c{;{d>F*v=Dm8TZEQ_ zGhx*ub~=Ks8DvN?!)L0RvgM3Bjl<9sFpd=YC<;>3yb7ODyk;eJPvhfYAaob$kzK9G zuTdvU30<-#O4uoGOdRAqMFAe6=~cyT&rqS3=)Z9@>~{)o@ejfRF+35=&@o^bv~gip zms6g;;?q-cz2XN2?Mv6cox_uefF?SP4Qi3udnr3dSuf2rbs(x%X~$#RUl5jE|7>bY zSZA;vJa+2^MjvsD?!Ti;7g~MJAg?;@-6{!2eZ6xf?7Cic3lf~;FB9y!kKNZW z4bL7uXB-U=d@_Y8VD{@2{Fsh?F;_V0gb;}_F1^C9TRFlamiU@&=NKy5ww6ZL%J2m>bHr;tBB{%x-Bp2q5XGSi+mil=Qoz7eZUykUyk z*#M{yt$v^qS6sqXHDg^`?yz9(oVO*FNRyRhhVF_~{!fr-$G_YIYnu!Nqo?I0VUi2k zM&Vqn9T3#~4iy3{Y<2;Sh!^~Gl{i6~(Jke{cIb>`=b1Nj?I)Y#gl0oLv9N%G5tJv~ z&Sg%f;Yc$MkdV}{!n}W-fy`g35nHKKrBrl-E=|w-(#m*?Ww%W@@2)=;Bs$oZEDCN5 z&c+_&7WoxL*Xt+&>AC;|?vXg+J3MEs$G0!}&7$wz>#_(o3@ugN-h#rUBuC1|31dYe z#2lUXPSj^OjOre#As>@+M%QX_b>C5V*qc?EqPnTVKr^=tVTy?45|po`#n|ZY(5K_2 z>ch6KLZE-Bvn5#g6>%z0^ygn_Rr`Jep*pa&ma`e+W`*NTaIU!6>KRYxC!-sL1$pCE0yjq+yDGId*1R=f3!mQ#y1T8yHiwpw#S;Tw^cV#5rx;$&F!py6PE*N>K-l`NU_2y{SKid`R{q?`@ z#ljqD>Zq%;U4vDC-6(X+xq;#GtcnTxCK^ZZ_Mzyy zceW9T(H&y^E=R4ws;2p0Z6~{?gD0;9hbkhMKLYtS!{{eM?Y(fN`PYu&-{ZWA;0 zg-S;C=;w}ErL!Ei`>Wu-j3ME`Pqah(ZKb;^9~jRk(}k-$N#ekzYjN5PZ9nvoQ0PHQ zpnfgkLmo*38$v3cALpP0iH?6us!n*PNiIo{3(+kgy%8NP^>Eb0A&!o5pf`SmVY$kH z+lt^#3giKKLRDy~9~YN|Q{ZE@#|)Dn+Mm$Fm+d}RI!ZaUa2vHhh#U&NHSl!E25&Yg zA4>e2__aZ(+`T%M7M{CSKgcnECc>OXd@8fievPAkE0+>>c&E9BmUw94UDk2s>rF>l zdARxk6E&epi?~YsZv1>Y5bhv88_-$#-BdrlB<6T`=7QHq^*64gJkE6Z${z4`Vd?R0d=>aqbUz8T}}^YQzFPaAK)|+9%jV>#4>HK$xmoIe>2jMXVd}=F$h5CZ(@ZId*!u1~gA1@blH%NI* z7Gs6~fhlY??hj>#lZ4xiel6bKKKiGGpcP@i|EJqe2MBNV8FT?&^JiQx={er-dTHJq z8Gsjq^5~d9xzlr+wFfkwX7$4_gl%NgN=qLuesQk<+LZ9b>*JQZHJkJbvuZp1eDMn` zcVz;V>i2&I1Rx;V>wuF@QlD6sYB6k3q&nCrM3dT0l4Zc|BmX)rQy84#OuRZ!a0C=C z#(%Hg+`1=qx6Lvl)RM)XKqjv#p~fUgV(JakX(K|`tUZB+-!Zq=@1G0uzuqtKs(l;8 z_bXT|+bV6bhEBcBSr_MbO}Ep3J&ywfb=x17L=Bjd~ApTH{Mz|_$Bd8)?bm+Ik| z<`%acYKg~E^R2UP@QV<{*lSl$1c$&eagJ;MND6=dcCu3L=)qam^Btf6G@&}Z3{FXC-Vv`Koz;XytH+2 z7{0_{U|wFc@(S{{LSFK%UlxMCw4Lt1txTUjK8~HRuHtU$1@w-owCcpf#O>@_uB$=* z{{*OC#2~(678?6^c)QjuLNh%y1x&pMKS{!8YFFMr@Dx1+Y?4&6pG+6r7QCmG!c=f6 zcmtPcXekAP(@P)5OAdw|%QWl!I567nUy_iM{Lo;Sp0$v(o6XT?Z2~X7%!@xKX8F%> zyrviM_LE{6fb#Dq*}#Hya2KG)N2T~WuS&ws_9G;yEVH21@v?S-|$)QTTHoccNj zrSjSTqlXoA5QJ-%tC>5o;^x?8>(Gvyk^o4Xv*0(^YY13A0+@+$e0TjFo}4){ODz0v<(IG2-K zNaIs-2JwSV_UY0+e$FJZJyq7WTZdt2z@#~r?xcA#5W!1+ESv^Z!XejK&bN$+hIqg3~X=p#e*#{5d_Pe(TrAR z+wAlk>F!G*{S<@lLSkYm*v@{~A;qI_3pBE?Jb^1y_T~uW?8D9zV#I_V6)pPxI0|p3Z=gAmZ7tPPSFj9!5LtB?EVM)9-Fe z8t=KUiEi)s?vzY#K{4p04g#TN5B{r)lSBF-;*1p;ZdI750gaRn(Mm;~bFt=#5Dis%+v7 z0SmT(!x5<;PWm#dSae=H>7jA*^0&BhHThAK%C!VNq71A`sz{XqL$8cpZy^5*UM@@w z7?9zB>ulf5NBY0^YZ{vqJ1OKi;Yv(3&Ws~nv=%JGb>+MgJVPl!fj<@ZwhbjL4+M3P z-TFgg))v4;Z8}8zm8)ORHMkj#5Q@}{hmhkcr~#@RXG*#|LU{yf|MBBTT`@Ju?uMwi z9vjx|D$4OKAl-hNhPr0JOs8X~ZROhDsY;rm_DN923$8a)mER$ECh zNQ3kY&eCeV&i-Bc-@Q5VCT^8~I_0%Qm0k+XMlj1b@^Qp#1+TP(d$(sdmW$dbj|g)r zr-=$wAGMb?YKm|f65K!fMDEq>5pp}l$jJC{>#(LdJ3Dxs=62;_CUv{hc_?j>9}XLo zo;i~RQhxjlNE)QD@KN?PdjmZ^>L~hf-SBte3gOaM9maRBR()>Hm!m9Zo<*y?d1Gcp ztACOjzW%KI+Y>_D2oz1aCUo>L`7f8Q#JJf{r?siSbnQA++Q6(?oNR;dyXn4$u?ar$ zp@zQYwkGm;yY=jfF4M2_5u;FAZ$`P2;#<1z+Mk-F+f`f)E-?SNm`77lblUT`%L^9tjP4K}jUnn-V=H7Y9 zHmEy)M6~vn>t4RVH~0CgKY}yK^T+I-Gc)t99lgl|x3Ifp_U^K$7Z}OovzvHeI zZ|VIK=@0@fx*l!65*f82P!rXOX@`TU zQ1;?ydq6V{*XD^(O{Mh66y>|qS^t-7Dh26QV0h8`M^r9K9o)Ogdz$i$Z*Y62W-rv! zo1qjh_2IUVrH}fCEICq%lqU#IQX}zes{si8Z zhF;GMtc;Nah4Uxz6u_=|+G4BW_hLTD3s@~rmjDsX_~K{a1;CbpvV0&G%b$P0#V1@Y zT)OeO^6TN(mqPXfertk6l#Y7g`i{ahzAp%^zc-Su0YUjk>Gg{Hnst>jOs@B+>G}|H zdwie&)iJq?CE=fG@Bs7_A^YKk!bv*~hy?e*)|d8Tm5}d&Tx^LyX8=AK+7HVX+P*_Q z$puZkH_7$DFgDJMU;a=~MVUdVO~TfuiU7vM8oZh7+$V8R2ds^q+^c+6Ul%)5L0y?M zk<|j&$zmfW|I*#dNYhYcbz)cI=aq;w{SwAi6c8+R#r>p4czFn)wuibk9i>iJ@CPk# z;hP-mVf3*Y_Qz7+W3x&7k zqLgg2h*@pfeBNfJ5lQp4GA&pxuQP`6m8)iQp4;?4Wu zeErMDiyF$7r>f056Xrgln3DB?`J6@T`PMZauD~w zHvU_HjUR$v&S=(zJ)Nn56%qDO$;C*J=DRB$=@oA>rVV<|o z5;X3=cTt%obW#P(>{p!j9(L1$)N&tvmORwHH$raFnoFHEiK#tNVO-F!GW^Im(8u+{ zY4lHuU~i|DOVRGB-DI z_E;@Uoc%@I_C*cdvXd?!@6gbYg?xEpVx8^b$nkx`3eIFQ+?LrZe;(e?KInWpN*pd3 z!pqyX9OG7&ABN=>6lBCZWfx{lmX}QvgFly5PnxmmoC7<^;p_hMQ~R4!+n{Uk%^`Tk z{_4`+oOj9kq@z%^@JlT%ptLD{9;4}YXTpi!O04hTclwZ@1Jq2z79oIRS2GO5ZFS)W zz4;?Ls?I<=iKx!^b>1m}I^M)73r}#B_^wsqn6m8CFI#Q%^1%WI?(Be~OyTSE+d_1S z8jTd>V*663cXtn7ry_vH+pADq6%g&oQFx(2;bc-HQ*U8)Fae+u%~U*;IBy|0=WQG< zuk%wQU90PMM?J)09YW~UTrj_Mzzb^;G~qUO7<{KSN`BPa+4nx?eBJi7!;=HdDs;FPwLZ|Q#OpE^du)^| z$D|0@AJ*k4j0c*!f?uJ;Wvzs5kDcgC*(iUs7rK1zM}!>H>}bti&@Mx zR%9f1NiI#cuWzvv^6K8LJxM@r$7N?m(O1!nx_wwP%T-LtNQLj6uPaC<6*b=MEL_7d zb-riLr_)2%C2 z#|4eo^k=#fm5e5LR@q?O^*_K}*yLv$IshVqFAj62u2-x&!3F7d7OVPHJW)#qN%Bmw z%bXLL%XYDMO^Hy7acBPE_VHeuE)lPB?Bk(a$|bp&d(Ty;I4GryAvB+sCrJC9@@zw; zqY0-M-+vGf#@{IP)*;Ut_Fz|S&LGoX?&Tgz)vhs-iV>~QF?dx{hail(X$8E5UlEVs zE)Eb#@V#f7?G?iO$9QHPv3Ft5Y^oa(|%dX6W}Wd zCu)jc50p;TWb^9czppB{79h6aMl4d2F{(tjHiQ&Z;c^qIludfz7+n1!SB{5fmMA*X z^1yrH%-eOQs75zeuMF`ub?6AR(_Zmpd+2(*;xuu{>lY9{*mxWH&6V>Gb(Nkt6`tOt zXn_ouR#7GC3|JRM(H<%vuz;zwg0tB?PlAXG#CxkC9ey#~93rqEKYr+T-9f(>oO2JD zbDZhhKCySNLLO3sYrJotnsEuD>p<2uKXI4O{^AVw;6t9 zkycUDIxes4D|w7Vapgm4r`0^bO2T!C$REvnOe*TP7Nj`Sq!tKPYn9(5x}Km*^J+I zYCLAbD)si0UXI_1a4%P1uIu7nXSjTCT{z?%sP*8mSKzuN$M=4nK$~HLNkx0%^I$LN zbg2KNC>m71yq zchs8ow1>*+acegZ#g6i2R;ANKHj%7VsfAYeFnd);J-wL2@bxdZ8y?Ird+aaUj&7yq zW&m&{=eYuAD3iQwQ=Q3^z*?M+zf--9cX;72JH37Oi(lWQ1A#HWsggfuw0f$H5-exb z!*m?BD48J=r{SX4+pjz!Uf1V~H&&82&M3+>Z~1^=_hGvRY=ZYm@?KTL9y}0eEARw% z)(d68xvlr@KW7M{RtKbM;NIq>KKm`VcTm@ps#6`qysXTU#f)_ZOO1{yLV`cG(u8*J zatzAZ_CL^zdAy`^2Y61Fr@th;eBEF?l!K6ZrFTio6*F2nS?)_x7e4A-VvtpBg9k|5 zm1OE_((MZ_&US1J-GQ1LVwK51!^XJy4Tr{4Rvizoup`P=W@ zC1@)1PadY06}mGUv^!||lhCjk_gFLRkp85ZIWkA}NzL#yI^+<}k$e5d z+HV7gShNz;4W1~y{L+|#Ua6pTdo8!y zUn?=HDOIZ8!dzl|Jb(xeIbH)=c8P6?$=KZ)<(7bZU5VZdhSWD`~c# zmvTUQ?fybq54`y>tpC6ox0iO|Nhtc3+GAM2I6{s4^yAO?+2;M%_a?)xEP>dDN$4

    2. %z6v_D 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 DP2?10 diff --git a/assets/images/ssh-workspace.png b/assets/images/ssh-workspace.png deleted file mode 100644 index a8318dba4a3e23d844a6f56187b0e47572fa8eab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 487773 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
    3. 9u~go$ZdF^6fg88V4ZT*PyWCzBBVT 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%0AFu{ALlLf?N%W=&Ib;W73s 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�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 z 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%0ASWkFW8rYfM>Ttpk0CWA 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%0A-BY3<*bLv(^isvlGT^`@4Zl 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

      srJXzS9QUgzTpBa>J=Y@|Gkd`nCI$7m4* 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�W6v~<52@g8%9Xr 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�Ec$T-E= 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

    4. USkXSbxBmS$2u@eCdtpxt_JweWd^r5Eua>K@%?cjuZ)#fq&f=`XIDTUb+vn*aa_#vv3c*ny$JA);UujN7>3Rv;u{9U#HlGGQDX`8g!vyTd^g z2$-CbU>&jn0mNYxkRS`z!I3rpp|~qJ8!%$Jjhm6d`%(g6x|Iqe)?2v^dA_HQez1bO zhc^L|N->gZUrtaax=K0=rm0-&fwCHrI`hIPaytY92m&%XkwTN^<&~RdA|^pI72@T1 zkx$+Wgr@2sP)0z%4?+2{9X8g3=A~flL9w-om}hK);`%bV6CykWL`T~tub@SnV!W&YdN?fJ<=63Z(s`&Rv{b20UI(Q5`dtj2N(&i`**h>8xU9v!XX^4 zq@*(%61p1-fFKGW0l*>u0SN}0yA&?~K>fH8K@-A390(#CMq$=t9f7f83m|w310WI( zJSmWX6|!O0r#pf>$|baczpq=PSK-ygK@*1{?{nBpb%z z*&zXwBRIA$;)GLJ?&2C|tmG<=$W9nrNt7UMSX+%0o6n+Z?Jy>BCj!d$Wd?!7G4{xV z5wj`BY7>??1e+5*xH`*@@=-2U>b5$YbXo!BmLt1(`}OjRdjQY0f3LlQaxk8^Rk>0oh%a<>IDPb_ z_1?nu&Juo}f+kG=W%rH=`Sgy`C4KD4UNMhtD7c&3LnOgLItny_+d<+tB0&@a+^8Fw zIw+c^$$O6*A_^YZyZ0Lr_MVrdJCl)My4zlly$}E-A=tTNOtQef36#6Dfbi+Q0FJuX zu{-cJK^vf8+acko`B}bUdK`LMA`riAr#qSxAQbK%^W~d;$gm|uIh@=?34Z=yk_-T< zxls>f291?Fcxc*)S;iY8uf=i81%jB*r3!0hlGMl+E{IDtA_!i`A&6PX6rvq$Py$vn zIq2v2Yxp#x13-$|G;5x#T!G0aBBQcq2t`UtCSrgh$Zt+Vh8k)$(x3Y|ENcK_%cKGX z+m$KM${v9Kg;M?{DX`F1MdD0@p0w+Tf40&>+ z%9bTzzNCpWq{fvkRo1M@(j>`|B!MiH8PugpibyLaB?&bu00bndLPTJZs7RC+k*0jQ z(&@{kK6@%9i#Dy=wQSqEeG50P+_`k?+P#Z6uim|U`}+M0SmnqBXagWxmkEi=Y~#YI z3l~ltqyiE&t#TY02!d>@kYL>i8p$Y4NB|I)kWE~+aM;3SgMwsLVv*uT0ZAfG6y|i= z6pz#*E|ck?0V1u6WHbPzb&*Od$PGkO>eZ_gXBq`bRJKgnL;(Rlxd0MYvkPR#x>VaZ z&myz`sY9Z;faI-&A)Xu=Aa-JxgG=IHS%4I_{3C@$wvcjG61Ld$i#`8ran@4z6#yZA z!%0A(X{On;g@L3Lu*pCEVML#XBT-0UE2NMSSc_}*cj8M4+|yx<3*J(IJrY5rpo0z; zNYEw=X+@9%G+G3J6e=!BN-H8g$Wj5n2${q`I!Z+1OI!TIlZIs2GgtvEqSa)XDzc~| zDVww+AcUpZq9KL_o^;EHB@r~zflf{N(kAwlXd!6+o%Nq!CPryrNihW#C~;9DWnq0= z#Wd)I69%fGR}nIr)o^$Ycb|!(_7_r^Fv^&gr>K64lv;|q2y3je&Pr>ow%&?suDZ_u z_0>`UKrv1xKp?7#I8k_pL;}NZq7F0&AfZ|TK!_ravH>I!0T3r4F^+c?Eo4-<006m085*%D4ArE8#VxFqE2{G zjHAV{xcxh9SOK6r?8V|FvFs|7eM=EczmB8Hy@^6a&=wC7R3(r(j%iUs5+soThin0m z#4l2iL{R}PlN1D>9I?11QB`gN5m7o3BmqL3NYM_6yUt`6O=RKx%M>9O;7%(*BtY}9 z04z9j0#G7(;>tb~=+@66*~3Kv3P1^Vs{m|qkEA4VVvDi&9Fprc(86 zIp}D8E_%;xZ9aAHzW)w<@WKyIJYa{$SO6rlAt6(7$Cb7PX+VrJ-xiTU6bWMRQLk8j zq+}B>VM8jak$&-M<6QxaCGqSQvn7DU7QqddKmrO}7YP&z7`BQwu*shZR1xMxq6rQn zsE3IFK}UVe8I}ajgQx&VKpUe#LJ|TH0QYDj3X!1RWWsc*@{M9Y8!=Vqb`+8=xlB(0 zvWJtB#5T1I#&H@7i2?$2Coyg1Kmq!PkN`l2v(b+td7@F3?BTNFy~R@hovK-Zj)D*{ zEo2KYD+NIcltet)!-`BRK-_FX5J<_5LmKj7NdAE!k&wb=Fa!`uxS$Z;k%fs@l#+o` z#-*!`4QYc4iJo?{paK3#Mmvd-Av+h8Fm@$ViyR=J3h62O9q&+U2~`OpdC5ynN+ge} z2w^O_Nku9$QW^@QOD6QGQe~w8R3Qv{rm~eGu|+GAQlc$yiOXE-a+kdHm4;eL5Qd2Z zGNM4lMz}Rhaj2tY1t=C~h6ymyJZ6}}qR1wOsg7(&i**|L+Q`gBEy6r(n&H@20!E<@ zabPnXK2s+)p@V>HMkY6i*rsW`xjzJ;6A}7UM?DKbt#ty7UXX$RrctDj&U8jb3P2dA zI>Q04kY(;9z$)3dq_UAM9jF!maFRtx@sD=2LU2KBMJs-Bw!%<^qb7YxliCqd72(W` z!(mYXINFW{@yT6*N&*02%8_5Ft(U&s)D~bWQXvsU2@Pt6JIolfsG$fgKw1b#3($_H zrRrx!`Nx<-)Q&GXqyRxM>3|MbqgJ%RK_)Fw#q@YNf>>#7?TFAsETW`;94I49Gbxuo z^pJ-9X|NW#m#KnaNl>W@Ni<0SVqH#HVzl?o+>6&htR#qV zA%TQQWI;y4%|sMdG8jl?Arg^brA|(CPc1~Dm63=T(=wrn{JDg;zAZ07A`#w9K*G7` zX>MZB16f5%p*aBHZTEm6g@YlNB}hnbZ#5Gj^!|1>N$M>UIQU#aE$SuaLnNgnH3d@G zq7^JsWdfAciVhKk3no><8cW+LG(E8ZO+v_uLh|8}d^lw)l0udMWsxnARB*#br!RC$_FN=j1i(xS*QV;^Smm zaBOV2fLM&0tEEcYVr{{wG}|(SZnC3~8m_S?!Zh+A7_` zMpCLpNf&NQirasa5F(bR>bMA6+p`J@M;C;~VZ+&@PUn&pk*!tY%! ze2#o6HMy5~?~khmD~@Ei$xn{*l;f7(cFDNPFYfBG|Ij4}!IQuy$dJXC&t+2^w^grt z_v&x!eCR|ky3vo0^rS0YB>>j+((ttOs7rn7RIj?#i|6vIYaQi1-@5R+4m=EgJ?k>} zy4lZ;_Oz>g?P~9Nv&pV=uoIQ#Y_GfB?~ZrBz&G!FpDoJ+@K%hI0`7UCJMg#wB*J4{ z+}cKMy~!d0PADGVf7ybVMa`?eYku>b@4V-Yjx#AJK?+D7w697Ik((naL}_GIz+sJ$ zUh7Kkc>PBn|Asub3_Medt;-fn$|CV`bPCgcO2rM;?0#$8Z2t&?;eADW#v=0b)UUqv zuaEuWar77duu{{2Ezx7!RjNgTvghIr#%PnJ|33eS8^JHG?0}y{^>9f789Jntui^Vu z>%W@S770a^#}=)^QYxYn5-@nX6FP8JNfc6NOTh&+Ru`EgZMlwiM#yN%od&q~dL3 zA%mKdZ5CK|Bp4wNq7<^Wa7*)l=*K&o5+Wg|eD-#PM6^n(q)Jd{O3%lEUkHX_D28cw z5-oK_86r0l#wMfF1|qdHC2>@?fMF0(WF{45DX~VIU<>U4Au{nHY;tCh#WS^(RW<_= zahQMsa%ChDh$)j(2{;%Mh7kcU5(p>(|4~Bo$lro#J1@2%A zoKS6QNPGlA2JO%WNw5VH(Q7$m5lWB{Y@!rXfQecadvN3mPed3Afe!)FgkxM~YS- zo=A)uh9;`m4yU1n0l+v^#!?{VQ3)WC2r)%DVt}pShZB(|iR3~;b`nysA}&-)Amu`( z;6q6hBoomg8$pZ`(F$5)O2Jko|6#>ZRMsJ>*dPT`GaV&XJ_P`!08;J13MZBTROBRD zF*YWaG5{ba;KDXZKnnJ73j+xe9MvRVbw!6mVk&YPq|jz}@-|CGVj*EgzffXTIV${7 zX-Sip^~jff>6d@WZXS4%53wU8_6t!35ePUWN=T9+@er*bFNCo(ivlND^C1nPR1Fa~ zpH&l>nL?|?R~rct6BZI*LKt&1CQ_g?1uz8%SpfggG##R0Nb?X2Az>(!0LcgdU1K?a z1QBHbn+uUsw)qPrk%RW}3-_=!wi7dP^ivfElVnAgWVMHjnGqzRgi?VaTA@M<5h6RI znr}EG_yt-5(UyUBawr=7XT2t33RE2W(X0tITEHBMKbn#A)^5H zfFN4IP07cbg|eb9H4!zF5qW|jr34|O0z*uRq9y_*4Y4!zbC9|D5A~xeQb3haS`mjC zLIxV8Sq3MSn2&2k68L9I6Ð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 AcQPmq~sF$$DfONlVV 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 sFXhaNxl_MqaPd^VLJv|s>u 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�R$FCZ?myx7Bxoy$^>CVS(-W(kGdxT@FpZm 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%0DRsEHcP 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

      Y;ACm2g{T0gwSkYkytufP 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

      SI*z~)-#Y)QDwb4 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�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%0AECrLF1P8j6~H1By{qDjB;kv;*-or@ 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 b7^0mgNCSlA$zFP^cnVKZO(m^ei?{a%$!9 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

    i&7 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�hVbqWrK)uuhl+D=d=YsAefBWyj@o)hLn_w8>b< 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�}d3R2EY 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%0At9{fXPR1(Ffp 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

  • G&IIG(l z&0;YD!Q(EjWBo*K!%5+m+6WMC&NJs^`HdrCH99dr3Sp{OCuMvA;jUj0J8HRTHwn?< zQ1Yh3bw)E`Z4zEPTjOZ~6FpdwlIZUVoc8dxCn8*CYgo|%8+Fre&X8kt4tdGv#1UC7 z=0{hjJpG~N_O%spXI9)f$0tg*K*1`>Z-q-jjRpNw=Y_6V?^%{5uk>#oC;hz|KpK0Z z{^)4*SFBR+IMN;^1QGHu9$~>@p0d;ldig4ikVR-`WU#UV2a^O-wty`fH!Mjz0Kyva_`PUUsDKQzkRk7l3qsTv7rtZ6c`_>$r5pFL zc*?LkBMae4TwS3)kSu9G_WO9q2S?FWqIwI+w?gxCOmR%P?~Xl4B!ZN?UA*`7;mY9% zSmld@=(54_KVhbFsnb*D1mWTqD$|HXsifo!AV^+1Nw)-`(6;Iq98;?#$P_s{@zust zVAiuHlzvG3f?(q8gIe~sKu%}rACBeCi~%*Z99xkg3=9P;2&H6C9Su7Dan9&5At8q* zKqzR^nrmoGVmh zUSx?8;(ROfc4>%xMm8xMBErv|5su{2UglVG{}VTUNociPe*ASI+OHGAK&TPdk7^?8 zuz?g3A#Dc#s77O%CX94*7%R(JMa&}paJ{DW2dyJ1(M|(Nfee;>Daym4bAB9$dkUoaer$zruNR$n+8ODG(HE7?#qo=B-&p)=l4JekU9Jdq{YSTdc- z;dH(=-dH-DD-Z~cC)HFoUr0?rtUJ+EzF4YID3vYMT(MlK(P*`8Rfo1(YcLprC*4xD z-e|E{p*z`9z1eDiFp(|YTC?3rYP+{R*;>2P>-P-?U#6{YZ!ipnMsKRE{$MnYL^?;N zz2Rswjm7%+RD0veY@To=zHCR+*CV=hoxVUA z0=cfXyMwVr8vU8B_J@3)D zbj!nd3G(v81R1uo!$bu!s-q+oHOr%94YTs26dl*Iqf~JM%mxQiYTJu#997kVv+PQ;+~L>fs_}(yy?q ze^gGDBl*gCR_bd+eO{)*X+>S+TS8riTGVoWt^@@Fthda`ks=bTsOqV>sNox*D66f< zrYUY0l|&hCRW+o1 zMcuRjB;Dhj2!`$ByaYw{@X9SN;Sb%{45R%%cfPkkE^zm znvd(Qm+Oz4K1hZ?w_w;(f9}R8YX96%vETf8nB#wOeOyxi>EpJjU;FvI<#zM=vKz|q z_w_LK=ij%}(%Qf8m#sH{KW;}EfPWrWe*!;WPYAHF-d}FMzJaiLAdnJ$U`7;P-(~W^ zFvj}6bKUwQM&*H1So{E2x(!gOC;ZMn)(`J_8%PM74-l6Sy2q>x+D`|ARv#Nc@3;+S zjLL^Kml(v}xDDZ$%7=Fw8^nLV4HbYbKm>+L3=w1Bg-OU1Ag7KEk#pUJD_l-N6-o?K zYu!a?OckKFjt$d$-bEU~7GjP{j4)^1MOnxcVy}*kuyx!;+ea1Ro=A*xZQRAUPZi3P zl#TMe-^KdD77;>9jtODk$A!rh5o3&xiE-V>$3+#9Qb>v)DBdTeO%;)|kB`fF-Y4e4 z7E_8#PAFyECzZ(*Q>$|}gVfz8*F_c6noCYC-jZf;m->3G$mN14&P8nf8 zq>agxFsF`BnQ=X&&qbB6mP$@rACa;=Wf zxOO~b-$s@4oJh`kZan0?PL=Y#j00zXy+7oFz?BIcmG}E&qb8>ClnG%>%!P10<|9Uz ziBMn@@F_hOU{05bu}{p$cs>>q!j(&iOD!a1JQh*PmP@HmETnWSv9EcT%a}_oW^6o` za7>rWxlJtQyg!x-z*Q)ON-fn6HYPZeCXzSRcyd$gy-ck3yg$|Y!BrVR zejUz+{am+ajcJ52xi-S}Tpt%*WkMmnJ`qxvmoi;t#y+_|{{ALLg1ALQ3QfLvVw#?_Am|NmEnmuUk*8$9# zx)Aou;>Y{3L0tIyFmaiEl?NML2XT{UWOeV1q z*pS6Hn$`O7{~LEo-opQldkmIm%kW0aKe%fXAOHTsT^z>4eaUkqk;XjA>;D0F{L9+= ze{k3D=J+_7-uVajUuMhT7@J?X17~0VLWH6Ff&GK~IZ^0;!(Gi{FPO7FU@rt0`50dY z+?A484m*K3PKt89AR`2NkG((>y5|e`sCEfsuUsGZgP6Ydv3)f*GmgGko_}x`OFvbM zlla12uJ@@lSFV_L>@X2bFZ?J4U6v|4MJMDeJH{~oH75Jt7_;?)(Fk?1 z*_zsl+$z*BC7P{bsxMX=B4|Bm?=?kKPxWp3*KiTmao+`DGM zjVhOHRH)0_X;mwq;dxDGlBiqd=r4`qmjA%LCIz*}$=$QIS)S|9#%OOckJKdOKe&rW zdOco<34T6-V#NL%_s$;(e}C0IX#92FXQ=*s&BLIJ`@kTc`6YZd`?FW%f;$5!|Flz^ z`e&{^3HWXv_waV(2lxkfOb(FCSXl&ip%-jD(VNgfS;k7>9B%^wEQA1Y4k6h0 z$)FNYLa4KYezY&#h5QM0Q~*p!(6yv&L0`CsrQqg31dD%}{D#U*o6W7_RkM$#6A@DaF6$r76vtd1~DRCbb`aKjM;hnzo9ZQl`OVKf| z>L1)CV;C1`(=Uq#gs3K@90JIhRdk3=g~ydTkbP^T$RyR$*_2}DQW|(Lu^h{BbvmL` zy8glajqL~617UR+DO2kDsG62&`jqn+Q#<&yh1R0tqRJ#ibmMf9^FxNLBRR(?Rfdg} zNY;-xaszKoO4kGw##0e}rF{=-c#$I88`2VPGGXBCxypm&@s#=4Un&xpU#7WWF0%YP zXbN9ku_&MQR{0cz-%DkH4d=z+ZTSAsV$!&K6t9a-Zs%!MGGF%)l>5GtRNIZhpXK!AAGDzV{nYMYv?VOr< zPAVvX+c|+QU0do{Q7`eKV=>k)p9996H2y5IO|zld{H+AjS`B6wUYJej82Y|hV^LeBh6vE5g{Q*SkW;eo~Vg% zR;Ncf;qOoFX%C4bL&sVZ?t+tTzHrAHl0QaEsD?7RWo$R3e`1VnqQ#{bU#HQ7pGfM> zs%1)i8(phx=o#=fTeh76PQhkJXFP$OEb6pRL!>tMlnqaa(!XKvJG9q*KLC!NnixGd{q zxm;?&UHnY$Sivp&kz|^vq6z6a+6LcJ$K-fnh=W5poDy3D+`mXB(PD%{7Ch z*x2=a&aacbvRj0NeY}3VX=ndOCNO#4{gwS{L`q;i*Dd^V0M``-4vU1^Le|0Asc9M7lEg=fWO?V5{igZkY%Sv3;mn=pmM0iGEIh4hRY0 zM_9_PBcpZNzX9vqt5mL=6GQ(TF`7e7c569qF7q6tjCv&U)I8*LIv#WHzuD>hM$E6R zH5Pf{%(45$luz@?CE(k!R0^MO&dqzS@`AOZeEC@A^?5<0y))9k;8K_QdAUi=y&+xx zjHXX|_J@=N9&+)yc{AHUJCq(I4ZfvoaoNy&XLU^;?B$GcZU0wq=l-PjOW!W-ofM9@ z|Vw2zD-@?EBrXXk0Vxn-eHR0cct<^!AcZwtkJ)Ea`Zp1 zy?`HTdp$stA%2wmz@0^?zMjp19Stu_pwT6NZ^II<@7pHuuV0k!XKSPHpUmUWzZibs z=Y260y@-u|Q3v{EeD?zz!-HP)L&Ws=EBeJr;Xfeew{Yi&9_EB;!H5^8ZrJZfZe}S! z9)RN>;5)D7ZstenPQSL|O0dR_+9sraVnUvV9*cp-^lC}B7RcKe$cKqU8>ak?DM)Y) z1>2p7<&_lx2)d7VV;eMJcMq!B3zBCKE;LkC3qzEY2-YjZ`7p7ER^%{R6VMeYwJ^AGJ0GLb$-4YD8#wIB)) z^FRSU{`3WeC2)kJ5r^>_hCkGY!8};eBZbqQh9|8lN2f{WN!X`ZP}&z;WMD>AtwoUb zTcoo`6ca`2sYiSR^=krXtUE+x3~{tbpaO%O`%WT;G@{OeHM%&kd&j88$M7aCqDYK_ zJd+~lTCJu5(QLCr*LM3Z8MZh9ilO+mj_H5f3_sr%Hm4C&F38MK^kYlO_vM`N^cC zXj3t0q$h`bPx%AttU{Gy_C_D9k_1_hf*6i!$|<9d#p}SyNbeCoLKbZ<8SKP~k~J25 zfvhEPo6^{jYDJXh0mW!TMOm4c7AlD!)lL)=&Z}FFcqyJn|B4uYhV=F$FlF5#`Yk>0 z4J8{ZbnZS)%s#8r-jT{jHx<3d3H55mN_HQA_JQ#{eTTojWrX8NSLji zypANf4GN`$lX0|Nd=lzM85R;fmP^WV7KTuE4OR+p-@wHKeWFQZ1q(IUBohYck$vca zxD$?XGLH0-m?PbvBf<)zlai%6M7Xb+GfA8q6z_5Ef!Eh=O>CYk7GiSY))^O z3YC{=k%tzBJ#Q}hWQmK!MT{baDzuafZIyyK;Vav~71WlG)q#yqT_6owa5s<#Wn4h? z?n0>*1!aXxeNIYOK{Xpr#t`Aiy{3ZXT!_wGsJfcQvq31RMPPSY=yU(`!=#8tOY_kv zO;`%0i%Mk%CH_YQm03wqr9+}TwB^_sBU44x_Xj`y4F=;5GmoI+r9(>#D|%~eCT%WS z+m51T*SsO*(!UtRjv1x1g&>|ArN7>>-8*pnu|0jY$~p$*z%@!jtjc}@p?M>qEmhyO zVk=NwJIY9y%DL3bu|mtA0Z8oSs=1KL85^qyj;pOLY9K{w#PVyvSR{5k&`vAp?%u;w5|M7K3@@!J z=OYl8l4}D5t2Rhc!j5V`v~u>wRUkHv9H?smNLAs2(yq{TEsnMPUzfl!)#3@&brse_ zZPq6Q)*p%1dT?QJt zxN~A3(5X5ZKg=zODud#0gr%F2MH=ZH6YJ?h99gC`@jJ`i2F+Y&Yr!z*!xx`YwZh79}rXDl#zZH8_G z;@6WgWoU<|zEi8ia%o2mm&_0Ac~jy%4|X#R8G4V5LW~R}gS;&=0ZK;nzKxa=kIIRT zu2WiCWQ|gqj*|3`dj6sPbt&%;Ht4G}hKe+nlz}!3T+s}JrHPiIQ^e(rtrDQ;8TSzy zxm4|1w;p3P9N!%ue?AzmAssMx?kdoUOLUo#${*ZGu1NyKZLDeWd{b1-;~YrTqh;w zC+ys&QZ>f+YN$dVa$OqIX$Q8&g(0v7Ux&Fx;AnpU!VqL3@pwGOVEe`C;lBm*BAJKB?{Nl{roG%s)7aa?wErW_~UH7LV==x|FMOltzL zYm%F*{Y)(lL4Fa@Ygk0CbJo2o54bv=y^>(Zl#`?)}`Optr4jh@EV@)Nd7 zU8`oQamdHED&uwVTZ89yH=*Y@Z6?|E$U>Gjrn%Pf&0JZWudR-=>N<@jAC9P|CNO{y|LL(*Yp!utnn|c9*$>n3YFmh zm4!05^H(&i1umBBm||kCFqxz`oBk^cUF7hBG~NCy3+csk{3{E!T6lbAA&zY0|04_e zqOgBup;9XbOP=nJm)n>3h7G=dXCa0*J|J+e8uFhk6o#h#{hutvmOlEQS?HhT=$|ZP zxNO_DWsU#;ISZvH`3e0y3y~TF(3cJq{*{G9ktF|zEJUTrYvy^pqhnq2PZoM#Hq3Hf zu{_CkKQ2GXvHcu8`C5*sPxFHQS&qWUD^3fd*uIt{G(M=WrYdK;Y@B3#t z`pQB@|13vkB^CeoaztbEuw8*+*71B!<68BH`tpBXj?}DerPP=+1dx$Q>up=1VC#ZO zwI!JB+E+^|Yg9o<=dL@izd}{l(L&}>$Lq0IQtKbPi`w>w?>x2O@90x&S)l`!bzMhn zHrL$(n6!68Ok^NIy`K>@!QdbWGIyf`V2rAr7!(E$T_D_D!`+0fmkko1V4wn>zpZF* zyBJQgFv6fZX@<#*VEq~<5H4&U=h22gV(Fg$EK0RKflV>>OQ_qr2!Ti##L|)f+@~0% z!ti-oQaaM&=i^dmxPauIn!YvS z##a{7HTEW;yV(DaEac4Vdr=A`xxOA{;E!D|UGC9;nvIPo{mMf8cZY@2fB%l6u_NC4 zB?jVywWIVwd}Sf}%uMrZ_PFoRLjj03Dd)^zS!kvh4f&BUoRV??1+FfLatq}DRCdy@6FQ$D7{~}b_N1sve&c*ZJvXEhd7{@P%f3ncmax}`PMHcl7 zmK1xNWn}bEop?OrR~Bkd;9_=U68Aoo2B8|4(z=%l9#SBOM3e+;zKKcw%0ed#l60Jo zNr+%%)av6>q{+vFHBhs(-O8K? z-kKojq`+Cvf3gsrGXFQJxquSuTw1I$!T+6wP9;_}`8=hZC84`d%V;a+fhMRFZ&8Rs z^Y@D34o&VvbiXAJ(iSe7np8-x%Knvw&Mk`RJ<4VOm4%YB_~9x6<#HZtfmnzgKI zVezuDhF?b@PI$J6CVkqZvC(W)LbWuNCCiyBPj0M8F*nxyK(V9{>RAVluu0}Gm)O!k zY{FJQt8}A5p#*wqn;fYTQgqumq)zGt;J4g?KSKW!e%m3DAmjXC)U>s<7dbq)^` zx*88D4tl(FohGliGdT0i`LlQ59-Vm}Nbg8ewf5L&GW>Gm+Wu5i>g5Ej^M#bz1;c40 z!h-AbLHNo-gGJrd+I4|QYdcVp=iLhNjM1##8PINVgTknc(l-Z&0?BIw^eTROay(U6 z1!+7n&h=UvI+BRJuOpjCOfh@J2Y9pKgM5DhaeJ8W@fv%P%Uts*Ff4 z^)_?*D+?u-&iu;JNqw2h;$(-JOEgi-)a@Vg=egEg35yT0GZSv{-4Gc>=MbOO~I6SS|R5R;SEt zqia31>R4o6&k}e^EBx-)#pa5eNq1!>f8Hc9)YPom{gs7qcxGE9n$ARQAELd8PX4xZ zIH_C@(RQw0#I%MDRO{NcX#d8NWEX0Rz9EJT*~!1C@2MBMG2HIlq37fn5M{Q{p!VJy zwrcCx(M6p=-$ z=xhm*Vn|Q(w>)qt>3FYpa!z4s2>T&?p7PCj2zu5~mXK@<3FVqAXVq{Q<4m5)&%W!G z@zGQ+Dqct&aY+xsyAH+kdTKCy?ES(=tF8R(vZ-a8rb2g{aoxQ78S2G6o8u;Z_gUa_ z)2RaSGk5)a&TW`{*Xv(;#hOU$8^vtvB_~Js3;}$h)KTSQ)1g;Om-hRJRs9oT`S%6u zpZ9JXJW7haiSwEG!Fj&CR>lloMRj`BXjMM)y0u;m+dVIRFCgJsjv9F566J7kdYra2O*%%4<3`^4FjE|*iVwx z6fVpdqm2kP&H1?1A0drM>e!#)>#QUI1{MJK{KfX0Mu2H*z#CCO&NCi;85WI%-;XjB z(6In6OiGHjK-u}gOn+NU=D-S}AU+AzQP3dqHY~dy}A)q96r;t@?ZrYCy26 z2Gu87u=Z=P!7H^MW{8Oesg_2Ff7`q3HkL@D;R=^1$08PNp=+k2!`BuEN{T&ftOiYr09qHXGXjg87@ssRHy07)PmdJ86!q-njG0Rmf>QA0!<7bgiDH6Az@jPY^R5S_D^y z`B|jvTV%ZPqqJs}_RGweoX!JM1)98;=XcF9~nNY-v>u6%K>-au{zW!9V@uK3eIt_6G^wq+ifM*JS3 z(XwDV<)y=!Am=4v-gPwan?e5ebwCs+!Ttdae(F_EJtRP1Q(KRgkjttH**bkiIoZ~$HreXm{lipH@VTT{DBZ0(s zat%icod-Qd|I+G0sh2U>`W2;C@MS?|B}!Q=uMbH(2n;PxfFC-_P!~$q56bxIk`Ad$ zFgqMQy0rWh`N;;fJM~yHk;>(p%Rfp~*sM`|ui@_5S3G+fsF>KUxJItTkSLqy)(p!E z@3u{`_p7)qPc)*eY-ucJoUANC)hIBms!J||dRO*BjH3PV>V>>$N~y|Ys^AP*Tm4x& zV`SP4d20;Sx?^Yu)~eljY9x2ck%r#%CF96u;g7~drx==PXV}iKrAuGd2w%QZJ|3}AUNg^#XeGx@xc zO1Q~-z7d^3(N)p#yF$a!5SVVtcIQrmY&j=y+~|4rD&)GvLJ4;CT6gT z)zLx=Hghtun=*EAVwD89hAp)*H8u82v?t%TLCV@mj-qwO+l3tQe3=bW9NRY=+gci% ztCO)qh=n|y7^wI=CaF3-mO5-=RV0dn!QC$7YpqnCRcXRm(*iG3jLfqGIxB<;3emzU z(z@&~JE)DiVpkZdtK(l$ch?C=GZuD0{JNk#`5n>SU8fRGkwL9Sh7C%t#Q_?F0i^0g ziKqkJEek#6lD)M*^mf`oG9!&J;jeC z#@7JCca;^+Tl5(?QGWW-x9w23OxMe}-DlnLZc3)#+p_;>c0VIcKWbnR#us9gX-0JP zffvRDG(|Cinmsb00TuXuXCu1TsRnoJFF)C|;!QJB=forM3>;4mHuw)BW)7NI=yKIy zk>o@Zp@aC*hwAT$d0F)2KyY3yL)dulsDat_ ztlT{xHR7o^!Wt@(dpbhB5@d`{IYInVF|ODlj@%}WNfVvijb&7SVN}i$@#V<=%TeB{(xq>3j4zU?*DK+8VZUQU&!dcgK}}?aLQ2I(MwBng zcu}!;2{bJ)mphTv_`X=yQhA1irDjIWWWLMrgAw$Dh=}^=@T~C}-b2QM)nf$4;fF=5 zWwm>dqX|A+`eGv|($5wRe5#LjGcu(L{k~^~-8ml_mpl#OgP$=ub~5W zSON32QJ6Su=DNYvL0GqrFoSp!bAIJwM5t$G)pQD14{_rwWNnUfLwgWD``J365H4ML zgG19+5$=<9En!~MW4m;JlS%y$dj@%XyAAaA5T?3W_-aAKc5Ha^4QXkcNk z5@~D|7H{`WY=dTL@m(ePl(t*8BWZrISdQQVFx4sha3+Ixu)S5{jYgkgg1(XBa@5f> z2lMo_?+RXiOerUcO5bHeYB4{M>fmG|)f!IL{QXL={V0m9qPs79f6F zgt+d%>G+Bl5hW|is{SVRXKW=dU4bA@d z8{EI6+5dKf`~L*Z?)!a%`yZg$f8F3<^p^Mk2+elDhx^A3?*A5={m&a*;O+5$zQHBQ zGX1{6!O-kK=&c;@lmCkw+&}59lhgYC=gj}O!6o2||0}(v>vZ-{ddo!dgWmcdqS@YVsQD%?&m7zTNpJlP&E^l1Zh~Rb|8Jw&!}xB0L$m+5 z!Rfg@-mKXDuhHzjn6P*Mg=W`3{rdT@Xg1NspY+zBXf~B1@gMY-;YAq1^ygHXihn_~ z2SHgE;bw#c|3tI*2#~G*muNOwRm0!V?6@MF^8YO~8^XpNSWFV@Gb~6(7fd=>O#1r< z_aD&g`w}6pD~S9eH4M%EeS?Fc*?ZAp1u!(*!!6-w$=}fIiAmkAtJDvuwEsY}f5cL= z`E-hzc+aE(Q#pvOxwWFY`$b#7@Dmjqu7*X*+s|K9xdeJ@!!#GfS_B` zYXt@0|BPnis=?s^=fa4tF!ESJ>p5~@rtPgpPjfmFr1U?3Tm)huS=ibz&-9UTaY*D@CHFJB&zdSs!e?M>y|MBNfp}5cg&d(qEvw?qc zg0yz(v-hc(hW0CbB__txSqW{|Os*6s>A=G17DWhZFQ49v+Q0Zv9j9 z-PBljRh55ng1$-AO#$uDU-~D=F8)oS^WHcid0(tfsV;q3wiiie`U3Jl_qC%^%~x z9G<>;^!@DwwRxKT!wFge3S--RhrUIX%>em<{`v4sD~xSN9y0P2sNV}A6Yx5Xw@BZPZRs$VskS4# zAf#$<);VH1>HKRO6i4%|@>DloS?BVgxEWuhGuatCfRMbiR0~@Xnih=$7p#t06 z)Mq`FI99jR2|Cr{w^19`OngFx)^|K-c9!nRLv%JC!xYwPn*5Cok30Z!p~M3+XU!|N zQw+^(zp-IW(|~2|owd>J{LlYrA(^(sWc=2278;ZGf2GUmpS`UsyF2VKFwpN7nt!&p<|#wl%Ul_cO~4=;pDEHQCHQ1{eSGYtKf*>5`~= zvD780&K*81lRL&1px;G*?GM`-W>f!4HPiQSxik=$wkj2``hkvGFcEq=u2)ZSiQ`iH zQ$_lOTn#LpH?+hm$Z&ljz|K z6p+;Jh_D<-!tJaI(R-12iVB>@$T)55YLh+-bAqtw`yC9M0~OIH*iRR_6-*atCzpWOL-#WtSz0!fVX@4L z?z6c-jda{FTj4_mwcOmXG!;m>Zj!?jjmP9wZr%{R+fRe{_eaeIyc7A7I5B@YLH5;f zj@-eD*HoI|VQCcqc}4>q%idjkxd<7J%@ofP@8ex@0#s;XQ42qEP^I#s$AVWVM;Wo@ zzVh#%KWvEQ6*ZM=FeeE1@CZwao+twg$qN=HDlxPjRiv48h9q<-TS&xptGn3JVGj?h zhQmJeq@{N4`sJ4;#qT`3It>pgRjxBDIzd*;=C|y1zBA0SAsl+Ws!R1<4$QxuAoSdY z8n0e-?sces?a#W#2o52xcMW;md_0;<2Ls~_7{5%1+fKgu0ZTmQ_5|UN6F%7AYR1~eT zyAkiF1H*z}TEA$R9)oT)EWV_lQobic-~_amm=itWTt z_>x;6{C#Tc7gw$KuN#y=1m(}o8|jdHnNoc;V?u1YjDZwEj_`=0PXHzDLA*BXkj2RD z5YY@q1Xl-9EC!$|hrn=+jC-Wq!REuV>(X!88PKuvZ%Q+am*{z z-LT!6R}$kYJMJMslESkEs=6sPs;(@R~ z9S;KtzE|6tULDMV>n^LM^T;3XT`pU1FlaI#$rM)loY1CN)-RA-X0(Yv#M%eJ`4aT; zWb+qhN7K$HvJj=46$Jb5QW$Kn;3#`2H%#RlO)PiEZvvp-yNRU8VU%#7&zrD=-D8rF3u5p+A+3V_gYnB6#m_Zo6vnvAsiKiHQ@G zi<@yfPbp!Zqr$T5T0%y+O6t!znDKmA!lG6zegSt%yV{w{jd-1$5_GC)AY?F{;GJD~ z{zY1&+oZ>|Ev=#V%$Gf8S&r^|&kN=g#LjMCFecaFi~fs6iJmR2d)39E8XDUa@QcEWOBk zNbm@Ll4JW?agJ~O!&c%+x#mT1w0`E#)W_f-^i+>&H37fiHQ%+bs8N3-SNJ8V@#c;m zueezG`$6CXe~6y0-FJE*nywcrK`2Nd6e|s9XITku{|$~k1qJ~RQAem8ZHR8@D^dn{ z(iKv;JGP3kH*YP1SdNGpkH`SyMvm8^6yrEM-l5Mpoq>0_jMi`YI~0Mm!L&G7UFBFp z89;FXQuc8+C4z89iEu>saDarHFoTX-2XXUaIFff5A|xCEK2lvkjtY#ul4`H1k7YUz zv^)|5%)iCwgF6|Cu*$$CF$Zq7M&dyt1UT(pj7AMT12=ys^JL(UsK90W^ zRwBuib6fTzn~aB_&Eu3n9AEcWHAvC^m}6zn!%$|3nUcrdg7O5E%b z&Qynx0}6IuhZ?q4q$9Tf2e6`6Qv6LD?t(zPM`4VKMhr_)0^>k}=3xT$_RAgngjnQP z>0n@ZN}LFMqO)cK(LlVUra$dv{0-up@kL?6vBc{myoZh?&YeVGs|d0Ia1XZ@>TwbQ zJcJB}_jZEt4G2gxmA(n6P%@GcIpC(+i+%@3R$|ddL-Hc*pVM)$GbT$veS^Sz zCkxygi5O4{339x25Dmsl=H^U^po36YB#APa9UQ zr%kt2ddp>MMhS=z%eOoH%!AX_HXOUgo2~-q>OFstIbjBcXWOMPFpr&V! z!j=LufYhtmIH75{+d1)w>T|~o?Oj$BswJc_3_c4Y@ye}=qB zS?xxxT%6E6*_$llZO<*6pv^n7bHALm&|Hv)9goGMcRd#_#WZzj98Wo z;2TO*uCiZ0ykuSUd5u@53oW~VFSmuSxH~9s&9o3oEzfT$wR$>%P8^WNC{m9PSH!Qy zq@a?-`;=O@bN*b43p2!nppq=wx*-6oQoCfHXBD9oX1Vdlmiw!eF=0ibl6a%?WyNqc zKH#^WkhZU}-rQHwVx`A*!3q#HKqN@-S}{v<&B0Bj?R+F?G6!ei4Zv1tM3Iwf|4p}J z%~u)o=}96S3eWs@~@^KE1R)hfr@HmD8~kSiBnxn5u=~HoUY=eWnrk0xd%6wE;e{e2*VctDx$! z%8IyJepp)fd9_)3OxfBvA$6>J_*zr>PC!T$-yLe><5MdS2eViMA=c+xb9$%djIcD3 zrFzUuVYZYezQ$T{V#mCk>M1_?hqmzKa`tXQOC?f!Y%d?AWJIiXd5D?kY1`}9WsKT6 z&jK<~QMqio>E5mr&Ys|+DRrO;+4V7qh8W?zSnf!1qJm7}zgrB+tgb^I=*&HBO>~kd z>+Vo%>{6lRc`ew994%HpMdgCnCNG3tSIy}c+uFJwCF!G48S8A{*=>YurNG;RW6@&` zYDJJ}p_}ji@llfJz8e|R+3c^ez?_Cq*z-E27yU`Nmj9@iu+3F`yk|K;($vS}DAsMS zTH)9*6P2R-r6S?_585-OP$%YSue(0!)Q(Eecgj@#KFuCK5qk$R`(n!z9ZOzaGn406 z_Zxrf2N@??=z}2A17{Nb=iBdaja#&Q9mqun5r+msEC(0E`;pw`?v(~_*BK&@LB#qpRz%U zBA!3+MlkS8!)=D$w@VOW1+H)Vi-kwzrUjgbv8XnIF3D?a5fB0uUT$jcU-G8pphy zg%j{oCpSm&_@NN_a+syl?d|kC#LEt?0AOYyRoHc5{?G9cn%JG?aTs@1j*e$6nB{{v zbpflu%}@Tq(-IQVDiVPJW7uQqrhm;hM{iG&6v3semNsq3uSfN_8P7;@`D1D21ZTbi z1Qx6st2QD|55(zhrMgl(%&O6KB>HE&YfZ1ky(tL?AsA@h{YT7P_QZ0p|CdH$lDX^J%+{8&%)NoLVdNXoo zLzr|Wa&s^*-#(&YUy;ZeCzs=pC{Q`^E9q;As?<*pjJTGDzC2Tw2~yf6TF?Ve_t=Aa ziI#&0mOHbtTxXb!Fi6n$Gy!;XT#uUDJaz8zoIxt%%m=x-u_;!MoHi;tDfCKyMk{li zAMXdHo=vO_P_6bwQ@;5$r{KQ2;?bD(IL+>!pYjQ3i`t@wXUJQ@qp%l0cZLM@^NNU* zL5FoC+=5fxBfmziv47*5HFT|Yh0rzkU8D8exY~7xZOztRubv#V=swjvHMPyyG`KW^4XyaDS>iHWyG7Zls*A_ZDe~EXGe0tMrR$eySPIY zT>lDTSFn!a0Dqg5gjc+8D0O?SB#K??d=t+?R{_(aKiy1VbN32szla+ok`PM%R!I9- zl^)yv`q4gX`~LC59!KM(${EjR*#q-mtGJX0E(`nVI|nPh2h8x}%#^#c;6wabkYn(i zCmH7})rmJ^ui)xHEd)mcPc(;b`;H7HMZmL1+JvS^MMs7^9}Y2&wVE;*$uzRrrkvJ} zGssSAq6mY;=xFaZx#3SzMmd&Lsz|f~e-s~1+#D(QVpsiQ5w|8t38pFCRBqYy3^r1G zmw-i(2G<>o{q=gzZ2lAhAp zu7V7usj|m*>00M`1Lsx}u$g@;9aOj>ySL=GX=l6V*A-t?t%5G=rgpuUn#j&ApNS)E zVdK={WR`m&e_hA3@TJYh!l;+`t^9B|__a6mQrG>otmsVJ{iJo)f@SwoSK=z{*I5=; z4aYjsTU;%zF#D?Y`@VxmRSCGY7Ge_dqnoqi>eOgp;p44n*?vbTl#LYK=+)bgiz`6`Brf5?fdzwy(t5+fm%Fr8(<%#?SX~Vz!VaGox