diff --git a/Makefile b/Makefile index bf723bd..90964a2 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,17 @@ define gen-doc-in-dir cat ./$1/koyeb_databases_*.md >> ./$1/reference.md cat ./$1/koyeb_version.md >> ./$1/reference.md cat ./$1/koyeb_volumes.md >> ./$1/reference.md + cat ./$1/koyeb_volumes_*.md >> ./$1/reference.md + cat ./$1/koyeb_regions.md >> ./$1/reference.md + cat ./$1/koyeb_regions_*.md >> ./$1/reference.md + cat ./$1/koyeb_regional-deployments.md >> ./$1/reference.md + cat ./$1/koyeb_regional-deployments_*.md >> ./$1/reference.md + cat ./$1/koyeb_metrics.md >> ./$1/reference.md + cat ./$1/koyeb_metrics_*.md >> ./$1/reference.md + cat ./$1/koyeb_snapshots.md >> ./$1/reference.md + cat ./$1/koyeb_snapshots_*.md >> ./$1/reference.md + cat ./$1/koyeb_compose.md >> ./$1/reference.md + cat ./$1/koyeb_compose_*.md >> ./$1/reference.md find ./$1 -type f -not -name 'reference.md' -delete endef diff --git a/docs/reference.md b/docs/reference.md index a00bed9..8527782 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -43,6 +43,7 @@ Koyeb CLI * [koyeb metrics](#koyeb-metrics) - Metrics * [koyeb organizations](#koyeb-organizations) - Organization * [koyeb regional-deployments](#koyeb-regional-deployments) - Regional deployments +* [koyeb regions](#koyeb-regions) - Regions * [koyeb secrets](#koyeb-secrets) - Secrets * [koyeb services](#koyeb-services) - Services * [koyeb snapshots](#koyeb-snapshots) - Manage snapshots @@ -292,12 +293,11 @@ See examples of koyeb service create --help --config-file strings Copy a local file to your service container using the format LOCAL_FILE:PATH:[PERMISSIONS] for example --config-file /etc/data.yaml:/etc/data.yaml:0644 To delete a config file, use !PATH, for example --config-file !/etc/data.yaml - + + --deep-sleep-delay duration Delay after which an idle service is put to deep sleep. Use duration format (e.g., '5m', '30m', '1h'). Set to 0 to disable. + --delete-after-delay duration Automatically delete the service after this duration from creation. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. + --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --deployment-strategy STRATEGY Deployment strategy, either "rolling" (default), "blue-green" or "immediate". - --delete-after-delay duration Automatically delete the service after this duration from creation. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. - --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --docker string Docker image --docker-args strings Set arguments to the docker command. To provide multiple arguments, use the --docker-args flag multiple times. --docker-command string Set the docker CMD explicitly. To provide arguments to the command, use the --docker-args flag. @@ -324,6 +324,7 @@ See examples of koyeb service create --help --git-workdir string Path to the sub-directory containing the code to build and deploy -h, --help help for init --instance-type string Instance type (default "nano") + --light-sleep-delay duration Delay after which an idle service is put to light sleep. Use duration format (e.g., '1m', '5m', '1h'). Set to 0 to disable. --max-scale int Max scale (default 1) --min-scale int Min scale (default 1) --ports strings Update service ports (available for services of type "web" only) using the format PORT[:PROTOCOL], for example --port 8080:http @@ -605,17 +606,17 @@ koyeb deploy / [flags] for example --config-file /etc/data.yaml:/etc/data.yaml:0644 To delete a config file, use !PATH, for example --config-file !/etc/data.yaml + --deep-sleep-delay duration Delay after which an idle service is put to deep sleep. Use duration format (e.g., '5m', '30m', '1h'). Set to 0 to disable. + --delete-after-delay duration Automatically delete the service after this duration from creation. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. + --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --deployment-strategy STRATEGY Deployment strategy, either "rolling" (default), "blue-green" or "immediate". - --delete-after-delay duration Automatically delete the service after this duration from creation. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. - --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --env strings Update service environment variables using the format KEY=VALUE, for example --env FOO=bar To use the value of a secret as an environment variable, use the following syntax: --env FOO={{secret.bar}} To delete an environment variable, prefix its name with '!', for example --env '!FOO' -h, --help help for deploy --instance-type string Instance type (default "nano") + --light-sleep-delay duration Delay after which an idle service is put to light sleep. Use duration format (e.g., '1m', '5m', '1h'). Set to 0 to disable. --max-scale int Max scale (default 1) --min-scale int Min scale (default 1) --ports strings Update service ports (available for services of type "web" only) using the format PORT[:PROTOCOL], for example --port 8080:http @@ -1421,12 +1422,11 @@ $> koyeb service create myservice --app myapp --docker nginx --port 80:tcp --config-file strings Copy a local file to your service container using the format LOCAL_FILE:PATH:[PERMISSIONS] for example --config-file /etc/data.yaml:/etc/data.yaml:0644 To delete a config file, use !PATH, for example --config-file !/etc/data.yaml - + + --deep-sleep-delay duration Delay after which an idle service is put to deep sleep. Use duration format (e.g., '5m', '30m', '1h'). Set to 0 to disable. + --delete-after-delay duration Automatically delete the service after this duration from creation. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. + --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --deployment-strategy STRATEGY Deployment strategy, either "rolling" (default), "blue-green" or "immediate". - --delete-after-delay duration Automatically delete the service after this duration from creation. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. - --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --docker string Docker image --docker-args strings Set arguments to the docker command. To provide multiple arguments, use the --docker-args flag multiple times. --docker-command string Set the docker CMD explicitly. To provide arguments to the command, use the --docker-args flag. @@ -1453,6 +1453,7 @@ $> koyeb service create myservice --app myapp --docker nginx --port 80:tcp --git-workdir string Path to the sub-directory containing the code to build and deploy -h, --help help for create --instance-type string Instance type (default "nano") + --light-sleep-delay duration Delay after which an idle service is put to light sleep. Use duration format (e.g., '1m', '5m', '1h'). Set to 0 to disable. --max-scale int Max scale (default 1) --min-scale int Min scale (default 1) --ports strings Update service ports (available for services of type "web" only) using the format PORT[:PROTOCOL], for example --port 8080:http @@ -1898,12 +1899,11 @@ $> koyeb service update myapp/myservice --port 80:tcp --route '!/' --config-file strings Copy a local file to your service container using the format LOCAL_FILE:PATH:[PERMISSIONS] for example --config-file /etc/data.yaml:/etc/data.yaml:0644 To delete a config file, use !PATH, for example --config-file !/etc/data.yaml - + + --deep-sleep-delay duration Delay after which an idle service is put to deep sleep. Use duration format (e.g., '5m', '30m', '1h'). Set to 0 to disable. + --delete-after-delay duration Automatically delete the service after this duration from creation. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. + --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --deployment-strategy STRATEGY Deployment strategy, either "rolling" (default), "blue-green" or "immediate". - --delete-after-delay duration Automatically delete the service after this duration from creation. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. - --delete-after-inactivity-delay duration Automatically delete the service after being inactive (sleeping) for this duration. - Use duration format (e.g., '1h', '30m', '24h'). Set to 0 to disable. --docker string Docker image --docker-args strings Set arguments to the docker command. To provide multiple arguments, use the --docker-args flag multiple times. --docker-command string Set the docker CMD explicitly. To provide arguments to the command, use the --docker-args flag. @@ -1930,6 +1930,7 @@ $> koyeb service update myapp/myservice --port 80:tcp --route '!/' --git-workdir string Path to the sub-directory containing the code to build and deploy -h, --help help for update --instance-type string Instance type (default "nano") + --light-sleep-delay duration Delay after which an idle service is put to light sleep. Use duration format (e.g., '1m', '5m', '1h'). Set to 0 to disable. --max-scale int Max scale (default 1) --min-scale int Min scale (default 1) --name string Specify to update the service name @@ -2696,3 +2697,722 @@ Manage persistent volumes * [koyeb volumes list](#koyeb-volumes-list) - List volumes * [koyeb volumes update](#koyeb-volumes-update) - Update a volume +## koyeb volumes create + +Create a new volume + +``` +koyeb volumes create NAME [flags] +``` + +### Options + +``` + -h, --help help for create + --read-only Force the volume to be read-only + --region string Region of the volume (default "was") + --size int Size of the volume in GB (default -1) + --snapshot string Specify a snapshot to use to create the volume from +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb volumes](#koyeb-volumes) - Manage persistent volumes + +## koyeb volumes delete + +Delete a volume + +``` +koyeb volumes delete NAME [flags] +``` + +### Options + +``` + -h, --help help for delete +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb volumes](#koyeb-volumes) - Manage persistent volumes + +## koyeb volumes get + +Get a volume + +``` +koyeb volumes get NAME [flags] +``` + +### Options + +``` + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb volumes](#koyeb-volumes) - Manage persistent volumes + +## koyeb volumes list + +List volumes + +``` +koyeb volumes list [flags] +``` + +### Options + +``` + -h, --help help for list +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb volumes](#koyeb-volumes) - Manage persistent volumes + +## koyeb volumes update + +Update a volume + +``` +koyeb volumes update NAME [flags] +``` + +### Options + +``` + -h, --help help for update + --name string Change the volume name + --size int Increase the volume size (default -1) +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb volumes](#koyeb-volumes) - Manage persistent volumes + +## koyeb regions + +Regions + +### Options + +``` + -h, --help help for regions +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb](#koyeb) - Koyeb CLI +* [koyeb regions get](#koyeb-regions-get) - Get region +* [koyeb regions list](#koyeb-regions-list) - List regions + +## koyeb regions get + +Get region + +``` +koyeb regions get NAME [flags] +``` + +### Options + +``` + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb regions](#koyeb-regions) - Regions + +## koyeb regions list + +List regions + +``` +koyeb regions list [flags] +``` + +### Options + +``` + -h, --help help for list +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb regions](#koyeb-regions) - Regions + +## koyeb regional-deployments + +Regional deployments + +### Options + +``` + -h, --help help for regional-deployments +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb](#koyeb) - Koyeb CLI +* [koyeb regional-deployments get](#koyeb-regional-deployments-get) - Get regional deployment +* [koyeb regional-deployments list](#koyeb-regional-deployments-list) - List regional deployments + +## koyeb regional-deployments get + +Get regional deployment + +``` +koyeb regional-deployments get NAME [flags] +``` + +### Options + +``` + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb regional-deployments](#koyeb-regional-deployments) - Regional deployments + +## koyeb regional-deployments list + +List regional deployments + +``` +koyeb regional-deployments list [flags] +``` + +### Options + +``` + --deployment string Limit the list to regional deployments of a specific deployment + -h, --help help for list +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb regional-deployments](#koyeb-regional-deployments) - Regional deployments + +## koyeb metrics + +Metrics + +### Options + +``` + -h, --help help for metrics +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb](#koyeb) - Koyeb CLI +* [koyeb metrics get](#koyeb-metrics-get) - Get metrics for a service or instance + +## koyeb metrics get + +Get metrics for a service or instance + +``` +koyeb metrics get [flags] +``` + +### Options + +``` + --end string End date for the metrics + -h, --help help for get + --instance string Instance name or ID + --service string Service name or ID + --start string Start date for the metrics +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb metrics](#koyeb-metrics) - Metrics + +## koyeb snapshots + +Manage snapshots + +### Options + +``` + -h, --help help for snapshots +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb](#koyeb) - Koyeb CLI +* [koyeb snapshots create](#koyeb-snapshots-create) - Create a new snapshot +* [koyeb snapshots delete](#koyeb-snapshots-delete) - Delete a snapshot +* [koyeb snapshots get](#koyeb-snapshots-get) - Get a snapshot +* [koyeb snapshots list](#koyeb-snapshots-list) - List snapshots +* [koyeb snapshots update](#koyeb-snapshots-update) - Update a snapshot + +## koyeb snapshots create + +Create a new snapshot + +``` +koyeb snapshots create NAME PARENT_VOLUME [flags] +``` + +### Options + +``` + -h, --help help for create +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb snapshots](#koyeb-snapshots) - Manage snapshots + +## koyeb snapshots delete + +Delete a snapshot + +``` +koyeb snapshots delete NAME [flags] +``` + +### Options + +``` + -h, --help help for delete +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb snapshots](#koyeb-snapshots) - Manage snapshots + +## koyeb snapshots get + +Get a snapshot + +``` +koyeb snapshots get NAME [flags] +``` + +### Options + +``` + -h, --help help for get +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb snapshots](#koyeb-snapshots) - Manage snapshots + +## koyeb snapshots list + +List snapshots + +``` +koyeb snapshots list [flags] +``` + +### Options + +``` + -h, --help help for list +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb snapshots](#koyeb-snapshots) - Manage snapshots + +## koyeb snapshots update + +Update a snapshot + +``` +koyeb snapshots update NAME [flags] +``` + +### Options + +``` + -h, --help help for update + --name string Change the snapshot name +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb snapshots](#koyeb-snapshots) - Manage snapshots + +## koyeb compose + +Create Koyeb resources from a koyeb-compose.yaml file + +``` +koyeb compose KOYEB_COMPOSE_FILE_PATH [flags] +``` + +### Examples + +``` +koyeb compose ./examples/mesh.yaml +``` + +### Options + +``` + -h, --help help for compose + -v, --verbose Tails service logs to have more information about your deployment. +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb](#koyeb) - Koyeb CLI +* [koyeb compose delete](#koyeb-compose-delete) - d +* [koyeb compose logs](#koyeb-compose-logs) - l + +## koyeb compose delete + +d + +``` +koyeb compose delete [flags] +``` + +### Options + +``` + -h, --help help for delete +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb compose](#koyeb-compose) - Create Koyeb resources from a koyeb-compose.yaml file + +## koyeb compose logs + +l + +``` +koyeb compose logs [flags] +``` + +### Options + +``` + -h, --help help for logs +``` + +### Options inherited from parent commands + +``` + -c, --config string config file (default is $HOME/.koyeb.yaml) + -d, --debug enable the debug output + --debug-full do not hide sensitive information (tokens) in the debug output + --force-ascii only output ascii characters (no unicode emojis) + --full do not truncate output + --organization string organization ID + -o, --output output output format (yaml,json,table) + --token string API token + --url string url of the api (default "https://app.koyeb.com") +``` + + + +* [koyeb compose](#koyeb-compose) - Create Koyeb resources from a koyeb-compose.yaml file + diff --git a/go.mod b/go.mod index deb8991..e6251b3 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/gofrs/uuid v4.3.0+incompatible github.com/gorilla/websocket v1.5.0 github.com/iancoleman/strcase v0.2.0 - github.com/koyeb/koyeb-api-client-go v0.0.0-20251231135535-21b1a3f8d818 + github.com/koyeb/koyeb-api-client-go v0.0.0-20260204084353-bdcef71b7bcd github.com/logrusorgru/aurora v2.0.3+incompatible github.com/manifoldco/promptui v0.9.0 github.com/mitchellh/go-homedir v1.1.0 diff --git a/go.sum b/go.sum index 86f7faa..c0a3a62 100644 --- a/go.sum +++ b/go.sum @@ -168,8 +168,8 @@ github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/koyeb/koyeb-api-client-go v0.0.0-20251231135535-21b1a3f8d818 h1:gkkhTDimP+Vn3u4x7X6MzevxmFlolw4O+GJRN9g6acc= -github.com/koyeb/koyeb-api-client-go v0.0.0-20251231135535-21b1a3f8d818/go.mod h1:+oQfFj2WL3gi9Pb+UHbob4D7xaT52mPfKyH1UvWa4PQ= +github.com/koyeb/koyeb-api-client-go v0.0.0-20260204084353-bdcef71b7bcd h1:cA9pcvsP5JEWTx7t7Rs910R/NpT1h18X3XSLCNeTywI= +github.com/koyeb/koyeb-api-client-go v0.0.0-20260204084353-bdcef71b7bcd/go.mod h1:+oQfFj2WL3gi9Pb+UHbob4D7xaT52mPfKyH1UvWa4PQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= diff --git a/pkg/koyeb/koyeb.go b/pkg/koyeb/koyeb.go index 88e10bd..524c95c 100644 --- a/pkg/koyeb/koyeb.go +++ b/pkg/koyeb/koyeb.go @@ -117,6 +117,7 @@ func GetRootCommand() *cobra.Command { rootCmd.AddCommand(NewVolumeCmd()) rootCmd.AddCommand(NewSnapshotCmd()) rootCmd.AddCommand(NewComposeCmd()) + rootCmd.AddCommand(NewRegionCmd()) return rootCmd } diff --git a/pkg/koyeb/regions.go b/pkg/koyeb/regions.go new file mode 100644 index 0000000..d0ef1d2 --- /dev/null +++ b/pkg/koyeb/regions.go @@ -0,0 +1,39 @@ +package koyeb + +import ( + "github.com/spf13/cobra" +) + +func NewRegionCmd() *cobra.Command { + h := NewRegionHandler() + + regionCmd := &cobra.Command{ + Use: "regions ACTION", + Aliases: []string{"region", "reg"}, + Short: "Regions", + } + + listRegionCmd := &cobra.Command{ + Use: "list", + Short: "List regions", + RunE: WithCLIContext(h.List), + } + regionCmd.AddCommand(listRegionCmd) + + getRegionCmd := &cobra.Command{ + Use: "get NAME", + Short: "Get region", + Args: cobra.ExactArgs(1), + RunE: WithCLIContext(h.Get), + } + regionCmd.AddCommand(getRegionCmd) + + return regionCmd +} + +type RegionHandler struct { +} + +func NewRegionHandler() *RegionHandler { + return &RegionHandler{} +} diff --git a/pkg/koyeb/regions_get.go b/pkg/koyeb/regions_get.go new file mode 100644 index 0000000..4e38bb0 --- /dev/null +++ b/pkg/koyeb/regions_get.go @@ -0,0 +1,76 @@ +package koyeb + +import ( + "fmt" + "os" + "strconv" + + "github.com/koyeb/koyeb-api-client-go/api/v1/koyeb" + "github.com/koyeb/koyeb-cli/pkg/koyeb/errors" + "github.com/koyeb/koyeb-cli/pkg/koyeb/renderer" + "github.com/spf13/cobra" +) + +func (h *RegionHandler) Get(ctx *CLIContext, cmd *cobra.Command, args []string) error { + res, resp, err := ctx.Client.CatalogRegionsApi.GetRegion(ctx.Context, args[0]).Execute() + if err != nil { + return errors.NewCLIErrorFromAPIError( + fmt.Sprintf("Error while retrieving the region `%s`", args[0]), + err, + resp, + ) + } + + getRegionReply := NewGetRegionReply(res) + + // For JSON/YAML output, use the standard renderer which includes instances + // in the serialized output. For table output, print a custom format. + if _, ok := ctx.Renderer.(*renderer.TableRenderer); ok { + region := res.GetRegion() + fmt.Fprintf(os.Stdout, "ID: %s\n", region.GetId()) + fmt.Fprintf(os.Stdout, "Name: %s\n", region.GetName()) + fmt.Fprintf(os.Stdout, "Scope: %s\n", region.GetScope()) + fmt.Fprintf(os.Stdout, "Volumes enabled: %s\n", strconv.FormatBool(region.GetVolumesEnabled())) + fmt.Fprintf(os.Stdout, "\nInstances:\n") + for _, inst := range region.GetInstances() { + fmt.Fprintf(os.Stdout, " - %s\n", inst) + } + } else { + ctx.Renderer.Render(getRegionReply) + } + return nil +} + +type GetRegionReply struct { + value *koyeb.GetRegionReply +} + +func NewGetRegionReply(value *koyeb.GetRegionReply) *GetRegionReply { + return &GetRegionReply{ + value: value, + } +} + +func (GetRegionReply) Title() string { + return "Region" +} + +func (r *GetRegionReply) MarshalBinary() ([]byte, error) { + return r.value.GetRegion().MarshalJSON() +} + +func (r *GetRegionReply) Headers() []string { + return []string{"id", "name", "scope", "volumes_enabled"} +} + +func (r *GetRegionReply) Fields() []map[string]string { + item := r.value.GetRegion() + fields := map[string]string{ + "id": item.GetId(), + "name": item.GetName(), + "scope": item.GetScope(), + "volumes_enabled": strconv.FormatBool(item.GetVolumesEnabled()), + } + + return []map[string]string{fields} +} diff --git a/pkg/koyeb/regions_list.go b/pkg/koyeb/regions_list.go new file mode 100644 index 0000000..f1f5f3a --- /dev/null +++ b/pkg/koyeb/regions_list.go @@ -0,0 +1,85 @@ +package koyeb + +import ( + "strconv" + "strings" + + "github.com/koyeb/koyeb-api-client-go/api/v1/koyeb" + "github.com/koyeb/koyeb-cli/pkg/koyeb/errors" + "github.com/spf13/cobra" +) + +func (h *RegionHandler) List(ctx *CLIContext, cmd *cobra.Command, args []string) error { + list := []koyeb.RegionListItem{} + + page := int64(0) + offset := int64(0) + limit := int64(100) + for { + res, resp, err := ctx.Client.CatalogRegionsApi.ListRegions(ctx.Context). + Limit(strconv.FormatInt(limit, 10)). + Offset(strconv.FormatInt(offset, 10)). + Execute() + if err != nil { + return errors.NewCLIErrorFromAPIError( + "Error while listing the regions", + err, + resp, + ) + } + for _, region := range res.GetRegions() { + if strings.EqualFold(region.GetStatus(), "available") { + list = append(list, region) + } + } + + page++ + offset = page * limit + if offset >= res.GetCount() { + break + } + } + + listRegionsReply := NewListRegionsReply(&koyeb.ListRegionsReply{Regions: list}) + ctx.Renderer.Render(listRegionsReply) + return nil +} + +type ListRegionsReply struct { + value *koyeb.ListRegionsReply +} + +func NewListRegionsReply(value *koyeb.ListRegionsReply) *ListRegionsReply { + return &ListRegionsReply{ + value: value, + } +} + +func (ListRegionsReply) Title() string { + return "Regions" +} + +func (r *ListRegionsReply) MarshalBinary() ([]byte, error) { + return r.value.MarshalJSON() +} + +func (r *ListRegionsReply) Headers() []string { + return []string{"id", "name", "scope", "volumes_enabled"} +} + +func (r *ListRegionsReply) Fields() []map[string]string { + items := r.value.GetRegions() + resp := make([]map[string]string, 0, len(items)) + + for _, item := range items { + fields := map[string]string{ + "id": item.GetId(), + "name": item.GetName(), + "scope": item.GetScope(), + "volumes_enabled": strconv.FormatBool(item.GetVolumesEnabled()), + } + resp = append(resp, fields) + } + + return resp +} diff --git a/pkg/koyeb/services.go b/pkg/koyeb/services.go index 81d38fd..c7dc154 100644 --- a/pkg/koyeb/services.go +++ b/pkg/koyeb/services.go @@ -377,6 +377,12 @@ func (h *ServiceHandler) addServiceDefinitionFlagsForAllSources(flags *pflag.Fla flags.Int64("autoscaling-requests-per-second", 0, "Target requests per second to trigger a scaling event. Set to 0 to disable requests per second autoscaling.") flags.Int64("autoscaling-concurrent-requests", 0, "Target concurrent requests to trigger a scaling event. Set to 0 to disable concurrent requests autoscaling.") flags.Int64("autoscaling-requests-response-time", 0, "Target p95 response time to trigger a scaling event (in ms). Set to 0 to disable concurrent response time autoscaling.") + flags.Duration("light-sleep-delay", 0, + "Delay after which an idle service is put to light sleep. "+ + "Use duration format (e.g., '1m', '5m', '1h'). Set to 0 to disable.") + flags.Duration("deep-sleep-delay", 0, + "Delay after which an idle service is put to deep sleep. "+ + "Use duration format (e.g., '5m', '30m', '1h'). Set to 0 to disable.") flags.Bool("privileged", false, "Whether the service container should run in privileged mode") flags.Bool("skip-cache", false, "Whether to use the cache when building the service") @@ -600,7 +606,11 @@ func (h *ServiceHandler) parseServiceDefinitionFlags(ctx *CLIContext, flags *pfl } isFreeUsed := isFreeInstanceUsed(definition.GetInstanceTypes()) - definition.SetScalings(h.parseScalings(isFreeUsed, flags, definition.Scalings)) + scalings, err := h.parseScalings(isFreeUsed, flags, definition.Scalings) + if err != nil { + return err + } + definition.SetScalings(scalings) healthchecks, err := h.parseChecks(definition.GetType(), flags, definition.HealthChecks) if err != nil { @@ -1023,7 +1033,7 @@ func (h *ServiceHandler) parseRegions(flags *pflag.FlagSet, currentRegions []str } // Parse --min-scale and --max-scale -func (h *ServiceHandler) parseScalings(isFreeUsed bool, flags *pflag.FlagSet, currentScalings []koyeb.DeploymentScaling) []koyeb.DeploymentScaling { +func (h *ServiceHandler) parseScalings(isFreeUsed bool, flags *pflag.FlagSet, currentScalings []koyeb.DeploymentScaling) ([]koyeb.DeploymentScaling, error) { var minScale, maxScale int64 if flags.Lookup("min-scale").Changed { @@ -1045,8 +1055,10 @@ func (h *ServiceHandler) parseScalings(isFreeUsed bool, flags *pflag.FlagSet, cu scaling := koyeb.NewDeploymentScalingWithDefaults() scaling.SetMin(minScale) scaling.SetMax(maxScale) - h.setScalingsTargets(flags, scaling) - return []koyeb.DeploymentScaling{*scaling} + if err := h.setScalingsTargets(flags, scaling); err != nil { + return nil, err + } + return []koyeb.DeploymentScaling{*scaling}, nil } else { // Otherwise, update the current scaling configuration only if one of the scale flags has been provided for idx := range currentScalings { @@ -1056,10 +1068,12 @@ func (h *ServiceHandler) parseScalings(isFreeUsed bool, flags *pflag.FlagSet, cu if flags.Lookup("scale").Changed || flags.Lookup("max-scale").Changed { currentScalings[idx].SetMax(maxScale) } - h.setScalingsTargets(flags, ¤tScalings[idx]) + if err := h.setScalingsTargets(flags, ¤tScalings[idx]); err != nil { + return nil, err + } } } - return currentScalings + return currentScalings, nil } // setScalingsTargets updates the scaling targets in a koyeb.DeploymentScaling object based on the specified flags. @@ -1080,7 +1094,7 @@ func (h *ServiceHandler) parseScalings(isFreeUsed bool, flags *pflag.FlagSet, cu // Note: there is no way to easily avoid the code duplication in this function // because NewDeploymentScalingTarget{AverageCPU,AverageMem,RequestsPerSecond,ConcurrentRequests,...} // do not implement a common interface. -func (h *ServiceHandler) setScalingsTargets(flags *pflag.FlagSet, scaling *koyeb.DeploymentScaling) { +func (h *ServiceHandler) setScalingsTargets(flags *pflag.FlagSet, scaling *koyeb.DeploymentScaling) error { if scaling.Targets == nil || scaling.GetMin() == scaling.GetMax() { scaling.Targets = []koyeb.DeploymentScalingTarget{} } @@ -1234,6 +1248,77 @@ func (h *ServiceHandler) setScalingsTargets(flags *pflag.FlagSet, scaling *koyeb } scaling.Targets = newTargets } + + if flags.Lookup("light-sleep-delay").Changed || flags.Lookup("deep-sleep-delay").Changed { + if scaling.GetMin() > 0 { + return &errors.CLIError{ + What: "Error while configuring the service", + Why: "--light-sleep-delay and --deep-sleep-delay can only be used when min-scale is 0", + Additional: []string{ + "Sleep delays are only applicable to services that can scale to zero.", + "Set --min-scale 0 to enable scale-to-zero before configuring sleep delays.", + }, + Orig: nil, + Solution: "Add --min-scale 0 to your command and try again", + } + } + + lightSleepDuration, _ := flags.GetDuration("light-sleep-delay") + deepSleepDuration, _ := flags.GetDuration("deep-sleep-delay") + lightSleepChanged := flags.Lookup("light-sleep-delay").Changed + deepSleepChanged := flags.Lookup("deep-sleep-delay").Changed + + newTargets := []koyeb.DeploymentScalingTarget{} + found := false + + for _, target := range scaling.GetTargets() { + if target.HasSleepIdleDelay() { + found = true + sid := target.GetSleepIdleDelay() + if lightSleepChanged { + if lightSleepDuration > 0 { + sid.SetLightSleepValue(int64(lightSleepDuration.Seconds())) + } else { + sid.LightSleepValue = nil + } + } + if deepSleepChanged { + if deepSleepDuration > 0 { + sid.SetDeepSleepValue(int64(deepSleepDuration.Seconds())) + } else { + sid.DeepSleepValue = nil + } + } + // Remove the target entirely if both values are unset + if sid.LightSleepValue == nil && sid.DeepSleepValue == nil { + continue + } + target.SetSleepIdleDelay(sid) + newTargets = append(newTargets, target) + } else { + newTargets = append(newTargets, target) + } + } + if !found { + sid := koyeb.NewDeploymentScalingTargetSleepIdleDelay() + hasValue := false + if lightSleepChanged && lightSleepDuration > 0 { + sid.SetLightSleepValue(int64(lightSleepDuration.Seconds())) + hasValue = true + } + if deepSleepChanged && deepSleepDuration > 0 { + sid.SetDeepSleepValue(int64(deepSleepDuration.Seconds())) + hasValue = true + } + if hasValue { + target := koyeb.NewDeploymentScalingTarget() + target.SetSleepIdleDelay(*sid) + newTargets = append(newTargets, *target) + } + } + scaling.Targets = newTargets + } + return nil } // Parse --git-* and --docker-* flags to set deployment.Git or deployment.Docker diff --git a/pkg/koyeb/services_test.go b/pkg/koyeb/services_test.go index eec96c6..032bba7 100644 --- a/pkg/koyeb/services_test.go +++ b/pkg/koyeb/services_test.go @@ -466,3 +466,183 @@ func TestSetDefaultPortsAndRoutes(t *testing.T) { }) } } + +func TestSetSleepDelayFlags(t *testing.T) { + tests := map[string]struct { + args []string + minScale int64 + currentTargets []koyeb.DeploymentScalingTarget + expected []koyeb.DeploymentScalingTarget + expectedErr bool + }{ + "set light sleep delay on new service": { + args: []string{"--light-sleep-delay", "5m"}, + minScale: 0, + currentTargets: nil, + expected: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + }, + }, + }, + }, + "set deep sleep delay on new service": { + args: []string{"--deep-sleep-delay", "30m"}, + minScale: 0, + currentTargets: nil, + expected: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + DeepSleepValue: koyeb.PtrInt64(1800), + }, + }, + }, + }, + "set both sleep delays on new service": { + args: []string{"--light-sleep-delay", "1m", "--deep-sleep-delay", "10m"}, + minScale: 0, + currentTargets: nil, + expected: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(60), + DeepSleepValue: koyeb.PtrInt64(600), + }, + }, + }, + }, + "update light sleep delay on existing service": { + args: []string{"--light-sleep-delay", "10m"}, + minScale: 0, + currentTargets: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + DeepSleepValue: koyeb.PtrInt64(1800), + }, + }, + }, + expected: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(600), + DeepSleepValue: koyeb.PtrInt64(1800), + }, + }, + }, + }, + "disable light sleep delay": { + args: []string{"--light-sleep-delay", "0"}, + minScale: 0, + currentTargets: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + DeepSleepValue: koyeb.PtrInt64(1800), + }, + }, + }, + expected: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + DeepSleepValue: koyeb.PtrInt64(1800), + }, + }, + }, + }, + "disable both sleep delays removes target": { + args: []string{"--light-sleep-delay", "0", "--deep-sleep-delay", "0"}, + minScale: 0, + currentTargets: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + DeepSleepValue: koyeb.PtrInt64(1800), + }, + }, + }, + expected: []koyeb.DeploymentScalingTarget{}, + }, + "preserve other targets when setting sleep delay": { + args: []string{"--light-sleep-delay", "5m"}, + minScale: 0, + currentTargets: []koyeb.DeploymentScalingTarget{ + { + AverageCpu: &koyeb.DeploymentScalingTargetAverageCPU{ + Value: koyeb.PtrInt64(80), + }, + }, + }, + expected: []koyeb.DeploymentScalingTarget{ + { + AverageCpu: &koyeb.DeploymentScalingTargetAverageCPU{ + Value: koyeb.PtrInt64(80), + }, + }, + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + }, + }, + }, + }, + "no flags does not modify targets": { + args: []string{}, + minScale: 0, + currentTargets: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + }, + }, + }, + expected: []koyeb.DeploymentScalingTarget{ + { + SleepIdleDelay: &koyeb.DeploymentScalingTargetSleepIdleDelay{ + LightSleepValue: koyeb.PtrInt64(300), + }, + }, + }, + }, + "error when min-scale is not zero with light-sleep-delay": { + args: []string{"--light-sleep-delay", "5m"}, + minScale: 1, + expectedErr: true, + }, + "error when min-scale is not zero with deep-sleep-delay": { + args: []string{"--deep-sleep-delay", "30m"}, + minScale: 1, + expectedErr: true, + }, + "error when min-scale is not zero with both sleep delays": { + args: []string{"--light-sleep-delay", "5m", "--deep-sleep-delay", "30m"}, + minScale: 2, + expectedErr: true, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + cmd := &cobra.Command{} + h := NewServiceHandler() + h.addServiceDefinitionFlags(cmd.Flags()) + + err := cmd.ParseFlags(tc.args) + assert.NoError(t, err) + + scaling := koyeb.NewDeploymentScalingWithDefaults() + scaling.SetMin(tc.minScale) + scaling.SetMax(1) + scaling.Targets = tc.currentTargets + + err = h.setScalingsTargets(cmd.Flags(), scaling) + if tc.expectedErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tc.expected, scaling.Targets) + } + }) + } +}