Skip to content

Commit c1bcb7e

Browse files
authored
feat: port linux server images to extension templates (#556)
1 parent b48797c commit c1bcb7e

File tree

110 files changed

+14559
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+14559
-9
lines changed

api/api/versions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
{
44
"version": "v1",
55
"status": "active",
6-
"release_date": "2025-11-02T07:52:11.101731+05:30",
6+
"release_date": "2025-11-02T13:45:06.273828+05:30",
77
"end_of_life": "0001-01-01T00:00:00Z",
88
"changes": [
99
"Initial API version"

api/doc/openapi.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

api/internal/features/extension/controller/delete_extension.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import (
55

66
"github.com/go-fuego/fuego"
77
"github.com/raghavyuva/nixopus-api/internal/features/logger"
8+
"github.com/raghavyuva/nixopus-api/internal/types"
89
)
910

10-
func (c *ExtensionsController) DeleteFork(ctx fuego.ContextNoBody) (*struct {
11-
Status string `json:"status"`
12-
}, error) {
11+
func (c *ExtensionsController) DeleteFork(ctx fuego.ContextNoBody) (*types.Response, error) {
1312
id := ctx.PathParam("id")
1413
if id == "" {
1514
return nil, fuego.HTTPError{Err: nil, Status: http.StatusBadRequest}
@@ -18,7 +17,5 @@ func (c *ExtensionsController) DeleteFork(ctx fuego.ContextNoBody) (*struct {
1817
c.logger.Log(logger.Error, err.Error(), "")
1918
return nil, fuego.HTTPError{Err: err, Status: http.StatusBadRequest}
2019
}
21-
return &struct {
22-
Status string `json:"status"`
23-
}{Status: "ok"}, nil
20+
return &types.Response{Status: "success", Message: "Fork deleted successfully"}, nil
2421
}

api/internal/features/extension/parser/validate.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ func (p *Parser) isValidCategory(category string) bool {
176176
validCategories := []string{
177177
"Security", "Containers", "Database", "Web Server",
178178
"Maintenance", "Monitoring", "Storage", "Network",
179-
"Development", "Other",
179+
"Development", "Media", "Game", "Utility", "Productivity", "Other",
180+
"Social",
180181
}
181182
for _, valid := range validCategories {
182183
if category == valid {

api/internal/types/extension.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ const (
2020
ExtensionCategoryStorage ExtensionCategory = "Storage"
2121
ExtensionCategoryNetwork ExtensionCategory = "Network"
2222
ExtensionCategoryDevelopment ExtensionCategory = "Development"
23+
ExtensionCategoryMedia ExtensionCategory = "Media"
24+
ExtensionCategoryGame ExtensionCategory = "Game"
25+
ExtensionCategoryUtility ExtensionCategory = "Utility"
2326
ExtensionCategoryOther ExtensionCategory = "Other"
27+
ExtensionCategoryProductivity ExtensionCategory = "Productivity"
28+
ExtensionCategorySocial ExtensionCategory = "Social"
2429
)
2530

2631
type ValidationStatus string

api/migrations/extensions/041_add_media_category_down.sql

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TYPE extension_category ADD VALUE IF NOT EXISTS 'Media';
2+
ALTER TYPE extension_category ADD VALUE IF NOT EXISTS 'Game';
3+
ALTER TYPE extension_category ADD VALUE IF NOT EXISTS 'Utility';
4+
ALTER TYPE extension_category ADD VALUE IF NOT EXISTS 'Productivity';
5+
ALTER TYPE extension_category ADD VALUE IF NOT EXISTS 'Social';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ALTER TABLE extensions
2+
DROP CONSTRAINT IF EXISTS extensions_description_check;
3+
4+
ALTER TABLE extensions
5+
ADD CONSTRAINT extensions_description_check
6+
CHECK (LENGTH(description) BETWEEN 10 AND 500);
7+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ALTER TABLE extensions
2+
DROP CONSTRAINT IF EXISTS extensions_description_check;
3+
4+
ALTER TABLE extensions
5+
ADD CONSTRAINT extensions_description_check
6+
CHECK (LENGTH(description) BETWEEN 10 AND 2000);
7+
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
metadata:
2+
id: "deploy-adguardhome-sync"
3+
name: "AdGuardHome Sync"
4+
description: "AdGuardHome Sync is a tool to synchronize AdGuardHome config to replica instances. It allows you to keep multiple AdGuardHome instances in sync with a master configuration. uses adguardhome-sync image from linuxserver.io"
5+
author: "Nixopus Team"
6+
icon: "🔄"
7+
category: "Network"
8+
type: "install"
9+
version: "1.0.0"
10+
isVerified: false
11+
12+
variables:
13+
image:
14+
type: "string"
15+
description: "Docker image for AdGuardHome Sync"
16+
default: "lscr.io/linuxserver/adguardhome-sync"
17+
is_required: true
18+
19+
tag:
20+
type: "string"
21+
description: "Docker image tag"
22+
default: "latest"
23+
is_required: true
24+
25+
container_name:
26+
type: "string"
27+
description: "Name of the AdGuardHome Sync container"
28+
default: "adguardhome-sync"
29+
is_required: true
30+
31+
host_port:
32+
type: "integer"
33+
description: "Host port to expose AdGuardHome Sync web API"
34+
default: 8080
35+
is_required: true
36+
37+
container_port:
38+
type: "integer"
39+
description: "Container port for AdGuardHome Sync web API"
40+
default: 8080
41+
is_required: true
42+
43+
config_volume_name:
44+
type: "string"
45+
description: "Named Docker volume for AdGuardHome Sync configuration files"
46+
default: "adguardhome-sync-config"
47+
is_required: true
48+
49+
puid:
50+
type: "integer"
51+
description: "User ID for running the container"
52+
default: 1000
53+
is_required: false
54+
55+
pgid:
56+
type: "integer"
57+
description: "Group ID for running the container"
58+
default: 1000
59+
is_required: false
60+
61+
timezone:
62+
type: "string"
63+
description: "Timezone (TZ) environment variable"
64+
default: "Etc/UTC"
65+
is_required: false
66+
67+
config_file:
68+
type: "string"
69+
description: "Path to the config file inside the container"
70+
default: "/config/adguardhome-sync.yaml"
71+
is_required: false
72+
73+
proxy_domain:
74+
type: "string"
75+
description: "Domain name for AdGuardHome Sync (optional)"
76+
default: ""
77+
is_required: false
78+
79+
execution:
80+
run:
81+
- name: "Remove existing AdGuardHome Sync container if present"
82+
type: "docker"
83+
properties:
84+
action: "rm"
85+
name: "{{ container_name }}"
86+
timeout: 30
87+
88+
- name: "Pull AdGuardHome Sync image"
89+
type: "docker"
90+
properties:
91+
action: "pull"
92+
image: "{{ image }}"
93+
tag: "{{ tag }}"
94+
timeout: 300
95+
96+
- name: "Run AdGuardHome Sync container"
97+
type: "docker"
98+
properties:
99+
action: "run"
100+
name: "{{ container_name }}"
101+
image: "{{ image }}"
102+
tag: "{{ tag }}"
103+
ports: "{{ host_port }}:{{ container_port }}"
104+
volumes:
105+
- "{{ config_volume_name }}:/config"
106+
env:
107+
PUID: "{{ puid }}"
108+
PGID: "{{ pgid }}"
109+
TZ: "{{ timezone }}"
110+
CONFIGFILE: "{{ config_file }}"
111+
restart: "unless-stopped"
112+
timeout: 120
113+
114+
- name: "Add proxy for AdGuardHome Sync"
115+
type: "proxy"
116+
properties:
117+
action: "add"
118+
domain: "{{ proxy_domain }}"
119+
port: "{{ host_port }}"
120+
timeout: 30
121+
122+
# validate:
123+
# - name: "Check AdGuardHome Sync web API is accessible"
124+
# type: "command"
125+
# properties:
126+
# cmd: "sh -c 'for i in $(seq 1 30); do code=$(curl -fsS -o /dev/null -w \"%{http_code}\\n\" http://localhost:{{ host_port }} || true); echo \"HTTP $code\"; echo $code | grep -E \"^(200|301|302)$\" && exit 0; sleep 2; done; exit 1'"
127+
# timeout: 60
128+

0 commit comments

Comments
 (0)