Add GoSRT & improvements (repo-merge)

Commits (Ingo Oppermann):
- Add experimental SRT connection stats and logs
- Hide /config/reload endpoint in reade-only mode
- Add SRT server
- Create v16 in go.mod
- Fix data races, tests, lint, and update dependencies
- Add trailing slash for routed directories (datarhei/restreamer#340)
- Allow relative URLs in content in static routes

Co-Authored-By: Ingo Oppermann <57445+ioppermann@users.noreply.github.com>
This commit is contained in:
Jan Stabenow 2022-06-23 22:13:58 +02:00
parent d7db9e4efe
commit eb1cc37456
No known key found for this signature in database
GPG Key ID: 9C22DD65A9AAF133
323 changed files with 17524 additions and 10050 deletions

View File

@ -1,5 +1,15 @@
# Core # Core
#### Core v16.8.0 > ?
- Add experimental SRT connection stats and logs
- Hide /config/reload endpoint in reade-only mode
- Add SRT server (datarhei/gosrt)
- Create v16 in go.mod
- Fix data races, tests, lint, and update dependencies
- Add trailing slash for routed directories (datarhei/restreamer#340)
- Allow relative URLs in content in static routes
#### Core v16.7.2 > v16.8.0 #### Core v16.7.2 > v16.8.0
- Add purge_on_delete function - Add purge_on_delete function

View File

@ -15,25 +15,26 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/app" "github.com/datarhei/core/v16/app"
"github.com/datarhei/core/config" "github.com/datarhei/core/v16/config"
"github.com/datarhei/core/ffmpeg" "github.com/datarhei/core/v16/ffmpeg"
"github.com/datarhei/core/http" "github.com/datarhei/core/v16/http"
"github.com/datarhei/core/http/cache" "github.com/datarhei/core/v16/http/cache"
"github.com/datarhei/core/http/jwt" "github.com/datarhei/core/v16/http/jwt"
"github.com/datarhei/core/http/router" "github.com/datarhei/core/v16/http/router"
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/math/rand" "github.com/datarhei/core/v16/math/rand"
"github.com/datarhei/core/monitor" "github.com/datarhei/core/v16/monitor"
"github.com/datarhei/core/net" "github.com/datarhei/core/v16/net"
"github.com/datarhei/core/prometheus" "github.com/datarhei/core/v16/prometheus"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/datarhei/core/restream/store" "github.com/datarhei/core/v16/restream/store"
"github.com/datarhei/core/rtmp" "github.com/datarhei/core/v16/rtmp"
"github.com/datarhei/core/service" "github.com/datarhei/core/v16/service"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/datarhei/core/update" "github.com/datarhei/core/v16/srt"
"github.com/datarhei/core/v16/update"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
) )
@ -64,6 +65,7 @@ type api struct {
diskfs fs.Filesystem diskfs fs.Filesystem
memfs fs.Filesystem memfs fs.Filesystem
rtmpserver rtmp.Server rtmpserver rtmp.Server
srtserver srt.Server
metrics monitor.HistoryMonitor metrics monitor.HistoryMonitor
prom prometheus.Metrics prom prometheus.Metrics
service service.Service service service.Service
@ -76,9 +78,6 @@ type api struct {
errorChan chan error errorChan chan error
startOnce sync.Once
stopOnce sync.Once
gcTickerStop context.CancelFunc gcTickerStop context.CancelFunc
log struct { log struct {
@ -89,6 +88,7 @@ type api struct {
main log.Logger main log.Logger
sidecar log.Logger sidecar log.Logger
rtmp log.Logger rtmp log.Logger
srt log.Logger
} }
} }
@ -319,6 +319,11 @@ func (a *api) start() error {
return fmt.Errorf("unable to register session collector: %w", err) return fmt.Errorf("unable to register session collector: %w", err)
} }
srt, err := sessions.Register("srt", config)
if err != nil {
return fmt.Errorf("unable to register session collector: %w", err)
}
if _, err := sessions.Register("http", config); err != nil { if _, err := sessions.Register("http", config); err != nil {
return fmt.Errorf("unable to register session collector: %w", err) return fmt.Errorf("unable to register session collector: %w", err)
} }
@ -333,13 +338,20 @@ func (a *api) start() error {
} }
hls.AddCompanion(rtmp) hls.AddCompanion(rtmp)
hls.AddCompanion(srt)
hls.AddCompanion(ffmpeg) hls.AddCompanion(ffmpeg)
rtmp.AddCompanion(hls) rtmp.AddCompanion(hls)
rtmp.AddCompanion(ffmpeg) rtmp.AddCompanion(ffmpeg)
rtmp.AddCompanion(srt)
srt.AddCompanion(hls)
srt.AddCompanion(ffmpeg)
srt.AddCompanion(rtmp)
ffmpeg.AddCompanion(hls) ffmpeg.AddCompanion(hls)
ffmpeg.AddCompanion(rtmp) ffmpeg.AddCompanion(rtmp)
ffmpeg.AddCompanion(srt)
} else { } else {
sessions, _ := session.New(session.Config{}) sessions, _ := session.New(session.Config{})
a.sessions = sessions a.sessions = sessions
@ -674,7 +686,6 @@ func (a *api) start() error {
} }
rtmpserver, err := rtmp.New(config) rtmpserver, err := rtmp.New(config)
if err != nil { if err != nil {
return fmt.Errorf("unable to create RMTP server: %w", err) return fmt.Errorf("unable to create RMTP server: %w", err)
} }
@ -683,6 +694,25 @@ func (a *api) start() error {
a.rtmpserver = rtmpserver a.rtmpserver = rtmpserver
} }
if cfg.SRT.Enable {
config := srt.Config{
Addr: cfg.SRT.Address,
Passphrase: cfg.SRT.Passphrase,
Token: cfg.SRT.Token,
Logger: a.log.logger.core.WithComponent("SRT").WithField("address", cfg.SRT.Address),
Collector: a.sessions.Collector("srt"),
SRTLogTopics: []string{"handshake", "connection"},
}
srtserver, err := srt.New(config)
if err != nil {
return fmt.Errorf("unable to create SRT server: %w", err)
}
a.log.logger.srt = config.Logger
a.srtserver = srtserver
}
logcontext := "HTTP" logcontext := "HTTP"
if cfg.TLS.Enable { if cfg.TLS.Enable {
logcontext = "HTTPS" logcontext = "HTTPS"
@ -733,6 +763,7 @@ func (a *api) start() error {
Origins: cfg.Storage.CORS.Origins, Origins: cfg.Storage.CORS.Origins,
}, },
RTMP: a.rtmpserver, RTMP: a.rtmpserver,
SRT: a.srtserver,
JWT: a.httpjwt, JWT: a.httpjwt,
Config: a.config.store, Config: a.config.store,
Cache: a.cache, Cache: a.cache,
@ -794,6 +825,7 @@ func (a *api) start() error {
Origins: cfg.Storage.CORS.Origins, Origins: cfg.Storage.CORS.Origins,
}, },
RTMP: a.rtmpserver, RTMP: a.rtmpserver,
SRT: a.srtserver,
JWT: a.httpjwt, JWT: a.httpjwt,
Config: a.config.store, Config: a.config.store,
Cache: a.cache, Cache: a.cache,
@ -888,6 +920,34 @@ func (a *api) start() error {
}() }()
} }
if a.srtserver != nil {
wgStart.Add(1)
a.wgStop.Add(1)
go func() {
logger := a.log.logger.srt
defer func() {
logger.Info().Log("Server exited")
a.wgStop.Done()
}()
wgStart.Done()
var err error
logger.Info().Log("Server started")
err = a.srtserver.ListenAndServe()
if err != nil && err != srt.ErrServerClosed {
err = fmt.Errorf("SRT server: %w", err)
} else {
err = nil
}
sendError(err)
}()
}
wgStart.Add(1) wgStart.Add(1)
a.wgStop.Add(1) a.wgStop.Add(1)
@ -1031,6 +1091,14 @@ func (a *api) stop() {
a.cache = nil a.cache = nil
} }
// Stop the SRT server
if a.srtserver != nil {
a.log.logger.srt.Info().Log("Stopping ...")
a.srtserver.Close()
a.srtserver = nil
}
// Stop the RTMP server // Stop the RTMP server
if a.rtmpserver != nil { if a.rtmpserver != nil {
a.log.logger.rtmp.Info().Log("Stopping ...") a.log.logger.rtmp.Info().Log("Stopping ...")

View File

@ -15,12 +15,12 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/encoding/json" "github.com/datarhei/core/v16/encoding/json"
"github.com/datarhei/core/ffmpeg" "github.com/datarhei/core/v16/ffmpeg"
"github.com/datarhei/core/ffmpeg/skills" "github.com/datarhei/core/v16/ffmpeg/skills"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
"github.com/datarhei/core/restream/store" "github.com/datarhei/core/v16/restream/store"
"github.com/google/uuid" "github.com/google/uuid"
) )

View File

