Skip to content

Commit 65edb54

Browse files
blink-so[bot]shengling5566DevelopmentCatsmatifali
authored
Add template scaffolding script and enhance module script (#395)
Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> Co-authored-by: matifali <[email protected]> Co-authored-by: DevCats <[email protected]> Co-authored-by: Atif Ali <[email protected]>
1 parent c270edf commit 65edb54

File tree

5 files changed

+364
-0
lines changed

5 files changed

+364
-0
lines changed

examples/namespace/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
display_name: NAMESPACE_NAME
3+
bio: Brief description of what this namespace provides
4+
github: your-github-username
5+
avatar: ./.images/avatar.svg
6+
linkedin: https://www.linkedin.com/in/your-profile
7+
website: https://your-website.com
8+
status: community
9+
---
10+
11+
# NAMESPACE_NAME
12+
13+
Brief description of what this namespace provides. Include information about:
14+
15+
- What types of templates/modules you offer
16+
- Your focus areas (e.g., specific cloud providers, technologies)
17+
- Any special features or configurations
18+
19+
## Templates
20+
21+
List your available templates here:
22+
23+
- **template-name**: Brief description
24+
25+
## Modules
26+
27+
List your available modules here:
28+
29+
- **module-name**: Brief description
30+
31+
## Contributing
32+
33+
If you'd like to contribute to this namespace, please [open an issue](https://github.com/coder/registry/issues) or submit a pull request.

examples/templates/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
name: TEMPLATE_NAME
3+
description: A brief description of what this template does
4+
tags: [tag1, tag2, tag3]
5+
icon: /icon/TEMPLATE_NAME.svg
6+
---
7+
8+
# TEMPLATE_NAME
9+
10+
A brief description of what this template provides and its use case.
11+
12+
## Features
13+
14+
- Feature 1
15+
- Feature 2
16+
- Feature 3
17+
18+
## Requirements
19+
20+
- List any prerequisites or requirements
21+
- Provider-specific requirements (e.g., Docker, AWS credentials)
22+
- Minimum Coder version if applicable
23+
24+
## Usage
25+
26+
1. Step-by-step instructions on how to use this template
27+
2. Any configuration that needs to be done
28+
3. How to customize the template
29+
30+
## Variables
31+
32+
| Name | Description | Type | Default | Required |
33+
| ----------- | --------------------------- | -------- | ----------------- | -------- |
34+
| example_var | Description of the variable | `string` | `"default_value"` | no |
35+
36+
## Resources Created
37+
38+
- List of resources that will be created
39+
- Brief description of each resource
40+
41+
## Customization
42+
43+
Explain how users can customize this template for their needs:
44+
45+
- How to modify the startup script
46+
- How to add additional software
47+
- How to configure different providers
48+
49+
## Troubleshooting
50+
51+
### Common Issues
52+
53+
- Issue 1 and its solution
54+
- Issue 2 and its solution
55+
56+
## Contributing
57+
58+
Contributions are welcome! Please see the [contributing guidelines](../../CONTRIBUTING.md) for more information.

examples/templates/main.tf

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
terraform {
2+
required_providers {
3+
coder = {
4+
source = "coder/coder"
5+
}
6+
# Add your provider here (e.g., docker, aws, gcp, azure)
7+
# docker = {
8+
# source = "kreuzwerker/docker"
9+
# }
10+
}
11+
}
12+
13+
locals {
14+
username = data.coder_workspace_owner.me.name
15+
}
16+
17+
# Add your variables here
18+
# variable "example_var" {
19+
# default = "default_value"
20+
# description = "Description of the variable"
21+
# type = string
22+
# }
23+
24+
# Configure your provider here
25+
# provider "docker" {
26+
# host = var.docker_socket != "" ? var.docker_socket : null
27+
# }
28+
29+
data "coder_provisioner" "me" {}
30+
data "coder_workspace" "me" {}
31+
data "coder_workspace_owner" "me" {}
32+
33+
resource "coder_agent" "main" {
34+
arch = data.coder_provisioner.me.arch
35+
os = "linux"
36+
startup_script = <<-EOT
37+
set -e
38+
39+
# Prepare user home with default files on first start.
40+
if [ ! -f ~/.init_done ]; then
41+
cp -rT /etc/skel ~
42+
touch ~/.init_done
43+
fi
44+
45+
# Add any commands that should be executed at workspace startup here
46+
EOT
47+
48+
# These environment variables allow you to make Git commits right away after creating a
49+
# workspace. Note that they take precedence over configuration defined in ~/.gitconfig!
50+
# You can remove this block if you'd prefer to configure Git manually or using
51+
# dotfiles. (see docs/dotfiles.md)
52+
env = {
53+
GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
54+
GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}"
55+
GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name)
56+
GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}"
57+
}
58+
59+
# The following metadata blocks are optional. They are used to display
60+
# information about your workspace in the dashboard. You can remove them
61+
# if you don't want to display any information.
62+
# For basic templates, you can remove the "display_apps" block.
63+
metadata {
64+
display_name = "CPU Usage"
65+
key = "0_cpu_usage"
66+
script = "coder stat cpu"
67+
interval = 10
68+
timeout = 1
69+
}
70+
71+
metadata {
72+
display_name = "RAM Usage"
73+
key = "1_ram_usage"
74+
script = "coder stat mem"
75+
interval = 10
76+
timeout = 1
77+
}
78+
79+
metadata {
80+
display_name = "Home Disk"
81+
key = "3_home_disk"
82+
script = "coder stat disk --path $${HOME}"
83+
interval = 60
84+
timeout = 1
85+
}
86+
87+
display_apps {
88+
vscode = true
89+
vscode_insiders = false
90+
ssh_helper = false
91+
port_forwarding_helper = true
92+
web_terminal = true
93+
}
94+
}
95+
96+
# Add your resources here (e.g., docker container, VM, etc.)
97+
# resource "docker_image" "main" {
98+
# name = "codercom/enterprise-base:ubuntu"
99+
# }
100+
101+
# resource "docker_container" "workspace" {
102+
# count = data.coder_workspace.me.start_count
103+
# image = docker_image.main.image_id
104+
# # Uses lower() to avoid Docker restriction on container names.
105+
# name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"
106+
# # Hostname makes the shell more user friendly: coder@my-workspace:~$
107+
# hostname = data.coder_workspace.me.name
108+
# # Use the docker gateway if the access URL is 127.0.0.1
109+
# entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\.0\.0\.1/", "host.docker.internal")]
110+
# env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
111+
# host {
112+
# host = "host.docker.internal"
113+
# ip = "host-gateway"
114+
# }
115+
# volumes {
116+
# container_path = "/home/${local.username}"
117+
# volume_name = docker_volume.home_volume[0].name
118+
# read_only = false
119+
# }
120+
# # Add labels in Docker to keep track of orphan resources.
121+
# labels {
122+
# label = "coder.owner"
123+
# value = data.coder_workspace_owner.me.name
124+
# }
125+
# labels {
126+
# label = "coder.owner_id"
127+
# value = data.coder_workspace_owner.me.id
128+
# }
129+
# labels {
130+
# label = "coder.workspace_id"
131+
# value = data.coder_workspace.me.id
132+
# }
133+
# labels {
134+
# label = "coder.workspace_name"
135+
# value = data.coder_workspace.me.name
136+
# }
137+
# }
138+
139+
# resource "docker_volume" "home_volume" {
140+
# count = data.coder_workspace.me.start_count
141+
# name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}-home"
142+
# # Protect the volume from being deleted due to changes in attributes.
143+
# lifecycle {
144+
# ignore_changes = all
145+
# }
146+
# # Add labels in Docker to keep track of orphan resources.
147+
# labels {
148+
# label = "coder.owner"
149+
# value = data.coder_workspace_owner.me.name
150+
# }
151+
# labels {
152+
# label = "coder.owner_id"
153+
# value = data.coder_workspace_owner.me.id
154+
# }
155+
# labels {
156+
# label = "coder.workspace_id"
157+
# value = data.coder_workspace.me.id
158+
# }
159+
# labels {
160+
# label = "coder.workspace_name"
161+
# value = data.coder_workspace.me.name
162+
# }
163+
# }
164+
165+
resource "coder_metadata" "workspace_info" {
166+
resource_id = coder_agent.main.id
167+
168+
item {
169+
key = "TEMPLATE_NAME"
170+
value = "TEMPLATE_NAME"
171+
}
172+
}

