Respect domain in cluster DB, allow metadata in process config for cluster
This commit is contained in:
parent
1689f3f7db
commit
8829b8fff0
@ -1493,7 +1493,7 @@ func probeInput(binary string, config app.Config) app.Probe {
|
||||
|
||||
rs.AddProcess(&config)
|
||||
|
||||
id := restream.TaskID{ID: config.ID}
|
||||
id := config.ProcessID()
|
||||
probe := rs.Probe(id)
|
||||
rs.DeleteProcess(id)
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
mwlog "github.com/datarhei/core/v16/http/middleware/log"
|
||||
"github.com/datarhei/core/v16/http/validator"
|
||||
"github.com/datarhei/core/v16/log"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
@ -161,6 +162,7 @@ func NewAPI(config APIConfig) (API, error) {
|
||||
|
||||
a.router.DELETE("/v1/process/:id", func(c echo.Context) error {
|
||||
id := util.PathParam(c, "id")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
origin := c.Request().Header.Get("X-Cluster-Origin")
|
||||
|
||||
@ -168,11 +170,13 @@ func NewAPI(config APIConfig) (API, error) {
|
||||
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
|
||||
}
|
||||
|
||||
a.logger.Debug().WithField("id", id).Log("Remove process request")
|
||||
pid := app.ProcessID{ID: id, Domain: domain}
|
||||
|
||||
err := a.cluster.RemoveProcess(origin, id)
|
||||
a.logger.Debug().WithField("id", pid).Log("Remove process request")
|
||||
|
||||
err := a.cluster.RemoveProcess(origin, pid)
|
||||
if err != nil {
|
||||
a.logger.Debug().WithError(err).WithField("id", id).Log("Unable to remove process")
|
||||
a.logger.Debug().WithError(err).WithField("id", pid).Log("Unable to remove process")
|
||||
return httpapi.Err(http.StatusInternalServerError, "unable to remove process", "%s", err)
|
||||
}
|
||||
|
||||
@ -181,6 +185,7 @@ func NewAPI(config APIConfig) (API, error) {
|
||||
|
||||
a.router.PUT("/v1/process/:id", func(c echo.Context) error {
|
||||
id := util.PathParam(c, "id")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
r := client.UpdateProcessRequest{}
|
||||
|
||||
@ -194,13 +199,15 @@ func NewAPI(config APIConfig) (API, error) {
|
||||
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
|
||||
}
|
||||
|
||||
if id != r.ID {
|
||||
pid := app.ProcessID{ID: id, Domain: domain}
|
||||
|
||||
if !pid.Equals(r.ID) {
|
||||
return httpapi.Err(http.StatusBadRequest, "Invalid data", "the ID in the path and the request do not match")
|
||||
}
|
||||
|
||||
a.logger.Debug().WithFields(log.Fields{
|
||||
"old_id": r.ID,
|
||||
"new_id": r.Config.ID,
|
||||
"new_id": r.Config.ProcessID(),
|
||||
}).Log("Update process request")
|
||||
|
||||
err := a.cluster.UpdateProcess(origin, r.ID, &r.Config)
|
||||
@ -215,6 +222,7 @@ func NewAPI(config APIConfig) (API, error) {
|
||||
a.router.PUT("/v1/process/:id/metadata/:key", func(c echo.Context) error {
|
||||
id := util.PathParam(c, "id")
|
||||
key := util.PathParam(c, "key")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
r := client.SetProcessMetadataRequest{}
|
||||
|
||||
@ -228,7 +236,9 @@ func NewAPI(config APIConfig) (API, error) {
|
||||
return httpapi.Err(http.StatusLoopDetected, "", "breaking circuit")
|
||||
}
|
||||
|
||||
err := a.cluster.SetProcessMetadata(origin, id, key, r.Metadata)
|
||||
pid := app.ProcessID{ID: id, Domain: domain}
|
||||
|
||||
err := a.cluster.SetProcessMetadata(origin, pid, key, r.Metadata)
|
||||
if err != nil {
|
||||
a.logger.Debug().WithError(err).WithField("id", r.ID).Log("Unable to update metadata")
|
||||
return httpapi.Err(http.StatusInternalServerError, "unable to update metadata", "%s", err)
|
||||
|
||||
@ -28,14 +28,14 @@ type AddProcessRequest struct {
|
||||
}
|
||||
|
||||
type UpdateProcessRequest struct {
|
||||
ID string `json:"id"`
|
||||
Config app.Config `json:"config"`
|
||||
ID app.ProcessID `json:"id"`
|
||||
Config app.Config `json:"config"`
|
||||
}
|
||||
|
||||
type SetProcessMetadataRequest struct {
|
||||
ID string `json:"id"`
|
||||
Key string `json:"key"`
|
||||
Metadata interface{} `json:"metadata"`
|
||||
ID app.ProcessID `json:"id"`
|
||||
Key string `json:"key"`
|
||||
Metadata interface{} `json:"metadata"`
|
||||
}
|
||||
|
||||
type AddIdentityRequest struct {
|
||||
@ -100,8 +100,8 @@ func (c *APIClient) AddProcess(origin string, r AddProcessRequest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *APIClient) RemoveProcess(origin string, id string) error {
|
||||
_, err := c.call(http.MethodDelete, "/process/"+id, "application/json", nil, origin)
|
||||
func (c *APIClient) RemoveProcess(origin string, id app.ProcessID) error {
|
||||
_, err := c.call(http.MethodDelete, "/process/"+id.ID+"?domain="+id.Domain, "application/json", nil, origin)
|
||||
|
||||
return err
|
||||
}
|
||||
@ -112,7 +112,7 @@ func (c *APIClient) UpdateProcess(origin string, r UpdateProcessRequest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = c.call(http.MethodPut, "/process/"+r.ID, "application/json", bytes.NewReader(data), origin)
|
||||
_, err = c.call(http.MethodPut, "/process/"+r.ID.ID+"?domain="+r.ID.Domain, "application/json", bytes.NewReader(data), origin)
|
||||
|
||||
return err
|
||||
}
|
||||
@ -123,7 +123,7 @@ func (c *APIClient) SetProcessMetadata(origin string, r SetProcessMetadataReques
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = c.call(http.MethodPut, "/process/"+r.ID+"/metadata/"+r.Key, "application/json", bytes.NewReader(data), origin)
|
||||
_, err = c.call(http.MethodPut, "/process/"+r.ID.ID+"/metadata/"+r.Key+"?domain="+r.ID.Domain, "application/json", bytes.NewReader(data), origin)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -66,11 +66,11 @@ type Cluster interface {
|
||||
Shutdown() error
|
||||
|
||||
ListProcesses() []store.Process
|
||||
GetProcess(id string) (store.Process, error)
|
||||
GetProcess(id app.ProcessID) (store.Process, error)
|
||||
AddProcess(origin string, config *app.Config) error
|
||||
RemoveProcess(origin, id string) error
|
||||
UpdateProcess(origin, id string, config *app.Config) error
|
||||
SetProcessMetadata(origin, id, key string, data interface{}) error
|
||||
RemoveProcess(origin string, id app.ProcessID) error
|
||||
UpdateProcess(origin string, id app.ProcessID, config *app.Config) error
|
||||
SetProcessMetadata(origin string, id app.ProcessID, key string, data interface{}) error
|
||||
|
||||
IAM(superuser iamidentity.User, jwtRealm, jwtSecret string) (iam.IAM, error)
|
||||
ListIdentities() (time.Time, []iamidentity.User)
|
||||
@ -707,7 +707,7 @@ func (c *cluster) ListProcesses() []store.Process {
|
||||
return c.store.ProcessList()
|
||||
}
|
||||
|
||||
func (c *cluster) GetProcess(id string) (store.Process, error) {
|
||||
func (c *cluster) GetProcess(id app.ProcessID) (store.Process, error) {
|
||||
return c.store.GetProcess(id)
|
||||
}
|
||||
|
||||
@ -726,7 +726,7 @@ func (c *cluster) AddProcess(origin string, config *app.Config) error {
|
||||
return c.applyCommand(cmd)
|
||||
}
|
||||
|
||||
func (c *cluster) RemoveProcess(origin, id string) error {
|
||||
func (c *cluster) RemoveProcess(origin string, id app.ProcessID) error {
|
||||
if !c.IsRaftLeader() {
|
||||
return c.forwarder.RemoveProcess(origin, id)
|
||||
}
|
||||
@ -741,7 +741,7 @@ func (c *cluster) RemoveProcess(origin, id string) error {
|
||||
return c.applyCommand(cmd)
|
||||
}
|
||||
|
||||
func (c *cluster) UpdateProcess(origin, id string, config *app.Config) error {
|
||||
func (c *cluster) UpdateProcess(origin string, id app.ProcessID, config *app.Config) error {
|
||||
if !c.IsRaftLeader() {
|
||||
return c.forwarder.UpdateProcess(origin, id, config)
|
||||
}
|
||||
@ -757,7 +757,7 @@ func (c *cluster) UpdateProcess(origin, id string, config *app.Config) error {
|
||||
return c.applyCommand(cmd)
|
||||
}
|
||||
|
||||
func (c *cluster) SetProcessMetadata(origin, id, key string, data interface{}) error {
|
||||
func (c *cluster) SetProcessMetadata(origin string, id app.ProcessID, key string, data interface{}) error {
|
||||
if !c.IsRaftLeader() {
|
||||
return c.forwarder.SetProcessMetadata(origin, id, key, data)
|
||||
}
|
||||
|
||||
@ -23,9 +23,9 @@ type Forwarder interface {
|
||||
Snapshot() (io.ReadCloser, error)
|
||||
|
||||
AddProcess(origin string, config *app.Config) error
|
||||
UpdateProcess(origin, id string, config *app.Config) error
|
||||
SetProcessMetadata(origin, id, key string, data interface{}) error
|
||||
RemoveProcess(origin, id string) error
|
||||
UpdateProcess(origin string, id app.ProcessID, config *app.Config) error
|
||||
SetProcessMetadata(origin string, id app.ProcessID, key string, data interface{}) error
|
||||
RemoveProcess(origin string, id app.ProcessID) error
|
||||
|
||||
AddIdentity(origin string, identity iamidentity.User) error
|
||||
UpdateIdentity(origin, name string, identity iamidentity.User) error
|
||||
@ -155,7 +155,7 @@ func (f *forwarder) AddProcess(origin string, config *app.Config) error {
|
||||
return client.AddProcess(origin, r)
|
||||
}
|
||||
|
||||
func (f *forwarder) UpdateProcess(origin, id string, config *app.Config) error {
|
||||
func (f *forwarder) UpdateProcess(origin string, id app.ProcessID, config *app.Config) error {
|
||||
if origin == "" {
|
||||
origin = f.id
|
||||
}
|
||||
@ -172,7 +172,7 @@ func (f *forwarder) UpdateProcess(origin, id string, config *app.Config) error {
|
||||
return client.UpdateProcess(origin, r)
|
||||
}
|
||||
|
||||
func (f *forwarder) SetProcessMetadata(origin, id, key string, data interface{}) error {
|
||||
func (f *forwarder) SetProcessMetadata(origin string, id app.ProcessID, key string, data interface{}) error {
|
||||
if origin == "" {
|
||||
origin = f.id
|
||||
}
|
||||
@ -190,7 +190,7 @@ func (f *forwarder) SetProcessMetadata(origin, id, key string, data interface{})
|
||||
return client.SetProcessMetadata(origin, r)
|
||||
}
|
||||
|
||||
func (f *forwarder) RemoveProcess(origin, id string) error {
|
||||
func (f *forwarder) RemoveProcess(origin string, id app.ProcessID) error {
|
||||
if origin == "" {
|
||||
origin = f.id
|
||||
}
|
||||
|
||||
@ -289,6 +289,8 @@ WAIT:
|
||||
func (c *cluster) establishLeadership(ctx context.Context) error {
|
||||
c.logger.Debug().Log("Establishing leadership")
|
||||
|
||||
// creating a map of which process runs where
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
c.cancelLeaderShip = cancel
|
||||
|
||||
@ -324,7 +326,7 @@ var errNoLimitsDefined = errors.New("no process limits are defined")
|
||||
|
||||
type processOpDelete struct {
|
||||
nodeid string
|
||||
processid string
|
||||
processid app.ProcessID
|
||||
}
|
||||
|
||||
type processOpMove struct {
|
||||
@ -336,7 +338,7 @@ type processOpMove struct {
|
||||
|
||||
type processOpStart struct {
|
||||
nodeid string
|
||||
processid string
|
||||
processid app.ProcessID
|
||||
}
|
||||
|
||||
type processOpAdd struct {
|
||||
@ -347,19 +349,19 @@ type processOpAdd struct {
|
||||
|
||||
type processOpUpdate struct {
|
||||
nodeid string
|
||||
processid string
|
||||
processid app.ProcessID
|
||||
config *app.Config
|
||||
metadata map[string]interface{}
|
||||
}
|
||||
|
||||
type processOpReject struct {
|
||||
processid string
|
||||
processid app.ProcessID
|
||||
err error
|
||||
}
|
||||
|
||||
type processOpSkip struct {
|
||||
nodeid string
|
||||
processid string
|
||||
processid app.ProcessID
|
||||
err error
|
||||
}
|
||||
|
||||
@ -370,12 +372,12 @@ func (c *cluster) applyOpStack(stack []interface{}) {
|
||||
err := c.proxy.ProcessAdd(v.nodeid, v.config, v.metadata)
|
||||
if err != nil {
|
||||
c.logger.Info().WithError(err).WithFields(log.Fields{
|
||||
"processid": v.config.ID,
|
||||
"processid": v.config.ProcessID(),
|
||||
"nodeid": v.nodeid,
|
||||
}).Log("Adding process")
|
||||
break
|
||||
}
|
||||
err = c.proxy.ProcessStart(v.nodeid, v.config.ID)
|
||||
err = c.proxy.ProcessStart(v.nodeid, v.config.ProcessID())
|
||||
if err != nil {
|
||||
c.logger.Info().WithError(err).WithFields(log.Fields{
|
||||
"processid": v.config.ID,
|
||||
@ -423,7 +425,7 @@ func (c *cluster) applyOpStack(stack []interface{}) {
|
||||
}).Log("Moving process, adding process")
|
||||
break
|
||||
}
|
||||
err = c.proxy.ProcessDelete(v.fromNodeid, v.config.ID)
|
||||
err = c.proxy.ProcessDelete(v.fromNodeid, v.config.ProcessID())
|
||||
if err != nil {
|
||||
c.logger.Info().WithError(err).WithFields(log.Fields{
|
||||
"processid": v.config.ID,
|
||||
@ -432,7 +434,7 @@ func (c *cluster) applyOpStack(stack []interface{}) {
|
||||
}).Log("Moving process, removing process")
|
||||
break
|
||||
}
|
||||
err = c.proxy.ProcessStart(v.toNodeid, v.config.ID)
|
||||
err = c.proxy.ProcessStart(v.toNodeid, v.config.ProcessID())
|
||||
if err != nil {
|
||||
c.logger.Info().WithError(err).WithFields(log.Fields{
|
||||
"processid": v.config.ID,
|
||||
@ -509,7 +511,8 @@ func synchronize(want []store.Process, have []proxy.Process, resources map[strin
|
||||
// we want to be running on the nodes.
|
||||
wantMap := map[string]store.Process{}
|
||||
for _, process := range want {
|
||||
wantMap[process.Config.ID] = process
|
||||
pid := process.Config.ProcessID().String()
|
||||
wantMap[pid] = process
|
||||
}
|
||||
|
||||
opStack := []interface{}{}
|
||||
@ -520,10 +523,11 @@ func synchronize(want []store.Process, have []proxy.Process, resources map[strin
|
||||
haveAfterRemove := []proxy.Process{}
|
||||
|
||||
for _, p := range have {
|
||||
if wantP, ok := wantMap[p.Config.ID]; !ok {
|
||||
pid := p.Config.ProcessID().String()
|
||||
if wantP, ok := wantMap[pid]; !ok {
|
||||
opStack = append(opStack, processOpDelete{
|
||||
nodeid: p.NodeID,
|
||||
processid: p.Config.ID,
|
||||
processid: p.Config.ProcessID(),
|
||||
})
|
||||
|
||||
// Adjust the resources
|
||||
@ -539,19 +543,19 @@ func synchronize(want []store.Process, have []proxy.Process, resources map[strin
|
||||
if wantP.UpdatedAt.After(p.UpdatedAt) {
|
||||
opStack = append(opStack, processOpUpdate{
|
||||
nodeid: p.NodeID,
|
||||
processid: p.Config.ID,
|
||||
processid: p.Config.ProcessID(),
|
||||
config: wantP.Config,
|
||||
metadata: wantP.Metadata,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
delete(wantMap, p.Config.ID)
|
||||
delete(wantMap, pid)
|
||||
|
||||
if p.Order != "start" {
|
||||
opStack = append(opStack, processOpStart{
|
||||
nodeid: p.NodeID,
|
||||
processid: p.Config.ID,
|
||||
processid: p.Config.ProcessID(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -568,7 +572,7 @@ func synchronize(want []store.Process, have []proxy.Process, resources map[strin
|
||||
// If a process doesn't have any limits defined, reject that process
|
||||
if process.Config.LimitCPU <= 0 || process.Config.LimitMemory <= 0 {
|
||||
opStack = append(opStack, processOpReject{
|
||||
processid: process.Config.ID,
|
||||
processid: process.Config.ProcessID(),
|
||||
err: errNoLimitsDefined,
|
||||
})
|
||||
|
||||
@ -631,7 +635,7 @@ func synchronize(want []store.Process, have []proxy.Process, resources map[strin
|
||||
}
|
||||
} else {
|
||||
opStack = append(opStack, processOpReject{
|
||||
processid: process.Config.ID,
|
||||
processid: process.Config.ProcessID(),
|
||||
err: errNotEnoughResources,
|
||||
})
|
||||
}
|
||||
@ -780,7 +784,7 @@ func rebalance(have []proxy.Process, resources map[string]proxy.NodeResources) [
|
||||
// There's no other node with enough resources to take over this process
|
||||
opStack = append(opStack, processOpSkip{
|
||||
nodeid: overloadedNodeid,
|
||||
processid: p.Config.ID,
|
||||
processid: p.Config.ProcessID(),
|
||||
err: errNotEnoughResourcesForRebalancing,
|
||||
})
|
||||
continue
|
||||
|
||||
@ -242,7 +242,7 @@ func TestSynchronizeAddNoResourcesCPU(t *testing.T) {
|
||||
|
||||
require.Equal(t, []interface{}{
|
||||
processOpReject{
|
||||
processid: "foobar",
|
||||
processid: app.ProcessID{ID: "foobar"},
|
||||
err: errNotEnoughResources,
|
||||
},
|
||||
}, stack)
|
||||
@ -283,7 +283,7 @@ func TestSynchronizeAddNoResourcesMemory(t *testing.T) {
|
||||
|
||||
require.Equal(t, []interface{}{
|
||||
processOpReject{
|
||||
processid: "foobar",
|
||||
processid: app.ProcessID{ID: "foobar"},
|
||||
err: errNotEnoughResources,
|
||||
},
|
||||
}, stack)
|
||||
@ -322,7 +322,7 @@ func TestSynchronizeAddNoLimits(t *testing.T) {
|
||||
|
||||
require.Equal(t, []interface{}{
|
||||
processOpReject{
|
||||
processid: "foobar",
|
||||
processid: app.ProcessID{ID: "foobar"},
|
||||
err: errNoLimitsDefined,
|
||||
},
|
||||
}, stack)
|
||||
@ -367,7 +367,7 @@ func TestSynchronizeRemove(t *testing.T) {
|
||||
require.Equal(t, []interface{}{
|
||||
processOpDelete{
|
||||
nodeid: "node2",
|
||||
processid: "foobar",
|
||||
processid: app.ProcessID{ID: "foobar"},
|
||||
},
|
||||
}, stack)
|
||||
|
||||
@ -437,7 +437,7 @@ func TestSynchronizeAddRemove(t *testing.T) {
|
||||
require.Equal(t, []interface{}{
|
||||
processOpDelete{
|
||||
nodeid: "node2",
|
||||
processid: "foobar2",
|
||||
processid: app.ProcessID{ID: "foobar2"},
|
||||
},
|
||||
processOpAdd{
|
||||
nodeid: "node1",
|
||||
@ -662,17 +662,17 @@ func TestRebalanceSkip(t *testing.T) {
|
||||
require.ElementsMatch(t, []interface{}{
|
||||
processOpSkip{
|
||||
nodeid: "node1",
|
||||
processid: "foobar3",
|
||||
processid: app.ProcessID{ID: "foobar3"},
|
||||
err: errNotEnoughResourcesForRebalancing,
|
||||
},
|
||||
processOpSkip{
|
||||
nodeid: "node1",
|
||||
processid: "foobar1",
|
||||
processid: app.ProcessID{ID: "foobar1"},
|
||||
err: errNotEnoughResourcesForRebalancing,
|
||||
},
|
||||
processOpSkip{
|
||||
nodeid: "node2",
|
||||
processid: "foobar2",
|
||||
processid: app.ProcessID{ID: "foobar2"},
|
||||
err: errNotEnoughResourcesForRebalancing,
|
||||
},
|
||||
}, opStack)
|
||||
|
||||
@ -11,9 +11,10 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
|
||||
client "github.com/datarhei/core-client-go/v16"
|
||||
clientapi "github.com/datarhei/core-client-go/v16/api"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
)
|
||||
|
||||
type Node interface {
|
||||
@ -27,10 +28,10 @@ type Node interface {
|
||||
GetFile(prefix, path string) (io.ReadCloser, error)
|
||||
|
||||
ProcessAdd(config *app.Config, metadata map[string]interface{}) error
|
||||
ProcessStart(id string) error
|
||||
ProcessStop(id string) error
|
||||
ProcessDelete(id string) error
|
||||
ProcessUpdate(id string, config *app.Config, metadata map[string]interface{}) error
|
||||
ProcessStart(id app.ProcessID) error
|
||||
ProcessStop(id app.ProcessID) error
|
||||
ProcessDelete(id app.ProcessID) error
|
||||
ProcessUpdate(id app.ProcessID, config *app.Config, metadata map[string]interface{}) error
|
||||
|
||||
NodeReader
|
||||
}
|
||||
@ -51,11 +52,12 @@ type NodeFiles struct {
|
||||
}
|
||||
|
||||
type NodeResources struct {
|
||||
NCPU float64 // Number of CPU on this node
|
||||
CPU float64 // Current CPU load, 0-100*ncpu
|
||||
CPULimit float64 // Defined CPU load limit, 0-100*ncpu
|
||||
Mem uint64 // Currently used memory in bytes
|
||||
MemLimit uint64 // Defined memory limit in bytes
|
||||
IsThrottling bool // Whether this core is currently throttling
|
||||
NCPU float64 // Number of CPU on this node
|
||||
CPU float64 // Current CPU load, 0-100*ncpu
|
||||
CPULimit float64 // Defined CPU load limit, 0-100*ncpu
|
||||
Mem uint64 // Currently used memory in bytes
|
||||
MemLimit uint64 // Defined memory limit in bytes
|
||||
}
|
||||
|
||||
type NodeAbout struct {
|
||||
@ -719,6 +721,8 @@ func (n *node) ProcessList() ([]Process, error) {
|
||||
|
||||
cfg := &app.Config{
|
||||
ID: p.Config.ID,
|
||||
Owner: p.Config.Owner,
|
||||
Domain: p.Config.Domain,
|
||||
Reference: p.Config.Reference,
|
||||
Input: []app.ConfigIO{},
|
||||
Output: []app.ConfigIO{},
|
||||
@ -727,6 +731,9 @@ func (n *node) ProcessList() ([]Process, error) {
|
||||
ReconnectDelay: p.Config.ReconnectDelay,
|
||||
Autostart: p.Config.Autostart,
|
||||
StaleTimeout: p.Config.StaleTimeout,
|
||||
Timeout: p.Config.Timeout,
|
||||
Scheduler: p.Config.Scheduler,
|
||||
LogPatterns: p.Config.LogPatterns,
|
||||
LimitCPU: p.Config.Limits.CPU,
|
||||
LimitMemory: p.Config.Limits.Memory * 1024 * 1024,
|
||||
LimitWaitFor: p.Config.Limits.WaitFor,
|
||||
@ -784,6 +791,8 @@ func (n *node) ProcessAdd(config *app.Config, metadata map[string]interface{}) e
|
||||
func convertConfig(config *app.Config, metadata map[string]interface{}) clientapi.ProcessConfig {
|
||||
cfg := clientapi.ProcessConfig{
|
||||
ID: config.ID,
|
||||
Owner: config.Owner,
|
||||
Domain: config.Domain,
|
||||
Type: "ffmpeg",
|
||||
Reference: config.Reference,
|
||||
Input: []clientapi.ProcessConfigIO{},
|
||||
@ -793,6 +802,9 @@ func convertConfig(config *app.Config, metadata map[string]interface{}) clientap
|
||||
ReconnectDelay: config.ReconnectDelay,
|
||||
Autostart: config.Autostart,
|
||||
StaleTimeout: config.StaleTimeout,
|
||||
Timeout: config.Timeout,
|
||||
Scheduler: config.Scheduler,
|
||||
LogPatterns: config.LogPatterns,
|
||||
Limits: clientapi.ProcessConfigLimits{
|
||||
CPU: config.LimitCPU,
|
||||
Memory: config.LimitMemory / 1024 / 1024,
|
||||
@ -832,7 +844,7 @@ func convertConfig(config *app.Config, metadata map[string]interface{}) clientap
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (n *node) ProcessStart(id string) error {
|
||||
func (n *node) ProcessStart(id app.ProcessID) error {
|
||||
n.peerLock.RLock()
|
||||
defer n.peerLock.RUnlock()
|
||||
|
||||
@ -840,10 +852,10 @@ func (n *node) ProcessStart(id string) error {
|
||||
return fmt.Errorf("not connected")
|
||||
}
|
||||
|
||||
return n.peer.ProcessCommand(id, "start")
|
||||
return n.peer.ProcessCommand(client.NewProcessID(id.ID, id.Domain), "start")
|
||||
}
|
||||
|
||||
func (n *node) ProcessStop(id string) error {
|
||||
func (n *node) ProcessStop(id app.ProcessID) error {
|
||||
n.peerLock.RLock()
|
||||
defer n.peerLock.RUnlock()
|
||||
|
||||
@ -851,10 +863,10 @@ func (n *node) ProcessStop(id string) error {
|
||||
return fmt.Errorf("not connected")
|
||||
}
|
||||
|
||||
return n.peer.ProcessCommand(id, "stop")
|
||||
return n.peer.ProcessCommand(client.NewProcessID(id.ID, id.Domain), "stop")
|
||||
}
|
||||
|
||||
func (n *node) ProcessDelete(id string) error {
|
||||
func (n *node) ProcessDelete(id app.ProcessID) error {
|
||||
n.peerLock.RLock()
|
||||
defer n.peerLock.RUnlock()
|
||||
|
||||
@ -862,10 +874,10 @@ func (n *node) ProcessDelete(id string) error {
|
||||
return fmt.Errorf("not connected")
|
||||
}
|
||||
|
||||
return n.peer.ProcessDelete(id)
|
||||
return n.peer.ProcessDelete(client.NewProcessID(id.ID, id.Domain))
|
||||
}
|
||||
|
||||
func (n *node) ProcessUpdate(id string, config *app.Config, metadata map[string]interface{}) error {
|
||||
func (n *node) ProcessUpdate(id app.ProcessID, config *app.Config, metadata map[string]interface{}) error {
|
||||
n.peerLock.RLock()
|
||||
defer n.peerLock.RUnlock()
|
||||
|
||||
@ -875,5 +887,5 @@ func (n *node) ProcessUpdate(id string, config *app.Config, metadata map[string]
|
||||
|
||||
cfg := convertConfig(config, metadata)
|
||||
|
||||
return n.peer.ProcessUpdate(id, cfg)
|
||||
return n.peer.ProcessUpdate(client.NewProcessID(id.ID, id.Domain), cfg)
|
||||
}
|
||||
|
||||
@ -25,9 +25,9 @@ type Proxy interface {
|
||||
Reader() ProxyReader
|
||||
|
||||
ProcessAdd(nodeid string, config *app.Config, metadata map[string]interface{}) error
|
||||
ProcessDelete(nodeid string, id string) error
|
||||
ProcessStart(nodeid string, id string) error
|
||||
ProcessUpdate(nodeid string, id string, config *app.Config, metadata map[string]interface{}) error
|
||||
ProcessDelete(nodeid string, id app.ProcessID) error
|
||||
ProcessStart(nodeid string, id app.ProcessID) error
|
||||
ProcessUpdate(nodeid string, id app.ProcessID, config *app.Config, metadata map[string]interface{}) error
|
||||
}
|
||||
|
||||
type ProxyReader interface {
|
||||
@ -495,7 +495,7 @@ func (p *proxy) ProcessAdd(nodeid string, config *app.Config, metadata map[strin
|
||||
return err
|
||||
}
|
||||
|
||||
err = node.ProcessStart(config.ID)
|
||||
err = node.ProcessStart(config.ProcessID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -503,7 +503,7 @@ func (p *proxy) ProcessAdd(nodeid string, config *app.Config, metadata map[strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *proxy) ProcessDelete(nodeid string, id string) error {
|
||||
func (p *proxy) ProcessDelete(nodeid string, id app.ProcessID) error {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
@ -520,7 +520,7 @@ func (p *proxy) ProcessDelete(nodeid string, id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *proxy) ProcessStart(nodeid string, id string) error {
|
||||
func (p *proxy) ProcessStart(nodeid string, id app.ProcessID) error {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
@ -537,7 +537,7 @@ func (p *proxy) ProcessStart(nodeid string, id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *proxy) ProcessUpdate(nodeid string, id string, config *app.Config, metadata map[string]interface{}) error {
|
||||
func (p *proxy) ProcessUpdate(nodeid string, id app.ProcessID, config *app.Config, metadata map[string]interface{}) error {
|
||||
p.lock.RLock()
|
||||
defer p.lock.RUnlock()
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ type Store interface {
|
||||
OnApply(func(op Operation))
|
||||
|
||||
ProcessList() []Process
|
||||
GetProcess(id string) (Process, error)
|
||||
GetProcess(id app.ProcessID) (Process, error)
|
||||
|
||||
UserList() Users
|
||||
GetUser(name string) Users
|
||||
@ -80,16 +80,16 @@ type CommandAddProcess struct {
|
||||
}
|
||||
|
||||
type CommandUpdateProcess struct {
|
||||
ID string
|
||||
ID app.ProcessID
|
||||
Config *app.Config
|
||||
}
|
||||
|
||||
type CommandRemoveProcess struct {
|
||||
ID string
|
||||
ID app.ProcessID
|
||||
}
|
||||
|
||||
type CommandSetProcessMetadata struct {
|
||||
ID string
|
||||
ID app.ProcessID
|
||||
Key string
|
||||
Data interface{}
|
||||
}
|
||||
@ -242,13 +242,15 @@ func (s *store) addProcess(cmd CommandAddProcess) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
_, ok := s.Process[cmd.Config.ID]
|
||||
id := cmd.Config.ProcessID().String()
|
||||
|
||||
_, ok := s.Process[id]
|
||||
if ok {
|
||||
return NewStoreError("the process with the ID '%s' already exists", cmd.Config.ID)
|
||||
return NewStoreError("the process with the ID '%s' already exists", id)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
s.Process[cmd.Config.ID] = Process{
|
||||
s.Process[id] = Process{
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
Config: cmd.Config,
|
||||
@ -262,7 +264,14 @@ func (s *store) removeProcess(cmd CommandRemoveProcess) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
delete(s.Process, cmd.ID)
|
||||
id := cmd.ID.String()
|
||||
|
||||
_, ok := s.Process[id]
|
||||
if !ok {
|
||||
return NewStoreError("the process with the ID '%s' doesn't exist", id)
|
||||
}
|
||||
|
||||
delete(s.Process, id)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -271,9 +280,12 @@ func (s *store) updateProcess(cmd CommandUpdateProcess) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
p, ok := s.Process[cmd.ID]
|
||||
srcid := cmd.ID.String()
|
||||
dstid := cmd.Config.ProcessID().String()
|
||||
|
||||
p, ok := s.Process[srcid]
|
||||
if !ok {
|
||||
return NewStoreError("the process with the ID '%s' doesn't exists", cmd.ID)
|
||||
return NewStoreError("the process with the ID '%s' doesn't exists", srcid)
|
||||
}
|
||||
|
||||
currentHash := p.Config.Hash()
|
||||
@ -283,19 +295,19 @@ func (s *store) updateProcess(cmd CommandUpdateProcess) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if cmd.ID == cmd.Config.ID {
|
||||
s.Process[cmd.ID] = Process{
|
||||
if srcid == dstid {
|
||||
s.Process[srcid] = Process{
|
||||
UpdatedAt: time.Now(),
|
||||
Config: cmd.Config,
|
||||
}
|
||||
} else {
|
||||
_, ok := s.Process[cmd.Config.ID]
|
||||
_, ok := s.Process[dstid]
|
||||
if ok {
|
||||
return NewStoreError("the process with the ID '%s' already exists", cmd.Config.ID)
|
||||
return NewStoreError("the process with the ID '%s' already exists", dstid)
|
||||
}
|
||||
|
||||
delete(s.Process, cmd.ID)
|
||||
s.Process[cmd.Config.ID] = Process{
|
||||
delete(s.Process, srcid)
|
||||
s.Process[dstid] = Process{
|
||||
UpdatedAt: time.Now(),
|
||||
Config: cmd.Config,
|
||||
}
|
||||
@ -308,7 +320,9 @@ func (s *store) setProcessMetadata(cmd CommandSetProcessMetadata) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
p, ok := s.Process[cmd.ID]
|
||||
id := cmd.ID.String()
|
||||
|
||||
p, ok := s.Process[id]
|
||||
if !ok {
|
||||
return NewStoreError("the process with the ID '%s' doesn't exists", cmd.ID)
|
||||
}
|
||||
@ -324,7 +338,7 @@ func (s *store) setProcessMetadata(cmd CommandSetProcessMetadata) error {
|
||||
}
|
||||
p.UpdatedAt = time.Now()
|
||||
|
||||
s.Process[cmd.ID] = p
|
||||
s.Process[id] = p
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -456,11 +470,11 @@ func (s *store) ProcessList() []Process {
|
||||
return processes
|
||||
}
|
||||
|
||||
func (s *store) GetProcess(id string) (Process, error) {
|
||||
func (s *store) GetProcess(id app.ProcessID) (Process, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
process, ok := s.Process[id]
|
||||
process, ok := s.Process[id.String()]
|
||||
if !ok {
|
||||
return Process{}, fmt.Errorf("not found")
|
||||
}
|
||||
|
||||
87
docs/docs.go
87
docs/docs.go
@ -1071,6 +1071,77 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v3/cluster/process/{id}/metadata/{key}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Add arbitrary JSON metadata under the given key. If the key exists, all already stored metadata with this key will be overwritten. If the key doesn't exist, it will be created.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"v16.?.?"
|
||||
],
|
||||
"summary": "Add JSON metadata with a process under the given key",
|
||||
"operationId": "cluster-3-set-process-metadata",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Process ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Key for data store",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Domain to act on",
|
||||
"name": "domain",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"description": "Arbitrary JSON data. The null value will remove the key and its contents",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v3/config": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -3773,6 +3844,9 @@ const docTemplate = `{
|
||||
"cpu": {
|
||||
"type": "number"
|
||||
},
|
||||
"domain": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3785,6 +3859,9 @@ const docTemplate = `{
|
||||
"order": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4982,10 +5059,16 @@ const docTemplate = `{
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"domain": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -5035,6 +5118,10 @@ const docTemplate = `{
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
@ -1063,6 +1063,77 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v3/cluster/process/{id}/metadata/{key}": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Add arbitrary JSON metadata under the given key. If the key exists, all already stored metadata with this key will be overwritten. If the key doesn't exist, it will be created.",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"v16.?.?"
|
||||
],
|
||||
"summary": "Add JSON metadata with a process under the given key",
|
||||
"operationId": "cluster-3-set-process-metadata",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Process ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Key for data store",
|
||||
"name": "key",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Domain to act on",
|
||||
"name": "domain",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"description": "Arbitrary JSON data. The null value will remove the key and its contents",
|
||||
"name": "data",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/api.Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v3/config": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -3765,6 +3836,9 @@
|
||||
"cpu": {
|
||||
"type": "number"
|
||||
},
|
||||
"domain": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3777,6 +3851,9 @@
|
||||
"order": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4974,10 +5051,16 @@
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"domain": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"reference": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -5027,6 +5110,10 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"options": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
@ -136,6 +136,8 @@ definitions:
|
||||
properties:
|
||||
cpu:
|
||||
type: number
|
||||
domain:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
memory_bytes:
|
||||
@ -144,6 +146,8 @@ definitions:
|
||||
type: string
|
||||
order:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
reference:
|
||||
type: string
|
||||
runtime_seconds:
|
||||
@ -944,9 +948,13 @@ definitions:
|
||||
created_at:
|
||||
format: int64
|
||||
type: integer
|
||||
domain:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
metadata: {}
|
||||
owner:
|
||||
type: string
|
||||
reference:
|
||||
type: string
|
||||
report:
|
||||
@ -977,6 +985,9 @@ definitions:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
metadata:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
options:
|
||||
items:
|
||||
type: string
|
||||
@ -2985,6 +2996,56 @@ paths:
|
||||
summary: Replace an existing process
|
||||
tags:
|
||||
- v16.?.?
|
||||
/api/v3/cluster/process/{id}/metadata/{key}:
|
||||
put:
|
||||
description: Add arbitrary JSON metadata under the given key. If the key exists,
|
||||
all already stored metadata with this key will be overwritten. If the key
|
||||
doesn't exist, it will be created.
|
||||
operationId: cluster-3-set-process-metadata
|
||||
parameters:
|
||||
- description: Process ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
- description: Key for data store
|
||||
in: path
|
||||
name: key
|
||||
required: true
|
||||
type: string
|
||||
- description: Domain to act on
|
||||
in: query
|
||||
name: domain
|
||||
type: string
|
||||
- description: Arbitrary JSON data. The null value will remove the key and its
|
||||
contents
|
||||
in: body
|
||||
name: data
|
||||
required: true
|
||||
schema: {}
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema: {}
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
$ref: '#/definitions/api.Error'
|
||||
"403":
|
||||
description: Forbidden
|
||||
schema:
|
||||
$ref: '#/definitions/api.Error'
|
||||
"404":
|
||||
description: Not Found
|
||||
schema:
|
||||
$ref: '#/definitions/api.Error'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Add JSON metadata with a process under the given key
|
||||
tags:
|
||||
- v16.?.?
|
||||
/api/v3/config:
|
||||
get:
|
||||
description: Retrieve the currently active Restreamer configuration
|
||||
|
||||
4
go.mod
4
go.mod
@ -9,7 +9,7 @@ require (
|
||||
github.com/atrox/haikunatorgo/v2 v2.0.1
|
||||
github.com/caddyserver/certmagic v0.17.2
|
||||
github.com/casbin/casbin/v2 v2.69.1
|
||||
github.com/datarhei/core-client-go/v16 v16.11.1-0.20230602102832-3d80767a2208
|
||||
github.com/datarhei/core-client-go/v16 v16.11.1-0.20230605095314-42546fbbbece
|
||||
github.com/datarhei/gosrt v0.4.1
|
||||
github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a
|
||||
github.com/fujiwara/shapeio v1.0.0
|
||||
@ -30,7 +30,7 @@ require (
|
||||
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
github.com/shirou/gopsutil/v3 v3.23.4
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/swaggo/echo-swagger v1.4.0
|
||||
github.com/swaggo/swag v1.16.1
|
||||
github.com/vektah/gqlparser/v2 v2.5.1
|
||||
|
||||
7
go.sum
7
go.sum
@ -47,8 +47,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/datarhei/core-client-go/v16 v16.11.1-0.20230602102832-3d80767a2208 h1:voT+m+r0r112S0BIbQDvW9S4BGBv2JXGW/1L5Cmmvq4=
|
||||
github.com/datarhei/core-client-go/v16 v16.11.1-0.20230602102832-3d80767a2208/go.mod h1:2eAeJtBPTyiI+9uhGcCEHZqATBt9J06Bb7Fbxj07lw4=
|
||||
github.com/datarhei/core-client-go/v16 v16.11.1-0.20230605095314-42546fbbbece h1:Gv+W986jLcMa/TOKg5YF3RMDlNDDyj7uHuH+mHP7xq8=
|
||||
github.com/datarhei/core-client-go/v16 v16.11.1-0.20230605095314-42546fbbbece/go.mod h1:6L0zr/NUwvaPsCTK/IL17m8JUEtgLp3BDtlsBREwacg=
|
||||
github.com/datarhei/gosrt v0.4.1 h1:08km3wKy72jOdC+JzBDWN57H7xST4mz5lFeJQHuWmMs=
|
||||
github.com/datarhei/gosrt v0.4.1/go.mod h1:FtsulRiUc67Oi3Ii9JH9aQkpO+ZfgeauRAtIE40mIVA=
|
||||
github.com/datarhei/joy4 v0.0.0-20230505074825-fde05957445a h1:Tf4DSHY1xruBglr+yYP5Wct7czM86GKMYgbXH8a7OFo=
|
||||
@ -298,8 +298,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/swaggo/echo-swagger v1.4.0 h1:RCxLKySw1SceHLqnmc41pKyiIeE+OiD7NSI7FUOBlLo=
|
||||
github.com/swaggo/echo-swagger v1.4.0/go.mod h1:Wh3VlwjZGZf/LH0s81tz916JokuPG7y/ZqaqnckYqoQ=
|
||||
github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw=
|
||||
|
||||
@ -15,11 +15,12 @@ type ClusterNode struct {
|
||||
}
|
||||
|
||||
type ClusterNodeResources struct {
|
||||
NCPU float64 `json:"ncpu"`
|
||||
CPU float64 `json:"cpu_used"` // percent 0-100*npcu
|
||||
CPULimit float64 `json:"cpu_limit"` // percent 0-100*npcu
|
||||
Mem uint64 `json:"memory_used_bytes"`
|
||||
MemLimit uint64 `json:"memory_limit_bytes"`
|
||||
IsThrottling bool `json:"is_throttling"`
|
||||
NCPU float64 `json:"ncpu"`
|
||||
CPU float64 `json:"cpu_used"` // percent 0-100*npcu
|
||||
CPULimit float64 `json:"cpu_limit"` // percent 0-100*npcu
|
||||
Mem uint64 `json:"memory_used_bytes"`
|
||||
MemLimit uint64 `json:"memory_limit_bytes"`
|
||||
}
|
||||
|
||||
type ClusterNodeFiles struct {
|
||||
@ -35,7 +36,9 @@ type ClusterServer struct {
|
||||
}
|
||||
|
||||
type ClusterProcess struct {
|
||||
ProcessID string `json:"id"`
|
||||
ID string `json:"id"`
|
||||
Owner string `json:"owner"`
|
||||
Domain string `json:"domain"`
|
||||
NodeID string `json:"node_id"`
|
||||
Reference string `json:"reference"`
|
||||
Order string `json:"order"`
|
||||
|
||||
@ -11,10 +11,12 @@ import (
|
||||
// Process represents all information on a process
|
||||
type Process struct {
|
||||
ID string `json:"id" jsonschema:"minLength=1"`
|
||||
Owner string `json:"owner"`
|
||||
Domain string `json:"domain"`
|
||||
Type string `json:"type" jsonschema:"enum=ffmpeg"`
|
||||
Reference string `json:"reference"`
|
||||
CreatedAt int64 `json:"created_at" jsonschema:"minimum=0" format:"int64"`
|
||||
UpdatedAt int64 `json:"updated_at" jsonschema:"minimum=0" format:"int64"`
|
||||
CreatedAt int64 `json:"created_at" format:"int64"`
|
||||
UpdatedAt int64 `json:"updated_at" format:"int64"`
|
||||
Config *ProcessConfig `json:"config,omitempty"`
|
||||
State *ProcessState `json:"state,omitempty"`
|
||||
Report *ProcessReport `json:"report,omitempty"`
|
||||
@ -207,6 +209,13 @@ func (cfg *ProcessConfig) Unmarshal(c *app.Config) {
|
||||
copy(cfg.LogPatterns, c.LogPatterns)
|
||||
}
|
||||
|
||||
func (p *ProcessConfig) ProcessID() app.ProcessID {
|
||||
return app.ProcessID{
|
||||
ID: p.ID,
|
||||
Domain: p.Domain,
|
||||
}
|
||||
}
|
||||
|
||||
// ProcessState represents the current state of an ffmpeg process
|
||||
type ProcessState struct {
|
||||
Order string `json:"order" jsonschema:"enum=start,enum=stop"`
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/datarhei/core/v16/http/graph/models"
|
||||
"github.com/datarhei/core/v16/playout"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
)
|
||||
|
||||
// PlayoutStatus is the resolver for the playoutStatus field.
|
||||
@ -22,7 +22,7 @@ func (r *queryResolver) PlayoutStatus(ctx context.Context, id string, domain str
|
||||
return nil, fmt.Errorf("forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/datarhei/core/v16/http/graph/models"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
)
|
||||
|
||||
// Processes is the resolver for the processes field.
|
||||
@ -42,7 +42,7 @@ func (r *queryResolver) Process(ctx context.Context, id string, domain string) (
|
||||
return nil, fmt.Errorf("forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -58,7 +58,7 @@ func (r *queryResolver) Probe(ctx context.Context, id string, domain string) (*m
|
||||
return nil, fmt.Errorf("forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/datarhei/core/v16/log"
|
||||
"github.com/datarhei/core/v16/monitor"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
)
|
||||
|
||||
// This file will not be regenerated automatically.
|
||||
@ -24,7 +25,7 @@ type Resolver struct {
|
||||
IAM iam.IAM
|
||||
}
|
||||
|
||||
func (r *queryResolver) getProcess(id restream.TaskID) (*models.Process, error) {
|
||||
func (r *queryResolver) getProcess(id app.ProcessID) (*models.Process, error) {
|
||||
process, err := r.Restream.GetProcess(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/datarhei/core/v16/iam/access"
|
||||
"github.com/datarhei/core/v16/iam/identity"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/lithammer/shortuuid/v4"
|
||||
@ -108,7 +109,9 @@ func (h *ClusterHandler) ListAllNodeProcesses(c echo.Context) error {
|
||||
}
|
||||
|
||||
processes = append(processes, api.ClusterProcess{
|
||||
ProcessID: p.Config.ID,
|
||||
ID: p.Config.ID,
|
||||
Owner: p.Config.Owner,
|
||||
Domain: p.Config.Domain,
|
||||
NodeID: p.NodeID,
|
||||
Reference: p.Config.Reference,
|
||||
Order: p.Order,
|
||||
@ -303,7 +306,9 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
|
||||
}
|
||||
|
||||
processes = append(processes, api.ClusterProcess{
|
||||
ProcessID: p.Config.ID,
|
||||
ID: p.Config.ID,
|
||||
Owner: p.Config.Owner,
|
||||
Domain: p.Config.Domain,
|
||||
NodeID: p.NodeID,
|
||||
Reference: p.Config.Reference,
|
||||
Order: p.Order,
|
||||
@ -341,9 +346,11 @@ func (h *ClusterHandler) ListStoreProcesses(c echo.Context) error {
|
||||
|
||||
process := api.Process{
|
||||
ID: p.Config.ID,
|
||||
Owner: p.Config.Owner,
|
||||
Domain: p.Config.Domain,
|
||||
Type: "ffmpeg",
|
||||
Reference: p.Config.Reference,
|
||||
CreatedAt: 0,
|
||||
CreatedAt: p.CreatedAt.Unix(),
|
||||
UpdatedAt: p.UpdatedAt.Unix(),
|
||||
Metadata: p.Metadata,
|
||||
}
|
||||
@ -412,7 +419,7 @@ func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
||||
}
|
||||
|
||||
for key, value := range metadata {
|
||||
h.cluster.SetProcessMetadata("", config.ID, key, value)
|
||||
h.cluster.SetProcessMetadata("", config.ProcessID(), key, value)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, process)
|
||||
@ -436,7 +443,7 @@ func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
||||
func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
superuser := util.DefaultContext(c, "superuser", false)
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
id := util.PathParam(c, "id")
|
||||
|
||||
process := api.ProcessConfig{
|
||||
@ -451,7 +458,9 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
current, err := h.cluster.GetProcess(id)
|
||||
pid := process.ProcessID()
|
||||
|
||||
current, err := h.cluster.GetProcess(pid)
|
||||
if err != nil {
|
||||
return api.Err(http.StatusNotFound, "Process not found", "%s", id)
|
||||
}
|
||||
@ -475,7 +484,7 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||
|
||||
config, metadata := process.Marshal()
|
||||
|
||||
if err := h.cluster.UpdateProcess("", id, config); err != nil {
|
||||
if err := h.cluster.UpdateProcess("", pid, config); err != nil {
|
||||
if err == restream.ErrUnknownProcess {
|
||||
return api.Err(http.StatusNotFound, "Process not found", "%s", id)
|
||||
}
|
||||
@ -483,8 +492,10 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "Process can't be updated", "%s", err)
|
||||
}
|
||||
|
||||
pid = process.ProcessID()
|
||||
|
||||
for key, value := range metadata {
|
||||
h.cluster.SetProcessMetadata("", id, key, value)
|
||||
h.cluster.SetProcessMetadata("", pid, key, value)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, process)
|
||||
@ -525,13 +536,13 @@ func (h *ClusterHandler) SetProcessMetadata(c echo.Context) error {
|
||||
if err := util.ShouldBindJSONValidation(c, &data, false); err != nil {
|
||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||
}
|
||||
/*
|
||||
tid := restream.TaskID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
*/
|
||||
if err := h.cluster.SetProcessMetadata("", id, key, data); err != nil {
|
||||
|
||||
pid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
if err := h.cluster.SetProcessMetadata("", pid, key, data); err != nil {
|
||||
return api.Err(http.StatusNotFound, "Unknown process ID", "%s", err)
|
||||
}
|
||||
|
||||
@ -546,21 +557,26 @@ func (h *ClusterHandler) SetProcessMetadata(c echo.Context) error {
|
||||
// @Produce json
|
||||
// @Param id path string true "Process ID"
|
||||
// @Success 200 {string} string
|
||||
// @Failure 400 {object} api.Error
|
||||
// @Failure 403 {object} api.Error
|
||||
// @Failure 500 {object} api.Error
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /api/v3/cluster/process/{id} [delete]
|
||||
func (h *ClusterHandler) DeleteProcess(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
id := util.PathParam(c, "id")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to delete process")
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to delete this process")
|
||||
}
|
||||
|
||||
if err := h.cluster.RemoveProcess("", id); err != nil {
|
||||
return api.Err(http.StatusInternalServerError, "Process can't be deleted", "%s", err)
|
||||
pid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
if err := h.cluster.RemoveProcess("", pid); err != nil {
|
||||
return api.Err(http.StatusBadRequest, "", "%s", err)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, "OK")
|
||||
|
||||
@ -22,12 +22,12 @@ func NewJWT(iam iam.IAM) *JWTHandler {
|
||||
func (j *JWTHandler) Login(c echo.Context) error {
|
||||
subject, ok := c.Get("user").(string)
|
||||
if !ok {
|
||||
return api.Err(http.StatusForbidden, "Invalid token")
|
||||
return api.Err(http.StatusForbidden, "Invalid user")
|
||||
}
|
||||
|
||||
at, rt, err := j.iam.CreateJWT(subject)
|
||||
if err != nil {
|
||||
return api.Err(http.StatusInternalServerError, "Failed to create JWT", "%s", err)
|
||||
return api.Err(http.StatusForbidden, "Failed to create JWT", "%s", err)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, api.JWT{
|
||||
@ -44,7 +44,7 @@ func (j *JWTHandler) Refresh(c echo.Context) error {
|
||||
|
||||
at, _, err := j.iam.CreateJWT(subject)
|
||||
if err != nil {
|
||||
return api.Err(http.StatusInternalServerError, "Failed to create JWT", "%s", err)
|
||||
return api.Err(http.StatusForbidden, "Failed to create JWT", "%s", err)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, api.JWTRefresh{
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"github.com/datarhei/core/v16/http/api"
|
||||
"github.com/datarhei/core/v16/http/handler/util"
|
||||
"github.com/datarhei/core/v16/playout"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
@ -39,7 +39,7 @@ func (h *RestreamHandler) PlayoutStatus(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -108,7 +108,7 @@ func (h *RestreamHandler) PlayoutKeyframe(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -166,7 +166,7 @@ func (h *RestreamHandler) PlayoutEncodeErrorframe(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -221,7 +221,7 @@ func (h *RestreamHandler) PlayoutSetErrorframe(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -277,7 +277,7 @@ func (h *RestreamHandler) PlayoutReopenInput(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -331,7 +331,7 @@ func (h *RestreamHandler) PlayoutSetStream(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import (
|
||||
"github.com/datarhei/core/v16/http/handler/util"
|
||||
"github.com/datarhei/core/v16/iam"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/lithammer/shortuuid/v4"
|
||||
@ -82,7 +83,7 @@ func (h *RestreamHandler) Add(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "Invalid process config", "%s", err.Error())
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: config.ID,
|
||||
Domain: config.Domain,
|
||||
}
|
||||
@ -127,7 +128,7 @@ func (h *RestreamHandler) GetAll(c echo.Context) error {
|
||||
domainpattern := util.DefaultQuery(c, "domainpattern", "")
|
||||
|
||||
preids := h.restream.GetProcessIDs(idpattern, refpattern, ownerpattern, domainpattern)
|
||||
ids := []restream.TaskID{}
|
||||
ids := []app.ProcessID{}
|
||||
|
||||
for _, id := range preids {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id.ID, "read") {
|
||||
@ -187,7 +188,7 @@ func (h *RestreamHandler) Get(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -219,7 +220,7 @@ func (h *RestreamHandler) Delete(c echo.Context) error {
|
||||
id := util.PathParam(c, "id")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -274,7 +275,7 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -303,7 +304,7 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
||||
|
||||
config, metadata := process.Marshal()
|
||||
|
||||
tid = restream.TaskID{
|
||||
tid = app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -316,7 +317,7 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "Process can't be updated", "%s", err)
|
||||
}
|
||||
|
||||
tid = restream.TaskID{
|
||||
tid = app.ProcessID{
|
||||
ID: config.ID,
|
||||
Domain: config.Domain,
|
||||
}
|
||||
@ -361,7 +362,7 @@ func (h *RestreamHandler) Command(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -409,7 +410,7 @@ func (h *RestreamHandler) GetConfig(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -448,7 +449,7 @@ func (h *RestreamHandler) GetState(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -510,7 +511,7 @@ func (h *RestreamHandler) GetReport(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -653,7 +654,7 @@ func (h *RestreamHandler) Probe(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -728,7 +729,7 @@ func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -777,7 +778,7 @@ func (h *RestreamHandler) SetProcessMetadata(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
@ -844,7 +845,7 @@ func (h *RestreamHandler) SetMetadata(c echo.Context) error {
|
||||
return c.JSON(http.StatusOK, data)
|
||||
}
|
||||
|
||||
func (h *RestreamHandler) getProcess(id restream.TaskID, filterString string) (api.Process, error) {
|
||||
func (h *RestreamHandler) getProcess(id app.ProcessID, filterString string) (api.Process, error) {
|
||||
filter := strings.FieldsFunc(filterString, func(r rune) bool {
|
||||
return r == rune(',')
|
||||
})
|
||||
@ -875,6 +876,8 @@ func (h *RestreamHandler) getProcess(id restream.TaskID, filterString string) (a
|
||||
|
||||
info := api.Process{
|
||||
ID: process.ID,
|
||||
Owner: process.Owner,
|
||||
Domain: process.Domain,
|
||||
Reference: process.Reference,
|
||||
Type: "ffmpeg",
|
||||
CreatedAt: process.CreatedAt,
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"github.com/datarhei/core/v16/http/api"
|
||||
"github.com/datarhei/core/v16/http/handler/util"
|
||||
"github.com/datarhei/core/v16/restream"
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
"github.com/datarhei/core/v16/session"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@ -49,7 +50,7 @@ func (w *WidgetHandler) Get(c echo.Context) error {
|
||||
return api.Err(http.StatusNotFound, "Unknown process ID")
|
||||
}
|
||||
|
||||
tid := restream.TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
@ -125,7 +125,10 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
resource := c.Request().URL.Path
|
||||
var domain string
|
||||
|
||||
if resource == "/ping" || resource == "/profiling" {
|
||||
c.Set("user", username)
|
||||
c.Set("superuser", false)
|
||||
|
||||
if resource == "/ping" {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
@ -151,7 +154,7 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
} else {
|
||||
identity, err = mw.findIdentityFromJWT(c)
|
||||
if err != nil {
|
||||
return api.Err(http.StatusForbidden, "Forbidden", "%s", err)
|
||||
return api.Err(http.StatusUnauthorized, "Unauthorized", "%s", err)
|
||||
}
|
||||
|
||||
if identity != nil {
|
||||
@ -223,6 +226,10 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
|
||||
action := c.Request().Method
|
||||
|
||||
if username == "$anon" && resource == "api:/api" {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
if !config.IAM.Enforce(username, domain, resource, action) {
|
||||
return api.Err(http.StatusForbidden, "Forbidden", "access denied")
|
||||
}
|
||||
|
||||
@ -176,6 +176,13 @@ func (config *Config) Hash() []byte {
|
||||
return sum[:]
|
||||
}
|
||||
|
||||
func (c *Config) ProcessID() ProcessID {
|
||||
return ProcessID{
|
||||
ID: c.ID,
|
||||
Domain: c.Domain,
|
||||
}
|
||||
}
|
||||
|
||||
type Process struct {
|
||||
ID string
|
||||
Owner string
|
||||
@ -202,6 +209,13 @@ func (process *Process) Clone() *Process {
|
||||
return clone
|
||||
}
|
||||
|
||||
func (process *Process) ProcessID() ProcessID {
|
||||
return ProcessID{
|
||||
ID: process.ID,
|
||||
Domain: process.Domain,
|
||||
}
|
||||
}
|
||||
|
||||
type ProcessStates struct {
|
||||
Finished uint64
|
||||
Starting uint64
|
||||
@ -254,3 +268,46 @@ type ProcessUsage struct {
|
||||
CPU ProcessUsageCPU
|
||||
Memory ProcessUsageMemory
|
||||
}
|
||||
|
||||
type ProcessID struct {
|
||||
ID string
|
||||
Domain string
|
||||
}
|
||||
|
||||
func NewProcessID(id, domain string) ProcessID {
|
||||
return ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
}
|
||||
|
||||
func ParseProcessID(pid string) ProcessID {
|
||||
p := ProcessID{}
|
||||
|
||||
p.Parse(pid)
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func (p ProcessID) String() string {
|
||||
return p.ID + "@" + p.Domain
|
||||
}
|
||||
|
||||
func (p ProcessID) Equals(b ProcessID) bool {
|
||||
if p.ID == b.ID && p.Domain == b.Domain {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *ProcessID) Parse(pid string) {
|
||||
i := strings.LastIndex(pid, "@")
|
||||
if i == -1 {
|
||||
p.ID = pid
|
||||
p.Domain = ""
|
||||
}
|
||||
|
||||
p.ID = pid[:i]
|
||||
p.Domain = pid[i+1:]
|
||||
}
|
||||
|
||||
@ -48,22 +48,22 @@ type Restreamer interface {
|
||||
GetMetadata(key string) (interface{}, error) // Get previously set general metadata
|
||||
|
||||
AddProcess(config *app.Config) error // Add a new process
|
||||
GetProcessIDs(idpattern, refpattern, ownerpattern, domainpattern string) []TaskID // Get a list of process IDs based on patterns for ID and reference
|
||||
DeleteProcess(id TaskID) error // Delete a process
|
||||
UpdateProcess(id TaskID, config *app.Config) error // Update a process
|
||||
StartProcess(id TaskID) error // Start a process
|
||||
StopProcess(id TaskID) error // Stop a process
|
||||
RestartProcess(id TaskID) error // Restart a process
|
||||
ReloadProcess(id TaskID) error // Reload a process
|
||||
GetProcess(id TaskID) (*app.Process, error) // Get a process
|
||||
GetProcessState(id TaskID) (*app.State, error) // Get the state of a process
|
||||
GetProcessLog(id TaskID) (*app.Log, error) // Get the logs of a process
|
||||
GetProcessIDs(idpattern, refpattern, ownerpattern, domainpattern string) []app.ProcessID // Get a list of process IDs based on patterns for ID and reference
|
||||
DeleteProcess(id app.ProcessID) error // Delete a process
|
||||
UpdateProcess(id app.ProcessID, config *app.Config) error // Update a process
|
||||
StartProcess(id app.ProcessID) error // Start a process
|
||||
StopProcess(id app.ProcessID) error // Stop a process
|
||||
RestartProcess(id app.ProcessID) error // Restart a process
|
||||
ReloadProcess(id app.ProcessID) error // Reload a process
|
||||
GetProcess(id app.ProcessID) (*app.Process, error) // Get a process
|
||||
GetProcessState(id app.ProcessID) (*app.State, error) // Get the state of a process
|
||||
GetProcessLog(id app.ProcessID) (*app.Log, error) // Get the logs of a process
|
||||
SearchProcessLogHistory(idpattern, refpattern, state string, from, to *time.Time) []app.LogHistorySearchResult // Search the log history of all processes
|
||||
GetPlayout(id TaskID, inputid string) (string, error) // Get the URL of the playout API for a process
|
||||
Probe(id TaskID) app.Probe // Probe a process
|
||||
ProbeWithTimeout(id TaskID, timeout time.Duration) app.Probe // Probe a process with specific timeout
|
||||
SetProcessMetadata(id TaskID, key string, data interface{}) error // Set metatdata to a process
|
||||
GetProcessMetadata(id TaskID, key string) (interface{}, error) // Get previously set metadata from a process
|
||||
GetPlayout(id app.ProcessID, inputid string) (string, error) // Get the URL of the playout API for a process
|
||||
Probe(id app.ProcessID) app.Probe // Probe a process
|
||||
ProbeWithTimeout(id app.ProcessID, timeout time.Duration) app.Probe // Probe a process with specific timeout
|
||||
SetProcessMetadata(id app.ProcessID, key string, data interface{}) error // Set metatdata to a process
|
||||
GetProcessMetadata(id app.ProcessID, key string) (interface{}, error) // Get previously set metadata from a process
|
||||
}
|
||||
|
||||
// Config is the required configuration for a new restreamer instance.
|
||||
@ -99,8 +99,8 @@ type task struct {
|
||||
metadata map[string]interface{}
|
||||
}
|
||||
|
||||
func (t *task) ID() TaskID {
|
||||
return TaskID{
|
||||
func (t *task) ID() app.ProcessID {
|
||||
return app.ProcessID{
|
||||
ID: t.id,
|
||||
Domain: t.domain,
|
||||
}
|
||||
@ -110,23 +110,6 @@ func (t *task) String() string {
|
||||
return t.ID().String()
|
||||
}
|
||||
|
||||
type TaskID struct {
|
||||
ID string
|
||||
Domain string
|
||||
}
|
||||
|
||||
func (t TaskID) String() string {
|
||||
return t.ID + "@" + t.Domain
|
||||
}
|
||||
|
||||
func (t TaskID) Equals(b TaskID) bool {
|
||||
if t.ID == b.ID && t.Domain == b.Domain {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type restream struct {
|
||||
id string
|
||||
name string
|
||||
@ -140,8 +123,8 @@ type restream struct {
|
||||
}
|
||||
replace replace.Replacer
|
||||
rewrite rewrite.Rewriter
|
||||
tasks map[TaskID]*task // domain:processid
|
||||
metadata map[string]interface{} // global metadata
|
||||
tasks map[app.ProcessID]*task // domain:ProcessID
|
||||
metadata map[string]interface{} // global metadata
|
||||
logger log.Logger
|
||||
|
||||
resources resources.Resources
|
||||
@ -386,7 +369,7 @@ func (r *restream) load() error {
|
||||
return err
|
||||
}
|
||||
|
||||
tasks := make(map[TaskID]*task)
|
||||
tasks := make(map[app.ProcessID]*task)
|
||||
|
||||
skills := r.ffmpeg.Skills()
|
||||
ffversion := skills.FFmpeg.Version
|
||||
@ -409,9 +392,10 @@ func (r *restream) load() error {
|
||||
process: p.Process,
|
||||
config: p.Process.Config.Clone(),
|
||||
logger: r.logger.WithFields(log.Fields{
|
||||
"id": p.Process.ID,
|
||||
"owner": p.Process.Owner,
|
||||
"domain": p.Process.Domain,
|
||||
"id": p.Process.ID,
|
||||
"owner": p.Process.Owner,
|
||||
"domain": p.Process.Domain,
|
||||
"reference": p.Process.Reference,
|
||||
}),
|
||||
}
|
||||
|
||||
@ -609,6 +593,7 @@ func (r *restream) createTask(config *app.Config) (*task, error) {
|
||||
|
||||
process := &app.Process{
|
||||
ID: config.ID,
|
||||
Owner: config.Owner,
|
||||
Domain: config.Domain,
|
||||
Reference: config.Reference,
|
||||
Config: config.Clone(),
|
||||
@ -624,12 +609,14 @@ func (r *restream) createTask(config *app.Config) (*task, error) {
|
||||
|
||||
t := &task{
|
||||
id: config.ID,
|
||||
owner: config.Owner,
|
||||
domain: config.Domain,
|
||||
reference: process.Reference,
|
||||
process: process,
|
||||
config: process.Config.Clone(),
|
||||
logger: r.logger.WithFields(log.Fields{
|
||||
"id": process.ID,
|
||||
"owner": process.Owner,
|
||||
"reference": process.Reference,
|
||||
"domain": process.Domain,
|
||||
}),
|
||||
@ -722,7 +709,7 @@ func (r *restream) onArgs(cfg *app.Config) func([]string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *restream) setCleanup(id TaskID, config *app.Config) {
|
||||
func (r *restream) setCleanup(id app.ProcessID, config *app.Config) {
|
||||
rePrefix := regexp.MustCompile(`^([a-z]+):`)
|
||||
|
||||
for _, output := range config.Output {
|
||||
@ -764,7 +751,7 @@ func (r *restream) setCleanup(id TaskID, config *app.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *restream) unsetCleanup(id TaskID) {
|
||||
func (r *restream) unsetCleanup(id app.ProcessID) {
|
||||
for _, fs := range r.fs.list {
|
||||
fs.UnsetCleanup(id.String())
|
||||
}
|
||||
@ -1024,7 +1011,7 @@ func validateOutputAddress(address, basedir string, ffmpeg ffmpeg.FFmpeg) (strin
|
||||
}
|
||||
|
||||
// resolveAddresses replaces the addresse reference from each input in a config with the actual address.
|
||||
func (r *restream) resolveAddresses(tasks map[TaskID]*task, config *app.Config) error {
|
||||
func (r *restream) resolveAddresses(tasks map[app.ProcessID]*task, config *app.Config) error {
|
||||
for i, input := range config.Input {
|
||||
// Resolve any references
|
||||
address, err := r.resolveAddress(tasks, config.ID, input.Address)
|
||||
@ -1041,7 +1028,7 @@ func (r *restream) resolveAddresses(tasks map[TaskID]*task, config *app.Config)
|
||||
}
|
||||
|
||||
// resolveAddress replaces the address reference with the actual address.
|
||||
func (r *restream) resolveAddress(tasks map[TaskID]*task, id, address string) (string, error) {
|
||||
func (r *restream) resolveAddress(tasks map[app.ProcessID]*task, id, address string) (string, error) {
|
||||
matches, err := parseAddressReference(address)
|
||||
if err != nil {
|
||||
return address, err
|
||||
@ -1176,7 +1163,7 @@ func parseAddressReference(address string) (map[string]string, error) {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
func (r *restream) UpdateProcess(id TaskID, config *app.Config) error {
|
||||
func (r *restream) UpdateProcess(id app.ProcessID, config *app.Config) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
@ -1241,11 +1228,11 @@ func (r *restream) UpdateProcess(id TaskID, config *app.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) GetProcessIDs(idpattern, refpattern, ownerpattern, domainpattern string) []TaskID {
|
||||
func (r *restream) GetProcessIDs(idpattern, refpattern, ownerpattern, domainpattern string) []app.ProcessID {
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
ids := []TaskID{}
|
||||
ids := []app.ProcessID{}
|
||||
|
||||
for _, t := range r.tasks {
|
||||
count := 0
|
||||
@ -1302,7 +1289,7 @@ func (r *restream) GetProcessIDs(idpattern, refpattern, ownerpattern, domainpatt
|
||||
continue
|
||||
}
|
||||
|
||||
tid := TaskID{
|
||||
tid := app.ProcessID{
|
||||
ID: t.id,
|
||||
Domain: t.domain,
|
||||
}
|
||||
@ -1313,7 +1300,7 @@ func (r *restream) GetProcessIDs(idpattern, refpattern, ownerpattern, domainpatt
|
||||
return ids
|
||||
}
|
||||
|
||||
func (r *restream) GetProcess(id TaskID) (*app.Process, error) {
|
||||
func (r *restream) GetProcess(id app.ProcessID) (*app.Process, error) {
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
@ -1327,7 +1314,7 @@ func (r *restream) GetProcess(id TaskID) (*app.Process, error) {
|
||||
return process, nil
|
||||
}
|
||||
|
||||
func (r *restream) DeleteProcess(id TaskID) error {
|
||||
func (r *restream) DeleteProcess(id app.ProcessID) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
@ -1341,7 +1328,7 @@ func (r *restream) DeleteProcess(id TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) deleteProcess(tid TaskID) error {
|
||||
func (r *restream) deleteProcess(tid app.ProcessID) error {
|
||||
task, ok := r.tasks[tid]
|
||||
if !ok {
|
||||
return ErrUnknownProcess
|
||||
@ -1359,7 +1346,7 @@ func (r *restream) deleteProcess(tid TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) StartProcess(id TaskID) error {
|
||||
func (r *restream) StartProcess(id app.ProcessID) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
@ -1373,7 +1360,7 @@ func (r *restream) StartProcess(id TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) startProcess(tid TaskID) error {
|
||||
func (r *restream) startProcess(tid app.ProcessID) error {
|
||||
task, ok := r.tasks[tid]
|
||||
if !ok {
|
||||
return ErrUnknownProcess
|
||||
@ -1404,7 +1391,7 @@ func (r *restream) startProcess(tid TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) StopProcess(id TaskID) error {
|
||||
func (r *restream) StopProcess(id app.ProcessID) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
@ -1418,7 +1405,7 @@ func (r *restream) StopProcess(id TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) stopProcess(tid TaskID) error {
|
||||
func (r *restream) stopProcess(tid app.ProcessID) error {
|
||||
task, ok := r.tasks[tid]
|
||||
if !ok {
|
||||
return ErrUnknownProcess
|
||||
@ -1443,14 +1430,14 @@ func (r *restream) stopProcess(tid TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) RestartProcess(id TaskID) error {
|
||||
func (r *restream) RestartProcess(id app.ProcessID) error {
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
return r.restartProcess(id)
|
||||
}
|
||||
|
||||
func (r *restream) restartProcess(tid TaskID) error {
|
||||
func (r *restream) restartProcess(tid app.ProcessID) error {
|
||||
task, ok := r.tasks[tid]
|
||||
if !ok {
|
||||
return ErrUnknownProcess
|
||||
@ -1472,7 +1459,7 @@ func (r *restream) restartProcess(tid TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) ReloadProcess(id TaskID) error {
|
||||
func (r *restream) ReloadProcess(id app.ProcessID) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
@ -1486,7 +1473,7 @@ func (r *restream) ReloadProcess(id TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) reloadProcess(tid TaskID) error {
|
||||
func (r *restream) reloadProcess(tid app.ProcessID) error {
|
||||
t, ok := r.tasks[tid]
|
||||
if !ok {
|
||||
return ErrUnknownProcess
|
||||
@ -1575,7 +1562,7 @@ func (r *restream) reloadProcess(tid TaskID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) GetProcessState(id TaskID) (*app.State, error) {
|
||||
func (r *restream) GetProcessState(id app.ProcessID) (*app.State, error) {
|
||||
state := &app.State{}
|
||||
|
||||
r.lock.RLock()
|
||||
@ -1735,7 +1722,7 @@ func convertProgressFromParser(progress *app.Progress, pprogress parse.Progress)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *restream) GetProcessLog(id TaskID) (*app.Log, error) {
|
||||
func (r *restream) GetProcessLog(id app.ProcessID) (*app.Log, error) {
|
||||
log := &app.Log{}
|
||||
|
||||
r.lock.RLock()
|
||||
@ -1851,11 +1838,11 @@ func (r *restream) SearchProcessLogHistory(idpattern, refpattern, state string,
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *restream) Probe(id TaskID) app.Probe {
|
||||
func (r *restream) Probe(id app.ProcessID) app.Probe {
|
||||
return r.ProbeWithTimeout(id, 20*time.Second)
|
||||
}
|
||||
|
||||
func (r *restream) ProbeWithTimeout(id TaskID, timeout time.Duration) app.Probe {
|
||||
func (r *restream) ProbeWithTimeout(id app.ProcessID, timeout time.Duration) app.Probe {
|
||||
appprobe := app.Probe{}
|
||||
|
||||
r.lock.RLock()
|
||||
@ -1954,7 +1941,7 @@ func (r *restream) ReloadSkills() error {
|
||||
return r.ffmpeg.ReloadSkills()
|
||||
}
|
||||
|
||||
func (r *restream) GetPlayout(id TaskID, inputid string) (string, error) {
|
||||
func (r *restream) GetPlayout(id app.ProcessID, inputid string) (string, error) {
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
@ -1977,7 +1964,7 @@ func (r *restream) GetPlayout(id TaskID, inputid string) (string, error) {
|
||||
|
||||
var ErrMetadataKeyNotFound = errors.New("unknown key")
|
||||
|
||||
func (r *restream) SetProcessMetadata(id TaskID, key string, data interface{}) error {
|
||||
func (r *restream) SetProcessMetadata(id app.ProcessID, key string, data interface{}) error {
|
||||
if len(key) == 0 {
|
||||
return fmt.Errorf("a key for storing the data has to be provided")
|
||||
}
|
||||
@ -2009,7 +1996,7 @@ func (r *restream) SetProcessMetadata(id TaskID, key string, data interface{}) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restream) GetProcessMetadata(id TaskID, key string) (interface{}, error) {
|
||||
func (r *restream) GetProcessMetadata(id app.ProcessID, key string) (interface{}, error) {
|
||||
r.lock.RLock()
|
||||
defer r.lock.RUnlock()
|
||||
|
||||
@ -2083,7 +2070,7 @@ func resolveStaticPlaceholders(config *app.Config, r replace.Replacer) {
|
||||
"processid": config.ID,
|
||||
"owner": config.Owner,
|
||||
"reference": config.Reference,
|
||||
"group": config.Domain,
|
||||
"domain": config.Domain,
|
||||
}
|
||||
|
||||
for i, option := range config.Options {
|
||||
@ -2098,12 +2085,14 @@ func resolveStaticPlaceholders(config *app.Config, r replace.Replacer) {
|
||||
for i, input := range config.Input {
|
||||
// Replace any known placeholders
|
||||
input.ID = r.Replace(input.ID, "processid", config.ID, vars, config, "input")
|
||||
input.ID = r.Replace(input.ID, "domain", config.Domain, vars, config, "input")
|
||||
input.ID = r.Replace(input.ID, "reference", config.Reference, vars, config, "input")
|
||||
|
||||
vars["inputid"] = input.ID
|
||||
|
||||
input.Address = r.Replace(input.Address, "inputid", input.ID, vars, config, "input")
|
||||
input.Address = r.Replace(input.Address, "processid", config.ID, vars, config, "input")
|
||||
input.Address = r.Replace(input.Address, "domain", config.Domain, vars, config, "input")
|
||||
input.Address = r.Replace(input.Address, "reference", config.Reference, vars, config, "input")
|
||||
input.Address = r.Replace(input.Address, "diskfs", "", vars, config, "input")
|
||||
input.Address = r.Replace(input.Address, "memfs", "", vars, config, "input")
|
||||
@ -2115,6 +2104,7 @@ func resolveStaticPlaceholders(config *app.Config, r replace.Replacer) {
|
||||
// Replace any known placeholders
|
||||
option = r.Replace(option, "inputid", input.ID, vars, config, "input")
|
||||
option = r.Replace(option, "processid", config.ID, vars, config, "input")
|
||||
option = r.Replace(option, "domain", config.Domain, vars, config, "input")
|
||||
option = r.Replace(option, "reference", config.Reference, vars, config, "input")
|
||||
option = r.Replace(option, "diskfs", "", vars, config, "input")
|
||||
option = r.Replace(option, "memfs", "", vars, config, "input")
|
||||
@ -2132,12 +2122,14 @@ func resolveStaticPlaceholders(config *app.Config, r replace.Replacer) {
|
||||
for i, output := range config.Output {
|
||||
// Replace any known placeholders
|
||||
output.ID = r.Replace(output.ID, "processid", config.ID, vars, config, "output")
|
||||
output.ID = r.Replace(output.ID, "domain", config.Domain, vars, config, "output")
|
||||
output.ID = r.Replace(output.ID, "reference", config.Reference, vars, config, "output")
|
||||
|
||||
vars["outputid"] = output.ID
|
||||
|
||||
output.Address = r.Replace(output.Address, "outputid", output.ID, vars, config, "output")
|
||||
output.Address = r.Replace(output.Address, "processid", config.ID, vars, config, "output")
|
||||
output.Address = r.Replace(output.Address, "domain", config.Domain, vars, config, "output")
|
||||
output.Address = r.Replace(output.Address, "reference", config.Reference, vars, config, "output")
|
||||
output.Address = r.Replace(output.Address, "diskfs", "", vars, config, "output")
|
||||
output.Address = r.Replace(output.Address, "memfs", "", vars, config, "output")
|
||||
@ -2149,6 +2141,7 @@ func resolveStaticPlaceholders(config *app.Config, r replace.Replacer) {
|
||||
// Replace any known placeholders
|
||||
option = r.Replace(option, "outputid", output.ID, vars, config, "output")
|
||||
option = r.Replace(option, "processid", config.ID, vars, config, "output")
|
||||
option = r.Replace(option, "domain", config.Domain, vars, config, "output")
|
||||
option = r.Replace(option, "reference", config.Reference, vars, config, "output")
|
||||
option = r.Replace(option, "diskfs", "", vars, config, "output")
|
||||
option = r.Replace(option, "memfs", "", vars, config, "output")
|
||||
@ -2161,6 +2154,7 @@ func resolveStaticPlaceholders(config *app.Config, r replace.Replacer) {
|
||||
// Replace any known placeholders
|
||||
cleanup.Pattern = r.Replace(cleanup.Pattern, "outputid", output.ID, vars, config, "output")
|
||||
cleanup.Pattern = r.Replace(cleanup.Pattern, "processid", config.ID, vars, config, "output")
|
||||
cleanup.Pattern = r.Replace(cleanup.Pattern, "domain", config.Domain, vars, config, "output")
|
||||
cleanup.Pattern = r.Replace(cleanup.Pattern, "reference", config.Reference, vars, config, "output")
|
||||
|
||||
output.Cleanup[j] = cleanup
|
||||
|
||||
@ -134,7 +134,7 @@ func TestAddProcess(t *testing.T) {
|
||||
process := getDummyProcess()
|
||||
require.NotNil(t, process)
|
||||
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
_, err = rs.GetProcess(tid)
|
||||
require.Equal(t, ErrUnknownProcess, err)
|
||||
@ -156,7 +156,7 @@ func TestAutostartProcess(t *testing.T) {
|
||||
process := getDummyProcess()
|
||||
process.Autostart = true
|
||||
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
@ -239,7 +239,7 @@ func TestRemoveProcess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
err = rs.AddProcess(process)
|
||||
require.Equal(t, nil, err, "Failed to add process (%s)", err)
|
||||
@ -258,12 +258,12 @@ func TestUpdateProcess(t *testing.T) {
|
||||
process1 := getDummyProcess()
|
||||
require.NotNil(t, process1)
|
||||
process1.ID = "process1"
|
||||
tid1 := TaskID{ID: process1.ID}
|
||||
tid1 := app.ProcessID{ID: process1.ID}
|
||||
|
||||
process2 := getDummyProcess()
|
||||
require.NotNil(t, process2)
|
||||
process2.ID = "process2"
|
||||
tid2 := TaskID{ID: process2.ID}
|
||||
tid2 := app.ProcessID{ID: process2.ID}
|
||||
|
||||
err = rs.AddProcess(process1)
|
||||
require.Equal(t, nil, err)
|
||||
@ -282,7 +282,7 @@ func TestUpdateProcess(t *testing.T) {
|
||||
process3 := getDummyProcess()
|
||||
require.NotNil(t, process3)
|
||||
process3.ID = "process2"
|
||||
tid3 := TaskID{ID: process3.ID}
|
||||
tid3 := app.ProcessID{ID: process3.ID}
|
||||
|
||||
err = rs.UpdateProcess(tid1, process3)
|
||||
require.Error(t, err)
|
||||
@ -308,7 +308,7 @@ func TestUpdateSameHashProcess(t *testing.T) {
|
||||
|
||||
config := getDummyProcess()
|
||||
require.NotNil(t, config)
|
||||
tid := TaskID{ID: config.ID}
|
||||
tid := app.ProcessID{ID: config.ID}
|
||||
|
||||
err = rs.AddProcess(config)
|
||||
require.Equal(t, nil, err)
|
||||
@ -339,7 +339,7 @@ func TestUpdateProcessLogHistoryTransfer(t *testing.T) {
|
||||
require.NotNil(t, p)
|
||||
p.ID = "process1"
|
||||
|
||||
tid1 := TaskID{ID: p.ID}
|
||||
tid1 := app.ProcessID{ID: p.ID}
|
||||
|
||||
err = rs.AddProcess(p)
|
||||
require.Equal(t, nil, err)
|
||||
@ -363,7 +363,7 @@ func TestUpdateProcessLogHistoryTransfer(t *testing.T) {
|
||||
err = rs.UpdateProcess(tid1, p)
|
||||
require.NoError(t, err)
|
||||
|
||||
tid2 := TaskID{ID: p.ID}
|
||||
tid2 := app.ProcessID{ID: p.ID}
|
||||
|
||||
_, err = rs.GetProcess(tid2)
|
||||
require.NoError(t, err)
|
||||
@ -393,7 +393,7 @@ func TestUpdateProcessMetadataTransfer(t *testing.T) {
|
||||
require.NotNil(t, p)
|
||||
p.ID = "process1"
|
||||
|
||||
tid1 := TaskID{ID: p.ID}
|
||||
tid1 := app.ProcessID{ID: p.ID}
|
||||
|
||||
err = rs.AddProcess(p)
|
||||
require.Equal(t, nil, err)
|
||||
@ -408,7 +408,7 @@ func TestUpdateProcessMetadataTransfer(t *testing.T) {
|
||||
err = rs.UpdateProcess(tid1, p)
|
||||
require.NoError(t, err)
|
||||
|
||||
tid2 := TaskID{ID: p.ID}
|
||||
tid2 := app.ProcessID{ID: p.ID}
|
||||
|
||||
_, err = rs.GetProcess(tid2)
|
||||
require.NoError(t, err)
|
||||
@ -427,19 +427,19 @@ func TestGetProcess(t *testing.T) {
|
||||
process1 := getDummyProcess()
|
||||
process1.ID = "foo_aaa_1"
|
||||
process1.Reference = "foo_aaa_1"
|
||||
tid1 := TaskID{ID: process1.ID}
|
||||
tid1 := app.ProcessID{ID: process1.ID}
|
||||
process2 := getDummyProcess()
|
||||
process2.ID = "bar_bbb_2"
|
||||
process2.Reference = "bar_bbb_2"
|
||||
tid2 := TaskID{ID: process2.ID}
|
||||
tid2 := app.ProcessID{ID: process2.ID}
|
||||
process3 := getDummyProcess()
|
||||
process3.ID = "foo_ccc_3"
|
||||
process3.Reference = "foo_ccc_3"
|
||||
tid3 := TaskID{ID: process3.ID}
|
||||
tid3 := app.ProcessID{ID: process3.ID}
|
||||
process4 := getDummyProcess()
|
||||
process4.ID = "bar_ddd_4"
|
||||
process4.Reference = "bar_ddd_4"
|
||||
tid4 := TaskID{ID: process4.ID}
|
||||
tid4 := app.ProcessID{ID: process4.ID}
|
||||
|
||||
rs.AddProcess(process1)
|
||||
rs.AddProcess(process2)
|
||||
@ -460,31 +460,31 @@ func TestGetProcess(t *testing.T) {
|
||||
|
||||
list := rs.GetProcessIDs("", "", "", "")
|
||||
require.Len(t, list, 4)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "foo_aaa_1"}, {ID: "bar_bbb_2"}, {ID: "foo_ccc_3"}, {ID: "bar_ddd_4"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "foo_aaa_1"}, {ID: "bar_bbb_2"}, {ID: "foo_ccc_3"}, {ID: "bar_ddd_4"}}, list)
|
||||
|
||||
list = rs.GetProcessIDs("foo_*", "", "", "")
|
||||
require.Len(t, list, 2)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "foo_aaa_1"}, {ID: "foo_ccc_3"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "foo_aaa_1"}, {ID: "foo_ccc_3"}}, list)
|
||||
|
||||
list = rs.GetProcessIDs("bar_*", "", "", "")
|
||||
require.Len(t, list, 2)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "bar_bbb_2"}, {ID: "bar_ddd_4"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "bar_bbb_2"}, {ID: "bar_ddd_4"}}, list)
|
||||
|
||||
list = rs.GetProcessIDs("*_bbb_*", "", "", "")
|
||||
require.Len(t, list, 1)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "bar_bbb_2"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "bar_bbb_2"}}, list)
|
||||
|
||||
list = rs.GetProcessIDs("", "foo_*", "", "")
|
||||
require.Len(t, list, 2)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "foo_aaa_1"}, {ID: "foo_ccc_3"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "foo_aaa_1"}, {ID: "foo_ccc_3"}}, list)
|
||||
|
||||
list = rs.GetProcessIDs("", "bar_*", "", "")
|
||||
require.Len(t, list, 2)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "bar_bbb_2"}, {ID: "bar_ddd_4"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "bar_bbb_2"}, {ID: "bar_ddd_4"}}, list)
|
||||
|
||||
list = rs.GetProcessIDs("", "*_bbb_*", "", "")
|
||||
require.Len(t, list, 1)
|
||||
require.ElementsMatch(t, []TaskID{{ID: "bar_bbb_2"}}, list)
|
||||
require.ElementsMatch(t, []app.ProcessID{{ID: "bar_bbb_2"}}, list)
|
||||
}
|
||||
|
||||
func TestStartProcess(t *testing.T) {
|
||||
@ -492,11 +492,11 @@ func TestStartProcess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
err = rs.StartProcess(TaskID{ID: "foobar"})
|
||||
err = rs.StartProcess(app.ProcessID{ID: "foobar"})
|
||||
require.NotEqual(t, nil, err, "shouldn't be able to start non-existing process")
|
||||
|
||||
err = rs.StartProcess(tid)
|
||||
@ -519,12 +519,12 @@ func TestStopProcess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
rs.StartProcess(tid)
|
||||
|
||||
err = rs.StopProcess(TaskID{ID: "foobar"})
|
||||
err = rs.StopProcess(app.ProcessID{ID: "foobar"})
|
||||
require.NotEqual(t, nil, err, "shouldn't be able to stop non-existing process")
|
||||
|
||||
err = rs.StopProcess(tid)
|
||||
@ -545,11 +545,11 @@ func TestRestartProcess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
err = rs.RestartProcess(TaskID{ID: "foobar"})
|
||||
err = rs.RestartProcess(app.ProcessID{ID: "foobar"})
|
||||
require.NotEqual(t, nil, err, "shouldn't be able to restart non-existing process")
|
||||
|
||||
err = rs.RestartProcess(tid)
|
||||
@ -571,11 +571,11 @@ func TestReloadProcess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
err = rs.ReloadProcess(TaskID{ID: "foobar"})
|
||||
err = rs.ReloadProcess(app.ProcessID{ID: "foobar"})
|
||||
require.NotEqual(t, nil, err, "shouldn't be able to reload non-existing process")
|
||||
|
||||
err = rs.ReloadProcess(tid)
|
||||
@ -605,7 +605,7 @@ func TestParseProcessPattern(t *testing.T) {
|
||||
process := getDummyProcess()
|
||||
process.LogPatterns = []string{"libx264"}
|
||||
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
rs.StartProcess(tid)
|
||||
@ -626,7 +626,7 @@ func TestProbeProcess(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
@ -640,7 +640,7 @@ func TestProcessMetadata(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
@ -665,11 +665,11 @@ func TestLog(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
_, err = rs.GetProcessLog(TaskID{ID: "foobar"})
|
||||
_, err = rs.GetProcessLog(app.ProcessID{ID: "foobar"})
|
||||
require.Error(t, err)
|
||||
|
||||
log, err := rs.GetProcessLog(tid)
|
||||
@ -704,7 +704,7 @@ func TestLogTransfer(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
err = rs.AddProcess(process)
|
||||
require.NoError(t, err)
|
||||
@ -730,13 +730,13 @@ func TestPlayoutNoRange(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
process.Input[0].Address = "playout:" + process.Input[0].Address
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
_, err = rs.GetPlayout(TaskID{ID: "foobar"}, process.Input[0].ID)
|
||||
_, err = rs.GetPlayout(app.ProcessID{ID: "foobar"}, process.Input[0].ID)
|
||||
require.Equal(t, ErrUnknownProcess, err)
|
||||
|
||||
_, err = rs.GetPlayout(tid, "foobar")
|
||||
@ -754,13 +754,13 @@ func TestPlayoutRange(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
process := getDummyProcess()
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
process.Input[0].Address = "playout:" + process.Input[0].Address
|
||||
|
||||
rs.AddProcess(process)
|
||||
|
||||
_, err = rs.GetPlayout(TaskID{ID: "foobar"}, process.Input[0].ID)
|
||||
_, err = rs.GetPlayout(app.ProcessID{ID: "foobar"}, process.Input[0].ID)
|
||||
require.Equal(t, ErrUnknownProcess, err)
|
||||
|
||||
_, err = rs.GetPlayout(tid, "foobar")
|
||||
@ -869,9 +869,9 @@ func TestTeeAddressReference(t *testing.T) {
|
||||
|
||||
r := rs.(*restream)
|
||||
|
||||
require.Equal(t, "http://example.com/live.m3u8", r.tasks[TaskID{ID: "process2"}].config.Input[0].Address)
|
||||
require.Equal(t, "http://example.com/live.m3u8", r.tasks[TaskID{ID: "process3"}].config.Input[0].Address)
|
||||
require.Equal(t, "rtmp://example.com/live.stream?token=123", r.tasks[TaskID{ID: "process4"}].config.Input[0].Address)
|
||||
require.Equal(t, "http://example.com/live.m3u8", r.tasks[app.ProcessID{ID: "process2"}].config.Input[0].Address)
|
||||
require.Equal(t, "http://example.com/live.m3u8", r.tasks[app.ProcessID{ID: "process3"}].config.Input[0].Address)
|
||||
require.Equal(t, "rtmp://example.com/live.stream?token=123", r.tasks[app.ProcessID{ID: "process4"}].config.Input[0].Address)
|
||||
}
|
||||
|
||||
func TestConfigValidation(t *testing.T) {
|
||||
@ -1449,7 +1449,7 @@ func TestProcessReplacer(t *testing.T) {
|
||||
LogPatterns: []string{},
|
||||
}
|
||||
|
||||
task, ok := rs.tasks[TaskID{ID: "314159265359"}]
|
||||
task, ok := rs.tasks[app.ProcessID{ID: "314159265359"}]
|
||||
require.True(t, ok)
|
||||
|
||||
require.Equal(t, process, task.config)
|
||||
@ -1466,7 +1466,7 @@ func TestProcessLogPattern(t *testing.T) {
|
||||
process.Autostart = false
|
||||
process.Reconnect = true
|
||||
|
||||
tid := TaskID{ID: process.ID}
|
||||
tid := app.ProcessID{ID: process.ID}
|
||||
|
||||
err = rs.AddProcess(process)
|
||||
require.NoError(t, err)
|
||||
@ -1500,7 +1500,7 @@ func TestProcessLimit(t *testing.T) {
|
||||
|
||||
rs := rsi.(*restream)
|
||||
|
||||
task, ok := rs.tasks[TaskID{ID: process.ID}]
|
||||
task, ok := rs.tasks[app.ProcessID{ID: process.ID}]
|
||||
require.True(t, ok)
|
||||
|
||||
status := task.ffmpeg.Status()
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package json
|
||||
|
||||
import "github.com/datarhei/core/v16/restream/app"
|
||||
import (
|
||||
"github.com/datarhei/core/v16/restream/app"
|
||||
)
|
||||
|
||||
type ProcessConfigIOCleanup struct {
|
||||
Pattern string `json:"pattern"`
|
||||
|
||||
46
vendor/github.com/datarhei/core-client-go/v16/api/process.go
generated
vendored
46
vendor/github.com/datarhei/core-client-go/v16/api/process.go
generated
vendored
@ -3,10 +3,12 @@ package api
|
||||
// Process represents all information on a process
|
||||
type Process struct {
|
||||
ID string `json:"id" jsonschema:"minLength=1"`
|
||||
Owner string `json:"owner"`
|
||||
Domain string `json:"domain"`
|
||||
Type string `json:"type" jsonschema:"enum=ffmpeg"`
|
||||
Reference string `json:"reference"`
|
||||
CreatedAt int64 `json:"created_at" jsonschema:"minimum=0" format:"int64"`
|
||||
UpdatedAt int64 `json:"updated_at" jsonschema:"minimum=0" format:"int64"`
|
||||
CreatedAt int64 `json:"created_at" jsonschema:"minimum=0" format:"int64"` // Unix timestamp
|
||||
UpdatedAt int64 `json:"updated_at" jsonschema:"minimum=0" format:"int64"` // Unix timestamp
|
||||
Config *ProcessConfig `json:"config,omitempty"`
|
||||
State *ProcessState `json:"state,omitempty"`
|
||||
Report *ProcessReport `json:"report,omitempty"`
|
||||
@ -24,29 +26,31 @@ type ProcessConfigIO struct {
|
||||
type ProcessConfigIOCleanup struct {
|
||||
Pattern string `json:"pattern" validate:"required"`
|
||||
MaxFiles uint `json:"max_files" format:"uint"`
|
||||
MaxFileAge uint `json:"max_file_age_seconds" format:"uint"`
|
||||
MaxFileAge uint `json:"max_file_age_seconds" format:"uint"` // seconds
|
||||
PurgeOnDelete bool `json:"purge_on_delete"`
|
||||
}
|
||||
|
||||
type ProcessConfigLimits struct {
|
||||
CPU float64 `json:"cpu_usage" jsonschema:"minimum=0,maximum=100"`
|
||||
Memory uint64 `json:"memory_mbytes" jsonschema:"minimum=0" format:"uint64"`
|
||||
WaitFor uint64 `json:"waitfor_seconds" jsonschema:"minimum=0" format:"uint64"`
|
||||
CPU float64 `json:"cpu_usage" jsonschema:"minimum=0"` // percent 0-100*ncpu
|
||||
Memory uint64 `json:"memory_mbytes" jsonschema:"minimum=0" format:"uint64"` // megabytes
|
||||
WaitFor uint64 `json:"waitfor_seconds" jsonschema:"minimum=0" format:"uint64"` // seconds
|
||||
}
|
||||
|
||||
// ProcessConfig represents the configuration of an ffmpeg process
|
||||
type ProcessConfig struct {
|
||||
ID string `json:"id"`
|
||||
Owner string `json:"owner"`
|
||||
Domain string `json:"domain"`
|
||||
Type string `json:"type" validate:"oneof='ffmpeg' ''" jsonschema:"enum=ffmpeg,enum="`
|
||||
Reference string `json:"reference"`
|
||||
Input []ProcessConfigIO `json:"input" validate:"required"`
|
||||
Output []ProcessConfigIO `json:"output" validate:"required"`
|
||||
Options []string `json:"options"`
|
||||
Reconnect bool `json:"reconnect"`
|
||||
ReconnectDelay uint64 `json:"reconnect_delay_seconds" format:"uint64"`
|
||||
ReconnectDelay uint64 `json:"reconnect_delay_seconds" format:"uint64"` // seconds
|
||||
Autostart bool `json:"autostart"`
|
||||
StaleTimeout uint64 `json:"stale_timeout_seconds" format:"uint64"`
|
||||
Timeout uint64 `json:"runtime_duration_seconds" format:"uint64"`
|
||||
StaleTimeout uint64 `json:"stale_timeout_seconds" format:"uint64"` // seconds
|
||||
Timeout uint64 `json:"runtime_duration_seconds" format:"uint64"` // seconds
|
||||
Scheduler string `json:"scheduler"`
|
||||
LogPatterns []string `json:"log_patterns"`
|
||||
Limits ProcessConfigLimits `json:"limits"`
|
||||
@ -57,29 +61,29 @@ type ProcessConfig struct {
|
||||
type ProcessState struct {
|
||||
Order string `json:"order" jsonschema:"enum=start,enum=stop"`
|
||||
State string `json:"exec" jsonschema:"enum=finished,enum=starting,enum=running,enum=finishing,enum=killed,enum=failed"`
|
||||
Runtime int64 `json:"runtime_seconds" jsonschema:"minimum=0" format:"int64"`
|
||||
Reconnect int64 `json:"reconnect_seconds" format:"int64"`
|
||||
Runtime int64 `json:"runtime_seconds" jsonschema:"minimum=0" format:"int64"` // seconds
|
||||
Reconnect int64 `json:"reconnect_seconds" format:"int64"` // seconds
|
||||
LastLog string `json:"last_logline"`
|
||||
Progress *Progress `json:"progress"`
|
||||
Memory uint64 `json:"memory_bytes" format:"uint64"`
|
||||
CPU float64 `json:"cpu_usage" swaggertype:"number" jsonschema:"type=number"`
|
||||
Memory uint64 `json:"memory_bytes" format:"uint64"` // bytes
|
||||
CPU float64 `json:"cpu_usage" swaggertype:"number" jsonschema:"type=number"` // percent 0-100*ncpu
|
||||
Resources ProcessUsage `json:"resources"`
|
||||
Command []string `json:"command"`
|
||||
}
|
||||
|
||||
type ProcessUsageCPU struct {
|
||||
NCPU float64 `json:"ncpu" swaggertype:"number" jsonschema:"type=number"`
|
||||
Current float64 `json:"cur" swaggertype:"number" jsonschema:"type=number"`
|
||||
Average float64 `json:"avg" swaggertype:"number" jsonschema:"type=number"`
|
||||
Max float64 `json:"max" swaggertype:"number" jsonschema:"type=number"`
|
||||
Limit float64 `json:"limit" swaggertype:"number" jsonschema:"type=number"`
|
||||
Current float64 `json:"cur" swaggertype:"number" jsonschema:"type=number"` // percent 0-100*ncpu
|
||||
Average float64 `json:"avg" swaggertype:"number" jsonschema:"type=number"` // percent 0-100*ncpu
|
||||
Max float64 `json:"max" swaggertype:"number" jsonschema:"type=number"` // percent 0-100*ncpu
|
||||
Limit float64 `json:"limit" swaggertype:"number" jsonschema:"type=number"` // percent 0-100*ncpu
|
||||
}
|
||||
|
||||
type ProcessUsageMemory struct {
|
||||
Current uint64 `json:"cur" format:"uint64"`
|
||||
Average float64 `json:"avg" swaggertype:"number" jsonschema:"type=number"`
|
||||
Max uint64 `json:"max" format:"uint64"`
|
||||
Limit uint64 `json:"limit" format:"uint64"`
|
||||
Current uint64 `json:"cur" format:"uint64"` // bytes
|
||||
Average float64 `json:"avg" swaggertype:"number" jsonschema:"type=number"` // bytes
|
||||
Max uint64 `json:"max" format:"uint64"` // bytes
|
||||
Limit uint64 `json:"limit" format:"uint64"` // bytes
|
||||
}
|
||||
|
||||
type ProcessUsage struct {
|
||||
|
||||
39
vendor/github.com/datarhei/core-client-go/v16/client.go
generated
vendored
39
vendor/github.com/datarhei/core-client-go/v16/client.go
generated
vendored
@ -74,18 +74,18 @@ type RestClient interface {
|
||||
MetricsList() ([]api.MetricsDescription, error) // GET /v3/metrics
|
||||
Metrics(query api.MetricsQuery) (api.MetricsResponse, error) // POST /v3/metrics
|
||||
|
||||
ProcessList(opts ProcessListOptions) ([]api.Process, error) // GET /v3/process
|
||||
ProcessAdd(p api.ProcessConfig) error // POST /v3/process
|
||||
Process(id string, filter []string) (api.Process, error) // GET /v3/process/{id}
|
||||
ProcessUpdate(id string, p api.ProcessConfig) error // PUT /v3/process/{id}
|
||||
ProcessDelete(id string) error // DELETE /v3/process/{id}
|
||||
ProcessCommand(id, command string) error // PUT /v3/process/{id}/command
|
||||
ProcessProbe(id string) (api.Probe, error) // GET /v3/process/{id}/probe
|
||||
ProcessConfig(id string) (api.ProcessConfig, error) // GET /v3/process/{id}/config
|
||||
ProcessReport(id string) (api.ProcessReport, error) // GET /v3/process/{id}/report
|
||||
ProcessState(id string) (api.ProcessState, error) // GET /v3/process/{id}/state
|
||||
ProcessMetadata(id, key string) (api.Metadata, error) // GET /v3/process/{id}/metadata/{key}
|
||||
ProcessMetadataSet(id, key string, metadata api.Metadata) error // PUT /v3/process/{id}/metadata/{key}
|
||||
ProcessList(opts ProcessListOptions) ([]api.Process, error) // GET /v3/process
|
||||
ProcessAdd(p api.ProcessConfig) error // POST /v3/process
|
||||
Process(id ProcessID, filter []string) (api.Process, error) // GET /v3/process/{id}
|
||||
ProcessUpdate(id ProcessID, p api.ProcessConfig) error // PUT /v3/process/{id}
|
||||
ProcessDelete(id ProcessID) error // DELETE /v3/process/{id}
|
||||
ProcessCommand(id ProcessID, command string) error // PUT /v3/process/{id}/command
|
||||
ProcessProbe(id ProcessID) (api.Probe, error) // GET /v3/process/{id}/probe
|
||||
ProcessConfig(id ProcessID) (api.ProcessConfig, error) // GET /v3/process/{id}/config
|
||||
ProcessReport(id ProcessID) (api.ProcessReport, error) // GET /v3/process/{id}/report
|
||||
ProcessState(id ProcessID) (api.ProcessState, error) // GET /v3/process/{id}/state
|
||||
ProcessMetadata(id ProcessID, key string) (api.Metadata, error) // GET /v3/process/{id}/metadata/{key}
|
||||
ProcessMetadataSet(id ProcessID, key string, metadata api.Metadata) error // PUT /v3/process/{id}/metadata/{key}
|
||||
|
||||
RTMPChannels() ([]api.RTMPChannel, error) // GET /v3/rtmp
|
||||
SRTChannels() ([]api.SRTChannel, error) // GET /v3/srt
|
||||
@ -96,7 +96,7 @@ type RestClient interface {
|
||||
Skills() (api.Skills, error) // GET /v3/skills
|
||||
SkillsReload() error // GET /v3/skills/reload
|
||||
|
||||
WidgetProcess(id string) (api.WidgetProcess, error) // GET /v3/widget/process/{id}
|
||||
WidgetProcess(id ProcessID) (api.WidgetProcess, error) // GET /v3/widget/process/{id}
|
||||
}
|
||||
|
||||
// Config is the configuration for a new REST API client.
|
||||
@ -451,12 +451,17 @@ func (r *restclient) request(req *http.Request) (int, io.ReadCloser, error) {
|
||||
return resp.StatusCode, resp.Body, nil
|
||||
}
|
||||
|
||||
func (r *restclient) stream(method, path, contentType string, data io.Reader) (io.ReadCloser, error) {
|
||||
func (r *restclient) stream(method, path string, query *url.Values, contentType string, data io.Reader) (io.ReadCloser, error) {
|
||||
if err := r.checkVersion(method, r.prefix+path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, r.address+r.prefix+path, data)
|
||||
u := r.address + r.prefix + path
|
||||
if query != nil {
|
||||
u += "?" + query.Encode()
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, u, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -516,8 +521,8 @@ func (r *restclient) stream(method, path, contentType string, data io.Reader) (i
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func (r *restclient) call(method, path, contentType string, data io.Reader) ([]byte, error) {
|
||||
body, err := r.stream(method, path, contentType, data)
|
||||
func (r *restclient) call(method, path string, query *url.Values, contentType string, data io.Reader) ([]byte, error) {
|
||||
body, err := r.stream(method, path, query, contentType, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
6
vendor/github.com/datarhei/core-client-go/v16/config.go
generated
vendored
6
vendor/github.com/datarhei/core-client-go/v16/config.go
generated
vendored
@ -16,7 +16,7 @@ type configVersion struct {
|
||||
func (r *restclient) Config() (int64, api.Config, error) {
|
||||
version := configVersion{}
|
||||
|
||||
data, err := r.call("GET", "/v3/config", "", nil)
|
||||
data, err := r.call("GET", "/v3/config", nil, "", nil)
|
||||
if err != nil {
|
||||
return 0, api.Config{}, err
|
||||
}
|
||||
@ -69,7 +69,7 @@ func (r *restclient) ConfigSet(config interface{}) error {
|
||||
e := json.NewEncoder(&buf)
|
||||
e.Encode(config)
|
||||
|
||||
_, err := r.call("PUT", "/v3/config", "application/json", &buf)
|
||||
_, err := r.call("PUT", "/v3/config", nil, "application/json", &buf)
|
||||
|
||||
if e, ok := err.(api.Error); ok {
|
||||
if e.Code == 409 {
|
||||
@ -85,7 +85,7 @@ func (r *restclient) ConfigSet(config interface{}) error {
|
||||
}
|
||||
|
||||
func (r *restclient) ConfigReload() error {
|
||||
_, err := r.call("GET", "/v3/config/reload", "", nil)
|
||||
_, err := r.call("GET", "/v3/config/reload", nil, "", nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
18
vendor/github.com/datarhei/core-client-go/v16/fs.go
generated
vendored
18
vendor/github.com/datarhei/core-client-go/v16/fs.go
generated
vendored
@ -23,12 +23,12 @@ const (
|
||||
func (r *restclient) FilesystemList(name, pattern, sort, order string) ([]api.FileInfo, error) {
|
||||
var files []api.FileInfo
|
||||
|
||||
values := url.Values{}
|
||||
values.Set("glob", pattern)
|
||||
values.Set("sort", sort)
|
||||
values.Set("order", order)
|
||||
query := &url.Values{}
|
||||
query.Set("glob", pattern)
|
||||
query.Set("sort", sort)
|
||||
query.Set("order", order)
|
||||
|
||||
data, err := r.call("GET", "/v3/fs/"+url.PathEscape(name)+"?"+values.Encode(), "", nil)
|
||||
data, err := r.call("GET", "/v3/fs/"+url.PathEscape(name), query, "", nil)
|
||||
if err != nil {
|
||||
return files, err
|
||||
}
|
||||
@ -43,7 +43,7 @@ func (r *restclient) FilesystemHasFile(name, path string) bool {
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
_, err := r.call("HEAD", "/v3/fs/"+url.PathEscape(name)+path, "", nil)
|
||||
_, err := r.call("HEAD", "/v3/fs/"+url.PathEscape(name)+path, nil, "", nil)
|
||||
|
||||
return err == nil
|
||||
}
|
||||
@ -53,7 +53,7 @@ func (r *restclient) FilesystemGetFile(name, path string) (io.ReadCloser, error)
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
return r.stream("GET", "/v3/fs/"+url.PathEscape(name)+path, "", nil)
|
||||
return r.stream("GET", "/v3/fs/"+url.PathEscape(name)+path, nil, "", nil)
|
||||
}
|
||||
|
||||
func (r *restclient) FilesystemDeleteFile(name, path string) error {
|
||||
@ -61,7 +61,7 @@ func (r *restclient) FilesystemDeleteFile(name, path string) error {
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
_, err := r.call("DELETE", "/v3/fs/"+url.PathEscape(name)+path, "", nil)
|
||||
_, err := r.call("DELETE", "/v3/fs/"+url.PathEscape(name)+path, nil, "", nil)
|
||||
|
||||
return err
|
||||
}
|
||||
@ -71,7 +71,7 @@ func (r *restclient) FilesystemAddFile(name, path string, data io.Reader) error
|
||||
path = "/" + path
|
||||
}
|
||||
|
||||
_, err := r.call("PUT", "/v3/fs/"+url.PathEscape(name)+path, "application/data", data)
|
||||
_, err := r.call("PUT", "/v3/fs/"+url.PathEscape(name)+path, nil, "application/data", data)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
2
vendor/github.com/datarhei/core-client-go/v16/graph.go
generated
vendored
2
vendor/github.com/datarhei/core-client-go/v16/graph.go
generated
vendored
@ -14,7 +14,7 @@ func (r *restclient) Graph(query api.GraphQuery) (api.GraphResponse, error) {
|
||||
e := json.NewEncoder(&buf)
|
||||
e.Encode(query)
|
||||
|
||||
data, err := r.call("PUT", "/v3/graph", "application/json", &buf)
|
||||
data, err := r.call("PUT", "/v3/graph", nil, "application/json", &buf)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
6
vendor/github.com/datarhei/core-client-go/v16/log.go
generated
vendored
6
vendor/github.com/datarhei/core-client-go/v16/log.go
generated
vendored
@ -2,6 +2,7 @@ package coreclient
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
|
||||
"github.com/datarhei/core-client-go/v16/api"
|
||||
)
|
||||
@ -9,7 +10,10 @@ import (
|
||||
func (r *restclient) Log() ([]api.LogEvent, error) {
|
||||
var log []api.LogEvent
|
||||
|
||||
data, err := r.call("GET", "/v3/log?format=raw", "", nil)
|
||||
query := &url.Values{}
|
||||
query.Set("format", "raw")
|
||||
|
||||
data, err := r.call("GET", "/v3/log", query, "", nil)
|
||||
if err != nil {
|
||||
return log, err
|
||||
}
|
||||
|
||||
4
vendor/github.com/datarhei/core-client-go/v16/metadata.go
generated
vendored
4
vendor/github.com/datarhei/core-client-go/v16/metadata.go
generated
vendored
@ -16,7 +16,7 @@ func (r *restclient) Metadata(key string) (api.Metadata, error) {
|
||||
path += "/" + url.PathEscape(key)
|
||||
}
|
||||
|
||||
data, err := r.call("GET", path, "", nil)
|
||||
data, err := r.call("GET", path, nil, "", nil)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
@ -37,7 +37,7 @@ func (r *restclient) MetadataSet(key string, metadata api.Metadata) error {
|
||||
path += "/" + url.PathEscape(key)
|
||||
}
|
||||
|
||||
_, err := r.call("PUT", path, "application/json", &buf)
|
||||
_, err := r.call("PUT", path, nil, "application/json", &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
4
vendor/github.com/datarhei/core-client-go/v16/metrics.go
generated
vendored
4
vendor/github.com/datarhei/core-client-go/v16/metrics.go
generated
vendored
@ -10,7 +10,7 @@ import (
|
||||
func (r *restclient) MetricsList() ([]api.MetricsDescription, error) {
|
||||
descriptions := []api.MetricsDescription{}
|
||||
|
||||
data, err := r.call("GET", "/v3/metrics", "application/json", nil)
|
||||
data, err := r.call("GET", "/v3/metrics", nil, "application/json", nil)
|
||||
if err != nil {
|
||||
return descriptions, err
|
||||
}
|
||||
@ -27,7 +27,7 @@ func (r *restclient) Metrics(query api.MetricsQuery) (api.MetricsResponse, error
|
||||
e := json.NewEncoder(&buf)
|
||||
e.Encode(query)
|
||||
|
||||
data, err := r.call("POST", "/v3/metrics", "application/json", &buf)
|
||||
data, err := r.call("POST", "/v3/metrics", nil, "application/json", &buf)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
|
||||
113
vendor/github.com/datarhei/core-client-go/v16/process.go
generated
vendored
113
vendor/github.com/datarhei/core-client-go/v16/process.go
generated
vendored
@ -9,29 +9,60 @@ import (
|
||||
"github.com/datarhei/core-client-go/v16/api"
|
||||
)
|
||||
|
||||
type ProcessID struct {
|
||||
ID string
|
||||
Domain string
|
||||
}
|
||||
|
||||
func NewProcessID(id, domain string) ProcessID {
|
||||
return ProcessID{
|
||||
ID: id,
|
||||
Domain: domain,
|
||||
}
|
||||
}
|
||||
|
||||
func ParseProcessID(pid string) ProcessID {
|
||||
i := strings.LastIndex(pid, "@")
|
||||
if i == -1 {
|
||||
return NewProcessID(pid, "")
|
||||
}
|
||||
|
||||
return NewProcessID(pid[:i], pid[i+1:])
|
||||
}
|
||||
|
||||
func ProcessIDFromProcess(p api.Process) ProcessID {
|
||||
return NewProcessID(p.ID, p.Config.Domain)
|
||||
}
|
||||
|
||||
func (p ProcessID) String() string {
|
||||
return p.ID + "@" + p.Domain
|
||||
}
|
||||
|
||||
type ProcessListOptions struct {
|
||||
ID []string
|
||||
Filter []string
|
||||
Domain string
|
||||
Reference string
|
||||
IDPattern string
|
||||
RefPattern string
|
||||
}
|
||||
|
||||
func (p *ProcessListOptions) Query() string {
|
||||
values := url.Values{}
|
||||
func (p *ProcessListOptions) Query() *url.Values {
|
||||
values := &url.Values{}
|
||||
values.Set("id", strings.Join(p.ID, ","))
|
||||
values.Set("filter", strings.Join(p.Filter, ","))
|
||||
values.Set("domain", p.Domain)
|
||||
values.Set("reference", p.Reference)
|
||||
values.Set("idpattern", p.IDPattern)
|
||||
values.Set("refpattern", p.RefPattern)
|
||||
|
||||
return values.Encode()
|
||||
return values
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessList(opts ProcessListOptions) ([]api.Process, error) {
|
||||
var processes []api.Process
|
||||
|
||||
data, err := r.call("GET", "/v3/process?"+opts.Query(), "", nil)
|
||||
data, err := r.call("GET", "/v3/process", opts.Query(), "", nil)
|
||||
if err != nil {
|
||||
return processes, err
|
||||
}
|
||||
@ -41,13 +72,14 @@ func (r *restclient) ProcessList(opts ProcessListOptions) ([]api.Process, error)
|
||||
return processes, err
|
||||
}
|
||||
|
||||
func (r *restclient) Process(id string, filter []string) (api.Process, error) {
|
||||
func (r *restclient) Process(id ProcessID, filter []string) (api.Process, error) {
|
||||
var info api.Process
|
||||
|
||||
values := url.Values{}
|
||||
values := &url.Values{}
|
||||
values.Set("filter", strings.Join(filter, ","))
|
||||
values.Set("domain", id.Domain)
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id)+"?"+values.Encode(), "", nil)
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id.ID), values, "", nil)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
@ -63,7 +95,7 @@ func (r *restclient) ProcessAdd(p api.ProcessConfig) error {
|
||||
e := json.NewEncoder(&buf)
|
||||
e.Encode(p)
|
||||
|
||||
_, err := r.call("POST", "/v3/process", "application/json", &buf)
|
||||
_, err := r.call("POST", "/v3/process", nil, "application/json", &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -71,13 +103,16 @@ func (r *restclient) ProcessAdd(p api.ProcessConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessUpdate(id string, p api.ProcessConfig) error {
|
||||
func (r *restclient) ProcessUpdate(id ProcessID, p api.ProcessConfig) error {
|
||||
var buf bytes.Buffer
|
||||
|
||||
e := json.NewEncoder(&buf)
|
||||
e.Encode(p)
|
||||
|
||||
_, err := r.call("PUT", "/v3/process/"+url.PathEscape(id)+"", "application/json", &buf)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
_, err := r.call("PUT", "/v3/process/"+url.PathEscape(id.ID), query, "application/json", &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -85,13 +120,16 @@ func (r *restclient) ProcessUpdate(id string, p api.ProcessConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessDelete(id string) error {
|
||||
r.call("DELETE", "/v3/process/"+url.PathEscape(id), "", nil)
|
||||
func (r *restclient) ProcessDelete(id ProcessID) error {
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
r.call("DELETE", "/v3/process/"+url.PathEscape(id.ID), query, "", nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessCommand(id, command string) error {
|
||||
func (r *restclient) ProcessCommand(id ProcessID, command string) error {
|
||||
var buf bytes.Buffer
|
||||
|
||||
e := json.NewEncoder(&buf)
|
||||
@ -99,7 +137,10 @@ func (r *restclient) ProcessCommand(id, command string) error {
|
||||
Command: command,
|
||||
})
|
||||
|
||||
_, err := r.call("PUT", "/v3/process/"+url.PathEscape(id)+"/command", "application/json", &buf)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
_, err := r.call("PUT", "/v3/process/"+url.PathEscape(id.ID)+"/command", query, "application/json", &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -107,10 +148,13 @@ func (r *restclient) ProcessCommand(id, command string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessProbe(id string) (api.Probe, error) {
|
||||
func (r *restclient) ProcessProbe(id ProcessID) (api.Probe, error) {
|
||||
var p api.Probe
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id)+"/probe", "", nil)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id.ID)+"/probe", query, "", nil)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
@ -120,10 +164,13 @@ func (r *restclient) ProcessProbe(id string) (api.Probe, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessConfig(id string) (api.ProcessConfig, error) {
|
||||
func (r *restclient) ProcessConfig(id ProcessID) (api.ProcessConfig, error) {
|
||||
var p api.ProcessConfig
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id)+"/config", "", nil)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id.ID)+"/config", query, "", nil)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
@ -133,10 +180,13 @@ func (r *restclient) ProcessConfig(id string) (api.ProcessConfig, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessReport(id string) (api.ProcessReport, error) {
|
||||
func (r *restclient) ProcessReport(id ProcessID) (api.ProcessReport, error) {
|
||||
var p api.ProcessReport
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id)+"/report", "", nil)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id.ID)+"/report", query, "", nil)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
@ -146,10 +196,13 @@ func (r *restclient) ProcessReport(id string) (api.ProcessReport, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessState(id string) (api.ProcessState, error) {
|
||||
func (r *restclient) ProcessState(id ProcessID) (api.ProcessState, error) {
|
||||
var p api.ProcessState
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id)+"/state", "", nil)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
data, err := r.call("GET", "/v3/process/"+url.PathEscape(id.ID)+"/state", query, "", nil)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
@ -159,15 +212,18 @@ func (r *restclient) ProcessState(id string) (api.ProcessState, error) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessMetadata(id, key string) (api.Metadata, error) {
|
||||
func (r *restclient) ProcessMetadata(id ProcessID, key string) (api.Metadata, error) {
|
||||
var m api.Metadata
|
||||
|
||||
path := "/v3/process/" + url.PathEscape(id) + "/metadata"
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
path := "/v3/process/" + url.PathEscape(id.ID) + "/metadata"
|
||||
if len(key) != 0 {
|
||||
path += "/" + url.PathEscape(key)
|
||||
}
|
||||
|
||||
data, err := r.call("GET", path, "", nil)
|
||||
data, err := r.call("GET", path, query, "", nil)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
@ -177,13 +233,16 @@ func (r *restclient) ProcessMetadata(id, key string) (api.Metadata, error) {
|
||||
return m, err
|
||||
}
|
||||
|
||||
func (r *restclient) ProcessMetadataSet(id, key string, metadata api.Metadata) error {
|
||||
func (r *restclient) ProcessMetadataSet(id ProcessID, key string, metadata api.Metadata) error {
|
||||
var buf bytes.Buffer
|
||||
|
||||
e := json.NewEncoder(&buf)
|
||||
e.Encode(metadata)
|
||||
|
||||
_, err := r.call("PUT", "/v3/process/"+url.PathEscape(id)+"/metadata/"+url.PathEscape(key), "application/json", &buf)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
_, err := r.call("PUT", "/v3/process/"+url.PathEscape(id.ID)+"/metadata/"+url.PathEscape(key), query, "application/json", &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
2
vendor/github.com/datarhei/core-client-go/v16/rtmp.go
generated
vendored
2
vendor/github.com/datarhei/core-client-go/v16/rtmp.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
||||
func (r *restclient) RTMPChannels() ([]api.RTMPChannel, error) {
|
||||
var m []api.RTMPChannel
|
||||
|
||||
data, err := r.call("GET", "/v3/rtmp", "", nil)
|
||||
data, err := r.call("GET", "/v3/rtmp", nil, "", nil)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
|
||||
12
vendor/github.com/datarhei/core-client-go/v16/session.go
generated
vendored
12
vendor/github.com/datarhei/core-client-go/v16/session.go
generated
vendored
@ -11,10 +11,10 @@ import (
|
||||
func (r *restclient) Sessions(collectors []string) (api.SessionsSummary, error) {
|
||||
var sessions api.SessionsSummary
|
||||
|
||||
values := url.Values{}
|
||||
values.Set("collectors", strings.Join(collectors, ","))
|
||||
query := &url.Values{}
|
||||
query.Set("collectors", strings.Join(collectors, ","))
|
||||
|
||||
data, err := r.call("GET", "/v3/sessions?"+values.Encode(), "", nil)
|
||||
data, err := r.call("GET", "/v3/sessions", query, "", nil)
|
||||
if err != nil {
|
||||
return sessions, err
|
||||
}
|
||||
@ -27,10 +27,10 @@ func (r *restclient) Sessions(collectors []string) (api.SessionsSummary, error)
|
||||
func (r *restclient) SessionsActive(collectors []string) (api.SessionsActive, error) {
|
||||
var sessions api.SessionsActive
|
||||
|
||||
values := url.Values{}
|
||||
values.Set("collectors", strings.Join(collectors, ","))
|
||||
query := &url.Values{}
|
||||
query.Set("collectors", strings.Join(collectors, ","))
|
||||
|
||||
data, err := r.call("GET", "/v3/sessions/active?"+values.Encode(), "", nil)
|
||||
data, err := r.call("GET", "/v3/sessions/active", query, "", nil)
|
||||
if err != nil {
|
||||
return sessions, err
|
||||
}
|
||||
|
||||
4
vendor/github.com/datarhei/core-client-go/v16/skills.go
generated
vendored
4
vendor/github.com/datarhei/core-client-go/v16/skills.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
||||
func (r *restclient) Skills() (api.Skills, error) {
|
||||
var skills api.Skills
|
||||
|
||||
data, err := r.call("GET", "/v3/skills", "", nil)
|
||||
data, err := r.call("GET", "/v3/skills", nil, "", nil)
|
||||
if err != nil {
|
||||
return skills, err
|
||||
}
|
||||
@ -20,7 +20,7 @@ func (r *restclient) Skills() (api.Skills, error) {
|
||||
}
|
||||
|
||||
func (r *restclient) SkillsReload() error {
|
||||
_, err := r.call("GET", "/v3/skills/reload", "", nil)
|
||||
_, err := r.call("GET", "/v3/skills/reload", nil, "", nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
2
vendor/github.com/datarhei/core-client-go/v16/srt.go
generated
vendored
2
vendor/github.com/datarhei/core-client-go/v16/srt.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
||||
func (r *restclient) SRTChannels() ([]api.SRTChannel, error) {
|
||||
var m []api.SRTChannel
|
||||
|
||||
data, err := r.call("GET", "/v3/srt", "", nil)
|
||||
data, err := r.call("GET", "/v3/srt", nil, "", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
7
vendor/github.com/datarhei/core-client-go/v16/widget.go
generated
vendored
7
vendor/github.com/datarhei/core-client-go/v16/widget.go
generated
vendored
@ -7,10 +7,13 @@ import (
|
||||
"github.com/datarhei/core-client-go/v16/api"
|
||||
)
|
||||
|
||||
func (r *restclient) WidgetProcess(id string) (api.WidgetProcess, error) {
|
||||
func (r *restclient) WidgetProcess(id ProcessID) (api.WidgetProcess, error) {
|
||||
var w api.WidgetProcess
|
||||
|
||||
data, err := r.call("GET", "/v3/widget/process"+url.PathEscape(id), "", nil)
|
||||
query := &url.Values{}
|
||||
query.Set("domain", id.Domain)
|
||||
|
||||
data, err := r.call("GET", "/v3/widget/process"+url.PathEscape(id.ID), query, "", nil)
|
||||
if err != nil {
|
||||
return w, err
|
||||
}
|
||||
|
||||
36
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
36
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
@ -352,9 +352,9 @@ func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {
|
||||
|
||||
// Greater asserts that the first element is greater than the second
|
||||
//
|
||||
// assert.Greater(t, 2, 1)
|
||||
// assert.Greater(t, float64(2), float64(1))
|
||||
// assert.Greater(t, "b", "a")
|
||||
// assert.Greater(t, 2, 1)
|
||||
// assert.Greater(t, float64(2), float64(1))
|
||||
// assert.Greater(t, "b", "a")
|
||||
func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -364,10 +364,10 @@ func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface
|
||||
|
||||
// GreaterOrEqual asserts that the first element is greater than or equal to the second
|
||||
//
|
||||
// assert.GreaterOrEqual(t, 2, 1)
|
||||
// assert.GreaterOrEqual(t, 2, 2)
|
||||
// assert.GreaterOrEqual(t, "b", "a")
|
||||
// assert.GreaterOrEqual(t, "b", "b")
|
||||
// assert.GreaterOrEqual(t, 2, 1)
|
||||
// assert.GreaterOrEqual(t, 2, 2)
|
||||
// assert.GreaterOrEqual(t, "b", "a")
|
||||
// assert.GreaterOrEqual(t, "b", "b")
|
||||
func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -377,9 +377,9 @@ func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...in
|
||||
|
||||
// Less asserts that the first element is less than the second
|
||||
//
|
||||
// assert.Less(t, 1, 2)
|
||||
// assert.Less(t, float64(1), float64(2))
|
||||
// assert.Less(t, "a", "b")
|
||||
// assert.Less(t, 1, 2)
|
||||
// assert.Less(t, float64(1), float64(2))
|
||||
// assert.Less(t, "a", "b")
|
||||
func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -389,10 +389,10 @@ func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{})
|
||||
|
||||
// LessOrEqual asserts that the first element is less than or equal to the second
|
||||
//
|
||||
// assert.LessOrEqual(t, 1, 2)
|
||||
// assert.LessOrEqual(t, 2, 2)
|
||||
// assert.LessOrEqual(t, "a", "b")
|
||||
// assert.LessOrEqual(t, "b", "b")
|
||||
// assert.LessOrEqual(t, 1, 2)
|
||||
// assert.LessOrEqual(t, 2, 2)
|
||||
// assert.LessOrEqual(t, "a", "b")
|
||||
// assert.LessOrEqual(t, "b", "b")
|
||||
func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -402,8 +402,8 @@ func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...inter
|
||||
|
||||
// Positive asserts that the specified element is positive
|
||||
//
|
||||
// assert.Positive(t, 1)
|
||||
// assert.Positive(t, 1.23)
|
||||
// assert.Positive(t, 1)
|
||||
// assert.Positive(t, 1.23)
|
||||
func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
@ -414,8 +414,8 @@ func Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
// Negative asserts that the specified element is negative
|
||||
//
|
||||
// assert.Negative(t, -1)
|
||||
// assert.Negative(t, -1.23)
|
||||
// assert.Negative(t, -1)
|
||||
// assert.Negative(t, -1.23)
|
||||
func Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {
|
||||
if h, ok := t.(tHelper); ok {
|
||||
h.Helper()
|
||||
|
||||
216
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
216
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
File diff suppressed because it is too large
Load Diff
432
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
432
vendor/github.com/stretchr/testify/assert/assertion_forward.go
generated
vendored
File diff suppressed because it is too large
Load Diff
24
vendor/github.com/stretchr/testify/assert/assertion_order.go
generated
vendored
24
vendor/github.com/stretchr/testify/assert/assertion_order.go
generated
vendored
@ -46,36 +46,36 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareT
|
||||
|
||||
// IsIncreasing asserts that the collection is increasing
|
||||
//
|
||||
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||
// assert.IsIncreasing(t, []float{1, 2})
|
||||
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||
// assert.IsIncreasing(t, []int{1, 2, 3})
|
||||
// assert.IsIncreasing(t, []float{1, 2})
|
||||
// assert.IsIncreasing(t, []string{"a", "b"})
|
||||
func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonIncreasing asserts that the collection is not increasing
|
||||
//
|
||||
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||
// assert.IsNonIncreasing(t, []int{2, 1, 1})
|
||||
// assert.IsNonIncreasing(t, []float{2, 1})
|
||||
// assert.IsNonIncreasing(t, []string{"b", "a"})
|
||||
func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsDecreasing asserts that the collection is decreasing
|
||||
//
|
||||
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||
// assert.IsDecreasing(t, []float{2, 1})
|
||||
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||
// assert.IsDecreasing(t, []int{2, 1, 0})
|
||||
// assert.IsDecreasing(t, []float{2, 1})
|
||||
// assert.IsDecreasing(t, []string{"b", "a"})
|
||||
func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
// IsNonDecreasing asserts that the collection is not decreasing
|
||||
//
|
||||
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||
// assert.IsNonDecreasing(t, []int{1, 1, 2})
|
||||
// assert.IsNonDecreasing(t, []float{1, 2})
|
||||
// assert.IsNonDecreasing(t, []string{"a", "b"})
|
||||
func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
|
||||
return isOrdered(t, object, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...)
|
||||
}
|
||||
|
||||
306
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
306
vendor/github.com/stretchr/testify/assert/assertions.go
generated
vendored
File diff suppressed because it is too large
Load Diff
43
vendor/github.com/stretchr/testify/assert/doc.go
generated
vendored
43
vendor/github.com/stretchr/testify/assert/doc.go
generated
vendored
@ -1,39 +1,40 @@
|
||||
// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
|
||||
//
|
||||
// Example Usage
|
||||
// # Example Usage
|
||||
//
|
||||
// The following is a complete example using assert in a standard test function:
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
// func TestSomething(t *testing.T) {
|
||||
//
|
||||
// assert.Equal(t, a, b, "The two words should be the same.")
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// }
|
||||
// assert.Equal(t, a, b, "The two words should be the same.")
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if you assert many times, use the format below:
|
||||
//
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/assert"
|
||||
// )
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// assert := assert.New(t)
|
||||
// func TestSomething(t *testing.T) {
|
||||
// assert := assert.New(t)
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// assert.Equal(a, b, "The two words should be the same.")
|
||||
// }
|
||||
// assert.Equal(a, b, "The two words should be the same.")
|
||||
// }
|
||||
//
|
||||
// Assertions
|
||||
// # Assertions
|
||||
//
|
||||
// Assertions allow you to easily write test code, and are global funcs in the `assert` package.
|
||||
// All assertion functions take, as the first argument, the `*testing.T` object provided by the
|
||||
|
||||
12
vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
12
vendor/github.com/stretchr/testify/assert/http_assertions.go
generated
vendored
@ -23,7 +23,7 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (
|
||||
|
||||
// HTTPSuccess asserts that a specified handler returns a success status code.
|
||||
//
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
@ -45,7 +45,7 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
|
||||
|
||||
// HTTPRedirect asserts that a specified handler returns a redirect status code.
|
||||
//
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
@ -67,7 +67,7 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
|
||||
|
||||
// HTTPError asserts that a specified handler returns an error status code.
|
||||
//
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
|
||||
@ -89,7 +89,7 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values
|
||||
|
||||
// HTTPStatusCode asserts that a specified handler returns a specified status code.
|
||||
//
|
||||
// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501)
|
||||
// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501)
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {
|
||||
@ -124,7 +124,7 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
|
||||
// HTTPBodyContains asserts that a specified handler returns a
|
||||
// body that contains a string.
|
||||
//
|
||||
// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
@ -144,7 +144,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
|
||||
// HTTPBodyNotContains asserts that a specified handler returns a
|
||||
// body that does not contain a string.
|
||||
//
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
|
||||
//
|
||||
// Returns whether the assertion was successful (true) or not (false).
|
||||
func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
|
||||
|
||||
23
vendor/github.com/stretchr/testify/require/doc.go
generated
vendored
23
vendor/github.com/stretchr/testify/require/doc.go
generated
vendored
@ -1,24 +1,25 @@
|
||||
// Package require implements the same assertions as the `assert` package but
|
||||
// stops test execution when a test fails.
|
||||
//
|
||||
// Example Usage
|
||||
// # Example Usage
|
||||
//
|
||||
// The following is a complete example using require in a standard test function:
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/require"
|
||||
// )
|
||||
//
|
||||
// func TestSomething(t *testing.T) {
|
||||
// import (
|
||||
// "testing"
|
||||
// "github.com/stretchr/testify/require"
|
||||
// )
|
||||
//
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
// func TestSomething(t *testing.T) {
|
||||
//
|
||||
// require.Equal(t, a, b, "The two words should be the same.")
|
||||
// var a string = "Hello"
|
||||
// var b string = "Hello"
|
||||
//
|
||||
// }
|
||||
// require.Equal(t, a, b, "The two words should be the same.")
|
||||
//
|
||||
// Assertions
|
||||
// }
|
||||
//
|
||||
// # Assertions
|
||||
//
|
||||
// The `require` package have same global functions as in the `assert` package,
|
||||
// but instead of returning a boolean result they call `t.FailNow()`.
|
||||
|
||||
444
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
444
vendor/github.com/stretchr/testify/require/require.go
generated
vendored
File diff suppressed because it is too large
Load Diff
432
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
432
vendor/github.com/stretchr/testify/require/require_forward.go
generated
vendored
File diff suppressed because it is too large
Load Diff
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
@ -78,7 +78,7 @@ github.com/cespare/xxhash/v2
|
||||
# github.com/cpuguy83/go-md2man/v2 v2.0.2
|
||||
## explicit; go 1.11
|
||||
github.com/cpuguy83/go-md2man/v2/md2man
|
||||
# github.com/datarhei/core-client-go/v16 v16.11.1-0.20230602102832-3d80767a2208
|
||||
# github.com/datarhei/core-client-go/v16 v16.11.1-0.20230605095314-42546fbbbece
|
||||
## explicit; go 1.18
|
||||
github.com/datarhei/core-client-go/v16
|
||||
github.com/datarhei/core-client-go/v16/api
|
||||
@ -352,8 +352,8 @@ github.com/shoenig/go-m1cpu
|
||||
# github.com/sirupsen/logrus v1.9.2
|
||||
## explicit; go 1.13
|
||||
github.com/sirupsen/logrus
|
||||
# github.com/stretchr/testify v1.8.2
|
||||
## explicit; go 1.13
|
||||
# github.com/stretchr/testify v1.8.4
|
||||
## explicit; go 1.20
|
||||
github.com/stretchr/testify/assert
|
||||
github.com/stretchr/testify/require
|
||||
# github.com/swaggo/echo-swagger v1.4.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user