mirror of
https://github.com/m1k1o/neko-rooms.git
synced 2026-11-02 22:51:34 -06:00
add labels filter support to API.
This commit is contained in:
+15
@@ -33,6 +33,13 @@ paths:
|
|||||||
- rooms
|
- rooms
|
||||||
summary: List all rooms
|
summary: List all rooms
|
||||||
operationId: roomsList
|
operationId: roomsList
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: labels
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
@@ -318,6 +325,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
format: datetime
|
format: datetime
|
||||||
example: "2021-03-07T21:56:34Z"
|
example: "2021-03-07T21:56:34Z"
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
|
||||||
RoomMount:
|
RoomMount:
|
||||||
type: object
|
type: object
|
||||||
@@ -415,6 +426,10 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
example:
|
example:
|
||||||
CUSTOM_ENV: custom value
|
CUSTOM_ENV: custom value
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
mounts:
|
mounts:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
|||||||
+29
-7
@@ -272,6 +272,12 @@ export interface RoomEntry {
|
|||||||
* @memberof RoomEntry
|
* @memberof RoomEntry
|
||||||
*/
|
*/
|
||||||
'created'?: string;
|
'created'?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {{ [key: string]: string; }}
|
||||||
|
* @memberof RoomEntry
|
||||||
|
*/
|
||||||
|
'labels'?: { [key: string]: string; };
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -490,6 +496,12 @@ export interface RoomSettings {
|
|||||||
* @memberof RoomSettings
|
* @memberof RoomSettings
|
||||||
*/
|
*/
|
||||||
'envs'?: { [key: string]: string; };
|
'envs'?: { [key: string]: string; };
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {{ [key: string]: string; }}
|
||||||
|
* @memberof RoomSettings
|
||||||
|
*/
|
||||||
|
'labels'?: { [key: string]: string; };
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @type {Array<RoomMount>}
|
* @type {Array<RoomMount>}
|
||||||
@@ -1248,10 +1260,11 @@ export const RoomsApiAxiosParamCreator = function (configuration?: Configuration
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary List all rooms
|
* @summary List all rooms
|
||||||
|
* @param {{ [key: string]: string; }} [labels]
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
roomsList: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
roomsList: async (labels?: { [key: string]: string; }, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||||
const localVarPath = `/api/rooms`;
|
const localVarPath = `/api/rooms`;
|
||||||
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||||
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
|
||||||
@@ -1264,6 +1277,12 @@ export const RoomsApiAxiosParamCreator = function (configuration?: Configuration
|
|||||||
const localVarHeaderParameter = {} as any;
|
const localVarHeaderParameter = {} as any;
|
||||||
const localVarQueryParameter = {} as any;
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
if (labels !== undefined) {
|
||||||
|
for (let param of Object.keys(labels)) {
|
||||||
|
localVarQueryParameter[param] = labels?.[param];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
||||||
@@ -1387,11 +1406,12 @@ export const RoomsApiFp = function(configuration?: Configuration) {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary List all rooms
|
* @summary List all rooms
|
||||||
|
* @param {{ [key: string]: string; }} [labels]
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
async roomsList(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<RoomEntry>>> {
|
async roomsList(labels?: { [key: string]: string; }, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<RoomEntry>>> {
|
||||||
const localVarAxiosArgs = await localVarAxiosParamCreator.roomsList(options);
|
const localVarAxiosArgs = await localVarAxiosParamCreator.roomsList(labels, options);
|
||||||
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -1497,11 +1517,12 @@ export const RoomsApiFactory = function (configuration?: Configuration, basePath
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary List all rooms
|
* @summary List all rooms
|
||||||
|
* @param {{ [key: string]: string; }} [labels]
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
*/
|
*/
|
||||||
roomsList(options?: any): AxiosPromise<Array<RoomEntry>> {
|
roomsList(labels?: { [key: string]: string; }, options?: any): AxiosPromise<Array<RoomEntry>> {
|
||||||
return localVarFp.roomsList(options).then((request) => request(axios, basePath));
|
return localVarFp.roomsList(labels, options).then((request) => request(axios, basePath));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1624,12 +1645,13 @@ export class RoomsApi extends BaseAPI {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary List all rooms
|
* @summary List all rooms
|
||||||
|
* @param {{ [key: string]: string; }} [labels]
|
||||||
* @param {*} [options] Override http request option.
|
* @param {*} [options] Override http request option.
|
||||||
* @throws {RequiredError}
|
* @throws {RequiredError}
|
||||||
* @memberof RoomsApi
|
* @memberof RoomsApi
|
||||||
*/
|
*/
|
||||||
public roomsList(options?: AxiosRequestConfig) {
|
public roomsList(labels?: { [key: string]: string; }, options?: AxiosRequestConfig) {
|
||||||
return RoomsApiFp(this.configuration).roomsList(options).then((request) => request(this.axios, this.basePath));
|
return RoomsApiFp(this.configuration).roomsList(labels, options).then((request) => request(this.axios, this.basePath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -156,14 +156,27 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-simple-table>
|
</v-simple-table>
|
||||||
|
|
||||||
<div class="my-3 headline">Mounts</div>
|
<template v-if="settings.labels && Object.keys(settings.labels).length > 0">
|
||||||
<v-simple-table>
|
<div class="my-3 headline">Labels</div>
|
||||||
<template v-slot:default>
|
<v-simple-table>
|
||||||
<tbody>
|
<template v-slot:default>
|
||||||
<tr v-for="({ type, host_path, container_path }, index) in settings.mounts" :key="index"><td style="width:50%;">{{ host_path }} <v-chip small>{{ type }}</v-chip></td><td>{{ container_path }}</td></tr>
|
<tbody>
|
||||||
</tbody>
|
<tr v-for="(val, key) in settings.labels" :key="key"><th style="width:50%;">{{ key }}</th><td>{{ val }}</td></tr>
|
||||||
</template>
|
</tbody>
|
||||||
</v-simple-table>
|
</template>
|
||||||
|
</v-simple-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="settings.mounts && settings.mounts.length > 0">
|
||||||
|
<div class="my-3 headline">Mounts</div>
|
||||||
|
<v-simple-table>
|
||||||
|
<template v-slot:default>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="({ type, host_path, container_path }, index) in settings.mounts" :key="index"><td style="width:50%;">{{ host_path }} <v-chip small>{{ type }}</v-chip></td><td>{{ container_path }}</td></tr>
|
||||||
|
</tbody>
|
||||||
|
</template>
|
||||||
|
</v-simple-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="my-3 headline">Resources</div>
|
<div class="my-3 headline">Resources</div>
|
||||||
<v-simple-table>
|
<v-simple-table>
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# custom labels
|
# custom labels
|
||||||
|
|
||||||
You can add custom lables for every room.
|
You can add custom labels for every room.
|
||||||
|
|
||||||
Example: Expose port 3000 from every room under `3000-(room-name)`:
|
Example: Expose port 3000 from every room under `3000-(room-name)`:
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -3,14 +3,28 @@ package api
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
|
||||||
|
"github.com/m1k1o/neko-rooms/internal/room"
|
||||||
"github.com/m1k1o/neko-rooms/internal/types"
|
"github.com/m1k1o/neko-rooms/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (manager *ApiManagerCtx) roomsList(w http.ResponseWriter, r *http.Request) {
|
func (manager *ApiManagerCtx) roomsList(w http.ResponseWriter, r *http.Request) {
|
||||||
response, err := manager.rooms.List()
|
labelsMap := map[string]string{}
|
||||||
|
for key, value := range r.URL.Query() {
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
|
||||||
|
if !room.CheckLabelKey(key) {
|
||||||
|
http.Error(w, "invalid label name, allowed characters: [a-z0-9.-]", 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
labelsMap[key] = value[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := manager.rooms.List(labelsMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), 500)
|
http.Error(w, err.Error(), 500)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ func (manager *RoomManagerCtx) containerToEntry(container dockerTypes.Container)
|
|||||||
Running: container.State == "running",
|
Running: container.State == "running",
|
||||||
Status: container.Status,
|
Status: container.Status,
|
||||||
Created: time.Unix(container.Created, 0),
|
Created: time.Unix(container.Created, 0),
|
||||||
|
Labels: labels.UserDefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
if labels.Mux {
|
if labels.Mux {
|
||||||
@@ -37,35 +38,23 @@ func (manager *RoomManagerCtx) containerToEntry(container dockerTypes.Container)
|
|||||||
return entry, nil
|
return entry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *RoomManagerCtx) listContainers() ([]dockerTypes.Container, error) {
|
func (manager *RoomManagerCtx) listContainers(labels map[string]string) ([]dockerTypes.Container, error) {
|
||||||
args := filters.NewArgs(
|
args := filters.NewArgs(
|
||||||
filters.Arg("label", "m1k1o.neko_rooms.instance"),
|
filters.Arg("label", fmt.Sprintf("m1k1o.neko_rooms.instance=%s", manager.config.InstanceName)),
|
||||||
)
|
)
|
||||||
|
|
||||||
containers, err := manager.client.ContainerList(context.Background(), dockerTypes.ContainerListOptions{
|
for key, val := range labels {
|
||||||
|
args.Add("label", fmt.Sprintf("m1k1o.neko_rooms.x-%s=%s", key, val))
|
||||||
|
}
|
||||||
|
|
||||||
|
return manager.client.ContainerList(context.Background(), dockerTypes.ContainerListOptions{
|
||||||
All: true,
|
All: true,
|
||||||
Filters: args,
|
Filters: args,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := []dockerTypes.Container{}
|
|
||||||
for _, container := range containers {
|
|
||||||
val, ok := container.Labels["m1k1o.neko_rooms.instance"]
|
|
||||||
if !ok || val != manager.config.InstanceName {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
result = append(result, container)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *RoomManagerCtx) containerFilter(args filters.Args) (*dockerTypes.Container, error) {
|
func (manager *RoomManagerCtx) containerFilter(args filters.Args) (*dockerTypes.Container, error) {
|
||||||
args.Add("label", "m1k1o.neko_rooms.instance")
|
args.Add("label", fmt.Sprintf("m1k1o.neko_rooms.instance=%s", manager.config.InstanceName))
|
||||||
|
|
||||||
containers, err := manager.client.ContainerList(context.Background(), dockerTypes.ContainerListOptions{
|
containers, err := manager.client.ContainerList(context.Background(), dockerTypes.ContainerListOptions{
|
||||||
All: true,
|
All: true,
|
||||||
@@ -81,12 +70,6 @@ func (manager *RoomManagerCtx) containerFilter(args filters.Args) (*dockerTypes.
|
|||||||
}
|
}
|
||||||
|
|
||||||
container := containers[0]
|
container := containers[0]
|
||||||
|
|
||||||
val, ok := container.Labels["m1k1o.neko_rooms.instance"]
|
|
||||||
if !ok || val != manager.config.InstanceName {
|
|
||||||
return nil, fmt.Errorf("this container does not belong to neko_rooms")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &container, nil
|
return &container, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ package room
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/m1k1o/neko-rooms/internal/types"
|
"github.com/m1k1o/neko-rooms/internal/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var labelRegex = regexp.MustCompile(`^[a-z0-9.-]+$`)
|
||||||
|
|
||||||
type RoomLabels struct {
|
type RoomLabels struct {
|
||||||
Name string
|
Name string
|
||||||
URL string
|
URL string
|
||||||
@@ -15,6 +19,7 @@ type RoomLabels struct {
|
|||||||
NekoImage string
|
NekoImage string
|
||||||
|
|
||||||
BrowserPolicy *BrowserPolicyLabels
|
BrowserPolicy *BrowserPolicyLabels
|
||||||
|
UserDefined map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type BrowserPolicyLabels struct {
|
type BrowserPolicyLabels struct {
|
||||||
@@ -101,6 +106,14 @@ func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract user defined labels
|
||||||
|
userDefined := map[string]string{}
|
||||||
|
for key, val := range labels {
|
||||||
|
if strings.HasPrefix(key, "m1k1o.neko_rooms.x-") {
|
||||||
|
userDefined[strings.TrimPrefix(key, "m1k1o.neko_rooms.x-")] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &RoomLabels{
|
return &RoomLabels{
|
||||||
Name: name,
|
Name: name,
|
||||||
URL: url,
|
URL: url,
|
||||||
@@ -109,6 +122,7 @@ func (manager *RoomManagerCtx) extractLabels(labels map[string]string) (*RoomLab
|
|||||||
Epr: epr,
|
Epr: epr,
|
||||||
|
|
||||||
BrowserPolicy: browserPolicy,
|
BrowserPolicy: browserPolicy,
|
||||||
|
UserDefined: userDefined,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,5 +147,16 @@ func (manager *RoomManagerCtx) serializeLabels(labels RoomLabels) map[string]str
|
|||||||
labelsMap["m1k1o.neko_rooms.browser_policy.path"] = labels.BrowserPolicy.Path
|
labelsMap["m1k1o.neko_rooms.browser_policy.path"] = labels.BrowserPolicy.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for key, val := range labels.UserDefined {
|
||||||
|
// to lowercase
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
|
||||||
|
labelsMap[fmt.Sprintf("m1k1o.neko_rooms.x-%s", key)] = val
|
||||||
|
}
|
||||||
|
|
||||||
return labelsMap
|
return labelsMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckLabelKey(name string) bool {
|
||||||
|
return labelRegex.MatchString(name)
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -62,13 +63,13 @@ func (manager *RoomManagerCtx) Config() types.RoomsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *RoomManagerCtx) List() ([]types.RoomEntry, error) {
|
func (manager *RoomManagerCtx) List(labels map[string]string) ([]types.RoomEntry, error) {
|
||||||
containers, err := manager.listContainers()
|
containers, err := manager.listContainers(labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := []types.RoomEntry{}
|
result := make([]types.RoomEntry, 0, len(containers))
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
entry, err := manager.containerToEntry(container)
|
entry, err := manager.containerToEntry(container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -174,6 +175,7 @@ func (manager *RoomManagerCtx) Create(settings types.RoomSettings) (string, erro
|
|||||||
NekoImage: settings.NekoImage,
|
NekoImage: settings.NekoImage,
|
||||||
|
|
||||||
BrowserPolicy: browserPolicyLabels,
|
BrowserPolicy: browserPolicyLabels,
|
||||||
|
UserDefined: settings.Labels,
|
||||||
})
|
})
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -652,9 +654,10 @@ func (manager *RoomManagerCtx) GetSettings(id string) (*types.RoomSettings, erro
|
|||||||
Name: labels.Name,
|
Name: labels.Name,
|
||||||
NekoImage: labels.NekoImage,
|
NekoImage: labels.NekoImage,
|
||||||
MaxConnections: labels.Epr.Max - labels.Epr.Min + 1,
|
MaxConnections: labels.Epr.Max - labels.Epr.Min + 1,
|
||||||
|
Labels: labels.UserDefined,
|
||||||
Mounts: mounts,
|
Mounts: mounts,
|
||||||
BrowserPolicy: browserPolicy,
|
|
||||||
Resources: roomResources,
|
Resources: roomResources,
|
||||||
|
BrowserPolicy: browserPolicy,
|
||||||
}
|
}
|
||||||
|
|
||||||
if labels.Mux {
|
if labels.Mux {
|
||||||
@@ -678,7 +681,7 @@ func (manager *RoomManagerCtx) GetStats(id string) (*types.RoomStats, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output, err := manager.containerExec(id, []string{
|
output, err := manager.containerExec(id, []string{
|
||||||
"wget", "-q", "-O-", "http://127.0.0.1:8080/stats?pwd=" + settings.AdminPass,
|
"wget", "-q", "-O-", "http://127.0.0.1:8080/stats?pwd=" + url.QueryEscape(settings.AdminPass),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func (manager *RoomManagerCtx) allocatePorts(sum uint16) (EprPorts, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (manager *RoomManagerCtx) getUsedPorts() ([]EprPorts, error) {
|
func (manager *RoomManagerCtx) getUsedPorts() ([]EprPorts, error) {
|
||||||
containers, err := manager.listContainers()
|
containers, err := manager.listContainers(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-10
@@ -35,15 +35,16 @@ type RoomsConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RoomEntry struct {
|
type RoomEntry struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
NekoImage string `json:"neko_image"`
|
NekoImage string `json:"neko_image"`
|
||||||
IsOutdated bool `json:"is_outdated"`
|
IsOutdated bool `json:"is_outdated"`
|
||||||
MaxConnections uint16 `json:"max_connections"` // 0 when using mux
|
MaxConnections uint16 `json:"max_connections"` // 0 when using mux
|
||||||
Running bool `json:"running"`
|
Running bool `json:"running"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MountType string
|
type MountType string
|
||||||
@@ -94,6 +95,7 @@ type RoomSettings struct {
|
|||||||
BroadcastPipeline string `json:"broadcast_pipeline,omitempty"`
|
BroadcastPipeline string `json:"broadcast_pipeline,omitempty"`
|
||||||
|
|
||||||
Envs map[string]string `json:"envs"`
|
Envs map[string]string `json:"envs"`
|
||||||
|
Labels map[string]string `json:"labels"`
|
||||||
Mounts []RoomMount `json:"mounts"`
|
Mounts []RoomMount `json:"mounts"`
|
||||||
Resources RoomResources `json:"resources"`
|
Resources RoomResources `json:"resources"`
|
||||||
|
|
||||||
@@ -280,7 +282,7 @@ type RoomMember struct {
|
|||||||
|
|
||||||
type RoomManager interface {
|
type RoomManager interface {
|
||||||
Config() RoomsConfig
|
Config() RoomsConfig
|
||||||
List() ([]RoomEntry, error)
|
List(labels map[string]string) ([]RoomEntry, error)
|
||||||
FindByName(name string) (*RoomEntry, error)
|
FindByName(name string) (*RoomEntry, error)
|
||||||
|
|
||||||
Create(settings RoomSettings) (string, error)
|
Create(settings RoomSettings) (string, error)
|
||||||
|
|||||||
Reference in New Issue
Block a user