Skip to content

Commit ececb2e

Browse files
committed
Add initial remote registry with inmemory store
1 parent 457df6a commit ececb2e

File tree

10 files changed

+657
-1
lines changed

10 files changed

+657
-1
lines changed

build.sh

+6
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@ VERSION=${1:-$DEFAULT_VERSION}
66
APP_NAME=${2:-cdt}
77
APP_LONG_NAME=${3:-Criteo Dev Toolkit}
88

9+
# build the command
910
go build -o $APP_NAME -ldflags="-X main.version=$VERSION -X main.buildNum=$(date +'%Y%m%d-%H%M%S') -X main.appName=$APP_NAME -X 'main.appLongName=$APP_LONG_NAME'"
11+
12+
# build the remote registry
13+
go build -o $APP_NAME-registry \
14+
-ldflags="-X main.version=$VERSION -X main.buildNum=$(date +'%Y%m%d-%H%M%S') -X main.appName=$APP_NAME-registry -X 'main.appLongName=$APP_LONG_NAME Remote Registry'" \
15+
remote-registry/main.go

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/criteo/command-launcher
22

3-
go 1.20
3+
go 1.22
44

55
require (
66
github.com/cavaliergopher/grab/v3 v3.0.1

remote-registry/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Command Launcher Remote Registry

remote-registry/handlers/index.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package handlers
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"strings"
8+
9+
"github.com/criteo/command-launcher/internal/remote"
10+
. "github.com/criteo/command-launcher/remote-registry/store"
11+
)
12+
13+
type Controller struct {
14+
store Store
15+
}
16+
17+
func NewController(store Store) *Controller {
18+
return &Controller{
19+
store: store,
20+
}
21+
}
22+
23+
func (c Controller) HomePageHandler(w http.ResponseWriter, r *http.Request) {
24+
regs, _ := c.store.AllRegistries()
25+
names := make([]string, 0)
26+
for _, reg := range regs {
27+
names = append(names, reg.Name)
28+
}
29+
output := strings.Join(names, ", ")
30+
w.Write(fmt.Appendf(nil, "Available registries: %s", output))
31+
}
32+
33+
// GET /registry/{registry}/index.json
34+
func (c Controller) IndexHandler(w http.ResponseWriter, r *http.Request) {
35+
// Extract the registry name from the URL
36+
registryName := r.PathValue("registry")
37+
if registryName == "" {
38+
http.Error(w,
39+
"Registry name is required",
40+
http.StatusBadRequest)
41+
return
42+
}
43+
pkgs, err := c.store.AllPackagesFromRegistry(registryName)
44+
if err != nil {
45+
http.Error(w,
46+
fmt.Sprintf("Failed to get packages from registry %s: %s", registryName, err),
47+
http.StatusInternalServerError)
48+
return
49+
}
50+
allVersions := make([]remote.PackageInfo, 0)
51+
for _, pkg := range pkgs {
52+
allVersions = append(allVersions, pkg.Versions...)
53+
}
54+
b, err := json.Marshal(allVersions)
55+
w.Write(b)
56+
}
57+
58+
func (c Controller) RegistryHandler(w http.ResponseWriter, r *http.Request) {
59+
w.Write([]byte("Registry Handler"))
60+
}
61+
62+
func (c Controller) PackageHandler(w http.ResponseWriter, r *http.Request) {
63+
w.Write([]byte("Package Handler"))
64+
}
65+
66+
func (c Controller) PackageVersionHandler(w http.ResponseWriter, r *http.Request) {
67+
w.Write([]byte("Package Version Handler"))
68+
}

