docs: add config profile git mounts documentation
- API documentation for config profiles with git mounts endpoint details - User guide for using git repositories in config profiles - Document branch pinning, glob patterns, error handling, and best practices - Update API README to link to new config-profiles documentation
This commit is contained in:
@@ -33,6 +33,7 @@ All responses are JSON. Error responses follow this format:
|
||||
- [Auth](auth.md) - Authentication endpoints
|
||||
- [Projects](projects.md) - Project management
|
||||
- [Repositories](repositories.md) - Git repositories and file operations
|
||||
- [Config Profiles](config-profiles.md) - Config profile management with git mounts
|
||||
- [Users](users.md) - User management and settings
|
||||
- [Tool Types](tool-types.md) - Tool type management
|
||||
- [SSH Keys](ssh-keys.md) - SSH key management
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
# Config Profiles
|
||||
|
||||
## Overview
|
||||
|
||||
Config profiles allow users to define reusable configuration sets for tool instances. Profiles can include environment variables, files, mounts, and git repository mounts. They support profile includes for composition and can be scoped to specific projects or tool types.
|
||||
|
||||
## Git Mounts
|
||||
|
||||
Git mounts allow you to mount files or directories from git repositories into tool instances at startup.
|
||||
|
||||
### Git Mount Object
|
||||
|
||||
```json
|
||||
{
|
||||
"repo_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"source_path": ".",
|
||||
"target_path": "/app/config",
|
||||
"branch": "main"
|
||||
}
|
||||
```
|
||||
|
||||
**Fields:**
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `repo_id` | string (UUID) | Yes | ID of the git repository to mount from |
|
||||
| `source_path` | string | No | Path within the repository (default: "."). Supports glob patterns like "*.json" or "configs/**" |
|
||||
| `target_path` | string | Yes | Absolute path inside the container where files will be mounted |
|
||||
| `branch` | string | No | Branch or tag to checkout before mounting (default: current branch) |
|
||||
|
||||
### Path Validation
|
||||
|
||||
- `source_path`: Must be relative (no leading `/`). Cannot contain `..` (path traversal)
|
||||
- `target_path`: Must be absolute (starts with `/`). Cannot contain `..`
|
||||
|
||||
### Glob Patterns
|
||||
|
||||
The `source_path` supports standard glob patterns:
|
||||
|
||||
- `*.json` - Match all JSON files in root
|
||||
- `configs/**` - Match all files in configs directory recursively
|
||||
- `src/*.py` - Match all Python files in src directory
|
||||
- `.` - Mount entire repository (default)
|
||||
|
||||
**Limits:**
|
||||
- Maximum 100 matches per glob pattern
|
||||
- Only matches within the repository boundary
|
||||
|
||||
### Branch Behavior
|
||||
|
||||
When a `branch` is specified:
|
||||
|
||||
1. System attempts to checkout the branch in the existing clone
|
||||
2. If branch doesn't exist locally, attempts to fetch from remote and checkout
|
||||
3. If checkout fails, logs warning and continues with current branch
|
||||
4. No branch specified: uses current checked-out branch
|
||||
|
||||
**Auto-clone:** If repository is not cloned locally, the system will automatically clone it using the repository's configured SSH key.
|
||||
|
||||
## Endpoints
|
||||
|
||||
### List Config Profiles
|
||||
|
||||
```
|
||||
GET /config-profiles
|
||||
```
|
||||
|
||||
Query parameters:
|
||||
- `project_id` (optional): Filter by project compatibility
|
||||
- `tool_type_id` (optional): Filter by tool type compatibility
|
||||
|
||||
Response includes `git_mounts` array in each profile.
|
||||
|
||||
### Create Config Profile
|
||||
|
||||
```
|
||||
POST /config-profiles
|
||||
```
|
||||
|
||||
Request body:
|
||||
```json
|
||||
{
|
||||
"name": "My Profile",
|
||||
"git_mounts": [
|
||||
{
|
||||
"repo_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"source_path": "configs/*.json",
|
||||
"target_path": "/app/config",
|
||||
"branch": "main"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Validation:
|
||||
- All referenced repositories must exist
|
||||
- Repositories must belong to the same project (if profile has project_id)
|
||||
- source_path and target_path must pass path validation
|
||||
|
||||
### Update Config Profile
|
||||
|
||||
```
|
||||
PUT /config-profiles/{id}
|
||||
```
|
||||
|
||||
Same request body as create. Partial updates supported (omit fields to keep current values).
|
||||
|
||||
### Preview Resolved Profile
|
||||
|
||||
```
|
||||
GET /config-profiles/{id}/preview
|
||||
```
|
||||
|
||||
Returns the fully resolved profile with all includes merged. Git mounts from included profiles are merged with override rules (later profiles override earlier ones with same repo_id + target_path combo).
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"profile_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"profile_name": "My Profile",
|
||||
"env_vars": {},
|
||||
"runtime_hints": {},
|
||||
"mounts": [],
|
||||
"git_mounts": [
|
||||
{
|
||||
"repo_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"source_path": "configs/*.json",
|
||||
"target_path": "/app/config",
|
||||
"branch": "main"
|
||||
}
|
||||
],
|
||||
"files": {},
|
||||
"overrides": {
|
||||
"env_vars": {},
|
||||
"runtime_hints": {},
|
||||
"files": {},
|
||||
"mounts": {}
|
||||
},
|
||||
"included_profiles": []
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Git mount errors during instance startup are non-blocking:
|
||||
- Missing repository: Mount skipped, warning logged
|
||||
- Clone failure: Mount skipped, warning logged
|
||||
- Invalid paths: Mount skipped, warning logged
|
||||
- Branch checkout failure: Falls back to current branch, warning logged
|
||||
|
||||
Instance startup continues normally even if some git mounts fail.
|
||||
|
||||
## Profile Resolution
|
||||
|
||||
When a profile includes other profiles, git mounts are merged:
|
||||
- Same `repo_id` + `target_path` combo: later profile overrides
|
||||
- Different combos: both are kept
|
||||
- Branch conflicts: later profile wins
|
||||
|
||||
Example:
|
||||
```
|
||||
Base Profile: git_mounts = [{repo_a, /app, main}]
|
||||
Included Profile: git_mounts = [{repo_a, /app, develop}, {repo_b, /data}]
|
||||
Resolved: git_mounts = [{repo_a, /app, develop}, {repo_b, /data}]
|
||||
```
|
||||
@@ -0,0 +1,159 @@
|
||||
# Using Git Repositories in Config Profiles
|
||||
|
||||
## Overview
|
||||
|
||||
Config profiles now support mounting files and directories from git repositories directly into your tool instances. This is useful for:
|
||||
|
||||
- Sharing configuration files across multiple instances
|
||||
- Mounting dotfiles or development environment configs
|
||||
- Including shared code or assets from other repositories
|
||||
- Pinning specific branches or versions of dependencies
|
||||
|
||||
## How It Works
|
||||
|
||||
When you start a tool instance with a config profile that has git mounts:
|
||||
|
||||
1. The system checks if the repository is cloned locally
|
||||
2. If not cloned and a remote URL is available, it automatically clones the repository
|
||||
3. If a branch is specified, it checks out that branch
|
||||
4. Files matching the source path pattern are mounted as bind mounts into the container
|
||||
5. Instance startup continues normally
|
||||
|
||||
## Adding Git Mounts
|
||||
|
||||
### Step 1: Select a Repository
|
||||
|
||||
In the config profile editor, find the "Git Mounts" section. Choose a repository from the dropdown. Only repositories from your projects are available.
|
||||
|
||||
### Step 2: Configure Source Path
|
||||
|
||||
The source path determines which files from the repository to mount:
|
||||
|
||||
- **`.`** (default): Mount the entire repository
|
||||
- **`configs/`**: Mount the configs directory
|
||||
- **`*.json`**: Mount all JSON files in the repository root
|
||||
- **`src/**/*.py`**: Mount all Python files in the src directory recursively
|
||||
|
||||
**Glob patterns are supported** - use `*` for any characters, `**` for recursive matching.
|
||||
|
||||
### Step 3: Set Target Path
|
||||
|
||||
The target path is where files appear inside the container:
|
||||
|
||||
- `/app/config` - Mount to /app/config
|
||||
- `/home/user/dotfiles` - Mount to user's home directory
|
||||
- `/workspace/shared` - Mount to workspace shared folder
|
||||
|
||||
Target paths must be absolute (start with `/`).
|
||||
|
||||
### Step 4: Optional Branch Selection
|
||||
|
||||
You can pin a specific branch or tag:
|
||||
|
||||
- `main` - Use the main branch
|
||||
- `develop` - Use the develop branch
|
||||
- `v1.2.3` - Pin to a specific tag
|
||||
|
||||
If not specified, the current checked-out branch is used.
|
||||
|
||||
## Examples
|
||||
|
||||
### Dotfiles Configuration
|
||||
|
||||
Mount your dotfiles repository into the home directory:
|
||||
|
||||
```
|
||||
Repository: dotfiles
|
||||
Source Path: .
|
||||
Target Path: /home/user
|
||||
Branch: main
|
||||
```
|
||||
|
||||
### Shared Configuration Files
|
||||
|
||||
Mount only JSON config files from a shared config repo:
|
||||
|
||||
```
|
||||
Repository: shared-configs
|
||||
Source Path: *.json
|
||||
Target Path: /app/config
|
||||
Branch: production
|
||||
```
|
||||
|
||||
### Development Tools Configuration
|
||||
|
||||
Mount specific tool configs:
|
||||
|
||||
```
|
||||
Repository: dev-tools
|
||||
Source Path: vscode/
|
||||
Target Path: /workspace/.vscode
|
||||
```
|
||||
|
||||
### Multiple Mounts
|
||||
|
||||
You can add multiple git mounts to a single profile:
|
||||
|
||||
1. Dotfiles → `/home/user`
|
||||
2. Shared configs → `/app/config`
|
||||
3. Assets → `/app/static`
|
||||
|
||||
## Profile Includes
|
||||
|
||||
Git mounts work with profile includes. If Profile A includes Profile B:
|
||||
|
||||
- Both profiles' git mounts are merged
|
||||
- Same repository + target path combinations override (later profile wins)
|
||||
- Different combinations are kept
|
||||
|
||||
Example:
|
||||
```
|
||||
Base Profile:
|
||||
- repo: dotfiles, target: /home/user, branch: main
|
||||
|
||||
Development Profile (includes Base):
|
||||
- repo: dotfiles, target: /home/user, branch: develop
|
||||
- repo: dev-tools, target: /opt/tools
|
||||
|
||||
Resolved Result:
|
||||
- repo: dotfiles, target: /home/user, branch: develop (overridden)
|
||||
- repo: dev-tools, target: /opt/tools (added)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
Git mounts are non-blocking:
|
||||
|
||||
- **Repository not found**: Mount is skipped, instance continues starting
|
||||
- **Clone fails**: Mount is skipped, warning logged
|
||||
- **Branch doesn't exist**: Falls back to current branch, warning logged
|
||||
- **Glob pattern matches nothing**: Mount is skipped, warning logged
|
||||
- **Path outside repository**: Match is skipped, warning logged
|
||||
|
||||
You can check the instance logs to see which mounts succeeded and which failed.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use specific paths**: Instead of mounting the entire repository, mount only the files you need. This reduces startup time and avoids conflicts.
|
||||
|
||||
2. **Pin branches**: For reproducible environments, pin specific branches or tags rather than using the default branch.
|
||||
|
||||
3. **Keep repositories small**: Large repositories take longer to clone. Consider splitting config repositories from code repositories.
|
||||
|
||||
4. **Use absolute target paths**: Always use absolute paths (starting with `/`) for target paths to ensure files end up in the expected location.
|
||||
|
||||
5. **Test includes**: When using profile includes, use the Preview feature to verify that git mounts are merged as expected.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Issue**: Git mount not appearing in container
|
||||
**Solution**: Check instance logs for warnings. Common causes: repository not found, clone failure, or source path not matching any files.
|
||||
|
||||
**Issue**: Wrong branch mounted
|
||||
**Solution**: Verify branch name is correct. If branch doesn't exist locally, the system falls back to the current branch. Ensure the remote has the branch.
|
||||
|
||||
**Issue**: Too many files matched
|
||||
**Solution**: Use more specific glob patterns. The system limits matches to 100 files per glob pattern.
|
||||
|
||||
**Issue**: Permission denied
|
||||
**Solution**: Ensure the target path inside the container is writable. Some paths like `/usr` or `/etc` may require root access.
|
||||
Reference in New Issue
Block a user