@ -6,8 +6,8 @@ import (
"os" "os"
"testing" "testing"
"github.com/datarhei/core/encoding/json" "github.com/datarhei/core/v16/encoding/json"
"github.com/datarhei/core/restream/store" "github.com/datarhei/core/v16/restream/store"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -3,9 +3,9 @@ package main
import ( import (
"os" "os"
"github.com/datarhei/core/config" "github.com/datarhei/core/v16/config"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/restream/store" "github.com/datarhei/core/v16/restream/store"
_ "github.com/joho/godotenv/autoload" _ "github.com/joho/godotenv/autoload"
) )

View File

@ -8,7 +8,7 @@ import (
"os" "os"
"time" "time"
"github.com/datarhei/core/math/rand" "github.com/datarhei/core/v16/math/rand"
haikunator "github.com/atrox/haikunatorgo/v2" haikunator "github.com/atrox/haikunatorgo/v2"
"github.com/google/uuid" "github.com/google/uuid"
@ -135,6 +135,12 @@ type Data struct {
App string `json:"app"` App string `json:"app"`
Token string `json:"token"` Token string `json:"token"`
} `json:"rtmp"` } `json:"rtmp"`
SRT struct {
Enable bool `json:"enable"`
Address string `json:"address"`
Passphrase string `json:"passphrase"`
Token string `json:"token"`
} `json:"srt"`
FFmpeg struct { FFmpeg struct {
Binary string `json:"binary"` Binary string `json:"binary"`
MaxProcesses int64 `json:"max_processes"` MaxProcesses int64 `json:"max_processes"`
@ -227,6 +233,7 @@ func NewConfigFrom(d *Config) *Config {
data.TLS = d.TLS data.TLS = d.TLS
data.Storage = d.Storage data.Storage = d.Storage
data.RTMP = d.RTMP data.RTMP = d.RTMP
data.SRT = d.SRT
data.FFmpeg = d.FFmpeg data.FFmpeg = d.FFmpeg
data.Playout = d.Playout data.Playout = d.Playout
data.Debug = d.Debug data.Debug = d.Debug
@ -339,6 +346,12 @@ func (d *Config) init() {
d.val(newStringValue(&d.RTMP.App, "/"), "rtmp.app", "CORE_RTMP_APP", nil, "RTMP app for publishing", false, false) d.val(newStringValue(&d.RTMP.App, "/"), "rtmp.app", "CORE_RTMP_APP", nil, "RTMP app for publishing", false, false)
d.val(newStringValue(&d.RTMP.Token, ""), "rtmp.token", "CORE_RTMP_TOKEN", nil, "RTMP token for publishing and playing", false, true) d.val(newStringValue(&d.RTMP.Token, ""), "rtmp.token", "CORE_RTMP_TOKEN", nil, "RTMP token for publishing and playing", false, true)
// SRT
d.val(newBoolValue(&d.SRT.Enable, false), "srt.enable", "CORE_SRT_ENABLE", nil, "Enable SRT server", false, false)
d.val(newAddressValue(&d.SRT.Address, ":6000"), "srt.address", "CORE_SRT_ADDRESS", nil, "SRT server listen address", false, false)
d.val(newStringValue(&d.SRT.Passphrase, ""), "srt.passphrase", "CORE_SRT_PASSPHRASE", nil, "SRT encryption passphrase", false, true)
d.val(newStringValue(&d.SRT.Token, ""), "srt.token", "CORE_SRT_TOKEN", nil, "SRT token for publishing and playing", false, true)
// FFmpeg // FFmpeg
d.val(newExecValue(&d.FFmpeg.Binary, "ffmpeg"), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false) d.val(newExecValue(&d.FFmpeg.Binary, "ffmpeg"), "ffmpeg.binary", "CORE_FFMPEG_BINARY", nil, "Path to ffmpeg binary", true, false)
d.val(newInt64Value(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false) d.val(newInt64Value(&d.FFmpeg.MaxProcesses, 0), "ffmpeg.max_processes", "CORE_FFMPEG_MAXPROCESSES", nil, "Max. allowed simultaneously running ffmpeg instances, 0 for unlimited", false, false)

View File

@ -8,8 +8,8 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/datarhei/core/encoding/json" "github.com/datarhei/core/v16/encoding/json"
"github.com/datarhei/core/io/file" "github.com/datarhei/core/v16/io/file"
) )
type jsonStore struct { type jsonStore struct {

View File

@ -13,7 +13,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/http/cors" "github.com/datarhei/core/v16/http/cors"
) )
type value interface { type value interface {

View File

@ -17,7 +17,7 @@ const docTemplate = `{
}, },
"license": { "license": {
"name": "Apache 2.0", "name": "Apache 2.0",
"url": "https://github.com/datarhei/core/blob/main/LICENSE" "url": "https://github.com/datarhei/core/v16/blob/main/LICENSE"
}, },
"version": "{{.Version}}" "version": "{{.Version}}"
}, },
@ -1784,11 +1784,11 @@ const docTemplate = `{
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "List all currently publishing streams", "description": "List all currently publishing RTMP streams",
"produces": [ "produces": [
"application/json" "application/json"
], ],
"summary": "List all publishing streams", "summary": "List all publishing RTMP streams",
"operationId": "rtmp-3-list-channels", "operationId": "rtmp-3-list-channels",
"responses": { "responses": {
"200": { "200": {
@ -1911,6 +1911,32 @@ const docTemplate = `{
} }
} }
}, },
"/api/v3/srt": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List all currently publishing SRT streams",
"produces": [
"application/json"
],
"summary": "List all publishing SRT treams",
"operationId": "srt-3-list-channels",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.SRTChannel"
}
}
}
}
}
},
"/api/v3/widget/process/{id}": { "/api/v3/widget/process/{id}": {
"get": { "get": {
"description": "Fetch minimal statistics about a process, which is not protected by any auth.", "description": "Fetch minimal statistics about a process, which is not protected by any auth.",
@ -2640,6 +2666,23 @@ const docTemplate = `{
} }
} }
}, },
"srt": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"enable": {
"type": "boolean"
},
"passphrase": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"storage": { "storage": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -3447,6 +3490,14 @@ const docTemplate = `{
} }
} }
}, },
"api.SRTChannel": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"api.Session": { "api.Session": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -3944,6 +3995,23 @@ const docTemplate = `{
} }
} }
}, },
"srt": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"enable": {
"type": "boolean"
},
"passphrase": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"storage": { "storage": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -10,7 +10,7 @@
}, },
"license": { "license": {
"name": "Apache 2.0", "name": "Apache 2.0",
"url": "https://github.com/datarhei/core/blob/main/LICENSE" "url": "https://github.com/datarhei/core/v16/blob/main/LICENSE"
}, },
"version": "3.0" "version": "3.0"
}, },
@ -1776,11 +1776,11 @@
"ApiKeyAuth": [] "ApiKeyAuth": []
} }
], ],
"description": "List all currently publishing streams", "description": "List all currently publishing RTMP streams",
"produces": [ "produces": [
"application/json" "application/json"
], ],
"summary": "List all publishing streams", "summary": "List all publishing RTMP streams",
"operationId": "rtmp-3-list-channels", "operationId": "rtmp-3-list-channels",
"responses": { "responses": {
"200": { "200": {
@ -1903,6 +1903,32 @@
} }
} }
}, },
"/api/v3/srt": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List all currently publishing SRT streams",
"produces": [
"application/json"
],
"summary": "List all publishing SRT treams",
"operationId": "srt-3-list-channels",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.SRTChannel"
}
}
}
}
}
},
"/api/v3/widget/process/{id}": { "/api/v3/widget/process/{id}": {
"get": { "get": {
"description": "Fetch minimal statistics about a process, which is not protected by any auth.", "description": "Fetch minimal statistics about a process, which is not protected by any auth.",
@ -2632,6 +2658,23 @@
} }
} }
}, },
"srt": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"enable": {
"type": "boolean"
},
"passphrase": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"storage": { "storage": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -3439,6 +3482,14 @@
} }
} }
}, },
"api.SRTChannel": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"api.Session": { "api.Session": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -3936,6 +3987,23 @@
} }
} }
}, },
"srt": {
"type": "object",
"properties": {
"address": {
"type": "string"
},
"enable": {
"type": "boolean"
},
"passphrase": {
"type": "string"
},
"token": {
"type": "string"
}
}
},
"storage": { "storage": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -301,6 +301,17 @@ definitions:
session_timeout_sec: session_timeout_sec:
type: integer type: integer
type: object type: object
srt:
properties:
address:
type: string
enable:
type: boolean
passphrase:
type: string
token:
type: string
type: object
storage: storage:
properties: properties:
cors: cors:
@ -834,6 +845,11 @@ definitions:
name: name:
type: string type: string
type: object type: object
api.SRTChannel:
properties:
name:
type: string
type: object
api.Session: api.Session:
properties: properties:
bandwidth_rx_kbit: bandwidth_rx_kbit:
@ -1160,6 +1176,17 @@ definitions:
session_timeout_sec: session_timeout_sec:
type: integer type: integer
type: object type: object
srt:
properties:
address:
type: string
enable:
type: boolean
passphrase:
type: string
token:
type: string
type: object
storage: storage:
properties: properties:
cors: cors:
@ -1419,7 +1446,7 @@ info:
description: Expose REST API for the datarhei Core description: Expose REST API for the datarhei Core
license: license:
name: Apache 2.0 name: Apache 2.0
url: https://github.com/datarhei/core/blob/main/LICENSE url: https://github.com/datarhei/core/v16/blob/main/LICENSE
title: datarhei Core API title: datarhei Core API
version: "3.0" version: "3.0"
paths: paths:
@ -2605,7 +2632,7 @@ paths:
summary: Get the state of a process summary: Get the state of a process
/api/v3/rtmp: /api/v3/rtmp:
get: get:
description: List all currently publishing streams description: List all currently publishing RTMP streams
operationId: rtmp-3-list-channels operationId: rtmp-3-list-channels
produces: produces:
- application/json - application/json
@ -2618,7 +2645,7 @@ paths:
type: array type: array
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: List all publishing streams summary: List all publishing RTMP streams
/api/v3/session: /api/v3/session:
get: get:
description: Get a summary of all active and past sessions of the given collector description: Get a summary of all active and past sessions of the given collector
@ -2686,6 +2713,22 @@ paths:
security: security:
- ApiKeyAuth: [] - ApiKeyAuth: []
summary: Refresh FFmpeg capabilities summary: Refresh FFmpeg capabilities
/api/v3/srt:
get:
description: List all currently publishing SRT streams
operationId: srt-3-list-channels
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.SRTChannel'
type: array
security:
- ApiKeyAuth: []
summary: List all publishing SRT treams
/api/v3/widget/process/{id}: /api/v3/widget/process/{id}:
get: get:
description: Fetch minimal statistics about a process, which is not protected description: Fetch minimal statistics about a process, which is not protected

View File

@ -1,7 +1,7 @@
package ffmpeg package ffmpeg
import ( import (
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
) )
type wrappedCollector struct { type wrappedCollector struct {

View File

@ -3,15 +3,16 @@ package ffmpeg
import ( import (
"fmt" "fmt"
"os/exec" "os/exec"
"sync"
"time" "time"
"github.com/datarhei/core/ffmpeg/parse" "github.com/datarhei/core/v16/ffmpeg/parse"
"github.com/datarhei/core/ffmpeg/probe" "github.com/datarhei/core/v16/ffmpeg/probe"
"github.com/datarhei/core/ffmpeg/skills" "github.com/datarhei/core/v16/ffmpeg/skills"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/net" "github.com/datarhei/core/v16/net"
"github.com/datarhei/core/process" "github.com/datarhei/core/v16/process"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
) )
type FFmpeg interface { type FFmpeg interface {
@ -64,7 +65,8 @@ type ffmpeg struct {
collector session.Collector collector session.Collector
states process.States states process.States
statesLock sync.RWMutex
} }
func New(config Config) (FFmpeg, error) { func New(config Config) (FFmpeg, error) {
@ -120,6 +122,7 @@ func (f *ffmpeg) New(config ProcessConfig) (process.Process, error) {
OnStart: config.OnStart, OnStart: config.OnStart,
OnExit: config.OnExit, OnExit: config.OnExit,
OnStateChange: func(from, to string) { OnStateChange: func(from, to string) {
f.statesLock.Lock()
switch to { switch to {
case "finished": case "finished":
f.states.Finished++ f.states.Finished++
@ -135,6 +138,7 @@ func (f *ffmpeg) New(config ProcessConfig) (process.Process, error) {
f.states.Killed++ f.states.Killed++
default: default:
} }
f.statesLock.Unlock()
if config.OnStateChange != nil { if config.OnStateChange != nil {
config.OnStateChange(from, to) config.OnStateChange(from, to)
@ -196,5 +200,8 @@ func (f *ffmpeg) PutPort(port int) {
} }
func (f *ffmpeg) States() process.States { func (f *ffmpeg) States() process.States {
f.statesLock.RLock()
defer f.statesLock.RUnlock()
return f.states return f.states
} }

View File

@ -10,11 +10,11 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/net/url" "github.com/datarhei/core/v16/net/url"
"github.com/datarhei/core/process" "github.com/datarhei/core/v16/process"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
) )
// Parser is an extension to the process.Parser interface // Parser is an extension to the process.Parser interface
@ -133,6 +133,7 @@ func New(config Config) Parser {
p.re.drop = regexp.MustCompile(`drop=\s*([0-9]+)`) p.re.drop = regexp.MustCompile(`drop=\s*([0-9]+)`)
p.re.dup = regexp.MustCompile(`dup=\s*([0-9]+)`) p.re.dup = regexp.MustCompile(`dup=\s*([0-9]+)`)
p.lock.prelude.Lock()
p.prelude.headLines = config.PreludeHeadLines p.prelude.headLines = config.PreludeHeadLines
if p.prelude.headLines <= 0 { if p.prelude.headLines <= 0 {
p.prelude.headLines = 100 p.prelude.headLines = 100
@ -142,7 +143,9 @@ func New(config Config) Parser {
p.prelude.tailLines = 50 p.prelude.tailLines = 50
} }
p.prelude.tail = ring.New(p.prelude.tailLines) p.prelude.tail = ring.New(p.prelude.tailLines)
p.lock.prelude.Unlock()
p.lock.log.Lock()
p.log = ring.New(config.LogLines) p.log = ring.New(config.LogLines)
if p.logHistoryLength > 0 { if p.logHistoryLength > 0 {
@ -154,6 +157,7 @@ func New(config Config) Parser {
} }
p.logStart = time.Now() p.logStart = time.Now()
p.lock.log.Unlock()
p.ResetStats() p.ResetStats()
@ -168,7 +172,9 @@ func (p *parser) Parse(line string) uint64 {
isAVstreamProgress := strings.HasPrefix(line, "avstream.progress:") isAVstreamProgress := strings.HasPrefix(line, "avstream.progress:")
if p.logStart.IsZero() { if p.logStart.IsZero() {
p.lock.log.Lock()
p.logStart = time.Now() p.logStart = time.Now()
p.lock.log.Unlock()
} }
if !p.prelude.done { if !p.prelude.done {
@ -199,7 +205,10 @@ func (p *parser) Parse(line string) uint64 {
}).Error().Log("Failed parsing outputs") }).Error().Log("Failed parsing outputs")
} else { } else {
p.logger.WithField("prelude", p.Prelude()).Debug().Log("") p.logger.WithField("prelude", p.Prelude()).Debug().Log("")
p.lock.prelude.Lock()
p.prelude.done = true p.prelude.done = true
p.lock.prelude.Unlock()
} }
return 0 return 0
@ -211,7 +220,10 @@ func (p *parser) Parse(line string) uint64 {
} }
p.logger.WithField("prelude", p.Prelude()).Debug().Log("") p.logger.WithField("prelude", p.Prelude()).Debug().Log("")
p.lock.prelude.Lock()
p.prelude.done = true p.prelude.done = true
p.lock.prelude.Unlock()
} }
} }
@ -219,17 +231,17 @@ func (p *parser) Parse(line string) uint64 {
// Write the current non-progress line to the log // Write the current non-progress line to the log
p.addLog(line) p.addLog(line)
p.lock.prelude.Lock()
if !p.prelude.done { if !p.prelude.done {
if len(p.prelude.data) < p.prelude.headLines { if len(p.prelude.data) < p.prelude.headLines {
p.prelude.data = append(p.prelude.data, line) p.prelude.data = append(p.prelude.data, line)
} else { } else {
p.lock.prelude.Lock()
p.prelude.tail.Value = line p.prelude.tail.Value = line
p.prelude.tail = p.prelude.tail.Next() p.prelude.tail = p.prelude.tail.Next()
p.lock.prelude.Unlock()
p.prelude.truncatedLines++ p.prelude.truncatedLines++
} }
} }
p.lock.prelude.Unlock()
return 0 return 0
} }
@ -508,7 +520,9 @@ func (p *parser) Progress() app.Progress {
} }
func (p *parser) Prelude() []string { func (p *parser) Prelude() []string {
p.lock.prelude.RLock()
if p.prelude.data == nil { if p.prelude.data == nil {
p.lock.prelude.RUnlock()
return []string{} return []string{}
} }
@ -517,8 +531,6 @@ func (p *parser) Prelude() []string {
tail := []string{} tail := []string{}
p.lock.prelude.RLock()
p.prelude.tail.Do(func(l interface{}) { p.prelude.tail.Do(func(l interface{}) {
if l == nil { if l == nil {
return return
@ -734,24 +746,25 @@ func (p *parser) ResetStats() {
p.progress.ffmpeg = ffmpegProgress{} p.progress.ffmpeg = ffmpegProgress{}
p.progress.avstream = make(map[string]ffmpegAVstream) p.progress.avstream = make(map[string]ffmpegAVstream)
p.lock.prelude.Lock()
p.prelude.done = false p.prelude.done = false
p.lock.prelude.Unlock()
} }
func (p *parser) ResetLog() { func (p *parser) ResetLog() {
p.storeLogHistory() p.storeLogHistory()
p.prelude.data = []string{}
p.lock.prelude.Lock() p.lock.prelude.Lock()
p.prelude.data = []string{}
p.prelude.tail = ring.New(p.prelude.tailLines) p.prelude.tail = ring.New(p.prelude.tailLines)
p.lock.prelude.Unlock()
p.prelude.truncatedLines = 0 p.prelude.truncatedLines = 0
p.prelude.done = false p.prelude.done = false
p.lock.prelude.Unlock()
p.lock.log.Lock() p.lock.log.Lock()
p.log = ring.New(p.logLines) p.log = ring.New(p.logLines)
p.lock.log.Unlock()
p.logStart = time.Now() p.logStart = time.Now()
p.lock.log.Unlock()
} }
// Report represents a log report, including the prelude and the last log lines // Report represents a log report, including the prelude and the last log lines
@ -777,11 +790,14 @@ func (p *parser) storeLogHistory() {
func (p *parser) Report() Report { func (p *parser) Report() Report {
h := Report{ h := Report{
CreatedAt: p.logStart, Prelude: p.Prelude(),
Prelude: p.Prelude(), Log: p.Log(),
Log: p.Log(),
} }
p.lock.log.RLock()
h.CreatedAt = p.logStart
p.lock.log.RUnlock()
return h return h
} }

View File

@ -6,7 +6,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -5,7 +5,7 @@ import (
"errors" "errors"
"time" "time"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
// Duration represents a time.Duration // Duration represents a time.Duration

View File

@ -7,9 +7,9 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/process" "github.com/datarhei/core/v16/process"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
type Parser interface { type Parser interface {

View File

@ -1,7 +1,7 @@
package probe package probe
import ( import (
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
type probeIO struct { type probeIO struct {

View File

@ -10,8 +10,6 @@ import (
// DevicesV4L returns a list of available V4L devices // DevicesV4L returns a list of available V4L devices
func DevicesV4L() ([]HWDevice, error) { func DevicesV4L() ([]HWDevice, error) {
devices := []HWDevice{}
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
cmd := exec.Command("v4l2-ctl", "--list-devices") cmd := exec.Command("v4l2-ctl", "--list-devices")
@ -19,7 +17,7 @@ func DevicesV4L() ([]HWDevice, error) {
cmd.Stdout = buf cmd.Stdout = buf
cmd.Run() cmd.Run()
devices = parseV4LDevices(buf) devices := parseV4LDevices(buf)
return devices, nil return devices, nil
} }

28
go.mod
View File

@ -1,12 +1,11 @@
module github.com/datarhei/core module github.com/datarhei/core/v16
go 1.16 go 1.16
require ( require (
github.com/99designs/gqlgen v0.17.9 github.com/99designs/gqlgen v0.17.10
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/atrox/haikunatorgo/v2 v2.0.1 github.com/atrox/haikunatorgo/v2 v2.0.1
github.com/datarhei/gosrt v0.1.1
github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce
github.com/go-openapi/spec v0.20.6 // indirect github.com/go-openapi/spec v0.20.6 // indirect
github.com/go-openapi/swag v0.21.1 // indirect github.com/go-openapi/swag v0.21.1 // indirect
@ -14,6 +13,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.4.1 github.com/golang-jwt/jwt/v4 v4.4.1
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/iancoleman/orderedmap v0.2.0 // indirect github.com/iancoleman/orderedmap v0.2.0 // indirect
github.com/invopop/jsonschema v0.4.0
github.com/joho/godotenv v1.4.0 github.com/joho/godotenv v1.4.0
github.com/labstack/echo/v4 v4.7.2 github.com/labstack/echo/v4 v4.7.2
github.com/lithammer/shortuuid/v4 v4.0.0 github.com/lithammer/shortuuid/v4 v4.0.0
@ -23,17 +23,19 @@ require (
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3 github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
github.com/prometheus/client_golang v1.12.2 github.com/prometheus/client_golang v1.12.2
github.com/prometheus/common v0.34.0 // indirect github.com/prometheus/common v0.35.0 // indirect
github.com/shirou/gopsutil/v3 v3.22.4 github.com/shirou/gopsutil/v3 v3.22.5
github.com/stretchr/testify v1.7.1 github.com/stretchr/testify v1.7.2
github.com/swaggo/echo-swagger v1.3.2 github.com/swaggo/echo-swagger v1.3.3
github.com/swaggo/swag v1.8.2 github.com/swaggo/swag v1.8.3
github.com/tklauser/numcpus v0.5.0 // indirect github.com/tklauser/numcpus v0.5.0 // indirect
github.com/vektah/gqlparser/v2 v2.4.4 github.com/vektah/gqlparser/v2 v2.4.5
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonschema v1.2.0 github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 // indirect golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
golang.org/x/tools v0.1.11 // indirect
) )

63
go.sum
View File

@ -31,8 +31,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/99designs/gqlgen v0.17.9 h1:0XvE3nMaTaLYq7XbBz1MY0t9BFcntydlt1zzNa4eY+4= github.com/99designs/gqlgen v0.17.10 h1:+JtGPZ6jqL0IcmLopq4iaEbh5Ggye+NiutU57w82xvk=
github.com/99designs/gqlgen v0.17.9/go.mod h1:PThAZAK9t2pAat7g8QdSI4dCBMOhBO+t2qj+0jvDqps= github.com/99designs/gqlgen v0.17.10/go.mod h1:tjgUrZGpynt+w38zmgTn5QGgd3EUhkHa4VRcX6/AyGo=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -44,10 +44,7 @@ github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaW
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d h1:4BQNwS4T13UU3Yee4GfzZH3Q9SNpKeJvLigfw8fDjX0=
github.com/alecthomas/jsonschema v0.0.0-20211228220459-151e3c21f49d/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -58,6 +55,8 @@ github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/atrox/haikunatorgo/v2 v2.0.1 h1:FCVx2KL2YvZtI1rI9WeEHxeLRrKGr0Dd4wfCJiUXupc= github.com/atrox/haikunatorgo/v2 v2.0.1 h1:FCVx2KL2YvZtI1rI9WeEHxeLRrKGr0Dd4wfCJiUXupc=
github.com/atrox/haikunatorgo/v2 v2.0.1/go.mod h1:BBQmx2o+1Z5poziaHRgddAZKOpijwfKdAmMnSYlFK70= github.com/atrox/haikunatorgo/v2 v2.0.1/go.mod h1:BBQmx2o+1Z5poziaHRgddAZKOpijwfKdAmMnSYlFK70=
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c h1:8XZeJrs4+ZYhJeJ2aZxADI2tGADS15AzIF8MQ8XAhT4=
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -75,6 +74,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/datarhei/gosrt v0.1.1 h1:y5v0CNmT8FFxgJnr2a0+RzoNS5t4OKJBkKtXovmfsFE=
github.com/datarhei/gosrt v0.1.1/go.mod h1:IftDbZGIIC9OvQO5on5ZpU0iB/JX/PFOqGXORbwHYQM=
github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce h1:bg/OE9GfGK6d/XbqiMq8YaGQzw1Ul3Y3qiGMzU1G4HQ= github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce h1:bg/OE9GfGK6d/XbqiMq8YaGQzw1Ul3Y3qiGMzU1G4HQ=
github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw= github.com/datarhei/joy4 v0.0.0-20210125162555-2102a8289cce/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -167,7 +168,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -196,6 +196,8 @@ github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0
github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA=
github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/invopop/jsonschema v0.4.0 h1:Yuy/unfgCnfV5Wl7H0HgFufp/rlurqPOOuacqyByrws=
github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@ -269,6 +271,7 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsK
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
@ -292,8 +295,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.34.0 h1:RBmGO9d/FVjqHT0yUGQwBJhkwKV+wPCn7KGpvfab0uE= github.com/prometheus/common v0.35.0 h1:Eyr+Pw2VymWejHqCugNaQXkAi6KayVNxaHeu6khmFBE=
github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
@ -309,8 +312,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil/v3 v3.22.4 h1:srAQaiX6jX/cYL6q29aE0m8lOskT9CurZ9N61YR3yoI= github.com/shirou/gopsutil/v3 v3.22.5 h1:atX36I/IXgFiB81687vSiBI5zrMsxcIBkP9cQMJQoJA=
github.com/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM= github.com/shirou/gopsutil/v3 v3.22.5/go.mod h1:so9G9VzeHt/hsd0YwqprnjHnfARAUktauykSbr+y2gA=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@ -325,15 +328,16 @@ github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/swaggo/echo-swagger v1.3.2 h1:D+3BNl8JMC6pKhA+egjh4LGI0jNesqlt77WahTHfTXQ= github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/swaggo/echo-swagger v1.3.2/go.mod h1:Sjj0O7Puf939HXhxhfZdR49MIrtcg3mLgdg3/qVcbyw= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM= github.com/swaggo/echo-swagger v1.3.3 h1:Fx8kQ8IcIIEL3ZE20wzvcT8gFnPo/4U+fsnS3I1wvCw=
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w= github.com/swaggo/echo-swagger v1.3.3/go.mod h1:vbKcEBeJgOexLuPcsdZhrRAV508fsE79xaKIqmvse98=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe h1:K8pHPVoTgxFJt1lXuIzzOX7zZhZFldJQK/CgKx9BFIc=
github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ= github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
github.com/swaggo/swag v1.8.2 h1:D4aBiVS2a65zhyk3WFqOUz7Rz0sOaUcgeErcid5uGL4= github.com/swaggo/swag v1.8.3 h1:3pZSSCQ//gAH88lfmxM3Cd1+JCsxV8Md6f36b9hrZ5s=
github.com/swaggo/swag v1.8.2/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg= github.com/swaggo/swag v1.8.3/go.mod h1:jMLeXOOmYyjk8PvHTsXBdrubsNd9gUJTTCzL5iBnseg=
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
@ -346,8 +350,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/vektah/gqlparser/v2 v2.4.4 h1:rh9hwZ5Jx9cCq88zXz2YHKmuQBuwY1JErHU8GywFdwE= github.com/vektah/gqlparser/v2 v2.4.5 h1:C02NsyEsL4TXJB7ndonqTfuQOL4XPIu0aAWugdmTgmc=
github.com/vektah/gqlparser/v2 v2.4.4/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0= github.com/vektah/gqlparser/v2 v2.4.5/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@ -413,8 +417,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -452,8 +457,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8= golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn0XuyJqkoft2IlrvOhc=
golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -521,8 +526,9 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -537,8 +543,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -582,12 +588,12 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
@ -685,8 +691,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -1,7 +1,7 @@
package api package api
import ( import (
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
type AVstreamIO struct { type AVstreamIO struct {

View File

@ -3,7 +3,7 @@ package api
import ( import (
"time" "time"
"github.com/datarhei/core/config" "github.com/datarhei/core/v16/config"
) )
// ConfigData embeds config.Data // ConfigData embeds config.Data
@ -41,6 +41,7 @@ func (rscfg *SetConfig) MergeTo(cfg *config.Config) {
cfg.TLS = rscfg.TLS cfg.TLS = rscfg.TLS
cfg.Storage = rscfg.Storage cfg.Storage = rscfg.Storage
cfg.RTMP = rscfg.RTMP cfg.RTMP = rscfg.RTMP
cfg.SRT = rscfg.SRT
cfg.FFmpeg = rscfg.FFmpeg cfg.FFmpeg = rscfg.FFmpeg
cfg.Playout = rscfg.Playout cfg.Playout = rscfg.Playout
cfg.Debug = rscfg.Debug cfg.Debug = rscfg.Debug

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/datarhei/core/monitor" "github.com/datarhei/core/v16/monitor"
) )
type MetricsQueryMetric struct { type MetricsQueryMetric struct {

View File

@ -1,6 +1,6 @@
package api package api
import "github.com/datarhei/core/playout" import "github.com/datarhei/core/v16/playout"
type PlayoutStatusIO struct { type PlayoutStatusIO struct {
State string `json:"state" enums:"running,idle" jsonschema:"enum=running,enum=idle"` State string `json:"state" enums:"running,idle" jsonschema:"enum=running,enum=idle"`

View File

@ -3,7 +3,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
// ProbeIO represents a stream of a probed file // ProbeIO represents a stream of a probed file
@ -17,11 +17,11 @@ type ProbeIO struct {
Type string `json:"type"` Type string `json:"type"`
Codec string `json:"codec"` Codec string `json:"codec"`
Coder string `json:"coder"` Coder string `json:"coder"`
Bitrate json.Number `json:"bitrate_kbps" swaggertype:"number"` Bitrate json.Number `json:"bitrate_kbps" swaggertype:"number" jsonschema:"type=number"`
Duration json.Number `json:"duration_sec" swaggertype:"number"` Duration json.Number `json:"duration_sec" swaggertype:"number" jsonschema:"type=number"`
// video // video
FPS json.Number `json:"fps" swaggertype:"number"` FPS json.Number `json:"fps" swaggertype:"number" jsonschema:"type=number"`
Pixfmt string `json:"pix_fmt"` Pixfmt string `json:"pix_fmt"`
Width uint64 `json:"width"` Width uint64 `json:"width"`
Height uint64 `json:"height"` Height uint64 `json:"height"`

View File

@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"strconv" "strconv"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
"github.com/lithammer/shortuuid/v4" "github.com/lithammer/shortuuid/v4"
) )
@ -239,7 +239,7 @@ type ProcessState struct {
LastLog string `json:"last_logline"` LastLog string `json:"last_logline"`
Progress *Progress `json:"progress"` Progress *Progress `json:"progress"`
Memory uint64 `json:"memory_bytes"` Memory uint64 `json:"memory_bytes"`
CPU json.Number `json:"cpu_usage" swaggertype:"number"` CPU json.Number `json:"cpu_usage" swaggertype:"number" jsonschema:"type=number"`
Command []string `json:"command"` Command []string `json:"command"`
} }

View File

@ -4,7 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
// ProgressIO represents the progress of an ffmpeg input or output // ProgressIO represents the progress of an ffmpeg input or output
@ -20,15 +20,15 @@ type ProgressIO struct {
Codec string `json:"codec"` Codec string `json:"codec"`
Coder string `json:"coder"` Coder string `json:"coder"`
Frame uint64 `json:"frame"` Frame uint64 `json:"frame"`
FPS json.Number `json:"fps" swaggertype:"number"` FPS json.Number `json:"fps" swaggertype:"number" jsonschema:"type=number"`
Packet uint64 `json:"packet"` Packet uint64 `json:"packet"`
PPS json.Number `json:"pps" swaggertype:"number"` PPS json.Number `json:"pps" swaggertype:"number" jsonschema:"type=number"`
Size uint64 `json:"size_kb"` // kbytes Size uint64 `json:"size_kb"` // kbytes
Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number"` // kbit/s Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s
// Video // Video
Pixfmt string `json:"pix_fmt,omitempty"` Pixfmt string `json:"pix_fmt,omitempty"`
Quantizer json.Number `json:"q,omitempty" swaggertype:"number"` Quantizer json.Number `json:"q,omitempty" swaggertype:"number" jsonschema:"type=number"`
Width uint64 `json:"width,omitempty"` Width uint64 `json:"width,omitempty"`
Height uint64 `json:"height,omitempty"` Height uint64 `json:"height,omitempty"`
@ -81,12 +81,12 @@ type Progress struct {
Output []ProgressIO `json:"outputs"` Output []ProgressIO `json:"outputs"`
Frame uint64 `json:"frame"` Frame uint64 `json:"frame"`
Packet uint64 `json:"packet"` Packet uint64 `json:"packet"`
FPS json.Number `json:"fps" swaggertype:"number"` FPS json.Number `json:"fps" swaggertype:"number" jsonschema:"type=number"`
Quantizer json.Number `json:"q" swaggertype:"number"` Quantizer json.Number `json:"q" swaggertype:"number" jsonschema:"type=number"`
Size uint64 `json:"size_kb"` // kbytes Size uint64 `json:"size_kb"` // kbytes
Time json.Number `json:"time" swaggertype:"number"` Time json.Number `json:"time" swaggertype:"number" jsonschema:"type=number"`
Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number"` // kbit/s Bitrate json.Number `json:"bitrate_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s
Speed json.Number `json:"speed" swaggertype:"number"` Speed json.Number `json:"speed" swaggertype:"number" jsonschema:"type=number"`
Drop uint64 `json:"drop"` Drop uint64 `json:"drop"`
Dup uint64 `json:"dup"` Dup uint64 `json:"dup"`
} }

View File

@ -3,7 +3,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
) )
// SessionStats are the accumulated numbers for the session summary // SessionStats are the accumulated numbers for the session summary
@ -30,8 +30,8 @@ type Session struct {
Extra string `json:"extra"` Extra string `json:"extra"`
RxBytes uint64 `json:"bytes_rx"` RxBytes uint64 `json:"bytes_rx"`
TxBytes uint64 `json:"bytes_tx"` TxBytes uint64 `json:"bytes_tx"`
RxBitrate json.Number `json:"bandwidth_rx_kbit" swaggertype:"number"` // kbit/s RxBitrate json.Number `json:"bandwidth_rx_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s
TxBitrate json.Number `json:"bandwidth_tx_kbit" swaggertype:"number"` // kbit/s TxBitrate json.Number `json:"bandwidth_tx_kbit" swaggertype:"number" jsonschema:"type=number"` // kbit/s
} }
func (s *Session) Unmarshal(sess session.Session) { func (s *Session) Unmarshal(sess session.Session) {
@ -51,11 +51,11 @@ func (s *Session) Unmarshal(sess session.Session) {
type SessionSummaryActive struct { type SessionSummaryActive struct {
SessionList []Session `json:"list"` SessionList []Session `json:"list"`
Sessions uint64 `json:"sessions"` Sessions uint64 `json:"sessions"`
RxBitrate json.Number `json:"bandwidth_rx_mbit" swaggertype:"number"` // mbit/s RxBitrate json.Number `json:"bandwidth_rx_mbit" swaggertype:"number" jsonschema:"type=number"` // mbit/s
TxBitrate json.Number `json:"bandwidth_tx_mbit" swaggertype:"number"` // mbit/s TxBitrate json.Number `json:"bandwidth_tx_mbit" swaggertype:"number" jsonschema:"type=number"` // mbit/s
MaxSessions uint64 `json:"max_sessions"` MaxSessions uint64 `json:"max_sessions"`
MaxRxBitrate json.Number `json:"max_bandwidth_rx_mbit" swaggertype:"number"` // mbit/s MaxRxBitrate json.Number `json:"max_bandwidth_rx_mbit" swaggertype:"number" jsonschema:"type=number"` // mbit/s
MaxTxBitrate json.Number `json:"max_bandwidth_tx_mbit" swaggertype:"number"` // mbit/s MaxTxBitrate json.Number `json:"max_bandwidth_tx_mbit" swaggertype:"number" jsonschema:"type=number"` // mbit/s
} }
// SessionSummarySummary represents the summary (history) of all finished sessions // SessionSummarySummary represents the summary (history) of all finished sessions

View File

@ -1,7 +1,7 @@
package api package api
import ( import (
"github.com/datarhei/core/ffmpeg/skills" "github.com/datarhei/core/v16/ffmpeg/skills"
) )
// SkillsFilter represents an ffmpeg filter // SkillsFilter represents an ffmpeg filter

6
http/api/srt.go Normal file
View File

@ -0,0 +1,6 @@
package api
// SRTChannel represents details about a currently connected SRT publisher
type SRTChannel struct {
Name string `json:"name" jsonschema:"minLength=1"`
}

2
http/cache/lru.go vendored
View File

@ -6,7 +6,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
) )
// LRUConfig is the configuration for a new LRU cache // LRUConfig is the configuration for a new LRU cache

View File

@ -5,7 +5,7 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -11,9 +11,9 @@ model:
models: models:
Uint64: Uint64:
model: github.com/datarhei/core/http/graph/scalars.Uint64 model: github.com/datarhei/core/v16/http/graph/scalars.Uint64
MetricsResponseValue: MetricsResponseValue:
model: github.com/datarhei/core/http/graph/scalars.MetricsResponseValue model: github.com/datarhei/core/v16/http/graph/scalars.MetricsResponseValue
resolver: resolver:
layout: follow-schema layout: follow-schema

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@ package models
import ( import (
"time" "time"
"github.com/datarhei/core/http/graph/scalars" "github.com/datarhei/core/v16/http/graph/scalars"
"github.com/datarhei/core/playout" "github.com/datarhei/core/v16/playout"
"github.com/datarhei/core/restream/app" "github.com/datarhei/core/v16/restream/app"
) )
func (s *RawAVstream) UnmarshalPlayout(status playout.Status) { func (s *RawAVstream) UnmarshalPlayout(status playout.Status) {

View File

@ -8,7 +8,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/datarhei/core/http/graph/scalars" "github.com/datarhei/core/v16/http/graph/scalars"
) )
type IProcessReportHistoryEntry interface { type IProcessReportHistoryEntry interface {

View File

@ -7,9 +7,9 @@ import (
"context" "context"
"time" "time"
"github.com/datarhei/core/app" "github.com/datarhei/core/v16/app"
"github.com/datarhei/core/http/graph/models" "github.com/datarhei/core/v16/http/graph/models"
"github.com/datarhei/core/http/graph/scalars" "github.com/datarhei/core/v16/http/graph/scalars"
) )
func (r *queryResolver) About(ctx context.Context) (*models.About, error) { func (r *queryResolver) About(ctx context.Context) (*models.About, error) {

View File

@ -7,7 +7,7 @@ import (
"context" "context"
"strings" "strings"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
) )
func (r *queryResolver) Log(ctx context.Context) ([]string, error) { func (r *queryResolver) Log(ctx context.Context) ([]string, error) {

View File

@ -7,9 +7,9 @@ import (
"context" "context"
"time" "time"
"github.com/datarhei/core/http/graph/models" "github.com/datarhei/core/v16/http/graph/models"
"github.com/datarhei/core/http/graph/scalars" "github.com/datarhei/core/v16/http/graph/scalars"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
) )
func (r *queryResolver) Metrics(ctx context.Context, query models.MetricsInput) (*models.Metrics, error) { func (r *queryResolver) Metrics(ctx context.Context, query models.MetricsInput) (*models.Metrics, error) {

View File

@ -9,8 +9,8 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/datarhei/core/http/graph/models" "github.com/datarhei/core/v16/http/graph/models"
"github.com/datarhei/core/playout" "github.com/datarhei/core/v16/playout"
) )
func (r *queryResolver) PlayoutStatus(ctx context.Context, id string, input string) (*models.RawAVstream, error) { func (r *queryResolver) PlayoutStatus(ctx context.Context, id string, input string) (*models.RawAVstream, error) {

View File

@ -6,7 +6,7 @@ package resolver
import ( import (
"context" "context"
"github.com/datarhei/core/http/graph/models" "github.com/datarhei/core/v16/http/graph/models"
) )
func (r *queryResolver) Processes(ctx context.Context) ([]*models.Process, error) { func (r *queryResolver) Processes(ctx context.Context) ([]*models.Process, error) {

View File

@ -6,10 +6,10 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/datarhei/core/http/graph/models" "github.com/datarhei/core/v16/http/graph/models"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/monitor" "github.com/datarhei/core/v16/monitor"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
) )
// This file will not be regenerated automatically. // This file will not be regenerated automatically.

View File

@ -6,7 +6,7 @@ package resolver
import ( import (
"context" "context"
"github.com/datarhei/core/http/graph/graph" "github.com/datarhei/core/v16/http/graph/graph"
) )
func (r *mutationResolver) Ping(ctx context.Context) (string, error) { func (r *mutationResolver) Ping(ctx context.Context) (string, error) {

View File

@ -4,9 +4,9 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/datarhei/core/app" "github.com/datarhei/core/v16/app"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,8 +4,8 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/mock" "github.com/datarhei/core/v16/http/mock"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -3,9 +3,9 @@ package api
import ( import (
"net/http" "net/http"
"github.com/datarhei/core/config" "github.com/datarhei/core/v16/config"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/datarhei/core/config" "github.com/datarhei/core/v16/config"
"github.com/datarhei/core/http/mock" "github.com/datarhei/core/v16/http/mock"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -51,6 +51,7 @@ func TestConfigSet(t *testing.T) {
cfg := config.New() cfg := config.New()
cfg.DB.Dir = "." cfg.DB.Dir = "."
cfg.Storage.Disk.Dir = "." cfg.Storage.Disk.Dir = "."
cfg.Storage.MimeTypes = ""
encoder := json.NewEncoder(&data) encoder := json.NewEncoder(&data)
encoder.Encode(cfg) encoder.Encode(cfg)

View File

@ -5,11 +5,11 @@ import (
"path/filepath" "path/filepath"
"sort" "sort"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/cache" "github.com/datarhei/core/v16/http/cache"
"github.com/datarhei/core/http/handler" "github.com/datarhei/core/v16/http/handler"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -3,8 +3,8 @@ package api
import ( import (
"net/http" "net/http"
"github.com/datarhei/core/http/graph/graph" "github.com/datarhei/core/v16/http/graph/graph"
"github.com/datarhei/core/http/graph/resolver" "github.com/datarhei/core/v16/http/graph/resolver"
"github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground" "github.com/99designs/gqlgen/graphql/playground"

View File

@ -4,8 +4,8 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,8 +4,8 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/mock" "github.com/datarhei/core/v16/http/mock"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -6,10 +6,10 @@ import (
"net/url" "net/url"
"sort" "sort"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler" "github.com/datarhei/core/v16/http/handler"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,10 +4,10 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/monitor" "github.com/datarhei/core/v16/monitor"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -8,10 +8,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/playout" "github.com/datarhei/core/v16/playout"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,9 +4,9 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/lithammer/shortuuid/v4" "github.com/lithammer/shortuuid/v4"

View File

@ -4,8 +4,8 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/mock" "github.com/datarhei/core/v16/http/mock"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -45,7 +45,7 @@ func TestAddProcessMissingField(t *testing.T) {
data := mock.Read(t, "./fixtures/addProcessMissingField.json") data := mock.Read(t, "./fixtures/addProcessMissingField.json")
mock.Request(t, http.StatusBadRequest, router, "POST", "/", data) mock.Request(t, http.StatusOK, router, "POST", "/", data)
} }
func TestAddProcessInvalidType(t *testing.T) { func TestAddProcessInvalidType(t *testing.T) {

View File

@ -3,8 +3,8 @@ package api
import ( import (
"net/http" "net/http"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/rtmp" "github.com/datarhei/core/v16/rtmp"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -21,9 +21,9 @@ func NewRTMP(rtmp rtmp.Server) *RTMPHandler {
} }
} }
// ListChannels lists all currently publishing streams // ListChannels lists all currently publishing RTMP streams
// @Summary List all publishing streams // @Summary List all publishing RTMP streams
// @Description List all currently publishing streams // @Description List all currently publishing RTMP streams
// @ID rtmp-3-list-channels // @ID rtmp-3-list-channels
// @Produce json // @Produce json
// @Success 200 {array} api.RTMPChannel // @Success 200 {array} api.RTMPChannel

View File

@ -4,9 +4,9 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
@ -63,9 +63,8 @@ func (s *SessionHandler) Active(c echo.Context) error {
for _, name := range collectors { for _, name := range collectors {
sessions := s.registry.Active(name) sessions := s.registry.Active(name)
active := []api.Session{}
active = make([]api.Session, len(sessions)) active := make([]api.Session, len(sessions))
for i, s := range sessions { for i, s := range sessions {
active[i].Unmarshal(s) active[i].Unmarshal(s)

View File

@ -4,9 +4,9 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/mock" "github.com/datarhei/core/v16/http/mock"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

35
http/handler/api/srt.go Normal file
View File

@ -0,0 +1,35 @@
package api
import (
"net/http"
"github.com/datarhei/core/v16/srt"
"github.com/labstack/echo/v4"
)
// The SRTHandler type provides a handler for retrieving details from the SRTHandler server
type SRTHandler struct {
srt srt.Server
}
// NewRTMP returns a new SRT type. You have to provide a SRT server instance.
func NewSRT(srt srt.Server) *SRTHandler {
return &SRTHandler{
srt: srt,
}
}
// ListChannels lists all currently publishing SRT streams
// @Summary List all publishing SRT treams
// @Description List all currently publishing SRT streams
// @ID srt-3-list-channels
// @Produce json
// @Success 200 {array} api.SRTChannel
// @Security ApiKeyAuth
// @Router /api/v3/srt [get]
func (srth *SRTHandler) ListChannels(c echo.Context) error {
channels := srth.srt.Channels()
return c.JSON(http.StatusOK, channels)
}

View File

@ -3,10 +3,10 @@ package api
import ( import (
"net/http" "net/http"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,10 +4,10 @@ import (
"net/http" "net/http"
"path/filepath" "path/filepath"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/cache" "github.com/datarhei/core/v16/http/cache"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,9 +4,9 @@ import (
"net/http" "net/http"
"path/filepath" "path/filepath"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -4,7 +4,7 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/datarhei/core/http/mock" "github.com/datarhei/core/v16/http/mock"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )

View File

@ -6,7 +6,7 @@ import (
"net/url" "net/url"
"strings" "strings"
"github.com/datarhei/core/encoding/json" "github.com/datarhei/core/v16/encoding/json"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )

View File

@ -7,8 +7,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/app" "github.com/datarhei/core/v16/app"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
jwtgo "github.com/golang-jwt/jwt/v4" jwtgo "github.com/golang-jwt/jwt/v4"
"github.com/google/uuid" "github.com/google/uuid"

View File

@ -4,9 +4,9 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/handler/util" "github.com/datarhei/core/v16/http/handler/util"
"github.com/datarhei/core/http/jwt/jwks" "github.com/datarhei/core/v16/http/jwt/jwks"
jwtgo "github.com/golang-jwt/jwt/v4" jwtgo "github.com/golang-jwt/jwt/v4"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"

View File

@ -8,7 +8,7 @@ import (
"path" "path"
"strings" "strings"
"github.com/datarhei/core/http/cache" "github.com/datarhei/core/v16/http/cache"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"

View File

@ -5,7 +5,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/http/cors" "github.com/datarhei/core/v16/http/cors"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"

View File

@ -3,7 +3,7 @@ package iplimit
import ( import (
"net/http" "net/http"
"github.com/datarhei/core/net" "github.com/datarhei/core/v16/net"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"

View File

@ -5,7 +5,7 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"

View File

@ -13,8 +13,8 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/datarhei/core/net" "github.com/datarhei/core/v16/net"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"

View File

@ -5,7 +5,7 @@ import (
"net" "net"
"net/http" "net/http"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"

View File

@ -10,14 +10,14 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/datarhei/core/ffmpeg" "github.com/datarhei/core/v16/ffmpeg"
"github.com/datarhei/core/http/api" "github.com/datarhei/core/v16/http/api"
"github.com/datarhei/core/http/errorhandler" "github.com/datarhei/core/v16/http/errorhandler"
"github.com/datarhei/core/http/validator" "github.com/datarhei/core/v16/http/validator"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/datarhei/core/restream/store" "github.com/datarhei/core/v16/restream/store"
"github.com/alecthomas/jsonschema" "github.com/invopop/jsonschema"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/xeipuuv/gojsonschema" "github.com/xeipuuv/gojsonschema"

View File

@ -7,13 +7,14 @@
// @contact.email hello@datarhei.com // @contact.email hello@datarhei.com
// @license.name Apache 2.0 // @license.name Apache 2.0
// @license.url https://github.com/datarhei/core/blob/main/LICENSE // @license.url https://github.com/datarhei/core/v16/blob/main/LICENSE
// @BasePath / // @BasePath /
// @securityDefinitions.apikey ApiKeyAuth // @securityDefinitions.apikey ApiKeyAuth
// @in header // @in header
// @name Authorization // @name Authorization
// @Param Authorization header string true "Insert your access token" default(Bearer <Add access token here>)
// @securityDefinitions.apikey ApiRefreshKeyAuth // @securityDefinitions.apikey ApiRefreshKeyAuth
// @in header // @in header
@ -30,33 +31,34 @@ package http
import ( import (
"net/http" "net/http"
"github.com/datarhei/core/config" "github.com/datarhei/core/v16/config"
"github.com/datarhei/core/http/cache" "github.com/datarhei/core/v16/http/cache"
"github.com/datarhei/core/http/errorhandler" "github.com/datarhei/core/v16/http/errorhandler"
"github.com/datarhei/core/http/graph/resolver" "github.com/datarhei/core/v16/http/graph/resolver"
"github.com/datarhei/core/http/handler" "github.com/datarhei/core/v16/http/handler"
api "github.com/datarhei/core/http/handler/api" api "github.com/datarhei/core/v16/http/handler/api"
"github.com/datarhei/core/http/jwt" "github.com/datarhei/core/v16/http/jwt"
"github.com/datarhei/core/http/router" "github.com/datarhei/core/v16/http/router"
"github.com/datarhei/core/http/validator" "github.com/datarhei/core/v16/http/validator"
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/monitor" "github.com/datarhei/core/v16/monitor"
"github.com/datarhei/core/net" "github.com/datarhei/core/v16/net"
"github.com/datarhei/core/prometheus" "github.com/datarhei/core/v16/prometheus"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
"github.com/datarhei/core/rtmp" "github.com/datarhei/core/v16/rtmp"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
"github.com/datarhei/core/v16/srt"
mwbodysize "github.com/datarhei/core/http/middleware/bodysize" mwbodysize "github.com/datarhei/core/v16/http/middleware/bodysize"
mwcache "github.com/datarhei/core/http/middleware/cache" mwcache "github.com/datarhei/core/v16/http/middleware/cache"
mwcors "github.com/datarhei/core/http/middleware/cors" mwcors "github.com/datarhei/core/v16/http/middleware/cors"
mwgzip "github.com/datarhei/core/http/middleware/gzip" mwgzip "github.com/datarhei/core/v16/http/middleware/gzip"
mwiplimit "github.com/datarhei/core/http/middleware/iplimit" mwiplimit "github.com/datarhei/core/v16/http/middleware/iplimit"
mwlog "github.com/datarhei/core/http/middleware/log" mwlog "github.com/datarhei/core/v16/http/middleware/log"
mwmime "github.com/datarhei/core/http/middleware/mime" mwmime "github.com/datarhei/core/v16/http/middleware/mime"
mwredirect "github.com/datarhei/core/http/middleware/redirect" mwredirect "github.com/datarhei/core/v16/http/middleware/redirect"
mwsession "github.com/datarhei/core/http/middleware/session" mwsession "github.com/datarhei/core/v16/http/middleware/session"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"
@ -64,7 +66,7 @@ import (
echoSwagger "github.com/swaggo/echo-swagger" // echo-swagger middleware echoSwagger "github.com/swaggo/echo-swagger" // echo-swagger middleware
// Expose the API docs // Expose the API docs
_ "github.com/datarhei/core/docs" _ "github.com/datarhei/core/v16/docs"
) )
var ListenAndServe = http.ListenAndServe var ListenAndServe = http.ListenAndServe
@ -82,6 +84,7 @@ type Config struct {
Profiling bool Profiling bool
Cors CorsConfig Cors CorsConfig
RTMP rtmp.Server RTMP rtmp.Server
SRT srt.Server
JWT jwt.JWT JWT jwt.JWT
Config config.Store Config config.Store
Cache cache.Cacher Cache cache.Cacher
@ -126,6 +129,7 @@ type server struct {
memfs *api.MemFSHandler memfs *api.MemFSHandler
diskfs *api.DiskFSHandler diskfs *api.DiskFSHandler
rtmp *api.RTMPHandler rtmp *api.RTMPHandler
srt *api.SRTHandler
config *api.ConfigHandler config *api.ConfigHandler
session *api.SessionHandler session *api.SessionHandler
widget *api.WidgetHandler widget *api.WidgetHandler
@ -248,6 +252,12 @@ func NewServer(config Config) (Server, error) {
) )
} }
if config.SRT != nil {
s.v3handler.srt = api.NewSRT(
config.SRT,
)
}
if config.Config != nil { if config.Config != nil {
s.v3handler.config = api.NewConfig( s.v3handler.config = api.NewConfig(
config.Config, config.Config,
@ -343,11 +353,7 @@ func NewServer(config Config) (Server, error) {
group := s.router.Group(path) group := s.router.Group(path)
group.Use(middleware.AddTrailingSlashWithConfig(middleware.TrailingSlashConfig{ group.Use(middleware.AddTrailingSlashWithConfig(middleware.TrailingSlashConfig{
Skipper: func(c echo.Context) bool { Skipper: func(c echo.Context) bool {
if path == c.Request().URL.Path { return path != c.Request().URL.Path
return false
}
return true
}, },
RedirectCode: 301, RedirectCode: 301,
})) }))
@ -368,11 +374,7 @@ func NewServer(config Config) (Server, error) {
group.Use(middleware.AddTrailingSlashWithConfig(middleware.TrailingSlashConfig{ group.Use(middleware.AddTrailingSlashWithConfig(middleware.TrailingSlashConfig{
Skipper: func(prefix string) func(c echo.Context) bool { Skipper: func(prefix string) func(c echo.Context) bool {
return func(c echo.Context) bool { return func(c echo.Context) bool {
if prefix == c.Request().URL.Path { return prefix != c.Request().URL.Path
return false
}
return true
} }
}(prefix), }(prefix),
RedirectCode: 301, RedirectCode: 301,
@ -609,13 +611,18 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
v3.GET("/rtmp", s.v3handler.rtmp.ListChannels) v3.GET("/rtmp", s.v3handler.rtmp.ListChannels)
} }
// v3 SRT
if s.v3handler.srt != nil {
v3.GET("/srt", s.v3handler.srt.ListChannels)
}
// v3 Config // v3 Config
if s.v3handler.config != nil { if s.v3handler.config != nil {
v3.GET("/config", s.v3handler.config.Get) v3.GET("/config", s.v3handler.config.Get)
v3.GET("/config/reload", s.v3handler.config.Reload)
if !s.readOnly { if !s.readOnly {
v3.PUT("/config", s.v3handler.config.Set) v3.PUT("/config", s.v3handler.config.Set)
v3.GET("/config/reload", s.v3handler.config.Reload)
} }
} }

View File

@ -8,7 +8,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
) )
// DiskConfig is the config required to create a new disk // DiskConfig is the config required to create a new disk
@ -241,7 +241,7 @@ func (fs *diskFilesystem) Store(path string, r io.Reader) (int64, bool, error) {
dir := filepath.Dir(path) dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil { if err := os.MkdirAll(dir, 0755); err != nil {
return -1, false, fmt.Errorf("Creating file failed: %w", err) return -1, false, fmt.Errorf("creating file failed: %w", err)
} }
var f *os.File var f *os.File
@ -251,7 +251,7 @@ func (fs *diskFilesystem) Store(path string, r io.Reader) (int64, bool, error) {
if err != nil { if err != nil {
f, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644) f, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil { if err != nil {
return -1, false, fmt.Errorf("Creating file failed: %w", err) return -1, false, fmt.Errorf("creating file failed: %w", err)
} }
replace = false replace = false
@ -259,7 +259,7 @@ func (fs *diskFilesystem) Store(path string, r io.Reader) (int64, bool, error) {
size, err := f.ReadFrom(r) size, err := f.ReadFrom(r)
if err != nil { if err != nil {
return -1, false, fmt.Errorf("Reading data failed: %w", err) return -1, false, fmt.Errorf("reading data failed: %w", err)
} }
return size, !replace, nil return size, !replace, nil

View File

@ -9,7 +9,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
) )
// MemConfig is the config that is required for creating // MemConfig is the config that is required for creating
@ -305,7 +305,7 @@ func (fs *memFilesystem) Store(path string, r io.Reader) (int64, bool, error) {
if newSize > fs.maxSize { if newSize > fs.maxSize {
if !fs.purge { if !fs.purge {
fs.dataPool.Put(data) fs.dataPool.Put(data)
return -1, false, fmt.Errorf("Not enough space on device") return -1, false, fmt.Errorf("not enough space on device")
} }
if replace { if replace {

View File

@ -168,9 +168,9 @@ rules:
continue rules continue rules
} }
switch value.(type) { switch value := value.(type) {
case string: case string:
if !re.MatchString(value.(string)) { if !re.MatchString(value) {
continue rules continue rules
} }
} }

View File

@ -4,8 +4,8 @@ import (
"os" "os"
"os/signal" "os/signal"
"github.com/datarhei/core/app/api" "github.com/datarhei/core/v16/app/api"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
_ "github.com/joho/godotenv/autoload" _ "github.com/joho/godotenv/autoload"
) )

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
) )
type cpuCollector struct { type cpuCollector struct {

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
) )
type diskCollector struct { type diskCollector struct {

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/ffmpeg" "github.com/datarhei/core/v16/ffmpeg"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
) )
type ffmpegCollector struct { type ffmpegCollector struct {

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/io/fs" "github.com/datarhei/core/v16/io/fs"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
) )
type filesystemCollector struct { type filesystemCollector struct {

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
) )
type memCollector struct { type memCollector struct {

View File

@ -7,7 +7,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
) )
type Monitor interface { type Monitor interface {

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
) )
type netCollector struct { type netCollector struct {

View File

@ -3,8 +3,8 @@ package monitor
import ( import (
"strconv" "strconv"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/datarhei/core/restream" "github.com/datarhei/core/v16/restream"
) )
type restreamCollector struct { type restreamCollector struct {

View File

@ -1,8 +1,8 @@
package monitor package monitor
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/datarhei/core/session" "github.com/datarhei/core/v16/session"
) )
type sessionCollector struct { type sessionCollector struct {

View File

@ -3,7 +3,7 @@ package monitor
import ( import (
"time" "time"
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
) )
type uptimeCollector struct { type uptimeCollector struct {

View File

@ -69,15 +69,15 @@ func TestPutPort(t *testing.T) {
} }
func TestClampRange(t *testing.T) { func TestClampRange(t *testing.T) {
portrange, _ := NewPortrange(0, 70000) portrange, _ := NewPortrange(65000, 70000)
port, _ := portrange.Get() port, _ := portrange.Get()
assert.Equal(t, 1, port) assert.Equal(t, 65000, port)
portrange.Put(1) portrange.Put(65000)
for i := 1; i <= 65535; i++ { for i := 65000; i <= 65535; i++ {
port, _ := portrange.Get() port, _ := portrange.Get()
assert.Equal(t, i, port, "at index %d", i) assert.Equal(t, i, port, "at index %d", i)
} }

View File

@ -6,7 +6,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
) )
type LimitFunc func(cpu float64, memory uint64) type LimitFunc func(cpu float64, memory uint64)

View File

@ -5,7 +5,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -28,7 +28,11 @@ func (p *psproc) VirtualMemory() (uint64, error) {
func (p *psproc) Stop() {} func (p *psproc) Stop() {}
func TestCPULimit(t *testing.T) { func TestCPULimit(t *testing.T) {
lock := sync.Mutex{}
lock.Lock()
done := false done := false
lock.Unlock()
go func() { go func() {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
@ -46,16 +50,25 @@ func TestCPULimit(t *testing.T) {
wg.Wait() wg.Wait()
lock.Lock()
done = true done = true
lock.Unlock()
}() }()
assert.Eventually(t, func() bool { assert.Eventually(t, func() bool {
lock.Lock()
defer lock.Unlock()
return done return done
}, 2*time.Second, 100*time.Millisecond) }, 2*time.Second, 100*time.Millisecond)
} }
func TestCPULimitWaitFor(t *testing.T) { func TestCPULimitWaitFor(t *testing.T) {
lock := sync.Mutex{}
lock.Lock()
done := false done := false
lock.Unlock()
go func() { go func() {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
@ -74,16 +87,25 @@ func TestCPULimitWaitFor(t *testing.T) {
wg.Wait() wg.Wait()
lock.Lock()
done = true done = true
lock.Unlock()
}() }()
assert.Eventually(t, func() bool { assert.Eventually(t, func() bool {
lock.Lock()
defer lock.Unlock()
return done return done
}, 10*time.Second, 1*time.Second) }, 10*time.Second, 1*time.Second)
} }
func TestMemoryLimit(t *testing.T) { func TestMemoryLimit(t *testing.T) {
lock := sync.Mutex{}
lock.Lock()
done := false done := false
lock.Unlock()
go func() { go func() {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
@ -101,16 +123,25 @@ func TestMemoryLimit(t *testing.T) {
wg.Wait() wg.Wait()
lock.Lock()
done = true done = true
lock.Unlock()
}() }()
assert.Eventually(t, func() bool { assert.Eventually(t, func() bool {
lock.Lock()
defer lock.Unlock()
return done return done
}, 2*time.Second, 100*time.Millisecond) }, 2*time.Second, 100*time.Millisecond)
} }
func TestMemoryLimitWaitFor(t *testing.T) { func TestMemoryLimitWaitFor(t *testing.T) {
lock := sync.Mutex{}
lock.Lock()
done := false done := false
lock.Unlock()
go func() { go func() {
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
@ -129,10 +160,15 @@ func TestMemoryLimitWaitFor(t *testing.T) {
wg.Wait() wg.Wait()
lock.Lock()
done = true done = true
lock.Unlock()
}() }()
assert.Eventually(t, func() bool { assert.Eventually(t, func() bool {
lock.Lock()
defer lock.Unlock()
return done return done
}, 10*time.Second, 1*time.Second) }, 10*time.Second, 1*time.Second)
} }

View File

@ -6,6 +6,7 @@ package process
import ( import (
"bufio" "bufio"
"context"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -16,8 +17,8 @@ import (
"time" "time"
"unicode/utf8" "unicode/utf8"
"github.com/datarhei/core/log" "github.com/datarhei/core/v16/log"
"github.com/datarhei/core/psutil" "github.com/datarhei/core/v16/psutil"
) )
// Process represents a process and ways to control it // Process represents a process and ways to control it
@ -168,7 +169,7 @@ type process struct {
stale struct { stale struct {
last time.Time last time.Time
timeout time.Duration timeout time.Duration
done chan struct{} cancel context.CancelFunc
lock sync.Mutex lock sync.Mutex
} }
reconn struct { reconn struct {
@ -177,10 +178,11 @@ type process struct {
timer *time.Timer timer *time.Timer
lock sync.Mutex lock sync.Mutex
} }
killTimer *time.Timer killTimer *time.Timer
logger log.Logger killTimerLock sync.Mutex
debuglogger log.Logger logger log.Logger
callbacks struct { debuglogger log.Logger
callbacks struct {
onStart func() onStart func()
onStop func() onStop func()
onStateChange func(from, to string) onStateChange func(from, to string)
@ -502,7 +504,13 @@ func (p *process) start() error {
// Start the stale timeout if enabled // Start the stale timeout if enabled
if p.stale.timeout != 0 { if p.stale.timeout != 0 {
go p.staler() var ctx context.Context
p.stale.lock.Lock()
ctx, p.stale.cancel = context.WithCancel(context.Background())
p.stale.lock.Unlock()
go p.staler(ctx)
} }
return nil return nil
@ -584,9 +592,11 @@ func (p *process) stop() error {
} else { } else {
// Set up a timer to kill the process with SIGKILL in case SIGINT didn't have // Set up a timer to kill the process with SIGKILL in case SIGINT didn't have
// an effect. // an effect.
p.killTimerLock.Lock()
p.killTimer = time.AfterFunc(5*time.Second, func() { p.killTimer = time.AfterFunc(5*time.Second, func() {
p.cmd.Process.Kill() p.cmd.Process.Kill()
}) })
p.killTimerLock.Unlock()
} }
} }
@ -643,9 +653,8 @@ func (p *process) unreconnect() {
// staler checks if the currently running process is stale, i.e. the reader // staler checks if the currently running process is stale, i.e. the reader
// didn't update the time of the last read. If the timeout is reached, the // didn't update the time of the last read. If the timeout is reached, the
// process will be stopped such that it can restart automatically afterwards. // process will be stopped such that it can restart automatically afterwards.
func (p *process) staler() { func (p *process) staler(ctx context.Context) {
p.stale.lock.Lock() p.stale.lock.Lock()
p.stale.done = make(chan struct{})
p.stale.last = time.Now() p.stale.last = time.Now()
p.stale.lock.Unlock() p.stale.lock.Unlock()
@ -656,7 +665,7 @@ func (p *process) staler() {
for { for {
select { select {
case <-p.stale.done: case <-ctx.Done():
p.debuglogger.Debug().Log("Stopping stale watcher") p.debuglogger.Debug().Log("Stopping stale watcher")
return return
case t := <-ticker.C: case t := <-ticker.C:
@ -772,16 +781,18 @@ func (p *process) waiter() {
p.limits.Stop() p.limits.Stop()
// Stop the kill timer // Stop the kill timer
p.killTimerLock.Lock()
if p.killTimer != nil { if p.killTimer != nil {
p.killTimer.Stop() p.killTimer.Stop()
p.killTimer = nil p.killTimer = nil
} }
p.killTimerLock.Unlock()
// Stop the stale progress timer // Stop the stale progress timer
p.stale.lock.Lock() p.stale.lock.Lock()
if p.stale.done != nil { if p.stale.cancel != nil {
close(p.stale.done) p.stale.cancel()
p.stale.done = nil p.stale.cancel = nil
} }
p.stale.lock.Unlock() p.stale.lock.Unlock()

View File

@ -1,7 +1,7 @@
package prometheus package prometheus
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

View File

@ -1,7 +1,7 @@
package prometheus package prometheus
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

View File

@ -1,7 +1,7 @@
package prometheus package prometheus
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

View File

@ -1,7 +1,7 @@
package prometheus package prometheus
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

View File

@ -1,7 +1,7 @@
package prometheus package prometheus
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

View File

@ -1,7 +1,7 @@
package prometheus package prometheus
import ( import (
"github.com/datarhei/core/monitor/metric" "github.com/datarhei/core/v16/monitor/metric"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )

Some files were not shown because too many files have changed in this diff Show More