remote-registry/main.go

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
7+
remote "github.com/criteo/command-launcher/internal/remote"
8+
handlers "github.com/criteo/command-launcher/remote-registry/handlers"
9+
model "github.com/criteo/command-launcher/remote-registry/model"
10+
. "github.com/criteo/command-launcher/remote-registry/store"
11+
)
12+
13+
func main() {
14+
// create a new in-memory store
15+
store := NewInMemoryStore()
16+
initStore(store)
17+
18+
// create a controller instance by specifying the store
19+
controller := handlers.NewController(store)
20+
21+
mux := http.NewServeMux()
22+
// Home Page
23+
mux.HandleFunc("/", controller.HomePageHandler)
24+
// GET the remote registry index
25+
mux.HandleFunc("/registry/{registry}/index.json", controller.IndexHandler)
26+
27+
mux.HandleFunc("/registry", controller.RegistryHandler)
28+
mux.HandleFunc("/registry/{registry}", controller.RegistryHandler)
29+
mux.HandleFunc("/registry/{registry}/package", controller.PackageHandler)
30+
mux.HandleFunc("/registry/{registry}/package/{package}", controller.PackageHandler)
31+
mux.HandleFunc("/registry/{registry}/package/{package}/version", controller.PackageVersionHandler)
32+
mux.HandleFunc("/registry/{registry}/package/{package}/version/{version}", controller.PackageVersionHandler)
33+
34+
log.Println("Starting server on :8080")
35+
log.Fatal(http.ListenAndServe(":8080", mux))
36+
}
37+
38+
func initStore(store Store) {
39+
// put some example data in the store
40+
store.NewRegistry("test-registry", model.RegistryMetadata{
41+
Name: "test-registry",
42+
Description: "Test Registry",
43+
Admin: []string{"a", "b"},
44+
CustomValues: map[string]string{"key": "value"},
45+
})
46+
// test-registry
47+
store.NewPackage("test-registry", "test-package", model.PackageMetadata{
48+
Name: "test-package",
49+
Description: "Test Package",
50+
Admin: []string{"a", "b"},
51+
CustomValues: map[string]string{"key": "value"},
52+
})
53+
store.NewPackageVersion("test-registry", "test-package", "1.0.0", remote.PackageInfo{
54+
Name: "test-package",
55+
Version: "1.0.0",
56+
Url: "http://example.com/test-package-1.0.0.tar.gz",
57+
Checksum: "abc123",
58+
StartPartition: 0,
59+
EndPartition: 9,
60+
})
61+
store.NewPackageVersion("test-registry", "test-package", "1.1.0", remote.PackageInfo{
62+
Name: "test-package",
63+
Version: "1.1.0",
64+
Url: "http://example.com/test-package-1.1.0.tar.gz",
65+
Checksum: "abc456",
66+
StartPartition: 0,
67+
EndPartition: 9,
68+
})
69+
70+
// test-registry-2
71+
store.NewRegistry("test-registry-2", model.RegistryMetadata{
72+
Name: "test-registry-2",
73+
Description: "Test Registry 2",
74+
Admin: []string{"a", "b"},
75+
CustomValues: map[string]string{"key": "value"},
76+
})
77+
store.NewPackage("test-registry-2", "test-package-2", model.PackageMetadata{
78+
Name: "test-package-2",
79+
Description: "Test Package 2",
80+
Admin: []string{"a", "b"},
81+
CustomValues: map[string]string{"key": "value"},
82+
})
83+
store.NewPackageVersion("test-registry-2", "test-package-2", "1.0.0", remote.PackageInfo{
84+
Name: "test-package-2",
85+
Version: "1.0.0",
86+
Url: "http://example.com/test-package-2-1.0.0.tar.gz",
87+
Checksum: "abc123",
88+
StartPartition: 0,
89+
EndPartition: 9,
90+
})
91+
92+
regs, _ := store.AllRegistries()
93+
log.Printf("Store initialized with example data, number of registries: %d\n", len(regs))
94+
}

remote-registry/model/index.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package model
2+
3+
import (
4+
remote "github.com/criteo/command-launcher/internal/remote"
5+
)
6+
7+
type RegistryMetadata struct {
8+
Name string `json:"name"`
9+
Description string `json:"description"`
10+
Admin []string `json:"admin"`
11+
CustomValues map[string]string `json:"customValues"`
12+
}
13+
14+
type Registry struct {
15+
RegistryMetadata
16+
Packages map[string]Package `json:"packages"`
17+
}
18+
19+
type PackageMetadata struct {
20+
Name string `json:"name"`
21+
Description string `json:"description"`
22+
Admin []string `json:"admin"`
23+
CustomValues map[string]string `json:"customValues"`
24+
}
25+
26+
type Package struct {
27+
PackageMetadata
28+
Versions []remote.PackageInfo `json:"versions"`
29+
}

remote-registry/store/api.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package store
2+
3+
import (
4+
remote "github.com/criteo/command-launcher/internal/remote"
5+
model "github.com/criteo/command-launcher/remote-registry/model"
6+
)
7+
8+
type Store interface {
9+
AllRegistries() ([]model.Registry, error)
10+
NewRegistry(name string, registryInfo model.RegistryMetadata) error
11+
UpdateRegistry(name string, registryInfo model.RegistryMetadata) error
12+
DeleteRegistry(name string) error
13+
14+
AllPackagesFromRegistry(registryName string) ([]model.Package, error)
15+
NewPackage(registryName string, packageName string, packageInfo model.PackageMetadata) error
16+
UpdatePackage(registryName string, packageName string, packageInfo model.PackageMetadata) error
17+
DeletePackage(registryName string, packageName string) error
18+
19+
AllPackageVersionsFromRegistry(registryName string, packageName string) ([]remote.PackageInfo, error)
20+
NewPackageVersion(registryName string, packageName string, version string, packageInfo remote.PackageInfo) error
21+
DeletePackageVersion(registryName string, packageName string, version string) error
22+
}

remote-registry/store/error.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package store
2+
3+
import "errors"
4+
5+
var (
6+
RegistryAlreadyExistsError = errors.New("registry already exists")
7+
RegistryDoesNotExistError = errors.New("registry does not exist")
8+
RegistryNameMismatchError = errors.New("registry name mismatch")
9+
PackageAlreadyExistsError = errors.New("package already exists")
10+
PackageDoesNotExistError = errors.New("package does not exist")
11+
PackageNameMismatchError = errors.New("package name mismatch")
12+
PackageVersionAlreadyExistsError = errors.New("package version already exists")
13+
PackageVersionDoesNotExistError = errors.New("package version does not exist")
14+
)

0 commit comments

Comments
 (0)