package devstar_devcontainer import ( "code.gitea.io/gitea/modules/json" ) // DevContainerJSON 用于反序列化仓库中的 DevContainer 配置信息 // `.devcontainer/devcontainer.json` or `.devcontainer.json` in project root. // ref: https://containers.dev/implementors/json_reference type DevContainerJSON struct { /*********************************************************************************** * BEGIN General devcontainer.json properties * https://containers.dev/implementors/json_reference/#general-properties ***********************************************************************************/ // Name A name for the dev container displayed in the UI. Name string `json:"name"` // ForwardPorts An array of port numbers or "host:port" values (e.g. [3000, "db:5432"]) // that should always be forwarded from inside the primary container to the local machine (including on the web). ForwardPorts []interface{} `json:"forwardPorts,omitempty"` // PortsAttributes Object that maps a port number, "host:port" value, range, or regular expression // to a set of default options. PortsAttributes map[string]PortAttributeType `json:"portsAttributes,omitempty"` // OtherPortsAttributes Default options for ports, port ranges, and hosts that aren’t configured using portsAttributes. OtherPortsAttributes *PortAttributeType `json:"otherPortsAttributes,omitempty"` // ContainerEnv A set of name-value pairs that sets or overrides environment variables for the container. ContainerEnv map[string]string `json:"containerEnv,omitempty"` // RemoteEnv A set of name-value pairs that sets or overrides environment variables // for the devcontainer.json supporting service / tool (or sub-processes like terminals) // but not the container as a whole. RemoteEnv map[string]interface{} `json:"remoteEnv,omitempty"` // RemoteUser Overrides the user for all operations run as inside the container. // Default to either `root` or the last USER instruction in the related Dockerfile used to create the image. RemoteUser *string `json:"remoteUser,omitempty"` // ContainerUser // Defaults to either root or the last USER instruction in the related Dockerfile used to create the image. ContainerUser *string `json:"containerUser,omitempty"` // UpdateRemoteUserUID On Linux, if containerUser or remoteUser is specified, // the user’s UID/GID will be updated to match the local user’s UID/GID to avoid permission problems with bind mounts. UpdateRemoteUserUID bool `json:"updateRemoteUserUID"` // UserEnvProbe Indicates the type of shell to use to “probe” for user environment variables // to include in devcontainer.json supporting services’ / tools’ processes: // none, interactiveShell, loginShell, or loginInteractiveShell (default). UserEnvProbe UserEnvProbeType `json:"userEnvProbe"` // OverrideCommand Tells devcontainer.json supporting services / tools // whether they should run /bin/sh -c "while sleep 1000; do :; done" when starting the container // instead of the container’s default command (since the container can shut down if the default command fails). // Set to false if the default command must run for the container to function properly. // Default to `true` for when using an image Dockerfile and `false` when referencing a Docker Compose file. OverrideCommand bool `json:"overrideCommand,omitempty"` // ShutdownAction Indicates whether devcontainer.json supporting tools should stop the containers // when the related tool window is closed / shut down. // Values are `none`, `stopContainer`(default for image/Dockerfile), and `stopCompose`(default for Docker Compose). ShutdownAction ShutdownActionType `json:"shutdownAction,omitempty"` // Init Defaults to false. // Cross-orchestrator way to indicate whether the tini init process should be used to help deal with zombie processes. Init bool `json:"init"` // Privileged Defaults to false. Cross-orchestrator way to cause the container to run in privileged mode (--privileged). // Required for things like Docker-in-Docker, but has security implications particularly when running directly on Linux. Privileged bool `json:"privileged"` // CapAdd Defaults to []. Cross-orchestrator way to add capabilities typically disabled for a container. // Most often used to add the *ptrace* capability required to debug languages like C++, Go, and Rust. CapAdd []string `json:"capAdd"` // SecurityOpt Defaults to []. Cross-orchestrator way to set container security options. SecurityOpt []string `json:"securityOpt"` // Mounts Cross-orchestrator way to add additional mounts to a container. // Each value is a string that accepts the same values as the Docker CLI --mount flag. // Environment and pre-defined variables may be referenced in the value. Mounts []interface{} `json:"mounts,omitempty"` // Features An object of Dev Container Feature IDs and related options to be added into your primary container. // The specific options that are available varies by feature, so see its documentation for additional details. Features map[string]interface{} `json:"features,omitempty"` // OverrideFeatureInstallOrder allows you to override the Feature install order when needed. OverrideFeatureInstallOrder []interface{} `json:"overrideFeatureInstallOrder,omitempty"` // Customizations Product specific properties, defined in https://containers.dev/supporting#visual-studio-code Customizations map[string]interface{} `json:"customizations,omitempty"` /*********************************************************************************** * END General devcontainer.json properties * https://containers.dev/implementors/json_reference/#general-properties ***********************************************************************************/ /*********************************************************************************** * BEGIN Scenario specific properties * https://containers.dev/implementors/json_reference/#scenario-specific ***********************************************************************************/ // Image Required when using an image. The name of an image in a container registry // that devcontainer.json supporting services/tools should use to create the DevContainer. Image string `json:"image"` // Build Docker build specific properties Build *DockerBuildType `json:"build,omitempty"` // AppPort accepts a port or array of ports that should be published locally when the container is running. AppPort *interface{} `json:"appPort"` // WorkspaceMount Requires workspaceFolder be set as well. // Overrides the default local mount point for the workspace when the container is created. // Supports the same values as the Docker CLI --mount flag. // Environment and pre-defined variables may be referenced in the value. WorkspaceMount *string `json:"workspaceMount,omitempty"` // WorkspaceFolder Requires workspaceMount be set. Sets the default path that devcontainer.json supporting services / tools should open when connecting to the container. Defaults to the automatic source code mount location. WorkspaceFolder *string `json:"workspaceFolder,omitempty"` // RunArgs An array of Docker CLI arguments that should be used when running the container. RunArgs []string `json:"runArgs,omitempty"` // DockerComposeFile Required when using Docker Compose. // Path or an ordered list of paths to Docker Compose files relative to the devcontainer.json file. DockerComposeFile *interface{} `json:"dockerComposeFile,omitempty"` // Service Required when using Docker Compose. // The name of the service devcontainer.json supporting services / tools should connect to once running. Service *string `json:"service,omitempty"` // RunServices An array of services in your Docker Compose configuration // that should be started by devcontainer.json supporting services / tools. // These will also be stopped when you disconnect unless "shutdownAction" is "none". Defaults to all services. RunServices []interface{} `json:"runServices,omitempty"` // WorkspaceFolder Sets the default path that devcontainer.json // supporting services/tools should open when connecting to the container // (which is often the path to a volume mount where the source code can be found in the container). // Defaults to "/". //WorkspaceFolder string `json:"workspaceFolder"` /*********************************************************************************** * END Scenario specific properties * https://containers.dev/implementors/json_reference/#scenario-specific ***********************************************************************************/ /*********************************************************************************** * BEGIN Tool-specific properties * https://containers.dev/implementors/json_reference/#tool-specific ***********************************************************************************/ // InitializedCommand A command string or list of command arguments to run on the host machine during initialization, // including during container creation and on subsequent starts. // The command may run more than once during a given session. // ⚠ The command is run wherever the source code is located on the host. For cloud services, this is in the cloud. // Note that the array syntax will execute the command without a shell. // You can learn more about formatting string vs array vs object properties. InitializeCommand *interface{} `json:"initializeCommand,omitempty"` // OnCreateCommand is the first of three (along with updateContentCommand and postCreateCommand) // that finalizes container setup when a dev container is created. // It and subsequent commands execute inside the container immediately after it has started for the first time. // Cloud services can use this command when caching or prebuilding a container. // This means that it will not typically have access to user-scoped assets or secrets. // Note that the array syntax will execute the command without a shell. OnCreateCommand interface{} `json:"onCreateCommand"` UpdateContentCommand interface{} `json:"updateContentCommand "` PostCreateCommand interface{} `json:"postCreateCommand"` PostStartCommand interface{} `json:"postStartCommand"` PostAttachCommand interface{} `json:"postAttachCommand"` WaitFor DevContainerConfigCommandType `json:"waitFor,omitempty"` HostRequirements *HostRequirementsType `json:"hostRequirements,omitempty"` /*********************************************************************************** * END Tool-specific properties * https://containers.dev/implementors/json_reference/#tool-specific ***********************************************************************************/ } type DevContainerConfigCommandType string const ( InitializeCommand DevContainerConfigCommandType = "initializeCommand" OnCreateCommand DevContainerConfigCommandType = "onCreateCommand" UpdateContentCommand DevContainerConfigCommandType = "updateContentCommand" PostCreateCommand DevContainerConfigCommandType = "postCreateCommand" PostStartCommand DevContainerConfigCommandType = "postStartCommand" PostAttachCommand DevContainerConfigCommandType = "postAttachCommand" ) type ShutdownActionType string const ( NoneShutdownActionType ShutdownActionType = "none" StopContainerShutdownActionType ShutdownActionType = "stopContainer" StopComposeShutdownActionType ShutdownActionType = "stopCompose" ) type UserEnvProbeType string const ( NoneUserEnvProbeType UserEnvProbeType = "none" LoginShellUserEnvProbeType UserEnvProbeType = "loginShell" InteractiveShellUserEnvProbeType UserEnvProbeType = "interactiveShell" LoginInteractiveShellUserEnvProbeType UserEnvProbeType = "loginInteractiveShell" ) // DockerBuildType Docker build specific properties type DockerBuildType struct { // Dockerfile Required when using a Dockerfile. // The location of a Dockerfile that defines the contents of the container. // The path is relative to the devcontainer.json file. Dockerfile string `json:"dockerfile,omitempty"` // Path that the Docker build should be run from relative to devcontainer.json. Context string `json:"context"` // Args A set of name-value pairs containing Docker image build arguments that should be passed when building a Dockerfile. // Environment and pre-defined variables may be referenced in the values. Args map[string]string `json:"args,omitempty"` // Options An array of Docker image build options that passed to the build command when building a Dockerfile. Options []string `json:"options"` // Target A string that specifies a Docker image build target that should be passed when building a Dockerfile. Target string `json:"target,omitempty"` // CacheFrom A string or array of strings that specify one or more images to use as caches when building the image. // Cached image identifiers are passed to the docker build command with --cache-from. CacheFrom interface{} `json:"cacheFrom"` } // ProtocolType Enum values for Protocol type ProtocolType string const ( ProtocolTCP ProtocolType = "tcp" ProtocolHTTP ProtocolType = "http" ProtocolHTTPS ProtocolType = "https" ) // OnAutoForwardType Enum for OnAutoForward type OnAutoForwardType string const ( OnAutoForwardNotify OnAutoForwardType = "notify" OnAutoForwardOpenBrowser OnAutoForwardType = "openBrowser" OnAutoForwardOpenBrowserOnce OnAutoForwardType = "openBrowserOnce" OnAutoForwardOpenPreview OnAutoForwardType = "openPreview" OnAutoForwardSilent OnAutoForwardType = "silent" OnAutoForwardIgnore OnAutoForwardType = "ignore" ) // PortAttributeType // // ref: https://containers.dev/implementors/json_reference/#port-attributes type PortAttributeType struct { Label string `json:"label,omitempty"` Protocol ProtocolType `json:"protocol,omitempty"` OnAutoForward OnAutoForwardType `json:"onAutoForward,omitempty"` RequireLocalPort bool `json:"requireLocalPort,omitempty"` ElevateIfNeeded bool `json:"elevateIfNeeded,omitempty"` } type HostGPURequirements struct { cores *uint64 `json:"cores"` memory *string `json:"memory"` } type HostRequirementsType struct { CPUs int `json:"cpus,omitempty"` Memory string `json:"memory,omitempty"` Storage string `json:"storage,omitempty"` GPU interface{} `json:"gpu,omitempty"` // Could be bool, 'optional', or HostGPURequirements } // Unmarshal 反序列化JSON,返回带有默认值的 DevContainerJSON func Unmarshal(devcontainerJSONContent string) (*DevContainerJSON, error) { // 1. 根据官方文档配置默认值 devcontainerJSON := &DevContainerJSON{ ForwardPorts: []interface{}{}, UpdateRemoteUserUID: true, UserEnvProbe: LoginInteractiveShellUserEnvProbeType, Init: false, Privileged: false, CapAdd: []string{}, SecurityOpt: []string{}, Build: &DockerBuildType{ Context: ".", Options: []string{}, }, WaitFor: UpdateContentCommand, OtherPortsAttributes: &PortAttributeType{ OnAutoForward: OnAutoForwardNotify, }, } // 2. JSON 反序列化 err := json.Unmarshal([]byte(devcontainerJSONContent), devcontainerJSON) if err != nil { return nil, err } // 3. 对于配置的端口的缺省字段进行设置 for _, portAttribute := range devcontainerJSON.PortsAttributes { if len(portAttribute.OnAutoForward) == 0 { portAttribute.OnAutoForward = OnAutoForwardNotify } } // 4. 返回 return devcontainerJSON, err }