add --check-version command line flag (#5786)
this allows to check whether a new version is available without upgrading.
This commit is contained in:
+20
-5
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/bluenviron/mediamtx/internal/servers/rtsp"
|
||||
"github.com/bluenviron/mediamtx/internal/servers/srt"
|
||||
"github.com/bluenviron/mediamtx/internal/servers/webrtc"
|
||||
"github.com/bluenviron/mediamtx/internal/upgrade"
|
||||
)
|
||||
|
||||
//go:generate go run ./versiongetter
|
||||
@@ -97,9 +98,10 @@ func getRTPMaxPayloadSize(udpMaxPayloadSize int, rtspEncryption conf.Encryption)
|
||||
}
|
||||
|
||||
var cli struct {
|
||||
Confpath string `arg:"" default:""`
|
||||
Version bool `help:"print version"`
|
||||
Upgrade bool `help:"upgrade executable to the latest version"`
|
||||
Confpath string `arg:"" default:""`
|
||||
Version bool `help:"print version"`
|
||||
CheckVersion bool `help:"check whether a new version is available"`
|
||||
Upgrade bool `help:"upgrade executable to the latest version"`
|
||||
}
|
||||
|
||||
// Core is an instance of MediaMTX.
|
||||
@@ -159,9 +161,22 @@ func New(args []string) (*Core, bool) {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if cli.CheckVersion {
|
||||
var newVersionAvailable bool
|
||||
newVersionAvailable, err = upgrade.CheckVersion(string(version), getArch())
|
||||
if err != nil {
|
||||
fmt.Printf("ERR: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if newVersionAvailable {
|
||||
os.Exit(2)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if cli.Upgrade {
|
||||
err = upgrade() //nolint:staticcheck
|
||||
if err != nil { //nolint:staticcheck
|
||||
err = upgrade.Upgrade(string(version), getArch())
|
||||
if err != nil {
|
||||
fmt.Printf("ERR: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
//go:build !enable_upgrade
|
||||
|
||||
package core
|
||||
|
||||
import "fmt"
|
||||
|
||||
func upgrade() error {
|
||||
return fmt.Errorf("upgrade command is not available")
|
||||
}
|
||||
@@ -30,7 +30,6 @@ var (
|
||||
dumpPath = ""
|
||||
)
|
||||
|
||||
|
||||
func multiplyAndDivide(v, m, d int64) int64 {
|
||||
secs := v / d
|
||||
dec := v % d
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
)
|
||||
|
||||
// CheckVersion checks whether a new version is available.
|
||||
// Returns true if a newer version is available.
|
||||
func CheckVersion(version, _ string) (bool, error) {
|
||||
if !currentRegexp.MatchString(version) {
|
||||
return false, fmt.Errorf("current version (%v) is not official and cannot be checked", version)
|
||||
}
|
||||
|
||||
fmt.Println("getting latest version...")
|
||||
|
||||
latest, err := latestRemoteVersion()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
current, _ := semver.NewVersion(version)
|
||||
|
||||
if current.GreaterThanEqual(latest) {
|
||||
fmt.Printf("current version (%v) is up to date\n", "v"+current.String())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fmt.Printf("a new version is available: %v (current: %v)\n", "v"+latest.String(), "v"+current.String())
|
||||
return true, nil
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
//go:build !windows
|
||||
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
const extension = "tar.gz"
|
||||
|
||||
func extractExecutable(r io.Reader) ([]byte, error) {
|
||||
gzReader, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gzReader.Close() //nolint:errcheck
|
||||
|
||||
tarReader := tar.NewReader(gzReader)
|
||||
|
||||
for {
|
||||
var header *tar.Header
|
||||
header, err = tarReader.Next()
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return nil, fmt.Errorf("executable not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if header.Name == executable {
|
||||
var buf []byte
|
||||
buf, err = io.ReadAll(tarReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
const extension = "zip"
|
||||
|
||||
func extractExecutable(r io.Reader) ([]byte, error) {
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zipReader, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, file := range zipReader.File {
|
||||
if file.Name == executable+".exe" {
|
||||
var rc io.ReadCloser
|
||||
rc, err = file.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
var buf []byte
|
||||
buf, err = io.ReadAll(rc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("executable not found")
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
//go:build enable_upgrade
|
||||
|
||||
package core
|
||||
// Package upgrade contains functions to upgrade the executable.
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@@ -61,68 +56,10 @@ func latestRemoteVersion() (*semver.Version, error) {
|
||||
return versions[0], nil
|
||||
}
|
||||
|
||||
func extractExecutable(r io.Reader) ([]byte, error) {
|
||||
gzReader, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gzReader.Close()
|
||||
|
||||
tarReader := tar.NewReader(gzReader)
|
||||
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
if err == io.EOF {
|
||||
return nil, fmt.Errorf("executable not found")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if header.Name == executable {
|
||||
buf, err := io.ReadAll(tarReader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func extractExecutableWin(r io.Reader) ([]byte, error) {
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zipReader, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, file := range zipReader.File {
|
||||
if file.Name == executable+".exe" {
|
||||
rc, err := file.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
buf, err := io.ReadAll(rc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("executable not found")
|
||||
}
|
||||
|
||||
func upgrade() error {
|
||||
if !currentRegexp.MatchString(string(version)) {
|
||||
return fmt.Errorf("current version (%v) is not official and cannot be upgraded", string(version))
|
||||
// Upgrade downloads the latest executable and replaces the current one with it.
|
||||
func Upgrade(version, arch string) error {
|
||||
if !currentRegexp.MatchString(version) {
|
||||
return fmt.Errorf("current version (%v) is not official and cannot be upgraded", version)
|
||||
}
|
||||
|
||||
fmt.Println("getting latest version...")
|
||||
@@ -132,7 +69,7 @@ func upgrade() error {
|
||||
return err
|
||||
}
|
||||
|
||||
current, _ := semver.NewVersion(string(version))
|
||||
current, _ := semver.NewVersion(version)
|
||||
|
||||
if current.GreaterThanEqual(latest) {
|
||||
fmt.Printf("current version (%v) is up to date\n", "v"+current.String())
|
||||
@@ -141,14 +78,7 @@ func upgrade() error {
|
||||
|
||||
fmt.Printf("downloading version %v...\n", "v"+latest.String())
|
||||
|
||||
var extension string
|
||||
if runtime.GOOS == "windows" {
|
||||
extension = "zip"
|
||||
} else {
|
||||
extension = "tar.gz"
|
||||
}
|
||||
|
||||
ur := fmt.Sprintf(downloadURL, "v"+latest.String(), "v"+latest.String(), runtime.GOOS, getArch(), extension)
|
||||
ur := fmt.Sprintf(downloadURL, "v"+latest.String(), "v"+latest.String(), runtime.GOOS, arch, extension)
|
||||
|
||||
res, err := http.Get(ur)
|
||||
if err != nil {
|
||||
@@ -160,11 +90,9 @@ func upgrade() error {
|
||||
return fmt.Errorf("bad status code: %v", res.StatusCode)
|
||||
}
|
||||
|
||||
var exe []byte
|
||||
if runtime.GOOS == "windows" {
|
||||
exe, err = extractExecutableWin(res.Body)
|
||||
} else {
|
||||
exe, err = extractExecutable(res.Body)
|
||||
exe, err := extractExecutable(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = selfupdate.Apply(bytes.NewReader(exe), selfupdate.Options{})
|
||||
+7
-7
@@ -14,33 +14,33 @@ RUN cp mediamtx.yml LICENSE tmp/
|
||||
RUN go generate ./...
|
||||
|
||||
FROM build-base AS build-windows-amd64
|
||||
RUN GOOS=windows GOARCH=amd64 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME).exe"
|
||||
RUN GOOS=windows GOARCH=amd64 go build -o "tmp/$(BINARY_NAME).exe"
|
||||
RUN go install github.com/tc-hib/go-winres@v0.3.3
|
||||
RUN go-winres patch --in scripts/winres.json --product-version "$$(git describe --tags --abbrev=0 | sed 's/^v//')" --file-version "$$(git describe --tags --abbrev=0 | sed 's/^v//')" tmp/mediamtx.exe
|
||||
RUN cd tmp && zip -q "../binaries/$(BINARY_NAME)_$$(cat ../internal/core/VERSION)_windows_amd64.zip" "$(BINARY_NAME).exe" mediamtx.yml LICENSE
|
||||
|
||||
FROM build-base AS build-linux-amd64
|
||||
RUN GOOS=linux GOARCH=amd64 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME)"
|
||||
RUN GOOS=linux GOARCH=amd64 go build -o "tmp/$(BINARY_NAME)"
|
||||
RUN tar -C tmp -czf "binaries/$(BINARY_NAME)_$$(cat internal/core/VERSION)_linux_amd64.tar.gz" --owner=0 --group=0 "$(BINARY_NAME)" mediamtx.yml LICENSE
|
||||
|
||||
FROM build-base AS build-darwin-amd64
|
||||
RUN GOOS=darwin GOARCH=amd64 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME)"
|
||||
RUN GOOS=darwin GOARCH=amd64 go build -o "tmp/$(BINARY_NAME)"
|
||||
RUN tar -C tmp -czf "binaries/$(BINARY_NAME)_$$(cat internal/core/VERSION)_darwin_amd64.tar.gz" --owner=0 --group=0 "$(BINARY_NAME)" mediamtx.yml LICENSE
|
||||
|
||||
FROM build-base AS build-darwin-arm64
|
||||
RUN GOOS=darwin GOARCH=arm64 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME)"
|
||||
RUN GOOS=darwin GOARCH=arm64 go build -o "tmp/$(BINARY_NAME)"
|
||||
RUN tar -C tmp -czf "binaries/$(BINARY_NAME)_$$(cat internal/core/VERSION)_darwin_arm64.tar.gz" --owner=0 --group=0 "$(BINARY_NAME)" mediamtx.yml LICENSE
|
||||
|
||||
FROM build-base AS build-linux-armv6
|
||||
RUN GOOS=linux GOARCH=arm GOARM=6 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME)"
|
||||
RUN GOOS=linux GOARCH=arm GOARM=6 go build -o "tmp/$(BINARY_NAME)"
|
||||
RUN tar -C tmp -czf "binaries/$(BINARY_NAME)_$$(cat internal/core/VERSION)_linux_armv6.tar.gz" --owner=0 --group=0 "$(BINARY_NAME)" mediamtx.yml LICENSE
|
||||
|
||||
FROM build-base AS build-linux-armv7
|
||||
RUN GOOS=linux GOARCH=arm GOARM=7 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME)"
|
||||
RUN GOOS=linux GOARCH=arm GOARM=7 go build -o "tmp/$(BINARY_NAME)"
|
||||
RUN tar -C tmp -czf "binaries/$(BINARY_NAME)_$$(cat internal/core/VERSION)_linux_armv7.tar.gz" --owner=0 --group=0 "$(BINARY_NAME)" mediamtx.yml LICENSE
|
||||
|
||||
FROM build-base AS build-linux-arm64
|
||||
RUN GOOS=linux GOARCH=arm64 go build -tags enable_upgrade -o "tmp/$(BINARY_NAME)"
|
||||
RUN GOOS=linux GOARCH=arm64 go build -o "tmp/$(BINARY_NAME)"
|
||||
RUN tar -C tmp -czf "binaries/$(BINARY_NAME)_$$(cat internal/core/VERSION)_linux_arm64.tar.gz" --owner=0 --group=0 "$(BINARY_NAME)" mediamtx.yml LICENSE
|
||||
|
||||
FROM $(BASE_IMAGE)
|
||||
|
||||
Reference in New Issue
Block a user