scripts/new_module.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,28 @@ if [ -d "registry/$NAMESPACE/modules/$MODULE_NAME" ]; then
2929
echo "Please choose a different name"
3030
exit 1
3131
fi
32+
33+
# Create namespace directory if it doesn't exist
34+
if [ ! -d "registry/$NAMESPACE" ]; then
35+
echo "Creating namespace directory: registry/$NAMESPACE"
36+
mkdir -p "registry/$NAMESPACE"
37+
38+
# Create namespace README if it doesn't exist
39+
if [ ! -f "registry/$NAMESPACE/README.md" ]; then
40+
echo "Creating namespace README: registry/$NAMESPACE/README.md"
41+
cp "examples/namespace/README.md" "registry/$NAMESPACE/README.md"
42+
43+
# Replace NAMESPACE_NAME placeholder in the README
44+
if [[ "$OSTYPE" == "darwin"* ]]; then
45+
# macOS
46+
sed -i '' "s/NAMESPACE_NAME/${NAMESPACE}/g" "registry/$NAMESPACE/README.md"
47+
else
48+
# Linux
49+
sed -i "s/NAMESPACE_NAME/${NAMESPACE}/g" "registry/$NAMESPACE/README.md"
50+
fi
51+
fi
52+
fi
53+
3254
mkdir -p "registry/${NAMESPACE}/modules/${MODULE_NAME}"
3355

