├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.yaml
│ ├── config.yml
│ └── feature_request.yaml
└── workflows
│ ├── build.yml
│ ├── close-inactive-issues.yml
│ ├── docker-amd-smi.yml
│ ├── docker-dind.yml
│ ├── docker-efa.yml
│ ├── docker.yml
│ ├── docs.yaml
│ ├── gcp-a3mega-image.yml
│ └── release.yml
├── .gitignore
├── .justfile
├── .pre-commit-config.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── contributing
├── ARCHITECTURE.md
├── AUTOSCALING.md
├── BACKENDS.md
├── DEVELOPMENT.md
├── FRONTEND.md
├── GPUHUNT.md
├── LOCKING.md
├── MIGRATIONS.md
├── PROXY.md
├── RUNNER-AND-SHIM.md
└── RUNS-AND-JOBS.md
├── docker
├── amd-smi
│ ├── Dockerfile
│ └── README.md
├── base
│ ├── Dockerfile
│ └── README.md
├── dind
│ ├── Dockerfile
│ ├── README.md
│ └── start-dockerd
├── efa
│ ├── Dockerfile
│ └── README.md
└── server
│ ├── README.md
│ ├── entrypoint.sh
│ ├── release
│ └── Dockerfile
│ └── stgn
│ └── Dockerfile
├── docs
├── CNAME
├── assets
│ ├── images
│ │ ├── aws-logo.svg
│ │ ├── azure-logo.svg
│ │ ├── cats-in-hats.png
│ │ ├── chevron-down.svg
│ │ ├── cudo-logo.svg
│ │ ├── datacrunch-logo.svg
│ │ ├── discord-logo.svg
│ │ ├── dstack-cli.png
│ │ ├── dstack-code-dark.png
│ │ ├── dstack-dev-environments-code.png
│ │ ├── dstack-dolly-code.png
│ │ ├── dstack-dolly.png
│ │ ├── dstack-fav-32.ico
│ │ ├── dstack-fine-tuning-diagram.png
│ │ ├── dstack-finetuning-hf.png
│ │ ├── dstack-finetuning-wandb.png
│ │ ├── dstack-google-colab.png
│ │ ├── dstack-gradio-falcon.png
│ │ ├── dstack-hub-create-aws-project.png
│ │ ├── dstack-hub-create-azure-project.png
│ │ ├── dstack-hub-create-gcp-project.png
│ │ ├── dstack-hub-create-lambda-project.png
│ │ ├── dstack-hub-create-project.png
│ │ ├── dstack-hub-edit-gateway.png
│ │ ├── dstack-hub-view-project-empty.png
│ │ ├── dstack-hub-view-project.png
│ │ ├── dstack-huggingface-space.png
│ │ ├── dstack-jupyterlab.png
│ │ ├── dstack-lambda-api-key.png
│ │ ├── dstack-llmchat-discord-chat.png
│ │ ├── dstack-llmchat-gallery.png
│ │ ├── dstack-logo-dark.svg
│ │ ├── dstack-logo-notext.png
│ │ ├── dstack-logo-notext.svg
│ │ ├── dstack-logo.svg
│ │ ├── dstack-mixtral-chat-ui.png
│ │ ├── dstack-playground-github-actions-ui.png
│ │ ├── dstack-run-artifacts.png
│ │ ├── dstack-runpod-dev-environment.png
│ │ ├── dstack-server-output-2.png
│ │ ├── dstack-stable-diffusion-code.png
│ │ ├── dstack-stable-diffusion.png
│ │ ├── dstack-tensorboard.png
│ │ ├── dstack-train-artifacts.png
│ │ ├── dstack-v010-vscode-desktop.png
│ │ ├── dstack-vscode-jupyter.png
│ │ ├── dstack-vscode.png
│ │ ├── gcp-logo.svg
│ │ ├── github-logo.svg
│ │ ├── hero_code_background.png
│ │ ├── hotaisle-logo.svg
│ │ ├── jb-toolbox-logo.svg
│ │ ├── jupyter-logo.svg
│ │ ├── kapa.svg
│ │ ├── kubernetes-logo.svg
│ │ ├── lambda-logo.svg
│ │ ├── logo.svg
│ │ ├── minus.svg
│ │ ├── nebius-logo.svg
│ │ ├── oci-logo.svg
│ │ ├── plus.svg
│ │ ├── runpod-logo.svg
│ │ ├── ssh-logo.svg
│ │ ├── tensordock-logo.svg
│ │ ├── tensorwave-logo.svg
│ │ ├── vastai-logo.svg
│ │ ├── vscode-logo.svg
│ │ └── vultr-logo.svg
│ ├── javascripts
│ │ ├── extra.js
│ │ ├── pricing.js
│ │ └── termynal.js
│ └── stylesheets
│ │ ├── extra.css
│ │ ├── landing.css
│ │ ├── pricing.css
│ │ └── termynal.css
├── blog
│ ├── archive
│ │ └── ambassador-program.md
│ ├── index.md
│ └── posts
│ │ ├── amd-mi300x-inference-benchmark.md
│ │ ├── amd-on-runpod.md
│ │ ├── amd-on-tensorwave.md
│ │ ├── beyond-kubernetes-2024-recap-and-whats-ahead.md
│ │ ├── cursor.md
│ │ ├── docker-inside-containers.md
│ │ ├── dstack-metrics.md
│ │ ├── dstack-sky-own-cloud-accounts.md
│ │ ├── dstack-sky.md
│ │ ├── ea-gtc25.md
│ │ ├── efa.md
│ │ ├── gh200-on-lambda.md
│ │ ├── gpu-blocks-and-proxy-jump.md
│ │ ├── h100-mi300x-inference-benchmark.md
│ │ ├── h200-mi300x-deepskeek-benchmark.md
│ │ ├── images
│ │ ├── dstack-diagram-stack-3.png
│ │ ├── dstack-research-banner-2.png
│ │ └── dstack-sky-banner-4.png
│ │ ├── inactivity-duration.md
│ │ ├── instance-volumes.md
│ │ ├── intel-gaudi.md
│ │ ├── metrics-ui.md
│ │ ├── mpi.md
│ │ ├── nebius.md
│ │ ├── nvidia-and-amd-on-vultr.md
│ │ ├── prometheus.md
│ │ ├── tpu-on-gcp.md
│ │ └── volumes-on-runpod.md
├── docs
│ ├── concepts
│ │ ├── backends.md
│ │ ├── dev-environments.md
│ │ ├── fleets.md
│ │ ├── gateways.md
│ │ ├── projects.md
│ │ ├── repos.md
│ │ ├── services.md
│ │ ├── snippets
│ │ │ ├── manage-fleets.ext
│ │ │ └── manage-runs.ext
│ │ ├── tasks.md
│ │ └── volumes.md
│ ├── guides
│ │ ├── clusters.md
│ │ ├── dstack-sky.md
│ │ ├── metrics.md
│ │ ├── plugins.md
│ │ ├── protips.md
│ │ ├── server-deployment.md
│ │ └── troubleshooting.md
│ ├── index.md
│ ├── installation
│ │ └── index.md
│ ├── quickstart.md
│ └── reference
│ │ ├── api
│ │ ├── python
│ │ │ └── index.md
│ │ └── rest
│ │ │ └── index.md
│ │ ├── cli
│ │ └── dstack
│ │ │ ├── apply.md
│ │ │ ├── attach.md
│ │ │ ├── config.md
│ │ │ ├── delete.md
│ │ │ ├── fleet.md
│ │ │ ├── gateway.md
│ │ │ ├── init.md
│ │ │ ├── logs.md
│ │ │ ├── metrics.md
│ │ │ ├── offer.md
│ │ │ ├── project.md
│ │ │ ├── ps.md
│ │ │ ├── server.md
│ │ │ ├── stop.md
│ │ │ └── volume.md
│ │ ├── dstack.yml.md
│ │ ├── dstack.yml
│ │ ├── dev-environment.md
│ │ ├── fleet.md
│ │ ├── gateway.md
│ │ ├── service.md
│ │ ├── task.md
│ │ └── volume.md
│ │ ├── environment-variables.md
│ │ ├── plugins
│ │ └── rest_plugin
│ │ │ └── index.md
│ │ ├── profiles.yml.md
│ │ └── server
│ │ └── config.yml.md
├── examples.md
├── examples
│ ├── accelerators
│ │ ├── amd
│ │ │ └── index.md
│ │ ├── intel
│ │ │ └── index.md
│ │ ├── tenstorrent
│ │ │ └── index.md
│ │ └── tpu
│ │ │ └── index.md
│ ├── clusters
│ │ ├── a3high
│ │ │ └── index.md
│ │ ├── a3mega
│ │ │ └── index.md
│ │ ├── nccl-tests
│ │ │ └── index.md
│ │ └── rccl-tests
│ │ │ └── index.md
│ ├── distributed-training
│ │ ├── axolotl
│ │ │ └── index.md
│ │ ├── ray-ragen
│ │ │ └── index.md
│ │ └── trl
│ │ │ └── index.md
│ ├── inference
│ │ ├── nim
│ │ │ └── index.md
│ │ ├── sglang
│ │ │ └── index.md
│ │ ├── tgi
│ │ │ └── index.md
│ │ ├── trtllm
│ │ │ └── index.md
│ │ └── vllm
│ │ │ └── index.md
│ ├── llms
│ │ ├── deepseek
│ │ │ └── index.md
│ │ └── llama
│ │ │ └── index.md
│ ├── misc
│ │ └── docker-compose
│ │ │ └── index.md
│ └── single-node-training
│ │ ├── axolotl
│ │ └── index.md
│ │ └── trl
│ │ └── index.md
├── index.md
├── layouts
│ └── custom.yml
├── overrides
│ ├── .icons
│ │ └── custom
│ │ │ ├── colored
│ │ │ ├── discord.svg
│ │ │ ├── github.svg
│ │ │ └── twitter.svg
│ │ │ └── github.svg
│ ├── assets
│ │ └── images
│ │ │ ├── github-logo.png
│ │ │ ├── hero.svg
│ │ │ ├── new.svg
│ │ │ ├── quotes
│ │ │ ├── alvarobartt.jpg
│ │ │ ├── chansung.jpg
│ │ │ ├── cudopete.png
│ │ │ ├── eckart.png
│ │ │ ├── movchan.jpg
│ │ │ └── spott.jpg
│ │ │ ├── slack.png
│ │ │ └── twitter.png
│ ├── header-2.html
│ ├── header.html
│ ├── home.html
│ ├── landing.html
│ ├── main.html
│ ├── partials
│ │ └── post.html
│ ├── path.html
│ ├── pricing.html
│ ├── privacy.html
│ ├── toc-item.html
│ └── toc.html
├── partners.md
├── privacy.md
└── terms.md
├── examples
├── .dstack.yml
├── __init__.py
├── accelerators
│ ├── amd
│ │ └── README.md
│ ├── intel
│ │ └── README.md
│ ├── tenstorrent
│ │ ├── .dstack.yml
│ │ ├── README.md
│ │ ├── tt-inference-server.dstack.yml
│ │ └── tt-smi.dstack.yml
│ └── tpu
│ │ └── README.md
├── clusters
│ ├── a3high
│ │ ├── README.md
│ │ ├── fleet.dstack.yml
│ │ └── nccl-tests.dstack.yml
│ ├── a3mega
│ │ ├── README.md
│ │ ├── fleet.dstack.yml
│ │ └── nccl-tests.dstack.yml
│ ├── nccl-tests
│ │ ├── .dstack.yml
│ │ └── README.md
│ └── rccl-tests
│ │ ├── .dstack.yml
│ │ └── README.md
├── distributed-training
│ ├── axolotl
│ │ ├── .dstack.yml
│ │ └── README.md
│ ├── ray-ragen
│ │ ├── .dstack.yml
│ │ └── README.md
│ ├── torchrun
│ │ └── .dstack.yml
│ └── trl
│ │ ├── README.md
│ │ ├── deepspeed.dstack.yml
│ │ └── fsdp.dstack.yml
├── inference
│ ├── nim
│ │ ├── .dstack.yml
│ │ └── README.md
│ ├── sglang
│ │ └── README.md
│ ├── tgi
│ │ ├── .dstack.yml
│ │ ├── README.md
│ │ ├── amd
│ │ │ └── .dstack.yml
│ │ └── tpu
│ │ │ └── .dstack.yml
│ ├── trtllm
│ │ ├── README.md
│ │ ├── build-image.dstack.yml
│ │ ├── build-model.dstack.yml
│ │ ├── convert-model.dstack.yml
│ │ ├── serve-distill.dstack.yml
│ │ └── serve-r1.dstack.yml
│ └── vllm
│ │ ├── .dstack.yml
│ │ ├── README.md
│ │ ├── amd
│ │ ├── .dstack.yml
│ │ └── build-vllm.dstack.yml
│ │ └── tpu
│ │ └── .dstack.yml
├── llms
│ ├── deepseek
│ │ ├── README.md
│ │ ├── sglang
│ │ │ ├── amd
│ │ │ │ ├── .dstack.yml
│ │ │ │ └── deepseek_v2_lite.dstack.yml
│ │ │ └── nvidia
│ │ │ │ ├── .dstack.yml
│ │ │ │ └── deepseek_v2_lite.dstack.yml
│ │ ├── tgi
│ │ │ └── intel
│ │ │ │ └── .dstack.yml
│ │ ├── trl
│ │ │ ├── amd
│ │ │ │ ├── .dstack.yml
│ │ │ │ ├── deepseek_v2.dstack.yml
│ │ │ │ ├── grpo.dstack.yml
│ │ │ │ └── grpo_train.py
│ │ │ ├── intel
│ │ │ │ ├── .dstack.yml
│ │ │ │ └── deepseek_v2.dstack.yml
│ │ │ └── nvidia
│ │ │ │ ├── .dstack.yml
│ │ │ │ └── deepseek_v2.dstack.yml
│ │ └── vllm
│ │ │ ├── amd
│ │ │ ├── .dstack.yml
│ │ │ └── deepseek_v2_lite.dstack.yml
│ │ │ ├── intel
│ │ │ └── .dstack.yml
│ │ │ └── nvidia
│ │ │ ├── .dstack.yml
│ │ │ └── deepseek_v2_lite.dstack.yml
│ ├── llama
│ │ ├── README.md
│ │ ├── sglang
│ │ │ └── nvidia
│ │ │ │ └── .dstack.yml
│ │ └── vllm
│ │ │ ├── amd
│ │ │ └── .dstack.yml
│ │ │ └── nvidia
│ │ │ └── .dstack.yml
│ ├── llama31
│ │ └── README.md
│ └── llama32
│ │ ├── README.md
│ │ └── vllm
│ │ └── .dstack.yml
├── misc
│ ├── airflow
│ │ ├── README.md
│ │ └── dags
│ │ │ ├── dstack-repo
│ │ │ └── task.dstack.yml
│ │ │ └── dstack_tasks.py
│ ├── docker-compose
│ │ ├── .dstack.yml
│ │ ├── README.md
│ │ ├── compose.yaml
│ │ ├── service.dstack.yml
│ │ ├── task.dstack.yml
│ │ └── volume.dstack.yml
│ ├── http.server
│ │ ├── .dstack.yml
│ │ ├── README.md
│ │ └── task.dstack.yml
│ ├── jupyterlab
│ │ └── .dstack.yml
│ ├── ray
│ │ ├── README.md
│ │ ├── cluster.dstack.yaml
│ │ ├── fleet.dstack.yaml
│ │ └── tasks
│ │ │ ├── pytorch-mnist.py
│ │ │ └── quicksort.py
│ ├── spark
│ │ ├── README.md
│ │ ├── cluster.dstack.yaml
│ │ ├── fleet.dstack.yaml
│ │ ├── task.dstack.yaml
│ │ └── tasks
│ │ │ └── words.py
│ └── streamlit
│ │ ├── .dstack.yml
│ │ ├── README.md
│ │ └── task.dstack.yml
├── plugins
│ ├── __init__.py
│ ├── example_plugin
│ │ ├── .python-version
│ │ ├── Dockerfile
│ │ ├── README.md
│ │ ├── enterprise.Dockerfile
│ │ ├── pyproject.toml
│ │ └── src
│ │ │ └── example_plugin
│ │ │ ├── __init__.py
│ │ │ └── py.typed
│ └── example_plugin_server
│ │ ├── .python-version
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── pyproject.toml
│ │ └── src
│ │ └── example_plugin_server
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── utils.py
├── server-deployment
│ └── cloudformation
│ │ ├── README.md
│ │ └── template.yaml
└── single-node-training
│ ├── axolotl
│ ├── .dstack.yml
│ ├── README.md
│ ├── amd
│ │ ├── .dstack.yml
│ │ ├── build-flash-attention.yml
│ │ └── build-xformers.dstack.yml
│ └── config.yaml
│ ├── optimum-tpu
│ └── llama31
│ │ ├── .dstack.yml
│ │ ├── config.yaml
│ │ └── train.py
│ ├── qlora
│ ├── .dstack.yml
│ ├── README.md
│ ├── requirements.txt
│ └── train.py
│ └── trl
│ ├── README.md
│ ├── amd
│ ├── .dstack.yml
│ └── train.py
│ └── train.dstack.yml
├── frontend
├── .babelrc
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .prettierrc
├── jest.config.ts
├── openapi-config.ts
├── package-lock.json
├── package.json
├── public
│ ├── index.html
│ ├── manifest.json
│ └── robots.txt
├── setupEnzyme.ts
├── src
│ ├── App
│ │ ├── AuthErrorMessage
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ ├── Loading
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ ├── Login
│ │ │ ├── EnterpriseLogin
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── EntraID
│ │ │ │ ├── LoginByEntraID
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ └── LoginByEntraIDCallback
│ │ │ │ │ └── index.tsx
│ │ │ ├── LoginByGithub
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── LoginByGithubCallback
│ │ │ │ └── index.tsx
│ │ │ ├── LoginByOkta
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── LoginByOktaCallback
│ │ │ │ └── index.tsx
│ │ │ ├── LoginByTokenForm
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ └── TokenLogin
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ ├── Logout
│ │ │ └── index.tsx
│ │ ├── constants.ts
│ │ ├── helpers.ts
│ │ ├── index.tsx
│ │ ├── slice.ts
│ │ └── types.ts
│ ├── api.ts
│ ├── assets
│ │ ├── css
│ │ │ ├── index.css
│ │ │ ├── mixins.css
│ │ │ └── variables.css
│ │ ├── icons
│ │ │ ├── .gitkeep
│ │ │ ├── entraID.svg
│ │ │ ├── github.svg
│ │ │ ├── okta.svg
│ │ │ └── theme.svg
│ │ └── images
│ │ │ ├── .gitkeep
│ │ │ ├── favicon.png
│ │ │ └── logo.svg
│ ├── components
│ │ ├── Button
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ ├── ButtonWithConfirmation
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── Code
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ ├── ConfirmationDialog
│ │ │ ├── index.tsx
│ │ │ ├── styles.module.scss
│ │ │ └── types.ts
│ │ ├── DetailsHeader
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── FileUploader
│ │ │ ├── FileEntry
│ │ │ │ └── index.tsx
│ │ │ ├── Token
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ └── index.tsx
│ │ ├── Hotspot
│ │ │ └── index.tsx
│ │ ├── InfoLink
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── ListEmptyMessage
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── Loader
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ ├── NavigateLink
│ │ │ └── index.tsx
│ │ ├── Notifications
│ │ │ ├── index.tsx
│ │ │ ├── slice.ts
│ │ │ └── types.ts
│ │ ├── PermissionGuard
│ │ │ ├── index.tsx
│ │ │ └── types.ts
│ │ ├── Tabs
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ ├── form
│ │ │ ├── Checkbox
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── CodeEditor
│ │ │ │ ├── constants.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Input
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Multiselect
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── RadioButtons
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── S3BucketSelector
│ │ │ │ ├── index.tsx
│ │ │ │ ├── styles.module.scss
│ │ │ │ ├── types.ts
│ │ │ │ └── utils.ts
│ │ │ ├── Select
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Textarea
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ └── Tiles
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ └── index.ts
│ ├── consts.ts
│ ├── consts
│ │ └── index.ts
│ ├── hooks
│ │ ├── index.ts
│ │ ├── useAppDispatch.ts
│ │ ├── useAppSelector.ts
│ │ ├── useBreadcrumbs.ts
│ │ ├── useHelpPanel.ts
│ │ ├── useInfiniteScroll.ts
│ │ ├── useIsMounted.ts
│ │ ├── useLocalStorageState.ts
│ │ ├── useNotifications.ts
│ │ ├── useOnClickOutside.ts
│ │ ├── usePermissionGuard.ts
│ │ ├── usePrevious.ts
│ │ └── useProjectFilter.ts
│ ├── index.tsx
│ ├── layouts
│ │ ├── AppLayout
│ │ │ ├── AnnotationContext
│ │ │ │ └── index.tsx
│ │ │ ├── Tally
│ │ │ │ └── index.tsx
│ │ │ ├── TutorialPanel
│ │ │ │ ├── constants.tsx
│ │ │ │ ├── hooks.ts
│ │ │ │ └── index.tsx
│ │ │ ├── hooks.ts
│ │ │ ├── index.module.scss
│ │ │ ├── index.tsx
│ │ │ └── themeIcons.tsx
│ │ └── UnauthorizedLayout
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ ├── libs
│ │ ├── fetchBaseQueryHeaders.ts
│ │ ├── fleet.ts
│ │ ├── form.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── run.ts
│ │ ├── serverErrors.ts
│ │ ├── types.ts
│ │ └── volumes.ts
│ ├── locale
│ │ ├── en.json
│ │ └── index.ts
│ ├── pages
│ │ ├── Fleets
│ │ │ ├── Details
│ │ │ │ └── index.tsx
│ │ │ ├── List
│ │ │ │ ├── hooks.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── styles.module.scss
│ │ │ │ └── useDeleteFleet.ts
│ │ │ └── index.ts
│ │ ├── Instances
│ │ │ ├── List
│ │ │ │ ├── hooks
│ │ │ │ │ ├── useActions.ts
│ │ │ │ │ ├── useColumnDefinitions.tsx
│ │ │ │ │ ├── useEmptyMessage.tsx
│ │ │ │ │ └── useFilters.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ └── index.ts
│ │ ├── Models
│ │ │ ├── Details
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── index.tsx
│ │ │ │ ├── styles.module.scss
│ │ │ │ └── types.ts
│ │ │ ├── List
│ │ │ │ ├── Preferences
│ │ │ │ │ ├── consts.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── useModelListPreferences.ts
│ │ │ │ ├── constants.ts
│ │ │ │ ├── hooks.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── styles.module.scss
│ │ │ │ └── types.ts
│ │ │ ├── helpers.ts
│ │ │ └── index.ts
│ │ ├── Project
│ │ │ ├── Add
│ │ │ │ └── index.tsx
│ │ │ ├── Backends
│ │ │ │ ├── Add
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Edit
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Table
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ ├── hooks
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── useColumnsDefinitions.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── types.ts
│ │ │ │ ├── YAMLForm
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── hooks
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── useBackendsTable.ts
│ │ │ │ └── index.tsx
│ │ │ ├── Details
│ │ │ │ ├── Settings
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ └── index.tsx
│ │ │ ├── Form
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Gateways
│ │ │ │ ├── Add
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ ├── Edit
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ ├── Table
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ ├── hooks
│ │ │ │ │ │ ├── index.ts
│ │ │ │ │ │ └── useColumnsDefinitions.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── types.ts
│ │ │ │ ├── hooks
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── useGatewaysTable.ts
│ │ │ │ └── index.tsx
│ │ │ ├── List
│ │ │ │ ├── hooks
│ │ │ │ │ ├── index.ts
│ │ │ │ │ └── useColumnsDefinitions.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── Members
│ │ │ │ ├── UsersAutosuggest
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ ├── styles.module.scss
│ │ │ │ └── types.ts
│ │ │ ├── hooks
│ │ │ │ ├── useCheckAvailableProjectPermission.ts
│ │ │ │ ├── useConfigProjectCliComand.ts
│ │ │ │ └── useDeleteProject.ts
│ │ │ ├── index.tsx
│ │ │ └── utils.ts
│ │ ├── Runs
│ │ │ ├── Details
│ │ │ │ ├── Artifacts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── types.ts
│ │ │ │ ├── Jobs
│ │ │ │ │ ├── Details
│ │ │ │ │ │ ├── JobDetails
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── styles.module.scss
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── styles.module.scss
│ │ │ │ │ ├── List
│ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ ├── hooks.tsx
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── Metrics
│ │ │ │ │ │ ├── consts.ts
│ │ │ │ │ │ ├── helpers.ts
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── useMetricsData.ts
│ │ │ │ ├── Logs
│ │ │ │ │ ├── helpers.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ ├── styles.module.scss
│ │ │ │ │ └── types.ts
│ │ │ │ ├── RunDetails
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── List
│ │ │ │ ├── Preferences
│ │ │ │ │ ├── consts.ts
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── useRunListPreferences.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── hooks
│ │ │ │ │ ├── index.ts
│ │ │ │ │ ├── useColumnsDefinitions.tsx
│ │ │ │ │ ├── useDeleteRuns.ts
│ │ │ │ │ ├── useDisabledStatesForButtons.ts
│ │ │ │ │ ├── useEmptyMessages.tsx
│ │ │ │ │ ├── useFilters.ts
│ │ │ │ │ └── useStopRuns.ts
│ │ │ │ ├── index.tsx
│ │ │ │ └── styles.module.scss
│ │ │ ├── constants.ts
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ ├── User
│ │ │ ├── Add
│ │ │ │ └── index.tsx
│ │ │ ├── Details
│ │ │ │ ├── Billing
│ │ │ │ │ ├── PayForm
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── types.ts
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── AmountField
│ │ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ │ └── styles.module.scss
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── CreditsHistory
│ │ │ │ │ ├── Add
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── types.ts
│ │ │ │ │ ├── constants.tsx
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── types.ts
│ │ │ │ ├── Payments
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── types.ts
│ │ │ │ ├── Projects
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── Settings
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.module.scss
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── Edit
│ │ │ │ └── index.tsx
│ │ │ ├── Form
│ │ │ │ ├── index.tsx
│ │ │ │ └── types.ts
│ │ │ ├── List
│ │ │ │ └── index.tsx
│ │ │ └── index.tsx
│ │ └── Volumes
│ │ │ ├── List
│ │ │ ├── hooks.tsx
│ │ │ ├── index.tsx
│ │ │ └── styles.module.scss
│ │ │ └── index.ts
│ ├── router.tsx
│ ├── routes.ts
│ ├── services
│ │ ├── artifact.ts
│ │ ├── auth.ts
│ │ ├── backend.ts
│ │ ├── fleet.ts
│ │ ├── gateway.ts
│ │ ├── instance.ts
│ │ ├── mainApi.ts
│ │ ├── project.ts
│ │ ├── run.ts
│ │ ├── server.ts
│ │ ├── user.ts
│ │ └── volume.ts
│ ├── setupTests.ts
│ ├── store.ts
│ └── types
│ │ ├── artifact.d.ts
│ │ ├── aws-backend.d.ts
│ │ ├── azure-backend.d.ts
│ │ ├── backend.d.ts
│ │ ├── bread-crums.d.ts
│ │ ├── fleet.d.ts
│ │ ├── gateway.d.ts
│ │ ├── gcp-backend.d.ts
│ │ ├── global.d.ts
│ │ ├── i18next.d.ts
│ │ ├── index.ts
│ │ ├── instance.d.ts
│ │ ├── labmda-backend.d.ts
│ │ ├── log.d.ts
│ │ ├── payment.d.ts
│ │ ├── project.d.ts
│ │ ├── repo.d.ts
│ │ ├── run.d.ts
│ │ ├── user.d.ts
│ │ └── volume.d.ts
├── staticServer.js
├── tests
│ ├── __mocks__
│ │ ├── MockStore.tsx
│ │ ├── fileMock.ts
│ │ ├── shim.ts
│ │ └── svgrMock.ts
│ └── setupEnzyme.ts
├── tsconfig.json
├── webpack.config.js
└── webpack
│ ├── base.js
│ ├── dev.js
│ ├── env.js
│ ├── getStyleLoaders.js
│ └── prod.js
├── gateway
├── README.md
├── pyproject.toml
└── src
│ ├── dstack
│ ├── __init__.py
│ └── gateway
│ │ ├── __init__.py
│ │ ├── main.py
│ │ ├── resources
│ │ └── systemd
│ │ │ ├── dstack.gateway.service
│ │ │ ├── start.sh
│ │ │ └── update.sh
│ │ ├── systemd
│ │ ├── __init__.py
│ │ └── __main__.py
│ │ └── version.py
│ └── tests
│ └── __init__.py
├── mkdocs.yml
├── pyproject.toml
├── pytest.ini
├── ruff.toml
├── runner
├── .golangci.yml
├── .justfile
├── README.md
├── cmd
│ ├── runner
│ │ ├── cmd.go
│ │ └── main.go
│ └── shim
│ │ └── main.go
├── consts
│ └── consts.go
├── docs
│ └── shim.openapi.yaml
├── go.mod
├── go.sum
└── internal
│ ├── api
│ └── common.go
│ ├── common
│ ├── gpu.go
│ ├── interpolator.go
│ ├── interpolator_test.go
│ └── string.go
│ ├── connections
│ ├── connections.go
│ └── connections_test.go
│ ├── executor
│ ├── base.go
│ ├── env.go
│ ├── env_test.go
│ ├── exec.go
│ ├── exec_test.go
│ ├── executor.go
│ ├── executor_test.go
│ ├── lock.go
│ ├── logs.go
│ ├── query.go
│ ├── repo.go
│ ├── states.go
│ ├── timestamp.go
│ └── timestamp_test.go
│ ├── gerrors
│ └── stacktrace.go
│ ├── log
│ └── log.go
│ ├── metrics
│ ├── metrics.go
│ └── metrics_test.go
│ ├── repo
│ ├── diff.go
│ ├── diff_test.go
│ └── manager.go
│ ├── runner
│ └── api
│ │ ├── http.go
│ │ ├── server.go
│ │ └── ws.go
│ ├── schemas
│ └── schemas.go
│ ├── shim
│ ├── api
│ │ ├── api_test.go
│ │ ├── handlers.go
│ │ ├── handlers_test.go
│ │ ├── schemas.go
│ │ └── server.go
│ ├── authorized_keys.go
│ ├── authorized_keys_test.go
│ ├── backends
│ │ ├── aws.go
│ │ ├── base.go
│ │ └── gcp.go
│ ├── dcgm
│ │ ├── exporter.go
│ │ ├── metrics.go
│ │ └── metrics_test.go
│ ├── docker.go
│ ├── docker_test.go
│ ├── errs.go
│ ├── host
│ │ ├── gpu.go
│ │ └── host.go
│ ├── host_info.go
│ ├── models.go
│ ├── resources.go
│ ├── resources_test.go
│ ├── runner.go
│ ├── task.go
│ └── task_test.go
│ └── types
│ └── types.go
├── scripts
├── add_backend.py
├── build_frontend.sh
├── docs
│ ├── gen_cli_reference.py
│ ├── gen_examples.py
│ ├── gen_openapi_reference.py
│ ├── gen_rest_plugin_spec_reference.py
│ └── gen_schema_reference.py
├── oci_image_tools.py
├── packer
│ ├── README.md
│ ├── aws-image-cuda.json
│ ├── aws-image.json
│ ├── aws-vars-prod.json
│ ├── azure-image-cuda.json
│ ├── azure-image-grid.json
│ ├── azure-image.json
│ ├── build-cuda-image.pkr.hcl
│ ├── build-image.pkr.hcl
│ ├── config.pkr.hcl
│ ├── gcp-a3mega-image.json
│ ├── gcp-image-cuda.json
│ ├── gcp-image.json
│ ├── locals.pkr.hcl
│ ├── oci-image-cuda.json
│ ├── oci-image.json
│ ├── provisioners
│ │ ├── cuda.sh
│ │ ├── install-docker.sh
│ │ ├── install-nvidia-container-toolkit.sh
│ │ ├── install-nvidia-grid-driver-for-azure.sh
│ │ ├── kernel
│ │ │ ├── apt-daily.sh
│ │ │ ├── apt-packages.sh
│ │ │ ├── apt-upgrade.sh
│ │ │ └── kernel-tuning.sh
│ │ ├── pull-docker-images.sh
│ │ ├── run-docker
│ │ └── wait-for-dpkg-lock.sh
│ ├── variables.pkr.hcl
│ └── versions.json
├── publish_azure_image.sh
└── sqlite_to_psql.load
└── src
├── dstack
├── __init__.py
├── _internal
│ ├── __init__.py
│ ├── cli
│ │ ├── __init__.py
│ │ ├── commands
│ │ │ ├── __init__.py
│ │ │ ├── apply.py
│ │ │ ├── attach.py
│ │ │ ├── completion.py
│ │ │ ├── config.py
│ │ │ ├── delete.py
│ │ │ ├── fleet.py
│ │ │ ├── gateway.py
│ │ │ ├── init.py
│ │ │ ├── logs.py
│ │ │ ├── metrics.py
│ │ │ ├── offer.py
│ │ │ ├── project.py
│ │ │ ├── ps.py
│ │ │ ├── server.py
│ │ │ ├── stats.py
│ │ │ ├── stop.py
│ │ │ └── volume.py
│ │ ├── main.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── args.py
│ │ │ ├── completion.py
│ │ │ ├── configurators
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── fleet.py
│ │ │ │ ├── gateway.py
│ │ │ │ ├── run.py
│ │ │ │ └── volume.py
│ │ │ ├── profile.py
│ │ │ └── repos.py
│ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── fleet.py
│ │ │ ├── gateway.py
│ │ │ ├── rich.py
│ │ │ ├── run.py
│ │ │ ├── updates.py
│ │ │ └── volume.py
│ ├── compat.py
│ ├── core
│ │ ├── __init__.py
│ │ ├── backends
│ │ │ ├── __init__.py
│ │ │ ├── aws
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── models.py
│ │ │ │ └── resources.py
│ │ │ ├── azure
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── models.py
│ │ │ │ ├── resources.py
│ │ │ │ └── utils.py
│ │ │ ├── base
│ │ │ │ ├── __init__.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── models.py
│ │ │ │ └── offers.py
│ │ │ ├── configurators.py
│ │ │ ├── cudo
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_client.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ │ ├── datacrunch
│ │ │ │ ├── __init__.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ │ ├── dstack
│ │ │ │ ├── __init__.py
│ │ │ │ └── models.py
│ │ │ ├── gcp
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── features
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── tcpx.py
│ │ │ │ ├── models.py
│ │ │ │ └── resources.py
│ │ │ ├── kubernetes
│ │ │ │ ├── __init__.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── models.py
│ │ │ │ └── utils.py
│ │ │ ├── lambdalabs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_client.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ │ ├── local
│ │ │ │ ├── __init__.py
│ │ │ │ ├── backend.py
│ │ │ │ └── compute.py
│ │ │ ├── models.py
│ │ │ ├── nebius
│ │ │ │ ├── __init__.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── fabrics.py
│ │ │ │ ├── models.py
│ │ │ │ └── resources.py
│ │ │ ├── oci
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── models.py
│ │ │ │ ├── region.py
│ │ │ │ └── resources.py
│ │ │ ├── remote
│ │ │ │ ├── __init__.py
│ │ │ │ └── provisioning.py
│ │ │ ├── runpod
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_client.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ │ ├── template
│ │ │ │ ├── __init__.py
│ │ │ │ ├── backend.py.jinja
│ │ │ │ ├── compute.py.jinja
│ │ │ │ ├── configurator.py.jinja
│ │ │ │ └── models.py.jinja
│ │ │ ├── tensordock
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_client.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ │ ├── vastai
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_client.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ │ └── vultr
│ │ │ │ ├── __init__.py
│ │ │ │ ├── api_client.py
│ │ │ │ ├── backend.py
│ │ │ │ ├── compute.py
│ │ │ │ ├── configurator.py
│ │ │ │ └── models.py
│ │ ├── consts.py
│ │ ├── errors.py
│ │ ├── models
│ │ │ ├── __init__.py
│ │ │ ├── backends
│ │ │ │ ├── __init__.py
│ │ │ │ └── base.py
│ │ │ ├── common.py
│ │ │ ├── config.py
│ │ │ ├── configurations.py
│ │ │ ├── envs.py
│ │ │ ├── fleets.py
│ │ │ ├── gateways.py
│ │ │ ├── instances.py
│ │ │ ├── logs.py
│ │ │ ├── metrics.py
│ │ │ ├── placement.py
│ │ │ ├── profiles.py
│ │ │ ├── projects.py
│ │ │ ├── repos
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── local.py
│ │ │ │ ├── remote.py
│ │ │ │ └── virtual.py
│ │ │ ├── resources.py
│ │ │ ├── runs.py
│ │ │ ├── secrets.py
│ │ │ ├── server.py
│ │ │ ├── services.py
│ │ │ ├── unix.py
│ │ │ ├── users.py
│ │ │ └── volumes.py
│ │ └── services
│ │ │ ├── __init__.py
│ │ │ ├── api_client.py
│ │ │ ├── configs
│ │ │ └── __init__.py
│ │ │ ├── diff.py
│ │ │ ├── logs.py
│ │ │ ├── profiles.py
│ │ │ ├── repos.py
│ │ │ └── ssh
│ │ │ ├── __init__.py
│ │ │ ├── attach.py
│ │ │ ├── client.py
│ │ │ ├── ports.py
│ │ │ └── tunnel.py
│ ├── proxy
│ │ ├── __init__.py
│ │ ├── gateway
│ │ │ ├── __init__.py
│ │ │ ├── app.py
│ │ │ ├── auth.py
│ │ │ ├── const.py
│ │ │ ├── deps.py
│ │ │ ├── main.py
│ │ │ ├── models.py
│ │ │ ├── repo
│ │ │ │ ├── __init__.py
│ │ │ │ ├── repo.py
│ │ │ │ └── state_v1.py
│ │ │ ├── resources
│ │ │ │ └── nginx
│ │ │ │ │ ├── 00-log-format.conf
│ │ │ │ │ ├── entrypoint.jinja2
│ │ │ │ │ └── service.jinja2
│ │ │ ├── routers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ ├── config.py
│ │ │ │ ├── registry.py
│ │ │ │ └── stats.py
│ │ │ ├── schemas
│ │ │ │ ├── __init__.py
│ │ │ │ ├── common.py
│ │ │ │ ├── config.py
│ │ │ │ ├── registry.py
│ │ │ │ └── stats.py
│ │ │ ├── services
│ │ │ │ ├── __init__.py
│ │ │ │ ├── nginx.py
│ │ │ │ ├── registry.py
│ │ │ │ ├── server_client.py
│ │ │ │ └── stats.py
│ │ │ └── testing
│ │ │ │ ├── __init__.py
│ │ │ │ └── common.py
│ │ └── lib
│ │ │ ├── __init__.py
│ │ │ ├── auth.py
│ │ │ ├── deps.py
│ │ │ ├── errors.py
│ │ │ ├── models.py
│ │ │ ├── repo.py
│ │ │ ├── routers
│ │ │ ├── __init__.py
│ │ │ └── model_proxy.py
│ │ │ ├── schemas
│ │ │ ├── __init__.py
│ │ │ └── model_proxy.py
│ │ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── model_proxy
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clients
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── openai.py
│ │ │ │ │ └── tgi.py
│ │ │ │ └── model_proxy.py
│ │ │ └── service_connection.py
│ │ │ └── testing
│ │ │ ├── __init__.py
│ │ │ ├── auth.py
│ │ │ └── common.py
│ ├── server
│ │ ├── __init__.py
│ │ ├── alembic.ini
│ │ ├── app.py
│ │ ├── background
│ │ │ ├── __init__.py
│ │ │ └── tasks
│ │ │ │ ├── __init__.py
│ │ │ │ ├── common.py
│ │ │ │ ├── process_fleets.py
│ │ │ │ ├── process_gateways.py
│ │ │ │ ├── process_instances.py
│ │ │ │ ├── process_metrics.py
│ │ │ │ ├── process_placement_groups.py
│ │ │ │ ├── process_prometheus_metrics.py
│ │ │ │ ├── process_running_jobs.py
│ │ │ │ ├── process_runs.py
│ │ │ │ ├── process_submitted_jobs.py
│ │ │ │ ├── process_terminating_jobs.py
│ │ │ │ └── process_volumes.py
│ │ ├── db.py
│ │ ├── deps.py
│ │ ├── main.py
│ │ ├── migrations
│ │ │ ├── __init__.py
│ │ │ ├── env.py
│ │ │ ├── script.py.mako
│ │ │ └── versions
│ │ │ │ ├── 065588ec72b8_add_vultr_to_backendtype_enum.py
│ │ │ │ ├── 0e33559e16ed_update_instancestatus.py
│ │ │ │ ├── 112753bc17dd_remove_nullable_fields.py
│ │ │ │ ├── 1338b788b612_reverse_job_instance_relationship.py
│ │ │ │ ├── 14f2cb002fc2_add_jobmodel_removed_flag.py
│ │ │ │ ├── 1a48dfe44a40_rework_termination_handling.py
│ │ │ │ ├── 1e3fb39ef74b_add_remote_connection_details.py
│ │ │ │ ├── 1e76fb0dde87_add_jobmodel_inactivity_secs.py
│ │ │ │ ├── 20166748b60c_add_jobmodel_disconnected_at.py
│ │ │ │ ├── 23e01c56279a_make_blob_nullable.py
│ │ │ │ ├── 252d3743b641_.py
│ │ │ │ ├── 27d3e55759fa_add_pools.py
│ │ │ │ ├── 29826f417010_remove_instancemodel_retry_policy.py
│ │ │ │ ├── 29c08c6a8cb3_.py
│ │ │ │ ├── 3cf77fb8bcf1_store_repo_clone_url.py
│ │ │ │ ├── 3dbdce90d0e0_fix_code_uq_constraint.py
│ │ │ │ ├── 48ad3ecbaea2_do_not_delete_projects_and_runs.py
│ │ │ │ ├── 4ae1a5b0e7f1_add_run_list_index.py
│ │ │ │ ├── 4b4319398164_introduce_runs_processing.py
│ │ │ │ ├── 51d45659d574_add_instancemodel_blocks_fields.py
│ │ │ │ ├── 54a77e19c64c_add_manager_project_role.py
│ │ │ │ ├── 555138b1f77f_change_instancemodel_for_asynchronous_.py
│ │ │ │ ├── 58aa5162dcc3_add_gatewaymodel_configuration.py
│ │ │ │ ├── 5ad8debc8fe6_fixes_for_psql.py
│ │ │ │ ├── 5ec538b70e71_replace_instansestatus.py
│ │ │ │ ├── 60e444118b6d_add_jobprometheusmetrics.py
│ │ │ │ ├── 63c3f19cb184_add_jobterminationreason_inactivity_.py
│ │ │ │ ├── 686fb8341ea5_add_user_emails.py
│ │ │ │ ├── 6c1a9d6530ee_add_jobmodel_exit_status.py
│ │ │ │ ├── 710e5b3fac8f_add_encryption.py
│ │ │ │ ├── 7b24b1c8eba7_add_instancemodel_last_processed_at.py
│ │ │ │ ├── 7ba3b59d7ca6_add_runmodel_resubmission_attempt.py
│ │ │ │ ├── 7bc2586e8b9e_make_instancemodel_pool_id_optional.py
│ │ │ │ ├── 803c7e9ed85d_add_jobmodel_job_runtime_data.py
│ │ │ │ ├── 82b32a135ea2_.py
│ │ │ │ ├── 866ec1d67184_replace_retrypolicy_limit_with_.py
│ │ │ │ ├── 91a12fff6c76_add_repocredsmodel.py
│ │ │ │ ├── 91ac5e543037_extend_repos_creds_column.py
│ │ │ │ ├── 98cd9c8b5927_add_volumemodel.py
│ │ │ │ ├── 98d1b92988bc_add_jobterminationreason_terminated_due_.py
│ │ │ │ ├── 99b4c8c954ea_add_termination_reason_message.py
│ │ │ │ ├── 9eea6af28e10_added_fail_reason_for_instancemodel.py
│ │ │ │ ├── __init__.py
│ │ │ │ ├── a060e2440936_.py
│ │ │ │ ├── a751ef183f27_move_attachment_data_to_volumes_.py
│ │ │ │ ├── a7b46c073fa1_add_placementgroupmodel.py
│ │ │ │ ├── afbc600ff2b2_add_created_at_to_usermodel_and_.py
│ │ │ │ ├── b4d6ad60db08_add_instancemodel_unreachable.py
│ │ │ │ ├── b88d55c2a07d_replace_instancestatus_ready.py
│ │ │ │ ├── bc8ca4a505c6_store_backendtype_as_string.py
│ │ │ │ ├── bca2fdf130bf_add_runmodel_priority.py
│ │ │ │ ├── bfba43f6def2_.py
│ │ │ │ ├── c00090eaef21_support_fleets.py
│ │ │ │ ├── c154eece89da_add_fields_for_async_gateway_creation.py
│ │ │ │ ├── c20626d03cfb_add_jobmetricspoint.py
│ │ │ │ ├── c48df7985d57_add_instance_termination_retries.py
│ │ │ │ ├── c83d45f9a971_replace_string_with_text.py
│ │ │ │ ├── d0bb68e48b9f_add_project_owners_and_quotas.py
│ │ │ │ ├── d3e8af4786fa_gateway_compute_flag_deleted.py
│ │ │ │ ├── d6b11105f659_add_usermodel_active.py
│ │ │ │ ├── da574e93fee0_add_jobmodel_volumes_detached_at.py
│ │ │ │ ├── dfffd6a1165c_add_fields_for_gateways_behind_alb.py
│ │ │ │ ├── e3b7db07727f_add_gatewaycomputemodel_app_updated_at.py
│ │ │ │ ├── e6391ca6a264_separate_gateways_from_compute.py
│ │ │ │ ├── ea60480f82bb_add_membermodel_member_num.py
│ │ │ │ ├── ed0ca30e13bb_migrate_instancestatus_provisioning.py
│ │ │ │ ├── fe72c4de8376_add_gateways.py
│ │ │ │ └── ffa99edd1988_add_jobterminationreason_max_duration_.py
│ │ ├── models.py
│ │ ├── routers
│ │ │ ├── __init__.py
│ │ │ ├── backends.py
│ │ │ ├── fleets.py
│ │ │ ├── gateways.py
│ │ │ ├── instances.py
│ │ │ ├── logs.py
│ │ │ ├── metrics.py
│ │ │ ├── projects.py
│ │ │ ├── prometheus.py
│ │ │ ├── repos.py
│ │ │ ├── runs.py
│ │ │ ├── secrets.py
│ │ │ ├── server.py
│ │ │ ├── users.py
│ │ │ └── volumes.py
│ │ ├── schemas
│ │ │ ├── __init__.py
│ │ │ ├── backends.py
│ │ │ ├── common.py
│ │ │ ├── fleets.py
│ │ │ ├── gateways.py
│ │ │ ├── instances.py
│ │ │ ├── logs.py
│ │ │ ├── projects.py
│ │ │ ├── repos.py
│ │ │ ├── runner.py
│ │ │ ├── runs.py
│ │ │ ├── secrets.py
│ │ │ ├── users.py
│ │ │ └── volumes.py
│ │ ├── security
│ │ │ ├── __init__.py
│ │ │ └── permissions.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ ├── backends
│ │ │ │ ├── __init__.py
│ │ │ │ └── handlers.py
│ │ │ ├── config.py
│ │ │ ├── docker.py
│ │ │ ├── encryption
│ │ │ │ ├── __init__.py
│ │ │ │ └── keys
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── aes.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ └── identity.py
│ │ │ ├── fleets.py
│ │ │ ├── gateways
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ ├── connection.py
│ │ │ │ └── pool.py
│ │ │ ├── instances.py
│ │ │ ├── jobs
│ │ │ │ ├── __init__.py
│ │ │ │ └── configurators
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── dev.py
│ │ │ │ │ ├── extensions
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── cursor.py
│ │ │ │ │ └── vscode.py
│ │ │ │ │ ├── service.py
│ │ │ │ │ └── task.py
│ │ │ ├── locking.py
│ │ │ ├── logging.py
│ │ │ ├── logs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── aws.py
│ │ │ │ ├── base.py
│ │ │ │ ├── filelog.py
│ │ │ │ └── gcp.py
│ │ │ ├── metrics.py
│ │ │ ├── offers.py
│ │ │ ├── permissions.py
│ │ │ ├── placement.py
│ │ │ ├── plugins.py
│ │ │ ├── projects.py
│ │ │ ├── prometheus.py
│ │ │ ├── proxy
│ │ │ │ ├── __init__.py
│ │ │ │ ├── auth.py
│ │ │ │ ├── deps.py
│ │ │ │ ├── repo.py
│ │ │ │ ├── routers
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── service_proxy.py
│ │ │ │ └── services
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── service_proxy.py
│ │ │ ├── repos.py
│ │ │ ├── resources.py
│ │ │ ├── runner
│ │ │ │ ├── __init__.py
│ │ │ │ ├── client.py
│ │ │ │ └── ssh.py
│ │ │ ├── runs.py
│ │ │ ├── services
│ │ │ │ ├── __init__.py
│ │ │ │ ├── autoscalers.py
│ │ │ │ └── options.py
│ │ │ ├── storage
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── gcs.py
│ │ │ │ └── s3.py
│ │ │ ├── users.py
│ │ │ └── volumes.py
│ │ ├── settings.py
│ │ ├── testing
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ └── conf.py
│ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── common.py
│ │ │ ├── logging.py
│ │ │ └── routers.py
│ ├── settings.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── common.py
│ │ ├── crypto.py
│ │ ├── dxf.py
│ │ ├── env.py
│ │ ├── event_loop.py
│ │ ├── gpu.py
│ │ ├── hash.py
│ │ ├── interpolator.py
│ │ ├── json_schema.py
│ │ ├── logging.py
│ │ ├── network.py
│ │ ├── path.py
│ │ ├── random_names.py
│ │ ├── ssh.py
│ │ └── tags.py
├── api
│ ├── __init__.py
│ ├── _public
│ │ ├── __init__.py
│ │ ├── backends.py
│ │ ├── repos.py
│ │ └── runs.py
│ ├── huggingface
│ │ └── __init__.py
│ ├── server
│ │ ├── __init__.py
│ │ ├── _backends.py
│ │ ├── _fleets.py
│ │ ├── _gateways.py
│ │ ├── _group.py
│ │ ├── _logs.py
│ │ ├── _metrics.py
│ │ ├── _projects.py
│ │ ├── _repos.py
│ │ ├── _runs.py
│ │ ├── _secrets.py
│ │ ├── _users.py
│ │ ├── _volumes.py
│ │ └── utils.py
│ └── utils.py
├── core
│ └── __init__.py
├── plugins
│ ├── __init__.py
│ ├── _base.py
│ ├── _models.py
│ ├── _utils.py
│ └── builtin
│ │ ├── __init__.py
│ │ └── rest_plugin
│ │ ├── __init__.py
│ │ ├── _models.py
│ │ └── _plugin.py
└── version.py
└── tests
├── __init__.py
├── _internal
├── __init__.py
├── cli
│ ├── __init__.py
│ ├── commands
│ │ ├── __init__.py
│ │ ├── test_config.py
│ │ ├── test_dstack.py
│ │ └── test_metrics.py
│ ├── common.py
│ ├── services
│ │ ├── __init__.py
│ │ └── configurators
│ │ │ ├── __init__.py
│ │ │ ├── test_fleet.py
│ │ │ ├── test_profile.py
│ │ │ └── test_run.py
│ └── utils
│ │ └── test_updates.py
├── core
│ ├── __init__.py
│ ├── backends
│ │ ├── __init__.py
│ │ ├── aws
│ │ │ ├── __init__.py
│ │ │ ├── test_configurator.py
│ │ │ └── test_resources.py
│ │ ├── azure
│ │ │ ├── __init__.py
│ │ │ ├── test_compute.py
│ │ │ ├── test_configurator.py
│ │ │ └── test_resources.py
│ │ ├── base
│ │ │ ├── __init__.py
│ │ │ └── test_compute.py
│ │ ├── cudo
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ │ ├── datacrunch
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ │ ├── gcp
│ │ │ ├── __init__.py
│ │ │ ├── test_configurator.py
│ │ │ └── test_resources.py
│ │ ├── kubernetes
│ │ │ ├── __init__.py
│ │ │ ├── test_compute.py
│ │ │ └── test_configurator.py
│ │ ├── lambdalabs
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ │ ├── oci
│ │ │ ├── __init__.py
│ │ │ ├── test_configurator.py
│ │ │ └── test_resources.py
│ │ ├── runpod
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ │ ├── tensordock
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ │ ├── vastai
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ │ └── vultr
│ │ │ ├── __init__.py
│ │ │ └── test_configurator.py
│ ├── models
│ │ ├── __init__.py
│ │ ├── repos
│ │ │ ├── __init__.py
│ │ │ ├── test_local.py
│ │ │ └── test_remote.py
│ │ ├── test_configurations.py
│ │ ├── test_instances.py
│ │ ├── test_resources.py
│ │ ├── test_runs.py
│ │ ├── test_unix.py
│ │ └── test_volumes.py
│ └── services
│ │ ├── __init__.py
│ │ ├── ssh
│ │ ├── __init__.py
│ │ ├── test_client.py
│ │ └── test_tunnel.py
│ │ └── test_logs.py
├── proxy
│ ├── __init__.py
│ ├── gateway
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── repo
│ │ │ ├── __init__.py
│ │ │ ├── test_repo.py
│ │ │ └── test_state_v1.py
│ │ ├── routers
│ │ │ ├── __init__.py
│ │ │ ├── test_registry.py
│ │ │ └── test_stats.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ └── test_stats.py
│ │ └── test_app.py
│ └── lib
│ │ ├── __init__.py
│ │ └── routers
│ │ ├── __init__.py
│ │ └── test_model_proxy.py
├── server
│ ├── __init__.py
│ ├── background
│ │ ├── __init__.py
│ │ └── tasks
│ │ │ ├── __init__.py
│ │ │ ├── test_process_fleets.py
│ │ │ ├── test_process_gateways.py
│ │ │ ├── test_process_instances.py
│ │ │ ├── test_process_metrics.py
│ │ │ ├── test_process_placement_groups.py
│ │ │ ├── test_process_prometheus_metrics.py
│ │ │ ├── test_process_running_jobs.py
│ │ │ ├── test_process_runs.py
│ │ │ ├── test_process_submitted_jobs.py
│ │ │ ├── test_process_submitted_volumes.py
│ │ │ └── test_process_terminating_jobs.py
│ ├── conftest.py
│ ├── routers
│ │ ├── __init__.py
│ │ ├── test_backends.py
│ │ ├── test_fleets.py
│ │ ├── test_gateways.py
│ │ ├── test_instances.py
│ │ ├── test_logs.py
│ │ ├── test_metrics.py
│ │ ├── test_projects.py
│ │ ├── test_prometheus.py
│ │ ├── test_repos.py
│ │ ├── test_runs.py
│ │ ├── test_server.py
│ │ ├── test_users.py
│ │ └── test_volumes.py
│ ├── services
│ │ ├── __init__.py
│ │ ├── backends
│ │ │ └── __init__.py
│ │ ├── encryption
│ │ │ ├── __init__.py
│ │ │ ├── keys
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_aes.py
│ │ │ └── test_encryption.py
│ │ ├── jobs
│ │ │ ├── __init__.py
│ │ │ └── configurators
│ │ │ │ ├── __init__.py
│ │ │ │ ├── test_base.py
│ │ │ │ └── test_task.py
│ │ ├── proxy
│ │ │ ├── __init__.py
│ │ │ └── routers
│ │ │ │ ├── __init__.py
│ │ │ │ └── test_service_proxy.py
│ │ ├── runner
│ │ │ ├── __init__.py
│ │ │ └── test_client.py
│ │ ├── services
│ │ │ ├── __init__.py
│ │ │ └── test_autoscalers.py
│ │ ├── test_config.py
│ │ ├── test_docker.py
│ │ ├── test_fleets.py
│ │ ├── test_instances.py
│ │ ├── test_logs.py
│ │ ├── test_metrics.py
│ │ ├── test_offers.py
│ │ ├── test_plugins.py
│ │ ├── test_repos.py
│ │ ├── test_runs.py
│ │ ├── test_users.py
│ │ └── test_volumes.py
│ ├── test_app.py
│ ├── test_migrations.py
│ └── utils
│ │ ├── __init__.py
│ │ ├── test_common.py
│ │ └── test_routers.py
└── utils
│ ├── __init__.py
│ ├── test_common.py
│ ├── test_env.py
│ ├── test_event_loop.py
│ ├── test_gpu.py
│ ├── test_interpolator.py
│ ├── test_network.py
│ ├── test_path.py
│ ├── test_ssh.py
│ └── test_tags.py
├── api
├── __init__.py
└── test_utils.py
├── conftest.py
└── plugins
├── __init__.py
└── test_rest_plugin.py
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Need help or have a question?
4 | url: https://discord.gg/u8SmfwPpMd
5 | about: Join our Discord server
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/__pycache__/
2 | *.py[co]
3 | *.egg-info
4 |
5 | dist/
6 | venv/
7 | /site/
8 | /.cache/
9 | .pytest_cache/
10 | .coverage
11 |
12 | .idea/
13 |
14 | /runner/cmd/shim/shim
15 | /runner/cmd/runner/runner
16 |
17 | /src/dstack/_internal/server/statics
18 |
19 | build/
20 | .DS_Store
21 | .fleet
22 | .env
23 | .envrc
24 | .vscode
25 | .aider*
26 | uv.lock
27 | .local/
28 |
--------------------------------------------------------------------------------
/.justfile:
--------------------------------------------------------------------------------
1 | # Root justfile
2 | #
3 | # This justfile serves as the main entry point to recipes from different components.
4 | #
5 | # Run `just` to see all available commands.
6 | #
7 | # Components:
8 | # * runner/justfile – Building and uploading dstack runner and shim
9 |
10 | default:
11 | @just --list
12 |
13 | set allow-duplicate-recipes
14 |
15 | import "runner/.justfile"
16 |
17 | # TODO: Add frontend/justfile for managing frontend development tasks
18 |
--------------------------------------------------------------------------------
/docker/amd-smi/README.md:
--------------------------------------------------------------------------------
1 | # dstack AMD SMI
2 |
3 | An Ubuntu-based image with [AMD SMI](https://rocm.docs.amd.com/projects/amdsmi/en/latest/) preinstalled. Suitable for AMD GPU detection.
4 |
5 | ## Usage
6 |
7 | ```shell
8 | docker run --rm --device /dev/kfd --device /dev/dri dstackai/amd-smi static
9 | ```
10 |
--------------------------------------------------------------------------------
/docker/base/README.md:
--------------------------------------------------------------------------------
1 | Image for `dstack` runner instances.
2 |
--------------------------------------------------------------------------------
/docker/efa/README.md:
--------------------------------------------------------------------------------
1 | # dstack AWS EFA
2 |
3 | This image has the following installed:
4 |
5 | * CUDA 12.1
6 | * AWS EFA Installer 1.38.1 (Libfabric + Open MPI 4 + Open MPI 5)
7 | * NCCL 2.26.2-1
8 | * AWS OFI NCCL 1.14.0
9 | * NCCL Tests
10 |
--------------------------------------------------------------------------------
/docker/server/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [ -n "${GOOGLE_APPLICATION_CREDENTIALS_JSON}" ]; then
5 | GOOGLE_APPLICATION_CREDENTIALS_DIR="${HOME}/.config/gcloud/"
6 | mkdir -p "${GOOGLE_APPLICATION_CREDENTIALS_DIR}"
7 | echo "${GOOGLE_APPLICATION_CREDENTIALS_JSON}" > "${GOOGLE_APPLICATION_CREDENTIALS_DIR}/application_default_credentials.json"
8 | fi
9 |
10 | if [[ -z "${LITESTREAM_REPLICA_URL}" ]]; then
11 | dstack server --host 0.0.0.0
12 | else
13 | litestream restore -if-replica-exists -o ${HOME}/.dstack/server/data/sqlite.db ${LITESTREAM_REPLICA_URL}
14 | litestream replicate -exec "dstack server --host 0.0.0.0" ${HOME}/.dstack/server/data/sqlite.db ${LITESTREAM_REPLICA_URL}
15 | fi
16 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | dstack.ai
2 |
--------------------------------------------------------------------------------
/docs/assets/images/cats-in-hats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/cats-in-hats.png
--------------------------------------------------------------------------------
/docs/assets/images/chevron-down.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/docs/assets/images/dstack-cli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-cli.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-code-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-code-dark.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-dev-environments-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-dev-environments-code.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-dolly-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-dolly-code.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-dolly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-dolly.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-fav-32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-fav-32.ico
--------------------------------------------------------------------------------
/docs/assets/images/dstack-fine-tuning-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-fine-tuning-diagram.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-finetuning-hf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-finetuning-hf.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-finetuning-wandb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-finetuning-wandb.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-google-colab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-google-colab.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-gradio-falcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-gradio-falcon.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-create-aws-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-create-aws-project.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-create-azure-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-create-azure-project.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-create-gcp-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-create-gcp-project.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-create-lambda-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-create-lambda-project.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-create-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-create-project.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-edit-gateway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-edit-gateway.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-view-project-empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-view-project-empty.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-hub-view-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-hub-view-project.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-huggingface-space.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-huggingface-space.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-jupyterlab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-jupyterlab.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-lambda-api-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-lambda-api-key.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-llmchat-discord-chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-llmchat-discord-chat.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-llmchat-gallery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-llmchat-gallery.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-logo-notext.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-logo-notext.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-mixtral-chat-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-mixtral-chat-ui.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-playground-github-actions-ui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-playground-github-actions-ui.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-run-artifacts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-run-artifacts.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-runpod-dev-environment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-runpod-dev-environment.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-server-output-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-server-output-2.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-stable-diffusion-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-stable-diffusion-code.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-stable-diffusion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-stable-diffusion.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-tensorboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-tensorboard.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-train-artifacts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-train-artifacts.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-v010-vscode-desktop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-v010-vscode-desktop.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-vscode-jupyter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-vscode-jupyter.png
--------------------------------------------------------------------------------
/docs/assets/images/dstack-vscode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/dstack-vscode.png
--------------------------------------------------------------------------------
/docs/assets/images/hero_code_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/assets/images/hero_code_background.png
--------------------------------------------------------------------------------
/docs/assets/images/jb-toolbox-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/assets/images/kapa.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/assets/images/lambda-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/assets/images/minus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/assets/images/oci-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/docs/assets/images/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/assets/images/ssh-logo.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/docs/assets/images/tensorwave-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/docs/assets/images/vastai-logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/docs/blog/index.md:
--------------------------------------------------------------------------------
1 |
6 |
7 | # Blog
8 |
--------------------------------------------------------------------------------
/docs/blog/posts/images/dstack-diagram-stack-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/blog/posts/images/dstack-diagram-stack-3.png
--------------------------------------------------------------------------------
/docs/blog/posts/images/dstack-research-banner-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/blog/posts/images/dstack-research-banner-2.png
--------------------------------------------------------------------------------
/docs/blog/posts/images/dstack-sky-banner-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/blog/posts/images/dstack-sky-banner-4.png
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/apply.md:
--------------------------------------------------------------------------------
1 | # dstack apply
2 |
3 | This command applies a given configuration. If a resource does not exist, `dstack apply` creates the resource.
4 | If a resource exists, `dstack apply` updates the resource in-place or re-creates the resource if the update is not possible.
5 |
6 | When applying run configurations, `dstack apply` requires that you run `dstack init` first,
7 | or specify a repo to work with via `-P` (or `--repo`), or specify `--no-repo` if you don't need any repo for the run.
8 |
9 | ## Usage
10 |
11 |
12 |
13 | ```shell
14 | $ dstack apply --help
15 | #GENERATE#
16 | ```
17 |
18 |
19 |
20 | [//]: # (TODO: Provide examples)
21 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/attach.md:
--------------------------------------------------------------------------------
1 | # dstack attach
2 |
3 | This command attaches to a given run. It establishes the SSH tunnel, forwards ports, and shows real-time run logs.
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack attach --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/delete.md:
--------------------------------------------------------------------------------
1 | # dstack delete
2 |
3 | This command deletes the resources defined by a given configuration.
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack delete --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/fleet.md:
--------------------------------------------------------------------------------
1 | # dstack fleet
2 |
3 | Fleets enable efficient provisioning and management of clusters and instances.
4 |
5 | ## dstack fleet list
6 |
7 | The `dstack fleet list` command displays fleets and instances.
8 |
9 |
10 |
11 | ```shell
12 | $ dstack fleet list --help
13 | #GENERATE#
14 | ```
15 |
16 |
17 |
18 | ## dstack fleet delete
19 |
20 | The `dstack fleet delete` deletes fleets and instances.
21 | Cloud instances are terminated upon deletion.
22 |
23 |
24 |
25 | ```shell
26 | $ dstack fleet delete --help
27 | #GENERATE#
28 | ```
29 |
30 |
31 |
32 | [//]: # (TODO: Provide examples)
33 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/logs.md:
--------------------------------------------------------------------------------
1 | # dstack logs
2 |
3 | This command shows the output of a given run.
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack logs --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/metrics.md:
--------------------------------------------------------------------------------
1 | # dstack metrics
2 |
3 | This command shows run hardware metrics such as CPU, memory, and GPU utilization.
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack metrics --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/ps.md:
--------------------------------------------------------------------------------
1 | # dstack ps
2 |
3 | This command shows the status of runs.
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack ps --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples, incl. `-a`)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/server.md:
--------------------------------------------------------------------------------
1 | # dstack server
2 |
3 | This command starts the `dstack` server.
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack server --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples; mention Docker; reference the deployment guide)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/stop.md:
--------------------------------------------------------------------------------
1 | # dstack stop
2 |
3 | This command stops run(s).
4 |
5 | ## Usage
6 |
7 |
8 |
9 | ```shell
10 | $ dstack stop --help
11 | #GENERATE#
12 | ```
13 |
14 |
15 |
16 | [//]: # (TODO: Provide examples, incl. `-x`)
17 |
--------------------------------------------------------------------------------
/docs/docs/reference/cli/dstack/volume.md:
--------------------------------------------------------------------------------
1 | # dstack volume
2 |
3 | The volumes commands.
4 |
5 | ## dstack volume list
6 |
7 | The `dstack volume list` command lists volumes.
8 |
9 | ##### Usage
10 |
11 |
12 |
13 | ```shell
14 | $ dstack volume list --help
15 | #GENERATE#
16 | ```
17 |
18 |
19 |
20 | ## dstack volume delete
21 |
22 | The `dstack volume delete` command deletes volumes.
23 |
24 | ##### Usage
25 |
26 |
27 |
28 | ```shell
29 | $ dstack volume delete --help
30 | #GENERATE#
31 | ```
32 |
33 |
34 |
35 | [//]: # (TODO: Provide examples)
36 |
--------------------------------------------------------------------------------
/docs/docs/reference/dstack.yml.md:
--------------------------------------------------------------------------------
1 | # .dstack.yml
2 |
3 | - [`dev-environment`](dstack.yml/dev-environment.md)
4 | - [`task`](dstack.yml/task.md)
5 | - [`service`](dstack.yml/service.md)
6 |
--------------------------------------------------------------------------------
/docs/docs/reference/dstack.yml/volume.md:
--------------------------------------------------------------------------------
1 | # `volume`
2 |
3 | The `volume` configuration type allows creating, registering, and updating [volumes](../../concepts/volumes.md).
4 |
5 | ## Root reference
6 |
7 | #SCHEMA# dstack._internal.core.models.volumes.VolumeConfiguration
8 | overrides:
9 | show_root_heading: false
10 | type:
11 | required: true
12 |
--------------------------------------------------------------------------------
/docs/examples/accelerators/amd/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/accelerators/amd/index.md
--------------------------------------------------------------------------------
/docs/examples/accelerators/intel/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/accelerators/intel/index.md
--------------------------------------------------------------------------------
/docs/examples/accelerators/tenstorrent/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/accelerators/tenstorrent/index.md
--------------------------------------------------------------------------------
/docs/examples/accelerators/tpu/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/accelerators/tpu/index.md
--------------------------------------------------------------------------------
/docs/examples/clusters/a3high/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/clusters/a3high/index.md
--------------------------------------------------------------------------------
/docs/examples/clusters/a3mega/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/clusters/a3mega/index.md
--------------------------------------------------------------------------------
/docs/examples/clusters/nccl-tests/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/clusters/nccl-tests/index.md
--------------------------------------------------------------------------------
/docs/examples/clusters/rccl-tests/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/clusters/rccl-tests/index.md
--------------------------------------------------------------------------------
/docs/examples/distributed-training/axolotl/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/distributed-training/axolotl/index.md
--------------------------------------------------------------------------------
/docs/examples/distributed-training/ray-ragen/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/distributed-training/ray-ragen/index.md
--------------------------------------------------------------------------------
/docs/examples/distributed-training/trl/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/distributed-training/trl/index.md
--------------------------------------------------------------------------------
/docs/examples/inference/nim/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/inference/nim/index.md
--------------------------------------------------------------------------------
/docs/examples/inference/sglang/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/inference/sglang/index.md
--------------------------------------------------------------------------------
/docs/examples/inference/tgi/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/inference/tgi/index.md
--------------------------------------------------------------------------------
/docs/examples/inference/trtllm/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/inference/trtllm/index.md
--------------------------------------------------------------------------------
/docs/examples/inference/vllm/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/inference/vllm/index.md
--------------------------------------------------------------------------------
/docs/examples/llms/deepseek/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/llms/deepseek/index.md
--------------------------------------------------------------------------------
/docs/examples/llms/llama/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/llms/llama/index.md
--------------------------------------------------------------------------------
/docs/examples/misc/docker-compose/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/misc/docker-compose/index.md
--------------------------------------------------------------------------------
/docs/examples/single-node-training/axolotl/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/single-node-training/axolotl/index.md
--------------------------------------------------------------------------------
/docs/examples/single-node-training/trl/index.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/examples/single-node-training/trl/index.md
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | template: home.html
3 | title: AI container orchestration for AI teams
4 | hide:
5 | - navigation
6 | - toc
7 | - footer
8 | ---
9 |
--------------------------------------------------------------------------------
/docs/overrides/.icons/custom/colored/github.svg:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/docs/overrides/.icons/custom/colored/twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/overrides/.icons/custom/github.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/overrides/assets/images/github-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/github-logo.png
--------------------------------------------------------------------------------
/docs/overrides/assets/images/quotes/alvarobartt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/quotes/alvarobartt.jpg
--------------------------------------------------------------------------------
/docs/overrides/assets/images/quotes/chansung.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/quotes/chansung.jpg
--------------------------------------------------------------------------------
/docs/overrides/assets/images/quotes/cudopete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/quotes/cudopete.png
--------------------------------------------------------------------------------
/docs/overrides/assets/images/quotes/eckart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/quotes/eckart.png
--------------------------------------------------------------------------------
/docs/overrides/assets/images/quotes/movchan.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/quotes/movchan.jpg
--------------------------------------------------------------------------------
/docs/overrides/assets/images/quotes/spott.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/quotes/spott.jpg
--------------------------------------------------------------------------------
/docs/overrides/assets/images/slack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/slack.png
--------------------------------------------------------------------------------
/docs/overrides/assets/images/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/docs/overrides/assets/images/twitter.png
--------------------------------------------------------------------------------
/docs/overrides/landing.html:
--------------------------------------------------------------------------------
1 | {% extends "main.html" %}
2 |
3 | {% block header %}
4 | {% include "header-2.html" %}
5 | {% endblock %}
6 |
--------------------------------------------------------------------------------
/docs/privacy.md:
--------------------------------------------------------------------------------
1 | ---
2 | template: privacy.html
3 | title: Privacy policy
4 | hide:
5 | - navigation
6 | - toc
7 | - footer
8 | ---
9 |
--------------------------------------------------------------------------------
/examples/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: dev-environment
2 | # The name is optional, if not specified, generated randomly
3 | name: vscode
4 |
5 | #python: "3.11"
6 |
7 | image: un1def/dstack-base:py3.12-dev-cuda-12.1
8 |
9 | ide: vscode
10 |
11 | # Use either spot or on-demand instances
12 | #spot_policy: auto
13 |
14 | resources:
15 | cpu: x86:8..32
16 | gpu: 24GB..:1
17 |
--------------------------------------------------------------------------------
/examples/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/examples/__init__.py
--------------------------------------------------------------------------------
/examples/accelerators/tenstorrent/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: dev-environment
2 | name: cursor
3 |
4 | image: dstackai/tt-smi:latest
5 |
6 | ide: cursor
7 |
8 | resources:
9 | gpu: n150:1
10 |
--------------------------------------------------------------------------------
/examples/accelerators/tenstorrent/tt-smi.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 | name: tt-smi
3 |
4 | image: dstackai/tt-smi:latest
5 |
6 | commands:
7 | - tt-smi -s
8 |
9 | resources:
10 | gpu: n150:1
11 |
--------------------------------------------------------------------------------
/examples/clusters/a3high/fleet.dstack.yml:
--------------------------------------------------------------------------------
1 | type: fleet
2 | name: a3high-cluster
3 | nodes: 2
4 | placement: cluster
5 | instance_types:
6 | - a3-highgpu-8g
7 | spot_policy: auto
8 |
--------------------------------------------------------------------------------
/examples/clusters/a3mega/fleet.dstack.yml:
--------------------------------------------------------------------------------
1 | type: fleet
2 | name: a3mega-cluster
3 | nodes: 2
4 | placement: cluster
5 | instance_types:
6 | - a3-megagpu-8g
7 | spot_policy: auto
8 |
--------------------------------------------------------------------------------
/examples/inference/nim/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: serve-distill-deepseek
3 |
4 | image: nvcr.io/nim/deepseek-ai/deepseek-r1-distill-llama-8b
5 | env:
6 | - NGC_API_KEY
7 | - NIM_MAX_MODEL_LEN=4096
8 | registry_auth:
9 | username: $oauthtoken
10 | password: ${{ env.NGC_API_KEY }}
11 | port: 8000
12 | # Register the model
13 | model: deepseek-ai/deepseek-r1-distill-llama-8b
14 |
15 | # Uncomment to leverage spot instances
16 | #spot_policy: auto
17 |
18 | # Cache downloaded models
19 | volumes:
20 | - instance_path: /root/.cache/nim
21 | path: /opt/nim/.cache
22 | optional: true
23 |
24 | resources:
25 | gpu: A100:40GB
26 | # Uncomment if using multiple GPUs
27 | #shm_size: 16GB
28 |
--------------------------------------------------------------------------------
/examples/inference/tgi/amd/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: amd-service-tgi
3 |
4 | image: ghcr.io/huggingface/text-generation-inference:sha-a379d55-rocm
5 | env:
6 | - HF_TOKEN
7 | - ROCM_USE_FLASH_ATTN_V2_TRITON=true
8 | - TRUST_REMOTE_CODE=true
9 | - MODEL_ID=meta-llama/Meta-Llama-3.1-70B-Instruct
10 | commands:
11 | - text-generation-launcher --port 8000
12 | port: 8000
13 | # Register the model
14 | model: meta-llama/Meta-Llama-3.1-70B-Instruct
15 |
16 | # Uncomment to leverage spot instances
17 | #spot_policy: auto
18 |
19 | resources:
20 | gpu: MI300X
21 | disk: 150GB
22 |
--------------------------------------------------------------------------------
/examples/inference/vllm/tpu/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | # The name is optional, if not specified, generated randomly
3 | name: llama31-service-vllm-tpu
4 | image: vllm/vllm-tpu:nightly
5 | env:
6 | - HF_TOKEN
7 | - MODEL_ID=meta-llama/Meta-Llama-3.1-8B-Instruct
8 | - MAX_MODEL_LEN=4096
9 | commands:
10 | - vllm serve $MODEL_ID
11 | --tensor-parallel-size 4
12 | --max-model-len $MAX_MODEL_LEN
13 | --port 8000
14 | # Expose the vllm server port
15 | port: 8000
16 | # Register the model
17 | model: meta-llama/Meta-Llama-3.1-8B-Instruct
18 |
19 | # Uncomment to leverage spot instances
20 | #spot_policy: auto
21 |
22 | resources:
23 | gpu: v5litepod-4
24 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/sglang/amd/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-r1-amd
3 |
4 | image: lmsysorg/sglang:v0.4.1.post4-rocm620
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-R1-Distill-Llama-70B
7 | commands:
8 | - python3 -m sglang.launch_server
9 | --model-path $MODEL_ID
10 | --port 8000
11 | --trust-remote-code
12 |
13 | port: 8000
14 | model: deepseek-ai/DeepSeek-R1-Distill-Llama-70B
15 |
16 | resources:
17 | gpu: mi300x
18 | disk: 300Gb
19 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/sglang/amd/deepseek_v2_lite.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-v2-lite-amd
3 |
4 | image: lmsysorg/sglang:v0.4.1.post4-rocm620
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-V2-Lite
7 | commands:
8 | - python3 -m sglang.launch_server
9 | --model-path $MODEL_ID
10 | --port 8000
11 | --trust-remote-code
12 |
13 | port: 8000
14 | model: deepseek-ai/DeepSeek-V2-Lite
15 |
16 | resources:
17 | gpu: mi300x
18 | disk: 150Gb
19 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/sglang/nvidia/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-r1-nvidia
3 |
4 | image: lmsysorg/sglang:latest
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-R1-Distill-Llama-8B
7 | commands:
8 | - python3 -m sglang.launch_server
9 | --model-path $MODEL_ID
10 | --port 8000
11 | --trust-remote-code
12 |
13 | port: 8000
14 |
15 | model: deepseek-ai/DeepSeek-R1-Distill-Llama-8B
16 |
17 | resources:
18 | gpu: 24GB
19 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/sglang/nvidia/deepseek_v2_lite.dstack.yml:
--------------------------------------------------------------------------------
1 | # Not Working https://github.com/sgl-project/sglang/issues/3451
2 | type: service
3 | name: deepseek-v2-lite-nvidia
4 |
5 | image: lmsysorg/sglang:latest
6 | env:
7 | - MODEL_ID=deepseek-ai/DeepSeek-V2-Lite
8 | commands:
9 | - python3 -m sglang.launch_server
10 | --model-path $MODEL_ID
11 | --port 8000
12 | --trust-remote-code
13 |
14 | port: 8000
15 |
16 | model: deepseek-ai/DeepSeek-V2-Lite
17 |
18 | resources:
19 | gpu: 80GB
20 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/vllm/amd/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-r1-amd
3 |
4 | image: rocm/vllm:rocm6.2_mi300_ubuntu20.04_py3.9_vllm_0.6.4
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-R1-Distill-Llama-70B
7 | - MAX_MODEL_LEN=126432
8 | commands:
9 | - vllm serve $MODEL_ID
10 | --max-model-len $MAX_MODEL_LEN
11 | --trust-remote-code
12 | port: 8000
13 |
14 | model: deepseek-ai/DeepSeek-R1-Distill-Llama-70B
15 |
16 |
17 | resources:
18 | gpu: mi300x
19 | disk: 300Gb
20 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/vllm/amd/deepseek_v2_lite.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-v2-lite-amd
3 |
4 | image: rocm/vllm:rocm6.2_mi300_ubuntu20.04_py3.9_vllm_0.6.4
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-V2-Lite
7 | commands:
8 | - vllm serve $MODEL_ID
9 | --trust-remote-code
10 |
11 | port: 8000
12 |
13 | model: deepseek-ai/DeepSeek-V2-Lite
14 |
15 |
16 | resources:
17 | gpu: mi300x
18 | disk: 150Gb
19 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/vllm/nvidia/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-r1-nvidia
3 |
4 | image: vllm/vllm-openai:latest
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-R1-Distill-Llama-8B
7 | - MAX_MODEL_LEN=4096
8 | commands:
9 | - vllm serve $MODEL_ID
10 | --max-model-len $MAX_MODEL_LEN
11 |
12 | port: 8000
13 |
14 | model: deepseek-ai/DeepSeek-R1-Distill-Llama-8B
15 |
16 | resources:
17 | gpu: 24GB
18 |
--------------------------------------------------------------------------------
/examples/llms/deepseek/vllm/nvidia/deepseek_v2_lite.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: deepseek-v2-lite-nvidia
3 |
4 | image: vllm/vllm-openai:latest
5 | env:
6 | - MODEL_ID=deepseek-ai/DeepSeek-V2-Lite
7 | - MAX_MODEL_LEN=4096
8 | commands:
9 | - vllm serve $MODEL_ID
10 | --max-model-len $MAX_MODEL_LEN
11 | --tensor-parallel-size $DSTACK_GPUS_NUM
12 | --trust-remote-code
13 |
14 | port: 8000
15 |
16 | model: deepseek-ai/DeepSeek-V2-Lite
17 |
18 | resources:
19 | gpu: 48GB
20 |
--------------------------------------------------------------------------------
/examples/llms/llama/sglang/nvidia/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: llama4-scout
3 |
4 | image: lmsysorg/sglang
5 | env:
6 | - HF_TOKEN
7 | - MODEL_ID=meta-llama/Llama-4-Scout-17B-16E-Instruct
8 | - CONTEXT_LEN=256000
9 | commands:
10 | - python3 -m sglang.launch_server
11 | --model-path $MODEL_ID
12 | --tp $DSTACK_GPUS_NUM
13 | --context-length $CONTEXT_LEN
14 | --port 8000
15 | --kv-cache-dtype fp8_e5m2
16 |
17 | port: 8000
18 | ## Register the model
19 | model: meta-llama/Llama-4-Scout-17B-16E-Instruct
20 |
21 | resources:
22 | gpu: H200:2
23 | disk: 500GB..
24 |
--------------------------------------------------------------------------------
/examples/llms/llama/vllm/nvidia/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: llama4-scout
3 |
4 | image: vllm/vllm-openai
5 | env:
6 | - HF_TOKEN
7 | - MODEL_ID=meta-llama/Llama-4-Scout-17B-16E-Instruct
8 | - VLLM_DISABLE_COMPILE_CACHE=1
9 | - MAX_MODEL_LEN=256000
10 | commands:
11 | - |
12 | vllm serve $MODEL_ID \
13 | --tensor-parallel-size $DSTACK_GPUS_NUM \
14 | --max-model-len $MAX_MODEL_LEN \
15 | --kv-cache-dtype fp8 \
16 | --override-generation-config='{"attn_temperature_tuning": true}'
17 |
18 | port: 8000
19 | # Register the model
20 | model: meta-llama/Llama-4-Scout-17B-16E-Instruct
21 |
22 | resources:
23 | gpu: H200:2
24 | disk: 500GB..
25 |
--------------------------------------------------------------------------------
/examples/misc/airflow/dags/dstack-repo/task.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 | commands:
3 | - echo "Running dstack task via Airflow"
4 | - sleep 10
5 | - echo "Finished"
6 |
--------------------------------------------------------------------------------
/examples/misc/docker-compose/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: dev-environment
2 | name: vscode-dind
3 |
4 | privileged: true
5 | image: dstackai/dind
6 | env:
7 | - MODEL_ID=meta-llama/Llama-3.2-3B-Instruct
8 | - HF_TOKEN
9 | ide: vscode
10 | init:
11 | - start-dockerd
12 |
13 | # Uncomment to leverage spot instances
14 | #spot_policy: auto
15 |
16 | resources:
17 | gpu: 24GB
18 |
--------------------------------------------------------------------------------
/examples/misc/docker-compose/service.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | name: chat-ui-service
3 |
4 | privileged: true
5 | image: dstackai/dind
6 | env:
7 | - MODEL_ID=meta-llama/Llama-3.2-3B-Instruct
8 | - HF_TOKEN
9 | working_dir: examples/misc/docker-compose
10 | commands:
11 | - start-dockerd
12 | - docker compose up
13 | port: 9000
14 | auth: false
15 |
16 | # Uncomment to leverage spot instances
17 | #spot_policy: auto
18 |
19 | resources:
20 | # Required resources
21 | gpu: "nvidia:24GB"
22 |
23 | # Uncomment to persist data
24 | #volumes:
25 | # - name: my-dind-volume
26 | # path: /var/lib/docker
27 |
--------------------------------------------------------------------------------
/examples/misc/docker-compose/task.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 | name: chat-ui-task
3 |
4 | privileged: true
5 | image: dstackai/dind
6 | env:
7 | - MODEL_ID=meta-llama/Llama-3.2-3B-Instruct
8 | - HF_TOKEN
9 | working_dir: examples/misc/docker-compose
10 | commands:
11 | - start-dockerd
12 | - docker compose up
13 | ports:
14 | - 9000
15 |
16 | # Use either spot or on-demand instances
17 | spot_policy: auto
18 |
19 | resources:
20 | # Required resources
21 | gpu: "nvidia:24GB"
22 |
23 | # Uncomment to persist data
24 | #volumes:
25 | # - name: my-dind-volume
26 | # path: /var/lib/docker
27 |
--------------------------------------------------------------------------------
/examples/misc/docker-compose/volume.dstack.yml:
--------------------------------------------------------------------------------
1 | type: volume
2 | name: my-dind-volume
3 |
4 | backend: aws
5 | region: eu-west-1
6 |
7 | # Required size
8 | size: 100GB
9 |
--------------------------------------------------------------------------------
/examples/misc/http.server/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | # This service deploys a simple HTTP server
3 |
4 | python: "3.11"
5 | commands:
6 | - python3 -m http.server
7 | port: 8000
8 |
9 | # Disable authentication
10 | auth: false
11 |
--------------------------------------------------------------------------------
/examples/misc/http.server/README.md:
--------------------------------------------------------------------------------
1 | # Streamlit
2 |
3 | ## Service
4 |
5 | The following command runs `http.server` as a service:
6 |
7 | ```shell
8 | dstack apply -f examples/misc/http.server/.dstack.yml
9 | ```
10 |
11 | See the configuration at [.dstack.yml](.dstack.yml).
12 |
13 | ## Task
14 |
15 | The following command runs `http.server` as a task:
16 |
17 | ```shell
18 | dstack apply -f examples/misc/http.server/task.dstack.yml
19 | ```
20 |
21 | See the configuration at [task.dstack.yml](task.dstack.yml).
22 |
23 | For more details, refer to [services](https://dstack.ai/docs/services) or [tasks](https://dstack.ai/docs/tasks).
24 |
--------------------------------------------------------------------------------
/examples/misc/http.server/task.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 | # This task runs a simple HTTP server
3 |
4 | python: "3.11"
5 |
6 | commands:
7 | - python3 -m http.server
8 |
9 | ports:
10 | - 8000
11 |
--------------------------------------------------------------------------------
/examples/misc/jupyterlab/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 | # This task runs a JupyterLab instance
3 |
4 | ports:
5 | - 8888
6 |
7 | commands:
8 | - pip install jupyterlab
9 | - jupyter lab --allow-root
10 |
--------------------------------------------------------------------------------
/examples/misc/ray/cluster.dstack.yaml:
--------------------------------------------------------------------------------
1 | type: task
2 | name: ray-cluster
3 | nodes: 4
4 | commands:
5 | - pip install -U "ray[default]"
6 | - >
7 | if [ $DSTACK_NODE_RANK = 0 ]; then
8 | ray start --head --port=6379;
9 | else
10 | ray start --address=$DSTACK_MASTER_NODE_IP:6379
11 | fi
12 | ports:
13 | - 8265 # ray dashboard port
14 | resources:
15 | shm_size: 8GB
16 |
--------------------------------------------------------------------------------
/examples/misc/ray/fleet.dstack.yaml:
--------------------------------------------------------------------------------
1 | type: fleet
2 | name: ray-fleet
3 | nodes: 4
4 | placement: cluster
5 | backends: [gcp]
6 | resources:
7 | cpu: 8..
8 | memory: 32GB..
9 | gpu: 1
10 |
--------------------------------------------------------------------------------
/examples/misc/spark/cluster.dstack.yaml:
--------------------------------------------------------------------------------
1 | type: task
2 | name: spark-cluster
3 | image: spark
4 | nodes: 2
5 | commands:
6 | - export SPARK_MASTER_HOST=$DSTACK_MASTER_NODE_IP
7 | - export SPARK_NO_DAEMONIZE=true
8 | - if [ $DSTACK_NODE_RANK = 0 ]; then /opt/spark/sbin/start-master.sh; else /opt/spark/sbin/start-worker.sh spark://$DSTACK_MASTER_NODE_IP:7077; fi
9 | ports:
10 | - 7077
11 | - 8080
12 |
--------------------------------------------------------------------------------
/examples/misc/spark/fleet.dstack.yaml:
--------------------------------------------------------------------------------
1 | type: fleet
2 | name: spark-fleet
3 | nodes: 3
4 | placement: cluster
5 | backends: [gcp]
6 |
--------------------------------------------------------------------------------
/examples/misc/spark/task.dstack.yaml:
--------------------------------------------------------------------------------
1 | type: task
2 | name: spark-task
3 | image: spark
4 | env:
5 | - SPARK_CLUSTER_IP
6 | commands:
7 | - pip install pyspark
8 | - python3 tasks/words.py
9 |
--------------------------------------------------------------------------------
/examples/misc/streamlit/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: service
2 | # This service deploys a "Hello world" Streamlit app
3 |
4 | image: python:3.11
5 | commands:
6 | - pip3 install streamlit
7 | - streamlit hello
8 | port: 8501
9 |
10 | # Disable authentication
11 | auth: false
12 |
--------------------------------------------------------------------------------
/examples/misc/streamlit/README.md:
--------------------------------------------------------------------------------
1 | # Streamlit
2 |
3 | ## Service (no auth)
4 |
5 | The following command runs `streamlit hello` as a service with disabled authentication:
6 |
7 | ```shell
8 | dstack apply -f examples/misc/streamlit/.dstack.yml
9 | ```
10 |
11 | See the configuration at [.dstack.yml](.dstack.yml).
12 |
13 | ## Task
14 |
15 | The following command runs `streamlit hello` as a task:
16 |
17 | ```shell
18 | dstack apply -f examples/misc/streamlit/task.dstack.yml
19 | ```
20 |
21 | See the configuration at [task.dstack.yml](task.dstack.yml).
22 |
23 | For more details, refer to [services](https://dstack.ai/docs/services) or [tasks](https://dstack.ai/docs/tasks).
24 |
--------------------------------------------------------------------------------
/examples/misc/streamlit/task.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 | # This task runs a "Hello world" Streamlit app
3 |
4 | image: python:3.11
5 | commands:
6 | - pip3 install streamlit
7 | - streamlit hello
8 | ports:
9 | - 8501
10 |
--------------------------------------------------------------------------------
/examples/plugins/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/examples/plugins/__init__.py
--------------------------------------------------------------------------------
/examples/plugins/example_plugin/.python-version:
--------------------------------------------------------------------------------
1 | 3.11
2 |
--------------------------------------------------------------------------------
/examples/plugins/example_plugin/Dockerfile:
--------------------------------------------------------------------------------
1 | # Example of including plugins into the dstack server Docker image
2 | FROM dstackai/dstack:latest
3 |
4 | # Installing plugin from Docker context
5 | COPY . plugins/example_plugin
6 | RUN uv tool install "dstack[all]" --with plugins/example_plugin
7 |
8 | # Installing some other plugins from pypi/git
9 | # RUN uv tool install "dstack[all]" --with plugin1 --with plugin2
10 |
--------------------------------------------------------------------------------
/examples/plugins/example_plugin/enterprise.Dockerfile:
--------------------------------------------------------------------------------
1 | # Example of including plugins into the dstack Enterprise Docker image
2 | FROM ghcr.io/dstackai/dstack-enterprise:latest
3 |
4 | # Installing plugin from Docker context
5 | COPY . plugins/example_plugin
6 | RUN uv pip install plugins/example_plugin
7 |
8 | # Installing some other plugins from pypi/git
9 | # RUN uv pip install plugin-name
10 |
--------------------------------------------------------------------------------
/examples/plugins/example_plugin/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "example-plugin"
3 | version = "0.1.0"
4 | description = "A dstack plugin example"
5 | readme = "README.md"
6 | authors = [
7 | { name = "Victor Skvortsov", email = "victor@dstack.ai" }
8 | ]
9 | requires-python = ">=3.9"
10 | dependencies = []
11 |
12 | [build-system]
13 | requires = ["hatchling"]
14 | build-backend = "hatchling.build"
15 |
16 | [project.entry-points."dstack.plugins"]
17 | example_plugin = "example_plugin:ExamplePlugin"
18 |
--------------------------------------------------------------------------------
/examples/plugins/example_plugin/src/example_plugin/py.typed:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/examples/plugins/example_plugin/src/example_plugin/py.typed
--------------------------------------------------------------------------------
/examples/plugins/example_plugin_server/.python-version:
--------------------------------------------------------------------------------
1 | 3.11
2 |
--------------------------------------------------------------------------------
/examples/plugins/example_plugin_server/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/examples/plugins/example_plugin_server/__init__.py
--------------------------------------------------------------------------------
/examples/plugins/example_plugin_server/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "dstack-plugin-server"
3 | version = "0.1.0"
4 | description = "Example plugin server"
5 | readme = "README.md"
6 | requires-python = ">=3.11"
7 | dependencies = [
8 | "fastapi[standard]>=0.115.12",
9 | "dstack",
10 | ]
11 |
12 | [build-system]
13 | requires = ["hatchling"]
14 | build-backend = "hatchling.build"
15 |
16 | [tool.hatch.build.targets.wheel]
17 | packages = ["src/example_plugin_server"]
18 |
--------------------------------------------------------------------------------
/examples/plugins/example_plugin_server/src/example_plugin_server/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/examples/plugins/example_plugin_server/src/example_plugin_server/__init__.py
--------------------------------------------------------------------------------
/examples/plugins/example_plugin_server/src/example_plugin_server/utils.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import os
3 |
4 |
5 | def configure_logging():
6 | log_level = os.getenv("LOG_LEVEL", "INFO").upper()
7 | logging.basicConfig(level=log_level)
8 |
--------------------------------------------------------------------------------
/examples/single-node-training/optimum-tpu/llama31/config.yaml:
--------------------------------------------------------------------------------
1 | per_device_train_batch_size: 24
2 | per_device_eval_batch_size: 8
3 | num_train_epochs: 1
4 | max_steps: -1
5 | output_dir: "./finetuned_models/llama3_fine_tuned"
6 | optim: "adafactor"
7 | dataset_name: "Abirate/english_quotes"
8 | model_name: "meta-llama/Meta-Llama-3.1-8B"
9 | lora_r: 4
10 | push_to_hub: True
11 |
--------------------------------------------------------------------------------
/examples/single-node-training/qlora/.dstack.yml:
--------------------------------------------------------------------------------
1 | type: task
2 |
3 | python: "3.11"
4 |
5 | env:
6 | - HF_TOKEN
7 | - HF_HUB_ENABLE_HF_TRANSFER=1
8 |
9 | commands:
10 | - pip install -r examples/single-node-training/qlora/requirements.txt
11 | - tensorboard --logdir results/runs &
12 | - python examples/single-node-training/qlora/train.py --merge_and_push ${{ run.args }}
13 | ports:
14 | - 6006
15 |
16 | resources:
17 | gpu: 16GB..24GB
18 |
--------------------------------------------------------------------------------
/examples/single-node-training/qlora/README.md:
--------------------------------------------------------------------------------
1 | # QLoRA
2 |
3 | The following command runs the task to fine-tune an LLM using QLoRA:
4 |
5 | ```shell
6 | dstack apply -f examples/single-node-training/qlora/.dstack.yml
7 | ```
8 |
9 | See the configuration at [.dstack.yml](.dstack.yml).
10 |
11 | For more details, refer to [tasks](https://dstack.ai/docs/tasks).
12 |
--------------------------------------------------------------------------------
/examples/single-node-training/qlora/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/examples/single-node-training/qlora/requirements.txt
--------------------------------------------------------------------------------
/frontend/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | build
3 | server.js
4 | src/locale
5 | src/types
6 | src/setupProxy.js
7 | webpack/**
8 | webpack/env.js
9 | webpack/prod.js
10 | public
11 | staticServer.js
12 | webpack.config.js
13 |
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
2 | /.idea/
3 | build
4 |
--------------------------------------------------------------------------------
/frontend/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "trailingComma": "all",
4 | "singleQuote": true,
5 | "printWidth": 128,
6 | "tabWidth": 4
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "dstack",
3 | "name": "dstack",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff",
15 | "permissions": ["clipboardWrite", "clipboardRead"]
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/frontend/setupEnzyme.ts:
--------------------------------------------------------------------------------
1 | import { configure } from 'enzyme';
2 | import Adapter from '@cfaester/enzyme-adapter-react-18';
3 |
4 | configure({ adapter: new Adapter() });
5 |
--------------------------------------------------------------------------------
/frontend/src/App/AuthErrorMessage/styles.module.scss:
--------------------------------------------------------------------------------
1 | .content {
2 | margin-top: 20px;
3 | }
4 |
--------------------------------------------------------------------------------
/frontend/src/App/Loading/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { AppLayout, Spinner } from 'components';
4 |
5 | import styles from './styles.module.scss';
6 |
7 | export const Loading: React.FC = () => {
8 | return (
9 |
15 |
16 |
17 | }
18 | />
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/frontend/src/App/Loading/styles.module.scss:
--------------------------------------------------------------------------------
1 | .spinner {
2 | height: 100%;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/App/Login/EnterpriseLogin/styles.module.scss:
--------------------------------------------------------------------------------
1 | .form {
2 | max-width: 440px;
3 | width: 100%;
4 | margin-left: auto;
5 | margin-right: auto;
6 | padding-top: 120px;
7 | }
8 | .token {
9 |
10 | }
11 | .okta {
12 | margin-top: 20px;
13 | }
14 | .entra {
15 | margin-top: 20px;
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/App/Login/EntraID/LoginByEntraID/styles.module.scss:
--------------------------------------------------------------------------------
1 | @use '@cloudscape-design/design-tokens/index' as awsui;
2 |
3 | .entraSignIn {
4 | display: flex;
5 | justify-content: center;
6 |
7 | button {
8 | .loginButtonInner {
9 | display: inline-flex;
10 | align-items: center;
11 | justify-content: center;
12 | gap: 8px;
13 | }
14 |
15 | .loginButtonLabel {
16 | height: 20px;
17 | line-height: 21px;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/src/App/Login/LoginByOkta/styles.module.scss:
--------------------------------------------------------------------------------
1 | @use '@cloudscape-design/design-tokens/index' as awsui;
2 |
3 | .signIn {
4 | display: flex;
5 | justify-content: center;
6 |
7 | button {
8 | .loginButtonInner {
9 | display: inline-flex;
10 | align-items: center;
11 | justify-content: center;
12 | gap: 8px;
13 | }
14 |
15 | .loginButtonLabel {
16 | height: 20px;
17 | line-height: 21px;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/src/App/Login/LoginByTokenForm/styles.module.scss:
--------------------------------------------------------------------------------
1 | .form {
2 | max-width: 440px;
3 | margin-left: auto;
4 | margin-right: auto;
5 | }
6 | .token {
7 | display: flex;
8 | align-items: flex-start;
9 | gap: 12px;
10 | }
11 | .fieldWrap {
12 | flex-grow: 1;
13 | min-width: 0;
14 | }
15 | .buttonWrap {
16 | display: flex;
17 | flex-shrink: 0;
18 | width: 104px;
19 | margin-right: -20px;
20 |
21 | button {
22 | white-space: nowrap !important;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/frontend/src/App/Login/TokenLogin/styles.module.scss:
--------------------------------------------------------------------------------
1 | .form {
2 | max-width: 440px;
3 | width: 100%;
4 | margin-left: auto;
5 | margin-right: auto;
6 | padding-top: 120px;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/App/Logout/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 | import { Navigate } from 'react-router-dom';
3 |
4 | import { useAppDispatch } from 'hooks';
5 | import { ROUTES } from 'routes';
6 | import { projectApi } from 'services/project';
7 | import { userApi } from 'services/user';
8 |
9 | import { removeAuthData } from '../slice';
10 |
11 | export const Logout: React.FC = () => {
12 | const dispatch = useAppDispatch();
13 |
14 | useEffect(() => {
15 | dispatch(removeAuthData());
16 |
17 | dispatch(userApi.util.resetApiState());
18 | dispatch(projectApi.util.resetApiState());
19 | }, []);
20 |
21 | return ;
22 | };
23 |
--------------------------------------------------------------------------------
/frontend/src/App/constants.ts:
--------------------------------------------------------------------------------
1 | export const AUTH_DATA_STORAGE_KEY = 'authData';
2 | export const MODE_STORAGE_KEY = 'mode';
3 |
--------------------------------------------------------------------------------
/frontend/src/App/helpers.ts:
--------------------------------------------------------------------------------
1 | import { Mode } from '@cloudscape-design/global-styles';
2 |
3 | export const getThemeMode = (): Mode => (window?.matchMedia('(prefers-color-scheme: dark)').matches ? Mode.Dark : Mode.Light);
4 |
5 | export function getBaseUrl(): string {
6 | const { protocol, hostname, port } = window.location;
7 | return `${protocol}//${hostname}${port ? `:${port}` : ''}`;
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/src/assets/css/index.css:
--------------------------------------------------------------------------------
1 | .b-page-header {
2 | position: relative;
3 | z-index: 1002;
4 | }
5 |
--------------------------------------------------------------------------------
/frontend/src/assets/css/mixins.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/frontend/src/assets/css/mixins.css
--------------------------------------------------------------------------------
/frontend/src/assets/css/variables.css:
--------------------------------------------------------------------------------
1 | @custom-media --mobile (width <= 640px);
2 | @custom-media --no-mobile (width > 640px);
3 | @custom-media --no-desktop (width < 980px);
4 | @custom-media --desktop (width >= 980px);
5 |
6 | :root {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/src/assets/icons/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/frontend/src/assets/icons/.gitkeep
--------------------------------------------------------------------------------
/frontend/src/assets/icons/okta.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/frontend/src/assets/icons/theme.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/frontend/src/assets/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/frontend/src/assets/images/.gitkeep
--------------------------------------------------------------------------------
/frontend/src/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/frontend/src/assets/images/favicon.png
--------------------------------------------------------------------------------
/frontend/src/components/Button/styles.module.scss:
--------------------------------------------------------------------------------
1 | @use '@cloudscape-design/design-tokens/index' as awsui;
2 |
3 | .button {
4 | &.danger-normal {
5 | &:not([disabled]) {
6 | color: awsui.$color-charts-red-600 !important;
7 | border-color: awsui.$color-charts-red-600 !important;
8 |
9 | &:hover {
10 | color: awsui.$color-charts-red-500 !important;
11 | border-color: awsui.$color-charts-red-500 !important;
12 | }
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/frontend/src/components/ButtonWithConfirmation/types.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | import type { IProps as ButtonProps } from '../Button';
4 |
5 | export interface IProps extends Omit {
6 | confirmTitle?: string;
7 | confirmContent?: ReactNode;
8 | onClick?: () => void;
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/components/Code/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classNames from 'classnames';
3 | import Box from '@cloudscape-design/components/box';
4 |
5 | import styles from './styles.module.scss';
6 |
7 | export interface Props extends React.PropsWithChildren {
8 | className?: string;
9 | }
10 |
11 | export const Code: React.FC = ({ children, className }) => {
12 | return (
13 |
14 |
15 | {children}
16 |
17 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/frontend/src/components/Code/styles.module.scss:
--------------------------------------------------------------------------------
1 | @use '@cloudscape-design/design-tokens/index' as awsui;
2 |
3 | .code {
4 | padding: 8px;
5 | background-color: awsui.$color-background-input-disabled;
6 | border-radius: 8px;
7 | white-space: pre-wrap;
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/src/components/ConfirmationDialog/styles.module.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/frontend/src/components/ConfirmationDialog/styles.module.scss
--------------------------------------------------------------------------------
/frontend/src/components/ConfirmationDialog/types.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | import { ButtonProps } from 'components';
4 |
5 | export interface IProps {
6 | title?: string;
7 | content?: ReactNode;
8 | visible?: boolean;
9 | onDiscard: ButtonProps['onClick'];
10 | onConfirm: ButtonProps['onClick'];
11 |
12 | cancelButtonLabel?: string;
13 | confirmButtonLabel?: string;
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/src/components/DetailsHeader/types.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export interface IProps {
4 | title: React.ReactNode;
5 | editAction?: () => void;
6 | deleteAction?: () => void;
7 | editDisabled?: boolean;
8 | deleteDisabled?: boolean;
9 | actionButtons?: React.ReactNode;
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/src/components/FileUploader/Token/styles.module.scss:
--------------------------------------------------------------------------------
1 | .tokenPanel {
2 | background-color: var(--color-background-item-selected-ebt4bi);
3 | display: flex;
4 | border: 0.2em solid var(--color-border-item-selected-ppkssz);
5 | padding: 1em;
6 | margin: 1em;
7 | border-radius: var(--border-radius-token-wohc9e);
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/src/components/Hotspot/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import HotspotGeneral, { HotspotProps } from '@cloudscape-design/components/hotspot';
3 |
4 | export interface IProps extends HotspotProps {
5 | renderHotspot?: boolean;
6 | }
7 |
8 | export const Hotspot: React.FC = ({ renderHotspot = true, children, ...props }) => {
9 | if (!renderHotspot) {
10 | return children;
11 | }
12 |
13 | return {children};
14 | };
15 |
--------------------------------------------------------------------------------
/frontend/src/components/InfoLink/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useTranslation } from 'react-i18next';
3 | import Link from '@cloudscape-design/components/link';
4 |
5 | import { IProps } from './types';
6 |
7 | export const InfoLink: React.FC = (props) => {
8 | const { t } = useTranslation();
9 |
10 | return (
11 |
12 | {t('common.info')}
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/frontend/src/components/InfoLink/types.ts:
--------------------------------------------------------------------------------
1 | import { LinkProps } from '@cloudscape-design/components/link';
2 |
3 | export interface IProps {
4 | id?: string;
5 | ariaLabel?: string;
6 | onFollow: LinkProps['onFollow'];
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/components/ListEmptyMessage/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Box from '@cloudscape-design/components/box';
3 |
4 | import { IProps } from './types';
5 |
6 | export const ListEmptyMessage: React.FC = ({ title, message, children }) => {
7 | return (
8 |
9 | {title && {title}}
10 |
11 | {message}
12 |
13 | {children}
14 |
15 | );
16 | };
17 |
--------------------------------------------------------------------------------
/frontend/src/components/ListEmptyMessage/types.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export interface IProps {
4 | title?: string;
5 | message?: string;
6 | children?: ReactNode;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/components/Loader/styles.module.scss:
--------------------------------------------------------------------------------
1 | .loader {
2 | display: flex;
3 | justify-content: center;
4 | transition: opacity .2s ease;
5 |
6 | &:not(.show) {
7 | opacity: 0;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/components/NavigateLink/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { useNavigate } from 'react-router-dom';
3 | import Link, { LinkProps } from '@cloudscape-design/components/link';
4 | export const NavigateLink: React.FC = ({ onFollow, ...props }) => {
5 | const navigate = useNavigate();
6 | const onFollowHandler: LinkProps['onFollow'] = (event) => {
7 | event.preventDefault();
8 |
9 | if (onFollow) onFollow(event);
10 | if (event.detail.href) navigate(event.detail.href);
11 | };
12 |
13 | return ;
14 | };
15 |
--------------------------------------------------------------------------------
/frontend/src/components/Notifications/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Flashbar from '@cloudscape-design/components/flashbar';
3 |
4 | import { useAppSelector } from 'hooks';
5 |
6 | import { selectNotifications } from './slice';
7 |
8 | export const Notifications: React.FC = () => {
9 | const notifications = useAppSelector(selectNotifications);
10 |
11 | return ;
12 | };
13 |
--------------------------------------------------------------------------------
/frontend/src/components/Notifications/types.ts:
--------------------------------------------------------------------------------
1 | import { FlashbarProps } from '@cloudscape-design/components/flashbar';
2 |
3 | export type Notification = FlashbarProps.MessageDefinition;
4 |
--------------------------------------------------------------------------------
/frontend/src/components/PermissionGuard/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { usePermissionGuard } from 'hooks';
4 |
5 | import { IProps } from './types';
6 |
7 | export const PermissionGuard: React.FC = ({ children, ...props }) => {
8 | const [isAvailable] = usePermissionGuard(props);
9 |
10 | if (!isAvailable) return null;
11 |
12 | return <>{children}>;
13 | };
14 |
--------------------------------------------------------------------------------
/frontend/src/components/PermissionGuard/types.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { GlobalUserRole, ProjectUserRole } from 'types';
4 |
5 | export interface IProps {
6 | allowedGlobalRoles?: GlobalUserRole[];
7 | allowedProjectRoles?: ProjectUserRole[];
8 | projectRole?: string;
9 | children: React.ReactNode;
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/src/components/Tabs/styles.module.scss:
--------------------------------------------------------------------------------
1 | .tabs {
2 | &:not(.hasContent) {
3 | :global {
4 | [class^="awsui_tabs-content-wrapper"] {
5 | display: none;
6 | }
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/components/form/Checkbox/types.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 | import { ControllerProps, FieldValues } from 'react-hook-form';
3 | import { CheckboxProps } from '@cloudscape-design/components/checkbox';
4 | import { FormFieldProps } from '@cloudscape-design/components/form-field';
5 |
6 | export type FormCheckboxProps = Omit &
7 | Omit &
8 | Pick, 'control' | 'name' | 'rules'> & {
9 | leftContent?: ReactNode;
10 | checkboxLabel?: string;
11 | };
12 |
--------------------------------------------------------------------------------
/frontend/src/components/form/CodeEditor/types.ts:
--------------------------------------------------------------------------------
1 | import { ControllerProps, FieldValues } from 'react-hook-form';
2 | import { CodeEditorProps } from '@cloudscape-design/components/code-editor';
3 | import { FormFieldProps } from '@cloudscape-design/components/form-field';
4 |
5 | export type FormCodeEditorProps = Omit<
6 | CodeEditorProps,
7 | 'value' | 'name' | 'i18nStrings' | 'ace' | 'onPreferencesChange' | 'preferences'
8 | > &
9 | Omit &
10 | Pick, 'control' | 'name' | 'rules'>;
11 |
--------------------------------------------------------------------------------
/frontend/src/components/form/Input/types.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 | import { ControllerProps, FieldValues } from 'react-hook-form';
3 | import { FormFieldProps } from '@cloudscape-design/components/form-field';
4 | import { InputProps } from '@cloudscape-design/components/input';
5 |
6 | export type FormInputProps = Omit &
7 | Omit &
8 | Pick, 'control' | 'name' | 'rules'> & {
9 | leftContent?: ReactNode;
10 | hotspotId?: string;
11 | };
12 |
--------------------------------------------------------------------------------
/frontend/src/components/form/RadioButtons/types.ts:
--------------------------------------------------------------------------------
1 | import { ControllerProps, FieldValues } from 'react-hook-form';
2 | import { FormFieldProps } from '@cloudscape-design/components/form-field';
3 | import { RadioGroupProps } from '@cloudscape-design/components/radio-group';
4 |
5 | export type FormRadioButtonsProps = Omit &
6 | Omit &
7 | Pick, 'control' | 'name' | 'rules'>;
8 |
--------------------------------------------------------------------------------
/frontend/src/components/form/Select/types.ts:
--------------------------------------------------------------------------------
1 | import { ControllerProps, FieldValues } from 'react-hook-form';
2 | import { FormFieldProps } from '@cloudscape-design/components/form-field';
3 | import { SelectProps } from '@cloudscape-design/components/select';
4 |
5 | export type FormSelectOption = SelectProps.Option;
6 | export type FormSelectOptions = ReadonlyArray;
7 |
8 | export type FormSelectProps = Omit &
9 | Omit &
10 | Pick, 'control' | 'name' | 'rules'> & {
11 | options: ReadonlyArray;
12 | };
13 |
--------------------------------------------------------------------------------
/frontend/src/components/form/Textarea/types.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 | import { ControllerProps, FieldValues } from 'react-hook-form';
3 | import { FormFieldProps } from '@cloudscape-design/components/form-field';
4 | import { TextareaProps } from '@cloudscape-design/components/textarea';
5 |
6 | export type FormTextareaProps = Omit &
7 | Omit &
8 | Pick, 'control' | 'name' | 'rules'> & {
9 | leftContent?: ReactNode;
10 | };
11 |
--------------------------------------------------------------------------------
/frontend/src/components/form/Tiles/types.ts:
--------------------------------------------------------------------------------
1 | import { Control, FieldValues, Path } from 'react-hook-form';
2 | import { TilesProps } from '@cloudscape-design/components/tiles';
3 |
4 | export type FormTilesProps = Omit & {
5 | control: Control;
6 | name: Path;
7 | };
8 |
--------------------------------------------------------------------------------
/frontend/src/consts.ts:
--------------------------------------------------------------------------------
1 | export const DATE_TIME_FORMAT = 'MM/dd/yyyy HH:mm';
2 | export const DISCORD_URL = 'https://discord.gg/u8SmfwPpMd';
3 | export const QUICK_START_URL = 'https://dstack.ai/docs/quickstart/';
4 | export const TALLY_FORM_ID = '3xYlYG';
5 | export const DOCS_URL = 'https://dstack.ai/docs/';
6 | export const DEFAULT_TABLE_PAGE_SIZE = 20;
7 |
--------------------------------------------------------------------------------
/frontend/src/consts/index.ts:
--------------------------------------------------------------------------------
1 | export const TEMP = 'temp';
2 |
--------------------------------------------------------------------------------
/frontend/src/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export { default as useAppDispatch } from './useAppDispatch';
2 | export { default as useAppSelector } from './useAppSelector';
3 | export { useBreadcrumbs } from './useBreadcrumbs';
4 | export { useNotifications } from './useNotifications';
5 | export { useHelpPanel } from './useHelpPanel';
6 | export { usePermissionGuard } from './usePermissionGuard';
7 | export { useInfiniteScroll } from './useInfiniteScroll';
8 |
9 | // cloudscape
10 | export { useCollection } from '@cloudscape-design/collection-hooks';
11 |
--------------------------------------------------------------------------------
/frontend/src/hooks/useAppDispatch.ts:
--------------------------------------------------------------------------------
1 | import { useDispatch } from 'react-redux';
2 | import { AppDispatch } from 'store';
3 |
4 | const useAppDispatch = () => useDispatch();
5 |
6 | export default useAppDispatch;
7 |
--------------------------------------------------------------------------------
/frontend/src/hooks/useAppSelector.ts:
--------------------------------------------------------------------------------
1 | import { TypedUseSelectorHook, useSelector } from 'react-redux';
2 | import { RootState } from 'store';
3 |
4 | const useAppSelector: TypedUseSelectorHook = useSelector;
5 |
6 | export default useAppSelector;
7 |
--------------------------------------------------------------------------------
/frontend/src/hooks/useBreadcrumbs.ts:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 |
3 | import { setBreadcrumb } from 'App/slice';
4 |
5 | import useAppDispatch from './useAppDispatch';
6 |
7 | export const useBreadcrumbs = (breadcrumbs: TBreadcrumb[]) => {
8 | const dispatch = useAppDispatch();
9 |
10 | useEffect(() => {
11 | dispatch(setBreadcrumb(breadcrumbs));
12 |
13 | return () => {
14 | dispatch(setBreadcrumb(null));
15 | };
16 | }, [breadcrumbs]);
17 | };
18 |
--------------------------------------------------------------------------------
/frontend/src/hooks/useHelpPanel.ts:
--------------------------------------------------------------------------------
1 | import { openHelpPanel } from 'App/slice';
2 |
3 | import useAppDispatch from './useAppDispatch';
4 |
5 | import { THelpPanelContent } from 'App/types';
6 |
7 | export const useHelpPanel = () => {
8 | const dispatch = useAppDispatch();
9 |
10 | const openPanel = (content: THelpPanelContent) => {
11 | dispatch(openHelpPanel(content));
12 | };
13 |
14 | return [openPanel];
15 | };
16 |
--------------------------------------------------------------------------------
/frontend/src/hooks/useIsMounted.ts:
--------------------------------------------------------------------------------
1 | import { useCallback, useEffect, useRef } from 'react';
2 |
3 | function useIsMounted() {
4 | const isMounted = useRef(false);
5 |
6 | useEffect(() => {
7 | isMounted.current = true;
8 |
9 | return () => {
10 | isMounted.current = false;
11 | };
12 | }, []);
13 |
14 | return useCallback(() => isMounted.current, []);
15 | }
16 |
17 | export default useIsMounted;
18 |
--------------------------------------------------------------------------------
/frontend/src/hooks/usePrevious.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react';
2 |
3 | function usePrevious(value: T): T {
4 | const ref = useRef(value);
5 |
6 | useEffect(() => {
7 | ref.current = value;
8 | }, [value]);
9 |
10 | return ref.current;
11 | }
12 |
13 | export default usePrevious;
14 |
--------------------------------------------------------------------------------
/frontend/src/layouts/AppLayout/Tally/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 |
3 | export const TallyComponent: React.FC = () => {
4 | useEffect(() => {
5 | const widgetScriptSrc = 'https://tally.so/widgets/embed.js';
6 |
7 | if (document.querySelector(`script[src="${widgetScriptSrc}"]`) === null) {
8 | const script = document.createElement('script');
9 | script.src = widgetScriptSrc;
10 | document.body.appendChild(script);
11 | return;
12 | }
13 | }, []);
14 |
15 | return null;
16 | };
17 |
--------------------------------------------------------------------------------
/frontend/src/layouts/AppLayout/TutorialPanel/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { TutorialPanel as TutorialPanelGeneric, TutorialPanelProps } from 'components';
4 |
5 | import { tutorialPanelI18nStrings } from './constants';
6 | import { useTutorials } from './hooks';
7 |
8 | export interface Props extends Partial {
9 | test?: string;
10 | }
11 |
12 | export const TutorialPanel: React.FC = () => {
13 | const { tutorials } = useTutorials();
14 |
15 | return ;
16 | };
17 |
--------------------------------------------------------------------------------
/frontend/src/layouts/UnauthorizedLayout/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import styles from './styles.module.scss';
4 |
5 | export interface UnauthorizedLayoutProps {
6 | children?: React.ReactNode;
7 | }
8 |
9 | export const UnauthorizedLayout: React.FC = ({ children }) => {
10 | return {children}
;
11 | };
12 |
--------------------------------------------------------------------------------
/frontend/src/layouts/UnauthorizedLayout/styles.module.scss:
--------------------------------------------------------------------------------
1 | @use '@cloudscape-design/design-tokens/index' as awsui;
2 |
3 | .layout {
4 | background: awsui.$color-background-layout-main;
5 | padding-top: 40px;
6 | padding-bottom: 40px;
7 | min-height: 100vh;
8 | box-sizing: border-box;
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/libs/fetchBaseQueryHeaders.ts:
--------------------------------------------------------------------------------
1 | import type { BaseQueryApi } from '@reduxjs/toolkit/query';
2 |
3 | import { RootState } from '../store';
4 |
5 | function baseQueryHeaders(headers: Headers, { getState }: Pick): Headers {
6 | const token = (getState() as RootState).app.authData?.token;
7 | const authorizationHeader = headers.get('Authorization');
8 |
9 | if (token && !authorizationHeader) {
10 | headers.set('Authorization', `Bearer ${token}`);
11 | }
12 |
13 | headers.set('X-API-VERSION', 'latest');
14 |
15 | return headers;
16 | }
17 |
18 | export default baseQueryHeaders;
19 |
--------------------------------------------------------------------------------
/frontend/src/libs/form.ts:
--------------------------------------------------------------------------------
1 | import { FormFieldError } from './types';
2 |
3 | export const getFieldErrorFromServerResponse = (error: FormFieldError): { fieldNamePath: string; message: string } => {
4 | const fieldNamePath = error.loc.filter((key) => key !== 'body').join('.');
5 | const message = error.msg;
6 |
7 | return { fieldNamePath, message };
8 | };
9 |
--------------------------------------------------------------------------------
/frontend/src/libs/types.ts:
--------------------------------------------------------------------------------
1 | export type FormFieldError = {
2 | loc: string[];
3 | msg: string;
4 | type?: string;
5 | code: string;
6 | };
7 |
8 | export type ResponseServerErrorItem = {
9 | msg: string;
10 | code: string;
11 | };
12 |
13 | export type ResponseServerError = {
14 | detail: (FormFieldError | ResponseServerErrorItem)[];
15 | };
16 |
--------------------------------------------------------------------------------
/frontend/src/libs/volumes.ts:
--------------------------------------------------------------------------------
1 | import { StatusIndicatorProps } from '@cloudscape-design/components';
2 |
3 | export const getStatusIconType = (status: IVolume['status']): StatusIndicatorProps['type'] => {
4 | switch (status) {
5 | case 'failed':
6 | return 'error';
7 | case 'active':
8 | return 'success';
9 | case 'provisioning':
10 | return 'in-progress';
11 | case 'submitted':
12 | default:
13 | console.error(new Error('Undefined volume status'));
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/frontend/src/locale/index.ts:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import { initReactI18next } from 'react-i18next';
3 |
4 | import en from './en.json';
5 |
6 | i18n.use(initReactI18next).init({
7 | returnNull: false,
8 | resources: {
9 | en: {
10 | translation: en,
11 | },
12 | },
13 | fallbackLng: 'en',
14 |
15 | interpolation: {
16 | escapeValue: false,
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/frontend/src/pages/Fleets/List/styles.module.scss:
--------------------------------------------------------------------------------
1 | .filters {
2 | --select-width: calc((688px - 3 * 20px) / 2);
3 | display: flex;
4 | flex-wrap: wrap;
5 | gap: 0 20px;
6 |
7 | .select {
8 | width: var(--select-width, 30%);
9 | }
10 |
11 | .activeOnly {
12 | display: flex;
13 | align-items: center;
14 | padding-top: 26px;
15 | }
16 |
17 | .clear {
18 | padding-top: 26px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/src/pages/Fleets/index.ts:
--------------------------------------------------------------------------------
1 | export { FleetList } from './List';
2 | export { FleetDetails } from './Details';
3 |
--------------------------------------------------------------------------------
/frontend/src/pages/Instances/List/styles.module.scss:
--------------------------------------------------------------------------------
1 | .filters {
2 | --select-width: calc((688px - 3 * 20px) / 2);
3 | display: flex;
4 | flex-wrap: wrap;
5 | gap: 0 20px;
6 |
7 | .select {
8 | width: var(--select-width, 30%);
9 | }
10 |
11 | .activeOnly {
12 | display: flex;
13 | align-items: center;
14 | padding-top: 26px;
15 | }
16 |
17 | .clear {
18 | padding-top: 26px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/src/pages/Instances/index.ts:
--------------------------------------------------------------------------------
1 | export { List as InstanceList } from './List';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Models/Details/types.ts:
--------------------------------------------------------------------------------
1 | export interface FormValues {
2 | instructions?: string;
3 | message: string;
4 | }
5 |
6 | export type Role = 'system' | 'user' | 'assistant' | 'tool';
7 |
8 | export interface Message {
9 | role: Role;
10 | content: string;
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/src/pages/Models/List/Preferences/useModelListPreferences.ts:
--------------------------------------------------------------------------------
1 | import { CollectionPreferencesProps } from 'components';
2 |
3 | import { useLocalStorageState } from 'hooks/useLocalStorageState';
4 |
5 | import { DEFAULT_PREFERENCES } from './consts';
6 |
7 | export const useModelListPreferences = () => {
8 | const [preferences, setPreferences] = useLocalStorageState(
9 | 'model-list-preferences',
10 | DEFAULT_PREFERENCES,
11 | );
12 |
13 | return [preferences, setPreferences] as const;
14 | };
15 |
--------------------------------------------------------------------------------
/frontend/src/pages/Models/List/styles.module.scss:
--------------------------------------------------------------------------------
1 | .selectFilters {
2 | --select-width: calc((688px - 3 * 20px) / 2);
3 | display: flex;
4 | flex-wrap: wrap;
5 | gap: 0 20px;
6 |
7 | .select {
8 | width: var(--select-width, 30%);
9 | }
10 |
11 | .activeOnly {
12 | display: flex;
13 | align-items: center;
14 | padding-top: 26px;
15 | }
16 |
17 | .clear {
18 | padding-top: 26px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/src/pages/Models/List/types.ts:
--------------------------------------------------------------------------------
1 | export interface IModelExtended extends Partial {
2 | id: string;
3 | run_name: string;
4 | project_name: string;
5 | submitted_at: string;
6 | user: string;
7 | resources: string | null;
8 | price: number | null;
9 | region: string | null;
10 | repository: string | null;
11 | backend: TBackendType | null;
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/src/pages/Models/helpers.ts:
--------------------------------------------------------------------------------
1 | import { isValidUrl } from 'libs';
2 |
3 | export const getModelGateway = (baseUrl?: IModel['base_url']) => {
4 | if (!baseUrl) {
5 | return '';
6 | }
7 |
8 | if (isValidUrl(baseUrl)) {
9 | return baseUrl;
10 | }
11 |
12 | return document.location.origin + baseUrl;
13 | };
14 |
--------------------------------------------------------------------------------
/frontend/src/pages/Models/index.ts:
--------------------------------------------------------------------------------
1 | export { List as ModelsList } from './List';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Backends/Table/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useColumnsDefinitions';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Backends/Table/styles.module.scss:
--------------------------------------------------------------------------------
1 | .cell {
2 | display: flex;
3 | align-items: center;
4 | }
5 |
6 | .contextMenu {
7 | margin-left: auto;
8 | padding-left: 20px;
9 | }
10 |
11 | .ellipsisCell {
12 | overflow: hidden;
13 | white-space: nowrap;
14 | text-overflow: ellipsis;
15 | max-width: 450px;
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Backends/Table/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps {
2 | backends: IProjectBackend[];
3 | onClickAddBackend?: () => void;
4 | deleteBackends?: (backends: readonly IProjectBackend[] | IProjectBackend[]) => void;
5 | editBackend?: (backend: IProjectBackend) => void;
6 | isDisabledDelete?: boolean;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Backends/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export { useBackendsTable } from './useBackendsTable';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Backends/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | export { BackendAdd } from './Add';
3 | export { BackendEdit } from './Edit';
4 |
5 | export const Backends: React.FC = () => {
6 | return null;
7 | };
8 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Details/Settings/styles.module.scss:
--------------------------------------------------------------------------------
1 | .dangerSectionGrid {
2 | display: grid;
3 | gap: 20px 40px;
4 | grid-template-columns: minmax(auto, 300px) 1fr;
5 | }
6 |
7 | .dangerSectionField {
8 | width: 300px;
9 | }
10 |
11 | .codeWrapper {
12 | position: relative;
13 |
14 | .code {
15 | padding: 16px 12px;
16 | }
17 |
18 | .copy {
19 | position: absolute;
20 | top: 10px;
21 | right: 8px;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Details/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Outlet, useParams } from 'react-router-dom';
3 |
4 | import { ContentLayout, DetailsHeader } from 'components';
5 |
6 | export const ProjectDetails: React.FC = () => {
7 | const params = useParams();
8 | const paramProjectName = params.projectName ?? '';
9 |
10 | return (
11 | }>
12 |
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Form/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps {
2 | initialValues?: Partial;
3 | loading?: boolean;
4 | onCancel: () => void;
5 | onSubmit: (user: IProject) => Promise;
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/Add/styles.module.scss:
--------------------------------------------------------------------------------
1 | .fieldSpinner {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | height: 34px;
6 | width: 34px;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/Edit/styles.module.scss:
--------------------------------------------------------------------------------
1 | .fieldSpinner {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | height: 34px;
6 | width: 34px;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/Table/constants.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const GATEWAYS_INFO = {
4 | header: Gateways
,
5 | body: (
6 | <>
7 | Gateways manage the ingress traffic for running services.
8 |
9 | To learn more about gateways, see the{' '}
10 |
11 | documentation
12 |
13 | .
14 |
15 | >
16 | ),
17 | };
18 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/Table/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useColumnsDefinitions';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/Table/styles.module.scss:
--------------------------------------------------------------------------------
1 | .cell {
2 | display: flex;
3 | align-items: center;
4 | }
5 |
6 | .contextMenu {
7 | margin-left: auto;
8 | padding-left: 20px;
9 | }
10 |
11 | .ellipsisCell {
12 | overflow: hidden;
13 | white-space: nowrap;
14 | text-overflow: ellipsis;
15 | max-width: 450px;
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/Table/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps {
2 | gateways: IGateway[];
3 | addItem?: () => void;
4 | deleteItem?: (gateways: readonly IGateway[] | IGateway[]) => void;
5 | editItem?: (gateways: IGateway) => void;
6 | isDisabledDelete?: boolean;
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export { useGatewaysTable } from './useGatewaysTable';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Gateways/index.tsx:
--------------------------------------------------------------------------------
1 | export { GatewaysTable } from './Table';
2 | export { AddGateway } from './Add';
3 | export { EditGateway } from './Edit';
4 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/List/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useColumnsDefinitions';
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/List/styles.module.scss:
--------------------------------------------------------------------------------
1 | .cell {
2 | display: flex;
3 | align-items: center;
4 | }
5 |
6 | .contextMenu {
7 | margin-left: auto;
8 | padding-left: 20px;
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Members/styles.module.scss:
--------------------------------------------------------------------------------
1 | .role {
2 | display: flex;
3 | align-items: center;
4 | gap: 20px;
5 | }
6 | .roleFieldWrapper {
7 | flex-grow: 1;
8 | flex-basis: 0;
9 | max-width: 200px;
10 | }
11 | .deleteMemberButtonWrapper {
12 | margin-left: auto;
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/Members/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps {
2 | members?: IProjectMember[];
3 | loading?: boolean;
4 | onChange: (users: IProjectMember[]) => void;
5 | readonly?: boolean;
6 | isAdmin?: boolean;
7 | }
8 |
9 | export type TProjectMemberWithIndex = IProjectMember & { index: number };
10 | export type TFormValues = { members: IProjectMember[] };
11 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/hooks/useConfigProjectCliComand.ts:
--------------------------------------------------------------------------------
1 | import { useAppSelector } from 'hooks';
2 | import { copyToClipboard } from 'libs';
3 |
4 | import { selectAuthToken } from 'App/slice';
5 |
6 | type Args = {
7 | projectName: string;
8 | };
9 | export const useConfigProjectCliCommand = ({ projectName }: Args) => {
10 | const currentUserToken = useAppSelector(selectAuthToken);
11 |
12 | const cliCommand = `dstack project add --name ${projectName} --url ${location.origin} --token ${currentUserToken}`;
13 |
14 | const copyCliCommand = () => {
15 | copyToClipboard(cliCommand);
16 | };
17 |
18 | return [cliCommand, copyCliCommand] as const;
19 | };
20 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | export { ProjectList } from './List';
3 | export { ProjectDetails } from './Details';
4 | export { ProjectSettings } from './Details/Settings';
5 | export { ProjectAdd } from './Add';
6 |
7 | export const Project: React.FC = () => {
8 | return null;
9 | };
10 |
--------------------------------------------------------------------------------
/frontend/src/pages/Project/utils.ts:
--------------------------------------------------------------------------------
1 | export const getProjectRoleByUserName = (
2 | project: IProject,
3 | userName: IProjectMember['user']['username'],
4 | ): TProjectRole | null => {
5 | return project.members.find((m) => m.user.username === userName)?.project_role ?? null;
6 | };
7 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Artifacts/styles.module.scss:
--------------------------------------------------------------------------------
1 | .artifacts {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Artifacts/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps extends Partial> {
2 | className?: string;
3 | }
4 |
5 | export interface ITableItem {
6 | name: string;
7 | path: string;
8 | type: string;
9 | size: number | null;
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Jobs/Details/JobDetails/styles.module.scss:
--------------------------------------------------------------------------------
1 | .details {
2 | height: calc(100vh - 272px);
3 | display: flex;
4 | flex-direction: column;
5 | gap: 16px;
6 |
7 | & > [class^="awsui_layout"] {
8 | height: 100%;
9 | & > [class^="awsui_content"] {
10 | display: flex;
11 | flex-direction: column;
12 | gap: 20px;
13 | height: 100%;
14 | }
15 | }
16 | }
17 |
18 | .logs {
19 | flex-grow: 1;
20 | min-height: 0;
21 | max-height: calc(100vh - 380px);
22 | }
23 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Jobs/Details/styles.module.scss:
--------------------------------------------------------------------------------
1 | .page {
2 | height: 100%;
3 |
4 | & > [class^="awsui_layout"] {
5 | height: 100%;
6 |
7 | & > [class^="awsui_content"] {
8 | display: flex;
9 | flex-direction: column;
10 | gap: 20px;
11 | height: 100%;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Jobs/Metrics/consts.ts:
--------------------------------------------------------------------------------
1 | export const second = 1000;
2 | export const minute = 60 * second;
3 | export const hour = minute * 60;
4 |
5 | export const kByte = 1024;
6 | export const MByte = kByte * 1024;
7 | export const GByte = MByte * 1024;
8 |
9 | export const CPU_NUMS = 'cpus_detected_num';
10 | export const ALL_CPU_USAGE = 'cpu_usage_percent';
11 | export const MEMORY_WORKING_SET = 'memory_working_set_bytes';
12 | export const MEMORY_TOTAL = 'memory_total_bytes';
13 | export const EACH_GPU_USAGE_PREFIX = 'gpu_util_percent_gpu';
14 | export const EACH_GPU_MEMORY_USAGE_PREFIX = 'gpu_memory_usage_bytes_gpu';
15 | export const EACH_GPU_MEMORY_TOTAL = 'gpu_memory_total_bytes';
16 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Logs/helpers.ts:
--------------------------------------------------------------------------------
1 | export const getJobSubmissionId = (run?: IRun): string | undefined => {
2 | if (!run) return;
3 |
4 | const lastJob = run.jobs[run.jobs.length - 1];
5 |
6 | if (!lastJob) return;
7 |
8 | return lastJob.job_submissions[lastJob.job_submissions.length - 1]?.id;
9 | };
10 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/Logs/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps {
2 | projectName: string;
3 | runName: string;
4 | jobSubmissionId?: string | null;
5 | className?: string;
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/RunDetails/styles.module.scss:
--------------------------------------------------------------------------------
1 | .logs {
2 | flex-grow: 1;
3 | min-height: 0;
4 | max-height: calc(100vh - 480px);
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/Details/styles.module.scss:
--------------------------------------------------------------------------------
1 | .page {
2 | height: 100%;
3 |
4 | & [class^="awsui_tabs-content"] {
5 | display: none;
6 | }
7 |
8 | & > [class^="awsui_layout"] {
9 | height: 100%;
10 |
11 | & > [class^="awsui_content"] {
12 | display: flex;
13 | flex-direction: column;
14 | gap: 20px;
15 | height: 100%;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/List/Preferences/useRunListPreferences.ts:
--------------------------------------------------------------------------------
1 | import { CollectionPreferencesProps } from 'components';
2 |
3 | import { useLocalStorageState } from 'hooks/useLocalStorageState';
4 |
5 | import { DEFAULT_PREFERENCES } from './consts';
6 |
7 | export const useRunListPreferences = () => {
8 | const [preferences, setPreferences] = useLocalStorageState(
9 | 'run-list-preferences',
10 | DEFAULT_PREFERENCES,
11 | );
12 |
13 | return [preferences, setPreferences] as const;
14 | };
15 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/List/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useColumnsDefinitions';
2 | export * from './useStopRuns';
3 | export * from './useDeleteRuns';
4 | export * from './useDisabledStatesForButtons';
5 | export * from './useEmptyMessages';
6 | export * from './useFilters';
7 |
--------------------------------------------------------------------------------
/frontend/src/pages/Runs/index.ts:
--------------------------------------------------------------------------------
1 | export { RunList } from './List';
2 | export { RunDetailsPage } from './Details';
3 | export { RunDetails } from './Details/RunDetails';
4 | export { JobMetrics } from './Details/Jobs/Metrics';
5 | export { Logs } from './Details/Logs';
6 | export { Artifacts } from './Details/Artifacts';
7 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/Billing/PayForm/types.ts:
--------------------------------------------------------------------------------
1 | export type FormValues = {
2 | amount: number;
3 | };
4 |
5 | export interface IProps {
6 | defaultValues?: Partial;
7 | isLoading?: boolean;
8 | onCancel?: () => void;
9 | onSubmit: (values: FormValues) => void;
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/Billing/components/AmountField/styles.module.scss:
--------------------------------------------------------------------------------
1 | .amountInput {
2 | .prefix {
3 | position: absolute;
4 | z-index: 1;
5 | transform: translate(8px, 6px);
6 | pointer-events: none;
7 | }
8 |
9 | input {
10 | padding-left: 18px !important;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/CreditsHistory/Add/types.ts:
--------------------------------------------------------------------------------
1 | export type TFormValue = Pick;
2 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/CreditsHistory/constants.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | export const PAYMENTS_INFO = {
3 | header: Credits history
,
4 | body: (
5 | <>
6 | Available for only the global admin role
7 | >
8 | ),
9 | };
10 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/CreditsHistory/types.ts:
--------------------------------------------------------------------------------
1 | export interface IProps {
2 | username: string;
3 | }
4 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/Payments/types.ts:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export interface IProps {
4 | payments: IPayment[];
5 | emptyMessageContent?: React.ReactNode;
6 | isLoading?: boolean;
7 | tableHeaderContent?: React.ReactNode;
8 | }
9 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/Settings/styles.module.scss:
--------------------------------------------------------------------------------
1 | .token {
2 | display: flex;
3 | align-items: center;
4 | height: 20px;
5 | gap: 12px;
6 |
7 | button {
8 | padding: 0 !important;
9 | border: none !important;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Details/types.ts:
--------------------------------------------------------------------------------
1 | export enum UserDetailsTabTypeEnum {
2 | SETTINGS = 'settings',
3 | PROJECTS = 'projects',
4 | BILLING = 'billing',
5 | }
6 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/Form/types.ts:
--------------------------------------------------------------------------------
1 | export type TRoleSelectOption = { label: string; value: TProjectRole; disabled?: boolean };
2 | export type TActiveSelectOption = { label: string; value: 'active' | 'inactive'; disabled?: boolean };
3 |
--------------------------------------------------------------------------------
/frontend/src/pages/User/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | export { UserList } from './List';
3 | export { UserDetails } from './Details';
4 | export { UserEdit } from './Edit';
5 | export { UserAdd } from './Add';
6 | export { Add as CreditsHistoryAdd } from './Details/CreditsHistory/Add';
7 |
8 | export const User: React.FC = () => {
9 | return null;
10 | };
11 |
--------------------------------------------------------------------------------
/frontend/src/pages/Volumes/List/styles.module.scss:
--------------------------------------------------------------------------------
1 | .filters {
2 | --select-width: calc((688px - 3 * 20px) / 2);
3 | display: flex;
4 | flex-wrap: wrap;
5 | gap: 0 20px;
6 |
7 | .select {
8 | width: var(--select-width, 30%);
9 | }
10 |
11 | .activeOnly {
12 | display: flex;
13 | align-items: center;
14 | padding-top: 26px;
15 | }
16 |
17 | .clear {
18 | padding-top: 26px;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/frontend/src/pages/Volumes/index.ts:
--------------------------------------------------------------------------------
1 | export { VolumeList } from './List';
2 |
--------------------------------------------------------------------------------
/frontend/src/services/mainApi.ts:
--------------------------------------------------------------------------------
1 | import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
2 |
3 | import fetchBaseQueryHeaders from '../libs/fetchBaseQueryHeaders';
4 |
5 | export const mainApi = createApi({
6 | baseQuery: fetchBaseQuery({
7 | prepareHeaders: fetchBaseQueryHeaders,
8 | }),
9 | endpoints: () => ({}),
10 | });
11 |
--------------------------------------------------------------------------------
/frontend/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/frontend/src/types/artifact.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare interface IArtifactFile {
3 | filepath: string,
4 | filesize_in_bytes: number | null
5 | }
6 | declare interface IArtifact {
7 | job_id: string,
8 | name: string,
9 | path: string,
10 |
11 | files: IArtifactFile[]
12 | }
13 |
14 | declare type TRequestArtifactListParams = {
15 | name: IProject['project_name'],
16 | run_name: IRun['run_name'],
17 | prefix: string,
18 | recursive?: boolean
19 | }
20 |
--------------------------------------------------------------------------------
/frontend/src/types/bread-crums.d.ts:
--------------------------------------------------------------------------------
1 | declare type TBreadcrumb = { text: string, href: string }
2 |
--------------------------------------------------------------------------------
/frontend/src/types/gateway.d.ts:
--------------------------------------------------------------------------------
1 | declare interface IGateway {
2 | backend: string,
3 | name: string,
4 | ip_address: string,
5 | instance_id: string,
6 | region:string
7 | wildcard_domain?: string
8 | default: boolean
9 | created_at?: number,
10 | }
11 |
12 | declare type TGatewayBackendsListResponse = {
13 | backend: string,
14 | regions: string[],
15 | }[]
16 |
17 | declare type TCreateGatewayParams = {
18 | backend_type: string,
19 | region?: string,
20 | }
21 |
22 | declare type TUpdateGatewayParams = {
23 | wildcard_domain?: string,
24 | default?: boolean,
25 | }
26 |
--------------------------------------------------------------------------------
/frontend/src/types/i18next.d.ts:
--------------------------------------------------------------------------------
1 | import 'i18next';
2 |
3 | declare module 'i18next' {
4 | interface CustomTypeOptions {
5 | returnNull: false;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/types/labmda-backend.d.ts:
--------------------------------------------------------------------------------
1 |
2 | declare interface ILambdaBackendValues {
3 | type: 'lambda',
4 | regions: TBackendValueField,
5 | }
6 |
7 | declare interface IBackendLambda {
8 | type: 'lambda',
9 | creds: {
10 | api_key: string,
11 | },
12 | regions: string[],
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/src/types/log.d.ts:
--------------------------------------------------------------------------------
1 | declare interface ILogItem {
2 | log_source: 'stdout' | 'stderr'
3 | timestamp: string,
4 | message: string | Uint8Array,
5 | }
6 |
7 | declare type TRequestLogsParams = {
8 | project_name: IProject['project_name'],
9 | run_name: IRun['run_name'],
10 | job_submission_id: string
11 | start_time?: DateTime,
12 | end_time?: DateTime,
13 | descending?: boolean,
14 | limit?: number
15 | diagnose?: boolean
16 | }
17 |
--------------------------------------------------------------------------------
/frontend/src/types/payment.d.ts:
--------------------------------------------------------------------------------
1 | declare interface IPayment {
2 | id: string,
3 | type: "invoice" | "manual",
4 | created_at: string,
5 | value: number,
6 | description: string
7 | }
8 |
--------------------------------------------------------------------------------
/frontend/src/types/repo.d.ts:
--------------------------------------------------------------------------------
1 | enum RepoTypeEnum {
2 | REMOTE = 'remote',
3 | LOCAL = 'local',
4 | }
5 |
6 | declare interface IRemoteRunRepoData {
7 | repo_type: 'remote'
8 | repo_name: string
9 | repo_branch?: string
10 | repo_hash?: string
11 | repo_diff?: string
12 | repo_config_name?: string
13 | repo_config_email?: string
14 | }
15 |
16 | declare interface ILocalRunRepoData {
17 | repo_type: 'local'
18 | repo_dir: string
19 | }
20 |
21 | declare interface VirtualRunRepoData {
22 | repo_type: 'virtual'
23 | }
24 |
25 | declare interface IRepo {
26 | repo_id: string,
27 | repo_info: IRemoteRunRepoData | ILocalRunRepoData | VirtualRunRepoData
28 | }
29 |
--------------------------------------------------------------------------------
/frontend/tests/__mocks__/MockStore.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Provider } from 'react-redux';
3 | import { store } from 'store';
4 |
5 | type Props = {
6 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
7 | children: any;
8 | };
9 |
10 | const MockStore = ({ children }: Props) => {
11 | return {children};
12 | };
13 |
14 | export default MockStore;
15 |
--------------------------------------------------------------------------------
/frontend/tests/__mocks__/fileMock.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2 | // @ts-ignore
3 | module.exports = 'test-file-stub';
4 |
--------------------------------------------------------------------------------
/frontend/tests/__mocks__/shim.ts:
--------------------------------------------------------------------------------
1 | global.requestAnimationFrame = (callback): number => {
2 | setTimeout(callback, 0);
3 | return 0;
4 | };
5 |
--------------------------------------------------------------------------------
/frontend/tests/__mocks__/svgrMock.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line
2 | export default 'SvgrURL';
3 | export const ReactComponent = 'IconMock';
4 |
--------------------------------------------------------------------------------
/frontend/tests/setupEnzyme.ts:
--------------------------------------------------------------------------------
1 | import Enzyme from 'enzyme';
2 | import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
3 |
4 | Enzyme.configure({ adapter: new Adapter() });
5 |
--------------------------------------------------------------------------------
/frontend/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { merge } = require("webpack-merge");
2 | const base = require("./webpack/base");
3 | const dev = require("./webpack/dev");
4 | const prod = require("./webpack/prod");
5 |
6 | const {isDev} = require('./webpack/env');
7 |
8 | module.exports = isDev ? merge(base, dev) : merge(base, prod);
9 |
--------------------------------------------------------------------------------
/gateway/README.md:
--------------------------------------------------------------------------------
1 | # `dstack-gateway`
2 |
3 | A thin package to deliver and install the gateway app. Expected to be merged with the `dstack` package in [#2251](https://github.com/dstackai/dstack/issues/2251).
4 |
5 | For details about gateways, see [contributing/PROXY.md](../contributing/PROXY.md).
6 |
--------------------------------------------------------------------------------
/gateway/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools>=61.0"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [project]
6 | name = "dstack-gateway"
7 | authors = [
8 | { name = "dstack GmbH" },
9 | ]
10 | requires-python = ">=3.10"
11 | dynamic = ["version"]
12 | dependencies = [
13 | # release builds of dstack-gateway depend on a PyPI version of dstack instead
14 | "dstack[gateway] @ git+https://github.com/dstackai/dstack.git@master",
15 | ]
16 |
17 | [tool.setuptools.package-data]
18 | "dstack.gateway" = [
19 | "resources/systemd/*",
20 | ]
21 |
22 | [tool.setuptools.dynamic]
23 | version = {attr = "dstack.gateway.version.__version__"}
24 |
--------------------------------------------------------------------------------
/gateway/src/dstack/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/gateway/src/dstack/__init__.py
--------------------------------------------------------------------------------
/gateway/src/dstack/gateway/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/gateway/src/dstack/gateway/__init__.py
--------------------------------------------------------------------------------
/gateway/src/dstack/gateway/main.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.proxy.gateway.main import app as app
2 |
--------------------------------------------------------------------------------
/gateway/src/dstack/gateway/resources/systemd/dstack.gateway.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=dstack gateway service
3 | After=network.target
4 |
5 | [Service]
6 | ExecStart=/bin/sh {working_dir}/start.sh
7 | WorkingDirectory={working_dir}
8 | User=ubuntu
9 | Group=ubuntu
10 | Restart=always
11 | RestartSec=5
12 |
13 | [Install]
14 | WantedBy=default.target
15 |
--------------------------------------------------------------------------------
/gateway/src/dstack/gateway/resources/systemd/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 | root="$( cd -- "$(dirname "$0")" >/dev/null 2>&1; pwd -P )"
4 |
5 | if [ -f "$root/version" ]; then
6 | version=$(cat "$root/version") # blue/green
7 | else
8 | version="blue"
9 | echo "$version" > "$root/version"
10 | fi
11 | "$root/$version/bin/uvicorn" dstack.gateway.main:app
12 |
--------------------------------------------------------------------------------
/gateway/src/dstack/gateway/systemd/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/gateway/src/dstack/gateway/systemd/__init__.py
--------------------------------------------------------------------------------
/gateway/src/dstack/gateway/version.py:
--------------------------------------------------------------------------------
1 | __version__ = "0.0.0"
2 |
--------------------------------------------------------------------------------
/gateway/src/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/gateway/src/tests/__init__.py
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | testpaths = src/tests
3 | addopts =
4 | --disable-socket
5 | --allow-hosts=127.0.0.1,localhost
6 | ; unix socket for Docker/testcontainers
7 | --allow-unix-socket
8 | markers =
9 | shim_version
10 | dockerized
11 |
--------------------------------------------------------------------------------
/ruff.toml:
--------------------------------------------------------------------------------
1 | target-version = "py39"
2 | line-length = 99
3 |
4 | [lint]
5 | select = ['E', 'F', 'I' ,'Q', 'W', 'PGH', 'FLY', 'S113']
6 | ignore = [
7 | 'E501',
8 | 'E712',
9 | ]
10 |
11 | [lint.isort]
12 | known-first-party = ["dstack"]
13 | known-third-party = ["mkdocs_gen_files", "datacrunch"]
14 |
--------------------------------------------------------------------------------
/runner/internal/common/string.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import "strings"
4 |
5 | func IndexWithOffset(hay string, needle string, start int) int {
6 | idx := strings.Index(hay[start:], needle)
7 | if idx < 0 {
8 | return -1
9 | }
10 | return start + idx
11 | }
12 |
--------------------------------------------------------------------------------
/runner/internal/executor/exec.go:
--------------------------------------------------------------------------------
1 | package executor
2 |
3 | import (
4 | "path/filepath"
5 | "strings"
6 |
7 | "github.com/dstackai/dstack/runner/internal/gerrors"
8 | )
9 |
10 | func joinRelPath(rootDir string, path string) (string, error) {
11 | if filepath.IsAbs(path) {
12 | return "", gerrors.New("path must be relative")
13 | }
14 | targetPath := filepath.Join(rootDir, path)
15 | if !strings.HasPrefix(targetPath, rootDir) {
16 | return "", gerrors.New("path is outside of the root directory")
17 | }
18 | return targetPath, nil
19 | }
20 |
--------------------------------------------------------------------------------
/runner/internal/executor/exec_test.go:
--------------------------------------------------------------------------------
1 | package executor
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestJoinRelPath(t *testing.T) {
10 | base := "/tmp/repo"
11 | var err error
12 | var res string
13 |
14 | res, err = joinRelPath(base, ".")
15 | assert.NoError(t, err)
16 | assert.Equal(t, "/tmp/repo", res)
17 |
18 | _, err = joinRelPath(base, "..")
19 | assert.Error(t, err)
20 |
21 | res, err = joinRelPath(base, "task")
22 | assert.NoError(t, err)
23 | assert.Equal(t, "/tmp/repo/task", res)
24 |
25 | _, err = joinRelPath(base, "/tmp/repo/task")
26 | assert.Error(t, err)
27 | }
28 |
--------------------------------------------------------------------------------
/runner/internal/executor/lock.go:
--------------------------------------------------------------------------------
1 | package executor
2 |
3 | func (ex *RunExecutor) Lock() {
4 | ex.mu.Lock()
5 | }
6 |
7 | func (ex *RunExecutor) Unlock() {
8 | ex.mu.Unlock()
9 | }
10 |
11 | func (ex *RunExecutor) RLock() {
12 | ex.mu.RLock()
13 | }
14 |
15 | func (ex *RunExecutor) RUnlock() {
16 | ex.mu.RUnlock()
17 | }
18 |
--------------------------------------------------------------------------------
/runner/internal/executor/states.go:
--------------------------------------------------------------------------------
1 | package executor
2 |
3 | const (
4 | WaitSubmit = "wait_submit"
5 | WaitCode = "wait_code"
6 | WaitRun = "wait_run"
7 | ServeLogs = "serve_logs"
8 | WaitLogsFinished = "wait_logs_finished"
9 | )
10 |
--------------------------------------------------------------------------------
/runner/internal/shim/backends/base.go:
--------------------------------------------------------------------------------
1 | package backends
2 |
3 | type Backend interface {
4 | // GetRealDeviceName returns the real device name for the given volume ID and virtual device name.
5 | GetRealDeviceName(volumeID, deviceName string) (string, error)
6 | }
7 |
--------------------------------------------------------------------------------
/scripts/build_frontend.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | script_path="$(realpath $0)"
4 | root_dir="$(dirname $(dirname $script_path))"
5 |
6 | cd $root_dir
7 | cd frontend
8 | npm install
9 | npm run build
10 | rm -rf ../src/dstack/_internal/server/statics
11 | cp -a build ../src/dstack/_internal/server/statics
12 |
--------------------------------------------------------------------------------
/scripts/docs/gen_openapi_reference.py:
--------------------------------------------------------------------------------
1 | """
2 | Generates OpenAPI schema from dstack server app.
3 | """
4 |
5 | import json
6 |
7 | import mkdocs_gen_files
8 |
9 | from dstack._internal.server.main import app
10 | from dstack._internal.settings import DSTACK_VERSION
11 |
12 | app.title = "OpenAPI Spec"
13 | app.servers = [
14 | {"url": "http://localhost:3000", "description": "Local server"},
15 | {"url": "https://sky.dstack.ai", "description": "Managed server"},
16 | ]
17 | app.version = DSTACK_VERSION or "0.0.0"
18 | with mkdocs_gen_files.open("docs/reference/api/rest/openapi.json", "w") as f:
19 | json.dump(app.openapi(), f)
20 |
--------------------------------------------------------------------------------
/scripts/packer/aws-vars-prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "ami_regions": "us-east-2,us-east-1,us-west-1,us-west-2,ca-central-1,eu-central-1,eu-west-1,eu-west-2,eu-west-3,eu-north-1,ap-southeast-1",
3 | "ami_groups": "all"
4 | }
5 |
--------------------------------------------------------------------------------
/scripts/packer/config.pkr.hcl:
--------------------------------------------------------------------------------
1 | packer {
2 | required_plugins {
3 | yandex = {
4 | version = ">= 1.1.2"
5 | source = "github.com/hashicorp/yandex"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/scripts/packer/locals.pkr.hcl:
--------------------------------------------------------------------------------
1 | locals {
2 | clean_image_version = regex_replace(var.image_version, "[^a-z0-9-]", "-")
3 | image_name = "${var.build_prefix}dstack-${local.clean_image_version}"
4 | docker_version = ""
5 | cuda_drivers_version = ""
6 | }
7 |
--------------------------------------------------------------------------------
/scripts/packer/provisioners/kernel/apt-upgrade.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Upgrade apt packages to latest versions.
4 | #
5 |
6 | set -e
7 |
8 | sudo apt-get update
9 | sudo DEBIAN_FRONTEND=noninteractive apt-get -o DPkg::Lock::Timeout=60 dist-upgrade -y -q
10 |
--------------------------------------------------------------------------------
/scripts/packer/provisioners/pull-docker-images.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | IMAGES="
6 | dstackai/${IMAGE_REPO}:py3.13-${IMAGE_VERSION}-cuda-12.1
7 | dstackai/${IMAGE_REPO}:py3.12-${IMAGE_VERSION}-cuda-12.1
8 | dstackai/${IMAGE_REPO}:py3.11-${IMAGE_VERSION}-cuda-12.1
9 | dstackai/${IMAGE_REPO}:py3.10-${IMAGE_VERSION}-cuda-12.1
10 | dstackai/${IMAGE_REPO}:py3.9-${IMAGE_VERSION}-cuda-12.1
11 | "
12 | echo "START pull image"
13 | for img in $IMAGES; do
14 | docker pull --platform linux/amd64 $img
15 | done
16 | echo "LIST installed images"
17 | docker image ls --all
18 | echo "END "
19 |
--------------------------------------------------------------------------------
/scripts/packer/provisioners/wait-for-dpkg-lock.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Wait until another process releases an apt/dpkg lock.
4 | #
5 | # This is a hack and it might not work for all cases. A better way of handling
6 | # apt races is the `-o DPkg::Lock::Timeout=X` option, but it does not work for
7 | # `apt-get update`.
8 | #
9 |
10 | while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do
11 | sleep 1
12 | done
13 |
--------------------------------------------------------------------------------
/scripts/packer/variables.pkr.hcl:
--------------------------------------------------------------------------------
1 | variable "build_prefix" {
2 | type = string
3 | default = ""
4 | }
5 |
6 | variable "image_version" {
7 | type = string
8 | }
9 |
--------------------------------------------------------------------------------
/scripts/packer/versions.json:
--------------------------------------------------------------------------------
1 | {
2 | "docker_version": "27.1.1",
3 | "cuda_drivers_version": "535"
4 | }
5 |
--------------------------------------------------------------------------------
/scripts/sqlite_to_psql.load:
--------------------------------------------------------------------------------
1 | LOAD DATABASE
2 | FROM {{SOURCE_PATH}} /* e.g. sqlite:///Users/me/.dstack/server/data/sqlite.db */
3 | INTO {{TARGET_PATH}} /* e.g. postgresql://postgres:postgres@localhost:5432/postgres */
4 |
5 | WITH preserve index names, data only
6 |
7 | EXCLUDING TABLE NAMES LIKE 'alembic_version'
8 |
9 | SET work_mem to '16MB', maintenance_work_mem to '512 MB';
10 |
--------------------------------------------------------------------------------
/src/dstack/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/cli/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/cli/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/cli/commands/completion.py:
--------------------------------------------------------------------------------
1 | import argcomplete
2 |
3 | from dstack._internal.cli.commands import BaseCommand
4 |
5 |
6 | class CompletionCommand(BaseCommand):
7 | NAME = "completion"
8 | DESCRIPTION = "Generate shell completion scripts"
9 |
10 | def _register(self):
11 | super()._register()
12 | self._parser.add_argument(
13 | "shell",
14 | help="The shell to generate the completion script for",
15 | choices=["bash", "zsh"],
16 | )
17 |
18 | def _command(self, args):
19 | super()._command(args)
20 | print(argcomplete.shellcode(["dstack"], shell=args.shell))
21 |
--------------------------------------------------------------------------------
/src/dstack/_internal/cli/commands/stats.py:
--------------------------------------------------------------------------------
1 | import argparse
2 |
3 | from dstack._internal.cli.commands.metrics import MetricsCommand
4 | from dstack._internal.utils.logging import get_logger
5 |
6 | logger = get_logger(__name__)
7 |
8 |
9 | class StatsCommand(MetricsCommand):
10 | NAME = "stats"
11 |
12 | def _command(self, args: argparse.Namespace):
13 | logger.warning("`dstack stats` is deprecated in favor of `dstack metrics`")
14 | super()._command(args)
15 |
--------------------------------------------------------------------------------
/src/dstack/_internal/cli/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/cli/services/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/cli/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/cli/utils/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/compat.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | IS_WINDOWS = os.name == "nt"
4 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/aws/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/aws/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/azure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/azure/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/base/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/base/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/base/backend.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from typing import ClassVar
3 |
4 | from dstack._internal.core.backends.base.compute import Compute
5 | from dstack._internal.core.models.backends.base import BackendType
6 |
7 |
8 | class Backend(ABC):
9 | TYPE: ClassVar[BackendType]
10 | # `COMPUTE_CLASS` is used to introspect compute features without initializing it.
11 | COMPUTE_CLASS: ClassVar[type[Compute]]
12 |
13 | @abstractmethod
14 | def compute(self) -> Compute:
15 | """
16 | Returns Compute instance.
17 | """
18 | pass
19 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/base/models.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 |
3 |
4 | def fill_data(values: dict, filename_field: str = "filename", data_field: str = "data") -> dict:
5 | if values.get(data_field) is not None:
6 | return values
7 | if (filename := values.get(filename_field)) is None:
8 | raise ValueError(f"Either `{filename_field}` or `{data_field}` must be specified")
9 | try:
10 | with open(Path(filename).expanduser()) as f:
11 | values[data_field] = f.read()
12 | except OSError:
13 | raise ValueError(f"No such file {filename}")
14 | return values
15 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/cudo/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/cudo/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/cudo/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.cudo.compute import CudoCompute
3 | from dstack._internal.core.backends.cudo.models import CudoConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class CudoBackend(Backend):
8 | TYPE = BackendType.CUDO
9 | COMPUTE_CLASS = CudoCompute
10 |
11 | def __init__(self, config: CudoConfig):
12 | self.config = config
13 | self._compute = CudoCompute(self.config)
14 |
15 | def compute(self) -> CudoCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/datacrunch/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/datacrunch/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/datacrunch/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.datacrunch.compute import DataCrunchCompute
3 | from dstack._internal.core.backends.datacrunch.models import DataCrunchConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class DataCrunchBackend(Backend):
8 | TYPE = BackendType.DATACRUNCH
9 | COMPUTE_CLASS = DataCrunchCompute
10 |
11 | def __init__(self, config: DataCrunchConfig):
12 | self.config = config
13 | self._compute = DataCrunchCompute(self.config)
14 |
15 | def compute(self) -> DataCrunchCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/dstack/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/dstack/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/gcp/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/gcp/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/gcp/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.gcp.compute import GCPCompute
3 | from dstack._internal.core.backends.gcp.models import GCPConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class GCPBackend(Backend):
8 | TYPE = BackendType.GCP
9 | COMPUTE_CLASS = GCPCompute
10 |
11 | def __init__(self, config: GCPConfig):
12 | self.config = config
13 | self._compute = GCPCompute(self.config)
14 | # self._check_credentials()
15 |
16 | def compute(self) -> GCPCompute:
17 | return self._compute
18 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/gcp/features/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/gcp/features/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/kubernetes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/kubernetes/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/kubernetes/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.kubernetes.compute import KubernetesCompute
3 | from dstack._internal.core.backends.kubernetes.models import KubernetesConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class KubernetesBackend(Backend):
8 | TYPE = BackendType.KUBERNETES
9 | COMPUTE_CLASS = KubernetesCompute
10 |
11 | def __init__(self, config: KubernetesConfig):
12 | self.config = config
13 | self._compute = KubernetesCompute(self.config)
14 |
15 | def compute(self) -> KubernetesCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/lambdalabs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/lambdalabs/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/lambdalabs/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.lambdalabs.compute import LambdaCompute
3 | from dstack._internal.core.backends.lambdalabs.models import LambdaConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class LambdaBackend(Backend):
8 | TYPE = BackendType.LAMBDA
9 | COMPUTE_CLASS = LambdaCompute
10 |
11 | def __init__(self, config: LambdaConfig):
12 | self.config = config
13 | self._compute = LambdaCompute(self.config)
14 | # self._check_credentials()
15 |
16 | def compute(self) -> LambdaCompute:
17 | return self._compute
18 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/local/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/local/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/local/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.local.compute import LocalCompute
3 | from dstack._internal.core.models.backends.base import BackendType
4 |
5 |
6 | class LocalBackend(Backend):
7 | TYPE = BackendType.LOCAL
8 | COMPUTE_CLASS = LocalCompute
9 |
10 | def __init__(self):
11 | self._compute = LocalCompute()
12 |
13 | def compute(self) -> LocalCompute:
14 | return self._compute
15 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/nebius/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/nebius/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/nebius/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.nebius.compute import NebiusCompute
3 | from dstack._internal.core.backends.nebius.models import NebiusConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class NebiusBackend(Backend):
8 | TYPE = BackendType.NEBIUS
9 | COMPUTE_CLASS = NebiusCompute
10 |
11 | def __init__(self, config: NebiusConfig):
12 | self.config = config
13 | self._compute = NebiusCompute(self.config)
14 |
15 | def compute(self) -> NebiusCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/oci/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/oci/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/oci/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.oci.compute import OCICompute
3 | from dstack._internal.core.backends.oci.models import OCIConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class OCIBackend(Backend):
8 | TYPE = BackendType.OCI
9 | COMPUTE_CLASS = OCICompute
10 |
11 | def __init__(self, config: OCIConfig):
12 | self.config = config
13 | self._compute = OCICompute(self.config)
14 |
15 | def compute(self) -> OCICompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/oci/exceptions.py:
--------------------------------------------------------------------------------
1 | from oci.exceptions import (
2 | BaseRequestException,
3 | ClientError,
4 | CompositeOperationError,
5 | MultipartUploadError,
6 | ServiceError,
7 | )
8 |
9 | any_oci_exception = (
10 | BaseRequestException,
11 | ClientError,
12 | CompositeOperationError,
13 | MultipartUploadError,
14 | ServiceError,
15 | )
16 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/remote/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/remote/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/runpod/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/runpod/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/runpod/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.runpod.compute import RunpodCompute
3 | from dstack._internal.core.backends.runpod.models import RunpodConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class RunpodBackend(Backend):
8 | TYPE = BackendType.RUNPOD
9 | COMPUTE_CLASS = RunpodCompute
10 |
11 | def __init__(self, config: RunpodConfig):
12 | self.config = config
13 | self._compute = RunpodCompute(self.config)
14 |
15 | def compute(self) -> RunpodCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/template/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/template/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/tensordock/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/tensordock/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/tensordock/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.tensordock.compute import TensorDockCompute
3 | from dstack._internal.core.backends.tensordock.models import TensorDockConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class TensorDockBackend(Backend):
8 | TYPE = BackendType.TENSORDOCK
9 | COMPUTE_CLASS = TensorDockCompute
10 |
11 | def __init__(self, config: TensorDockConfig):
12 | self.config = config
13 | self._compute = TensorDockCompute(self.config)
14 |
15 | def compute(self) -> TensorDockCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/vastai/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/vastai/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/vastai/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.vastai.compute import VastAICompute
3 | from dstack._internal.core.backends.vastai.models import VastAIConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class VastAIBackend(Backend):
8 | TYPE = BackendType.VASTAI
9 | COMPUTE_CLASS = VastAICompute
10 |
11 | def __init__(self, config: VastAIConfig):
12 | self.config = config
13 | self._compute = VastAICompute(self.config)
14 |
15 | def compute(self) -> VastAICompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/vultr/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/backends/vultr/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/backends/vultr/backend.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.backends.base.backend import Backend
2 | from dstack._internal.core.backends.vultr.compute import VultrCompute
3 | from dstack._internal.core.backends.vultr.models import VultrConfig
4 | from dstack._internal.core.models.backends.base import BackendType
5 |
6 |
7 | class VultrBackend(Backend):
8 | TYPE = BackendType.VULTR
9 | COMPUTE_CLASS = VultrCompute
10 |
11 | def __init__(self, config: VultrConfig):
12 | self.config = config
13 | self._compute = VultrCompute(self.config)
14 |
15 | def compute(self) -> VultrCompute:
16 | return self._compute
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/consts.py:
--------------------------------------------------------------------------------
1 | # shim (runs on the host) HTTP API port
2 | DSTACK_SHIM_HTTP_PORT = 10998
3 | # runner (runs inside a container) HTTP API port
4 | DSTACK_RUNNER_HTTP_PORT = 10999
5 | # ssh server (runs alongside the runner inside a container) listen port
6 | DSTACK_RUNNER_SSH_PORT = 10022
7 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/models/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/backends/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/core/models/backends/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/config.py:
--------------------------------------------------------------------------------
1 | from pydantic.fields import Field
2 | from typing_extensions import Annotated, List, Optional
3 |
4 | from dstack._internal.core.models.common import CoreModel
5 | from dstack._internal.core.models.repos.base import RepoType
6 |
7 |
8 | class ProjectConfig(CoreModel):
9 | name: str
10 | url: str
11 | token: str
12 | default: Optional[bool]
13 |
14 |
15 | class RepoConfig(CoreModel):
16 | path: str
17 | repo_id: str
18 | repo_type: RepoType
19 | ssh_key_path: str
20 |
21 |
22 | class GlobalConfig(CoreModel):
23 | projects: Annotated[List[ProjectConfig], Field(description="The list of projects")] = []
24 | repos: List[RepoConfig] = []
25 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/logs.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from enum import Enum
3 | from typing import List
4 |
5 | from dstack._internal.core.models.common import CoreModel
6 |
7 |
8 | class LogProducer(Enum):
9 | RUNNER = "runner"
10 | JOB = "job"
11 |
12 |
13 | class LogEventSource(str, Enum):
14 | STDOUT = "stdout"
15 | STDERR = "stderr"
16 |
17 |
18 | class LogEvent(CoreModel):
19 | timestamp: datetime
20 | log_source: LogEventSource
21 | message: str
22 |
23 |
24 | class JobSubmissionLogs(CoreModel):
25 | logs: List[LogEvent]
26 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/metrics.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from typing import Any, List
3 |
4 | from dstack._internal.core.models.common import CoreModel
5 |
6 |
7 | class Metric(CoreModel):
8 | name: str
9 | timestamps: List[datetime]
10 | values: List[Any]
11 |
12 |
13 | class JobMetrics(CoreModel):
14 | metrics: List[Metric]
15 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/secrets.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.core.models.common import CoreModel
2 |
3 |
4 | class Secret(CoreModel):
5 | name: str
6 | value: str
7 |
8 | def __str__(self) -> str:
9 | return f'Secret(name="{self.name}", value={"*" * len(self.value)})'
10 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/models/server.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | from dstack._internal.core.models.common import CoreModel
4 |
5 |
6 | class ServerInfo(CoreModel):
7 | server_version: Optional[str]
8 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/services/__init__.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | from dstack._internal.core.errors import ServerClientError
4 |
5 |
6 | def validate_dstack_resource_name(resource_name: str):
7 | if not is_valid_dstack_resource_name(resource_name):
8 | raise ServerClientError("Resource name should match regex '^[a-z][a-z0-9-]{1,40}$'")
9 |
10 |
11 | def is_valid_dstack_resource_name(resource_name: str) -> bool:
12 | return re.match("^[a-z][a-z0-9-]{1,40}$", resource_name) is not None
13 |
--------------------------------------------------------------------------------
/src/dstack/_internal/core/services/diff.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Dict
2 |
3 | from pydantic import BaseModel
4 |
5 |
6 | # TODO: calculate nested diffs
7 | def diff_models(old: BaseModel, new: BaseModel) -> Dict[str, Any]:
8 | if type(old) is not type(new):
9 | raise TypeError("Both instances must be of the same Pydantic model class.")
10 |
11 | changes = {}
12 | for field in old.__fields__:
13 | old_value = getattr(old, field)
14 | new_value = getattr(new, field)
15 | if old_value != new_value:
16 | changes[field] = {"old": old_value, "new": new_value}
17 |
18 | return changes
19 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | dstack-proxy is a component responsible for proxying ingress HTTP traffic to
3 | services and models hosted by dstack. It can also perform load balancing,
4 | collect service usage stats, obtain SSL certificates, etc.
5 |
6 | This component can run as a standalone web application on a gateway instance or
7 | as part of the dstack-server web application.
8 | """
9 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/gateway/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/const.py:
--------------------------------------------------------------------------------
1 | """Gateway-related constants useful in various dstack modules."""
2 |
3 | from pathlib import Path
4 |
5 | DSTACK_DIR_ON_GATEWAY = Path("/home/ubuntu/dstack")
6 | SERVER_CONNECTIONS_DIR_ON_GATEWAY = DSTACK_DIR_ON_GATEWAY / "server-connections"
7 | PROXY_PORT_ON_GATEWAY = 8000
8 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/main.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from dstack._internal.proxy.gateway.app import make_app
4 |
5 |
6 | def configure_logging(level: int = logging.INFO):
7 | formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
8 | handler = logging.StreamHandler()
9 | handler.setFormatter(formatter)
10 |
11 | logger = logging.getLogger("dstack")
12 | logger.setLevel(level)
13 | logger.addHandler(handler)
14 |
15 |
16 | configure_logging(logging.DEBUG)
17 | app = make_app()
18 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/models.py:
--------------------------------------------------------------------------------
1 | """Things stored in GatewayProxyRepo in addition to those from BaseProxyRepo."""
2 |
3 | from typing import Optional
4 |
5 | from pydantic import AnyHttpUrl
6 |
7 | from dstack._internal.proxy.lib.models import ImmutableModel
8 |
9 |
10 | class ModelEntrypoint(ImmutableModel):
11 | project_name: str
12 | domain: str
13 | https: bool
14 |
15 |
16 | class ACMESettings(ImmutableModel):
17 | server: Optional[AnyHttpUrl] = None
18 | eab_kid: Optional[str] = None
19 | eab_hmac_key: Optional[str] = None
20 |
21 |
22 | class GlobalProxyConfig(ImmutableModel):
23 | acme_settings: ACMESettings = ACMESettings()
24 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/repo/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/gateway/repo/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/resources/nginx/00-log-format.conf:
--------------------------------------------------------------------------------
1 | log_format dstack_stat '$time_iso8601 $host $status $request_time $dstack_replica_hit';
2 |
3 |
4 | # A hack to avoid this Nginx reload error when no services are registered:
5 | # nginx: [emerg] unknown "dstack_replica_hit" variable
6 | server {
7 | listen unix:/tmp/dstack-dummy-nginx.sock;
8 | server_name placeholder.local;
9 | deny all;
10 | set $dstack_replica_hit 0;
11 | }
12 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/gateway/routers/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/routers/auth.py:
--------------------------------------------------------------------------------
1 | from fastapi import APIRouter, Depends
2 |
3 | from dstack._internal.proxy.lib.deps import ProxyAuth
4 |
5 | router = APIRouter()
6 |
7 |
8 | @router.get("/{project_name}", dependencies=[Depends(ProxyAuth(auto_enforce=True))])
9 | async def get_auth():
10 | return {"status": "ok"}
11 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/schemas/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/gateway/schemas/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/schemas/common.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 |
3 |
4 | class OkResponse(BaseModel):
5 | status: str = "ok"
6 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/schemas/config.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | from pydantic import AnyHttpUrl, BaseModel
4 |
5 |
6 | class ConfigRequest(BaseModel):
7 | acme_server: Optional[AnyHttpUrl]
8 | acme_eab_kid: Optional[str]
9 | acme_eab_hmac_key: Optional[str]
10 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/schemas/stats.py:
--------------------------------------------------------------------------------
1 | from pydantic import BaseModel
2 |
3 |
4 | class Stat(BaseModel):
5 | requests: int
6 | request_time: float
7 |
8 |
9 | PerWindowStats = dict[int, Stat] # keys - length of time window in seconds
10 |
11 |
12 | class ServiceStats(BaseModel):
13 | project_name: str
14 | run_name: str
15 | stats: PerWindowStats
16 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/gateway/services/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/testing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/gateway/testing/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/gateway/testing/common.py:
--------------------------------------------------------------------------------
1 | from dataclasses import dataclass
2 | from typing import Union
3 | from unittest.mock import AsyncMock, MagicMock
4 |
5 | AnyMock = Union[MagicMock, AsyncMock]
6 |
7 |
8 | @dataclass
9 | class Mocks:
10 | reload_nginx: AnyMock
11 | run_certbot: AnyMock
12 | open_conn: AnyMock
13 | close_conn: AnyMock
14 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/auth.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class BaseProxyAuthProvider(ABC):
5 | @abstractmethod
6 | async def is_project_member(self, project_name: str, token: str) -> bool:
7 | pass
8 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/errors.py:
--------------------------------------------------------------------------------
1 | from fastapi import HTTPException, status
2 |
3 |
4 | class ProxyError(HTTPException):
5 | """Errors in dstack-proxy that are caused by and should be reported to the user"""
6 |
7 | def __init__(self, detail: str, code: int = status.HTTP_400_BAD_REQUEST) -> None:
8 | super().__init__(detail=detail, status_code=code)
9 |
10 |
11 | class UnexpectedProxyError(RuntimeError):
12 | """Internal errors in dstack-proxy that should have never happened"""
13 |
14 | pass
15 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/routers/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/schemas/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/schemas/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/services/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/services/model_proxy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/services/model_proxy/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/services/model_proxy/clients/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/services/model_proxy/clients/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/services/model_proxy/clients/base.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from typing import AsyncIterator
3 |
4 | from dstack._internal.proxy.lib.schemas.model_proxy import (
5 | ChatCompletionsChunk,
6 | ChatCompletionsRequest,
7 | ChatCompletionsResponse,
8 | )
9 |
10 |
11 | class ChatCompletionsClient(ABC):
12 | @abstractmethod
13 | async def generate(self, request: ChatCompletionsRequest) -> ChatCompletionsResponse:
14 | pass
15 |
16 | @abstractmethod
17 | async def stream(self, request: ChatCompletionsRequest) -> AsyncIterator[ChatCompletionsChunk]:
18 | yield
19 |
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/testing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/proxy/lib/testing/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/proxy/lib/testing/auth.py:
--------------------------------------------------------------------------------
1 | from typing import Container, Optional
2 |
3 | from dstack._internal.proxy.lib.auth import BaseProxyAuthProvider
4 |
5 |
6 | class ProxyTestAuthProvider(BaseProxyAuthProvider):
7 | def __init__(self, project_to_tokens: Optional[dict[str, Container[str]]] = None) -> None:
8 | self._project_to_tokens = project_to_tokens or {}
9 |
10 | async def is_project_member(self, project_name: str, token: str) -> bool:
11 | return token in self._project_to_tokens.get(project_name, set())
12 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/background/tasks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/background/tasks/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/main.py:
--------------------------------------------------------------------------------
1 | from dstack._internal.server.app import create_app, register_routes
2 |
3 | app = create_app()
4 | register_routes(app)
5 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/migrations/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/migrations/versions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/migrations/versions/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/migrations/versions/b88d55c2a07d_replace_instancestatus_ready.py:
--------------------------------------------------------------------------------
1 | """Replace InstanceStatus.READY with InstanceStatus.IDLE
2 |
3 | Revision ID: b88d55c2a07d
4 | Revises: ed0ca30e13bb
5 | Create Date: 2024-02-28 06:15:32.172109
6 |
7 | """
8 |
9 | # revision identifiers, used by Alembic.
10 | revision = "b88d55c2a07d"
11 | down_revision = "ed0ca30e13bb"
12 | branch_labels = None
13 | depends_on = None
14 |
15 |
16 | def upgrade() -> None:
17 | pass
18 |
19 |
20 | def downgrade() -> None:
21 | pass
22 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/routers/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/routers/server.py:
--------------------------------------------------------------------------------
1 | from fastapi import APIRouter
2 |
3 | from dstack._internal import settings
4 | from dstack._internal.core.models.server import ServerInfo
5 |
6 | router = APIRouter(
7 | prefix="/api/server",
8 | tags=["server"],
9 | )
10 |
11 |
12 | @router.post("/get_info")
13 | async def get_server_info() -> ServerInfo:
14 | return ServerInfo(
15 | server_version=settings.DSTACK_VERSION,
16 | )
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/schemas/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/backends.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | from dstack._internal.core.models.backends.base import BackendType
4 | from dstack._internal.core.models.common import CoreModel
5 |
6 |
7 | class DeleteBackendsRequest(CoreModel):
8 | backends_names: List[BackendType]
9 |
10 |
11 | class CreateBackendYAMLRequest(CoreModel):
12 | config_yaml: str
13 |
14 |
15 | class UpdateBackendYAMLRequest(CreateBackendYAMLRequest):
16 | pass
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/common.py:
--------------------------------------------------------------------------------
1 | from typing import Annotated
2 |
3 | from pydantic import Field
4 |
5 | from dstack._internal.core.models.common import CoreModel
6 |
7 |
8 | class RepoRequest(CoreModel):
9 | repo_id: Annotated[str, Field(description="A unique identifier of the repo")]
10 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/instances.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from typing import Optional
3 | from uuid import UUID
4 |
5 | from dstack._internal.core.models.common import CoreModel
6 |
7 |
8 | class ListInstancesRequest(CoreModel):
9 | project_names: Optional[list[str]] = None
10 | fleet_ids: Optional[list[UUID]] = None
11 | only_active: bool = False
12 | prev_created_at: Optional[datetime] = None
13 | prev_id: Optional[UUID] = None
14 | limit: int = 1000
15 | ascending: bool = False
16 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/logs.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | from typing import Optional
3 |
4 | from pydantic import UUID4, Field
5 |
6 | from dstack._internal.core.models.common import CoreModel
7 |
8 |
9 | class PollLogsRequest(CoreModel):
10 | run_name: str
11 | job_submission_id: UUID4
12 | start_time: Optional[datetime]
13 | end_time: Optional[datetime]
14 | descending: bool = False
15 | limit: int = Field(100, ge=0, le=1000)
16 | diagnose: bool = False
17 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/projects.py:
--------------------------------------------------------------------------------
1 | from typing import Annotated, List
2 |
3 | from pydantic import Field
4 |
5 | from dstack._internal.core.models.common import CoreModel
6 | from dstack._internal.core.models.users import ProjectRole
7 |
8 |
9 | class CreateProjectRequest(CoreModel):
10 | project_name: str
11 |
12 |
13 | class DeleteProjectsRequest(CoreModel):
14 | projects_names: List[str]
15 |
16 |
17 | class MemberSetting(CoreModel):
18 | username: Annotated[
19 | str,
20 | Field(description="The username or email of the user"),
21 | ]
22 | project_role: ProjectRole
23 |
24 |
25 | class SetProjectMembersRequest(CoreModel):
26 | members: List[MemberSetting]
27 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/secrets.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | from dstack._internal.core.models.secrets import Secret
4 | from dstack._internal.server.schemas.common import RepoRequest
5 |
6 |
7 | class ListSecretsRequest(RepoRequest):
8 | pass
9 |
10 |
11 | class GetSecretsRequest(RepoRequest):
12 | pass
13 |
14 |
15 | class AddSecretRequest(RepoRequest):
16 | secret: Secret
17 |
18 |
19 | class DeleteSecretsRequest(RepoRequest):
20 | secrets_names: List[str]
21 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/schemas/users.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional
2 |
3 | from dstack._internal.core.models.common import CoreModel
4 | from dstack._internal.core.models.users import GlobalRole
5 |
6 |
7 | class GetUserRequest(CoreModel):
8 | username: str
9 |
10 |
11 | class CreateUserRequest(CoreModel):
12 | username: str
13 | global_role: GlobalRole
14 | email: Optional[str]
15 | active: bool = True
16 |
17 |
18 | UpdateUserRequest = CreateUserRequest
19 |
20 |
21 | class RefreshTokenRequest(CoreModel):
22 | username: str
23 |
24 |
25 | class DeleteUsersRequest(CoreModel):
26 | users: List[str]
27 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/security/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/security/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/encryption/keys/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/encryption/keys/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/encryption/keys/base.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from typing import ClassVar
3 |
4 |
5 | class EncryptionKey(ABC):
6 | TYPE: ClassVar[str]
7 |
8 | @property
9 | @abstractmethod
10 | def name(self) -> str:
11 | pass
12 |
13 | @abstractmethod
14 | def encrypt(self, plaintext: str) -> str:
15 | pass
16 |
17 | @abstractmethod
18 | def decrypt(self, ciphertext: str) -> str:
19 | pass
20 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/jobs/configurators/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/jobs/configurators/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/jobs/configurators/extensions/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/jobs/configurators/extensions/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/jobs/configurators/extensions/base.py:
--------------------------------------------------------------------------------
1 | from typing import Callable, List
2 |
3 | CommandsExtension = Callable[[], List[str]]
4 |
5 |
6 | def get_required_commands(executables: List[str]) -> CommandsExtension:
7 | def wrapper() -> List[str]:
8 | commands = []
9 | for exe in executables:
10 | commands.append(
11 | f'((command -v {exe} > /dev/null) || (echo "{exe} is required" && exit 1))'
12 | )
13 | return commands
14 |
15 | return wrapper
16 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/logging.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | from dstack._internal.server.models import JobModel, RunModel
4 |
5 |
6 | def fmt(model: Union[RunModel, JobModel]) -> str:
7 | """Consistent string representation of a model for logging."""
8 | if isinstance(model, RunModel):
9 | return f"run({model.id.hex[:6]}){model.run_name}"
10 | if isinstance(model, JobModel):
11 | return f"job({model.id.hex[:6]}){model.job_name}"
12 | return str(model)
13 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/proxy/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Dependencies for dstack-proxy that allow it to run as part of dstack-server.
3 | """
4 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/proxy/auth.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy.ext.asyncio import AsyncSession
2 |
3 | from dstack._internal.proxy.lib.auth import BaseProxyAuthProvider
4 | from dstack._internal.server.security.permissions import is_project_member
5 |
6 |
7 | class ServerProxyAuthProvider(BaseProxyAuthProvider):
8 | def __init__(self, session: AsyncSession) -> None:
9 | self.session = session
10 |
11 | async def is_project_member(self, project_name: str, token: str) -> bool:
12 | return await is_project_member(self.session, project_name, token)
13 |
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/proxy/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/proxy/routers/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/proxy/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/proxy/services/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/services/runner/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/services/runner/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/testing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/testing/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/server/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/server/utils/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/_internal/utils/__init__.py
--------------------------------------------------------------------------------
/src/dstack/_internal/utils/env.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 |
4 | def get_bool(name: str, default: bool = False) -> bool:
5 | try:
6 | value = os.environ[name]
7 | except KeyError:
8 | return default
9 | value = value.lower()
10 | if value in ["0", "false", "off"]:
11 | return False
12 | if value in ["1", "true", "on"]:
13 | return True
14 | raise ValueError(f"Invalid bool value: {name}={value}")
15 |
--------------------------------------------------------------------------------
/src/dstack/_internal/utils/json_schema.py:
--------------------------------------------------------------------------------
1 | def add_extra_schema_types(schema_property: dict, extra_types: list[dict]):
2 | if "allOf" in schema_property:
3 | refs = [schema_property.pop("allOf")[0]]
4 | elif "anyOf" in schema_property:
5 | refs = schema_property.pop("anyOf")
6 | else:
7 | refs = [{"type": schema_property.pop("type")}]
8 | refs.extend(extra_types)
9 | schema_property["anyOf"] = refs
10 |
--------------------------------------------------------------------------------
/src/dstack/_internal/utils/logging.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 |
4 | def get_logger(name: str) -> logging.Logger:
5 | return logging.getLogger(name)
6 |
--------------------------------------------------------------------------------
/src/dstack/api/server/_group.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | import requests
4 | from typing_extensions import Protocol
5 |
6 |
7 | class APIRequest(Protocol):
8 | def __call__(
9 | self,
10 | path: str,
11 | body: Optional[str] = None,
12 | raise_for_status: bool = True,
13 | method: str = "POST",
14 | **kwargs,
15 | ) -> requests.Response:
16 | pass
17 |
18 |
19 | class APIClientGroup:
20 | def __init__(self, _request: APIRequest):
21 | self._request = _request
22 |
--------------------------------------------------------------------------------
/src/dstack/api/server/_logs.py:
--------------------------------------------------------------------------------
1 | from pydantic import parse_obj_as
2 |
3 | from dstack._internal.core.models.logs import JobSubmissionLogs
4 | from dstack._internal.server.schemas.logs import PollLogsRequest
5 | from dstack.api.server._group import APIClientGroup
6 |
7 |
8 | class LogsAPIClient(APIClientGroup):
9 | def poll(self, project_name: str, body: PollLogsRequest) -> JobSubmissionLogs:
10 | resp = self._request(f"/api/project/{project_name}/logs/poll", body=body.json())
11 | return parse_obj_as(JobSubmissionLogs.__response__, resp.json())
12 |
--------------------------------------------------------------------------------
/src/dstack/core/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/core/__init__.py
--------------------------------------------------------------------------------
/src/dstack/plugins/__init__.py:
--------------------------------------------------------------------------------
1 | # ruff: noqa: F401
2 | from dstack._internal.core.models.fleets import FleetSpec
3 | from dstack._internal.core.models.gateways import GatewaySpec
4 | from dstack._internal.core.models.runs import RunSpec
5 | from dstack._internal.core.models.volumes import VolumeSpec
6 | from dstack.plugins._base import ApplyPolicy, Plugin
7 | from dstack.plugins._models import ApplySpec
8 | from dstack.plugins._utils import get_plugin_logger
9 |
--------------------------------------------------------------------------------
/src/dstack/plugins/_models.py:
--------------------------------------------------------------------------------
1 | from typing import TypeVar
2 |
3 | from dstack._internal.core.models.fleets import FleetSpec
4 | from dstack._internal.core.models.gateways import GatewaySpec
5 | from dstack._internal.core.models.runs import RunSpec
6 | from dstack._internal.core.models.volumes import VolumeSpec
7 |
8 | ApplySpec = TypeVar("ApplySpec", RunSpec, FleetSpec, VolumeSpec, GatewaySpec)
9 |
--------------------------------------------------------------------------------
/src/dstack/plugins/_utils.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from dstack._internal.utils.logging import get_logger
4 |
5 |
6 | def get_plugin_logger(name: str) -> logging.Logger:
7 | """
8 | Use this function to set up loggers in plugins.
9 |
10 | Put at the top of the plugin modules:
11 |
12 | ```
13 | from dstack.plugins import get_plugin_logger
14 |
15 | logger = get_plugin_logger(__name__)
16 | ```
17 |
18 | """
19 | return get_logger(f"dstack.plugins.{name}")
20 |
--------------------------------------------------------------------------------
/src/dstack/plugins/builtin/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/dstack/plugins/builtin/__init__.py
--------------------------------------------------------------------------------
/src/dstack/plugins/builtin/rest_plugin/__init__.py:
--------------------------------------------------------------------------------
1 | # ruff: noqa: F401
2 | from dstack.plugins.builtin.rest_plugin._models import (
3 | FleetSpecRequest,
4 | FleetSpecResponse,
5 | GatewaySpecRequest,
6 | GatewaySpecResponse,
7 | RunSpecRequest,
8 | RunSpecResponse,
9 | SpecApplyRequest,
10 | SpecApplyResponse,
11 | VolumeSpecRequest,
12 | VolumeSpecResponse,
13 | )
14 | from dstack.plugins.builtin.rest_plugin._plugin import (
15 | PLUGIN_SERVICE_URI_ENV_VAR_NAME,
16 | CustomApplyPolicy,
17 | RESTPlugin,
18 | )
19 |
--------------------------------------------------------------------------------
/src/dstack/version.py:
--------------------------------------------------------------------------------
1 | __version__ = "0.0.0"
2 | __is_release__ = False
3 | base_image = "0.8"
4 |
--------------------------------------------------------------------------------
/src/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/cli/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/cli/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/cli/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/cli/commands/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/cli/commands/test_dstack.py:
--------------------------------------------------------------------------------
1 | from pytest import CaptureFixture
2 |
3 | from tests._internal.cli.common import run_dstack_cli
4 |
5 |
6 | class TestDstack:
7 | def test_prints_help_and_exists_with_0_exit_code(self, capsys: CaptureFixture):
8 | exit_code = run_dstack_cli([])
9 | assert exit_code == 0
10 | assert capsys.readouterr().out.startswith("Usage: dstack [-h] [-v] COMMAND ...")
11 |
--------------------------------------------------------------------------------
/src/tests/_internal/cli/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/cli/services/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/cli/services/configurators/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/cli/services/configurators/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/aws/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/aws/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/azure/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/azure/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/base/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/base/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/cudo/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/cudo/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/datacrunch/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/datacrunch/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/gcp/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/gcp/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/kubernetes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/kubernetes/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/lambdalabs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/lambdalabs/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/oci/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/oci/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/runpod/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/runpod/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/tensordock/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/tensordock/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/vastai/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/vastai/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/backends/vultr/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/backends/vultr/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/models/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/models/repos/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/models/repos/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/services/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/core/services/ssh/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/core/services/ssh/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/gateway/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/gateway/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/gateway/repo/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/gateway/repo/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/gateway/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/gateway/routers/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/gateway/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/gateway/services/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/lib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/lib/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/proxy/lib/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/proxy/lib/routers/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/background/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/background/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/background/tasks/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/background/tasks/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/routers/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/routers/test_server.py:
--------------------------------------------------------------------------------
1 | from unittest.mock import patch
2 |
3 | import pytest
4 | from httpx import AsyncClient
5 |
6 | from dstack._internal import settings
7 |
8 |
9 | class TestGetInfo:
10 | @pytest.mark.asyncio
11 | async def test_returns_40x_if_not_authenticated(self, test_db, client: AsyncClient):
12 | with patch.object(settings, "DSTACK_VERSION", "0.18.10"):
13 | response = await client.post("/api/server/get_info")
14 | assert response.status_code == 200
15 | assert response.json() == {"server_version": "0.18.10"}
16 |
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/backends/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/backends/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/encryption/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/encryption/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/encryption/keys/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/encryption/keys/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/jobs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/jobs/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/jobs/configurators/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/jobs/configurators/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/proxy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/proxy/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/proxy/routers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/proxy/routers/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/runner/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/runner/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/services/services/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/services/services/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/server/test_app.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from fastapi.testclient import TestClient
3 | from httpx import AsyncClient
4 | from sqlalchemy.ext.asyncio import AsyncSession
5 |
6 | from dstack._internal.server.main import app
7 |
8 | client = TestClient(app)
9 |
10 |
11 | class TestIndex:
12 | @pytest.mark.ui
13 | @pytest.mark.asyncio
14 | @pytest.mark.parametrize("test_db", ["sqlite", "postgres"], indirect=True)
15 | async def test_returns_html(self, test_db, session: AsyncSession, client: AsyncClient):
16 | response = await client.get("/")
17 | assert response.status_code == 200
18 | assert response.content.startswith(b'<')
19 |
--------------------------------------------------------------------------------
/src/tests/_internal/server/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/server/utils/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/utils/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/_internal/utils/__init__.py
--------------------------------------------------------------------------------
/src/tests/_internal/utils/test_event_loop.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | from dstack._internal.utils.event_loop import DaemonEventLoop
4 |
5 |
6 | def test_daemon_event_loop():
7 | q = asyncio.Queue()
8 |
9 | async def worker(i):
10 | await q.put(i)
11 |
12 | async def all_workers():
13 | await asyncio.gather(*[worker(i) for i in range(3)])
14 |
15 | loop = DaemonEventLoop()
16 | loop.await_(all_workers())
17 | assert q.qsize() == 3
18 | assert {loop.await_(q.get()) for _ in range(3)} == {0, 1, 2}
19 |
--------------------------------------------------------------------------------
/src/tests/_internal/utils/test_path.py:
--------------------------------------------------------------------------------
1 | from pathlib import PurePath
2 |
3 | import pytest
4 |
5 | from dstack._internal.utils.path import resolve_relative_path
6 |
7 |
8 | class TestResolveRelativePath:
9 | def test_abs_path(self):
10 | with pytest.raises(ValueError):
11 | resolve_relative_path("/tmp")
12 |
13 | def test_escape_repo(self):
14 | with pytest.raises(ValueError):
15 | resolve_relative_path("repo/../..")
16 |
17 | def test_normalize(self):
18 | assert resolve_relative_path("repo/./../repo2") == PurePath("repo2")
19 |
--------------------------------------------------------------------------------
/src/tests/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/api/__init__.py
--------------------------------------------------------------------------------
/src/tests/api/test_utils.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 |
3 | from dstack.api.utils import load_profile
4 |
5 |
6 | class TestLoadProfile:
7 | def test_loads_empty_profile_when_no_profiles(self, monkeypatch, tmpdir):
8 | test_dir = Path(tmpdir)
9 | repo_dir = test_dir / "repo"
10 | home_dir = test_dir / "home_dir"
11 | monkeypatch.setattr(Path, "home", lambda: home_dir)
12 | load_profile(repo_dir, profile_name=None)
13 |
--------------------------------------------------------------------------------
/src/tests/plugins/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dstackai/dstack/95650451e5156745cdefb01b59c5dbd356fbad7e/src/tests/plugins/__init__.py
--------------------------------------------------------------------------------