// Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once #include "devcontainer_global.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DevContainer { // Forward declarations struct BuildOptions; struct Mount; struct DevContainerCommon; struct NonComposeBase; struct DockerfileContainer; struct ImageContainer; struct ComposeContainer; struct Config; // Enums enum class ShutdownAction { None, StopContainer, StopCompose }; enum class WaitFor { InitializeCommand, OnCreateCommand, UpdateContentCommand, PostCreateCommand, PostStartCommand }; enum class UserEnvProbe { None, LoginShell, LoginInteractiveShell, InteractiveShell }; enum class OnAutoForward { Notify, OpenBrowser, OpenBrowserOnce, OpenPreview, Silent, Ignore }; enum class MountType { Bind, Volume }; // Command can be string, array, or object of commands using CommandMap = std::map>; using Command = std::variant; // Returns a string from the provided JSON value. Can modifiy the string to replace variables. using JsonStringToString = std::function; // Port attributes structure struct PortAttributes { OnAutoForward onAutoForward = OnAutoForward::Notify; bool elevateIfNeeded = false; QString label = "Application"; bool requireLocalPort = false; std::optional protocol; static Utils::Result fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); static void visitStrings(std::function visitor); }; // GPU requirements structure struct DEVCONTAINER_EXPORT GpuRequirements { struct GpuDetailedRequirements { std::optional cores; std::optional memory; static GpuDetailedRequirements fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); }; std::variant requirements; static GpuRequirements fromJson( const QJsonValue &json, const JsonStringToString &jsonStringToString); }; // Host hardware requirements structure struct DEVCONTAINER_EXPORT HostRequirements { std::optional cpus; std::optional memory; std::optional storage; std::optional gpu; static HostRequirements fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); }; // Secret metadata structure struct DEVCONTAINER_EXPORT SecretMetadata { std::optional description; std::optional documentationUrl; static SecretMetadata fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); }; // Mount structure struct DEVCONTAINER_EXPORT Mount { MountType type; std::optional source; QString target; static Utils::Result fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); static Utils::Result> fromJsonVariant( const QJsonValue &value, const JsonStringToString &jsonStringToString); }; // Build options structure struct DEVCONTAINER_EXPORT BuildOptions { std::optional target; std::map args; std::optional> cacheFrom; QStringList options; static BuildOptions fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); }; // Non-compose base structure struct DEVCONTAINER_EXPORT NonComposeBase { std::optional>>> appPort; std::optional runArgs; ShutdownAction shutdownAction = ShutdownAction::StopContainer; bool overrideCommand = true; QString workspaceFolder = "/devcontainer/workspace"; std::optional workspaceMount; Utils::Result<> fromJson(const QJsonObject &json, const JsonStringToString &jsonStringToString); }; // Dockerfile container structure struct DEVCONTAINER_EXPORT DockerfileContainer : NonComposeBase { QString dockerfile; //! Path that the Docker build command should be run from. Relative to the devcontainer.json file. QString context = "."; std::optional buildOptions; static Utils::Result fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); static bool isDockerfileContainer(const QJsonObject &json); }; // Image container structure struct DEVCONTAINER_EXPORT ImageContainer : NonComposeBase { QString image; static Utils::Result fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); static bool isImageContainer(const QJsonObject &json); }; // Compose container structure struct DEVCONTAINER_EXPORT ComposeContainer { std::variant dockerComposeFile; QString service; std::optional runServices; QString workspaceFolder = "/devcontainer/workspace"; ShutdownAction shutdownAction = ShutdownAction::StopCompose; bool overrideCommand = true; static Utils::Result fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); static bool isComposeContainer(const QJsonObject &json); }; // Dev container common structure struct DEVCONTAINER_EXPORT DevContainerCommon { std::optional schema; std::optional name; std::map features; std::optional overrideFeatureInstallOrder; std::map secrets; std::optional>> forwardPorts; std::map portsAttributes; std::optional otherPortsAttributes; std::optional updateRemoteUserUID; std::map containerEnv; std::optional containerUser; std::vector> mounts; std::optional init; std::optional privileged; std::optional capAdd; std::optional securityOpt; std::map> remoteEnv; std::optional remoteUser; std::optional initializeCommand; std::optional onCreateCommand; std::optional updateContentCommand; std::optional postCreateCommand; std::optional postStartCommand; std::optional postAttachCommand; std::optional waitFor; UserEnvProbe userEnvProbe = UserEnvProbe::LoginInteractiveShell; std::optional hostRequirements; QJsonObject customizations; QJsonObject additionalProperties; static Utils::Result fromJson( const QJsonObject &json, const JsonStringToString &jsonStringToString); static void visitStrings(std::function visitor); }; // Complete DevContainer Configuration struct DEVCONTAINER_EXPORT Config { DevContainerCommon common; std::optional> containerConfig; static Utils::FilePath workspaceFolder(const Config &config); static Utils::Result fromJson( const QJsonObject &json, JsonStringToString jsonStringToString); static Utils::Result fromJson( const QByteArray &data, const JsonStringToString &jsonStringToString); }; //! Returns a QJsonValue for the specified path. e.g.: customization(config, "qt-creator/device/mount-cmd-bridge") DEVCONTAINER_EXPORT QJsonValue customization(const Config &config, const QString &path); // QDebug stream operators for all DevContainer structures DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::OnAutoForward &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::ShutdownAction &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::WaitFor &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::UserEnvProbe &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::MountType &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::PortAttributes &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::GpuRequirements::GpuDetailedRequirements &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::GpuRequirements &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::HostRequirements &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::SecretMetadata &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::Mount &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const std::variant &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::BuildOptions &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::DockerfileContainer &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::ImageContainer &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::ComposeContainer &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::NonComposeBase &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::Command &cmd); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::DevContainerCommon &value); DEVCONTAINER_EXPORT QDebug operator<<(QDebug debug, const DevContainer::Config &value); } // namespace DevContainer