3456
# Copy required files from the example module

scripts/new_template.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env bash
2+
3+
# This script creates a new sample template directory with required files
4+
# Run it like: ./scripts/new_template.sh my-namespace/my-template
5+
6+
TEMPLATE_ARG=$1
7+
8+
# Check if they are in the root directory
9+
if [ ! -d "registry" ]; then
10+
echo "Please run this script from the root directory of the repository"
11+
echo "Usage: ./scripts/new_template.sh <namespace>/<template_name>"
12+
exit 1
13+
fi
14+
15+
# check if template name is in the format <namespace>/<template_name>
16+
if ! [[ "$TEMPLATE_ARG" =~ ^[a-z0-9_-]+/[a-z0-9_-]+$ ]]; then
17+
echo "Template name must be in the format <namespace>/<template_name>"
18+
echo "Usage: ./scripts/new_template.sh <namespace>/<template_name>"
19+
exit 1
20+
fi
21+
22+
# Extract the namespace and template name
23+
NAMESPACE=$(echo "$TEMPLATE_ARG" | cut -d'/' -f1)
24+
TEMPLATE_NAME=$(echo "$TEMPLATE_ARG" | cut -d'/' -f2)
25+
26+
# Check if the template already exists
27+
if [ -d "registry/$NAMESPACE/templates/$TEMPLATE_NAME" ]; then
28+
echo "Template at registry/$NAMESPACE/templates/$TEMPLATE_NAME already exists"
29+
echo "Please choose a different name"
30+
exit 1
31+
fi
32+
33+
# Create namespace directory if it doesn't exist
34+
if [ ! -d "registry/$NAMESPACE" ]; then
35+
echo "Creating namespace directory: registry/$NAMESPACE"
36+
mkdir -p "registry/$NAMESPACE"
37+
38+
# Create namespace README if it doesn't exist
39+
if [ ! -f "registry/$NAMESPACE/README.md" ]; then
40+
echo "Creating namespace README: registry/$NAMESPACE/README.md"
41+
cp "examples/namespace/README.md" "registry/$NAMESPACE/README.md"
42+
43+
# Replace NAMESPACE_NAME placeholder in the README
44+
if [[ "$OSTYPE" == "darwin"* ]]; then
45+
# macOS
46+
sed -i '' "s/NAMESPACE_NAME/${NAMESPACE}/g" "registry/$NAMESPACE/README.md"
47+
else
48+
# Linux
49+
sed -i "s/NAMESPACE_NAME/${NAMESPACE}/g" "registry/$NAMESPACE/README.md"
50+
fi
51+
fi
52+
fi
53+
54+
# Create the template directory structure
55+
mkdir -p "registry/${NAMESPACE}/templates/${TEMPLATE_NAME}"
56+
57+
# Copy required files from the example template
58+
cp -r examples/templates/* "registry/${NAMESPACE}/templates/${TEMPLATE_NAME}/"
59+
60+
# Change to template directory
61+
cd "registry/${NAMESPACE}/templates/${TEMPLATE_NAME}"
62+
63+
# Detect OS and replace placeholders
64+
if [[ "$OSTYPE" == "darwin"* ]]; then
65+
# macOS
66+
sed -i '' "s/TEMPLATE_NAME/${TEMPLATE_NAME}/g" main.tf
67+
sed -i '' "s/TEMPLATE_NAME/${TEMPLATE_NAME}/g" README.md
68+
else
69+
# Linux
70+
sed -i "s/TEMPLATE_NAME/${TEMPLATE_NAME}/g" main.tf
71+
sed -i "s/TEMPLATE_NAME/${TEMPLATE_NAME}/g" README.md
72+
fi
73+
74+
echo "Template scaffolded successfully at registry/${NAMESPACE}/templates/${TEMPLATE_NAME}"
75+
echo "Next steps:"
76+
echo "1. Edit main.tf to add your infrastructure resources"
77+
echo "2. Update README.md with template-specific information"
78+
echo "3. Test your template with 'coder templates push'"
79+
echo "4. Consider adding an icon at .icons/${TEMPLATE_NAME}.svg"

0 commit comments

Comments
 (0)