Documentation
¶
Overview ¶
Package projects provides utilities for managing Docker Compose projects and their metadata.
Index ¶
- Constants
- Variables
- func ApplyLenientLoaderOptions(ctx context.Context, opts *loader.Options, composeFile string)
- func ApplyProjectFileChanges(projectPath string, changes []project.ProjectFileChange, ...) error
- func ApplyProjectFileDrafts(projectPath string, drafts []project.ProjectFileDraft, ...) error
- func BuildAdditiveOverrideEnvContent(gitContent, localContent string) (string, error)
- func BuildArgsFromCompose(args map[string]*string) map[string]string
- func BuildEffectiveEnvContent(gitContent, overrideContent string) (string, error)
- func BuildImagePullPlan(services composetypes.Services) map[string]ImagePullMode
- func BuildImageRefsFromComposeProject(project *composetypes.Project) []string
- func BuildLocalImageTag(projectID, projectName, serviceName string) string
- func BuildOverrideEnvContent(gitContent, effectiveContent string) (string, error)
- func BuildPlatformsFromCompose(svc composetypes.ServiceConfig) []string
- func CleanupRemovedFiles(projectsRoot, projectPath string, oldFiles, newFiles []string) error
- func ComposeContentProjectName(composeContent string) string
- func ComposeDown(ctx context.Context, proj *types.Project, removeVolumes bool) error
- func ComposeFileCandidates() []string
- func ComposeLogs(ctx context.Context, projectName string, out io.Writer, follow bool, ...) error
- func ComposeOverrideFileCandidates() []string
- func ComposePs(ctx context.Context, proj *types.Project, services []string, all bool) ([]api.ContainerSummary, error)
- func ComposeRestart(ctx context.Context, proj *types.Project, services []string) error
- func ComposeStop(ctx context.Context, proj *types.Project, services []string) error
- func ComposeUp(ctx context.Context, proj *types.Project, services []string, ...) error
- func CopyDirectoryContents(srcDir, destDir string) error
- func CopyDirectoryContentsTolerant(srcDir, destDir string) (skipped []string, err error)
- func CreateExactDir(projectsRoot, basePath, name string, perm os.FileMode) (path, folderName string, err error)
- func CreateUniqueDir(projectsRoot, basePath, name string, perm os.FileMode) (path, folderName string, err error)
- func DefaultSwarmStackEnvTemplate() string
- func DefaultSwarmStackTemplate() string
- func DetectComposeFile(dir string) (string, error)
- func DetectComposeOverrideFile(dir string) string
- func DirectorySyncContentsChanged(projectPath string, syncFiles []SyncFile, oldSyncedFiles []string, ...) (bool, error)
- func EnsureDefaultTemplates(ctx context.Context, configuredTemplatesDir string) error
- func EnsureEnvFile(projectsRoot, dirPath string) error
- func EnsureTemplateDir(ctx context.Context, templatesDir, base string) (dir, composePath, envPath string, err error)
- func GetHostPathForContainerPath(ctx context.Context, dockerCli *client.Client, containerPath string) (string, error)
- func GetProjectsDirectory(ctx context.Context, projectsDir string) (string, error)
- func GetTemplatesDirectory(ctx context.Context, templatesDir string) (string, error)
- func HasComposeRootKeysInFile(path string) (bool, error)
- func ImageRefsFromComposeConfigs(services []composetypes.ServiceConfig) []string
- func ImageRefsFromComposeServices(services composetypes.Services) []string
- func ImageRefsFromRuntimeServices(services []projecttypes.RuntimeService) []string
- func ImportedComposeDescription(dir string) string
- func IsAlwaysPullPolicy(policy string) bool
- func IsBinaryProjectFileContent(content []byte) bool
- func IsFilesystemSnapshotDirName(name string) bool
- func IsGitOpsScratchDirName(name string) bool
- func IsInternalScratchDirName(name string) bool
- func IsProjectDirectoryEntry(entry os.DirEntry, path string, followSymlinks bool) bool
- func IsProjectDirectoryPath(path string, followSymlinks bool) (bool, error)
- func IsProjectFile(filename string) bool
- func IsSafeSubdirectory(baseDir, subdir string) bool
- func IsWindowsDrivePath(path string) bool
- func LabelsFromCompose(labels composetypes.Labels) map[string]string
- func ListGlobalComposeContainers(ctx context.Context) ([]container.Summary, error)
- func LoadComposeProject(ctx context.Context, composeFile, projectName, projectsDirectory string, ...) (*composetypes.Project, error)
- func LoadComposeProjectFromDir(ctx context.Context, dir, projectName, projectsDirectory string, ...) (*composetypes.Project, string, error)
- func LoadComposeProjectLenient(ctx context.Context, composeFile, projectName, projectsDirectory string, ...) (*composetypes.Project, error)
- func MarshalImageRefsJSON(refs []string) string
- func MergeBuildTags(primaryImage string, composeTags []string) []string
- func MirrorDirectoryContentsPreserving(srcDir, destDir string, preserve []string) error
- func NormalizeDeployPullPolicy(policy string) string
- func NormalizeProjectName(name string) string
- func NormalizeProjectRelativePath(input string) (string, error)
- func NormalizePullPolicy(policy string) string
- func ParseEnvContent(content string) []env.Variable
- func ParseImageRefsJSON(raw string) []string
- func PathContainsSnapshotDirectory(relPath string) bool
- func ProtectedProjectFilePaths(composeFileName string) map[string]bool
- func ReadComposeOverrideContent(dir string) string
- func ReadFolderComposeTemplate(baseDir, folder string) (string, *string, string, bool, error)
- func ReadProjectDirectoryFiles(projectPath string, shownFiles map[string]bool, maxDepth int, ...) ([]project.IncludeFile, error)
- func ReadProjectFileTree(projectPath string, maxDepth int, skipDirectories, composeFileName string, ...) ([]project.ProjectFile, string, bool, error)
- func ReadProjectFiles(projectPath, composePath string) (composeContent, envContent string, err error)
- func RemoveProjectFile(projectsRoot, dirPath, fileName string) error
- func RemoveStaleComposeFiles(projectPath, composeFileName string, syncedFiles []string) error
- func ResolveBuildContext(workingDir string, svc composetypes.ServiceConfig, serviceName string) (string, error)
- func ResolveComposeOverride(exists func(name string) bool, read func(name string) (string, error)) (fileName string, content string, found bool, err error)
- func ResolveConfiguredContainerDirectory(configuredPath, defaultPath string) string
- func ResolveDirectoryIdentityInternal(path string) (string, error)
- func ResolveDockerfilePath(svc composetypes.ServiceConfig) string
- func ResolveHostPath(mounts []HostMount, containerPath string) (string, bool)
- func ResolveRelativeProjectPaths(project *composetypes.Project, workdir string)
- func RestoreProjectUpdateBackup(projectDir string, backup *ProjectUpdateBackup) error
- func RollbackRenamedProjectDirectory(oldPath, newPath string) (pathsMissing bool, err error)
- func SanitizeImageComponent(value string) string
- func SanitizeProjectName(name string) string
- func SaveOrUpdateProjectFiles(projectsRoot, projectPath, composeContent string, envContent *string) error
- func Slugify(in string) string
- func UlimitsFromCompose(ulimits map[string]*composetypes.UlimitsConfig) map[string]string
- func ValidateIncludePathForWrite(projectDir, includePath string) (string, error)
- func ValidateProjectFileName(name string) (string, error)
- func WithTransientValidationEnvFile(projectPath string, effectiveEnvContent *string, run func() error) (err error)
- func WriteComposeFile(projectsRoot, dirPath, content string) error
- func WriteComposeOverrideFile(projectsRoot, dir string, content *string, fileName string) error
- func WriteEnvFile(projectsRoot, dirPath, content string) error
- func WriteFileWithPerm(filePath, content string, perm os.FileMode) error
- func WriteIncludeFile(projectDir, includePath, content string) error
- func WriteManagedEnvFile(projectsDirectory, projectPath, fileName string, unreadable bool, ...) error
- func WriteProjectFile(projectsRoot, dirPath, fileName, content string) error
- func WriteProjectFiles(projectsRoot, dirPath, composeContent string, envContent *string) error
- func WriteSyncedDirectory(projectsRoot, projectPath string, files []SyncFile) ([]string, error)
- func WriteTemplateFile(filePath, content string) error
- func WriteTemplateFiles(composePath, envPath, composeContent, envContent string) (*string, error)
- type ArcaneComposeMetadata
- type Client
- type DeployImageDecision
- type DiscoveredProjectDir
- type EnvLoader
- type EnvMap
- type HostMount
- type IconSet
- type ImagePullMode
- type IncludeFile
- type MissingIncludeStubLoader
- type PathMapper
- type ProgressWriterKey
- type ProjectEnvMode
- type ProjectEnvState
- type ProjectFileApplyOptions
- type ProjectUpdateBackup
- type ProjectUpdateBackupScope
- type SyncFile
Constants ¶
const ( // ArcaneIconLabel is the full reverse-DNS label key for fallback service-level icons. ArcaneIconLabel = "com.getarcaneapp.arcane.icon" // ArcaneIconLightLabel is the full reverse-DNS label key for light service-level icons. ArcaneIconLightLabel = "com.getarcaneapp.arcane.icon-light" // ArcaneIconDarkLabel is the full reverse-DNS label key for dark service-level icons. ArcaneIconDarkLabel = "com.getarcaneapp.arcane.icon-dark" )
const ( GlobalEnvFileName = ".env.global" EffectiveEnvFileName = ".env" GitSourceEnvFileName = ".env.git" OverrideEnvFileName = "project.env" )
const ( MaxManagedProjectFileBytes = 1024 * 1024 ProjectFileTreeUseScanDepth = -1 // DefaultProjectFileTreeMaxEntries bounds the file-tree walk so a project // with a huge data directory cannot stall the details load. Not a user // setting; pass 0 to use it. DefaultProjectFileTreeMaxEntries = 2000 )
const ArcaneTrashPrefix = ".arcane-trash-"
ArcaneTrashPrefix is the prefix Arcane uses when quarantining (soft-deleting) a project's files, e.g. ".arcane-trash-<name>-<unix>". Trash directories are Arcane-managed and must never be discovered or imported as user projects.
const DefaultComposeFileName = "compose.yaml"
DefaultComposeFileName is the compose filename Arcane writes when a project has no existing compose file.
const DefaultComposeOverrideFileName = "compose.override.yaml"
DefaultComposeOverrideFileName is the override filename Arcane writes when a project gains an override but has none on disk. It is deliberately composeOverrideFileCandidates[1] ("compose.override.yaml"), NOT [0] ("compose.override.yml"), so the default override extension matches Arcane's ".yaml" base default (DefaultComposeFileName = "compose.yaml"). Do not "fix" this to [0]: `docker compose` has no preference between the two, and keeping ".yaml" avoids a mismatched base/override extension pair.
Variables ¶
var ( ErrProjectFileRevisionConflict = errors.New("project file tree changed; refresh the project and try again") ErrProjectFileOutsideProjectDirectory = errors.New("path is outside project directory") ErrProjectFileProtectedPath = errors.New("protected project file cannot be modified") ErrProjectFileSymlinkPath = errors.New("symlink project paths are not supported") )
var ErrProjectDirExists = errors.New("project directory already exists")
ErrProjectDirExists is returned by CreateExactDir when the target directory already exists. Callers that must not auto-rename (e.g. GitOps creates, which must never mint "-N" duplicate projects on a broken binding) use this to fail loudly instead of suffixing.
var ProjectFileCandidates = append( append(slices.Clone(composeFileCandidates), composeOverrideFileCandidates...), ".env", )
ProjectFileCandidates enumerates known project files: base compose names, compose override names, and .env. It is used as a membership set for recognizing and skipping known files during discovery; it is NOT the base-detection order (see composeFileCandidates for that).
Functions ¶
func ApplyLenientLoaderOptions ¶ added in v2.3.2
ApplyLenientLoaderOptions configures a compose loader.Options for tolerant loading: structural validation and consistency checks are skipped, and unresolvable ${VAR} references are substituted with a placeholder instead of an empty string (which would otherwise produce invalid volume/bind specs like ":/path"). Callers use this when a .env file may not yet exist or may not define every variable the compose file references.
The placeholder is applied at the substitution level, not the lookup level: the lookup must keep reporting undefined variables as missing so compose-go resolves default operators (${VAR:-default}, ${VAR-default}) normally. Reporting the placeholder as the variable's value would suppress those defaults and feed the placeholder into fields like ports host entries.
func ApplyProjectFileChanges ¶ added in v2.1.0
func ApplyProjectFileChanges(projectPath string, changes []project.ProjectFileChange, opts ProjectFileApplyOptions) error
func ApplyProjectFileDrafts ¶ added in v2.1.0
func ApplyProjectFileDrafts(projectPath string, drafts []project.ProjectFileDraft, opts ProjectFileApplyOptions) error
func BuildAdditiveOverrideEnvContent ¶
BuildAdditiveOverrideEnvContent derives override content from a pre-git local .env file. Like other generated env helpers, the result is normalized and does not preserve comments or original key ordering.
func BuildArgsFromCompose ¶ added in v2.1.0
BuildArgsFromCompose flattens compose build args into a string map, dropping nil values.
func BuildEffectiveEnvContent ¶
BuildEffectiveEnvContent merges git and override env sources into the effective .env content written to disk. Each source is preserved verbatim, with the override appended after the Git content so duplicate keys resolve to the override value when Compose parses the effective file.
func BuildImagePullPlan ¶ added in v2.3.2
func BuildImagePullPlan(services composetypes.Services) map[string]ImagePullMode
BuildImagePullPlan builds a deduplicated image pull plan for non-build services.
func BuildImageRefsFromComposeProject ¶ added in v2.5.0
func BuildImageRefsFromComposeProject(project *composetypes.Project) []string
BuildImageRefsFromComposeProject returns the image references produced by services with build directives, including Compose's default image name when a service does not declare image explicitly.
func BuildLocalImageTag ¶ added in v2.1.0
BuildLocalImageTag derives a deterministic local image tag for a built service.
func BuildOverrideEnvContent ¶
BuildOverrideEnvContent derives the editable override file from git-backed and effective env content. Content that already contains only real overrides is returned verbatim; derived or cleaned output uses Arcane's canonical format.
func BuildPlatformsFromCompose ¶ added in v2.1.0
func BuildPlatformsFromCompose(svc composetypes.ServiceConfig) []string
BuildPlatformsFromCompose returns the build platforms for a service, falling back to the service platform when no build platforms are declared.
func CleanupRemovedFiles ¶
CleanupRemovedFiles deletes files that were in the old sync but are not in the new sync. It only removes files that were previously synced (tracked in oldFiles). Empty directories are removed after file deletion. This is a best-effort operation - errors are logged but don't cause failure.
func ComposeContentProjectName ¶ added in v2.0.3
ComposeContentProjectName returns the normalized top-level `name:` from compose YAML content, or "" when the key is absent or unusable. Interpolated names (containing `${`) are treated as absent so the backend and the frontend name lock behave identically; parse errors are ignored here because the full compose validation reports them with proper context.
func ComposeDown ¶
func ComposeFileCandidates ¶
func ComposeFileCandidates() []string
ComposeFileCandidates returns the supported base compose filenames in Arcane's detection order. A copy is returned so callers can't mutate package state.
func ComposeLogs ¶
func ComposeOverrideFileCandidates ¶ added in v2.4.0
func ComposeOverrideFileCandidates() []string
ComposeOverrideFileCandidates returns the supported compose override filenames in detection order. A copy is returned so callers can't mutate package state.
func ComposeRestart ¶
func ComposeStop ¶
func CopyDirectoryContents ¶
func CopyDirectoryContentsTolerant ¶ added in v2.2.0
CopyDirectoryContentsTolerant copies srcDir into destDir like CopyDirectoryContents, except that files (or whole subdirectories) which cannot be read because of a permission error are skipped instead of aborting the copy. The skipped entries' project-relative paths are returned sorted so callers can avoid deleting them on a later restore. Any non-permission error still aborts the copy.
func CreateExactDir ¶ added in v2.3.0
func CreateExactDir(projectsRoot, basePath, name string, perm os.FileMode) (path, folderName string, err error)
CreateExactDir creates basePath (the sanitized project directory) under projectsRoot WITHOUT any "-N" collision suffixing. It returns ErrProjectDirExists when the directory already exists, leaving the caller to decide how to proceed. Validation mirrors CreateUniqueDir so the created directory is always within projectsRoot.
func CreateUniqueDir ¶
func CreateUniqueDir(projectsRoot, basePath, name string, perm os.FileMode) (path, folderName string, err error)
CreateUniqueDir creates a unique directory within the allowed projectsRoot. It validates that the created directory is always within projectsRoot.
func DefaultSwarmStackEnvTemplate ¶
func DefaultSwarmStackEnvTemplate() string
func DefaultSwarmStackTemplate ¶
func DefaultSwarmStackTemplate() string
func DetectComposeFile ¶
func DetectComposeOverrideFile ¶ added in v2.4.0
DetectComposeOverrideFile returns the path to the highest-preference compose override file present in dir, following compose-go's preference order, or "" when none exists. When multiple override files are present it returns the highest-preference match and logs a warning, mirroring compose-go behavior.
func EnsureDefaultTemplates ¶
func EnsureEnvFile ¶
func EnsureTemplateDir ¶
func GetHostPathForContainerPath ¶ added in v2.2.0
func GetHostPathForContainerPath(ctx context.Context, dockerCli *client.Client, containerPath string) (string, error)
GetHostPathForContainerPath attempts to discover the host-side path for a given container path by inspecting the container itself. This is useful for Docker-in-Docker scenarios where the application needs to know host paths for volume mapping. It returns an empty string when the path is not covered by any of Arcane's mounts.
func GetProjectsDirectory ¶
func GetTemplatesDirectory ¶
func ImageRefsFromComposeConfigs ¶
func ImageRefsFromComposeConfigs(services []composetypes.ServiceConfig) []string
ImageRefsFromComposeConfigs returns unique, non-empty image references from compose service configs while preserving first-seen order.
func ImageRefsFromComposeServices ¶
func ImageRefsFromComposeServices(services composetypes.Services) []string
ImageRefsFromComposeServices returns unique, non-empty image references from a compose service map in stable service-name order.
func ImageRefsFromRuntimeServices ¶
func ImageRefsFromRuntimeServices(services []projecttypes.RuntimeService) []string
ImageRefsFromRuntimeServices returns unique, non-empty image references from runtime service DTOs while preserving first-seen order.
func IsAlwaysPullPolicy ¶ added in v2.3.2
IsAlwaysPullPolicy reports whether policy means always pull.
func IsFilesystemSnapshotDirName ¶ added in v2.4.0
IsFilesystemSnapshotDirName reports whether name is a well-known filesystem snapshot/trash directory (see filesystemSnapshotDirNames).
func IsGitOpsScratchDirName ¶ added in v2.3.0
IsGitOpsScratchDirName reports whether name is an Arcane GitOps scratch directory: the hidden staging/backup temp dirs (".gitops-sync-stage-*", ".gitops-backup-*") or the legacy name-embedded backup form ("<name>.gitops-backup-<digits>"). These are Arcane-internal working directories and must never be imported as user projects.
func IsInternalScratchDirName ¶ added in v2.3.0
IsInternalScratchDirName reports whether name is any Arcane-managed scratch directory that must never be discovered or imported as a user project: the project-update preview/backup temp dirs, the quarantine/trash dirs (see ArcaneTrashPrefix), or the GitOps sync-stage/backup dirs (see IsGitOpsScratchDirName). This is the single source of truth for the discovery walker and the DB cleanup pass.
func IsProjectDirectoryEntry ¶
IsProjectDirectoryEntry reports whether a directory entry should be treated as a project directory. Regular directories are always accepted. Symlinked directories are accepted only when enabled.
func IsProjectDirectoryPath ¶
IsProjectDirectoryPath reports whether an existing path should be treated as a project directory. Regular directories are always accepted. Symlinked directories are accepted only when enabled.
func IsProjectFile ¶
IsProjectFile reports whether filename is a known project file or a plausible custom YAML filename worth watching for compose discovery.
func IsSafeSubdirectory ¶
IsSafeSubdirectory returns true if subdir is a subdirectory of baseDir (absolute, normalized)
func IsWindowsDrivePath ¶
IsWindowsDrivePath returns true if the path looks like a Windows drive path (e.g., "C:/path")
func LabelsFromCompose ¶ added in v2.1.0
func LabelsFromCompose(labels composetypes.Labels) map[string]string
LabelsFromCompose copies compose labels into a plain map, returning nil when empty.
func LoadComposeProject ¶
func LoadComposeProject(ctx context.Context, composeFile, projectName, projectsDirectory string, autoInjectEnv bool, pathMapper *PathMapper) (*composetypes.Project, error)
func LoadComposeProjectFromDir ¶
func LoadComposeProjectFromDir(ctx context.Context, dir, projectName, projectsDirectory string, autoInjectEnv bool, pathMapper *PathMapper) (*composetypes.Project, string, error)
func LoadComposeProjectLenient ¶
func LoadComposeProjectLenient(ctx context.Context, composeFile, projectName, projectsDirectory string, autoInjectEnv bool, pathMapper *PathMapper) (*composetypes.Project, error)
LoadComposeProjectLenient loads a compose project tolerating undefined variables. Instead of substituting undefined ${VAR} references with an empty string (which produces invalid volume/bind specs like ":/path"), it replaces them with a placeholder value so structural validation can succeed. This is useful during GitSync validation where a .env file may not yet exist.
func MarshalImageRefsJSON ¶ added in v2.3.2
MarshalImageRefsJSON serializes image references to JSON, returning an empty string when there are no refs or encoding fails.
func MergeBuildTags ¶ added in v2.1.0
MergeBuildTags combines a primary image tag with compose tags, trimming blanks and de-duplicating while preserving order (primary first).
func MirrorDirectoryContentsPreserving ¶ added in v2.2.0
MirrorDirectoryContentsPreserving makes destDir match srcDir while updating files and directories in place, so existing inodes (and therefore container bind mounts into destDir) stay valid. Entries missing from srcDir or whose type differs are removed, then srcDir is copied over the result. It never prunes a destDir entry whose project-relative path is listed in preserve, nor any directory that still contains a preserved entry. It is used when restoring a backup that intentionally omits files the caller could not read: those files must survive the restore rather than be deleted.
func NormalizeDeployPullPolicy ¶ added in v2.3.2
NormalizeDeployPullPolicy returns a supported deploy pull policy or empty string.
func NormalizeProjectName ¶ added in v2.3.2
NormalizeProjectName returns compose-go's normalized project name. If compose-go returns empty, the input is returned unchanged.
func NormalizeProjectRelativePath ¶ added in v2.1.0
func NormalizePullPolicy ¶ added in v2.3.2
NormalizePullPolicy normalizes compose pull policy aliases.
func ParseEnvContent ¶
ParseEnvContent parses environment variables from .env file content
func ParseImageRefsJSON ¶ added in v2.3.2
ParseImageRefsJSON parses a JSON array of image references, returning nil for empty or invalid input.
func PathContainsSnapshotDirectory ¶ added in v2.4.0
PathContainsSnapshotDirectory reports whether any segment of relPath is a filesystem snapshot/trash directory name, i.e. the path points into a point-in-time copy rather than a live project directory.
func ProtectedProjectFilePaths ¶ added in v2.1.0
func ReadComposeOverrideContent ¶ added in v2.4.0
ReadComposeOverrideContent returns the content of the highest-preference compose override file present in dir, or "" when none exists or it cannot be read. It is a best-effort read intended for change detection.
func ReadProjectFileTree ¶ added in v2.1.0
func ReadProjectFiles ¶
func RemoveProjectFile ¶
func RemoveStaleComposeFiles ¶
func ResolveBuildContext ¶ added in v2.3.2
func ResolveBuildContext(workingDir string, svc composetypes.ServiceConfig, serviceName string) (string, error)
ResolveBuildContext resolves a service build context against workingDir. The service config must have a non-nil Build field.
func ResolveComposeOverride ¶ added in v2.4.0
func ResolveComposeOverride(exists func(name string) bool, read func(name string) (string, error)) (fileName string, content string, found bool, err error)
ResolveComposeOverride finds the highest-preference compose override file among the supported candidates using the exists probe, then loads it via read. It centralizes override discovery so non-filesystem sources (e.g. a Git working tree accessed through a validated client) reuse the same preference order. When multiple candidates exist it warns and uses the highest-preference match, mirroring DetectComposeOverrideFile. found is false (with empty name/content) when no candidate exists.
func ResolveDockerfilePath ¶ added in v2.3.2
func ResolveDockerfilePath(svc composetypes.ServiceConfig) string
ResolveDockerfilePath returns the configured Dockerfile path or Dockerfile. The service config must have a non-nil Build field.
func ResolveHostPath ¶ added in v2.1.0
ResolveHostPath returns the host-side path for containerPath by selecting the longest-prefix mount whose Destination contains it and appending the trailing relative segment to that mount's Source. ok is false when no mount contains the path.
func ResolveRelativeProjectPaths ¶
func ResolveRelativeProjectPaths(project *composetypes.Project, workdir string)
func RestoreProjectUpdateBackup ¶ added in v2.4.0
func RestoreProjectUpdateBackup(projectDir string, backup *ProjectUpdateBackup) error
RestoreProjectUpdateBackup rolls the scoped parts of projectDir back to the state captured in backup. Files are restored in place (preserving inodes so container bind mounts stay valid) and out-of-scope files are never touched.
func RollbackRenamedProjectDirectory ¶ added in v2.3.2
RollbackRenamedProjectDirectory restores a project directory rename when possible.
func SanitizeImageComponent ¶ added in v2.1.0
SanitizeImageComponent lowercases a value and replaces characters that are invalid in an image reference component with '-'.
func SanitizeProjectName ¶
func UlimitsFromCompose ¶ added in v2.1.0
func UlimitsFromCompose(ulimits map[string]*composetypes.UlimitsConfig) map[string]string
UlimitsFromCompose renders compose ulimits as Docker-style "soft:hard" (or single) strings.
func ValidateIncludePathForWrite ¶
ValidateIncludePathForWrite ensures the include path is safe for write operations Returns the validated absolute path to prevent recomputation after validation Only allows writing within the project directory
func ValidateProjectFileName ¶ added in v2.1.0
func WithTransientValidationEnvFile ¶ added in v2.3.2
func WithTransientValidationEnvFile(projectPath string, effectiveEnvContent *string, run func() error) (err error)
WithTransientValidationEnvFile temporarily writes a project .env file while running compose validation, then restores the original file state.
func WriteComposeFile ¶
WriteComposeFile writes a compose file to the specified directory. It detects existing compose file names (docker-compose.yml, compose.yaml, etc.) and uses the existing name if found, otherwise defaults to compose.yaml projectsRoot is the allowed root directory to prevent path traversal attacks
func WriteComposeOverrideFile ¶ added in v2.4.0
WriteComposeOverrideFile writes content as the override file named fileName in dir when content is non-nil, and removes every other override candidate so a renamed or deleted override never leaves a stale copy behind. When content is nil, all supported override files are removed. projectsRoot bounds writes to prevent path traversal.
func WriteEnvFile ¶
WriteEnvFile writes a .env file to the specified directory projectsRoot is the allowed root directory to prevent path traversal attacks
func WriteFileWithPerm ¶
WriteFileWithPerm is a generic file writer with custom permissions
func WriteIncludeFile ¶
WriteIncludeFile writes content to an include file path
func WriteManagedEnvFile ¶ added in v2.3.2
func WriteManagedEnvFile(projectsDirectory, projectPath, fileName string, unreadable bool, content string) error
WriteManagedEnvFile writes (or, for project.env, removes) one of the three env-merge bookkeeping files — fileName must be EffectiveEnvFileName, GitSourceEnvFileName, or OverrideEnvFileName. If the existing file is permission-locked, the write is skipped and a warning logged instead: its contents can't be verified, and a locked file is typically unwritable too, so attempting the write would abort the whole caller.
func WriteProjectFile ¶
func WriteProjectFiles ¶
WriteProjectFiles writes both compose and env files to a project directory. An empty .env file is always created to prevent compose-go from failing when the compose file references env_file: .env projectsRoot is the allowed root directory to prevent path traversal attacks
func WriteSyncedDirectory ¶
WriteSyncedDirectory writes multiple files to a project directory. It validates all paths are within the project directory and creates subdirectories as needed. Returns the list of written file paths.
func WriteTemplateFile ¶
WriteTemplateFile writes a template file (like .compose.template or .env.template)
func WriteTemplateFiles ¶
Types ¶
type ArcaneComposeMetadata ¶
type ArcaneComposeMetadata struct {
// ProjectIcon contains fallback, light, and dark icon values for the project.
ProjectIcon IconSet
// ProjectURLS are additional URLs related to the project (e.g., documentation, homepage).
ProjectURLS []string
// ServiceIconSets maps service names to their fallback, light, and dark icon values.
ServiceIconSets map[string]IconSet
}
ArcaneComposeMetadata represents Arcane-specific configuration extracted from a Compose file.
func ParseArcaneComposeMetadata ¶
func ParseArcaneComposeMetadata(ctx context.Context, composeFilePath, projectsDirectory string, autoInjectEnv bool) (ArcaneComposeMetadata, error)
ParseArcaneComposeMetadata reads a Docker Compose file and extracts Arcane-specific metadata. When projectsDirectory is set, Arcane's project env loading is used so .env.global is available.
func ParseArcaneComposeMetadataWithEnv ¶
func ParseArcaneComposeMetadataWithEnv(ctx context.Context, composeFilePath string, envMap map[string]string) (ArcaneComposeMetadata, error)
ParseArcaneComposeMetadataWithEnv reads a Docker Compose file and extracts Arcane-specific metadata using a provided environment.
type DeployImageDecision ¶ added in v2.3.2
type DeployImageDecision struct {
Build bool
PullAlways bool
PullIfMissing bool
FallbackBuildOnPullFail bool
RequireLocalOnly bool
}
DeployImageDecision describes how deploy should handle a service image.
func DecideDeployImageAction ¶ added in v2.3.2
func DecideDeployImageAction(svc composetypes.ServiceConfig, pullPolicyOverride string) DeployImageDecision
DecideDeployImageAction decides whether deploy should build, pull, or require local images.
type DiscoveredProjectDir ¶
func DiscoverProjectDirectories ¶
func DiscoverProjectDirectories(root string, followSymlinks bool, maxDepth int) ([]DiscoveredProjectDir, error)
type EnvLoader ¶
type EnvLoader struct {
// contains filtered or unexported fields
}
func NewEnvLoader ¶
func (*EnvLoader) LoadEnvironment ¶
func (l *EnvLoader) LoadEnvironment(ctx context.Context) (envMap EnvMap, injectionVars EnvMap, err error)
LoadEnvironment loads and merges environment variables from all sources: 1. Process environment 2. Global .env.global file (from projects directory) 3. Project-specific .env file (from workdir)
type EnvMap ¶
func ParseProjectEnvContent ¶
ParseProjectEnvContent parses project .env content from a string with variable expansion.
func ParseProjectEnvFile ¶
ParseProjectEnvFile parses a project .env file with variable expansion using the provided context map (e.g. process env). Returns nil without error when the file does not exist. Only the specified file is read — global env files are intentionally not loaded here.
type HostMount ¶ added in v2.1.0
type HostMount struct {
Destination string // container-side mount path, e.g. "/app/data/projects/homeassistant"
Source string // host-side path, e.g. "/home/user/homeassistant"
}
HostMount is one container→host mount (bind or named volume) from Arcane's own container. It is used for longest-prefix host-path resolution in Docker-in-Docker setups, where independently bind-mounted project directories each map to their own host path rather than a single projects-root prefix.
func GetCurrentContainerMounts ¶ added in v2.2.0
GetCurrentContainerMounts inspects Arcane's own container and returns its bind and named-volume mounts as HostMount entries. It returns no mounts when Arcane is not running in a container (or the daemon is unreachable). This is the basis for Docker-in-Docker host-path resolution.
type IconSet ¶
type IconSet = iconcatalog.IconSet
func FindArcaneIconSet ¶
FindArcaneIconSet attempts to locate Arcane icon labels within service labels. It supports both map[string]string and []string label formats.
type ImagePullMode ¶ added in v2.3.2
type ImagePullMode int
ImagePullMode describes when Arcane should pull an image for a project.
const ( // ImagePullModeNever skips pulling the image. ImagePullModeNever ImagePullMode = iota // ImagePullModeIfMissing pulls only when the image is missing locally. ImagePullModeIfMissing // ImagePullModeAlways pulls even when the image is present locally. ImagePullModeAlways )
func ResolveServiceImagePullMode ¶ added in v2.3.2
func ResolveServiceImagePullMode(svc composetypes.ServiceConfig) ImagePullMode
ResolveServiceImagePullMode resolves compose pull_policy into Arcane's pull mode.
type IncludeFile ¶
type IncludeFile struct {
Path string `json:"path"`
RelativePath string `json:"relative_path"`
Content string `json:"content"`
}
func ParseIncludes ¶
func ParseIncludes(composeFilePath string, envMap EnvMap, includeContent bool) ([]IncludeFile, error)
ParseIncludes reads a compose file and extracts all include directives. envMap is used to expand variables (e.g., ${VAR}) in include paths.
func ParseIncludesFromContent ¶
func ParseIncludesFromContent(composeFilePath string, content []byte, envMap EnvMap, includeContent bool) ([]IncludeFile, error)
ParseIncludesFromContent extracts include directives from compose content using composeFilePath as the base path.
type MissingIncludeStubLoader ¶ added in v2.3.2
type MissingIncludeStubLoader struct {
// contains filtered or unexported fields
}
MissingIncludeStubLoader creates temporary stub compose files for missing include paths during validation.
func NewMissingIncludeStubLoader ¶ added in v2.3.2
func NewMissingIncludeStubLoader(projectPath string) *MissingIncludeStubLoader
NewMissingIncludeStubLoader creates a loader for validation stubs under projectPath.
func (*MissingIncludeStubLoader) Accept ¶ added in v2.3.2
func (l *MissingIncludeStubLoader) Accept(path string) bool
func (*MissingIncludeStubLoader) Cleanup ¶ added in v2.3.2
func (l *MissingIncludeStubLoader) Cleanup()
Cleanup removes any temporary validation stub files created by the loader.
func (*MissingIncludeStubLoader) Dir ¶ added in v2.3.2
func (l *MissingIncludeStubLoader) Dir(path string) string
type PathMapper ¶
type PathMapper struct {
// contains filtered or unexported fields
}
PathMapper handles translation between container and host paths
func NewPathMapper ¶
func NewPathMapper(containerDir, hostDir string) *PathMapper
NewPathMapper creates a new path mapper
func NewPathMapperFromMounts ¶ added in v2.1.0
func NewPathMapperFromMounts(mounts []HostMount) *PathMapper
NewPathMapperFromMounts creates a path mapper that resolves each source against the given container mount table by longest-prefix match, instead of a single container→host prefix. This is used for Docker-in-Docker auto-discovery so that an independently bind-mounted project directory maps to its real host path.
func (*PathMapper) ContainerToHost ¶
func (pm *PathMapper) ContainerToHost(containerPath string) (string, error)
ContainerToHost translates a container path to host path
func (*PathMapper) IsNonMatchingMount ¶
func (pm *PathMapper) IsNonMatchingMount() bool
func (*PathMapper) TranslateVolumeSources ¶
func (pm *PathMapper) TranslateVolumeSources(project *composetypes.Project) error
TranslateVolumeSources translates all bind mount sources in a compose project
type ProgressWriterKey ¶
type ProgressWriterKey struct{}
ProgressWriterKey can be set on a context to enable JSON-line progress updates. The value must be an io.Writer (typically the HTTP response writer).
type ProjectEnvMode ¶
type ProjectEnvMode string
const ( ProjectEnvModeDirect ProjectEnvMode = "direct" ProjectEnvModeOverride ProjectEnvMode = "override" )
type ProjectEnvState ¶
type ProjectEnvState struct {
Mode ProjectEnvMode
EditableFileName string
EditableContent string
EffectiveContent string
DirectContent string
GitContent string
OverrideContent string
HasEffective bool
HasGitSource bool
HasOverride bool
// The *Unreadable fields report a file that exists on disk but could not be
// read because of a permission error (e.g. a chmod 000 or foreign-owned
// file reachable through a bind mount). Such a file is treated as absent
// for merge purposes, and callers persisting env state must not attempt to
// write or remove it — its contents are unknown, so writing could either
// fail (bricking the caller) or silently clobber operator intent.
EffectiveUnreadable bool
GitSourceUnreadable bool
OverrideUnreadable bool
}
func ReadProjectEnvState ¶
func ReadProjectEnvState(projectPath string) (ProjectEnvState, error)
type ProjectFileApplyOptions ¶ added in v2.1.0
type ProjectUpdateBackup ¶ added in v2.4.0
type ProjectUpdateBackup struct {
BackupDir string
TopLevelFiles bool
FileEntries []string // regular file contents copied into BackupDir
DirEntries []string // directories copied recursively
AbsentEntries []string // did not exist at backup time -> removed on restore
RenamedDirs [][2]string // undone via inverse rename on restore
Skipped []string // unreadable, skipped; preserved on restore
// contains filtered or unexported fields
}
ProjectUpdateBackup records what BackupProjectUpdateScope copied so RestoreProjectUpdateBackup can put the project directory back without touching anything outside the update's scope.
func BackupProjectUpdateScope ¶ added in v2.4.0
func BackupProjectUpdateScope(projectDir, backupDir string, scope ProjectUpdateBackupScope) (*ProjectUpdateBackup, error)
BackupProjectUpdateScope copies the parts of projectDir named by scope into backupDir. Unreadable files are skipped (recorded in Skipped) so an unrelated foreign-owned file cannot block a save, matching the tolerant semantics of the old whole-directory backup.
type ProjectUpdateBackupScope ¶ added in v2.4.0
type ProjectUpdateBackupScope struct {
// TopLevelFiles backs up every top-level regular file in the project
// directory. Compose/env persistence only ever writes top-level files.
TopLevelFiles bool
// Paths are normalized project-relative paths a file change can create,
// overwrite or delete.
Paths []string
// RenamedDirs holds {src, dest} pairs for a rename/move of an existing
// directory. These are rolled back with an inverse rename instead of a
// copy, so a huge directory move never triggers a full copy.
RenamedDirs [][2]string
}
ProjectUpdateBackupScope describes exactly what a project update can mutate, so the pre-update backup copies only those paths instead of the whole project directory (which may contain huge container data directories).
func (ProjectUpdateBackupScope) IsEmpty ¶ added in v2.4.0
func (s ProjectUpdateBackupScope) IsEmpty() bool
type SyncFile ¶
type SyncFile struct {
RelativePath string // Path relative to the project directory
Content []byte
// Executable preserves the source's +x bit so lifecycle hooks and other
// repo-committed scripts arrive runnable in the project workspace.
Executable bool
}
SyncFile represents a file to be written during directory sync